time.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include "all-headers.h"
  2. // Configure systick
  3. static void startSystick (BOOT_MODE) {
  4. // Configure Systick
  5. SYST_RVR = CPU_MHZ * 1000 - 1 ; // Underflow every ms
  6. SYST_CVR = 0 ;
  7. SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_ENABLE ;
  8. // Configure and chain PIT0 and PIT1 for 64-bit counting
  9. // Power on PIT
  10. SIM_SCGC6 |= SIM_SCGC6_PIT ;
  11. // Enable PIT module
  12. PIT_MCR = 0 ;
  13. // Disable PIT0 and PIT1
  14. PIT_TCTRL (0) = 0 ;
  15. PIT_TCTRL (1) = 0 ;
  16. // PIT0 and PIT1 down-count: initialize them with all 1's
  17. PIT_LDVAL (0) = UINT32_MAX ;
  18. PIT_LDVAL (1) = UINT32_MAX ;
  19. // Enable PIT0 and PIT1: start counting, chain PI1 to PIT0, no interrupt
  20. PIT_TCTRL (1) = PIT_TCTRL_CHN | PIT_TCTRL_TEN ;
  21. PIT_TCTRL (0) = PIT_TCTRL_TEN ;
  22. }
  23. MACRO_BOOT_ROUTINE (startSystick) ;
  24. static void activateSystickInterrupt (INIT_MODE) {
  25. SYST_CSR |= SYST_CSR_TICKINT ;
  26. }
  27. MACRO_INIT_ROUTINE (activateSystickInterrupt) ;
  28. // micros current value
  29. uint64_t section_micros (SECTION_MODE) {
  30. // To obtain the correct value, first read LTMR64H and then LTMR64L
  31. uint64_t result = PIT_LTMR64H ;
  32. result <<= 32 ;
  33. result |= PIT_LTMR64L ;
  34. // PIT0 and PIT1 actually downcount
  35. result = ~ result ;
  36. // Divide by the clock frequency in MHz for getting microsecond count
  37. return result / busMHZ () ;
  38. }
  39. // busyWaitDuring — INIT MODE
  40. void busyWaitDuring_initMode (INIT_MODE_ const uint32_t inDelayMS) {
  41. const uint32_t COUNTFLAG_MASK = 1 << 16 ;
  42. for (uint32_t i=0 ; i<inDelayMS ; i++) {
  43. while ((SYST_CSR & COUNTFLAG_MASK) == 0) {} // Busy wait, polling COUNTFLAG
  44. }
  45. }
  46. // Configure systick — FAULT MODE
  47. void configureSystick_faultMode (FAULT_MODE) {
  48. // Configure Systick
  49. SYST_CSR = 0 ; // Stop systick
  50. SYST_RVR = CPU_MHZ * 1000 - 1 ; // Underflow every ms
  51. SYST_CVR = 0 ;
  52. SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_ENABLE ;
  53. }
  54. // busyWaitDuring — FAULT MODE
  55. void busyWaitDuring_faultMode (FAULT_MODE_ const uint32_t inDelayMS) {
  56. const uint32_t COUNTFLAG_MASK = 1 << 16 ;
  57. for (uint32_t i=0 ; i<inDelayMS ; i++) {
  58. while ((SYST_CSR & COUNTFLAG_MASK) == 0) {} // Busy wait, polling COUNTFLAG
  59. }
  60. }
  61. // millis — ANY MODE
  62. static volatile uint32_t gUptime ;
  63. uint32_t millis (ANY_MODE) {
  64. return gUptime ;
  65. }
  66. // systick — ANY MODE
  67. uint32_t systick (ANY_MODE) {
  68. return SYST_CVR ;
  69. }
  70. // SYSTICK interrupt service routine
  71. void systickInterruptServiceRoutine (IRQ_MODE) {
  72. const uint32_t newUptime = gUptime + 1 ;
  73. gUptime = newUptime ;
  74. // Run real.time.interrupt.routine.array section routines
  75. extern void (* __real_time_interrupt_routine_array_start) (IRQ_MODE_ const uint32_t inUptime) ;
  76. extern void (* __real_time_interrupt_routine_array_end) (IRQ_MODE_ const uint32_t inUptime) ;
  77. void (* * ptr) (IRQ_MODE_ const uint32_t) = & __real_time_interrupt_routine_array_start ;
  78. while (ptr != & __real_time_interrupt_routine_array_end) {
  79. (* ptr) (MODE_ newUptime) ;
  80. ptr ++ ;
  81. }
  82. }
  83. // busyWaitDuring, busyWaitUntil — USER MODE
  84. void waitDuring (USER_MODE_ const uint32_t inDelayMS) {
  85. waitUntil (MODE_ gUptime + inDelayMS) ;
  86. }
  87. void service_waitUntil (KERNEL_MODE_ const uint32_t inDeadlineMS) {
  88. if (inDeadlineMS > gUptime) {
  89. kernel_blockOnDeadline(MODE_ inDeadlineMS);
  90. }
  91. }