Advertisement
anon2110

massage.c

Jun 27th, 2018
215
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.51 KB | None | 0 0
  1. #include <avr/io.h>
  2. #include <util/atomic.h>
  3. #include "messages.h"
  4. #include "globals.h"
  5.  
  6. volatile iTimer lTimer[maxTimers]; // список таймеров
  7. volatile iHandler lHandler[maxHandlers]; // список обработчиков
  8. volatile uint8_t numHandlers, numTimers;
  9.  
  10. volatile iMessage lMessage[maxMessages]; // буфер сообщений
  11. volatile uint16_t lMesPointer, hMesPointer; // указатели на начало и конец буфера
  12.  
  13. // установка обработчика события
  14. // вызывается: setHandler(MSG_KEY_PRESS, &checkKey);
  15. void setHandler(msg_num msg, handler hnd) {
  16. ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  17. if (numHandlers < maxHandlers) {
  18. lHandler[numHandlers].hnd = hnd; // и регистрирем обработчик
  19. lHandler[numHandlers].msg = msg;
  20. numHandlers++;
  21. }
  22. }
  23. }
  24.  
  25. // снятие обработчика события
  26. // вызывается: killHandler(MSG_KEY_PRESS, &checkKey);
  27. // удаляет один последний обработчик.
  28. void killHandler(msg_num msg, handler hnd) {
  29. if (numHandlers==0)
  30. return;
  31. ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  32. int8_t i, j;
  33. j = 0;
  34. for (i = numHandlers-1; i >= 0; i--) {
  35.  
  36. if ((lHandler[i].msg == msg) && (lHandler[i].hnd == hnd)) {
  37.  
  38. // сдвигаем все записи к началу списка, чтобы дырок не было
  39. for (j = i; j < numHandlers-1 ; j++) {
  40. lHandler[j].msg = lHandler[j + 1].msg;
  41. lHandler[j].hnd = lHandler[j + 1].hnd;
  42. }
  43. numHandlers--;
  44. break;
  45. }
  46. }
  47.  
  48. }
  49. }
  50.  
  51. // занести событие в очередь
  52. // пример вызова: sendMessage(MSG_KEY_PRESS, KEY_MENU)
  53. void sendMessage(msg_num msg, msg_par par) {
  54.  
  55. ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  56. hMesPointer = (hMesPointer + 1) & (maxMessages - 1); // сдвигаем указатель головы
  57.  
  58. lMessage[hMesPointer].msg = msg; // заносим событие и параметр
  59. lMessage[hMesPointer].par = par;
  60. if (hMesPointer == lMesPointer) { // догнали начало очереди, убиваем необработанное сообытие
  61. lMesPointer = (lMesPointer + 1) & (maxMessages - 1);
  62. }
  63. }
  64. }
  65. ;
  66.  
  67. // обработка событий
  68. void dispatchMessage(void) {
  69. int8_t i;
  70. uint8_t res;
  71. msg_num msg;
  72. msg_par par;
  73.  
  74. if (hMesPointer == lMesPointer) { // если пустая очередь - возврат
  75. return;
  76. }
  77.  
  78. ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  79. lMesPointer = (lMesPointer + 1) & (maxMessages - 1); // сдвинем указатель
  80.  
  81. msg = lMessage[lMesPointer].msg;
  82. par = lMessage[lMesPointer].par;
  83. }
  84.  
  85. if (msg != 0 && numHandlers > 0) {
  86. for (i = numHandlers - 1; i >= 0; i--) { // просматриваем обработчики с конца
  87. if (lHandler[i].msg == msg) { // последний занесенный имеет приоритет
  88. res = lHandler[i].hnd(par); // вызываем обработчик
  89. if (res) { // если обработчик вернул 1, перываем обработку события
  90. break;
  91. }
  92. }
  93. }
  94. }
  95. }
  96.  
  97. // установить таймер
  98. // пример вызова: setTimer(MSG_LCD_REFRESH, 0, 50);
  99. void setTimer(msg_num msg, msg_par par, uint16_t time) {
  100. uint8_t i, firstFree;
  101. if (time == 0) {
  102. sendMessage(msg, par);
  103. } else {
  104.  
  105. ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  106. firstFree = numTimers + 1;
  107.  
  108. for (i = 0; i <= numTimers; i++) { // ищем установленный таймер
  109. if (lTimer[i].msg == 0) {
  110. firstFree = i;
  111. } else { // если нашли - обновляем время
  112. //if ((lTimer[i].msg == msg) && (lTimer[i].par == par)) {
  113. if (lTimer[i].msg == msg) {
  114. lTimer[i].time = time;
  115. lTimer[i].timeOrigin = time;
  116. lTimer[i].par = par;
  117. firstFree = maxTimers + 1;
  118. break;
  119. }
  120. }
  121. }
  122. if (firstFree <= maxTimers) { // иначе - просто добавляем новый
  123. lTimer[firstFree].msg = msg;
  124. lTimer[firstFree].par = par;
  125. lTimer[firstFree].time = time;
  126. lTimer[firstFree].timeOrigin = time;
  127.  
  128. if (firstFree > numTimers)
  129. numTimers = firstFree;
  130. }
  131. }
  132. }
  133. }
  134.  
  135. // убить таймер
  136. // особенность - убивает все установленные таймеры на данное событие,
  137. // не зависимо от параметра события
  138. void killTimer(msg_num msg) {
  139. uint8_t i;
  140. ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
  141. for (i = 0; i < maxTimers; i++) {
  142. if (lTimer[i].msg == msg) {
  143. lTimer[i].msg = 0;
  144. }
  145. }
  146. while ((lTimer[numTimers].msg == 0) && (numTimers > 0))
  147. numTimers--;
  148. }
  149. }
  150.  
  151. // диспетчер таймеров
  152.  
  153. void dispatchTimer() {
  154. uint8_t i;
  155.  
  156. for (i = 0; i <= numTimers; i++) {
  157. if (lTimer[i].msg == 0)
  158. continue;
  159.  
  160. if (lTimer[i].time > 0) { // если не пришло время
  161. lTimer[i].time--; // просто уменьшаем время
  162. } else {
  163. sendMessage(lTimer[i].msg, lTimer[i].par); // создаем событие
  164. lTimer[i].time = lTimer[i].timeOrigin;
  165. }
  166. }
  167. }
  168.  
  169. void initMessages() {
  170. numHandlers = 0;
  171. numTimers = 0;
  172. lMesPointer = 0;
  173. hMesPointer = 0;
  174.  
  175. // главный таймер
  176. TCCR2 = _BV(WGM21) | _BV(CS22) | _BV(CS20);
  177. OCR2 = F_CPU / 102400; // период 1/100 сек, делитель 1/1024
  178. TIMSK |= _BV(OCIE2);
  179. }
  180.  
  181. ISR(TIMER2_COMP_vect)
  182. {
  183. dispatchTimer(); // а вот и диспетчер
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement