My Marlin configs for Fabrikator Mini and CTC i3 Pro B
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

SWI_INLINE.h 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * File: SWI_INLINE.h
  3. * Author: xxxajk@gmail.com
  4. *
  5. * Created on December 5, 2014, 9:40 AM
  6. *
  7. * This is the actual library.
  8. * There are no 'c' or 'cpp' files.
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. #ifdef DYN_SWI_H
  24. #ifndef SWI_INLINE_H
  25. #define SWI_INLINE_H
  26. #ifndef SWI_MAXIMUM_ALLOWED
  27. #define SWI_MAXIMUM_ALLOWED 4
  28. #endif
  29. #if defined(__arm__) || defined(ARDUINO_ARCH_PIC32)
  30. static char dyn_SWI_initied = 0;
  31. static dyn_SWI* dyn_SWI_LIST[SWI_MAXIMUM_ALLOWED];
  32. static dyn_SWI* dyn_SWI_EXEC[SWI_MAXIMUM_ALLOWED];
  33. #ifdef __arm__
  34. #ifdef __USE_CMSIS_VECTORS__
  35. extern "C" {
  36. void (*_VectorsRam[VECTORTABLE_SIZE])(void)__attribute__((aligned(VECTORTABLE_ALIGNMENT)));
  37. }
  38. #else
  39. __attribute__((always_inline)) static inline void __DSB() {
  40. __asm__ volatile ("dsb");
  41. }
  42. #endif // defined(__USE_CMSIS_VECTORS__)
  43. #else // defined(__arm__)
  44. __attribute__((always_inline)) static inline void __DSB() {
  45. __asm__ volatile ("sync" : : : "memory");
  46. }
  47. #endif // defined(__arm__)
  48. /**
  49. * Execute queued class ISR routines.
  50. */
  51. #ifdef ARDUINO_ARCH_PIC32
  52. static p32_regset *ifs = ((p32_regset *) & IFS0) + (SWI_IRQ_NUM / 32); //interrupt flag register set
  53. static p32_regset *iec = ((p32_regset *) & IEC0) + (SWI_IRQ_NUM / 32); //interrupt enable control reg set
  54. static uint32_t swibit = 1 << (SWI_IRQ_NUM % 32);
  55. void
  56. #ifdef __PIC32MZXX__
  57. __attribute__((nomips16,at_vector(SWI_VECTOR),interrupt(SWI_IPL)))
  58. #else
  59. __attribute__((interrupt(),nomips16))
  60. #endif
  61. softISR() {
  62. #else
  63. #ifdef ARDUINO_spresense_ast
  64. unsigned int softISR() {
  65. #else
  66. void softISR() {
  67. #endif
  68. #endif
  69. //
  70. // TO-DO: Perhaps limit to 8, and inline this?
  71. //
  72. // Make a working copy, while clearing the queue.
  73. noInterrupts();
  74. #ifdef ARDUINO_ARCH_PIC32
  75. //ifs->clr = swibit;
  76. #endif
  77. for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) {
  78. dyn_SWI_EXEC[i] = dyn_SWI_LIST[i];
  79. dyn_SWI_LIST[i] = NULL;
  80. }
  81. __DSB();
  82. interrupts();
  83. // Execute each class SWI
  84. for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) {
  85. if(dyn_SWI_EXEC[i]) {
  86. #ifdef __DYN_SWI_DEBUG_LED__
  87. digitalWrite(__DYN_SWI_DEBUG_LED__, HIGH);
  88. #endif
  89. dyn_SWI_EXEC[i]->dyn_SWISR();
  90. #ifdef __DYN_SWI_DEBUG_LED__
  91. digitalWrite(__DYN_SWI_DEBUG_LED__, LOW);
  92. #endif
  93. }
  94. }
  95. #ifdef ARDUINO_ARCH_PIC32
  96. noInterrupts();
  97. if(!dyn_SWI_EXEC[0]) ifs->clr = swibit;
  98. interrupts();
  99. #endif
  100. #ifdef ARDUINO_spresense_ast
  101. return 0;
  102. #endif
  103. }
  104. #define DDSB() __DSB()
  105. #endif
  106. #ifdef __arm__
  107. #ifndef interruptsStatus
  108. #define interruptsStatus() __interruptsStatus()
  109. static inline unsigned char __interruptsStatus() __attribute__((always_inline, unused));
  110. static inline unsigned char __interruptsStatus() {
  111. unsigned int primask;
  112. asm volatile ("mrs %0, primask" : "=r" (primask));
  113. if(primask) return 0;
  114. return 1;
  115. }
  116. #endif
  117. /**
  118. * Initialize the Dynamic (class) Software Interrupt
  119. */
  120. static void Init_dyn_SWI() {
  121. if(!dyn_SWI_initied) {
  122. #ifdef __USE_CMSIS_VECTORS__
  123. uint32_t *X_Vectors = (uint32_t*)SCB->VTOR;
  124. for(int i = 0; i < VECTORTABLE_SIZE; i++) {
  125. _VectorsRam[i] = reinterpret_cast<void (*)()>(X_Vectors[i]); /* copy vector table to RAM */
  126. }
  127. /* relocate vector table */
  128. noInterrupts();
  129. SCB->VTOR = reinterpret_cast<uint32_t>(&_VectorsRam);
  130. DDSB();
  131. interrupts();
  132. #endif
  133. #ifndef ARDUINO_spresense_ast
  134. for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) dyn_SWI_LIST[i] = NULL;
  135. noInterrupts();
  136. _VectorsRam[SWI_IRQ_NUM + 16] = reinterpret_cast<void (*)()>(softISR);
  137. DDSB();
  138. interrupts();
  139. NVIC_SET_PRIORITY(SWI_IRQ_NUM, 255);
  140. NVIC_ENABLE_IRQ(SWI_IRQ_NUM);
  141. #endif
  142. #ifdef __DYN_SWI_DEBUG_LED__
  143. pinMode(__DYN_SWI_DEBUG_LED__, OUTPUT);
  144. digitalWrite(__DYN_SWI_DEBUG_LED__, LOW);
  145. #endif
  146. dyn_SWI_initied = 1;
  147. }
  148. }
  149. /**
  150. * @param klass class that extends dyn_SWI
  151. * @return 0 on queue full, else returns queue position (ones based)
  152. */
  153. int exec_SWI(const dyn_SWI* klass) {
  154. int rc = 0;
  155. uint8_t irestore = interruptsStatus();
  156. // Allow use from inside a critical section...
  157. // ... and prevent races if also used inside an ISR
  158. noInterrupts();
  159. for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) {
  160. if(!dyn_SWI_LIST[i]) {
  161. rc = 1 + i; // Success!
  162. dyn_SWI_LIST[i] = (dyn_SWI*)klass;
  163. #ifndef ARDUINO_spresense_ast
  164. if(!NVIC_GET_PENDING(SWI_IRQ_NUM)) NVIC_SET_PENDING(SWI_IRQ_NUM);
  165. #else
  166. // Launch 1-shot timer as an emulated SWI
  167. // Hopefully the value of Zero is legal.
  168. // 1 microsecond latency would suck!
  169. attachTimerInterrupt(softISR, 100);
  170. #endif
  171. DDSB();
  172. break;
  173. }
  174. }
  175. // Restore interrupts, if they were on.
  176. if(irestore) interrupts();
  177. return rc;
  178. }
  179. #elif defined(ARDUINO_ARCH_PIC32)
  180. /**
  181. * Initialize the Dynamic (class) Software Interrupt
  182. */
  183. static void Init_dyn_SWI() {
  184. if(!dyn_SWI_initied) {
  185. uint32_t sreg = disableInterrupts();
  186. setIntVector(SWI_VECTOR, softISR);
  187. setIntPriority(SWI_VECTOR, 1, 1); // Lowest priority, ever.
  188. ifs->clr = swibit;
  189. iec->clr = swibit;
  190. iec->set = swibit;
  191. restoreInterrupts(sreg);
  192. #ifdef __DYN_SWI_DEBUG_LED__
  193. pinMode(__DYN_SWI_DEBUG_LED__, OUTPUT);
  194. UHS_PIN_WRITE(__DYN_SWI_DEBUG_LED__, LOW);
  195. #endif
  196. }
  197. }
  198. /**
  199. * @param klass class that extends dyn_SWI
  200. * @return 0 on queue full, else returns queue position (ones based)
  201. */
  202. int exec_SWI(const dyn_SWI* klass) {
  203. int rc = 0;
  204. uint32_t sreg = disableInterrupts();
  205. for(int i = 0; i < SWI_MAXIMUM_ALLOWED; i++) {
  206. if(!dyn_SWI_LIST[i]) {
  207. rc = 1 + i; // Success!
  208. dyn_SWI_LIST[i] = (dyn_SWI*)klass;
  209. if(!(ifs->reg & swibit)) ifs->set = swibit;
  210. ;
  211. break;
  212. }
  213. }
  214. restoreInterrupts(sreg);
  215. return rc;
  216. }
  217. #endif /* defined(__arm__) */
  218. #endif /* SWI_INLINE_H */
  219. #else
  220. #error "Never include SWI_INLINE.h directly, include dyn_SWI.h instead"
  221. #endif