diff --git a/lib/pbio/drv/clock/clock_ev3.c b/lib/pbio/drv/clock/clock_ev3.c index 193b24297..75dd19883 100644 --- a/lib/pbio/drv/clock/clock_ev3.c +++ b/lib/pbio/drv/clock/clock_ev3.c @@ -21,16 +21,16 @@ #include #include -/** - * The compare value to set for the 16 least significant bits of the hardware timer - * - * This is the value which causes the interrupt to be triggered every millisecond. - */ -#define TMR_PERIOD_LSB32 0x05CC -/* - * The compare value to set for the 16 most significant bits of the hardware timer - */ -#define TMR_PERIOD_MSB32 0x0 +// The input to the Timer0 module is PLL0_AUXCLK. This will always run at 24 MHz on the EV3, +// regardless of what the CPU speed is set to. We configure the timer to generate interrupts +// every millisecond, and we configure the timer to reset to 0 when it reaches a count value +// corresponding to one millisecond of time. Finer timing resolution can be obtained by +// combining the software-managed millisecond counter with the timer value. +// +// The system tick uses the "12" half of the timer, and the PRU1 (TODO) uses the "34" half. +static const uint32_t auxclk_freq_hz = SOC_ASYNC_2_FREQ; +static const uint32_t timer_ms_period = (auxclk_freq_hz / 1000) - 1; +static const uint32_t timer_us_division = auxclk_freq_hz / 1000000; /** * The current tick in milliseconds @@ -41,37 +41,14 @@ volatile uint32_t systick_ms = 0; * The systick interrupt service routine (ISR) which will be called every millisecond. */ void systick_isr_C(void) { - /* Disable the timer interrupt */ - TimerIntDisable(SOC_TMR_0_REGS, TMR_INT_TMR34_NON_CAPT_MODE); - /* Clear the interrupt status in AINTC and in timer */ - IntSystemStatusClear(SYS_INT_TINT34_0); - TimerIntStatusClear(SOC_TMR_0_REGS, TMR_INT_TMR34_NON_CAPT_MODE); + IntSystemStatusClear(SYS_INT_TINT12_0); + TimerIntStatusClear(SOC_TMR_0_REGS, TMR_INTSTAT12_TIMER_NON_CAPT); ++systick_ms; etimer_request_poll(); pbio_os_request_poll(); - - /* Enable the timer interrupt */ - TimerIntEnable(SOC_TMR_0_REGS, TMR_INT_TMR34_NON_CAPT_MODE); -} - -/** - * Disable the timer and therefore the systick - * - */ -void systick_suspend(void) { - /* Disable the timer interrupt */ - TimerDisable(SOC_TMR_0_REGS, TMR_TIMER34); -} - -/** - * Enable the timer and therefore the systick - */ -void systick_resume(void) { - /* Enable the timer interrupt */ - TimerEnable(SOC_TMR_0_REGS, TMR_TIMER34, TMR_ENABLE_CONTRELOAD); } /** @@ -86,28 +63,28 @@ void pbdrv_clock_init(void) { /* Set up the timer */ TimerConfigure(SOC_TMR_0_REGS, TMR_CFG_32BIT_UNCH_CLK_BOTH_INT); - TimerPeriodSet(SOC_TMR_0_REGS, TMR_TIMER34, TMR_PERIOD_LSB32); - TimerReloadSet(SOC_TMR_0_REGS, TMR_TIMER34, TMR_PERIOD_LSB32); + TimerPeriodSet(SOC_TMR_0_REGS, TMR_TIMER12, timer_ms_period); /* Register the Timer ISR */ - IntRegister(SYS_INT_TINT34_0, systick_isr_C); + IntRegister(SYS_INT_TINT12_0, systick_isr_C); /* Set the channel number for Timer interrupt, it will map to IRQ */ - IntChannelSet(SYS_INT_TINT34_0, 3); + IntChannelSet(SYS_INT_TINT12_0, 3); /* Enable timer interrupts in AINTC */ - IntSystemEnable(SYS_INT_TINT34_0); + IntSystemEnable(SYS_INT_TINT12_0); /* Enable the timer interrupt */ - TimerIntEnable(SOC_TMR_0_REGS, TMR_INT_TMR34_NON_CAPT_MODE); + TimerIntEnable(SOC_TMR_0_REGS, TMR_INT_TMR12_NON_CAPT_MODE); /* Start the timer */ - TimerEnable(SOC_TMR_0_REGS, TMR_TIMER34, TMR_ENABLE_CONTRELOAD); + TimerEnable(SOC_TMR_0_REGS, TMR_TIMER12, TMR_ENABLE_CONT); } uint32_t pbdrv_clock_get_us(void) { - // TODO: TIAM1808 implementation. - return 0; + uint32_t tim_val = TimerCounterGet(SOC_TMR_0_REGS, TMR_TIMER12); + uint32_t t_us = tim_val / timer_us_division; + return pbdrv_clock_get_ms() * 1000 + t_us; } uint32_t pbdrv_clock_get_ms(void) { @@ -115,8 +92,9 @@ uint32_t pbdrv_clock_get_ms(void) { } uint32_t pbdrv_clock_get_100us(void) { - // REVISIT: Use actual time since this isn't providing better resolution. - return pbdrv_clock_get_ms() * 10; + uint32_t tim_val = TimerCounterGet(SOC_TMR_0_REGS, TMR_TIMER12); + uint32_t t_100_us = tim_val / timer_us_division / 100; + return pbdrv_clock_get_ms() * 10 + t_100_us; } #endif // PBDRV_CONFIG_CLOCK_TIAM1808