|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- #include "core_pins.h"
- #include "arm_math.h" // micros() synchronization
-
- //volatile uint32_t F_CPU = 396000000;
- //volatile uint32_t F_BUS = 132000000;
- 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"
- // Testing shows the frequency is actually 100 kHz - but how? Did NXP really
- // hide an undocumented divide-by-240 circuit in the hardware?
- #define SYSTICK_EXT_FREQ 100000
-
- #if 0
- // moved to EventResponder.cpp
- void systick_isr(void)
- {
- systick_millis_count++;
- // MillisTimer::runFromTimer();
- //digitalWriteFast(12, HIGH);
- //delayMicroseconds(1);
- //digitalWriteFast(12, LOW);
- }
- #endif
-
- #if 0
- void millis_init(void)
- {
- //printf("millis_init %08lX\n", SYST_CALIB);
- _VectorsRam[15] = systick_isr;
- #ifdef SYSTICK_EXT_FREQ
- SYST_RVR = (SYSTICK_EXT_FREQ / 1000) - 1;
- SYST_CVR = 0;
- SYST_CSR = SYST_CSR_TICKINT | SYST_CSR_ENABLE;
- #else
- SYST_RVR = (F_CPU / 1000) - 1;
- SYST_CVR = 0;
- SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE;
- #endif
- //SCB_SHPR3 = 0x20200000; // Systick = priority 32
- //printf("RVR=%lu\r\n", SYST_RVR);
- }
- #endif
-
- /*void yield(void)
- {
-
- }*/
-
- void delay(uint32_t msec)
- {
- uint32_t start;
-
- if (msec == 0) return;
- start = micros();
- while (1) {
- while ((micros() - start) >= 1000) {
- if (--msec == 0) return;
- start += 1000;
- }
- yield();
- }
- // 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 msec, tick, elapsed, istatus, usec;
- //static uint32_t prev_msec=0;
- //static uint32_t prev_istatus=0;
- //static uint32_t prev_tick=0;
- //static uint32_t prev_elapsed=0;
- static uint32_t prev_usec=0;
- static int doprint=180;
-
- __disable_irq();
- tick = SYST_CVR;
- msec = systick_millis_count;
- istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
- #ifndef SYSTICK_EXT_FREQ
- const uint32_t fcpu = F_CPU;
- #endif
- __enable_irq();
- istatus &= SCB_ICSR_PENDSTSET;
- #ifdef SYSTICK_EXT_FREQ
- if ((istatus & SCB_ICSR_PENDSTSET) && (tick == 0 || tick > (SYSTICK_EXT_FREQ / 2000))) {
- #else
- if ((istatus & SCB_ICSR_PENDSTSET) && (tick == 0 || tick > (fcpu / 2000))) {
- #endif
- // systick generated an interrupt at the 1 -> 0 transition, and
- // we read it before an ISR could increment systick_millis_count
- msec++;
- }
- #if defined(SYSTICK_EXT_FREQ) && SYSTICK_EXT_FREQ <= 1000000
- elapsed = (SYSTICK_EXT_FREQ / 1000) - tick;
- if (tick == 0) elapsed = 0;
- usec = msec * 1000 + elapsed * (1000000 / SYSTICK_EXT_FREQ);
- #elif defined(SYSTICK_EXT_FREQ) && SYSTICK_EXT_FREQ > 1000000
- elapsed = (SYSTICK_EXT_FREQ / 1000) - tick;
- if (tick == 0) elapsed = 0;
- usec = msec * 1000 + elapsed / (SYSTICK_EXT_FREQ / 1000000);
- #else
- elapsed = (fcpu / 1000) - tick;
- if (tick == 0) elapsed = 0;
- usec = msec * 1000 + elapsed / (fcpu / 1000000);
- #endif
- //if (doprint) printf("%lu %lu\r\n", msec, systick);
- if (usec < prev_usec && doprint) {
- //print("opps\r\n");
- //printf("opps then: msec=%lu, systick=%lu, elapsed=%lu, usec=%lu, i=%lx\n",
- //prev_msec, prev_tick, prev_elapsed, prev_usec, prev_istatus);
- //printf(" now: msec=%lu, systick=%lu, elapsed=%lu, usec=%lu, i=%lx\n",
- //msec, tick, elapsed, usec, istatus);
- if (doprint > 0) doprint--;
- }
- //prev_msec = msec;
- //prev_elapsed = elapsed;
- //prev_tick = tick;
- //prev_istatus = istatus;
- prev_usec = usec;
- return usec;
- }
- #endif
|