From 2ece5c277d9d891e688f15fe497e948bc4d0ef8a Mon Sep 17 00:00:00 2001 From: NationsHuanghanbin <95665874+NationsHuanghanbin@users.noreply.github.com> Date: Fri, 15 Jul 2022 13:36:32 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9i2c=E5=92=8Crtc=E9=A9=B1?= =?UTF-8?q?=E5=8A=A8=20(#6166)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修改I2C和RTC 驱动 --- .../N32G45x_Firmware_Library/SConscript | 3 + bsp/n32/libraries/n32_drivers/SConscript | 4 +- bsp/n32/libraries/n32_drivers/drv_i2c.c | 253 ++++++++++++------ bsp/n32/libraries/n32_drivers/drv_i2c.h | 57 +++- bsp/n32/libraries/n32_drivers/drv_rtc.c | 11 +- bsp/n32/n32g45xvl-stb/.config | 5 +- bsp/n32/n32g45xvl-stb/board/Kconfig | 47 ++-- 7 files changed, 269 insertions(+), 111 deletions(-) diff --git a/bsp/n32/libraries/N32G45x_Firmware_Library/SConscript b/bsp/n32/libraries/N32G45x_Firmware_Library/SConscript index f31797233c..bff005385c 100644 --- a/bsp/n32/libraries/N32G45x_Firmware_Library/SConscript +++ b/bsp/n32/libraries/N32G45x_Firmware_Library/SConscript @@ -46,6 +46,9 @@ if GetDepend(['RT_USING_RTC']): if GetDepend(['RT_USING_WDT']): src += ['n32g45x_std_periph_driver/src/n32g45x_wwdg.c'] src += ['n32g45x_std_periph_driver/src/n32g45x_iwdg.c'] + +if GetDepend(['BSP_USING_RTC']): + src += ['n32g45x_std_periph_driver/src/n32g45x_bkp.c'] if GetDepend(['RT_USING_SDIO']): src += ['n32g45x_std_periph_driver/src/n32g45x_sdio.c'] diff --git a/bsp/n32/libraries/n32_drivers/SConscript b/bsp/n32/libraries/n32_drivers/SConscript index bb5f92d0f3..5340b2eb3a 100644 --- a/bsp/n32/libraries/n32_drivers/SConscript +++ b/bsp/n32/libraries/n32_drivers/SConscript @@ -39,7 +39,9 @@ if GetDepend(['RT_USING_DAC']): if GetDepend(['RT_USING_CAN']): src += ['drv_can.c'] - + +if GetDepend(['BSP_USING_RTC']): + src += ['drv_rtc.c'] if GetDepend(['BSP_USING_WDT']): src += ['drv_wdt.c'] diff --git a/bsp/n32/libraries/n32_drivers/drv_i2c.c b/bsp/n32/libraries/n32_drivers/drv_i2c.c index 5a4faf4b4a..a4f8e3e056 100644 --- a/bsp/n32/libraries/n32_drivers/drv_i2c.c +++ b/bsp/n32/libraries/n32_drivers/drv_i2c.c @@ -50,97 +50,193 @@ #endif #include -#define I2CT_FLAG_TIMEOUT ((uint32_t)0x1000) -#define I2CT_LONG_TIMEOUT ((uint32_t)(10 * I2CT_FLAG_TIMEOUT)) - - #ifdef RT_USING_I2C_BITOPS - -/*user can change this*/ -#define I2C_BUS_NAME "i2c1" - -/*user should change this to adapt specific board*/ -#define I2C_SCL_PIN GPIO_PIN_8 -#define I2C_SCL_PORT GPIOB -#define I2C_SCL_CLK RCC_APB2_PERIPH_GPIOB -#define I2C_SDA_PIN GPIO_PIN_9 -#define I2C_SDA_PORT GPIOB -#define I2C_SDA_CLK RCC_APB2_PERIPH_GPIOB - -struct n32_i2c_bit_data +static const struct n32_soft_i2c_config soft_i2c_config[] = { - struct - { - rt_uint32_t clk; - GPIO_Module* port; - rt_uint32_t pin; - }scl, sda; +#ifdef BSP_USING_I2C1 + I2C1_BUS_CONFIG, +#endif + +#ifdef BSP_USING_I2C2 + I2C2_BUS_CONFIG, +#endif + +#ifdef BSP_USING_I2C3 + I2C3_BUS_CONFIG, +#endif + +#ifdef BSP_USING_I2C4 + I2C4_BUS_CONFIG, +#endif }; -static void gpio_set_sda(void *data, rt_int32_t state) -{ - struct n32_i2c_bit_data* bd = data; +static struct n32_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])]; +/** +*\*\name n32_i2c_gpio_init +*\*\fun Initializes the i2c pin. +*\*\param i2c dirver class +*\*\return none +**/ +static void n32_i2c_gpio_init(struct n32_i2c *i2c) +{ + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)i2c->ops.data; + + rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD); + rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD); + + rt_pin_write(cfg->scl, PIN_HIGH); + rt_pin_write(cfg->sda, PIN_HIGH); +} + +/** +*\*\name n32_set_sda +*\*\fun sets the sda pin. +*\*\param data config class +*\*\param state sda pin state +*\*\return none +**/ +static void n32_set_sda(void *data, rt_int32_t state) +{ + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data; if (state) { - GPIO_SetBits((GPIO_Module*)bd->sda.port, bd->sda.pin); + rt_pin_write(cfg->sda, PIN_HIGH); } else { - GPIO_ResetBits((GPIO_Module*)bd->sda.port, bd->sda.pin); + rt_pin_write(cfg->sda, PIN_LOW); } } -static void gpio_set_scl(void *data, rt_int32_t state) +/** +*\*\name n32_set_scl +*\*\fun sets the scl pin. +*\*\param data config class +*\*\param state scl pin state +*\*\return none +**/ +static void n32_set_scl(void *data, rt_int32_t state) { - struct n32_i2c_bit_data* bd = data; + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data; if (state) { - GPIO_SetBits((GPIO_Module*)bd->scl.port, bd->scl.pin); + rt_pin_write(cfg->scl, PIN_HIGH); } else { - GPIO_ResetBits((GPIO_Module*)bd->scl.port, bd->scl.pin); + rt_pin_write(cfg->scl, PIN_LOW); } } -static rt_int32_t gpio_get_sda(void *data) +/** +*\*\name n32_get_sda +*\*\fun gets the sda pin state. +*\*\param data config class +*\*\return sda pin state +**/ +static rt_int32_t n32_get_sda(void *data) { - struct n32_i2c_bit_data* bd = data; - - return GPIO_ReadInputDataBit((GPIO_Module*)bd->sda.port, bd->sda.pin); + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data; + return rt_pin_read(cfg->sda); } -static rt_int32_t gpio_get_scl(void *data) +/** +*\*\name n32_get_scl +*\*\fun gets the scl pin state. +*\*\param data config class +*\*\return scl pin state +**/ +static rt_int32_t n32_get_scl(void *data) { - struct n32_i2c_bit_data* bd = data; - - return GPIO_ReadInputDataBit((GPIO_Module*)bd->scl.port, bd->scl.pin); + struct n32_soft_i2c_config* cfg = (struct n32_soft_i2c_config*)data; + return rt_pin_read(cfg->scl); } -static void gpio_udelay(rt_uint32_t us) + +/** +*\*\name n32_udelay +*\*\fun The time delay function. +*\*\param us +*\*\return none +**/ +static void n32_udelay(rt_uint32_t us) { - RCC_ClocksType* RCC_Clocks = {0}; - RCC_GetClocksFreqValue(RCC_Clocks); - int i = ( RCC_Clocks->SysclkFreq / 4000000 * us); - while(i) + rt_uint32_t ticks; + rt_uint32_t told, tnow, tcnt = 0; + rt_uint32_t reload = SysTick->LOAD; + + ticks = us * reload / (1000000 / RT_TICK_PER_SECOND); + told = SysTick->VAL; + + while(1) { - i--; + tnow = SysTick->VAL; + if(tnow != told) + { + if(tnow < told) + { + tcnt += told - tnow; + } + else + { + tcnt += reload - tnow + told; + } + told = tnow; + + if(tcnt >= ticks) + { + break; + } + } } } -static void drv_i2c_gpio_init(const struct n32_i2c_bit_data* bd) +static const struct rt_i2c_bit_ops n32_bit_ops_default = { - RCC_EnableAPB2PeriphClk(bd->sda.clk | bd->scl.clk, ENABLE); - GPIOInit((GPIO_Module*)bd->sda.port, GPIO_Mode_Out_OD, GPIO_Speed_10MHz, bd->sda.pin); - GPIOInit((GPIO_Module*)bd->scl.port, GPIO_Mode_Out_OD, GPIO_Speed_10MHz, bd->scl.pin); + .data = RT_NULL, + .set_sda = n32_set_sda, + .set_scl = n32_set_scl, + .get_sda = n32_get_sda, + .get_scl = n32_get_scl, + .udelay = n32_udelay, + .delay_us = 1, + .timeout = 100 +}; - GPIO_SetBits((GPIO_Module*)bd->sda.port, bd->sda.pin); - GPIO_SetBits((GPIO_Module*)bd->scl.port, bd->scl.pin); + +/** +*\*\name n32_i2c_bus_unlock +*\*\fun If i2c is locked, this function will unlock it. +*\*\param cfg +*\*\return RT_EOK indicates successful unlock +**/ +static rt_err_t n32_i2c_bus_unlock(const struct n32_soft_i2c_config *cfg) +{ + rt_int32_t i = 0; + + if(PIN_LOW == rt_pin_read(cfg->sda)) + { + while(i++ < 9) + { + rt_pin_write(cfg->scl, PIN_HIGH); + n32_udelay(100); + rt_pin_write(cfg->scl, PIN_LOW); + n32_udelay(100); + } + } + + if(PIN_LOW == rt_pin_read(cfg->sda)) + { + return -RT_ERROR; + } + + return RT_EOK; } +#endif /* RT_USING_I2C_BITOPS */ -#else /* use hardware i2c */ +#ifdef RT_USING_HARDWARE_I2C static uint32_t I2CTimeout = I2CT_LONG_TIMEOUT; @@ -323,40 +419,35 @@ static const struct rt_i2c_bus_device_ops i2c_ops = RT_NULL }; -#endif /* RT_USING_I2C_BITOPS */ +#endif /* RT_USING_HARDWARE_I2C */ int rt_hw_i2c_init(void) { #ifdef RT_USING_I2C_BITOPS + + rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct n32_i2c); + rt_err_t result; + + for(int i = 0; i < obj_num; i++) { - static struct rt_i2c_bus_device i2c_device; - static const struct n32_i2c_bit_data _i2c_bdata = - { - /* SCL */ - { I2C_SCL_CLK, I2C_SCL_PORT, I2C_SCL_PIN}, - /* SDA */ - { I2C_SDA_CLK, I2C_SDA_PORT, I2C_SDA_PIN}, - }; + i2c_obj[i].ops = n32_bit_ops_default; + i2c_obj[i].ops.data = (void*)&soft_i2c_config[i]; + i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops; - static const struct rt_i2c_bit_ops _i2c_bit_ops = - { - (void*)&_i2c_bdata, - gpio_set_sda, - gpio_set_scl, - gpio_get_sda, - gpio_get_scl, - gpio_udelay, - 1, - 100 - }; + n32_i2c_gpio_init(&i2c_obj[i]); + result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name); - drv_i2c_gpio_init(&_i2c_bdata); + RT_ASSERT(result == RT_EOK); + n32_i2c_bus_unlock(&soft_i2c_config[i]); - i2c_device.priv = (void *)&_i2c_bit_ops; - rt_i2c_bit_add_bus(&i2c_device, I2C_BUS_NAME); - } - -#else /* register hardware I2C */ + rt_kprintf("software simulation %s init done, pin scl: %d, pin sda %d", + soft_i2c_config[i].bus_name, + soft_i2c_config[i].scl, + soft_i2c_config[i].sda); + } +#endif /* RT_USING_I2C_BITOPS */ + +#ifdef RT_USING_HARDWARE_I2C #ifdef BSP_USING_I2C1 #define I2C1_SPEED 400000 @@ -475,9 +566,9 @@ int rt_hw_i2c_init(void) rt_i2c_bus_device_register(&i2c_bus4.parent, "i2c4"); #endif -#endif /* RT_USING_I2C_BITOPS */ +#endif /* RT_USING_HARDWARE_I2C */ - return 0; + return RT_EOK; } INIT_DEVICE_EXPORT(rt_hw_i2c_init); diff --git a/bsp/n32/libraries/n32_drivers/drv_i2c.h b/bsp/n32/libraries/n32_drivers/drv_i2c.h index 9433dd4083..db3aab22c1 100644 --- a/bsp/n32/libraries/n32_drivers/drv_i2c.h +++ b/bsp/n32/libraries/n32_drivers/drv_i2c.h @@ -36,7 +36,60 @@ #ifndef __DRV_I2C__ #define __DRV_I2C__ -#include "i2c.h" +#include +#include +#include + +/* n32 config class */ +struct n32_soft_i2c_config +{ + rt_uint8_t scl; + rt_uint8_t sda; + const char *bus_name; +}; + +/* n32 i2c dirver class */ +struct n32_i2c +{ + struct rt_i2c_bit_ops ops; + struct rt_i2c_bus_device i2c2_bus; +}; + +#ifdef BSP_USING_I2C1 +#define I2C1_BUS_CONFIG \ + { \ + .scl = BSP_I2C1_SCL_PIN, \ + .sda = BSP_I2C1_SDA_PIN, \ + .bus_name = "i2c1", \ + } +#endif + +#ifdef BSP_USING_I2C2 +#define I2C2_BUS_CONFIG \ + { \ + .scl = BSP_I2C2_SCL_PIN, \ + .sda = BSP_I2C2_SDA_PIN, \ + .bus_name = "i2c2", \ + } +#endif + +#ifdef BSP_USING_I2C3 +#define I2C3_BUS_CONFIG \ + { \ + .scl = BSP_I2C3_SCL_PIN, \ + .sda = BSP_I2C3_SDA_PIN, \ + .bus_name = "i2c3", \ + } +#endif + +#ifdef BSP_USING_I2C4 +#define I2C4_BUS_CONFIG \ + { \ + .scl = BSP_I2C4_SCL_PIN, \ + .sda = BSP_I2C4_SDA_PIN, \ + .bus_name = "i2c4", \ + } +#endif struct rt_i2c_bus { @@ -46,4 +99,4 @@ struct rt_i2c_bus int rt_hw_i2c_init(void); -#endif +#endif /* __DRV_I2C__ */ diff --git a/bsp/n32/libraries/n32_drivers/drv_rtc.c b/bsp/n32/libraries/n32_drivers/drv_rtc.c index 876cb4d9ae..e846b273bd 100644 --- a/bsp/n32/libraries/n32_drivers/drv_rtc.c +++ b/bsp/n32/libraries/n32_drivers/drv_rtc.c @@ -32,12 +32,9 @@ * * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved. */ -#include -#include #include "board.h" -#include "time.h" -#include "rtdef.h" -#include "rtc.h" +#include +#include #ifdef BSP_USING_RTC @@ -105,8 +102,8 @@ static rt_err_t rt_rtc_config(void) RTC_InitType RTC_InitStructure; /* Configure the RTC data register and RTC prescaler */ - RTC_InitStructure.RTC_AsynchPrediv = 128; - RTC_InitStructure.RTC_SynchPrediv = 128; + RTC_InitStructure.RTC_AsynchPrediv = AsynchPrediv; + RTC_InitStructure.RTC_SynchPrediv = SynchPrediv; RTC_InitStructure.RTC_HourFormat = RTC_24HOUR_FORMAT; /* Check on RTC init */ diff --git a/bsp/n32/n32g45xvl-stb/.config b/bsp/n32/n32g45xvl-stb/.config index 40b6e6350d..a77d752108 100644 --- a/bsp/n32/n32g45xvl-stb/.config +++ b/bsp/n32/n32g45xvl-stb/.config @@ -224,6 +224,7 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # # IoT - internet of things # + # CONFIG_PKG_USING_LWIP is not set # CONFIG_PKG_USING_LORAWAN_DRIVER is not set # CONFIG_PKG_USING_PAHOMQTT is not set @@ -237,7 +238,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8 # CONFIG_PKG_USING_WEBTERMINAL is not set # CONFIG_PKG_USING_LIBMODBUS is not set # CONFIG_PKG_USING_FREEMODBUS is not set -# CONFIG_PKG_USING_NANOPB is not set # # Wi-Fi @@ -689,7 +689,8 @@ CONFIG_BSP_USING_USART1=y # CONFIG_BSP_USING_UART6 is not set # CONFIG_BSP_USING_UART7 is not set # CONFIG_BSP_USING_SPI is not set -# CONFIG_BSP_USING_I2C is not set +# CONFIG_BSP_USING_I2C1 is not set +# CONFIG_BSP_USING_RTC is not set # CONFIG_BSP_USING_WDT is not set # CONFIG_BSP_USING_HWTIMER is not set # CONFIG_BSP_USING_ADC is not set diff --git a/bsp/n32/n32g45xvl-stb/board/Kconfig b/bsp/n32/n32g45xvl-stb/board/Kconfig index 0aac4afa40..8d7f1007bd 100644 --- a/bsp/n32/n32g45xvl-stb/board/Kconfig +++ b/bsp/n32/n32g45xvl-stb/board/Kconfig @@ -75,27 +75,38 @@ menu "On-chip Peripheral Drivers" endif - menuconfig BSP_USING_I2C - bool "Enable I2C BUS" + menuconfig BSP_USING_I2C1 + bool "Enable I2C1 BUS (software simulation)" default n select RT_USING_I2C - if BSP_USING_I2C - config BSP_USING_I2C1 - bool "Enable I2C1" - default n - - config BSP_USING_I2C2 - bool "Enable I2C2" - default n - - config BSP_USING_I2C3 - bool "Enable I2C3" - default n - - config BSP_USING_I2C4 - bool "Enable I2C4" - default n + select RT_USING_I2C_BITOPS + select RT_USING_PIN + if BSP_USING_I2C1 + config BSP_I2C1_SCL_PIN + int "i2c1 scl pin number" + range 0 111 + default 22 + config BSP_I2C1_SDA_PIN + int "I2C1 sda pin number" + range 0 111 + default 23 + endif + + menuconfig BSP_USING_RTC + bool "Enable RTC" + select RT_USING_RTC + default n + if BSP_USING_RTC + choice + prompt "Select clock source" + default BSP_RTC_USING_LSE + config BSP_RTC_USING_LSE + bool "RTC USING LSE" + + config BSP_RTC_USING_LSI + bool "RTC USING LSI" + endchoice endif config BSP_USING_WDT