Browse Source

Merge pull request #4268 from greedyhao/bluetrum

[bsp][bluetrum] add i2c, wdt and hwtimer support
Bernard Xiong 4 years ago
parent
commit
fdb270c6f4

+ 25 - 11
bsp/bluetrum/ab32vg1-ab-prougen/.config

@@ -114,8 +114,16 @@ CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
 CONFIG_DFS_FD_MAX=16
 # CONFIG_RT_USING_DFS_MNTTABLE is not set
 # CONFIG_RT_USING_DFS_ELMFAT is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
+# CONFIG_RT_DFS_ELM_USE_LFN_3 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_0 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set
+# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set
 # CONFIG_RT_USING_DFS_DEVFS is not set
-CONFIG_RT_USING_DFS_ROMFS=y
+# CONFIG_RT_USING_DFS_ROMFS is not set
 # CONFIG_RT_USING_DFS_RAMFS is not set
 # CONFIG_RT_USING_DFS_UFFS is not set
 # CONFIG_RT_USING_DFS_JFFS2 is not set
@@ -145,10 +153,7 @@ CONFIG_RT_USING_PIN=y
 # CONFIG_RT_USING_SDIO is not set
 # CONFIG_RT_USING_SPI is not set
 # CONFIG_RT_USING_WDT is not set
-CONFIG_RT_USING_AUDIO=y
-CONFIG_RT_AUDIO_REPLAY_MP_BLOCK_SIZE=1024
-CONFIG_RT_AUDIO_REPLAY_MP_BLOCK_COUNT=2
-CONFIG_RT_AUDIO_RECORD_PIPE_SIZE=512
+# CONFIG_RT_USING_AUDIO is not set
 # CONFIG_RT_USING_SENSOR is not set
 # CONFIG_RT_USING_TOUCH is not set
 # CONFIG_RT_USING_HWCRYPTO is not set
@@ -328,6 +333,8 @@ CONFIG_RT_USING_LIBC=y
 # CONFIG_PKG_USING_RDB is not set
 # CONFIG_PKG_USING_QRCODE is not set
 # CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_ULOG_FILE is not set
+# CONFIG_PKG_USING_LOGMGR is not set
 # CONFIG_PKG_USING_ADBD is not set
 # CONFIG_PKG_USING_COREMARK is not set
 # CONFIG_PKG_USING_DHRYSTONE is not set
@@ -343,6 +350,8 @@ CONFIG_RT_USING_LIBC=y
 # CONFIG_PKG_USING_CPU_USAGE is not set
 # CONFIG_PKG_USING_GBK2UTF8 is not set
 # CONFIG_PKG_USING_VCONSOLE is not set
+# CONFIG_PKG_USING_KDB is not set
+# CONFIG_PKG_USING_WAMR is not set
 
 #
 # system packages
@@ -382,6 +391,10 @@ CONFIG_RT_USING_LIBC=y
 # CONFIG_PKG_USING_PPOOL is not set
 # CONFIG_PKG_USING_OPENAMP is not set
 # CONFIG_PKG_USING_RT_PRINTF is not set
+# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
+# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
+# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
+# CONFIG_PKG_USING_QFPLIB_M3 is not set
 
 #
 # peripheral libraries and drivers
@@ -390,6 +403,7 @@ CONFIG_RT_USING_LIBC=y
 # CONFIG_PKG_USING_REALTEK_AMEBA is not set
 # CONFIG_PKG_USING_SHT2X is not set
 # CONFIG_PKG_USING_SHT3X is not set
+# CONFIG_PKG_USING_AS7341 is not set
 # CONFIG_PKG_USING_STM32_SDIO is not set
 # CONFIG_PKG_USING_ICM20608 is not set
 # CONFIG_PKG_USING_U8G2 is not set
@@ -442,6 +456,7 @@ CONFIG_RT_USING_LIBC=y
 # CONFIG_PKG_USING_NES is not set
 # CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
 # CONFIG_PKG_USING_VDEVICE is not set
+# CONFIG_PKG_USING_SGM706 is not set
 
 #
 # miscellaneous packages
@@ -491,6 +506,7 @@ CONFIG_RT_USING_LIBC=y
 # CONFIG_PKG_USING_TETRIS is not set
 # CONFIG_PKG_USING_LWGPS is not set
 # CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
+# CONFIG_PKG_USING_STATE_MACHINE is not set
 
 #
 # Hardware Drivers Config
@@ -500,8 +516,7 @@ CONFIG_RT_USING_LIBC=y
 # Onboard Peripheral Drivers
 #
 CONFIG_BSP_USING_USB_TO_USART=y
-CONFIG_BSP_USING_AUDIO=y
-CONFIG_BSP_USING_AUDIO_PLAY=y
+# CONFIG_BSP_USING_AUDIO is not set
 # CONFIG_BSP_USING_SDCARD is not set
 
 #
