Browse Source

[bsp][bouffalo] add pwm & rtc & wdt devices (#7122)

WCX 2 years ago
parent
commit
fb09316cb5

+ 13 - 12
bsp/bouffalo_lab/bl808/m0/.config

@@ -84,7 +84,9 @@ CONFIG_RT_USING_CONSOLE=y
 CONFIG_RT_CONSOLEBUF_SIZE=128
 CONFIG_RT_CONSOLEBUF_SIZE=128
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
 CONFIG_RT_CONSOLE_DEVICE_NAME="uart0"
 CONFIG_RT_VER_NUM=0x50000
 CONFIG_RT_VER_NUM=0x50000
+# CONFIG_RT_USING_STDC_ATOMIC is not set
 # CONFIG_RT_USING_CACHE is not set
 # CONFIG_RT_USING_CACHE is not set
+# CONFIG_RT_USING_HW_ATOMIC is not set
 # CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
 # CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE is not set
 # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
 # CONFIG_ARCH_CPU_STACK_GROWS_UPWARD is not set
 # CONFIG_RT_USING_CPU_FFS is not set
 # CONFIG_RT_USING_CPU_FFS is not set
@@ -141,15 +143,17 @@ CONFIG_RT_USING_PIN=y
 # CONFIG_RT_USING_NULL is not set
 # CONFIG_RT_USING_NULL is not set
 # CONFIG_RT_USING_ZERO is not set
 # CONFIG_RT_USING_ZERO is not set
 # CONFIG_RT_USING_RANDOM is not set
 # CONFIG_RT_USING_RANDOM is not set
-# CONFIG_RT_USING_PWM is not set
+CONFIG_RT_USING_PWM=y
 # CONFIG_RT_USING_MTD_NOR is not set
 # CONFIG_RT_USING_MTD_NOR is not set
 # CONFIG_RT_USING_MTD_NAND is not set
 # CONFIG_RT_USING_MTD_NAND is not set
 # CONFIG_RT_USING_PM is not set
 # CONFIG_RT_USING_PM is not set
 # CONFIG_RT_USING_FDT is not set
 # CONFIG_RT_USING_FDT is not set
-# CONFIG_RT_USING_RTC is not set
+CONFIG_RT_USING_RTC=y
+# CONFIG_RT_USING_ALARM is not set
+# CONFIG_RT_USING_SOFT_RTC is not set
 # CONFIG_RT_USING_SDIO is not set
 # CONFIG_RT_USING_SDIO is not set
 # CONFIG_RT_USING_SPI is not set
 # CONFIG_RT_USING_SPI is not set
-# CONFIG_RT_USING_WDT is not set
+CONFIG_RT_USING_WDT=y
 # CONFIG_RT_USING_AUDIO is not set
 # CONFIG_RT_USING_AUDIO is not set
 # CONFIG_RT_USING_SENSOR is not set
 # CONFIG_RT_USING_SENSOR is not set
 # CONFIG_RT_USING_TOUCH is not set
 # CONFIG_RT_USING_TOUCH is not set
@@ -912,7 +916,6 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # Display
 # Display
 #
 #
 # CONFIG_PKG_USING_ARDUINO_U8G2 is not set
 # CONFIG_PKG_USING_ARDUINO_U8G2 is not set
-# CONFIG_PKG_USING_ARDUINO_U8GLIB_ARDUINO is not set
 # CONFIG_PKG_USING_SEEED_TM1637 is not set
 # CONFIG_PKG_USING_SEEED_TM1637 is not set
 
 
 #
 #
@@ -942,17 +945,10 @@ CONFIG_RT_LIBC_DEFAULT_TIMEZONE=8
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
 # CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
 # CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
 # CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set
 
 
 #
 #
 # Other
 # Other
 #
 #
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set
-# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set
-# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set
 
 
 #
 #
 # Signal IO
 # Signal IO
@@ -976,7 +972,7 @@ CONFIG_BL808_CORE_M0=y
 #
 #
 # General Drivers Configuration
 # General Drivers Configuration
 #
 #
-# CONFIG_BSP_USING_GPIO is not set
+CONFIG_BSP_USING_GPIO=y
 
 
 #
 #
 # General Purpose UARTs
 # General Purpose UARTs
@@ -989,3 +985,8 @@ CONFIG_UART0_TX_USING_GPIO14=y
 CONFIG_UART0_RX_USING_GPIO15=y
 CONFIG_UART0_RX_USING_GPIO15=y
 # CONFIG_UART0_RX_USING_GPIO22 is not set
 # CONFIG_UART0_RX_USING_GPIO22 is not set
 # CONFIG_UART0_RX_USING_GPIO23 is not set
 # CONFIG_UART0_RX_USING_GPIO23 is not set
+# CONFIG_BSP_USING_UART1 is not set
+# CONFIG_BSP_USING_UART2 is not set
+# CONFIG_BSP_USING_RTC is not set
+# CONFIG_BSP_USING_WDT is not set
+# CONFIG_BSP_USING_PWM is not set

+ 70 - 0
bsp/bouffalo_lab/bl808/m0/applications/pwm_led_sample.c

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2023-3-27     wcx1024979076   first version.
+ */
+/*
+ * 程序清单:这是一个 PWM 设备使用例程
+ * 例程导出了 pwm_led_sample 命令到控制终端
+ * 命令调用格式:pwm_led_sample
+ * 程序功能:通过 PWM 设备控制 LED 灯的亮度,可以看到LED不停的由暗变到亮,然后又从亮变到暗。
+*/
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef RT_USING_PWM
+
+#define LED_PIN_NUM          8     /* LED PIN脚编号,查看驱动文件drv_gpio.c确定 */
+#define PWM_DEV_NAME        "pwm"  /* PWM设备名称 */
+#define PWM_DEV_CHANNEL      0       /* PWM通道 */
+struct rt_device_pwm *pwm_dev;      /* PWM设备句柄 */
+static int pwm_led_sample(int argc, char *argv[])
+{
+    rt_uint32_t period, pulse, dir;
+    period = 500000;    /* 周期为0.5ms,单位为纳秒ns */
+    dir = 1;            /* PWM脉冲宽度值的增减方向 */
+    pulse = 0;          /* PWM脉冲宽度值,单位为纳秒ns */
+
+    /* 查找设备 */
+    pwm_dev = (struct rt_device_pwm *)rt_device_find(PWM_DEV_NAME);
+    if (pwm_dev == RT_NULL)
+    {
+        rt_kprintf("pwm sample run failed! can't find %s device!\n", PWM_DEV_NAME);
+        return -RT_ERROR;
+    }
+    /* 设置PWM周期和脉冲宽度默认值 */
+    rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
+    /* 使能设备 */
+    rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);
+
+    while (1)
+    {
+        rt_thread_mdelay(50);
+        if (dir)
+        {
+            pulse += 400000;      /* 从0值开始每次增加5000ns */
+        }
+        else
+        {
+            pulse -= 400000;      /* 从最大值开始每次减少5000ns */
+        }
+        if (pulse >= period)
+        {
+            dir = 0;
+        }
+        if (0 == pulse)
+        {
+            dir = 1;
+        }
+        /* 设置PWM周期和脉冲宽度 */
+        rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL, period, pulse);
+    }
+}
+/* 导出到 msh 命令列表中 */
+MSH_CMD_EXPORT(pwm_led_sample, pwm sample);
+
+#endif   /* RT_USING_PWM */

