You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
5.0 KiB
173 lines
5.0 KiB
/*
|
|
* Copyright (c) 2019-2022, Erich Styger
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "McuI2cLibconfig.h"
|
|
|
|
#if McuLib_CONFIG_MCUI2CLIB_ENABLED
|
|
#include "McuLib.h"
|
|
#include "McuI2cLib.h"
|
|
#include "fsl_i2c.h"
|
|
#include "McuGPIO.h"
|
|
#include "McuWait.h"
|
|
#if McuLib_CONFIG_CPU_IS_KINETIS
|
|
#include "fsl_port.h"
|
|
#elif McuLib_CONFIG_CPU_IS_LPC
|
|
#include "pin_mux.h"
|
|
#include "fsl_iocon.h"
|
|
#endif
|
|
#if McuLib_CONFIG_CPU_VARIANT==McuLib_CONFIG_CPU_VARIANT_NXP_LPC845
|
|
#include "fsl_swm.h"
|
|
#endif
|
|
|
|
static uint8_t i2cSlaveDeviceAddr; /* used to store the current I2C device address used */
|
|
|
|
uint8_t McuI2cLib_SendBlock(void *Ptr, uint16_t Siz, uint16_t *Snt) {
|
|
status_t status;
|
|
|
|
#if McuLib_CONFIG_CPU_IS_KINETIS
|
|
I2C_MasterClearStatusFlags(MCUI2CLIB_CONFIG_I2C_MASTER_BASEADDR, kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag);
|
|
#elif McuLib_CONFIG_CPU_IS_LPC
|
|
I2C_MasterClearStatusFlags(MCUI2CLIB_CONFIG_I2C_MASTER_BASEADDR, kI2C_MasterPendingFlag | kI2C_MasterArbitrationLostFlag | kI2C_MasterStartStopErrorFlag);
|
|
#endif
|
|
status = I2C_MasterStart(MCUI2CLIB_CONFIG_I2C_MASTER_BASEADDR, i2cSlaveDeviceAddr, kI2C_Write);
|
|
if (status!=kStatus_Success) {
|
|
return ERR_FAILED;
|
|
}
|
|
#if MCUI2CLIB_CONFIG_ADD_DELAY
|
|
McuWait_Waitus(MCUI2CLIB_CONFIG_ADD_DELAY_US);
|
|
#endif
|
|
status = I2C_MasterWriteBlocking(MCUI2CLIB_CONFIG_I2C_MASTER_BASEADDR, Ptr, Siz, kI2C_TransferNoStartFlag|kI2C_TransferNoStopFlag);
|
|
if (status!=kStatus_Success) {
|
|
return ERR_FAILED;
|
|
}
|
|
*Snt = Siz;
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint8_t McuI2cLib_RecvBlock(void *Ptr, uint16_t Siz, uint16_t *Rcv) {
|
|
status_t status;
|
|
|
|
status = I2C_MasterRepeatedStart(MCUI2CLIB_CONFIG_I2C_MASTER_BASEADDR, i2cSlaveDeviceAddr, kI2C_Read);
|
|
if (status!=kStatus_Success) {
|
|
return ERR_FAILED;
|
|
}
|
|
#if MCUI2CLIB_CONFIG_ADD_DELAY
|
|
McuWait_Waitus(MCUI2CLIB_CONFIG_ADD_DELAY_US);
|
|
#endif
|
|
status = I2C_MasterReadBlocking(MCUI2CLIB_CONFIG_I2C_MASTER_BASEADDR, Ptr, Siz, kI2C_TransferDefaultFlag);
|
|
if (status!=kStatus_Success) {
|
|
return ERR_FAILED;
|
|
}
|
|
*Rcv = Siz;
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint8_t McuI2cLib_SendStop(void) {
|
|
status_t status;
|
|
|
|
status = I2C_MasterStop(MCUI2CLIB_CONFIG_I2C_MASTER_BASEADDR);
|
|
if (status!=kStatus_Success) {
|
|
return ERR_FAILED;
|
|
}
|
|
return ERR_OK;
|
|
}
|
|
|
|
uint8_t McuI2cLib_SelectSlave(uint8_t Slv) {
|
|
i2cSlaveDeviceAddr = Slv;
|
|
return ERR_OK;
|
|
}
|
|
|
|
static void McuI2cLib_ReleaseBus(void) {
|
|
McuGPIO_Handle_t sdaPin, sclPin;
|
|
McuGPIO_Config_t config;
|
|
uint8_t i = 0;
|
|
|
|
McuGPIO_GetDefaultConfig(&config);
|
|
config.isInput = false;
|
|
config.isHighOnInit = true;
|
|
config.hw.gpio = MCUI2CLIB_CONFIG_SDA_GPIO;
|
|
config.hw.pin = MCUI2CLIB_CONFIG_SDA_GPIO_PIN;
|
|
config.hw.port = MCUI2CLIB_CONFIG_SDA_GPIO_PORT;
|
|
sdaPin = McuGPIO_InitGPIO(&config);
|
|
|
|
config.hw.gpio = MCUI2CLIB_CONFIG_SCL_GPIO;
|
|
config.hw.pin = MCUI2CLIB_CONFIG_SCL_GPIO_PIN;
|
|
config.hw.port = MCUI2CLIB_CONFIG_SCL_GPIO_PORT;
|
|
sclPin = McuGPIO_InitGPIO(&config);
|
|
|
|
/* Drive SDA low first to simulate a start */
|
|
McuGPIO_SetLow(sdaPin);
|
|
McuWait_Waitus(10);
|
|
/* Send 9 pulses on SCL and keep SDA high */
|
|
for (i = 0; i < 9; i++) {
|
|
McuGPIO_SetLow(sclPin);
|
|
McuWait_Waitus(10);
|
|
|
|
McuGPIO_SetHigh(sdaPin);
|
|
McuWait_Waitus(10);
|
|
|
|
McuGPIO_SetHigh(sclPin);
|
|
McuWait_Waitus(20);
|
|
}
|
|
/* Send stop */
|
|
McuGPIO_SetLow(sclPin);
|
|
McuWait_Waitus(10);
|
|
|
|
McuGPIO_SetLow(sdaPin);
|
|
McuWait_Waitus(10);
|
|
|
|
McuGPIO_SetLow(sclPin);
|
|
McuWait_Waitus(10);
|
|
|
|
McuGPIO_SetHigh(sdaPin);
|
|
McuWait_Waitus(10);
|
|
/* cleanup */
|
|
sdaPin = McuGPIO_DeinitGPIO(sdaPin);
|
|
sclPin = McuGPIO_DeinitGPIO(sclPin);
|
|
}
|
|
|
|
/* mux as I2C pins */
|
|
static void McuI2cLib_ConfigureI2cPins(void) {
|
|
#if McuLib_CONFIG_CPU_IS_KINETIS \
|
|
|| McuLib_CONFIG_CPU_VARIANT==McuLib_CONFIG_CPU_VARIANT_NXP_LPC55S16 \
|
|
|| McuLib_CONFIG_CPU_VARIANT==McuLib_CONFIG_CPU_VARIANT_NXP_LPC55S69 \
|
|
|| McuLib_CONFIG_CPU_VARIANT==McuLib_CONFIG_CPU_VARIANT_NXP_LPC845
|
|
MCUI2CLIB_CONFIG_MUX_I2C_PINS();
|
|
#else
|
|
#error "unknown configuration and MCU"
|
|
#endif
|
|
}
|
|
|
|
void McuI2cLib_Deinit(void) {
|
|
}
|
|
|
|
void McuI2cLib_Init(void) {
|
|
McuI2cLib_ReleaseBus();
|
|
#if McuLib_CONFIG_CPU_IS_KINETIS \
|
|
|| McuLib_CONFIG_CPU_IS_LPC55xx && McuLib_CONFIG_CPU_VARIANT==McuLib_CONFIG_CPU_VARIANT_NXP_LPC55S16 \
|
|
|| McuLib_CONFIG_CPU_IS_LPC55xx && McuLib_CONFIG_CPU_VARIANT==McuLib_CONFIG_CPU_VARIANT_NXP_LPC55S69 \
|
|
|| McuLib_CONFIG_CPU_IS_LPC && McuLib_CONFIG_CPU_VARIANT==McuLib_CONFIG_CPU_VARIANT_NXP_LPC845
|
|
MCUI2CLIB_CONFIG_CLOCK_SELECT();
|
|
#else
|
|
#error "unknown configuration and MCU"
|
|
#endif
|
|
|
|
McuI2cLib_ConfigureI2cPins();
|
|
|
|
i2c_master_config_t masterConfig;
|
|
uint32_t sourceClock;
|
|
/*
|
|
* masterConfig->baudRate_Bps = 100000U;
|
|
* masterConfig->enableStopHold = false;
|
|
* masterConfig->glitchFilterWidth = 0U;
|
|
* masterConfig->enableMaster = true;
|
|
*/
|
|
I2C_MasterGetDefaultConfig(&masterConfig);
|
|
masterConfig.baudRate_Bps = MCUI2CLIB_CONFIG_I2C_BAUDRATE;
|
|
sourceClock = MCUI2CLIB_CONFIG_I2C_MASTER_CLK_FREQ;
|
|
I2C_MasterInit(MCUI2CLIB_CONFIG_I2C_MASTER_BASEADDR, &masterConfig, sourceClock);
|
|
}
|
|
#endif /* McuGenericI2C_CONFIG_INTERFACE_HEADER_FILE */
|
|
|