@@ -509,10 +524,9 @@ CONFIG_BSP_USING_AUDIO_PLAY=y
 #
 CONFIG_BSP_USING_UART0=y
 # CONFIG_BSP_USING_SDIO is not set
-
-#
-# On-chip Peripheral Drivers
-#
+# CONFIG_BSP_USING_I2C1 is not set
+# CONFIG_BSP_USING_WDT is not set
+# CONFIG_BSP_USING_TIM is not set
 
 #
 # Board extended module Drivers

+ 5 - 4
bsp/bluetrum/ab32vg1-ab-prougen/README.md

@@ -39,13 +39,14 @@ ab32vg1-prougen 是 中科蓝讯(Bluetrum) 推出的一款基于 RISC-V 内核
 | **片上外设** | **支持情况** | **备注**    |
 | GPIO         |     支持     | PA PB PE PF |
 | UART         |     支持     | UART0/1/2   |
-| SDIO         |   即将支持   |             |
+| SDIO         |     支持     |             |
 | ADC          |   即将支持   |             |
-| SPI          |   即将支持   |             |
-| I2C          |   即将支持   | 软件 I2C    |
+| SPI          |   即将支持   | 软件 SPI    |
+| I2C          |     支持     | 软件 I2C    |
 | RTC          |   即将支持   |             |
-| WDT          |   即将支持   |             |
+| WDT          |     支持     |             |
 | FLASH        |   即将支持   |             |
+| TIMER        |     支持     |             |
 | PWM          |   即将支持   |             |
 | USB Device   |   暂不支持   |             |
 | USB Host     |   暂不支持   |             |

+ 49 - 0
bsp/bluetrum/ab32vg1-ab-prougen/board/Kconfig

@@ -47,6 +47,55 @@ menu "On-chip Peripheral Drivers"
         select RT_USING_DFS_ELMFAT
         default n
 
+    menuconfig BSP_USING_I2C1
+        bool "Enable I2C1 BUS (software simulation)"
+        default n
+        select RT_USING_I2C
+        select RT_USING_I2C_BITOPS
+        select RT_USING_PIN
+        if BSP_USING_I2C1
+            comment "Notice: PE3 --> 16; PE2 --> 15"
+            config BSP_I2C1_SCL_PIN
+                int "I2C1 scl pin number"
+                range 1 27
+                default 16
+            config BSP_I2C1_SDA_PIN
+                int "I2C1 sda pin number"
+                range 1 27
+                default 15
+        endif
+
+    config BSP_USING_WDT
+        bool "Enable Watchdog Timer"
+        select RT_USING_WDT
+        default n
+
+    menuconfig BSP_USING_TIM
+        bool "Enable timer"
+        default n
+        select RT_USING_HWTIMER
+        if BSP_USING_TIM
+            config BSP_USING_TIM1
+                bool "Enable TIM1"
+                default n
+
+            config BSP_USING_TIM2
+                bool "Enable TIM2"
+                default n
+
+            config BSP_USING_TIM3
+                bool "Enable TIM3"
+                default n
+
+            config BSP_USING_TIM4
+                bool "Enable TIM4"
+                default n
+                
+            config BSP_USING_TIM5
+                bool "Enable TIM5"
+                default n
+        endif
+
 endmenu
 
 menu "Board extended module Drivers"

+ 20 - 23
bsp/bluetrum/ab32vg1-ab-prougen/link.lds

@@ -34,20 +34,6 @@ SECTIONS
     } > init
 
     .ram1 __ram1_vma : {
-        . = ALIGN(4);
-        PROVIDE(__ctors_start__ = .);
-        KEEP (*(SORT(.init_array.*)))
-        KEEP (*(.init_array))
-        PROVIDE(__ctors_end__ = .);
-
-        . = ALIGN(4);
-        *components*drivers**.o (.text*)
-        *device.o (.text*)
-        *components.o (.text*)
-        *idle.o (.text*)
-    } > ram1 AT > flash
-
-    .rti : {
         . = ALIGN(4);
         /* section information for initial */
         __rt_init_start = .;
@@ -64,27 +50,38 @@ SECTIONS
         KEEP(*(VSymTab))
         __vsymtab_end = .;
 
-        . = ALIGN(32);
+        . = ALIGN(4);
+        PROVIDE(__ctors_start__ = .);
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        PROVIDE(__ctors_end__ = .);
+
+        . = ALIGN(4);
+        *components*drivers**.o (.text*)
+        *components.o (.text*)
+        *idle.o (.text*)
+        *object.o (.text*)
+        *scheduler.o (.text*)
     } > ram1 AT > flash
 
