Skip to content

Commit 1fa3374

Browse files
committed
[Nuvoton] Remove special handling for dummy interrupt in lp_ticker
It is because dummy interrupt is very rare or pending time caused by it is very short.
1 parent 310a1fe commit 1fa3374

File tree

4 files changed

+60
-80
lines changed

4 files changed

+60
-80
lines changed

targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,21 @@ static volatile uint16_t ticker_inited = 0;
5454
#define TMR_CMP_MIN 2
5555
#define TMR_CMP_MAX 0xFFFFFFu
5656

57-
/* NOTE: When system clock is higher than timer clock, we need to add 3 engine clock
58-
* (recommended by designer) delay to wait for above timer control to take effect. */
57+
/* Synchronization issue with LXT/LIRC-clocked Timer
58+
*
59+
* PCLK : typical HCLK/2
60+
* ECLK (engine clock) : LXT/LIRC for Timer used to implement lp_ticker
61+
*
62+
* When system clock is higher than Timer clock (LXT/LIRC), we need to add delay for ECLK
63+
* domain to take effect:
64+
* 1. Write : typical 1PCLK + 2ECLK
65+
* Read-check doesn't work because it just checks PCLK domain and doesn't check into
66+
* ECLK domain.
67+
* 2. Clear interrupt flag : typical 2PCLK
68+
* It is very rare that we would meet dummy interrupt and get stuck in ISR until
69+
* 'clear interrupt flag' takes effect. The issue is ignorable because the pending
70+
* time is very short (at most 1 dummy interrupt). We won't take special handling for it.
71+
*/
5972

