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.

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