+ 82 - 0
bsp/bouffalo_lab/bl808/m0/applications/wdt_sample.c

@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author         Notes
+ * 2023-3-27     wcx1024979076  first version.
+ */
+/*
+ * 程序清单:这是一个独立看门狗设备使用例程
+ * 例程导出了 wdt_sample 命令到控制终端
+ * 命令调用格式:wdt_sample wdt
+ * 命令解释:命令第二个参数是要使用的看门狗设备名称,为空则使用例程默认的看门狗设备。
+ * 程序功能:程序通过设备名称查找看门狗设备,然后初始化设备并设置看门狗设备溢出时间。
+ *           然后设置空闲线程回调函数,在回调函数里会喂狗。
+*/
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#ifdef RT_USING_WDT
+
+#define WDT_DEVICE_NAME    "wdt"    /* 看门狗设备名称 */
+
+static rt_device_t wdg_dev;         /* 看门狗设备句柄 */
+
+static void idle_hook(void)
+{
+    /* 在空闲线程的回调函数里喂狗 */
+    rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
+    rt_kprintf("feed the dog!\n ");
+}
+
+static int wdt_sample(int argc, char *argv[])
+{
+    rt_err_t ret = RT_EOK;
+    rt_uint32_t timeout = 1;        /* 溢出时间,单位:秒 */
+    char device_name[RT_NAME_MAX];
+
+    /* 判断命令行参数是否给定了设备名称 */
+    if (argc == 2)
+    {
+        rt_strncpy(device_name, argv[1], RT_NAME_MAX);
+    }
+    else
+    {
+        rt_strncpy(device_name, WDT_DEVICE_NAME, RT_NAME_MAX);
+    }
+    /* 根据设备名称查找看门狗设备,获取设备句柄 */
+    wdg_dev = rt_device_find(device_name);
+    if (!wdg_dev)
+    {
+        rt_kprintf("find %s failed!\n", device_name);
+        return -RT_ERROR;
+    }
+    /* 初始化设备 */
+    rt_device_init(wdg_dev);
+
+    /* 设置看门狗溢出时间 */
+    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("set %s timeout failed!\n", device_name);
+        return -RT_ERROR;
+    }
+
+    /* 启动看门狗 */
+    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);
+    if (ret != RT_EOK)
+    {
+        rt_kprintf("start %s failed!\n", device_name);
+        return -RT_ERROR;
+    }
+    /* 设置空闲线程回调函数 */
+    rt_thread_idle_sethook(idle_hook);
+    return ret;
+}
+/* 导出到 msh 命令列表中 */
+MSH_CMD_EXPORT(wdt_sample, wdt sample);
+
+#endif  /* RT_USING_WDT */

