|
@ -137,3 +137,44 @@ void HAL_adc_start_conversion(uint8_t adc_pin); |
|
|
void HAL_idletask(); |
|
|
void HAL_idletask(); |
|
|
void HAL_init(); |
|
|
void HAL_init(); |
|
|
void HAL_init_board(); |
|
|
void HAL_init_board(); |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
// Delay in cycles (used by DELAY_NS / DELAY_US)
|
|
|
|
|
|
//
|
|
|
|
|
|
FORCE_INLINE static void DELAY_CYCLES(uint32_t x) { |
|
|
|
|
|
unsigned long start, ccount, stop; |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* It's important to care for race conditions (and overflows) here. |
|
|
|
|
|
* Race condition example: If `stop` calculates to being close to the upper boundary of |
|
|
|
|
|
* `uint32_t` and if at the same time a longer loop interruption kicks in (e.g. due to other |
|
|
|
|
|
* FreeRTOS tasks or interrupts), `ccount` might overflow (and therefore be below `stop` again) |
|
|
|
|
|
* without the loop ever being able to notice that `ccount` had already been above `stop` once |
|
|
|
|
|
* (and that therefore the number of cycles to delay has already passed). |
|
|
|
|
|
* As DELAY_CYCLES (through DELAY_NS / DELAY_US) is used by software SPI bit banging to drive |
|
|
|
|
|
* LCDs and therefore might be called very, very often, this seemingly improbable situation did |
|
|
|
|
|
* actually happen in reality. It resulted in apparently random print pauses of ~17.9 seconds |
|
|
|
|
|
* (0x100000000 / 240 MHz) or multiples thereof, essentially ruining the current print by causing |
|
|
|
|
|
* large blobs of filament. |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (start) ); |
|
|
|
|
|
stop = start + x; |
|
|
|
|
|
ccount = start; |
|
|
|
|
|
|
|
|
|
|
|
if (stop >= start) { |
|
|
|
|
|
// no overflow, so only loop while in between start and stop:
|
|
|
|
|
|
// 0x00000000 -----------------start****stop-- 0xffffffff
|
|
|
|
|
|
while (ccount >= start && ccount < stop) { |
|
|
|
|
|
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) ); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
// stop did overflow, so only loop while outside of stop and start:
|
|
|
|
|
|
// 0x00000000 **stop-------------------start** 0xffffffff
|
|
|
|
|
|
while (ccount >= start || ccount < stop) { |
|
|
|
|
|
__asm__ __volatile__ ( "rsr %0, ccount" : "=a" (ccount) ); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|