Browse Source

修改i2c和rtc驱动 (#6166)

* 修改I2C和RTC 驱动
NationsHuanghanbin 3 years ago
parent
commit
2ece5c277d

+ 3 - 0
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']

+ 3 - 1
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']

+ 169 - 78
bsp/n32/libraries/n32_drivers/drv_i2c.c

@@ -50,97 +50,193 @@
 #endif
 #include <rtdbg.h>
 
-#define I2CT_FLAG_TIMEOUT ((uint32_t)0x1000)
-#define I2CT_LONG_TIMEOUT ((uint32_t)(10 * I2CT_FLAG_TIMEOUT))
-
-
 
 #ifdef RT_USING_I2C_BITOPS
+static const struct n32_soft_i2c_config soft_i2c_config[] =
+{
+#ifdef BSP_USING_I2C1
+    I2C1_BUS_CONFIG,
+#endif
 
-/*user can change this*/
-#define I2C_BUS_NAME  "i2c1"
+#ifdef BSP_USING_I2C2
+    I2C2_BUS_CONFIG,
+#endif
 
-/*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
+#ifdef BSP_USING_I2C3
+    I2C3_BUS_CONFIG,
+#endif
 
-struct n32_i2c_bit_data
-{
-    struct
-    {
-        rt_uint32_t clk;
-        GPIO_Module* port;
-        rt_uint32_t pin;
-    }scl, sda;
+#ifdef BSP_USING_I2C4
+    I2C4_BUS_CONFIG,
+#endif
 };
 
-static void gpio_set_sda(void *data, rt_int32_t state)
+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_i2c_bit_data* bd = data;
+    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 =
+{
+    .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
+};
+
+
+/**
+*\*\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)
 {
-    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);
+    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);
+        }
+    }
 
-    GPIO_SetBits((GPIO_Module*)bd->sda.port, bd->sda.pin);
-    GPIO_SetBits((GPIO_Module*)bd->scl.port, bd->scl.pin);
+    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
-    {
-        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},
-        };
 
-        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
-        };
+	  rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct n32_i2c);
+    rt_err_t result;
+
+    for(int i = 0; i < obj_num; i++)
+    {
+        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;
 
-        drv_i2c_gpio_init(&_i2c_bdata);
+        n32_i2c_gpio_init(&i2c_obj[i]);
+        result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name);
 
-        i2c_device.priv = (void *)&_i2c_bit_ops;
-        rt_i2c_bit_add_bus(&i2c_device, I2C_BUS_NAME);
-    } 
+        RT_ASSERT(result == RT_EOK);
+        n32_i2c_bus_unlock(&soft_i2c_config[i]);
 
-#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);
 

+ 55 - 2
bsp/n32/libraries/n32_drivers/drv_i2c.h

@@ -36,7 +36,60 @@
 #ifndef __DRV_I2C__
 #define __DRV_I2C__
 
-#include "i2c.h"
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+
+/* 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__ */

+ 4 - 7
bsp/n32/libraries/n32_drivers/drv_rtc.c

@@ -32,12 +32,9 @@
  *
  * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
  */
-#include <rtthread.h>
-#include <n32g45x.h>
 #include "board.h"
-#include "time.h"
-#include "rtdef.h"
-#include "rtc.h"
+#include <sys/time.h>
+#include <rtdevice.h>
 
 #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 */

+ 3 - 2
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

+ 29 - 18
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