+ 1 - 2
bsp/bouffalo_lab/bl808/m0/rtconfig.h

@@ -83,7 +83,6 @@
 #define RT_SERIAL_USING_DMA
 #define RT_SERIAL_USING_DMA
 #define RT_SERIAL_RB_BUFSZ 64
 #define RT_SERIAL_RB_BUFSZ 64
 #define RT_USING_PIN
 #define RT_USING_PIN
-
 /* Using USB */
 /* Using USB */
 
 
 
 
@@ -219,7 +218,6 @@
 
 
 /* Other */
 /* Other */
 
 
-
 /* Signal IO */
 /* Signal IO */
 
 
 
 
@@ -230,6 +228,7 @@
 
 
 /* General Drivers Configuration */
 /* General Drivers Configuration */
 
 
+#define BSP_USING_GPIO
 
 
 /* General Purpose UARTs */
 /* General Purpose UARTs */
 
 

+ 32 - 0
bsp/bouffalo_lab/libraries/rt_drivers/Kconfig

@@ -121,5 +121,37 @@ menu "General Drivers Configuration"
 
 
     endmenu
     endmenu
 
 
+    menuconfig BSP_USING_RTC
+        bool "Enable RTC"
+        select RT_USING_RTC
+        default n
+
+    config BSP_USING_WDT
+        bool "Enable Watchdog Timer"
+        select RT_USING_WDT
+        default n
+
+    menuconfig BSP_USING_PWM
+        bool "Enable PWM"
+        default n
+        select RT_USING_PWM
+        if BSP_USING_PWM
+            config BSP_USING_PWM0
+                bool "Enable PWM0"
+                default n
+
+            config BSP_USING_PWM1
+                bool "Enable PWM1"
+                default n
+
+            config BSP_USING_PWM2
+                bool "Enable PWM2"
+                default n
+
+            config BSP_USING_PWM3
+                bool "Enable PWM3"
+                default n
+        endif
+
 endmenu
 endmenu
 
 

+ 9 - 0
bsp/bouffalo_lab/libraries/rt_drivers/SConscript

@@ -12,6 +12,15 @@ if GetDepend('BSP_USING_GPIO'):
 if  GetDepend('BSP_USING_I2C'):
 if  GetDepend('BSP_USING_I2C'):
     src += ['drv_i2c.c']
     src += ['drv_i2c.c']
 
 
+if GetDepend('BSP_USING_RTC'):
+    src += ['drv_rtc.c']
+
+if GetDepend('RT_USING_PWM'):
+    src += ['drv_pwm.c']
+
+if GetDepend('RT_USING_WDT'):
+    src += ['drv_wdt.c']
+
 group = DefineGroup('rt_drivers', src, depend = [''], CPPPATH = CPPPATH)
 group = DefineGroup('rt_drivers', src, depend = [''], CPPPATH = CPPPATH)
 
 
 objs = [group]
 objs = [group]

+ 140 - 0
bsp/bouffalo_lab/libraries/rt_drivers/drv_pwm.c

@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date             Author           Notes
+ * 2023-03-12       wcx1024979076    first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "drv_pwm.h"
+
+#define DBG_LEVEL   DBG_LOG
+#include <rtdbg.h>
+#define LOG_TAG "DRV.PWM"
+
+#ifdef BSP_USING_PWM
+
+static rt_err_t _pwm_set(rt_uint8_t channel, struct rt_pwm_configuration *configuration)
+{
+    struct bflb_device_s* pwm = bflb_device_get_by_name("pwm_v2_0");
+
+    uint32_t period_hz = 1000000000 / configuration->period;
+
+    struct bflb_pwm_v2_config_s pwm_config;
+
+    pwm_config.clk_source = BFLB_SYSTEM_XCLK;
+
+    pwm_config.clk_div = 40;
+
+    pwm_config.period = 1000000 / period_hz;
+
+    bflb_pwm_v2_init(pwm, &pwm_config);
+
+    struct bflb_pwm_v2_channel_config_s pwm_ch_config = {
+        .positive_polarity = PWM_POLARITY_ACTIVE_HIGH,
+        .negative_polarity = PWM_POLARITY_ACTIVE_HIGH,
+        .positive_stop_state = PWM_STATE_INACTIVE,
+        .negative_stop_state = PWM_STATE_ACTIVE,
+        .positive_brake_state = PWM_STATE_INACTIVE,
+        .negative_brake_state = PWM_STATE_INACTIVE,
+        .dead_time = 0,
+    };
+
+    bflb_pwm_v2_channel_init(pwm, channel, &pwm_ch_config);
+
+    bflb_pwm_v2_channel_set_threshold(pwm, channel, 0, configuration->pulse);
+
+    bflb_pwm_v2_channel_positive_stop(pwm, channel);
+    bflb_pwm_v2_channel_negative_stop(pwm, channel);
+    bflb_pwm_v2_stop(pwm);
+
+    bflb_pwm_v2_channel_positive_start(pwm, channel);
+    bflb_pwm_v2_channel_negative_start(pwm, channel);
+    bflb_pwm_v2_start(pwm);
+
+    return RT_EOK;
+}
+
+static rt_err_t _pwm_get(rt_uint8_t channel, struct rt_pwm_configuration *configuration)
+{
+    uint32_t reg_base, regval, tmp;
+    float period;
+
+    reg_base = bflb_device_get_by_name("pwm_v2_0")->reg_base;
+    regval = getreg32(reg_base + PWM_MC0_PERIOD_OFFSET);
+    tmp = (regval & PWM_PERIOD_MASK) >> PWM_PERIOD_SHIFT;
+    period = (float)tmp;
+
+    uint32_t period_hz = 1000000 / period;
+
+    regval = getreg32(reg_base + PWM_MC0_CH0_THRE_OFFSET + channel * 4);
+    uint16_t high_threhold = regval >> 16;
+    uint16_t low_threhold = regval;
+
+    configuration->period = 1000000000 / period_hz;
+
+    configuration->pulse = high_threhold;
+
+    return RT_EOK;
+}
+
+static rt_err_t _pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
+{
+    struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
+
+    rt_uint32_t channel = 0;
+
+    channel = configuration->channel;
+
+    if (channel >= 4)
+        return -RT_EINVAL;
+
+    struct bflb_device_s* pwm = bflb_device_get_by_name("pwm_v2_0");
+    switch (cmd)
+    {
+    case PWM_CMD_ENABLE:
+        bflb_pwm_v2_channel_positive_start(pwm, channel);
+        bflb_pwm_v2_channel_negative_start(pwm, channel);
+        return RT_EOK;
+    case PWM_CMD_DISABLE:
+        bflb_pwm_v2_channel_positive_stop(pwm, channel);
+        bflb_pwm_v2_channel_negative_stop(pwm, channel);
+        return RT_EOK;
+    case PWM_CMD_SET:
+        return _pwm_set(channel, configuration);
+    case PWM_CMD_GET:
+        return _pwm_get(channel, configuration);
+    default:
+        return -RT_EINVAL;
+    }
+}
+
+static struct rt_pwm_ops _pwm_ops =
+{
+    _pwm_control
+};
+static struct rt_device_pwm pwm_device;
+
+int rt_hw_pwm_init(void)
+{
+    int result = RT_EOK;
+
+    struct bflb_device_s* gpio = bflb_device_get_by_name("gpio");
+    bflb_gpio_init(gpio, GPIO_PIN_8, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLDOWN | GPIO_SMT_EN | GPIO_DRV_1);
+    struct bflb_device_s* pwm = bflb_device_get_by_name("pwm_v2_0");
+    bflb_pwm_v2_start(pwm);
+
+    result = rt_device_pwm_register(&pwm_device, "pwm", &_pwm_ops, 0);
+    if(result != RT_EOK)
+    {
+        LOG_E("pwm device register fail.");
+    }
+    return result;
+}
+INIT_DEVICE_EXPORT(rt_hw_pwm_init);
+
+#endif /* BSP_USING_PWM */

