|
16 | 16 | #include <stddef.h>
|
17 | 17 | #include "us_ticker_api.h"
|
18 | 18 | #include "PeripheralNames.h"
|
19 |
| - |
20 | 19 | #define US_TICKER_TIMER1 CMSDK_DUALTIMER1
|
21 | 20 | #define US_TICKER_TIMER2 CMSDK_DUALTIMER2
|
22 | 21 | #define US_TICKER_TIMER_IRQn DUALTIMER_IRQn
|
23 | 22 |
|
24 |
| -int us_ticker_inited = 0; |
| 23 | +/** mbed OS HAL API defined us_ticker as an increment ticker |
| 24 | + * MPS2 platform provided in SSE-200 are decrement tickers |
| 25 | + * with interrupt fired counter reaches 0. |
| 26 | + * |
| 27 | + * So 2 Timers are used to construct mbed OS HAL ticker. |
| 28 | + * |
| 29 | + * TIMER1 is for counting, and returns inverted binary when read from it |
| 30 | + * TIMER1 will be kept in free-running mode (default, and not generate interrupts) |
| 31 | + * |
| 32 | + * TIMER2 is for generating interrupts |
| 33 | + * So TIMER2 is set to periodic mode, which start decrement counting form LOADVALUE generates interrupts at 0 |
| 34 | + * and TIMER2 also set into one-shot mode, which counter halts when is reaches 0 |
| 35 | + */ |
| 36 | + |
| 37 | +static int us_ticker_inited = 0; |
25 | 38 |
|
26 | 39 | void us_ticker_init(void)
|
27 | 40 | {
|
28 | 41 | if (us_ticker_inited) {
|
| 42 | + us_ticker_disable_interrupt(); |
29 | 43 | return;
|
30 | 44 | }
|
31 |
| - us_ticker_inited = 1; |
32 | 45 |
|
33 |
| - US_TICKER_TIMER1->TimerControl = 0x0; // disable timer |
34 |
| - US_TICKER_TIMER2->TimerControl = 0x00; // disable timer |
35 |
| - US_TICKER_TIMER1->TimerLoad = 0xFFFFFFFF; |
36 |
| - US_TICKER_TIMER2->TimerLoad = 0xFFFFFFFF; |
| 46 | + US_TICKER_TIMER1->TimerControl = 0x0ul; // disable TIMER1 and reset all control |
| 47 | + US_TICKER_TIMER2->TimerControl = 0x0ul; // disable TIMER2 and reset all control |
| 48 | + |
| 49 | + US_TICKER_TIMER1->TimerLoad = 0xFFFFFFFFul; |
| 50 | + US_TICKER_TIMER2->TimerLoad = 0xFFFFFFFFul; |
| 51 | + |
| 52 | + US_TICKER_TIMER1->TimerControl |= CMSDK_DUALTIMER1_CTRL_SIZE_Msk; // set TIMER1 to 32 bit counter |
| 53 | + US_TICKER_TIMER2->TimerControl |= CMSDK_DUALTIMER2_CTRL_SIZE_Msk; // set TIMER2 to 32 bit counter |
37 | 54 |
|
38 |
| - US_TICKER_TIMER1->TimerControl = 0x62; // enable interrupt and set to 32 bit counter and set to periodic mode |
39 |
| - US_TICKER_TIMER2->TimerControl = 0x42; // enable interrupt and set to 32 bit counter |
| 55 | + US_TICKER_TIMER1->TimerControl |= 0x1 << CMSDK_DUALTIMER1_CTRL_PRESCALE_Pos; // set TIMER1 with 4 stages prescale |
| 56 | + US_TICKER_TIMER2->TimerControl |= 0x1 << CMSDK_DUALTIMER2_CTRL_PRESCALE_Pos; // set TIMER2 with 4 stages prescale |
40 | 57 |
|
41 |
| - US_TICKER_TIMER1->TimerControl |= 0x80; // enable counter |
42 |
| - US_TICKER_TIMER2->TimerControl |= 0x80; // enable counter |
| 58 | + US_TICKER_TIMER2->TimerControl |= CMSDK_DUALTIMER2_CTRL_MODE_Msk; // set TIMER2 periodic mode |
| 59 | + US_TICKER_TIMER2->TimerControl |= CMSDK_DUALTIMER2_CTRL_ONESHOOT_Msk; // set TIMER2 one-shot mode |
| 60 | + |
| 61 | + US_TICKER_TIMER1->TimerControl |= CMSDK_DUALTIMER1_CTRL_EN_Msk; // enable TIMER1 counter |
43 | 62 |
|
44 | 63 | NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
|
45 |
| - NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); |
| 64 | + us_ticker_inited = 1; |
| 65 | +} |
| 66 | + |
| 67 | +void us_ticker_free(void) |
| 68 | +{ |
| 69 | + US_TICKER_TIMER1->TimerControl &= ~CMSDK_DUALTIMER1_CTRL_EN_Msk; // disable TIMER1 |
| 70 | + US_TICKER_TIMER2->TimerControl &= ~CMSDK_DUALTIMER2_CTRL_EN_Msk; // disable TIMER2 |
| 71 | + us_ticker_disable_interrupt(); |
| 72 | + us_ticker_inited = 0; |
46 | 73 | }
|
47 | 74 |
|
48 | 75 | uint32_t us_ticker_read()
|
49 | 76 | {
|
50 |
| - uint32_t return_value = 0; |
51 |
| - if (!us_ticker_inited) { |
52 |
| - us_ticker_init(); |
53 |
| - } |
54 |
| - return_value = ((~US_TICKER_TIMER2->TimerValue) / 25); |
55 |
| - return return_value; |
| 77 | + return ~US_TICKER_TIMER1->TimerValue; |
56 | 78 | }
|
57 | 79 |
|
58 | 80 | void us_ticker_set_interrupt(timestamp_t timestamp)
|
59 | 81 | {
|
60 |
| - if (!us_ticker_inited) { |
61 |
| - us_ticker_init(); |
62 |
| - } |
63 |
| - |
64 |
| - uint32_t delta = timestamp - us_ticker_read(); |
65 |
| - // enable interrupt |
66 |
| - US_TICKER_TIMER1->TimerControl = 0x0; // disable timer |
67 |
| - US_TICKER_TIMER1->TimerControl = 0x62; // enable interrupt and set to 32 bit counter and set to periodic mode |
68 |
| - US_TICKER_TIMER1->TimerLoad = (delta) * 25; //initialise the timer value |
69 |
| - US_TICKER_TIMER1->TimerControl |= 0x80; //enable timer |
| 82 | + uint32_t delta = timestamp - us_ticker_read(); |
| 83 | + US_TICKER_TIMER2->TimerControl &= ~CMSDK_DUALTIMER2_CTRL_EN_Msk; // disable TIMER2 |
| 84 | + US_TICKER_TIMER2->TimerLoad = delta; // Set TIMER2 load value |
| 85 | + US_TICKER_TIMER2->TimerControl |= CMSDK_DUALTIMER2_CTRL_INTEN_Msk; // enable TIMER2 interrupt |
| 86 | + US_TICKER_TIMER2->TimerControl |= CMSDK_DUALTIMER2_CTRL_EN_Msk; // enable TIMER2 counter |
| 87 | + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); |
70 | 88 | }
|
71 | 89 |
|
72 | 90 | void us_ticker_fire_interrupt(void)
|
73 | 91 | {
|
| 92 | + NVIC_EnableIRQ(US_TICKER_TIMER_IRQn); |
74 | 93 | NVIC_SetPendingIRQ(US_TICKER_TIMER_IRQn);
|
75 | 94 | }
|
76 | 95 |
|
77 | 96 |
|
78 | 97 | void us_ticker_disable_interrupt(void)
|
79 | 98 | {
|
80 |
| - |
81 |
| - US_TICKER_TIMER1->TimerControl &= 0xDF; |
82 |
| - US_TICKER_TIMER2->TimerControl &= 0xDF; |
83 |
| - |
| 99 | + US_TICKER_TIMER2->TimerControl &= ~CMSDK_DUALTIMER2_CTRL_INTEN_Msk; |
| 100 | + US_TICKER_TIMER2->TimerControl &= ~CMSDK_DUALTIMER2_CTRL_EN_Msk; // disable TIMER2 |
| 101 | + NVIC_DisableIRQ(US_TICKER_TIMER_IRQn); |
84 | 102 | }
|
85 | 103 |
|
86 | 104 | void us_ticker_clear_interrupt(void)
|
87 | 105 | {
|
| 106 | + US_TICKER_TIMER2->TimerIntClr = CMSDK_DUALTIMER2_INTCLR_Msk; |
| 107 | +} |
88 | 108 |
|
89 |
| - US_TICKER_TIMER1->TimerIntClr = 0x1; |
90 |
| - US_TICKER_TIMER2->TimerIntClr = 0x1; |
91 |
| - |
| 109 | +const ticker_info_t *us_ticker_get_info(void) |
| 110 | +{ |
| 111 | + static const ticker_info_t info = { |
| 112 | + 1562500, // 4 stages prescaled from 25MHz (dived by 16) |
| 113 | + 32 // 32 bit counter |
| 114 | + }; |
| 115 | + return &info; |
92 | 116 | }
|
0 commit comments