diff --git a/targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c index 282005904f..a2a8abee63 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c @@ -53,6 +53,10 @@ static int ticker_inited = 0; void lp_ticker_init(void) { if (ticker_inited) { + /* By HAL spec, ticker_init allows the ticker to keep counting and disables the + * ticker interrupt. */ + lp_ticker_disable_interrupt(); + lp_ticker_clear_interrupt(); return; } ticker_inited = 1; @@ -88,7 +92,7 @@ void lp_ticker_init(void) NVIC_EnableIRQ(TIMER_MODINIT.irq_n); - TIMER_EnableInt(timer_base); + TIMER_DisableInt(timer_base); wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); TIMER_EnableWakeup(timer_base); @@ -101,6 +105,33 @@ void lp_ticker_init(void) while(! (timer_base->CTL & TIMER_CTL_ACTSTS_Msk)); } +void lp_ticker_free(void) +{ + TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname); + + /* Stop counting */ + TIMER_Stop(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + /* Wait for timer to stop counting and unset active flag */ + while((timer_base->CTL & TIMER_CTL_ACTSTS_Msk)); + + /* Disable wakeup */ + TIMER_DisableWakeup(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + /* Disable interrupt */ + TIMER_DisableInt(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + NVIC_DisableIRQ(TIMER_MODINIT.irq_n); + + /* Disable IP clock */ + CLK_DisableModuleClock(TIMER_MODINIT.clkidx); + + ticker_inited = 0; +} + timestamp_t lp_ticker_read() { if (! ticker_inited) { @@ -131,6 +162,9 @@ void lp_ticker_set_interrupt(timestamp_t timestamp) timer_base->CMP = cmp_timer; wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + TIMER_EnableInt(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); } void lp_ticker_disable_interrupt(void) diff --git a/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c index a09360608e..83c43fe13c 100644 --- a/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c @@ -53,6 +53,10 @@ static int ticker_inited = 0; void lp_ticker_init(void) { if (ticker_inited) { + /* By HAL spec, ticker_init allows the ticker to keep counting and disables the + * ticker interrupt. */ + lp_ticker_disable_interrupt(); + lp_ticker_clear_interrupt(); return; } ticker_inited = 1; @@ -88,7 +92,7 @@ void lp_ticker_init(void) NVIC_EnableIRQ(TIMER_MODINIT.irq_n); - TIMER_EnableInt(timer_base); + TIMER_DisableInt(timer_base); wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); TIMER_EnableWakeup(timer_base); @@ -101,6 +105,33 @@ void lp_ticker_init(void) while(! (timer_base->CTL & TIMER_CTL_ACTSTS_Msk)); } +void lp_ticker_free(void) +{ + TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname); + + /* Stop counting */ + TIMER_Stop(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + /* Wait for timer to stop counting and unset active flag */ + while((timer_base->CTL & TIMER_CTL_ACTSTS_Msk)); + + /* Disable wakeup */ + TIMER_DisableWakeup(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + /* Disable interrupt */ + TIMER_DisableInt(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + NVIC_DisableIRQ(TIMER_MODINIT.irq_n); + + /* Disable IP clock */ + CLK_DisableModuleClock(TIMER_MODINIT.clkidx); + + ticker_inited = 0; +} + timestamp_t lp_ticker_read() { if (! ticker_inited) { @@ -131,6 +162,9 @@ void lp_ticker_set_interrupt(timestamp_t timestamp) timer_base->CMP = cmp_timer; wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + TIMER_EnableInt(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); } void lp_ticker_disable_interrupt(void) diff --git a/targets/TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c index 6355531d33..451834ed55 100644 --- a/targets/TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c @@ -55,6 +55,10 @@ static int ticker_inited = 0; void lp_ticker_init(void) { if (ticker_inited) { + /* By HAL spec, ticker_init allows the ticker to keep counting and disables the + * ticker interrupt. */ + lp_ticker_disable_interrupt(); + lp_ticker_clear_interrupt(); return; } ticker_inited = 1; @@ -92,7 +96,7 @@ void lp_ticker_init(void) NVIC_EnableIRQ(TIMER_MODINIT.irq_n); - TIMER_EnableInt(timer_base); + TIMER_DisableInt(timer_base); wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); TIMER_EnableWakeup(timer_base); @@ -105,6 +109,33 @@ void lp_ticker_init(void) while(! (timer_base->CTL & TIMER_CTL_TMR_ACT_Msk)); } +void lp_ticker_free(void) +{ + TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname); + + /* Stop counting */ + TIMER_Stop(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + /* Wait for timer to stop counting and unset active flag */ + while((timer_base->CTL & TIMER_CTL_TMR_ACT_Msk)); + + /* Disable wakeup */ + TIMER_DisableWakeup(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + /* Disable interrupt */ + TIMER_DisableInt(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + NVIC_DisableIRQ(TIMER_MODINIT.irq_n); + + /* Disable IP clock */ + CLK_DisableModuleClock(TIMER_MODINIT.clkidx); + + ticker_inited = 0; +} + timestamp_t lp_ticker_read() { if (! ticker_inited) { @@ -135,6 +166,9 @@ void lp_ticker_set_interrupt(timestamp_t timestamp) timer_base->CMPR = cmp_timer; wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + TIMER_EnableInt(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); } void lp_ticker_disable_interrupt(void) diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c b/targets/TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c index 08ce7f8989..015e7caf2b 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c @@ -53,6 +53,10 @@ static int ticker_inited = 0; void lp_ticker_init(void) { if (ticker_inited) { + /* By HAL spec, ticker_init allows the ticker to keep counting and disables the + * ticker interrupt. */ + lp_ticker_disable_interrupt(); + lp_ticker_clear_interrupt(); return; } ticker_inited = 1; @@ -87,7 +91,7 @@ void lp_ticker_init(void) NVIC_EnableIRQ(TIMER_MODINIT.irq_n); - TIMER_EnableInt(timer_base); + TIMER_DisableInt(timer_base); wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); TIMER_EnableWakeup(timer_base); @@ -100,6 +104,33 @@ void lp_ticker_init(void) while(! (timer_base->CTL & TIMER_CTL_ACTSTS_Msk)); } +void lp_ticker_free(void) +{ + TIMER_T *timer_base = (TIMER_T *) NU_MODBASE(TIMER_MODINIT.modname); + + /* Stop counting */ + TIMER_Stop(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + /* Wait for timer to stop counting and unset active flag */ + while((timer_base->CTL & TIMER_CTL_ACTSTS_Msk)); + + /* Disable wakeup */ + TIMER_DisableWakeup(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + /* Disable interrupt */ + TIMER_DisableInt(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + NVIC_DisableIRQ(TIMER_MODINIT.irq_n); + + /* Disable IP clock */ + CLK_DisableModuleClock(TIMER_MODINIT.clkidx); + + ticker_inited = 0; +} + timestamp_t lp_ticker_read() { if (! ticker_inited) { @@ -130,6 +161,9 @@ void lp_ticker_set_interrupt(timestamp_t timestamp) timer_base->CMP = cmp_timer; wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); + + TIMER_EnableInt(timer_base); + wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3); } void lp_ticker_disable_interrupt(void) diff --git a/targets/targets.json b/targets/targets.json index 3c730b8968..979d1b3423 100755 --- a/targets/targets.json +++ b/targets/targets.json @@ -3844,7 +3844,7 @@ }, "inherits": ["Target"], "macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT"], - "device_has": ["USTICKER", "RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG", "CAN", "FLASH", "EMAC"], + "device_has": ["USTICKER", "LPTICKER", "RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG", "CAN", "FLASH", "EMAC"], "release_versions": ["5"], "device_name": "NUC472HI8AE", "bootloader_supported": true, @@ -3915,7 +3915,7 @@ }, "inherits": ["Target"], "progen": {"target": "numaker-pfm-m453"}, - "device_has": ["USTICKER", "RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "CAN", "FLASH"], + "device_has": ["USTICKER", "LPTICKER", "RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "CAN", "FLASH"], "release_versions": ["2", "5"], "device_name": "M453VG6AE", "bootloader_supported": true @@ -3946,7 +3946,7 @@ }, "inherits": ["Target"], "macros": ["CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"","MBED_FAULT_HANDLER_DISABLED"], - "device_has": ["USTICKER", "RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH"], + "device_has": ["USTICKER", "LPTICKER", "RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH"], "release_versions": ["5"], "device_name": "NANO130KE3BN" }, @@ -4113,7 +4113,7 @@ }, "inherits": ["Target"], "macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT"], - "device_has": ["USTICKER", "RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG", "FLASH", "CAN", "EMAC"], + "device_has": ["USTICKER", "LPTICKER", "RTC", "ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "SERIAL", "SERIAL_ASYNCH", "SERIAL_FC", "STDIO_MESSAGES", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "TRNG", "FLASH", "CAN", "EMAC"], "release_versions": ["5"], "device_name": "M487JIDAE", "bootloader_supported": true,