Skip to content

Commit 6ff874c

Browse files
committed
Modified timer code
Timer/Wait timer
1 parent 19d1319 commit 6ff874c

File tree

1 file changed

+26
-7
lines changed
  • libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M

1 file changed

+26
-7
lines changed

libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20D5M/us_ticker.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,29 @@ void us_ticker_init(void) {
3434
lptmr_init();
3535
}
3636

37-
static uint32_t pit_us_ticker_counter = 0;
37+
static volatile uint32_t pit_msb_counter = 0;
38+
static uint32_t pit_division; //Division used to get LSB bits
3839

3940
void pit0_isr(void) {
40-
pit_us_ticker_counter++;
41-
PIT->CHANNEL[0].LDVAL = pit_ldval; // 1us
41+
pit_msb_counter++;
42+
PIT->CHANNEL[0].LDVAL = pit_ldval;
4243
PIT->CHANNEL[0].TFLG = 1;
4344
}
4445

4546
/******************************************************************************
4647
* Timer for us timing.
48+
*
49+
* The K20D5M does not have a prescaler on its PIT timer nor the option
50+
* to chain timers, which is why a software timer is required to get 32-bit
51+
* word length.
4752
******************************************************************************/
4853
static void pit_init(void) {
4954
SIM->SCGC6 |= SIM_SCGC6_PIT_MASK; // Clock PIT
5055
PIT->MCR = 0; // Enable PIT
51-
52-
pit_ldval = bus_frequency() / 1000000;
56+
57+
pit_division = bus_frequency() / 1000000;
58+
//CLZ counts the leading zeros, returning number of bits not used by pit_division
59+
pit_ldval = pit_division << __CLZ(pit_division);
5360

5461
PIT->CHANNEL[0].LDVAL = pit_ldval; // 1us
5562
PIT->CHANNEL[0].TCTRL |= PIT_TCTRL_TIE_MASK;
@@ -62,8 +69,20 @@ static void pit_init(void) {
6269
uint32_t us_ticker_read() {
6370
if (!us_ticker_inited)
6471
us_ticker_init();
65-
66-
return pit_us_ticker_counter;
72+
73+
uint32_t retval;
74+
__disable_irq();
75+
retval = (pit_ldval - PIT->CHANNEL[0].CVAL) / pit_division; //Hardware bits
76+
retval |= pit_msb_counter << __CLZ(pit_division); //Software bits
77+
78+
if (PIT->CHANNEL[0].TFLG == 1) { //If overflow bit is set, force it to be handled
79+
pit0_isr(); //Handle IRQ, read again to make sure software/hardware bits are synced
80+
NVIC_ClearPendingIRQ(PIT0_IRQn);
81+
return us_ticker_read();
82+
}
83+
84+
__enable_irq();
85+
return retval;
6786
}
6887

6988
/******************************************************************************

0 commit comments

Comments
 (0)