shark_task.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "libs/shark_task.h"
  2. #include "bsp/shark_bsp.h"
  3. #include "bsp/fmc_flash.h"
  4. #include "app/iap.h"
  5. extern uint32_t get_system_sleep_time(void);
  6. static u64 shark_mseconds;
  7. static u32 shark_timer_task_handler(void);
  8. static shark_timer_t shark_timer_head = {
  9. .prev = &shark_timer_head,
  10. .next = &shark_timer_head
  11. };
  12. static shark_task_t shark_task_head = {
  13. .next = &shark_task_head,
  14. .handler = shark_timer_task_handler
  15. };
  16. void SysTick_Handler(void)
  17. {
  18. shark_mseconds++;
  19. }
  20. u64 shark_get_mseconds(void)
  21. {
  22. return shark_mseconds;
  23. }
  24. u32 shark_get_seconds(void){
  25. return shark_mseconds/1000 + get_system_sleep_time();
  26. }
  27. void task_ticks_enable(void)
  28. {
  29. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  30. DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
  31. }
  32. u32 task_ticks_abs(void)
  33. {
  34. return DWT->CYCCNT;
  35. }
  36. u32 task_ticks_rel(u32 start)
  37. {
  38. u32 ticks = DWT->CYCCNT;
  39. if (ticks >= start) {
  40. return ticks - start;
  41. }
  42. return 0xFFFFFFFF - start + ticks + 1;
  43. }
  44. void task_ticks_delay(u32 ticks)
  45. {
  46. u32 start;
  47. start = task_ticks_abs();
  48. while (task_ticks_rel(start) < ticks);
  49. }
  50. void task_udelay(u32 delay)
  51. {
  52. task_ticks_delay(delay * (SystemCoreClock / 1000000));
  53. }
  54. static inline void shark_timer_sync(void)
  55. {
  56. shark_task_head.time = shark_timer_head.next->time;
  57. }
  58. void shark_timer_post(shark_timer_t *timer, u32 delay)
  59. {
  60. shark_timer_t *node;
  61. u64 time;
  62. __disable_irq();
  63. time = shark_mseconds + (delay > 0 ? delay : 1);
  64. if (timer->prev != NULL) {
  65. timer->prev->next = timer->next;
  66. }
  67. if (timer->next != NULL) {
  68. timer->next->prev = timer->prev;
  69. }
  70. for (node = shark_timer_head.next; node != &shark_timer_head; node = node->next) {
  71. if (node->time > time) {
  72. break;
  73. }
  74. }
  75. timer->prev = node->prev;
  76. node->prev->next = timer;
  77. node->prev = timer;
  78. timer->next = node;
  79. timer->time = time;
  80. shark_timer_sync();
  81. __enable_irq();
  82. }
  83. void shark_timer_cancel(shark_timer_t *timer)
  84. {
  85. __disable_irq();
  86. timer->prev->next = timer->next;
  87. timer->next->prev = timer->prev;
  88. timer->next = timer->prev = timer;
  89. shark_timer_sync();
  90. __enable_irq();
  91. }
  92. static u32 shark_timer_task_handler(void)
  93. {
  94. while (1) {
  95. shark_timer_t *timer = shark_timer_head.next;
  96. if (timer->time > shark_mseconds) {
  97. return timer->time - shark_mseconds;
  98. }
  99. if (timer != &shark_timer_head) {
  100. shark_timer_cancel(timer);
  101. timer->handler(timer);
  102. } else {
  103. break;
  104. }
  105. wdog_reload();
  106. }
  107. return 0xFFFFFFFF;
  108. }
  109. void shark_task_add(shark_task_t *task)
  110. {
  111. __disable_irq();
  112. task->next = shark_task_head.next;
  113. shark_task_head.next = task;
  114. __enable_irq();
  115. }
  116. void shark_task_run(void)
  117. {
  118. shark_task_t *head = &shark_task_head;
  119. fmc_iap_write_magic(SHARK_IAP_MAGIC_SUCCESS);
  120. /* setup systick timer for 1000Hz interrupts */
  121. SysTick_Config(SystemCoreClock / 1000);
  122. /* configure the systick handler priority */
  123. NVIC_SetPriority(SysTick_IRQn, 0x00U);
  124. while (1) {
  125. wdog_reload();
  126. if (head->time <= shark_mseconds) {
  127. head->time = shark_mseconds + head->handler();
  128. }
  129. head = head->next;
  130. }
  131. }