+ 19 - 0
bsp/bouffalo_lab/libraries/rt_drivers/drv_pwm.h

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date             Author          Notes
+ * 2023-03-12       wcx1024979076    first version
+ */
+
+#ifndef __DRV_PWM_H__
+#define __DRV_PWM_H__
+#include "bflb_pwm_v2.h"
+#include "bflb_clock.h"
+#include "board.h"
+#include "hardware/pwm_v2_reg.h"
+int rt_hw_pwm_init(void);
+
+#endif /* __DRV_PWM_H__ */

+ 90 - 0
bsp/bouffalo_lab/libraries/rt_drivers/drv_rtc.c

@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date         Author          Notes
+ * 2023-03-13   wcx1024979076   the first version
+ */
+
+#include <rtdevice.h>
+#include "board.h"
+#include "drv_rtc.h"
+
+#define DBG_TAG "DRV.RTC"
+#define DBG_LVL DBG_WARNING
+#include <rtdbg.h>
+
+#ifdef RT_USING_RTC
+
+static struct rt_device rtc;
+static rt_uint32_t rtc_time;
+
+static rt_err_t _rtc_open(rt_device_t dev, rt_uint16_t oflag)
+{
+    if (dev->rx_indicate != RT_NULL)
+    {
+        /* Open Interrupt */
+    }
+
+    return RT_EOK;
+}
+
+static rt_ssize_t _rtc_read(
+    rt_device_t     dev,
+    rt_off_t        pos,
+    void*           buffer,
+    rt_size_t       size)
+{
+    return 0;
+}
+
+static rt_err_t _rtc_control(rt_device_t dev, int cmd, void *args)
+{
+    RT_ASSERT(dev != RT_NULL);
+    struct bflb_device_s* bflb_rtc = bflb_device_get_by_name("rtc");
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_RTC_GET_TIME:
+        *(rt_uint32_t *)args = rtc_time + BFLB_RTC_TIME2SEC(bflb_rtc_get_time(bflb_rtc));
+        break;
+
+    case RT_DEVICE_CTRL_RTC_SET_TIME:
+        rtc_time = *(rt_uint32_t *)args;
+        bflb_rtc_set_time(bflb_rtc, 0);
+        break;
+    }
+
+    return RT_EOK;
+}
+
+int rt_hw_rtc_init(void)
+{
+    int result = RT_EOK;
+
+    struct bflb_device_s* bflb_rtc = bflb_device_get_by_name("rtc");
+    bflb_rtc_set_time(bflb_rtc, 0);
+    /* register rtc device */
+    rtc.type        = RT_Device_Class_RTC;
+    rtc.rx_indicate = RT_NULL;
+    rtc.tx_complete = RT_NULL;
+    rtc.init        = RT_NULL;
+    rtc.open        = _rtc_open;
+    rtc.close       = RT_NULL;
+    rtc.read        = _rtc_read;
+    rtc.write       = RT_NULL;
+    rtc.control     = _rtc_control;
+    rtc.user_data   = RT_NULL; /* no private */
+
+    result = rt_device_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
+    if(result != RT_EOK)
+    {
+        LOG_E("rtc device register fail.");
+    }
+
+    return result;
+}
+
+INIT_DEVICE_EXPORT(rt_hw_rtc_init);
+#endif /* RT_USING_RTC */

+ 19 - 0
bsp/bouffalo_lab/libraries/rt_drivers/drv_rtc.h

