CCmicros - micros version using Cycle counterteensy4-core
| // TODO: this doesn't work for IMXRT - no longer using predefined names | // TODO: this doesn't work for IMXRT - no longer using predefined names | ||||
| extern "C" volatile uint32_t systick_millis_count; | extern "C" volatile uint32_t systick_millis_count; | ||||
| extern "C" volatile uint32_t systick_cycle_count; | |||||
| extern "C" uint32_t systick_safe_read; // micros() synchronization | |||||
| extern "C" void systick_isr(void) | extern "C" void systick_isr(void) | ||||
| { | { | ||||
| systick_cycle_count = ARM_DWT_CYCCNT; | |||||
| systick_millis_count++; | systick_millis_count++; | ||||
| MillisTimer::runFromTimer(); | MillisTimer::runFromTimer(); | ||||
| } | } |
| #include "core_pins.h" | #include "core_pins.h" | ||||
| #include "arm_math.h" // micros() synchronization | |||||
| //volatile uint32_t F_CPU = 396000000; | //volatile uint32_t F_CPU = 396000000; | ||||
| //volatile uint32_t F_BUS = 132000000; | //volatile uint32_t F_BUS = 132000000; | ||||
| volatile uint32_t systick_millis_count = 0; | volatile uint32_t systick_millis_count = 0; | ||||
| volatile uint32_t systick_cycle_count = 0; | |||||
| uint32_t systick_safe_read; // micros() synchronization | |||||
| // page 411 says "24 MHz XTALOSC can be the external clock source of SYSTICK" | // page 411 says "24 MHz XTALOSC can be the external clock source of SYSTICK" | ||||
| // Testing shows the frequency is actually 100 kHz - but how? Did NXP really | // Testing shows the frequency is actually 100 kHz - but how? Did NXP really | ||||
| // TODO... | // TODO... | ||||
| } | } | ||||
| uint32_t micros(void) | |||||
| { | |||||
| uint32_t ccdelta, usec, smc, scc; | |||||
| do { | |||||
| __LDREXW(&systick_safe_read); | |||||
| smc = systick_millis_count; | |||||
| scc = systick_cycle_count; | |||||
| } while ( __STREXW(1, &systick_safe_read)); | |||||
| ccdelta = ARM_DWT_CYCCNT - scc; | |||||
| usec = 1000*smc + (ccdelta/(F_CPU_ACTUAL/1000000)); | |||||
| return usec; | |||||
| } | |||||
| #if 0 // kept to compare test to cycle count micro() | |||||
| uint32_t micros(void) | uint32_t micros(void) | ||||
| { | { | ||||
| uint32_t msec, tick, elapsed, istatus, usec; | uint32_t msec, tick, elapsed, istatus, usec; | ||||
| prev_usec = usec; | prev_usec = usec; | ||||
| return usec; | return usec; | ||||
| } | } | ||||
| #endif |
| // the ARM clock to run at different speeds. | // the ARM clock to run at different speeds. | ||||
| #define SYSTICK_EXT_FREQ 100000 | #define SYSTICK_EXT_FREQ 100000 | ||||
| extern volatile uint32_t systick_cycle_count; | |||||
| static void configure_systick(void) | static void configure_systick(void) | ||||
| { | { | ||||
| _VectorsRam[14] = pendablesrvreq_isr; | _VectorsRam[14] = pendablesrvreq_isr; | ||||
| SCB_SHPR3 = 0x20000000; // Systick = priority 32 | SCB_SHPR3 = 0x20000000; // Systick = priority 32 | ||||
| ARM_DEMCR |= ARM_DEMCR_TRCENA; | ARM_DEMCR |= ARM_DEMCR_TRCENA; | ||||
| ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; // turn on cycle counter | ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA; // turn on cycle counter | ||||
| systick_cycle_count = ARM_DWT_CYCCNT; // compiled 0, corrected w/1st systick | |||||
| } | } | ||||
| // R2 | // R2 | ||||
| // R1 | // R1 | ||||
| // R0 | // R0 | ||||
| __attribute__((weak)) | |||||
| void unused_interrupt_vector(void) | void unused_interrupt_vector(void) | ||||
| { | { | ||||
| // TODO: polling Serial to complete buffered transmits | // TODO: polling Serial to complete buffered transmits |