From a33910467b5d3fa43c3bd9c2c5c1212b9193a4e0 Mon Sep 17 00:00:00 2001 From: R Date: Mon, 14 Jul 2025 09:29:03 +0100 Subject: [PATCH 1/6] pbio/drv/clock/clock_ev3: Clear the correct interrupt flag The interrupt enable and interrupt status bits are not the same. There is no need to disable and re-enable the interrupt if clearing the correct bit. --- lib/pbio/drv/clock/clock_ev3.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/pbio/drv/clock/clock_ev3.c b/lib/pbio/drv/clock/clock_ev3.c index 193b24297..5800810ed 100644 --- a/lib/pbio/drv/clock/clock_ev3.c +++ b/lib/pbio/drv/clock/clock_ev3.c @@ -41,20 +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); + TimerIntStatusClear(SOC_TMR_0_REGS, TMR_INTSTAT34_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); } /** From cb53d6222c05c019b3ec4276939a32d2261f098f Mon Sep 17 00:00:00 2001 From: R Date: Mon, 14 Jul 2025 09:55:13 +0100 Subject: [PATCH 2/6] pbio/drv/clock/clock_ev3: Remove unnecessary use of reload Because the time period never changes, there is no reason to use reload --- lib/pbio/drv/clock/clock_ev3.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/pbio/drv/clock/clock_ev3.c b/lib/pbio/drv/clock/clock_ev3.c index 5800810ed..968fd2354 100644 --- a/lib/pbio/drv/clock/clock_ev3.c +++ b/lib/pbio/drv/clock/clock_ev3.c @@ -65,7 +65,7 @@ void systick_suspend(void) { */ void systick_resume(void) { /* Enable the timer interrupt */ - TimerEnable(SOC_TMR_0_REGS, TMR_TIMER34, TMR_ENABLE_CONTRELOAD); + TimerEnable(SOC_TMR_0_REGS, TMR_TIMER34, TMR_ENABLE_CONT); } /** @@ -81,7 +81,6 @@ 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); /* Register the Timer ISR */ IntRegister(SYS_INT_TINT34_0, systick_isr_C); @@ -96,7 +95,7 @@ void pbdrv_clock_init(void) { TimerIntEnable(SOC_TMR_0_REGS, TMR_INT_TMR34_NON_CAPT_MODE); /* Start the timer */ - TimerEnable(SOC_TMR_0_REGS, TMR_TIMER34, TMR_ENABLE_CONTRELOAD); + TimerEnable(SOC_TMR_0_REGS, TMR_TIMER34, TMR_ENABLE_CONT); } uint32_t pbdrv_clock_get_us(void) { From 5ece1d3afbed02e8acb7e64515fec6c84583b642 Mon Sep 17 00:00:00 2001 From: R Date: Mon, 14 Jul 2025 10:13:30 +0100 Subject: [PATCH 3/6] pbio/drv/clock/clock_ev3: Stop depending on boot process to set up prescaler --- lib/pbio/drv/clock/clock_ev3.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/pbio/drv/clock/clock_ev3.c b/lib/pbio/drv/clock/clock_ev3.c index 968fd2354..dced79218 100644 --- a/lib/pbio/drv/clock/clock_ev3.c +++ b/lib/pbio/drv/clock/clock_ev3.c @@ -21,16 +21,15 @@ #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; /** * The current tick in milliseconds @@ -80,7 +79,8 @@ 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); + TimerPreScalarCount34Set(SOC_TMR_0_REGS, 0); + TimerPeriodSet(SOC_TMR_0_REGS, TMR_TIMER34, timer_ms_period); /* Register the Timer ISR */ IntRegister(SYS_INT_TINT34_0, systick_isr_C); From fa4bbe85b382712262d9de65db2c88d2659c71e4 Mon Sep 17 00:00:00 2001 From: R Date: Mon, 14 Jul 2025 10:17:32 +0100 Subject: [PATCH 4/6] pbio/drv/clock/clock_ev3: Switch to timer 12 instead of 34 The PRU1 code which will be added in the future expects the 34 part of Timer0 to count with a period which is a multiple of 256*256 in order to generate accurate PWM widths. We switch the system tick in order to not conflict with it. --- lib/pbio/drv/clock/clock_ev3.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/lib/pbio/drv/clock/clock_ev3.c b/lib/pbio/drv/clock/clock_ev3.c index dced79218..c64476469 100644 --- a/lib/pbio/drv/clock/clock_ev3.c +++ b/lib/pbio/drv/clock/clock_ev3.c @@ -41,8 +41,8 @@ volatile uint32_t systick_ms = 0; */ void systick_isr_C(void) { /* Clear the interrupt status in AINTC and in timer */ - IntSystemStatusClear(SYS_INT_TINT34_0); - TimerIntStatusClear(SOC_TMR_0_REGS, TMR_INTSTAT34_TIMER_NON_CAPT); + IntSystemStatusClear(SYS_INT_TINT12_0); + TimerIntStatusClear(SOC_TMR_0_REGS, TMR_INTSTAT12_TIMER_NON_CAPT); ++systick_ms; @@ -56,7 +56,7 @@ void systick_isr_C(void) { */ void systick_suspend(void) { /* Disable the timer interrupt */ - TimerDisable(SOC_TMR_0_REGS, TMR_TIMER34); + TimerDisable(SOC_TMR_0_REGS, TMR_TIMER12); } /** @@ -64,7 +64,7 @@ void systick_suspend(void) { */ void systick_resume(void) { /* Enable the timer interrupt */ - TimerEnable(SOC_TMR_0_REGS, TMR_TIMER34, TMR_ENABLE_CONT); + TimerEnable(SOC_TMR_0_REGS, TMR_TIMER12, TMR_ENABLE_CONT); } /** @@ -79,23 +79,22 @@ void pbdrv_clock_init(void) { /* Set up the timer */ TimerConfigure(SOC_TMR_0_REGS, TMR_CFG_32BIT_UNCH_CLK_BOTH_INT); - TimerPreScalarCount34Set(SOC_TMR_0_REGS, 0); - TimerPeriodSet(SOC_TMR_0_REGS, TMR_TIMER34, timer_ms_period); + 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_CONT); + TimerEnable(SOC_TMR_0_REGS, TMR_TIMER12, TMR_ENABLE_CONT); } uint32_t pbdrv_clock_get_us(void) { From 70e439c867f3e8ffd366f4c42a5ce229bd068350 Mon Sep 17 00:00:00 2001 From: R Date: Mon, 14 Jul 2025 10:21:36 +0100 Subject: [PATCH 5/6] pbio/drv/clock/clock_ev3: Remove timer suspend functions --- lib/pbio/drv/clock/clock_ev3.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/pbio/drv/clock/clock_ev3.c b/lib/pbio/drv/clock/clock_ev3.c index c64476469..15eb58126 100644 --- a/lib/pbio/drv/clock/clock_ev3.c +++ b/lib/pbio/drv/clock/clock_ev3.c @@ -50,23 +50,6 @@ void systick_isr_C(void) { pbio_os_request_poll(); } -/** - * Disable the timer and therefore the systick - * - */ -void systick_suspend(void) { - /* Disable the timer interrupt */ - TimerDisable(SOC_TMR_0_REGS, TMR_TIMER12); -} - -/** - * Enable the timer and therefore the systick - */ -void systick_resume(void) { - /* Enable the timer interrupt */ - TimerEnable(SOC_TMR_0_REGS, TMR_TIMER12, TMR_ENABLE_CONT); -} - /** * Initialize the systick module, i.e. the hardware timer of the SoC * From 6a40bb6f146cdcc34cf0c12eec5bcb20409f001b Mon Sep 17 00:00:00 2001 From: R Date: Mon, 14 Jul 2025 10:26:04 +0100 Subject: [PATCH 6/6] pbio/drv/clock/clock_ev3: Implement finer-resolution timer values --- lib/pbio/drv/clock/clock_ev3.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/pbio/drv/clock/clock_ev3.c b/lib/pbio/drv/clock/clock_ev3.c index 15eb58126..75dd19883 100644 --- a/lib/pbio/drv/clock/clock_ev3.c +++ b/lib/pbio/drv/clock/clock_ev3.c @@ -30,6 +30,7 @@ // 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 @@ -81,8 +82,9 @@ void pbdrv_clock_init(void) { } 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) { @@ -90,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