-    .comm : {
+    .comm __comm_vma : {
         . = ALIGN(4);
         KEEP(*(.vector))
-        EXCLUDE_FILE(*components*finsh**.o *components*libc**.o *romfs.o 
-        *lib_a**.o *divdi3.o *moddi3.o *divdf3.o *muldf3.o *eqtf2.o *getf2.o
+        EXCLUDE_FILE(*components*finsh**.o *components*libc**.o *dfs*filesystems**.o  
+        *romfs.o *lib_a**.o *divdi3.o *moddi3.o *divdf3.o *muldf3.o *eqtf2.o *getf2.o
         *letf2.o *multf3.o *subtf3.o *fixtfsi.o *floatsitf.o *extenddftf2.o
         *trunctfdf2.o *_clzsi2.o *cp-demangle.o *unwind*.o) *(.text)
         *finsh*shell.o (.text*)
         *(.text.unlikely)
         *(.text.startup)
-        EXCLUDE_FILE (*components*libc**.o *romfs.o *lib_a**.o *cp-demangle.o
-        *divdf3.o *muldf3.o *multf3.o *unwind*.o *_clz.o) *(.rodata)
+        EXCLUDE_FILE (*components*libc**.o *dfs*filesystems**.o *romfs.o *lib_a**.o 
+        *cp-demangle.o *divdf3.o *muldf3.o *multf3.o *unwind*.o *_clz.o) *(.rodata)
         *(.rodata.name)
-        EXCLUDE_FILE(*lib_a**.o *cp-demangle.o) *(.rodata.str1.4)
+        EXCLUDE_FILE(*lib_a**.o *cp-demangle.o *cp-demangle.o) *(.rodata.str1.4)
         EXCLUDE_FILE(*lib_a**.o *unwind*.o) *(.srodata)
         *(.rela*)
         *(.data*)
-	    *(.sdata*)
+        *(.sdata*)
     } > comm AT > flash
 
     .bss (NOLOAD):
@@ -124,4 +121,4 @@ __bank_size = SIZEOF(.flash);
 __comm_lma = LOADADDR(.comm);
 __comm_size = SIZEOF(.comm);
 __ram1_lma = LOADADDR(.ram1);
-__ram1_size = SIZEOF(.ram1) + SIZEOF(.rti);
+__ram1_size = SIZEOF(.ram1);

+ 0 - 9
bsp/bluetrum/ab32vg1-ab-prougen/rtconfig.h

@@ -77,7 +77,6 @@
 #define DFS_FILESYSTEMS_MAX 2
 #define DFS_FILESYSTEM_TYPES_MAX 2
 #define DFS_FD_MAX 16
-#define RT_USING_DFS_ROMFS
 
 /* Device Drivers */
 
@@ -86,10 +85,6 @@
 #define RT_USING_SERIAL
 #define RT_SERIAL_RB_BUFSZ 64
 #define RT_USING_PIN
-#define RT_USING_AUDIO
-#define RT_AUDIO_REPLAY_MP_BLOCK_SIZE 1024
-#define RT_AUDIO_REPLAY_MP_BLOCK_COUNT 2
-#define RT_AUDIO_RECORD_PIPE_SIZE 512
 
 /* Using USB */
 
@@ -169,15 +164,11 @@
 /* Onboard Peripheral Drivers */
 
 #define BSP_USING_USB_TO_USART
-#define BSP_USING_AUDIO
-#define BSP_USING_AUDIO_PLAY
 
 /* On-chip Peripheral Drivers */
 
 #define BSP_USING_UART0
 
-/* On-chip Peripheral Drivers */
-
 /* Board extended module Drivers */
 
 #define BOARD_BLUETRUM_EVB

+ 9 - 0
bsp/bluetrum/libraries/hal_drivers/SConscript

@@ -16,6 +16,15 @@ if GetDepend('RT_USING_SERIAL'):
 if GetDepend('RT_USING_SDIO'):
     src += ['drv_sdio.c']
 
+if GetDepend('RT_USING_I2C'):
+    src += ['drv_soft_i2c.c']
+
+if GetDepend('RT_USING_WDT'):
+    src += ['drv_wdt.c']
+
+if GetDepend('RT_USING_HWTIMER'):
+    src += ['drv_hwtimer.c']
+
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
 
 objs = [group]

+ 89 - 0
bsp/bluetrum/libraries/hal_drivers/config/tim_config.h

@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2020-2021, Bluetrum Development Team
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2021-01-22     greedyhao         first version
+ */
+
+#ifndef __TIM_CONFIG_H__
+#define __TIM_CONFIG_H__
+
+#include <rtthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TIM_DEV_INFO_CONFIG
+#define TIM_DEV_INFO_CONFIG                     \
+    {                                           \
+        .maxfreq = 1000000,                     \
+        .minfreq = 3000,                        \
+        .maxcnt  = 0xFFFFFFFF,                  \
+        .cntmode = HWTIMER_CNTMODE_UP,          \
+    }
+#endif /* TIM_DEV_INFO_CONFIG */
+
+#ifdef BSP_USING_TIM1
+#ifndef TIM1_CONFIG
+#define TIM1_CONFIG                             \
+    {                                           \
+       .tim_handle      = TIM1_BASE,            \
+       .tim_irqn        = IRQ_TMR1_VECTOR,      \
+       .name            = "timer1",             \
+    }
+#endif /* TIM1_CONFIG */
+#endif /* BSP_USING_TIM1 */
+
+#ifdef BSP_USING_TIM2
+#ifndef TIM2_CONFIG
+#define TIM2_CONFIG                             \
+    {                                           \
+       .tim_handle      = TIM2_BASE,            \
+       .tim_irqn        = IRQ_TMR2_4_5_VECTOR,  \
+       .name            = "timer2",             \
+    }
+#endif /* TIM1_CONFIG */
+#endif /* BSP_USING_TIM2 */
+
+#ifdef BSP_USING_TIM3
+#ifndef TIM3_CONFIG
+#define TIM3_CONFIG                             \
+    {                                           \
+       .tim_handle      = TIM3_BASE,            \
+       .tim_irqn        = IRQ_IRRX_VECTOR,      \
+       .name            = "timer3",             \
+    }
+#endif /* TIM1_CONFIG */
+#endif /* BSP_USING_TIM3 */
+
+#ifdef BSP_USING_TIM4
+#ifndef TIM4_CONFIG
+#define TIM4_CONFIG                             \
+    {                                           \
+       .tim_handle      = TIM4_BASE,            \
+       .tim_irqn        = IRQ_TMR2_4_5_VECTOR,  \
+       .name            = "timer4",             \
+    }
+#endif /* TIM1_CONFIG */
+#endif /* BSP_USING_TIM4 */
+
+#ifdef BSP_USING_TIM5
+#ifndef TIM5_CONFIG
+#define TIM5_CONFIG                             \
+    {                                           \
+       .tim_handle      = TIM5_BASE,            \
+       .tim_irqn        = IRQ_TMR2_4_5_VECTOR,  \
+       .name            = "timer5",             \
+    }
+#endif /* TIM1_CONFIG */
+#endif /* BSP_USING_TIM5 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIM_CONFIG_H__ */

+ 268 - 0
bsp/bluetrum/libraries/hal_drivers/drv_hwtimer.c

@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2020-2021, Bluetrum Development Team
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2021-01-22     greedyhao         first version
+ */
+
+#include "board.h"
+#ifdef BSP_USING_TIM
+#include "tim_config.h"
+
+//#define DRV_DEBUG
+#define LOG_TAG             "drv.hwtimer"
+#include <drv_log.h>
+
+#ifdef RT_USING_HWTIMER
+
+enum
+{
+#ifdef BSP_USING_TIM1
+    TIM1_INDEX,
+#endif
+#ifdef BSP_USING_TIM2
+    TIM2_INDEX,
+#endif
+#ifdef BSP_USING_TIM3
+    TIM3_INDEX,
+#endif
+#ifdef BSP_USING_TIM4
+    TIM4_INDEX,
+#endif
+#ifdef BSP_USING_TIM5
+    TIM5_INDEX,
+#endif
+};
+
+struct ab32_hwtimer
+{
+    rt_hwtimer_t time_device;
+    hal_sfr_t     tim_handle;
+    char *name;
+    irq_type tim_irqn;
+};
+
+static struct ab32_hwtimer ab32_hwtimer_obj[] =
+{
+#ifdef BSP_USING_TIM1
+    TIM1_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM2
+    TIM2_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM3
+    TIM3_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM4
+    TIM4_CONFIG,
+#endif
+
+#ifdef BSP_USING_TIM5
+    TIM5_CONFIG,
+#endif
+};
+
+static void timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
+{
+    uint32_t prescaler_value = 0;
+    hal_sfr_t tim = RT_NULL;
+    struct ab32_hwtimer *tim_device = RT_NULL;
+
+    RT_ASSERT(timer != RT_NULL);
+    tim = (hal_sfr_t)timer->parent.user_data;
+
+    if (state)
+    {
+        tim_device = (struct ab32_hwtimer *)timer;
+
+        if (timer->info->cntmode != HWTIMER_CNTMODE_UP)
+        {
+            LOG_E("Only support HWTIMER_CNTMODE_UP!");
+        }
+
+        /* set tim int */
+        tim[TMRxCON] = BIT(7);
+
+        LOG_D("%s init success", tim_device->name);
+    } else {
+        /* stop timer */
+        tim[TMRxCON] = 0;
+    }
+}
+
+static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
+{
+    rt_err_t result = RT_EOK;
+    hal_sfr_t tim = RT_NULL;
+
+    RT_ASSERT(timer != RT_NULL);
+
+    tim = (hal_sfr_t)timer->parent.user_data;
+
+    /* set tim cnt */
+    tim[TMRxCNT] = 0;
+    tim[TMRxPR] = t * (get_sysclk_nhz() / timer->freq) - 1;
+
+    if (opmode != HWTIMER_MODE_PERIOD)
+    {
+        LOG_E("Opmode only support HWTIMER_MODE_PERIOD!");
+        return -RT_EINVAL;
+    }
+
+    /* start timer */
+    tim[TMRxCON] |= BIT(0);
+
+    return result;
+}
+
+static void timer_stop(rt_hwtimer_t *timer)
+{
+    hal_sfr_t tim = RT_NULL;
+
+    RT_ASSERT(timer != RT_NULL);
+
+    tim = (hal_sfr_t)timer->parent.user_data;
+
+    /* stop timer */
+    tim[TMRxCON] &= ~BIT(0);
+
+    /* set tim cnt */
+    tim[TMRxCNT] = 0;
+}
+
+static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
+{
+    hal_sfr_t tim = RT_NULL;
+    rt_err_t result = RT_EOK;
+
+    RT_ASSERT(timer != RT_NULL);
+    RT_ASSERT(arg != RT_NULL);
+
+    tim = (hal_sfr_t)timer->parent.user_data;
+
+    switch (cmd)
+    {
+    case HWTIMER_CTRL_FREQ_SET:
+    {
+    }
+    break;
+    default:
+    {
+        result = -RT_ENOSYS;
+    }
+    break;
+    }
+
+    return result;
+}
+
+static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer)
+{
+    hal_sfr_t tim = RT_NULL;
+
+    RT_ASSERT(timer != RT_NULL);
+
+    tim = (hal_sfr_t)timer->parent.user_data;
+
+    return tim[TMRxCNT] / (get_sysclk_nhz() / timer->freq);
+}
+
+static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
+
+static const struct rt_hwtimer_ops _ops =
+{
+    .init = timer_init,
+    .start = timer_start,
+    .stop = timer_stop,
+    .count_get = timer_counter_get,
+    .control = timer_ctrl,
+};
+
+#if defined(BSP_USING_TIM2) || defined(BSP_USING_TIM4) || defined(BSP_USING_TIM5)
+void timer2_4_5_isr(int vector, void *param)
+{
+    rt_interrupt_enter();
+#ifdef BSP_USING_TIM2
+    if (ab32_hwtimer_obj[TIM2_INDEX].tim_handle[TMRxCON] != 0) {
+        ab32_hwtimer_obj[TIM2_INDEX].tim_handle[TMRxCPND] = BIT(9);
+        rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM2_INDEX].time_device);
+    }
+#endif
+#ifdef BSP_USING_TIM4
+    if (ab32_hwtimer_obj[TIM4_INDEX].tim_handle[TMRxCON] != 0) {
+        ab32_hwtimer_obj[TIM4_INDEX].tim_handle[TMRxCPND] = BIT(9);
+        rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM4_INDEX].time_device);
+    }
+#endif
+#ifdef BSP_USING_TIM5
+    if (ab32_hwtimer_obj[TIM5_INDEX].tim_handle[TMRxCON] != 0) {
+        ab32_hwtimer_obj[TIM5_INDEX].tim_handle[TMRxCPND] = BIT(9);
+        rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM5_INDEX].time_device);
+    }
+#endif
+    rt_interrupt_leave();
+}
+#endif
+
+#ifdef BSP_USING_TIM3
+void timer3_isr(int vector, void *param)
+{
+    rt_interrupt_enter();
+    ab32_hwtimer_obj[TIM3_INDEX].tim_handle[TMRxCPND] = BIT(9);
+    rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM3_INDEX].time_device);
+    rt_interrupt_leave();
+}
+#endif
+
+#ifdef BSP_USING_TIM1
+void timer1_isr(int vector, void *param)
+{
+    rt_interrupt_enter();
+    ab32_hwtimer_obj[TIM1_INDEX].tim_handle[TMRxCPND] = BIT(9);
+    rt_device_hwtimer_isr(&ab32_hwtimer_obj[TIM1_INDEX].time_device);
+    rt_interrupt_leave();
+}
+#endif
+
+static int ab32_hwtimer_init(void)
+{
+    int i = 0;
+    int result = RT_EOK;
+
+    for (i = 0; i < sizeof(ab32_hwtimer_obj) / sizeof(ab32_hwtimer_obj[0]); i++)
+    {
+        ab32_hwtimer_obj[i].time_device.info = &_info;
+        ab32_hwtimer_obj[i].time_device.ops  = &_ops;
+        if (rt_device_hwtimer_register(&ab32_hwtimer_obj[i].time_device, ab32_hwtimer_obj[i].name, (void *)ab32_hwtimer_obj[i].tim_handle) == RT_EOK)
+        {
+            LOG_D("%s register success", ab32_hwtimer_obj[i].name);
+        }
+        else
+        {
+            LOG_E("%s register failed", ab32_hwtimer_obj[i].name);
+            result = -RT_ERROR;
+        }
+    }
+
+#ifdef BSP_USING_TIM1
+    rt_hw_interrupt_install(IRQ_TMR1_VECTOR, timer1_isr, RT_NULL, "t1_isr");
+#endif
+#if defined(BSP_USING_TIM2) || defined(BSP_USING_TIM4) || defined(BSP_USING_TIM5)
+    rt_hw_interrupt_install(IRQ_TMR2_4_5_VECTOR, timer2_4_5_isr, RT_NULL, "t245_isr");
+#endif
+#ifdef BSP_USING_TIM3
+    rt_hw_interrupt_install(IRQ_IRRX_VECTOR, timer3_isr, RT_NULL, "t3_isr");
+#endif
+
+    return result;
+}
+INIT_BOARD_EXPORT(ab32_hwtimer_init);
+
+#endif /* RT_USING_HWTIMER */
+#endif /* BSP_USING_TIM */