@@ -0,0 +1,19 @@
+ /*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date         Author      Notes
+ * 2023-03-13   wcx1024979076   the first version
+ */
+
+#ifndef __DRV_RTC_H__
+#define __DRV_RTC_H__
+#include "bflb_rtc.h"
+#include <rtdevice.h>
+#include <rthw.h>
+
+int rt_hw_rtc_init(void);
+
+#endif /* __DRV_RTC_H__ */

+ 97 - 0
bsp/bouffalo_lab/libraries/rt_drivers/drv_wdt.c

@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author        Notes
+ * 2023-03-14     wcx1024979076 first version
+ */
+
+#include "drv_wdt.h"
+
+#ifdef RT_USING_WDT
+#ifdef BSP_USING_WDT
+#define DBG_LEVEL   DBG_LOG
+#include <rtdbg.h>
+#define LOG_TAG "DRV.WDT"
+
+struct rt_watchdog_device wdt_device;
+
+static rt_err_t _wdt_configure(rt_watchdog_t *wdt_device)
+{
+    struct bflb_device_s* wdt = bflb_device_get_by_name("watchdog");
+    struct bflb_wdg_config_s wdg_cfg;
+
+    wdg_cfg.clock_source = BFLB_SYSTEM_XCLK;
+    wdg_cfg.clock_div = 40;
+    wdg_cfg.comp_val = 10000000;
+    wdg_cfg.mode = WDG_MODE_RESET;
+    bflb_wdg_init(wdt, &wdg_cfg);
+
+    return RT_EOK;
+}
+
+static rt_err_t _wdt_control(rt_watchdog_t *wdt_device, int cmd, void *arg)
+{
+    RT_ASSERT(wdt_device != RT_NULL);
+
+    struct bflb_device_s* wdt = bflb_device_get_by_name("watchdog");
+    struct bflb_wdg_config_s wdg_cfg;
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_WDT_KEEPALIVE:
+        bflb_wdg_reset_countervalue(wdt);
+        break;
+    case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
+        wdg_cfg.clock_source = BFLB_SYSTEM_XCLK;
+        wdg_cfg.clock_div = 40;
+        wdg_cfg.comp_val = 10000000 * (*(rt_uint32_t *)arg);
+        wdg_cfg.mode = WDG_MODE_RESET;
+        bflb_wdg_init(wdt, &wdg_cfg);
+        bflb_wdg_start(wdt);
+        wdt_device->parent.user_data = (rt_uint32_t)(*(rt_uint32_t *)arg);
+        break;
+    case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
+        *(rt_uint32_t *)arg = (rt_uint32_t)wdt_device->parent.user_data;
+        break;
+    case RT_DEVICE_CTRL_WDT_GET_TIMELEFT:
+        *(rt_uint32_t *)arg = bflb_wdg_get_countervalue(wdt) / 10000000;
+        break;
+    case RT_DEVICE_CTRL_WDT_START:
+        bflb_wdg_start(wdt);
+        break;
+    case RT_DEVICE_CTRL_WDT_STOP:
+        bflb_wdg_stop(wdt);
+        break;
+    default:
+        LOG_W("This command is not supported.");
+        return -RT_EINVAL;
+    }
+
+    return RT_EOK;
+}
+
+static const struct rt_watchdog_ops _wdt_ops =
+{
+    .init = _wdt_configure,
+    .control = _wdt_control
+};
+
+int rt_hw_wdt_init(void)
+{
+    int result = RT_EOK;
+
+    wdt_device.ops = &_wdt_ops;
+    result = rt_hw_watchdog_register(&wdt_device, "wdt", RT_DEVICE_FLAG_RDWR, RT_NULL);
+    if(result != RT_EOK)
+    {
+        LOG_E("wdt device register fail.");
+    }
+    return result;
+}
+INIT_BOARD_EXPORT(rt_hw_wdt_init);
+
+#endif /* BSP_USING_WDT */
+#endif /* RT_USING_WDT */

+ 23 - 0
bsp/bouffalo_lab/libraries/rt_drivers/drv_wdt.h

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2006-2022, Synwit Technology Co.,Ltd.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author        Notes
+ * 2023-03-14     wcx1024979076 first version
+ */
+
+#ifndef __DRV_WDT_H__
+#define __DRV_WDT_H__
+
+#include "board.h"
+#include "bflb_wdg.h"
+#include "bflb_clock.h"
+#include <rtthread.h>
+#include "rtdevice.h"
+#include <rthw.h>
+
+int rt_hw_wdt_init(void);
+
+#endif /* __DRV_WDT_H__ */