diff --git a/drivers/lhal/include/bflb_timer.h b/drivers/lhal/include/bflb_timer.h index adcf7c8e..d52335d2 100644 --- a/drivers/lhal/include/bflb_timer.h +++ b/drivers/lhal/include/bflb_timer.h @@ -19,6 +19,7 @@ #define TIMER_COMP_ID_0 0 #define TIMER_COMP_ID_1 1 #define TIMER_COMP_ID_2 2 +#define TIMER_COMP_NONE 3 /** * @} */ diff --git a/drivers/lhal/include/bflb_wdg.h b/drivers/lhal/include/bflb_wdg.h index b58d70d7..22301308 100644 --- a/drivers/lhal/include/bflb_wdg.h +++ b/drivers/lhal/include/bflb_wdg.h @@ -4,17 +4,28 @@ #include "bflb_core.h" #include "bflb_clock.h" +/** @defgroup WDG_MODE Watch-dog reset/interrupt mode definition + * @{ + */ +#define WDG_MODE_INTERRUPT 0 +#define WDG_MODE_RESET 1 +/** + * @} + */ + /** * @brief WDG configuration structure * * @param clock_source Wdg clock source, use BFLB_SYSTEM_* definition * @param clock_div Wdg clock divison value, from 0 to 255 - * @param comp_val Wdg compare value + * @param comp_val Wdg compare value + * @param mode Wdg reset/interrupt mode */ struct bflb_wdg_config_s { uint8_t clock_source; uint8_t clock_div; uint16_t comp_val; + uint8_t mode; }; #ifdef __cplusplus diff --git a/drivers/lhal/src/bflb_timer.c b/drivers/lhal/src/bflb_timer.c index 0652db8a..15c3f7ce 100644 --- a/drivers/lhal/src/bflb_timer.c +++ b/drivers/lhal/src/bflb_timer.c @@ -9,6 +9,11 @@ void bflb_timer_init(struct bflb_device_s *dev, const struct bflb_timer_config_s reg_base = dev->reg_base; + /* Disable timer */ + regval = getreg32(reg_base + TIMER_TCER_OFFSET); + regval &= ~(1 << (dev->idx + 1)); + putreg32(regval, reg_base + TIMER_TCER_OFFSET); + /* Configure clock source */ if (config->clock_source == BFLB_SYSTEM_CPU_CLK) { clk_source = 0; @@ -16,7 +21,7 @@ void bflb_timer_init(struct bflb_device_s *dev, const struct bflb_timer_config_s clk_source = 3; } else if (config->clock_source == BFLB_SYSTEM_32K_CLK) { clk_source = 1; - } else if (config->clock_source == BFLB_SYSTEM_1K_CLK){ + } else if (config->clock_source == BFLB_SYSTEM_1K_CLK) { clk_source = 2; } @@ -48,7 +53,9 @@ void bflb_timer_init(struct bflb_device_s *dev, const struct bflb_timer_config_s /* Configure preload trigger source */ regval = getreg32(reg_base + TIMER_TPLCR0_OFFSET + 4 * dev->idx); regval &= ~TIMER_TPLCR0_MASK; - regval |= ((config->trigger_comp_id + 1) << TIMER_TPLCR0_SHIFT); + if (config->trigger_comp_id != TIMER_COMP_NONE) { + regval |= ((config->trigger_comp_id + 1) << TIMER_TPLCR0_SHIFT); + } putreg32(regval, reg_base + TIMER_TPLCR0_OFFSET + 4 * dev->idx); if (config->counter_mode == TIMER_COUNTER_MODE_PROLOAD) { @@ -164,9 +171,9 @@ bool bflb_timer_get_compint_status(struct bflb_device_s *dev, uint8_t cmp_no) if (regval & (1 << cmp_no)) { return true; + } else { + return false; } - - return false; } void bflb_timer_compint_clear(struct bflb_device_s *dev, uint8_t cmp_no) diff --git a/drivers/lhal/src/bflb_wdg.c b/drivers/lhal/src/bflb_wdg.c index 7802d89b..9c887ec8 100644 --- a/drivers/lhal/src/bflb_wdg.c +++ b/drivers/lhal/src/bflb_wdg.c @@ -15,7 +15,11 @@ void bflb_wdg_init(struct bflb_device_s *dev, const struct bflb_wdg_config_s *co regval = getreg32(reg_base + TIMER_WMER_OFFSET); regval &= ~TIMER_WE; - regval &= ~TIMER_WRIE; + if (config->mode == WDG_MODE_INTERRUPT) { + regval &= ~TIMER_WRIE; + } else { + regval |= TIMER_WRIE; + } putreg32(regval, reg_base + TIMER_WMER_OFFSET); /* Configure clock source */ @@ -72,7 +76,6 @@ void bflb_wdg_stop(struct bflb_device_s *dev) regval = getreg32(reg_base + TIMER_WMER_OFFSET); regval &= ~TIMER_WE; - regval &= ~TIMER_WRIE; putreg32(regval, reg_base + TIMER_WMER_OFFSET); } diff --git a/examples/peripherals/wdg/main.c b/examples/peripherals/wdg/main.c deleted file mode 100644 index 6782fcde..00000000 --- a/examples/peripherals/wdg/main.c +++ /dev/null @@ -1,55 +0,0 @@ -#include "bflb_mtimer.h" -#include "bflb_wdg.h" -#include "board.h" - -struct bflb_device_s *wdt; -static volatile uint8_t wdt_int_arrived = 0; - -void wdt_isr(int irq, void *arg) -{ - wdt_int_arrived = 1; - bflb_wdg_compint_clear(wdt); -} - -int main(void) -{ - board_init(); - printf("Timer watchdog interrupt test\r\n"); - - struct bflb_wdg_config_s wdt_cfg; - wdt_cfg.clock_source = BFLB_SYSTEM_32K_CLK; - wdt_cfg.clock_div = 0; - wdt_cfg.comp_val = 64000; - - wdt = bflb_device_get_by_name("watchdog"); - bflb_wdg_init(wdt, &wdt_cfg); - bflb_irq_attach(wdt->irq_num, wdt_isr, wdt); - bflb_irq_enable(wdt->irq_num); - - wdt_int_arrived = 0; - bflb_wdg_start(wdt); - - /* delay 1s and wdt interrupt should not trigger. */ - bflb_mtimer_delay_ms(1000); - bflb_wdg_reset_countervalue(wdt); - if (wdt_int_arrived) { - printf("Error! Delay 1s, WDT interrupt should not arrive\r\n"); - bflb_wdg_stop(wdt); - } - - /* delay 2s will trigger WDT interrupt */ - bflb_mtimer_delay_ms(2000); - bflb_wdg_reset_countervalue(wdt); - if (wdt_int_arrived) { - printf("Delay 2s, WDT interrupt arrived\r\n"); - } else { - printf("Error! Delay 2s, WDT interrupt should arrive\r\n"); - printf("get wdt cnt = %d\r\n", bflb_wdg_get_countervalue(wdt)); - } - - bflb_wdg_stop(wdt); - - while (1) { - bflb_mtimer_delay_ms(1500); - } -} diff --git a/examples/peripherals/wdg/CMakeLists.txt b/examples/peripherals/wdg/wdg_int/CMakeLists.txt similarity index 89% rename from examples/peripherals/wdg/CMakeLists.txt rename to examples/peripherals/wdg/wdg_int/CMakeLists.txt index 5fb0a505..2bcf86e4 100644 --- a/examples/peripherals/wdg/CMakeLists.txt +++ b/examples/peripherals/wdg/wdg_int/CMakeLists.txt @@ -6,4 +6,4 @@ find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) sdk_set_main_file(main.c) -project(wdg) +project(wdg_int) diff --git a/examples/peripherals/wdg/Makefile b/examples/peripherals/wdg/wdg_int/Makefile similarity index 82% rename from examples/peripherals/wdg/Makefile rename to examples/peripherals/wdg/wdg_int/Makefile index 9b01b7fe..44367c02 100644 --- a/examples/peripherals/wdg/Makefile +++ b/examples/peripherals/wdg/wdg_int/Makefile @@ -1,5 +1,5 @@ SDK_DEMO_PATH ?= . -BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../.. +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. export BL_SDK_BASE diff --git a/examples/peripherals/wdg/wdg_int/main.c b/examples/peripherals/wdg/wdg_int/main.c new file mode 100644 index 00000000..16f57926 --- /dev/null +++ b/examples/peripherals/wdg/wdg_int/main.c @@ -0,0 +1,57 @@ +#include "bflb_mtimer.h" +#include "bflb_wdg.h" +#include "board.h" + +struct bflb_device_s *wdg; +static volatile uint8_t wdg_int_arrived = 0; + +void wdg_isr(int irq, void *arg) +{ + wdg_int_arrived = 1; + bflb_wdg_compint_clear(wdg); +} + +int main(void) +{ + board_init(); + printf("Watchdog interrupt test\r\n"); + + struct bflb_wdg_config_s wdg_cfg; + wdg_cfg.clock_source = BFLB_SYSTEM_32K_CLK; + wdg_cfg.clock_div = 0; + wdg_cfg.comp_val = 64000; + wdg_cfg.mode = WDG_MODE_INTERRUPT; + + wdg = bflb_device_get_by_name("watchdog"); + bflb_wdg_init(wdg, &wdg_cfg); + bflb_irq_attach(wdg->irq_num, wdg_isr, wdg); + bflb_irq_enable(wdg->irq_num); + + wdg_int_arrived = 0; + bflb_wdg_start(wdg); + + /* delay 1s and wdg interrupt should not trigger. */ + bflb_mtimer_delay_ms(1000); + bflb_wdg_reset_countervalue(wdg); + if (wdg_int_arrived) { + printf("Error! Delay 1s, wdg interrupt should not arrive\r\n"); + bflb_wdg_stop(wdg); + } else { + printf("Delay 1s, wdg interrupt not arrive, pass\r\n"); + } + + /* delay 2s will trigger wdg interrupt */ + bflb_mtimer_delay_ms(2000); + bflb_wdg_reset_countervalue(wdg); + if (wdg_int_arrived) { + printf("Delay 2s, wdg interrupt arrived, pass\r\n"); + } else { + printf("Error! Delay 2s, wdg interrupt not arrived, count = %d\r\n", + bflb_wdg_get_countervalue(wdg)); + } + bflb_wdg_stop(wdg); + + while (1) { + bflb_mtimer_delay_ms(1500); + } +} diff --git a/examples/peripherals/wdg/proj.conf b/examples/peripherals/wdg/wdg_int/proj.conf similarity index 100% rename from examples/peripherals/wdg/proj.conf rename to examples/peripherals/wdg/wdg_int/proj.conf diff --git a/examples/peripherals/wdg/wdg_reset/CMakeLists.txt b/examples/peripherals/wdg/wdg_reset/CMakeLists.txt new file mode 100644 index 00000000..a8c63072 --- /dev/null +++ b/examples/peripherals/wdg/wdg_reset/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.15) + +include(proj.conf) + +find_package(bouffalo_sdk REQUIRED HINTS $ENV{BL_SDK_BASE}) + +sdk_set_main_file(main.c) + +project(wdg_reset) diff --git a/examples/peripherals/wdg/wdg_reset/Makefile b/examples/peripherals/wdg/wdg_reset/Makefile new file mode 100644 index 00000000..44367c02 --- /dev/null +++ b/examples/peripherals/wdg/wdg_reset/Makefile @@ -0,0 +1,13 @@ +SDK_DEMO_PATH ?= . +BL_SDK_BASE ?= $(SDK_DEMO_PATH)/../../../.. + +export BL_SDK_BASE + +CHIP ?= bl616 +BOARD ?= bl616dk +CROSS_COMPILE ?= riscv64-unknown-elf- + +# add custom cmake definition +#cmake_definition+=-Dxxx=sss + +include $(BL_SDK_BASE)/project.build diff --git a/examples/peripherals/wdg/wdg_reset/main.c b/examples/peripherals/wdg/wdg_reset/main.c new file mode 100644 index 00000000..d43d3732 --- /dev/null +++ b/examples/peripherals/wdg/wdg_reset/main.c @@ -0,0 +1,50 @@ +#include "bflb_mtimer.h" +#include "bflb_wdg.h" +#include "board.h" + +struct bflb_device_s *wdg; +static volatile uint8_t wdg_int_arrived = 0; + +int main(void) +{ + board_init(); + printf("Watchdog interrupt test\r\n"); + + struct bflb_wdg_config_s wdg_cfg; + wdg_cfg.clock_source = BFLB_SYSTEM_32K_CLK; + wdg_cfg.clock_div = 0; + wdg_cfg.comp_val = 64000; + wdg_cfg.mode = WDG_MODE_RESET; + + wdg = bflb_device_get_by_name("watchdog"); + bflb_wdg_init(wdg, &wdg_cfg); + + wdg_int_arrived = 0; + bflb_wdg_start(wdg); + + /* delay 1s and wdg interrupt should not trigger. */ + bflb_mtimer_delay_ms(1000); + bflb_wdg_reset_countervalue(wdg); + if (wdg_int_arrived) { + printf("Error! Delay 1s, wdg not reset.\r\n"); + bflb_wdg_stop(wdg); + } else { + printf("Delay 1s, wdg interrupt not arrive, pass\r\n"); + } + + printf("Next delay 2s, wdg will reset it."); + /* delay 2s will trigger wdg interrupt */ + bflb_mtimer_delay_ms(2000); + bflb_wdg_reset_countervalue(wdg); + if (wdg_int_arrived) { + printf("Delay 2s, wdg reset, pass\r\n"); + } else { + printf("Error! Delay 2s, wdg not reset, count = %d\r\n", + bflb_wdg_get_countervalue(wdg)); + } + bflb_wdg_stop(wdg); + + while (1) { + bflb_mtimer_delay_ms(1500); + } +} diff --git a/examples/peripherals/wdg/wdg_reset/proj.conf b/examples/peripherals/wdg/wdg_reset/proj.conf new file mode 100644 index 00000000..13320d67 --- /dev/null +++ b/examples/peripherals/wdg/wdg_reset/proj.conf @@ -0,0 +1 @@ +#set(CONFIG_XXX 1) \ No newline at end of file