+ 247 - 0
bsp/bluetrum/libraries/hal_drivers/drv_soft_i2c.c

@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2020-2021, Bluetrum Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2021-01-07     greedyhao         first version
+ */
+
+#include <board.h>
+#include "drv_soft_i2c.h"
+
+#ifdef RT_USING_I2C
+
+// #define DRV_DEBUG
+#define LOG_TAG              "drv.i2c"
+#include <drv_log.h>
+
+#if !defined(BSP_USING_I2C1) && !defined(BSP_USING_I2C2) && !defined(BSP_USING_I2C3) && !defined(BSP_USING_I2C4)
+#error "Please define at least one BSP_USING_I2Cx"
+/* this driver can be disabled at menuconfig → RT-Thread Components → Device Drivers */
+#endif
+
+static const struct ab32_soft_i2c_config soft_i2c_config[] =
+{
+#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 struct ab32_i2c i2c_obj[sizeof(soft_i2c_config) / sizeof(soft_i2c_config[0])] = {0};
+
+/**
+ * This function initializes the i2c pin.
+ *
+ * @param ab32 i2c dirver class.
+ */
+static void ab32_i2c_gpio_init(struct ab32_i2c *i2c)
+{
+    struct ab32_soft_i2c_config* cfg = (struct ab32_soft_i2c_config*)i2c->ops.data;
+
+    cfg->scl_mode = PIN_MODE_OUTPUT_OD;
+    cfg->sda_mode = PIN_MODE_OUTPUT_OD;
+    rt_pin_mode(cfg->scl, cfg->scl_mode);
+    rt_pin_mode(cfg->sda, cfg->sda_mode);
+
+    rt_pin_write(cfg->scl, PIN_HIGH);
+    rt_pin_write(cfg->sda, PIN_HIGH);
+}
+
+/**
+ * This function sets the sda pin.
+ *
+ * @param data ab32 config class.
+ * @param state The sda pin state.
+ */
+static void ab32_set_sda(void *data, rt_int32_t state)
+{
+    struct ab32_soft_i2c_config* cfg = (struct ab32_soft_i2c_config*)data;
+
+    if (cfg->sda_mode == PIN_MODE_INPUT_PULLUP) {
+        cfg->sda_mode = PIN_MODE_OUTPUT_OD;
+        rt_pin_mode(cfg->sda, cfg->sda_mode);
+    }
+
+    if (state)
+    {
+        rt_pin_write(cfg->sda, PIN_HIGH);
+    }
+    else
+    {
+        rt_pin_write(cfg->sda, PIN_LOW);
+    }
+}
+
+/**
+ * This function sets the scl pin.
+ *
+ * @param data ab32 config class.
+ * @param state The scl pin state.
+ */
+static void ab32_set_scl(void *data, rt_int32_t state)
+{
+    struct ab32_soft_i2c_config* cfg = (struct ab32_soft_i2c_config*)data;
+
+    if (cfg->scl_mode == PIN_MODE_INPUT_PULLUP) {
+        cfg->scl_mode = PIN_MODE_OUTPUT_OD;
+        rt_pin_mode(cfg->scl, cfg->scl_mode);
+    }
+
+    if (state)
+    {
+        rt_pin_write(cfg->scl, PIN_HIGH);
+    }
+    else
+    {
+        rt_pin_write(cfg->scl, PIN_LOW);
+    }
+}
+
+/**
+ * This function gets the sda pin state.
+ *
+ * @param data The sda pin state.
+ */
+static rt_int32_t ab32_get_sda(void *data)
+{
+    struct ab32_soft_i2c_config* cfg = (struct ab32_soft_i2c_config*)data;
+
+    if (cfg->sda_mode != PIN_MODE_INPUT_PULLUP) {
+        cfg->sda_mode = PIN_MODE_INPUT_PULLUP;
+        rt_pin_mode(cfg->sda, cfg->sda_mode);
+    }
+
+    return rt_pin_read(cfg->sda);
+}
+
+/**
+ * This function gets the scl pin state.
+ *
+ * @param data The scl pin state.
+ */
+static rt_int32_t ab32_get_scl(void *data)
+{
+    struct ab32_soft_i2c_config* cfg = (struct ab32_soft_i2c_config*)data;
+
+    if (cfg->scl_mode == PIN_MODE_INPUT_PULLUP) {
+        cfg->scl_mode = PIN_MODE_INPUT_PULLUP;
+        rt_pin_mode(cfg->scl, cfg->scl_mode);
+    }
+
+    return rt_pin_read(cfg->scl);
+}
+
+/**
+ * The time delay function.
+ *
+ * @param us microseconds.
+ */
+static void ab32_udelay(rt_uint32_t us)
+{
+    rt_uint32_t ticks;
+    rt_uint32_t told, tnow, tcnt = 0;
+    rt_uint32_t reload = TMR0PR;
+
+    ticks = us * reload / (1000 / RT_TICK_PER_SECOND);
+    told = TMR0CNT;
+    while (1)
+    {
+        tnow = TMR0CNT;
+        if (tnow != told)
+        {
+            if (tnow < told)
+            {
+                tcnt += told - tnow;
+            }
+            else
+            {
+                tcnt += reload - tnow + told;
+            }
+            told = tnow;
+            if (tcnt >= ticks)
+            {
+                break;
+            }
+        }
+    }
+}
+
+static const struct rt_i2c_bit_ops ab32_bit_ops_default =
+{
+    .data     = RT_NULL,
+    .set_sda  = ab32_set_sda,
+    .set_scl  = ab32_set_scl,
+    .get_sda  = ab32_get_sda,
+    .get_scl  = ab32_get_scl,
+    .udelay   = ab32_udelay,
+    .delay_us = 1,
+    .timeout  = 100
+};
+
+/**
+ * if i2c is locked, this function will unlock it
+ *
+ * @param cfg ab32 config class
+ *
+ * @return RT_EOK indicates successful unlock.
+ */
+static rt_err_t ab32_i2c_bus_unlock(const struct ab32_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);
+            ab32_udelay(100);
+            rt_pin_write(cfg->scl, PIN_LOW);
+            ab32_udelay(100);
+        }
+    }
+    if (PIN_LOW == rt_pin_read(cfg->sda))
+    {
+        return -RT_ERROR;
+    }
+
+    return RT_EOK;
+}
+
+/* I2C initialization function */
+int rt_hw_i2c_init(void)
+{
+    rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct ab32_i2c);
+    rt_err_t result;
+
+    for (int i = 0; i < obj_num; i++)
+    {
+        i2c_obj[i].ops = ab32_bit_ops_default;
+        i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
+        i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
+        ab32_i2c_gpio_init(&i2c_obj[i]);
+        result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name);
+        RT_ASSERT(result == RT_EOK);
+        ab32_i2c_bus_unlock(&soft_i2c_config[i]);
+
+        LOG_D("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);
+    }
+
+    return RT_EOK;
+}
+INIT_BOARD_EXPORT(rt_hw_i2c_init);
+
+#endif

