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.

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