6073
void lp_ticker_init(void)
6174
{
@@ -214,25 +227,7 @@ const ticker_info_t* lp_ticker_get_info()
214227

215228
static void tmr1_vec(void)
216229
{
217-
/* NOTE: Avoid blocking in ISR due to wait for "clear interrupt flag"
218-
*
219-
* "clear interrupt flag" needs wait to take effect which isn't added here to avoid
220-
* blocking in ISR.
221-
*
222-
* Continuing above, we will get stuck in ISR due to dummy interrupt until
223-
* "clear interrupt flag" takes effect. To avoid it, we disable interrupt here and enable
224-
* interrupt in lp_ticker_fire_interrupt/lp_ticker_set_interrupt. There is another risk
225-
* that we may get stuck in a loop of ISR and lp_ticker_fire_interrupt/
226-
* lp_ticker_set_interrupt (called by lp_ticker_irq_handler), but actually we don't:
227-
* 1. When lp_ticker_fire_interrupt gets called, it means there is a past event and so this
228-
* interrupt isn't dummy.
229-
* 2. With LPTICKER_DELAY_TICKS enabled, it is lp_ticker_set_interrupt_wrapper rather than
230-
* lp_ticker_set_interrupt that gets straight called. lp_ticker_set_interrupt_wrapper
231-
* guarantees that lp_ticker_set_interrupt won't get re-called in LPTICKER_DELAY_TICKS ticks
232-
* which is just enough for "clear interrupt flag" to take effect.
233-
*/
234230
lp_ticker_clear_interrupt();
235-
lp_ticker_disable_interrupt();
236231

237232
// NOTE: lp_ticker_set_interrupt() may get called in lp_ticker_irq_handler();
238233
lp_ticker_irq_handler();

targets/TARGET_NUVOTON/TARGET_M480/lp_ticker.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,21 @@ static volatile uint16_t ticker_inited = 0;
5454
#define TMR_CMP_MIN 2
5555
#define TMR_CMP_MAX 0xFFFFFFu
5656

57-
/* NOTE: When system clock is higher than timer clock, we need to add 3 engine clock
58-
* (recommended by designer) delay to wait for above timer control to take effect. */
57+
/* Synchronization issue with LXT/LIRC-clocked Timer
58+
*
59+
* PCLK : typical HCLK/2
60+
* ECLK (engine clock) : LXT/LIRC for Timer used to implement lp_ticker
61+
*
62+
* When system clock is higher than Timer clock (LXT/LIRC), we need to add delay for ECLK
63+
* domain to take effect:
64+
* 1. Write : typical 1PCLK + 2ECLK
65+
* Read-check doesn't work because it just checks PCLK domain and doesn't check into
66+
* ECLK domain.
67+
* 2. Clear interrupt flag : typical 2PCLK
68+
* It is very rare that we would meet dummy interrupt and get stuck in ISR until
69+
* 'clear interrupt flag' takes effect. The issue is ignorable because the pending
70+
* time is very short (at most 1 dummy interrupt). We won't take special handling for it.
71+
*/
5972

6073
void lp_ticker_init(void)
6174
{
@@ -214,25 +227,7 @@ const ticker_info_t* lp_ticker_get_info()
214227

215228
static void tmr1_vec(void)
216229
{
217-
/* NOTE: Avoid blocking in ISR due to wait for "clear interrupt flag"
218-
*
219-
* "clear interrupt flag" needs wait to take effect which isn't added here to avoid
220-
* blocking in ISR.
221-
*
222-
* Continuing above, we will get stuck in ISR due to dummy interrupt until
223-
* "clear interrupt flag" takes effect. To avoid it, we disable interrupt here and enable
224-
* interrupt in lp_ticker_fire_interrupt/lp_ticker_set_interrupt. There is another risk
225-
* that we may get stuck in a loop of ISR and lp_ticker_fire_interrupt/
226-
* lp_ticker_set_interrupt (called by lp_ticker_irq_handler), but actually we don't:
227-
* 1. When lp_ticker_fire_interrupt gets called, it means there is a past event and so this
228-
* interrupt isn't dummy.
229-
* 2. With LPTICKER_DELAY_TICKS enabled, it is lp_ticker_set_interrupt_wrapper rather than
230-
* lp_ticker_set_interrupt that gets straight called. lp_ticker_set_interrupt_wrapper
231-
* guarantees that lp_ticker_set_interrupt won't get re-called in LPTICKER_DELAY_TICKS ticks
232-
* which is just enough for "clear interrupt flag" to take effect.
233-
*/
234230
lp_ticker_clear_interrupt();
235-
lp_ticker_disable_interrupt();
236231

237232
// NOTE: lp_ticker_set_interrupt() may get called in lp_ticker_irq_handler();
238233
lp_ticker_irq_handler();

targets/TARGET_NUVOTON/TARGET_NANO100/lp_ticker.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,21 @@ static volatile uint16_t ticker_inited = 0;
5656
#define TMR_CMP_MIN 2
5757
#define TMR_CMP_MAX 0xFFFFFFu
5858

59-
/* NOTE: When system clock is higher than timer clock, we need to add 3 engine clock
60-
* (recommended by designer) delay to wait for above timer control to take effect. */
59+
/* Synchronization issue with LXT/LIRC-clocked Timer
60+
*
61+
* PCLK : typical HCLK/2
62+
* ECLK (engine clock) : LXT/LIRC for Timer used to implement lp_ticker
63+
*
64+
* When system clock is higher than Timer clock (LXT/LIRC), we need to add delay for ECLK
65+
* domain to take effect:
66+
* 1. Write : typical 1PCLK + 2ECLK
67+
* Read-check doesn't work because it just checks PCLK domain and doesn't check into
68+
* ECLK domain.
69+
* 2. Clear interrupt flag : typical 2PCLK
70+
* It is very rare that we would meet dummy interrupt and get stuck in ISR until
71+
* 'clear interrupt flag' takes effect. The issue is ignorable because the pending
72+
* time is very short (at most 1 dummy interrupt). We won't take special handling for it.
73+
*/
6174

6275
void lp_ticker_init(void)
6376
{
@@ -218,25 +231,7 @@ const ticker_info_t* lp_ticker_get_info()
218231

219232
void TMR1_IRQHandler(void)
220233
{
221-
/* NOTE: Avoid blocking in ISR due to wait for "clear interrupt flag"
222-
*
223-
* "clear interrupt flag" needs wait to take effect which isn't added here to avoid
224-
* blocking in ISR.
225-
*
226-
* Continuing above, we will get stuck in ISR due to dummy interrupt until
227-
* "clear interrupt flag" takes effect. To avoid it, we disable interrupt here and enable
228-
* interrupt in lp_ticker_fire_interrupt/lp_ticker_set_interrupt. There is another risk
229-
* that we may get stuck in a loop of ISR and lp_ticker_fire_interrupt/
230-
* lp_ticker_set_interrupt (called by lp_ticker_irq_handler), but actually we don't:
231-
* 1. When lp_ticker_fire_interrupt gets called, it means there is a past event and so this
232-
* interrupt isn't dummy.
233-
* 2. With LPTICKER_DELAY_TICKS enabled, it is lp_ticker_set_interrupt_wrapper rather than
234-
* lp_ticker_set_interrupt that gets straight called. lp_ticker_set_interrupt_wrapper
235-
* guarantees that lp_ticker_set_interrupt won't get re-called in LPTICKER_DELAY_TICKS ticks
236-
* which is just enough for "clear interrupt flag" to take effect.
237-
*/
238234
lp_ticker_clear_interrupt();
239-
lp_ticker_disable_interrupt();
240235

241236
// NOTE: lp_ticker_set_interrupt() may get called in lp_ticker_irq_handler();
242237
lp_ticker_irq_handler();

targets/TARGET_NUVOTON/TARGET_NUC472/lp_ticker.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,21 @@ static volatile uint16_t ticker_inited = 0;
5454
#define TMR_CMP_MIN 2
5555
#define TMR_CMP_MAX 0xFFFFFFu
5656

57-
/* NOTE: When system clock is higher than timer clock, we need to add 3 engine clock
58-
* (recommended by designer) delay to wait for above timer control to take effect. */
57+
/* Synchronization issue with LXT/LIRC-clocked Timer
58+
*
59+
* PCLK : typical HCLK/2
60+
* ECLK (engine clock) : LXT/LIRC for Timer used to implement lp_ticker
61+
*
62+
* When system clock is higher than Timer clock (LXT/LIRC), we need to add delay for ECLK
63+
* domain to take effect:
64+
* 1. Write : typical 1PCLK + 2ECLK
65+
* Read-check doesn't work because it just checks PCLK domain and doesn't check into
66+
* ECLK domain.
67+
* 2. Clear interrupt flag : typical 2PCLK
68+
* It is very rare that we would meet dummy interrupt and get stuck in ISR until
69+
* 'clear interrupt flag' takes effect. The issue is ignorable because the pending
70+
* time is very short (at most 1 dummy interrupt). We won't take special handling for it.
71+
*/
5972

6073
void lp_ticker_init(void)
6174
{
@@ -213,25 +226,7 @@ const ticker_info_t* lp_ticker_get_info()
213226

214227
static void tmr1_vec(void)
215228
{
216-
/* NOTE: Avoid blocking in ISR due to wait for "clear interrupt flag"
217-
*
218-
* "clear interrupt flag" needs wait to take effect which isn't added here to avoid
219-
* blocking in ISR.
220-
*
221-
* Continuing above, we will get stuck in ISR due to dummy interrupt until
222-
* "clear interrupt flag" takes effect. To avoid it, we disable interrupt here and enable
223-
* interrupt in lp_ticker_fire_interrupt/lp_ticker_set_interrupt. There is another risk
224-
* that we may get stuck in a loop of ISR and lp_ticker_fire_interrupt/
225-
* lp_ticker_set_interrupt (called by lp_ticker_irq_handler), but actually we don't:
226-
* 1. When lp_ticker_fire_interrupt gets called, it means there is a past event and so this
227-
* interrupt isn't dummy.
228-
* 2. With LPTICKER_DELAY_TICKS enabled, it is lp_ticker_set_interrupt_wrapper rather than
229-
* lp_ticker_set_interrupt that gets straight called. lp_ticker_set_interrupt_wrapper
230-
* guarantees that lp_ticker_set_interrupt won't get re-called in LPTICKER_DELAY_TICKS ticks
231-
* which is just enough for "clear interrupt flag" to take effect.
232-
*/
233229
lp_ticker_clear_interrupt();
234-
lp_ticker_disable_interrupt();
235230

236231
// NOTE: lp_ticker_set_interrupt() may get called in lp_ticker_irq_handler();
237232
lp_ticker_irq_handler();

0 commit comments

Comments
 (0)