+ 72 - 0
bsp/bluetrum/libraries/hal_drivers/drv_soft_i2c.h

@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2020-2021, Bluetrum Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2021-01-07     greedyhao         first version
+ */
+
+#ifndef __DRV_I2C__
+#define __DRV_I2C__
+
+#include <rtthread.h>
+#include <rthw.h>
+#include <rtdevice.h>
+
+/* ab32 config class */
+struct ab32_soft_i2c_config
+{
+    rt_uint8_t scl;
+    rt_uint8_t sda;
+    rt_uint8_t sda_mode;
+    rt_uint8_t scl_mode;
+    const char *bus_name;
+};
+
+/* ab32 i2c dirver class */
+struct ab32_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
+int rt_hw_i2c_init(void);
+
+#endif

+ 149 - 0
bsp/bluetrum/libraries/hal_drivers/drv_wdt.c

@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2020-2021, Bluetrum Development Team
+ * 
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author            Notes
+ * 2020-11-30     greedyhao         first version
+ */
+
+#include <board.h>
+
+#ifdef RT_USING_WDT
+
+// #define DRV_DEBUG
+#define LOG_TAG             "drv.wdt"
+#include <drv_log.h>
+
+struct ab32_wdt_obj
+{
+    rt_watchdog_t watchdog;
+};
+static struct ab32_wdt_obj ab32_wdt;
+static struct rt_watchdog_ops ops;
+
+static rt_err_t wdt_init(rt_watchdog_t *wdt)
+{
+    return RT_EOK;
+}
+
+static rt_err_t wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
+{
+    rt_uint32_t tmp = 0;
+
+    switch (cmd)
+    {
+        /* feed the watchdog */
+    case RT_DEVICE_CTRL_WDT_KEEPALIVE:
+        WDTCON = 0xa;
+        break;
+        /* set watchdog timeout */
+    case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:
+        if (arg == RT_NULL) {
+            LOG_E("The watchdog timeout argument cannot be NULL!");
+            break;
+        }
+
+        tmp = WDTCON & ~(0x7 << 20);
+
+        switch (*((rt_uint32_t *)arg))
+        {
+        case 0:
+            LOG_I("The watchdog timeout is set to 1ms");
+            tmp |= (0xa << 24) | (0x00 << 20);
+            break;
+        case 1:
+            LOG_I("The watchdog timeout is set to 256ms");
+            tmp |= (0xa << 24) | (0x01 << 20);
+            break;
+        case 2:
+            LOG_I("The watchdog timeout is set to 512ms");
+            tmp |= (0xa << 24) | (0x02 << 20);
+            break;
+        case 3:
+            LOG_I("The watchdog timeout is set to 1024ms");
+            tmp |= (0xa << 24) | (0x03 << 20);
+            break;
+        case 4:
+            LOG_I("The watchdog timeout is set to 2048ms");
+            tmp |= (0xa << 24) | (0x04 << 20);
+            break;
+        case 5:
+            LOG_I("The watchdog timeout is set to 4096ms");
+            tmp |= (0xa << 24) | (0x05 << 20);
+            break;
+        case 6:
+            LOG_I("The watchdog timeout is set to 8192ms");
+            tmp |= (0xa << 24) | (0x06 << 20);
+            break;
+        case 7:
+            LOG_I("The watchdog timeout is set to 16384ms");
+            tmp |= (0xa << 24) | (0x07 << 20);
+            break;
+        default:
+            LOG_W("The watchdog timeout argument range from 0 to 7!");
+            tmp = WDTCON;
+            break;
+        }
+        WDTCON = tmp;
+        LOG_D("WDTCON=%X", WDTCON);
+        break;
+    case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:
+        switch ((WDTCON >> 20) & 0x7)
+        {
+        case 0:
+            LOG_D("The watchdog timeout is set to 1ms");
+            break;
+        case 1:
+            LOG_D("The watchdog timeout is set to 256ms");
+            break;
+        case 2:
+            LOG_D("The watchdog timeout is set to 512ms");
+            break;
+        case 3:
+            LOG_D("The watchdog timeout is set to 1024ms");
+            break;
+        case 4:
+            LOG_D("The watchdog timeout is set to 2048ms");
+            break;
+        case 5:
+            LOG_D("The watchdog timeout is set to 4096ms");
+            break;
+        case 6:
+            LOG_D("The watchdog timeout is set to 8192ms");
+            break;
+        case 7:
+            LOG_D("The watchdog timeout is set to 16384ms");
+            break;
+        default:
+            break;
+        }
+        break;
+    case RT_DEVICE_CTRL_WDT_START:
+        WDTCON = 0x110;
+        break;
+    default:
+        LOG_W("This command is not supported.");
+        return -RT_ERROR;
+    }
+    return RT_EOK;
+}
+
+int rt_wdt_init(void)
+{
+    ops.init = &wdt_init;
+    ops.control = &wdt_control;
+    ab32_wdt.watchdog.ops = &ops;
+    /* register watchdog device */
+    if (rt_hw_watchdog_register(&ab32_wdt.watchdog, "wdt", RT_DEVICE_FLAG_DEACTIVATE, RT_NULL) != RT_EOK)
+    {
+        LOG_E("wdt device register failed.");
+        return -RT_ERROR;
+    }
+    LOG_D("wdt device register success.");
+    return RT_EOK;
+}
+INIT_BOARD_EXPORT(rt_wdt_init);
+
+#endif /* RT_USING_WDT */

