You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
3.7KB

  1. #include "core_pins.h"
  2. #include "arm_math.h" // micros() synchronization
  3. //volatile uint32_t F_CPU = 396000000;
  4. //volatile uint32_t F_BUS = 132000000;
  5. volatile uint32_t systick_millis_count = 0;
  6. volatile uint32_t systick_cycle_count = 0;
  7. uint32_t systick_safe_read; // micros() synchronization
  8. // page 411 says "24 MHz XTALOSC can be the external clock source of SYSTICK"
  9. // Testing shows the frequency is actually 100 kHz - but how? Did NXP really
  10. // hide an undocumented divide-by-240 circuit in the hardware?
  11. #define SYSTICK_EXT_FREQ 100000
  12. #if 0
  13. // moved to EventResponder.cpp
  14. void systick_isr(void)
  15. {
  16. systick_millis_count++;
  17. // MillisTimer::runFromTimer();
  18. //digitalWriteFast(12, HIGH);
  19. //delayMicroseconds(1);
  20. //digitalWriteFast(12, LOW);
  21. }
  22. #endif
  23. #if 0
  24. void millis_init(void)
  25. {
  26. //printf("millis_init %08lX\n", SYST_CALIB);
  27. _VectorsRam[15] = systick_isr;
  28. #ifdef SYSTICK_EXT_FREQ
  29. SYST_RVR = (SYSTICK_EXT_FREQ / 1000) - 1;
  30. SYST_CVR = 0;
  31. SYST_CSR = SYST_CSR_TICKINT | SYST_CSR_ENABLE;
  32. #else
  33. SYST_RVR = (F_CPU / 1000) - 1;
  34. SYST_CVR = 0;
  35. SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE;
  36. #endif
  37. //SCB_SHPR3 = 0x20200000; // Systick = priority 32
  38. //printf("RVR=%lu\r\n", SYST_RVR);
  39. }
  40. #endif
  41. /*void yield(void)
  42. {
  43. }*/
  44. void delay(uint32_t msec)
  45. {
  46. uint32_t start;
  47. if (msec == 0) return;
  48. start = micros();
  49. while (1) {
  50. while ((micros() - start) >= 1000) {
  51. if (--msec == 0) return;
  52. start += 1000;
  53. }
  54. yield();
  55. }
  56. // TODO...
  57. }
  58. uint32_t micros(void)
  59. {
  60. uint32_t ccdelta, usec, smc, scc;
  61. do {
  62. __LDREXW(&systick_safe_read);
  63. smc = systick_millis_count;
  64. scc = systick_cycle_count;
  65. } while ( __STREXW(1, &systick_safe_read));
  66. ccdelta = ARM_DWT_CYCCNT - scc;
  67. uint32_t frac = ccdelta/(F_CPU_ACTUAL/1000000);
  68. if (frac > 999) frac = 999;
  69. usec = 1000*smc + frac;
  70. return usec;
  71. }
  72. #if 0 // kept to compare test to cycle count micro()
  73. uint32_t micros(void)
  74. {
  75. uint32_t msec, tick, elapsed, istatus, usec;
  76. //static uint32_t prev_msec=0;
  77. //static uint32_t prev_istatus=0;
  78. //static uint32_t prev_tick=0;
  79. //static uint32_t prev_elapsed=0;
  80. static uint32_t prev_usec=0;
  81. static int doprint=180;
  82. __disable_irq();
  83. tick = SYST_CVR;
  84. msec = systick_millis_count;
  85. istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
  86. #ifndef SYSTICK_EXT_FREQ
  87. const uint32_t fcpu = F_CPU;
  88. #endif
  89. __enable_irq();
  90. istatus &= SCB_ICSR_PENDSTSET;
  91. #ifdef SYSTICK_EXT_FREQ
  92. if ((istatus & SCB_ICSR_PENDSTSET) && (tick == 0 || tick > (SYSTICK_EXT_FREQ / 2000))) {
  93. #else
  94. if ((istatus & SCB_ICSR_PENDSTSET) && (tick == 0 || tick > (fcpu / 2000))) {
  95. #endif
  96. // systick generated an interrupt at the 1 -> 0 transition, and
  97. // we read it before an ISR could increment systick_millis_count
  98. msec++;
  99. }
  100. #if defined(SYSTICK_EXT_FREQ) && SYSTICK_EXT_FREQ <= 1000000
  101. elapsed = (SYSTICK_EXT_FREQ / 1000) - tick;
  102. if (tick == 0) elapsed = 0;
  103. usec = msec * 1000 + elapsed * (1000000 / SYSTICK_EXT_FREQ);
  104. #elif defined(SYSTICK_EXT_FREQ) && SYSTICK_EXT_FREQ > 1000000
  105. elapsed = (SYSTICK_EXT_FREQ / 1000) - tick;
  106. if (tick == 0) elapsed = 0;
  107. usec = msec * 1000 + elapsed / (SYSTICK_EXT_FREQ / 1000000);
  108. #else
  109. elapsed = (fcpu / 1000) - tick;
  110. if (tick == 0) elapsed = 0;
  111. usec = msec * 1000 + elapsed / (fcpu / 1000000);
  112. #endif
  113. //if (doprint) printf("%lu %lu\r\n", msec, systick);
  114. if (usec < prev_usec && doprint) {
  115. //print("opps\r\n");
  116. //printf("opps then: msec=%lu, systick=%lu, elapsed=%lu, usec=%lu, i=%lx\n",
  117. //prev_msec, prev_tick, prev_elapsed, prev_usec, prev_istatus);
  118. //printf(" now: msec=%lu, systick=%lu, elapsed=%lu, usec=%lu, i=%lx\n",
  119. //msec, tick, elapsed, usec, istatus);
  120. if (doprint > 0) doprint--;
  121. }
  122. //prev_msec = msec;
  123. //prev_elapsed = elapsed;
  124. //prev_tick = tick;
  125. //prev_istatus = istatus;
  126. prev_usec = usec;
  127. return usec;
  128. }
  129. #endif