From 6d63451e38f59f0874b94d7ece3a706a8794c27b Mon Sep 17 00:00:00 2001 From: balanceTWK Date: Thu, 5 Apr 2018 11:44:25 +0800 Subject: [PATCH] [bsp][imxrt1052] add hardware i2c --- bsp/imxrt1052-evk/Kconfig | 54 ++- bsp/imxrt1052-evk/drivers/SConscript | 4 + bsp/imxrt1052-evk/drivers/drv_i2c.c | 552 ++++++++++++++++++++++----- bsp/imxrt1052-evk/drivers/drv_i2c.h | 34 ++ 4 files changed, 545 insertions(+), 99 deletions(-) create mode 100644 bsp/imxrt1052-evk/drivers/drv_i2c.h diff --git a/bsp/imxrt1052-evk/Kconfig b/bsp/imxrt1052-evk/Kconfig index 0216ef30d6..acfdff1a48 100644 --- a/bsp/imxrt1052-evk/Kconfig +++ b/bsp/imxrt1052-evk/Kconfig @@ -93,7 +93,7 @@ menu "Select spi bus drivers" config LPSPI_CLK_SOURCE_DIVIDER int "SPI bus clock source divider" - range 0 8 + range 1 8 default 7 config RT_USING_SPIBUS1 @@ -225,6 +225,58 @@ menu "Select spi bus drivers" endchoice endmenu +menu "Select iic drivers" + + config LPI2C_CLOCK_SOURCE_DIVIDER + int "lpi2c bus clock source divider" + range 1 64 + default 4 + + config RT_USING_I2C1 + bool "USING I2C1" + select RT_USING_I2C + default n + if RT_USING_I2C1 + config RT_USING_I2C1_BITOPS + select RT_USING_I2C_BITOPS + default n + bool "using simulate I2C1" + endif + + config RT_USING_I2C2 + bool "USING I2C2" + select RT_USING_I2C + default n + if RT_USING_I2C2 + config RT_USING_I2C2_BITOPS + select RT_USING_I2C_BITOPS + default n + bool "using simulate I2C2" + endif + + config RT_USING_I2C3 + bool "USING I2C3" + select RT_USING_I2C + default n + if RT_USING_I2C3 + config RT_USING_I2C3_BITOPS + select RT_USING_I2C_BITOPS + default n + bool "using simulate I2C3" + endif + + config RT_USING_I2C4 + bool "USING I2C4" + select RT_USING_I2C + default n + if RT_USING_I2C4 + config RT_USING_I2C4_BITOPS + select RT_USING_I2C_BITOPS + default n + bool "using simulate I2C4" + endif +endmenu + #menu "SDRAM driver support" config RT_USING_SDRAM bool "Using sdram" diff --git a/bsp/imxrt1052-evk/drivers/SConscript b/bsp/imxrt1052-evk/drivers/SConscript index 73bcec1fd6..e19e0044bd 100644 --- a/bsp/imxrt1052-evk/drivers/SConscript +++ b/bsp/imxrt1052-evk/drivers/SConscript @@ -30,6 +30,10 @@ if GetDepend('RT_USING_RTC_HP'): if GetDepend('RT_USING_SPI'): src += ['drv_spi_bus.c'] +# add i2cbus driver code +if GetDepend('RT_USING_I2C'): + src += ['drv_i2c.c'] + if GetDepend('BOARD_RT1050_EVK'): src += ['hyper_flash_boot.c'] diff --git a/bsp/imxrt1052-evk/drivers/drv_i2c.c b/bsp/imxrt1052-evk/drivers/drv_i2c.c index 4d23ea36cc..efe33efa6e 100644 --- a/bsp/imxrt1052-evk/drivers/drv_i2c.c +++ b/bsp/imxrt1052-evk/drivers/drv_i2c.c @@ -19,23 +19,32 @@ * Change Logs: * Date Author Notes * 2017-08-08 Yang the first version + * 2018-03-24 LaiYiKeTang add hardware iic */ - + #include #include #include "board.h" #include "fsl_gpio.h" #include "fsl_lpi2c.h" +#include "drv_i2c.h" //#define DRV_I2C_DEBUG #ifdef RT_USING_I2C -#ifdef RT_USING_I2C_BITOPS +#define I2C1BUS_NAME "i2c1" +#define I2C2BUS_NAME "i2c2" +#define I2C3BUS_NAME "i2c3" +#define I2C4BUS_NAME "i2c4" + +/* Get frequency of lpi2c clock */ +#define LPI2C_CLOCK_FREQUENCY ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U)) -#define I2CBUS_NAME "i2c0" +#if defined(RT_USING_I2C_BITOPS) && (defined(RT_USING_I2C1_BITOPS) || defined(RT_USING_I2C2_BITOPS) || \ + defined(RT_USING_I2C3_BITOPS) || defined(RT_USING_I2C4_BITOPS)) -struct stm32_i2c_bit_data +struct rt1052_i2c_bit_data { struct { @@ -49,24 +58,24 @@ static void gpio_udelay(rt_uint32_t us) volatile rt_int32_t i; for (; us > 0; us--) { - i = 1000; + i = 100; while (i--); } } -static void gpio_set_input(GPIO_Type* base, uint32_t pin) +static void gpio_set_input(GPIO_Type *base, uint32_t pin) { - if (base->GDIR & (1 << pin)) //output mode + if (base->GDIR & (1 << pin)) { base->GDIR &= ~(1 << pin); gpio_udelay(5); } } -static void gpio_set_output(GPIO_Type* base, uint32_t pin) +static void gpio_set_output(GPIO_Type *base, uint32_t pin) { - if (!(base->GDIR & (1 << pin))) //input mode - { + if (!(base->GDIR & (1 << pin))) + { base->GDIR |= (1 << pin); gpio_udelay(5); } @@ -74,26 +83,26 @@ static void gpio_set_output(GPIO_Type* base, uint32_t pin) static void gpio_set_sda(void *data, rt_int32_t state) { - struct stm32_i2c_bit_data *bd = data; - + struct rt1052_i2c_bit_data *bd = data; + gpio_set_output(bd->sda.base, bd->sda.pin); - + GPIO_PinWrite(bd->sda.base, bd->sda.pin, !!state); } static void gpio_set_scl(void *data, rt_int32_t state) { - struct stm32_i2c_bit_data *bd = data; - + struct rt1052_i2c_bit_data *bd = data; + gpio_set_output(bd->scl.base, bd->scl.pin); - + GPIO_PinWrite(bd->scl.base, bd->scl.pin, !!state); } static rt_int32_t gpio_get_sda(void *data) { - struct stm32_i2c_bit_data *bd = data; - + struct rt1052_i2c_bit_data *bd = data; + gpio_set_input(bd->sda.base, bd->sda.pin); return GPIO_ReadPinInput(bd->sda.base, bd->sda.pin); @@ -101,89 +110,434 @@ static rt_int32_t gpio_get_sda(void *data) static rt_int32_t gpio_get_scl(void *data) { - struct stm32_i2c_bit_data *bd = data; - + struct rt1052_i2c_bit_data *bd = data; + gpio_set_input(bd->scl.base, bd->scl.pin); return GPIO_ReadPinInput(bd->scl.base, bd->scl.pin); } +#endif -#else /* RT_USING_I2C_BITOPS */ - // todo : add hardware i2c -#endif /* RT_USING_I2C_BITOPS */ +#ifdef RT_USING_I2C1 +#ifdef RT_USING_I2C1_BITOPS -int rt_hw_i2c_init(void) +#else +static struct rt1052_i2c_bus lpi2c1 = +{ + .I2C = LPI2C1, + .device_name = I2C1BUS_NAME, +}; +#endif /* RT_USING_I2C1_BITOPS */ +#endif /* RT_USING_I2C1 */ + +#ifdef RT_USING_I2C2 +#ifdef RT_USING_I2C2_BITOPS + +#else +static struct rt1052_i2c_bus lpi2c2 = +{ + .I2C = LPI2C2, + .device_name = I2C2BUS_NAME, +}; +#endif /* RT_USING_I2C2_BITOPS */ +#endif /* RT_USING_I2C2 */ + +#ifdef RT_USING_I2C3 +#ifdef RT_USING_I2C3_BITOPS + +#else +static struct rt1052_i2c_bus lpi2c3 = +{ + .I2C = LPI2C3, + .device_name = I2C3BUS_NAME, +}; + +#endif /* RT_USING_I2C3_BITOPS */ +#endif /* RT_USING_I2C3 */ + +#ifdef RT_USING_I2C4 + +#ifdef RT_USING_I2C4_BITOPS + +#else +static struct rt1052_i2c_bus lpi2c4 = +{ + .I2C = LPI2C4, + .device_name = I2C4BUS_NAME, +}; +#endif /* RT_USING_I2C1_BITOPS */ + +#endif /* RT_USING_I2C4 */ + +#if (defined(RT_USING_I2C1) || defined(RT_USING_I2C2) || \ + defined(RT_USING_I2C3) || defined(RT_USING_I2C4)) + +static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num); +static rt_size_t imxrt_i2c_slv_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num); +static rt_err_t imxrt_i2c_bus_control(struct rt_i2c_bus_device *bus, + rt_uint32_t, + rt_uint32_t); + +static const struct rt_i2c_bus_device_ops imxrt_i2c_ops = +{ + imxrt_i2c_mst_xfer, + imxrt_i2c_slv_xfer, + imxrt_i2c_bus_control, +}; + +#if !defined(RT_USING_I2C_BITOPS) || (!defined(RT_USING_I2C1_BITOPS) || !defined(RT_USING_I2C2_BITOPS) || \ + !defined(RT_USING_I2C3_BITOPS) || !defined(RT_USING_I2C4_BITOPS)) + +void imxrt_lpi2c_gpio_init(struct rt1052_i2c_bus *bus) { -#ifdef RT_USING_I2C_BITOPS - /* register I2C1: SCL/P0_20 SDA/P0_19 */ + if (bus->I2C == LPI2C1) { - static struct rt_i2c_bus_device i2c_device; + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, + 1U); + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, + 1U); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, + 0xD8B0u); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, + 0xD8B0u); + } + else if (bus->I2C == LPI2C2) + { + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_04_LPI2C2_SCL, + 1U); + IOMUXC_SetPinMux( + IOMUXC_GPIO_B0_05_LPI2C2_SDA, + 1U); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_04_LPI2C2_SCL, + 0xD8B0u); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_B0_05_LPI2C2_SDA, + 0xD8B0u); + } + else if (bus->I2C == LPI2C3) + { + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL, + 1U); + IOMUXC_SetPinMux( + IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA, + 1U); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B1_07_LPI2C3_SCL, + 0xD8B0u); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_AD_B1_06_LPI2C3_SDA, + 0xD8B0u); + } + else if (bus->I2C == LPI2C4) + { + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_12_LPI2C4_SCL, + 1U); + IOMUXC_SetPinMux( + IOMUXC_GPIO_EMC_11_LPI2C4_SDA, + 1U); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_12_LPI2C4_SCL, + 0xD8B0u); + IOMUXC_SetPinConfig( + IOMUXC_GPIO_EMC_11_LPI2C4_SDA, + 0xD8B0u); + } + else + { + RT_ASSERT(RT_NULL); + } +} - static const struct stm32_i2c_bit_data _i2c_bdata = - { - /* SCL */ {GPIO1, 16}, - /* SDA */ {GPIO1, 17}, - }; +static rt_err_t imxrt_lpi2c_configure(struct rt1052_i2c_bus *bus, lpi2c_master_config_t *cfg) +{ + RT_ASSERT(bus != RT_NULL); + RT_ASSERT(cfg != RT_NULL); + + imxrt_lpi2c_gpio_init(bus); + bus->parent.ops = &imxrt_i2c_ops; + LPI2C_MasterInit(bus->I2C, cfg, LPI2C_CLOCK_FREQUENCY); + return RT_EOK; +} - static const struct rt_i2c_bit_ops _i2c_bit_ops = +#endif + +static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + struct rt1052_i2c_bus *rt1052_i2c; + rt_uint32_t numbak; + rt_uint16_t i; + RT_ASSERT(bus != RT_NULL); + rt1052_i2c = (struct rt1052_i2c_bus *) bus; + + rt1052_i2c->msg = msgs; + rt1052_i2c->msg_ptr = 0; + rt1052_i2c->msg_cnt = num; + rt1052_i2c->dptr = 0; + + for (i = 0; i < num; i++) + { + if (rt1052_i2c->msg[i].flags & RT_I2C_RD) { - (void*)&_i2c_bdata, - gpio_set_sda, - gpio_set_scl, - gpio_get_sda, - gpio_get_scl, - - gpio_udelay, - - 50, - 1000 - }; - - gpio_pin_config_t pin_config = { - kGPIO_DigitalOutput, 0, - }; - - CLOCK_EnableClock(kCLOCK_Iomuxc); - - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_GPIO1_IO16, 1U); - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_GPIO1_IO16, - 0xD8B0u); /* Slew Rate Field: Slow Slew Rate - Drive Strength Field: R0/6 - Speed Field: medium(100MHz) - Open Drain Enable Field: Open Drain Enabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Keeper - Pull Up / Down Config. Field: 22K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_GPIO1_IO17, 1U); - IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_GPIO1_IO17, - 0xD8B0u); /* Slew Rate Field: Slow Slew Rate - Drive Strength Field: R0/6 - Speed Field: medium(100MHz) - Open Drain Enable Field: Open Drain Enabled - Pull / Keep Enable Field: Pull/Keeper Enabled - Pull / Keep Select Field: Keeper - Pull Up / Down Config. Field: 22K Ohm Pull Up - Hyst. Enable Field: Hysteresis Disabled */ - /* Enable touch panel controller */ - GPIO_PinInit(_i2c_bdata.sda.base, _i2c_bdata.sda.pin, &pin_config); - GPIO_PinInit(_i2c_bdata.scl.base, _i2c_bdata.scl.pin, &pin_config); - - GPIO_PortSet(_i2c_bdata.sda.base, _i2c_bdata.sda.pin); - GPIO_PortSet(_i2c_bdata.scl.base, _i2c_bdata.scl.pin); - - //RT_ASSERT(gpio_get_scl(&_i2c_bdata) != 0); - //RT_ASSERT(gpio_get_sda(&_i2c_bdata) != 0); - - i2c_device.priv = (void *)&_i2c_bit_ops; - rt_i2c_bit_add_bus(&i2c_device, I2CBUS_NAME); - } /* register I2C */ - -#else /* RT_USING_I2C_BITOPS */ - // Todo : add hardware i2c - -#endif /* RT_USING_I2C_BITOPS */ + LPI2C_MasterStart(rt1052_i2c->I2C, rt1052_i2c->msg[i].addr, kLPI2C_Read); + if (LPI2C_MasterReceive(rt1052_i2c->I2C, rt1052_i2c->msg->buf, rt1052_i2c->msg->len) == kStatus_LPI2C_Nak) + { + i = 0; + break; + } + } + else + { + LPI2C_MasterStart(rt1052_i2c->I2C, rt1052_i2c->msg[i].addr, kLPI2C_Write); + if (LPI2C_MasterSend(rt1052_i2c->I2C, rt1052_i2c->msg->buf, rt1052_i2c->msg->len) == kStatus_LPI2C_Nak) + { + i = 0; + break; + } + } + } + + i2c_dbg("send stop condition\n"); + LPI2C_MasterStop(rt1052_i2c->I2C); + + numbak = i; + rt1052_i2c->msg = RT_NULL; + rt1052_i2c->msg_ptr = 0; + rt1052_i2c->msg_cnt = 0; + rt1052_i2c->dptr = 0; + return numbak; +} +static rt_size_t imxrt_i2c_slv_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], + rt_uint32_t num) +{ + return 0; +} +static rt_err_t imxrt_i2c_bus_control(struct rt_i2c_bus_device *bus, + rt_uint32_t cmd, + rt_uint32_t arg) +{ + return RT_ERROR; +} + +#endif + +int rt_hw_i2c_init(void) +{ +#if !defined(RT_USING_I2C_BITOPS) || (!defined(RT_USING_I2C1_BITOPS) || !defined(RT_USING_I2C2_BITOPS) || \ + !defined(RT_USING_I2C3_BITOPS) || !defined(RT_USING_I2C4_BITOPS)) + + lpi2c_master_config_t masterConfig = {0}; + + /*Clock setting for LPI2C*/ + CLOCK_SetMux(kCLOCK_Lpi2cMux, 0); + CLOCK_SetDiv(kCLOCK_Lpi2cDiv, LPI2C_CLOCK_SOURCE_DIVIDER); + +#endif + +#if defined(RT_USING_I2C_BITOPS) && (defined(RT_USING_I2C1_BITOPS) || defined(RT_USING_I2C2_BITOPS) || \ + defined(RT_USING_I2C3_BITOPS) || defined(RT_USING_I2C4_BITOPS)) + gpio_pin_config_t pin_config = + { + kGPIO_DigitalOutput, + 0, + }; +#endif /* RT_USING_I2C_BITOPS= RT_USING_I2C1_BITOPS RT_USING_I2C2_BITOPS RT_USING_I2C3_BITOPS RT_USING_I2C4_BITOPS */ +#if defined(RT_USING_I2C1) && defined(RT_USING_I2C1_BITOPS) + + static struct rt_i2c_bus_device i2c1_device; + + static const struct rt1052_i2c_bit_data _i2c1_bdata = + { + /* SCL */ {GPIO1, 16}, + /* SDA */ {GPIO1, 17}, + }; + + static const struct rt_i2c_bit_ops _i2c1_bit_ops = + { + (void *) &_i2c1_bdata, + gpio_set_sda, + gpio_set_scl, + gpio_get_sda, + gpio_get_scl, + + gpio_udelay, + + 50, + 1000 + }; + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_00_GPIO1_IO16, 1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_00_GPIO1_IO16, 0xD8B0u); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_01_GPIO1_IO17, 1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_01_GPIO1_IO17, 0xD8B0u); + + /* Enable touch panel controller */ + GPIO_PinInit(_i2c1_bdata.sda.base, _i2c1_bdata.sda.pin, &pin_config); + GPIO_PinInit(_i2c1_bdata.scl.base, _i2c1_bdata.scl.pin, &pin_config); + + GPIO_PortSet(_i2c1_bdata.sda.base, _i2c1_bdata.sda.pin); + GPIO_PortSet(_i2c1_bdata.scl.base, _i2c1_bdata.scl.pin); + + i2c1_device.priv = (void *) &_i2c1_bit_ops; + rt_i2c_bit_add_bus(&i2c1_device, I2C1BUS_NAME); + +#elif defined(RT_USING_I2C1) && !defined(RT_USING_I2C1_BITOPS) + LPI2C_MasterGetDefaultConfig(&masterConfig); + imxrt_lpi2c_configure(&lpi2c1, &masterConfig); + rt_i2c_bus_device_register(&lpi2c1.parent, lpi2c1.device_name); +#endif +#if defined(RT_USING_I2C2) && defined(RT_USING_I2C2_BITOPS) + + static struct rt_i2c_bus_device i2c2_device; + + static const struct rt1052_i2c_bit_data _i2c2_bdata = + { + /* SCL */ {GPIO2, 4}, + /* SDA */ {GPIO2, 5}, + }; + + static const struct rt_i2c_bit_ops _i2c2_bit_ops = + { + (void *) &_i2c2_bdata, + gpio_set_sda, + gpio_set_scl, + gpio_get_sda, + gpio_get_scl, + + gpio_udelay, + + 50, + 1000 + }; + + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_04_GPIO2_IO04, 1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_04_GPIO2_IO04, 0xD8B0u); + IOMUXC_SetPinMux(IOMUXC_GPIO_B0_05_GPIO2_IO05, 1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_B0_05_GPIO2_IO05, 0xD8B0u); + + /* Enable touch panel controller */ + GPIO_PinInit(_i2c2_bdata.sda.base, _i2c2_bdata.sda.pin, &pin_config); + GPIO_PinInit(_i2c2_bdata.scl.base, _i2c2_bdata.scl.pin, &pin_config); + + GPIO_PortSet(_i2c2_bdata.sda.base, _i2c2_bdata.sda.pin); + GPIO_PortSet(_i2c2_bdata.scl.base, _i2c2_bdata.scl.pin); + + + i2c2_device.priv = (void *) &_i2c2_bit_ops; + rt_i2c_bit_add_bus(&i2c2_device, I2C2BUS_NAME); + +#elif defined(RT_USING_I2C2) && !defined(RT_USING_I2C2_BITOPS) + LPI2C_MasterGetDefaultConfig(&masterConfig); + imxrt_lpi2c_configure(&lpi2c2, &masterConfig); + rt_i2c_bus_device_register(&lpi2c2.parent, lpi2c2.device_name); +#endif +#if defined(RT_USING_I2C3) && defined(RT_USING_I2C3_BITOPS) + + static struct rt_i2c_bus_device i2c3_device; + + static const struct rt1052_i2c_bit_data _i2c3_bdata = + { + /* SCL */ {GPIO1, 23}, + /* SDA */ {GPIO1, 22}, + }; + + static const struct rt_i2c_bit_ops _i2c3_bit_ops = + { + (void *) &_i2c3_bdata, + gpio_set_sda, + gpio_set_scl, + gpio_get_sda, + gpio_get_scl, + + gpio_udelay, + + 50, + 1000 + }; + + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_GPIO1_IO23, 1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_07_GPIO1_IO23, 0xD8B0u); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_GPIO1_IO22, 1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_06_GPIO1_IO22, 0xD8B0u); + + /* Enable touch panel controller */ + GPIO_PinInit(_i2c3_bdata.sda.base, _i2c3_bdata.sda.pin, &pin_config); + GPIO_PinInit(_i2c3_bdata.scl.base, _i2c3_bdata.scl.pin, &pin_config); + + GPIO_PortSet(_i2c3_bdata.sda.base, _i2c3_bdata.sda.pin); + GPIO_PortSet(_i2c3_bdata.scl.base, _i2c3_bdata.scl.pin); + + + i2c3_device.priv = (void *) &_i2c3_bit_ops; + rt_i2c_bit_add_bus(&i2c3_device, I2C3BUS_NAME); + +#elif defined(RT_USING_I2C3) && !defined(RT_USING_I2C3_BITOPS) + LPI2C_MasterGetDefaultConfig(&masterConfig); + imxrt_lpi2c_configure(&lpi2c3, &masterConfig); + rt_i2c_bus_device_register(&lpi2c3.parent, lpi2c3.device_name); +#endif +#if defined(RT_USING_I2C4) && defined(RT_USING_I2C4_BITOPS) + + static struct rt_i2c_bus_device i2c4_device; + + static const struct rt1052_i2c_bit_data _i2c4_bdata = + { + /* SCL */ {GPIO4, 12}, + /* SDA */ {GPIO4, 11}, + }; + + static const struct rt_i2c_bit_ops _i2c4_bit_ops = + { + (void *) &_i2c4_bdata, + gpio_set_sda, + gpio_set_scl, + gpio_get_sda, + gpio_get_scl, + + gpio_udelay, + + 50, + 1000 + }; + + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_12_GPIO4_IO12, 1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_12_GPIO4_IO12, 0xD8B0u); + IOMUXC_SetPinMux(IOMUXC_GPIO_EMC_11_GPIO4_IO11, 1U); + IOMUXC_SetPinConfig(IOMUXC_GPIO_EMC_11_GPIO4_IO11, 0xD8B0u); + + /* Enable touch panel controller */ + GPIO_PinInit(_i2c4_bdata.sda.base, _i2c4_bdata.sda.pin, &pin_config); + GPIO_PinInit(_i2c4_bdata.scl.base, _i2c4_bdata.scl.pin, &pin_config); + + GPIO_PortSet(_i2c4_bdata.sda.base, _i2c4_bdata.sda.pin); + GPIO_PortSet(_i2c4_bdata.scl.base, _i2c4_bdata.scl.pin); + + + i2c4_device.priv = (void *) &_i2c4_bit_ops; + rt_i2c_bit_add_bus(&i2c4_device, I2C4BUS_NAME); + +#elif defined(RT_USING_I2C4) && !defined(RT_USING_I2C4_BITOPS) + LPI2C_MasterGetDefaultConfig(&masterConfig); + imxrt_lpi2c_configure(&lpi2c4, &masterConfig); + rt_i2c_bus_device_register(&lpi2c4.parent, lpi2c4.device_name); +#endif + + return 0; } @@ -197,7 +551,7 @@ static rt_device_t _i2c_find(const char *name) rt_device_t dev; dev = rt_device_find(name); - if (!dev) + if (!dev) { rt_kprintf("search device failed: %s\n", name); return RT_NULL; @@ -210,7 +564,7 @@ static rt_device_t _i2c_find(const char *name) } rt_kprintf("open i2c bus: %s\n", name); - + return dev; } @@ -231,7 +585,7 @@ static void _search_i2c_device(rt_device_t dev, uint8_t cmd) for (int i = 0; i <= 0x7f; i++) { int len; - + msgs[0].addr = i; msgs[1].addr = i; len = rt_i2c_transfer((struct rt_i2c_bus_device *)dev, msgs, 2); @@ -239,9 +593,9 @@ static void _search_i2c_device(rt_device_t dev, uint8_t cmd) { count++; rt_kprintf("add:%02X transfer success, id: %02X\n", i, buf); - } + } } - + rt_kprintf("i2c device: %d\n", count); } @@ -253,14 +607,16 @@ static int i2c_test(const char *name, uint8_t cmd) rt_kprintf("search i2c device faild\n"); return -1; } - + _search_i2c_device(dev, cmd); - + rt_device_close(dev); - + return 0; } -FINSH_FUNCTION_EXPORT(i2c_test, e.g: i2c_test("i2c0", 0xA3)); +FINSH_FUNCTION_EXPORT(i2c_test, e.g: i2c_test("i2c1", 0xA3)); #endif #endif /* RT_USING_I2C */ + + diff --git a/bsp/imxrt1052-evk/drivers/drv_i2c.h b/bsp/imxrt1052-evk/drivers/drv_i2c.h new file mode 100644 index 0000000000..4743225c37 --- /dev/null +++ b/bsp/imxrt1052-evk/drivers/drv_i2c.h @@ -0,0 +1,34 @@ +/* + * File : drv_i2c.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2018-03-24 LaiYiKeTang the first version + */ + +#ifndef __DRVI2C_H__ +#define __DRVI2C_H__ + +#include +#include +#include +#include "board.h" +struct rt1052_i2c_bus +{ + struct rt_i2c_bus_device parent; + LPI2C_Type *I2C; + struct rt_i2c_msg *msg; + rt_uint32_t msg_cnt; + volatile rt_uint32_t msg_ptr; + volatile rt_uint32_t dptr; + char *device_name; +}; + +#endif + -- GitLab