|
16 | 16 | #include <stddef.h>
|
17 | 17 | #include "us_ticker_api.h"
|
18 | 18 | #include "PeripheralNames.h"
|
| 19 | +#include "critical.h" |
19 | 20 |
|
20 |
| -#define US_TICKER_TIMER_IRQn RIT_IRQn |
| 21 | +#define US_TICKER_TIMER_IRQn SCT3_IRQn |
21 | 22 |
|
22 | 23 | int us_ticker_inited = 0;
|
23 | 24 |
|
24 | 25 | void us_ticker_init(void) {
|
25 |
| - if (us_ticker_inited) return; |
| 26 | + if (us_ticker_inited) |
| 27 | + return; |
| 28 | + |
26 | 29 | us_ticker_inited = 1;
|
27 |
| - |
28 |
| - // Enable the RIT clock |
29 |
| - LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << 1); |
30 |
| - |
31 |
| - // Clear peripheral reset the RIT |
32 |
| - LPC_SYSCON->PRESETCTRL1 |= (1 << 1); |
33 |
| - LPC_SYSCON->PRESETCTRL1 &= ~(1 << 1); |
34 |
| - |
35 |
| - LPC_RIT->MASK = 0; |
36 |
| - LPC_RIT->MASK_H = 0; |
37 |
| - |
38 |
| - LPC_RIT->COUNTER = 0; |
39 |
| - LPC_RIT->COUNTER_H = 0; |
40 |
| - |
41 |
| - LPC_RIT->COMPVAL = 0xffffffff; |
42 |
| - LPC_RIT->COMPVAL_H = 0x0000ffff; |
43 |
| - |
44 |
| - // Timer enable, enable for debug |
45 |
| - LPC_RIT->CTRL = 0xC; |
46 |
| - |
| 30 | + |
| 31 | + // Enable the SCT3 clock |
| 32 | + LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << 5); |
| 33 | + |
| 34 | + // Clear peripheral reset the SCT3 |
| 35 | + LPC_SYSCON->PRESETCTRL1 |= (1 << 5); |
| 36 | + LPC_SYSCON->PRESETCTRL1 &= ~(1 << 5); |
| 37 | + |
| 38 | + // Configure SCT3 as a 1MHz 32-bit counter with no auto limiting or match reload |
| 39 | + char sctClkDiv = ((SystemCoreClock + 1000000 - 1) / 1000000) - 1; |
| 40 | + LPC_SCT3->CONFIG = (1 << 7) | (1 << 0); |
| 41 | + LPC_SCT3->CTRL = (sctClkDiv << 5) | (1 << 3) | (1 << 2); |
| 42 | + |
| 43 | + // Configure SCT3 event 0 to fire on match register 0 |
| 44 | + LPC_SCT3->EV0_STATE = (1 << 0); |
| 45 | + LPC_SCT3->EV0_CTRL = (0x1 << 12); |
| 46 | + |
| 47 | + // Start SCT3 |
| 48 | + LPC_SCT3->CTRL &= ~(1 << 2); |
| 49 | + |
| 50 | + // Set SCT3 interrupt vector |
47 | 51 | NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
|
48 | 52 | NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
|
49 | 53 | }
|
50 | 54 |
|
51 | 55 | uint32_t us_ticker_read() {
|
52 | 56 | if (!us_ticker_inited)
|
53 | 57 | us_ticker_init();
|
54 |
| - |
55 |
| - uint64_t temp; |
56 |
| - temp = LPC_RIT->COUNTER | ((uint64_t)LPC_RIT->COUNTER_H << 32); |
57 |
| - temp /= (SystemCoreClock/1000000); |
58 |
| - return (uint32_t)temp; |
| 58 | + |
| 59 | + // Return SCT3 count value |
| 60 | + return LPC_SCT3->COUNT; |
59 | 61 | }
|
60 | 62 |
|
61 | 63 | void us_ticker_set_interrupt(timestamp_t timestamp) {
|
62 |
| - uint64_t temp = ((uint64_t)timestamp * (SystemCoreClock/1000000)); |
63 |
| - LPC_RIT->COMPVAL = (temp & 0xFFFFFFFFL); |
64 |
| - LPC_RIT->COMPVAL_H = ((temp >> 32)& 0x0000FFFFL); |
| 64 | + // Set SCT3 match register 0 (critical section) |
| 65 | + core_util_critical_section_enter(); |
| 66 | + LPC_SCT3->CTRL |= (1 << 2); |
| 67 | + LPC_SCT3->MATCH0 = (uint32_t)timestamp; |
| 68 | + LPC_SCT3->CTRL &= ~(1 << 2); |
| 69 | + core_util_critical_section_exit(); |
| 70 | + |
| 71 | + // Enable interrupt on SCT3 event 0 |
| 72 | + LPC_SCT3->EVEN = (1 << 0); |
65 | 73 | }
|
66 | 74 |
|
67 | 75 | void us_ticker_disable_interrupt(void) {
|
68 |
| - LPC_RIT->CTRL |= (1 << 3); |
| 76 | + // Disable interrupt on SCT3 event 0 |
| 77 | + LPC_SCT3->EVEN = 0; |
69 | 78 | }
|
70 | 79 |
|
71 | 80 | void us_ticker_clear_interrupt(void) {
|
72 |
| - LPC_RIT->CTRL |= (1 << 0); |
| 81 | + // Clear SCT3 event 0 interrupt flag |
| 82 | + LPC_SCT3->EVFLAG = (1 << 0); |
73 | 83 | }
|
0 commit comments