diff --git a/bsp/imxrt/libraries/drivers/drv_i2c.c b/bsp/imxrt/libraries/drivers/drv_i2c.c index 1920c0d502283dfe997f77f367f13bcda4b67fb6..0ccbb4899625f26c85ba7515e9dc16d219f7c8b9 100644 --- a/bsp/imxrt/libraries/drivers/drv_i2c.c +++ b/bsp/imxrt/libraries/drivers/drv_i2c.c @@ -18,7 +18,7 @@ #define LOG_TAG "drv.i2c" #include -#if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4) +#if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4) && !defined(BSP_USING_I2C5)&& !defined(BSP_USING_I2C6) #error "Please define at least one BSP_USING_I2Cx" #endif @@ -35,6 +35,9 @@ struct imxrt_i2c_bus volatile rt_uint32_t msg_ptr; volatile rt_uint32_t dptr; char *device_name; +#ifdef SOC_IMXRT1170_SERIES + clock_root_t clock_root; +#endif }; #if defined (BSP_USING_I2C1) @@ -55,13 +58,28 @@ struct imxrt_i2c_bus #define I2C4BUS_NAME "i2c4" #endif /*BSP_USING_I2C4*/ +#if defined (BSP_USING_I2C5) +#define I2C5BUS_NAME "i2c5" +#endif /*BSP_USING_I2C5*/ + +#if defined (BSP_USING_I2C6) +#define I2C6BUS_NAME "i2c6" +#endif /*BSP_USING_I2C6*/ + #endif /* MIMXRT1015_SERIES */ -#define LPI2C_CLOCK_SOURCE_DIVIDER 4 +/* Select USB1 PLL (360 MHz) as master lpi2c clock source */ +#define LPI2C_CLOCK_SOURCE_SELECT (1U) +#ifdef SOC_IMXRT1170_SERIES +/* Clock divider for master lpi2c clock source */ +#define LPI2C_CLOCK_SOURCE_DIVIDER (12U) +#else +#define LPI2C_CLOCK_SOURCE_DIVIDER (0U) /* Get frequency of lpi2c clock */ -#define LPI2C_CLOCK_FREQUENCY ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER)) +#define LPI2C_CLOCK_FREQUENCY ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U)) +#endif #ifdef BSP_USING_I2C1 static struct imxrt_i2c_bus lpi2c1 = { @@ -96,9 +114,25 @@ static struct imxrt_i2c_bus lpi2c4 = }; #endif /* RT_USING_HW_I2C4 */ +#ifdef BSP_USING_I2C5 +static struct imxrt_i2c_bus lpi2c5 = +{ + .I2C = LPI2C5, + .device_name = I2C5BUS_NAME, +}; +#endif /* RT_USING_HW_I2C5 */ + +#ifdef BSP_USING_I2C6 +static struct imxrt_i2c_bus lpi2c6 = +{ + .I2C = LPI2C6, + .device_name = I2C6BUS_NAME, +}; +#endif /* RT_USING_HW_I2C6 */ + #endif /* MIMXRT1015_SERIES */ -#if (defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3) || defined(BSP_USING_I2C4)) +#if (defined(BSP_USING_I2C1) || defined(BSP_USING_I2C2) || defined(BSP_USING_I2C3) || defined(BSP_USING_I2C4) ||defined(BSP_USING_I2C5) || defined(BSP_USING_I2C6)) static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], @@ -123,7 +157,19 @@ static rt_err_t imxrt_lpi2c_configure(struct imxrt_i2c_bus *bus, lpi2c_master_co RT_ASSERT(cfg != RT_NULL); bus->parent.ops = &imxrt_i2c_ops; +#ifdef SOC_IMXRT1170_SERIES + clock_root_config_t rootCfg = {0}; + rootCfg.mux = LPI2C_CLOCK_SOURCE_SELECT; + rootCfg.div = LPI2C_CLOCK_SOURCE_DIVIDER + 1; + CLOCK_SetRootClock(bus->clock_root, &rootCfg); + volatile uint32_t freq = CLOCK_GetRootClockFreq(bus->clock_root); + LPI2C_MasterInit(bus->I2C, cfg, freq); +#else + CLOCK_SetMux(kCLOCK_Lpi2cMux, LPI2C_CLOCK_SOURCE_SELECT); + CLOCK_SetDiv(kCLOCK_Lpi2cDiv, LPI2C_CLOCK_SOURCE_DIVIDER); LPI2C_MasterInit(bus->I2C, cfg, LPI2C_CLOCK_FREQUENCY); +#endif + return RT_EOK; } @@ -221,6 +267,37 @@ static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, { if (imxrt_i2c->msg[i].flags & RT_I2C_RD) { + if ((imxrt_i2c->msg[i].flags & RT_I2C_NO_START) != RT_I2C_NO_START) + { + if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Write) != kStatus_Success) + { + i = 0; + break; + } + + while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag) + { + } + + if (LPI2C_MasterRepeatedStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Read) != kStatus_Success) + { + i = 0; + break; + } + } + else + { + if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Read) != kStatus_Success) + { + i = 0; + break; + } + + while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag) + { + } + } + if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Read) != kStatus_Success) { i = 0; @@ -244,9 +321,17 @@ static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, i = 0; break; } - - while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag) + + if(LPI2C_MasterWaitForTxFifoAllEmpty(imxrt_i2c->I2C) != kStatus_Success) { + i = 0; + break; + } + + if (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag) + { + i = 0; + break; } if (LPI2C_MasterSend(imxrt_i2c->I2C, imxrt_i2c->msg[i].buf, imxrt_i2c->msg[i].len) != kStatus_Success) @@ -261,11 +346,12 @@ static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, break; } } - } - - if (LPI2C_MasterStop(imxrt_i2c->I2C) != kStatus_Success) - { - i = 0; + + if (LPI2C_MasterStop(imxrt_i2c->I2C) != kStatus_Success) + { + i = 0; + } + } imxrt_i2c->msg = RT_NULL; @@ -341,6 +427,31 @@ int rt_hw_i2c_init(void) rt_i2c_bus_device_register(&lpi2c4.parent, lpi2c4.device_name); #endif /* BSP_USING_I2C4 */ +#if defined(BSP_USING_I2C5) + LPI2C_MasterGetDefaultConfig(&masterConfig); +#if defined(HW_I2C5_BADURATE_400kHZ) + masterConfig.baudRate_Hz = 400000U; +#elif defined(HW_I2C5_BADURATE_100kHZ) + masterConfig.baudRate_Hz = 100000U; +#endif /* HW_I2C5_BADURATE_400kHZ */ + lpi2c5.clock_root = kCLOCK_Root_Lpi2c5; + imxrt_lpi2c_configure(&lpi2c5, &masterConfig); + rt_i2c_bus_device_register(&lpi2c5.parent, lpi2c5.device_name); +#endif /* BSP_USING_I2C5 */ + +#if defined(BSP_USING_I2C6) + LPI2C_MasterGetDefaultConfig(&masterConfig); +#if defined(HW_I2C6_BADURATE_400kHZ) + masterConfig.baudRate_Hz = 400000U; +#elif defined(HW_I2C6_BADURATE_100kHZ) + masterConfig.baudRate_Hz = 100000U; +#endif /* HW_I2C6_BADURATE_400kHZ */ + lpi2c6.clock_root = kCLOCK_Root_Lpi2c6; + imxrt_lpi2c_configure(&lpi2c6, &masterConfig); + rt_i2c_bus_device_register(&lpi2c6.parent, lpi2c6.device_name); +#endif /* BSP_USING_I2C6 */ + + #endif /* MIMXRT1015_SERIES */ return 0;