From f32693bf4ec20b48786cdc39a8f26c6c93187605 Mon Sep 17 00:00:00 2001 From: Markus Hitter Date: Sat, 1 Aug 2015 14:07:50 +0200 Subject: [PATCH] ARM: extend the SysTick handler to also call dda_clock(). As dda_clock() is potantially too slow for high step rates, we call it with a secondary interrupt with slightly slower priority. This makes sure the slow part is ignored on high system load, still reasonably synchonized with the clock tick. Test: steppers should move and accelerate now. Current binary size: SIZES ARM... lpc1114 FLASH : 7756 bytes 24% RAM : 960 bytes 24% EEPROM : 0 bytes 0% --- timer-arm.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/timer-arm.c b/timer-arm.c index 964ccca..58f9e82 100644 --- a/timer-arm.c +++ b/timer-arm.c @@ -20,6 +20,13 @@ For the system clock, we use SysTickTimer. This timer is made for exactly such purposes. + + Other than AVRs, Cortex-M doesn't allow reentry of interupts. To deal with + this we use another interrupt, PendSV, with slightly lower priority and + without an interrupt source. The possibly lengthy operation in dda_clock() + goes into there and at the end of the SysTick interrupt we simply set PendSV + pending. This way PendSV is executed right after SysTick or, if PendSV is + already running, ignored. */ void timer_init() { @@ -48,6 +55,11 @@ void timer_init() { | SysTick_CTRL_TICKINT_Msk // Enable interrupt. | SysTick_CTRL_CLKSOURCE_Msk; // Run at full CPU clock. + /** + Initialise PendSV for dda_clock(). + */ + NVIC_SetPriority(PendSV_IRQn, 1); // Almost highest priority. + /** Initialise the stepper timer. On ARM we have the comfort of hardware 32-bit timers, so we don't have to artifically extend the timer to this @@ -79,9 +91,17 @@ void timer_init() { void SysTick_Handler(void) { clock_tick(); - #ifndef __ARMEL_NOTYET__ + + SCB->ICSR = SCB_ICSR_PENDSVSET_Msk; // Trigger PendSV_Handler(). +} + +/** System clock interrupt, slow part. + + Here we do potentially lengthy calculations. Must have the same name as in + cmsis-startup_lpc11xx.s +*/ +void PendSV_Handler(void) { dda_clock(); - #endif /* __ARMEL_NOTYET__ */ } /** Step interrupt.