+ 5 - 0
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_conf.h

@@ -14,6 +14,7 @@
 #define HAL_WDT_MODULE_ENABLED
 // #define HAL_DAC_MODULE_ENABLED
 #define HAL_SD_MODULE_ENABLED
+#define HAL_TIM_MODULE_ENABLED
 
 /*  Includes  */
 #ifdef HAL_GPIO_MODULE_ENABLED
@@ -40,6 +41,10 @@
 #include "ab32vg1_hal_sd.h"
 #endif
 
+#ifdef HAL_TIM_MODULE_ENABLED
+#include "ab32vg1_hal_tim.h"
+#endif
+
 #include <assert.h>
 
 #endif

+ 31 - 0
bsp/bluetrum/libraries/hal_libraries/ab32vg1_hal/include/ab32vg1_hal_tim.h

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020-2020, BLUETRUM Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef AB32VG1_HAL_TIM_H__
+#define AB32VG1_HAL_TIM_H__
+
+#include "ab32vg1_hal_def.h"
+
+enum
+{
+    TMRxCON,
+    TMRxCPND,
+    TMRxCNT,
+    TMRxPR,
+    TMRxCPT,
+    TMRxDUTY0,
+    TMRxDUTY1,
+    TMRxDUTY2
+};
+
+#define TIM0_BASE   ((hal_sfr_t)&TMR0CON)
+#define TIM1_BASE   ((hal_sfr_t)&TMR1CON)
+#define TIM2_BASE   ((hal_sfr_t)&TMR2CON)
+#define TIM3_BASE   ((hal_sfr_t)&TMR3CON)
+#define TIM4_BASE   ((hal_sfr_t)&TMR4CON)
+#define TIM5_BASE   ((hal_sfr_t)&TMR5CON)
+
+#endif