Teensy 4.1 core updated for C++20
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.

преди 11 години
преди 10 години
преди 11 години
преди 9 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 9 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 9 години
преди 9 години
преди 10 години
преди 11 години
преди 9 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 11 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 11 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 11 години
преди 9 години
преди 10 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 9 години
преди 9 години
преди 10 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 9 години
преди 9 години
преди 11 години
преди 11 години
преди 11 години
преди 10 години
преди 9 години
преди 10 години
преди 9 години
преди 9 години
преди 10 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 10 години
преди 9 години
преди 9 години
преди 11 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 9 години
преди 11 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 11 години
преди 10 години
преди 9 години
преди 9 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 9 години
преди 11 години
преди 10 години
преди 9 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 10 години
преди 11 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233
  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2013 PJRC.COM, LLC.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #include "core_pins.h"
  31. #include "pins_arduino.h"
  32. #include "HardwareSerial.h"
  33. #if defined(KINETISK)
  34. #define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
  35. #define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
  36. //#define GPIO_SET_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 1)
  37. //#define GPIO_CLR_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 0)
  38. const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
  39. {GPIO_BITBAND_PTR(CORE_PIN0_PORTREG, CORE_PIN0_BIT), &CORE_PIN0_CONFIG},
  40. {GPIO_BITBAND_PTR(CORE_PIN1_PORTREG, CORE_PIN1_BIT), &CORE_PIN1_CONFIG},
  41. {GPIO_BITBAND_PTR(CORE_PIN2_PORTREG, CORE_PIN2_BIT), &CORE_PIN2_CONFIG},
  42. {GPIO_BITBAND_PTR(CORE_PIN3_PORTREG, CORE_PIN3_BIT), &CORE_PIN3_CONFIG},
  43. {GPIO_BITBAND_PTR(CORE_PIN4_PORTREG, CORE_PIN4_BIT), &CORE_PIN4_CONFIG},
  44. {GPIO_BITBAND_PTR(CORE_PIN5_PORTREG, CORE_PIN5_BIT), &CORE_PIN5_CONFIG},
  45. {GPIO_BITBAND_PTR(CORE_PIN6_PORTREG, CORE_PIN6_BIT), &CORE_PIN6_CONFIG},
  46. {GPIO_BITBAND_PTR(CORE_PIN7_PORTREG, CORE_PIN7_BIT), &CORE_PIN7_CONFIG},
  47. {GPIO_BITBAND_PTR(CORE_PIN8_PORTREG, CORE_PIN8_BIT), &CORE_PIN8_CONFIG},
  48. {GPIO_BITBAND_PTR(CORE_PIN9_PORTREG, CORE_PIN9_BIT), &CORE_PIN9_CONFIG},
  49. {GPIO_BITBAND_PTR(CORE_PIN10_PORTREG, CORE_PIN10_BIT), &CORE_PIN10_CONFIG},
  50. {GPIO_BITBAND_PTR(CORE_PIN11_PORTREG, CORE_PIN11_BIT), &CORE_PIN11_CONFIG},
  51. {GPIO_BITBAND_PTR(CORE_PIN12_PORTREG, CORE_PIN12_BIT), &CORE_PIN12_CONFIG},
  52. {GPIO_BITBAND_PTR(CORE_PIN13_PORTREG, CORE_PIN13_BIT), &CORE_PIN13_CONFIG},
  53. {GPIO_BITBAND_PTR(CORE_PIN14_PORTREG, CORE_PIN14_BIT), &CORE_PIN14_CONFIG},
  54. {GPIO_BITBAND_PTR(CORE_PIN15_PORTREG, CORE_PIN15_BIT), &CORE_PIN15_CONFIG},
  55. {GPIO_BITBAND_PTR(CORE_PIN16_PORTREG, CORE_PIN16_BIT), &CORE_PIN16_CONFIG},
  56. {GPIO_BITBAND_PTR(CORE_PIN17_PORTREG, CORE_PIN17_BIT), &CORE_PIN17_CONFIG},
  57. {GPIO_BITBAND_PTR(CORE_PIN18_PORTREG, CORE_PIN18_BIT), &CORE_PIN18_CONFIG},
  58. {GPIO_BITBAND_PTR(CORE_PIN19_PORTREG, CORE_PIN19_BIT), &CORE_PIN19_CONFIG},
  59. {GPIO_BITBAND_PTR(CORE_PIN20_PORTREG, CORE_PIN20_BIT), &CORE_PIN20_CONFIG},
  60. {GPIO_BITBAND_PTR(CORE_PIN21_PORTREG, CORE_PIN21_BIT), &CORE_PIN21_CONFIG},
  61. {GPIO_BITBAND_PTR(CORE_PIN22_PORTREG, CORE_PIN22_BIT), &CORE_PIN22_CONFIG},
  62. {GPIO_BITBAND_PTR(CORE_PIN23_PORTREG, CORE_PIN23_BIT), &CORE_PIN23_CONFIG},
  63. {GPIO_BITBAND_PTR(CORE_PIN24_PORTREG, CORE_PIN24_BIT), &CORE_PIN24_CONFIG},
  64. {GPIO_BITBAND_PTR(CORE_PIN25_PORTREG, CORE_PIN25_BIT), &CORE_PIN25_CONFIG},
  65. {GPIO_BITBAND_PTR(CORE_PIN26_PORTREG, CORE_PIN26_BIT), &CORE_PIN26_CONFIG},
  66. {GPIO_BITBAND_PTR(CORE_PIN27_PORTREG, CORE_PIN27_BIT), &CORE_PIN27_CONFIG},
  67. {GPIO_BITBAND_PTR(CORE_PIN28_PORTREG, CORE_PIN28_BIT), &CORE_PIN28_CONFIG},
  68. {GPIO_BITBAND_PTR(CORE_PIN29_PORTREG, CORE_PIN29_BIT), &CORE_PIN29_CONFIG},
  69. {GPIO_BITBAND_PTR(CORE_PIN30_PORTREG, CORE_PIN30_BIT), &CORE_PIN30_CONFIG},
  70. {GPIO_BITBAND_PTR(CORE_PIN31_PORTREG, CORE_PIN31_BIT), &CORE_PIN31_CONFIG},
  71. {GPIO_BITBAND_PTR(CORE_PIN32_PORTREG, CORE_PIN32_BIT), &CORE_PIN32_CONFIG},
  72. {GPIO_BITBAND_PTR(CORE_PIN33_PORTREG, CORE_PIN33_BIT), &CORE_PIN33_CONFIG},
  73. #ifdef CORE_PIN34_PORTREG
  74. {GPIO_BITBAND_PTR(CORE_PIN34_PORTREG, CORE_PIN34_BIT), &CORE_PIN34_CONFIG},
  75. {GPIO_BITBAND_PTR(CORE_PIN35_PORTREG, CORE_PIN35_BIT), &CORE_PIN35_CONFIG},
  76. {GPIO_BITBAND_PTR(CORE_PIN36_PORTREG, CORE_PIN36_BIT), &CORE_PIN36_CONFIG},
  77. {GPIO_BITBAND_PTR(CORE_PIN37_PORTREG, CORE_PIN37_BIT), &CORE_PIN37_CONFIG},
  78. {GPIO_BITBAND_PTR(CORE_PIN38_PORTREG, CORE_PIN38_BIT), &CORE_PIN38_CONFIG},
  79. {GPIO_BITBAND_PTR(CORE_PIN39_PORTREG, CORE_PIN39_BIT), &CORE_PIN39_CONFIG},
  80. #endif
  81. };
  82. #elif defined(KINETISL)
  83. const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
  84. {((volatile uint8_t *)&CORE_PIN0_PORTREG + (CORE_PIN0_BIT >> 3)), &CORE_PIN0_CONFIG, (1<<(CORE_PIN0_BIT & 7))},
  85. {((volatile uint8_t *)&CORE_PIN1_PORTREG + (CORE_PIN1_BIT >> 3)), &CORE_PIN1_CONFIG, (1<<(CORE_PIN1_BIT & 7))},
  86. {((volatile uint8_t *)&CORE_PIN2_PORTREG + (CORE_PIN2_BIT >> 3)), &CORE_PIN2_CONFIG, (1<<(CORE_PIN2_BIT & 7))},
  87. {((volatile uint8_t *)&CORE_PIN3_PORTREG + (CORE_PIN3_BIT >> 3)), &CORE_PIN3_CONFIG, (1<<(CORE_PIN3_BIT & 7))},
  88. {((volatile uint8_t *)&CORE_PIN4_PORTREG + (CORE_PIN4_BIT >> 3)), &CORE_PIN4_CONFIG, (1<<(CORE_PIN4_BIT & 7))},
  89. {((volatile uint8_t *)&CORE_PIN5_PORTREG + (CORE_PIN5_BIT >> 3)), &CORE_PIN5_CONFIG, (1<<(CORE_PIN5_BIT & 7))},
  90. {((volatile uint8_t *)&CORE_PIN6_PORTREG + (CORE_PIN6_BIT >> 3)), &CORE_PIN6_CONFIG, (1<<(CORE_PIN6_BIT & 7))},
  91. {((volatile uint8_t *)&CORE_PIN7_PORTREG + (CORE_PIN7_BIT >> 3)), &CORE_PIN7_CONFIG, (1<<(CORE_PIN7_BIT & 7))},
  92. {((volatile uint8_t *)&CORE_PIN8_PORTREG + (CORE_PIN8_BIT >> 3)), &CORE_PIN8_CONFIG, (1<<(CORE_PIN8_BIT & 7))},
  93. {((volatile uint8_t *)&CORE_PIN9_PORTREG + (CORE_PIN9_BIT >> 3)), &CORE_PIN9_CONFIG, (1<<(CORE_PIN9_BIT & 7))},
  94. {((volatile uint8_t *)&CORE_PIN10_PORTREG + (CORE_PIN10_BIT >> 3)), &CORE_PIN10_CONFIG, (1<<(CORE_PIN10_BIT & 7))},
  95. {((volatile uint8_t *)&CORE_PIN11_PORTREG + (CORE_PIN11_BIT >> 3)), &CORE_PIN11_CONFIG, (1<<(CORE_PIN11_BIT & 7))},
  96. {((volatile uint8_t *)&CORE_PIN12_PORTREG + (CORE_PIN12_BIT >> 3)), &CORE_PIN12_CONFIG, (1<<(CORE_PIN12_BIT & 7))},
  97. {((volatile uint8_t *)&CORE_PIN13_PORTREG + (CORE_PIN13_BIT >> 3)), &CORE_PIN13_CONFIG, (1<<(CORE_PIN13_BIT & 7))},
  98. {((volatile uint8_t *)&CORE_PIN14_PORTREG + (CORE_PIN14_BIT >> 3)), &CORE_PIN14_CONFIG, (1<<(CORE_PIN14_BIT & 7))},
  99. {((volatile uint8_t *)&CORE_PIN15_PORTREG + (CORE_PIN15_BIT >> 3)), &CORE_PIN15_CONFIG, (1<<(CORE_PIN15_BIT & 7))},
  100. {((volatile uint8_t *)&CORE_PIN16_PORTREG + (CORE_PIN16_BIT >> 3)), &CORE_PIN16_CONFIG, (1<<(CORE_PIN16_BIT & 7))},
  101. {((volatile uint8_t *)&CORE_PIN17_PORTREG + (CORE_PIN17_BIT >> 3)), &CORE_PIN17_CONFIG, (1<<(CORE_PIN17_BIT & 7))},
  102. {((volatile uint8_t *)&CORE_PIN18_PORTREG + (CORE_PIN18_BIT >> 3)), &CORE_PIN18_CONFIG, (1<<(CORE_PIN18_BIT & 7))},
  103. {((volatile uint8_t *)&CORE_PIN19_PORTREG + (CORE_PIN19_BIT >> 3)), &CORE_PIN19_CONFIG, (1<<(CORE_PIN19_BIT & 7))},
  104. {((volatile uint8_t *)&CORE_PIN20_PORTREG + (CORE_PIN20_BIT >> 3)), &CORE_PIN20_CONFIG, (1<<(CORE_PIN20_BIT & 7))},
  105. {((volatile uint8_t *)&CORE_PIN21_PORTREG + (CORE_PIN21_BIT >> 3)), &CORE_PIN21_CONFIG, (1<<(CORE_PIN21_BIT & 7))},
  106. {((volatile uint8_t *)&CORE_PIN22_PORTREG + (CORE_PIN22_BIT >> 3)), &CORE_PIN22_CONFIG, (1<<(CORE_PIN22_BIT & 7))},
  107. {((volatile uint8_t *)&CORE_PIN23_PORTREG + (CORE_PIN23_BIT >> 3)), &CORE_PIN23_CONFIG, (1<<(CORE_PIN23_BIT & 7))},
  108. {((volatile uint8_t *)&CORE_PIN24_PORTREG + (CORE_PIN24_BIT >> 3)), &CORE_PIN24_CONFIG, (1<<(CORE_PIN24_BIT & 7))},
  109. {((volatile uint8_t *)&CORE_PIN25_PORTREG + (CORE_PIN25_BIT >> 3)), &CORE_PIN25_CONFIG, (1<<(CORE_PIN25_BIT & 7))},
  110. {((volatile uint8_t *)&CORE_PIN26_PORTREG + (CORE_PIN26_BIT >> 3)), &CORE_PIN26_CONFIG, (1<<(CORE_PIN26_BIT & 7))}
  111. };
  112. #endif
  113. typedef void (*voidFuncPtr)(void);
  114. volatile static voidFuncPtr intFunc[CORE_NUM_DIGITAL];
  115. #if defined(KINETISK)
  116. static void porta_interrupt(void);
  117. static void portb_interrupt(void);
  118. static void portc_interrupt(void);
  119. static void portd_interrupt(void);
  120. static void porte_interrupt(void);
  121. #elif defined(KINETISL)
  122. static void porta_interrupt(void);
  123. static void portcd_interrupt(void);
  124. #endif
  125. void attachInterruptVector(enum IRQ_NUMBER_t irq, void (*function)(void))
  126. {
  127. _VectorsRam[irq + 16] = function;
  128. }
  129. void attachInterrupt(uint8_t pin, void (*function)(void), int mode)
  130. {
  131. volatile uint32_t *config;
  132. uint32_t cfg, mask;
  133. if (pin >= CORE_NUM_DIGITAL) return;
  134. switch (mode) {
  135. case CHANGE: mask = 0x0B; break;
  136. case RISING: mask = 0x09; break;
  137. case FALLING: mask = 0x0A; break;
  138. case LOW: mask = 0x08; break;
  139. case HIGH: mask = 0x0C; break;
  140. default: return;
  141. }
  142. mask = (mask << 16) | 0x01000000;
  143. config = portConfigRegister(pin);
  144. #if defined(KINETISK)
  145. attachInterruptVector(IRQ_PORTA, porta_interrupt);
  146. attachInterruptVector(IRQ_PORTB, portb_interrupt);
  147. attachInterruptVector(IRQ_PORTC, portc_interrupt);
  148. attachInterruptVector(IRQ_PORTD, portd_interrupt);
  149. attachInterruptVector(IRQ_PORTE, porte_interrupt);
  150. #elif defined(KINETISL)
  151. attachInterruptVector(IRQ_PORTA, porta_interrupt);
  152. attachInterruptVector(IRQ_PORTCD, portcd_interrupt);
  153. #endif
  154. __disable_irq();
  155. cfg = *config;
  156. cfg &= ~0x000F0000; // disable any previous interrupt
  157. *config = cfg;
  158. intFunc[pin] = function; // set the function pointer
  159. cfg |= mask;
  160. *config = cfg; // enable the new interrupt
  161. __enable_irq();
  162. }
  163. void detachInterrupt(uint8_t pin)
  164. {
  165. volatile uint32_t *config;
  166. config = portConfigRegister(pin);
  167. __disable_irq();
  168. *config = ((*config & ~0x000F0000) | 0x01000000);
  169. intFunc[pin] = NULL;
  170. __enable_irq();
  171. }
  172. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  173. static void porta_interrupt(void)
  174. {
  175. uint32_t isfr = PORTA_ISFR;
  176. PORTA_ISFR = isfr;
  177. if ((isfr & CORE_PIN3_BITMASK) && intFunc[3]) intFunc[3]();
  178. if ((isfr & CORE_PIN4_BITMASK) && intFunc[4]) intFunc[4]();
  179. if ((isfr & CORE_PIN24_BITMASK) && intFunc[24]) intFunc[24]();
  180. if ((isfr & CORE_PIN33_BITMASK) && intFunc[33]) intFunc[33]();
  181. }
  182. static void portb_interrupt(void)
  183. {
  184. uint32_t isfr = PORTB_ISFR;
  185. PORTB_ISFR = isfr;
  186. if ((isfr & CORE_PIN0_BITMASK) && intFunc[0]) intFunc[0]();
  187. if ((isfr & CORE_PIN1_BITMASK) && intFunc[1]) intFunc[1]();
  188. if ((isfr & CORE_PIN16_BITMASK) && intFunc[16]) intFunc[16]();
  189. if ((isfr & CORE_PIN17_BITMASK) && intFunc[17]) intFunc[17]();
  190. if ((isfr & CORE_PIN18_BITMASK) && intFunc[18]) intFunc[18]();
  191. if ((isfr & CORE_PIN19_BITMASK) && intFunc[19]) intFunc[19]();
  192. if ((isfr & CORE_PIN25_BITMASK) && intFunc[25]) intFunc[25]();
  193. if ((isfr & CORE_PIN32_BITMASK) && intFunc[32]) intFunc[32]();
  194. }
  195. static void portc_interrupt(void)
  196. {
  197. // TODO: these are inefficent. Use CLZ somehow....
  198. uint32_t isfr = PORTC_ISFR;
  199. PORTC_ISFR = isfr;
  200. if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9]();
  201. if ((isfr & CORE_PIN10_BITMASK) && intFunc[10]) intFunc[10]();
  202. if ((isfr & CORE_PIN11_BITMASK) && intFunc[11]) intFunc[11]();
  203. if ((isfr & CORE_PIN12_BITMASK) && intFunc[12]) intFunc[12]();
  204. if ((isfr & CORE_PIN13_BITMASK) && intFunc[13]) intFunc[13]();
  205. if ((isfr & CORE_PIN15_BITMASK) && intFunc[15]) intFunc[15]();
  206. if ((isfr & CORE_PIN22_BITMASK) && intFunc[22]) intFunc[22]();
  207. if ((isfr & CORE_PIN23_BITMASK) && intFunc[23]) intFunc[23]();
  208. if ((isfr & CORE_PIN27_BITMASK) && intFunc[27]) intFunc[27]();
  209. if ((isfr & CORE_PIN28_BITMASK) && intFunc[28]) intFunc[28]();
  210. if ((isfr & CORE_PIN29_BITMASK) && intFunc[29]) intFunc[29]();
  211. if ((isfr & CORE_PIN30_BITMASK) && intFunc[30]) intFunc[30]();
  212. }
  213. static void portd_interrupt(void)
  214. {
  215. uint32_t isfr = PORTD_ISFR;
  216. PORTD_ISFR = isfr;
  217. if ((isfr & CORE_PIN2_BITMASK) && intFunc[2]) intFunc[2]();
  218. if ((isfr & CORE_PIN5_BITMASK) && intFunc[5]) intFunc[5]();
  219. if ((isfr & CORE_PIN6_BITMASK) && intFunc[6]) intFunc[6]();
  220. if ((isfr & CORE_PIN7_BITMASK) && intFunc[7]) intFunc[7]();
  221. if ((isfr & CORE_PIN8_BITMASK) && intFunc[8]) intFunc[8]();
  222. if ((isfr & CORE_PIN14_BITMASK) && intFunc[14]) intFunc[14]();
  223. if ((isfr & CORE_PIN20_BITMASK) && intFunc[20]) intFunc[20]();
  224. if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21]();
  225. }
  226. static void porte_interrupt(void)
  227. {
  228. uint32_t isfr = PORTE_ISFR;
  229. PORTE_ISFR = isfr;
  230. if ((isfr & CORE_PIN26_BITMASK) && intFunc[26]) intFunc[26]();
  231. if ((isfr & CORE_PIN31_BITMASK) && intFunc[31]) intFunc[31]();
  232. }
  233. #elif defined(__MKL26Z64__)
  234. static void porta_interrupt(void)
  235. {
  236. uint32_t isfr = PORTA_ISFR;
  237. PORTA_ISFR = isfr;
  238. if ((isfr & CORE_PIN3_BITMASK) && intFunc[3]) intFunc[3]();
  239. if ((isfr & CORE_PIN4_BITMASK) && intFunc[4]) intFunc[4]();
  240. }
  241. static void portcd_interrupt(void)
  242. {
  243. uint32_t isfr = PORTC_ISFR;
  244. PORTC_ISFR = isfr;
  245. if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9]();
  246. if ((isfr & CORE_PIN10_BITMASK) && intFunc[10]) intFunc[10]();
  247. if ((isfr & CORE_PIN11_BITMASK) && intFunc[11]) intFunc[11]();
  248. if ((isfr & CORE_PIN12_BITMASK) && intFunc[12]) intFunc[12]();
  249. if ((isfr & CORE_PIN13_BITMASK) && intFunc[13]) intFunc[13]();
  250. if ((isfr & CORE_PIN15_BITMASK) && intFunc[15]) intFunc[15]();
  251. if ((isfr & CORE_PIN22_BITMASK) && intFunc[22]) intFunc[22]();
  252. if ((isfr & CORE_PIN23_BITMASK) && intFunc[23]) intFunc[23]();
  253. isfr = PORTD_ISFR;
  254. PORTD_ISFR = isfr;
  255. if ((isfr & CORE_PIN2_BITMASK) && intFunc[2]) intFunc[2]();
  256. if ((isfr & CORE_PIN5_BITMASK) && intFunc[5]) intFunc[5]();
  257. if ((isfr & CORE_PIN6_BITMASK) && intFunc[6]) intFunc[6]();
  258. if ((isfr & CORE_PIN7_BITMASK) && intFunc[7]) intFunc[7]();
  259. if ((isfr & CORE_PIN8_BITMASK) && intFunc[8]) intFunc[8]();
  260. if ((isfr & CORE_PIN14_BITMASK) && intFunc[14]) intFunc[14]();
  261. if ((isfr & CORE_PIN20_BITMASK) && intFunc[20]) intFunc[20]();
  262. if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21]();
  263. }
  264. #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
  265. static void porta_interrupt(void)
  266. {
  267. uint32_t isfr = PORTA_ISFR;
  268. PORTA_ISFR = isfr;
  269. if ((isfr & CORE_PIN3_BITMASK) && intFunc[3]) intFunc[3]();
  270. if ((isfr & CORE_PIN4_BITMASK) && intFunc[4]) intFunc[4]();
  271. if ((isfr & CORE_PIN25_BITMASK) && intFunc[25]) intFunc[25]();
  272. if ((isfr & CORE_PIN26_BITMASK) && intFunc[26]) intFunc[26]();
  273. if ((isfr & CORE_PIN27_BITMASK) && intFunc[27]) intFunc[27]();
  274. if ((isfr & CORE_PIN28_BITMASK) && intFunc[28]) intFunc[28]();
  275. if ((isfr & CORE_PIN39_BITMASK) && intFunc[39]) intFunc[39]();
  276. }
  277. static void portb_interrupt(void)
  278. {
  279. uint32_t isfr = PORTB_ISFR;
  280. PORTB_ISFR = isfr;
  281. if ((isfr & CORE_PIN0_BITMASK) && intFunc[0]) intFunc[0]();
  282. if ((isfr & CORE_PIN1_BITMASK) && intFunc[1]) intFunc[1]();
  283. if ((isfr & CORE_PIN16_BITMASK) && intFunc[16]) intFunc[16]();
  284. if ((isfr & CORE_PIN17_BITMASK) && intFunc[17]) intFunc[17]();
  285. if ((isfr & CORE_PIN18_BITMASK) && intFunc[18]) intFunc[18]();
  286. if ((isfr & CORE_PIN19_BITMASK) && intFunc[19]) intFunc[19]();
  287. if ((isfr & CORE_PIN29_BITMASK) && intFunc[29]) intFunc[29]();
  288. if ((isfr & CORE_PIN30_BITMASK) && intFunc[30]) intFunc[30]();
  289. if ((isfr & CORE_PIN31_BITMASK) && intFunc[31]) intFunc[31]();
  290. if ((isfr & CORE_PIN32_BITMASK) && intFunc[32]) intFunc[32]();
  291. }
  292. static void portc_interrupt(void)
  293. {
  294. // TODO: these are inefficent. Use CLZ somehow....
  295. uint32_t isfr = PORTC_ISFR;
  296. PORTC_ISFR = isfr;
  297. if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9]();
  298. if ((isfr & CORE_PIN10_BITMASK) && intFunc[10]) intFunc[10]();
  299. if ((isfr & CORE_PIN11_BITMASK) && intFunc[11]) intFunc[11]();
  300. if ((isfr & CORE_PIN12_BITMASK) && intFunc[12]) intFunc[12]();
  301. if ((isfr & CORE_PIN13_BITMASK) && intFunc[13]) intFunc[13]();
  302. if ((isfr & CORE_PIN15_BITMASK) && intFunc[15]) intFunc[15]();
  303. if ((isfr & CORE_PIN22_BITMASK) && intFunc[22]) intFunc[22]();
  304. if ((isfr & CORE_PIN23_BITMASK) && intFunc[23]) intFunc[23]();
  305. if ((isfr & CORE_PIN35_BITMASK) && intFunc[35]) intFunc[35]();
  306. if ((isfr & CORE_PIN36_BITMASK) && intFunc[36]) intFunc[36]();
  307. if ((isfr & CORE_PIN37_BITMASK) && intFunc[37]) intFunc[37]();
  308. if ((isfr & CORE_PIN38_BITMASK) && intFunc[38]) intFunc[38]();
  309. }
  310. static void portd_interrupt(void)
  311. {
  312. uint32_t isfr = PORTD_ISFR;
  313. PORTD_ISFR = isfr;
  314. if ((isfr & CORE_PIN2_BITMASK) && intFunc[2]) intFunc[2]();
  315. if ((isfr & CORE_PIN5_BITMASK) && intFunc[5]) intFunc[5]();
  316. if ((isfr & CORE_PIN6_BITMASK) && intFunc[6]) intFunc[6]();
  317. if ((isfr & CORE_PIN7_BITMASK) && intFunc[7]) intFunc[7]();
  318. if ((isfr & CORE_PIN8_BITMASK) && intFunc[8]) intFunc[8]();
  319. if ((isfr & CORE_PIN14_BITMASK) && intFunc[14]) intFunc[14]();
  320. if ((isfr & CORE_PIN20_BITMASK) && intFunc[20]) intFunc[20]();
  321. if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21]();
  322. }
  323. static void porte_interrupt(void)
  324. {
  325. uint32_t isfr = PORTE_ISFR;
  326. PORTE_ISFR = isfr;
  327. if ((isfr & CORE_PIN24_BITMASK) && intFunc[24]) intFunc[24]();
  328. if ((isfr & CORE_PIN33_BITMASK) && intFunc[33]) intFunc[33]();
  329. if ((isfr & CORE_PIN34_BITMASK) && intFunc[34]) intFunc[34]();
  330. }
  331. #endif
  332. #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  333. unsigned long rtc_get(void)
  334. {
  335. return RTC_TSR;
  336. }
  337. void rtc_set(unsigned long t)
  338. {
  339. RTC_SR = 0;
  340. RTC_TPR = 0;
  341. RTC_TSR = t;
  342. RTC_SR = RTC_SR_TCE;
  343. }
  344. // adjust is the amount of crystal error to compensate, 1 = 0.1192 ppm
  345. // For example, adjust = -100 is slows the clock by 11.92 ppm
  346. //
  347. void rtc_compensate(int adjust)
  348. {
  349. uint32_t comp, interval, tcr;
  350. // This simple approach tries to maximize the interval.
  351. // Perhaps minimizing TCR would be better, so the
  352. // compensation is distributed more evenly across
  353. // many seconds, rather than saving it all up and then
  354. // altering one second up to +/- 0.38%
  355. if (adjust >= 0) {
  356. comp = adjust;
  357. interval = 256;
  358. while (1) {
  359. tcr = comp * interval;
  360. if (tcr < 128*256) break;
  361. if (--interval == 1) break;
  362. }
  363. tcr = tcr >> 8;
  364. } else {
  365. comp = -adjust;
  366. interval = 256;
  367. while (1) {
  368. tcr = comp * interval;
  369. if (tcr < 129*256) break;
  370. if (--interval == 1) break;
  371. }
  372. tcr = tcr >> 8;
  373. tcr = 256 - tcr;
  374. }
  375. RTC_TCR = ((interval - 1) << 8) | tcr;
  376. }
  377. #else
  378. unsigned long rtc_get(void) { return 0; }
  379. void rtc_set(unsigned long t) { }
  380. void rtc_compensate(int adjust) { }
  381. #endif
  382. #if 0
  383. // TODO: build system should define this
  384. // so RTC is automatically initialized to approx correct time
  385. // at least when the program begins running right after upload
  386. #ifndef TIME_T
  387. #define TIME_T 1350160272
  388. #endif
  389. void init_rtc(void)
  390. {
  391. serial_print("init_rtc\n");
  392. //SIM_SCGC6 |= SIM_SCGC6_RTC;
  393. // enable the RTC crystal oscillator, for approx 12pf crystal
  394. if (!(RTC_CR & RTC_CR_OSCE)) {
  395. serial_print("start RTC oscillator\n");
  396. RTC_SR = 0;
  397. RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
  398. }
  399. // should wait for crystal to stabilize.....
  400. serial_print("SR=");
  401. serial_phex32(RTC_SR);
  402. serial_print("\n");
  403. serial_print("CR=");
  404. serial_phex32(RTC_CR);
  405. serial_print("\n");
  406. serial_print("TSR=");
  407. serial_phex32(RTC_TSR);
  408. serial_print("\n");
  409. serial_print("TCR=");
  410. serial_phex32(RTC_TCR);
  411. serial_print("\n");
  412. if (RTC_SR & RTC_SR_TIF) {
  413. // enable the RTC
  414. RTC_SR = 0;
  415. RTC_TPR = 0;
  416. RTC_TSR = TIME_T;
  417. RTC_SR = RTC_SR_TCE;
  418. }
  419. }
  420. #endif
  421. extern void usb_init(void);
  422. // create a default PWM at the same 488.28 Hz as Arduino Uno
  423. #if defined(KINETISK)
  424. #define F_TIMER F_BUS
  425. #elif defined(KINETISL)
  426. #if F_CPU > 16000000
  427. #define F_TIMER (F_PLL/2)
  428. #else
  429. #define F_TIMER (F_PLL)
  430. #endif//Low Power
  431. #endif
  432. #if F_TIMER == 60000000
  433. #define DEFAULT_FTM_MOD (61440 - 1)
  434. #define DEFAULT_FTM_PRESCALE 1
  435. #elif F_TIMER == 56000000
  436. #define DEFAULT_FTM_MOD (57344 - 1)
  437. #define DEFAULT_FTM_PRESCALE 1
  438. #elif F_TIMER == 48000000
  439. #define DEFAULT_FTM_MOD (49152 - 1)
  440. #define DEFAULT_FTM_PRESCALE 1
  441. #elif F_TIMER == 40000000
  442. #define DEFAULT_FTM_MOD (40960 - 1)
  443. #define DEFAULT_FTM_PRESCALE 1
  444. #elif F_TIMER == 36000000
  445. #define DEFAULT_FTM_MOD (36864 - 1)
  446. #define DEFAULT_FTM_PRESCALE 1
  447. #elif F_TIMER == 24000000
  448. #define DEFAULT_FTM_MOD (49152 - 1)
  449. #define DEFAULT_FTM_PRESCALE 0
  450. #elif F_TIMER == 16000000
  451. #define DEFAULT_FTM_MOD (32768 - 1)
  452. #define DEFAULT_FTM_PRESCALE 0
  453. #elif F_TIMER == 8000000
  454. #define DEFAULT_FTM_MOD (16384 - 1)
  455. #define DEFAULT_FTM_PRESCALE 0
  456. #elif F_TIMER == 4000000
  457. #define DEFAULT_FTM_MOD (8192 - 1)
  458. #define DEFAULT_FTM_PRESCALE 0
  459. #elif F_TIMER == 2000000
  460. #define DEFAULT_FTM_MOD (4096 - 1)
  461. #define DEFAULT_FTM_PRESCALE 0
  462. #endif
  463. //void init_pins(void)
  464. void _init_Teensyduino_internal_(void)
  465. {
  466. #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  467. NVIC_ENABLE_IRQ(IRQ_PORTA);
  468. NVIC_ENABLE_IRQ(IRQ_PORTB);
  469. NVIC_ENABLE_IRQ(IRQ_PORTC);
  470. NVIC_ENABLE_IRQ(IRQ_PORTD);
  471. NVIC_ENABLE_IRQ(IRQ_PORTE);
  472. #elif defined(__MKL26Z64__)
  473. NVIC_ENABLE_IRQ(IRQ_PORTA);
  474. NVIC_ENABLE_IRQ(IRQ_PORTCD);
  475. #endif
  476. //SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write
  477. //SIM_SCGC6 |= SIM_SCGC6_FTM1;
  478. FTM0_CNT = 0;
  479. FTM0_MOD = DEFAULT_FTM_MOD;
  480. FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
  481. FTM0_C1SC = 0x28;
  482. FTM0_C2SC = 0x28;
  483. FTM0_C3SC = 0x28;
  484. FTM0_C4SC = 0x28;
  485. FTM0_C5SC = 0x28;
  486. #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  487. FTM0_C6SC = 0x28;
  488. FTM0_C7SC = 0x28;
  489. #endif
  490. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  491. FTM3_C0SC = 0x28;
  492. FTM3_C1SC = 0x28;
  493. FTM3_C2SC = 0x28;
  494. FTM3_C3SC = 0x28;
  495. FTM3_C4SC = 0x28;
  496. FTM3_C5SC = 0x28;
  497. FTM3_C6SC = 0x28;
  498. FTM3_C7SC = 0x28;
  499. #endif
  500. FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  501. FTM1_CNT = 0;
  502. FTM1_MOD = DEFAULT_FTM_MOD;
  503. FTM1_C0SC = 0x28;
  504. FTM1_C1SC = 0x28;
  505. FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  506. #if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__)
  507. FTM2_CNT = 0;
  508. FTM2_MOD = DEFAULT_FTM_MOD;
  509. FTM2_C0SC = 0x28;
  510. FTM2_C1SC = 0x28;
  511. FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  512. #endif
  513. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  514. FTM3_CNT = 0;
  515. FTM3_MOD = DEFAULT_FTM_MOD;
  516. FTM3_C0SC = 0x28;
  517. FTM3_C1SC = 0x28;
  518. FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  519. #endif
  520. analog_init();
  521. // for background about this startup delay, please see this conversation
  522. // https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
  523. delay(250);
  524. usb_init();
  525. }
  526. #if defined(__MK20DX128__)
  527. #define FTM0_CH0_PIN 22
  528. #define FTM0_CH1_PIN 23
  529. #define FTM0_CH2_PIN 9
  530. #define FTM0_CH3_PIN 10
  531. #define FTM0_CH4_PIN 6
  532. #define FTM0_CH5_PIN 20
  533. #define FTM0_CH6_PIN 21
  534. #define FTM0_CH7_PIN 5
  535. #define FTM1_CH0_PIN 3
  536. #define FTM1_CH1_PIN 4
  537. #elif defined(__MK20DX256__)
  538. #define FTM0_CH0_PIN 22
  539. #define FTM0_CH1_PIN 23
  540. #define FTM0_CH2_PIN 9
  541. #define FTM0_CH3_PIN 10
  542. #define FTM0_CH4_PIN 6
  543. #define FTM0_CH5_PIN 20
  544. #define FTM0_CH6_PIN 21
  545. #define FTM0_CH7_PIN 5
  546. #define FTM1_CH0_PIN 3
  547. #define FTM1_CH1_PIN 4
  548. #define FTM2_CH0_PIN 32
  549. #define FTM2_CH1_PIN 25
  550. #elif defined(__MKL26Z64__)
  551. #define FTM0_CH0_PIN 22
  552. #define FTM0_CH1_PIN 23
  553. #define FTM0_CH2_PIN 9
  554. #define FTM0_CH3_PIN 10
  555. #define FTM0_CH4_PIN 6
  556. #define FTM0_CH5_PIN 20
  557. #define FTM1_CH0_PIN 16
  558. #define FTM1_CH1_PIN 17
  559. #define FTM2_CH0_PIN 3
  560. #define FTM2_CH1_PIN 4
  561. #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
  562. #define FTM0_CH0_PIN 22
  563. #define FTM0_CH1_PIN 23
  564. #define FTM0_CH2_PIN 9
  565. #define FTM0_CH3_PIN 10
  566. #define FTM0_CH4_PIN 6
  567. #define FTM0_CH5_PIN 20
  568. #define FTM0_CH6_PIN 21
  569. #define FTM0_CH7_PIN 5
  570. #define FTM1_CH0_PIN 3
  571. #define FTM1_CH1_PIN 4
  572. #define FTM2_CH0_PIN 29
  573. #define FTM2_CH1_PIN 30
  574. #define FTM3_CH0_PIN 2
  575. #define FTM3_CH1_PIN 14
  576. #define FTM3_CH2_PIN 7
  577. #define FTM3_CH3_PIN 8
  578. #define FTM3_CH4_PIN 35
  579. #define FTM3_CH5_PIN 36
  580. #define FTM3_CH6_PIN 37
  581. #define FTM3_CH7_PIN 38
  582. #endif
  583. #define FTM_PINCFG(pin) FTM_PINCFG2(pin)
  584. #define FTM_PINCFG2(pin) CORE_PIN ## pin ## _CONFIG
  585. static uint8_t analog_write_res = 8;
  586. // SOPT4 is SIM select clocks?
  587. // FTM is clocked by the bus clock, either 24 or 48 MHz
  588. // input capture can be FTM1_CH0, CMP0 or CMP1 or USB start of frame
  589. // 24 MHz with reload 49152 to match Arduino's speed = 488.28125 Hz
  590. void analogWrite(uint8_t pin, int val)
  591. {
  592. uint32_t cval, max;
  593. #if defined(__MK20DX256__)
  594. if (pin == A14) {
  595. uint8_t res = analog_write_res;
  596. if (res < 12) {
  597. val <<= 12 - res;
  598. } else if (res > 12) {
  599. val >>= res - 12;
  600. }
  601. analogWriteDAC0(val);
  602. return;
  603. }
  604. #elif defined(__MKL26Z64__)
  605. if (pin == A12) {
  606. uint8_t res = analog_write_res;
  607. if (res < 12) {
  608. val <<= 12 - res;
  609. } else if (res > 12) {
  610. val >>= res - 12;
  611. }
  612. analogWriteDAC0(val);
  613. return;
  614. }
  615. #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
  616. if (pin == A21 || pin == A22) {
  617. uint8_t res = analog_write_res;
  618. if (res < 12) {
  619. val <<= 12 - res;
  620. } else if (res > 12) {
  621. val >>= res - 12;
  622. }
  623. if (pin == A21) analogWriteDAC0(val);
  624. else analogWriteDAC1(val);
  625. return;
  626. }
  627. #endif
  628. max = 1 << analog_write_res;
  629. if (val <= 0) {
  630. digitalWrite(pin, LOW);
  631. pinMode(pin, OUTPUT); // TODO: implement OUTPUT_LOW
  632. return;
  633. } else if (val >= max) {
  634. digitalWrite(pin, HIGH);
  635. pinMode(pin, OUTPUT); // TODO: implement OUTPUT_HIGH
  636. return;
  637. }
  638. //serial_print("analogWrite\n");
  639. //serial_print("val = ");
  640. //serial_phex32(val);
  641. //serial_print("\n");
  642. //serial_print("analog_write_res = ");
  643. //serial_phex(analog_write_res);
  644. //serial_print("\n");
  645. if (pin == FTM1_CH0_PIN || pin == FTM1_CH1_PIN) {
  646. cval = ((uint32_t)val * (uint32_t)(FTM1_MOD + 1)) >> analog_write_res;
  647. #if defined(FTM2_CH0_PIN)
  648. } else if (pin == FTM2_CH0_PIN || pin == FTM2_CH1_PIN) {
  649. cval = ((uint32_t)val * (uint32_t)(FTM2_MOD + 1)) >> analog_write_res;
  650. #endif
  651. } else {
  652. cval = ((uint32_t)val * (uint32_t)(FTM0_MOD + 1)) >> analog_write_res;
  653. }
  654. //serial_print("cval = ");
  655. //serial_phex32(cval);
  656. //serial_print("\n");
  657. switch (pin) {
  658. #ifdef FTM0_CH0_PIN
  659. case FTM0_CH0_PIN: // PTC1, FTM0_CH0
  660. FTM0_C0V = cval;
  661. FTM_PINCFG(FTM0_CH0_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  662. break;
  663. #endif
  664. #ifdef FTM0_CH1_PIN
  665. case FTM0_CH1_PIN: // PTC2, FTM0_CH1
  666. FTM0_C1V = cval;
  667. FTM_PINCFG(FTM0_CH1_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  668. break;
  669. #endif
  670. #ifdef FTM0_CH2_PIN
  671. case FTM0_CH2_PIN: // PTC3, FTM0_CH2
  672. FTM0_C2V = cval;
  673. FTM_PINCFG(FTM0_CH2_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  674. break;
  675. #endif
  676. #ifdef FTM0_CH3_PIN
  677. case FTM0_CH3_PIN: // PTC4, FTM0_CH3
  678. FTM0_C3V = cval;
  679. FTM_PINCFG(FTM0_CH3_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  680. break;
  681. #endif
  682. #ifdef FTM0_CH4_PIN
  683. case FTM0_CH4_PIN: // PTD4, FTM0_CH4
  684. FTM0_C4V = cval;
  685. FTM_PINCFG(FTM0_CH4_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  686. break;
  687. #endif
  688. #ifdef FTM0_CH5_PIN
  689. case FTM0_CH5_PIN: // PTD5, FTM0_CH5
  690. FTM0_C5V = cval;
  691. FTM_PINCFG(FTM0_CH5_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  692. break;
  693. #endif
  694. #ifdef FTM0_CH6_PIN
  695. case FTM0_CH6_PIN: // PTD6, FTM0_CH6
  696. FTM0_C6V = cval;
  697. FTM_PINCFG(FTM0_CH6_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  698. break;
  699. #endif
  700. #ifdef FTM0_CH7_PIN
  701. case FTM0_CH7_PIN: // PTD7, FTM0_CH7
  702. FTM0_C7V = cval;
  703. FTM_PINCFG(FTM0_CH7_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  704. break;
  705. #endif
  706. #ifdef FTM1_CH0_PIN
  707. case FTM1_CH0_PIN: // PTA12, FTM1_CH0
  708. FTM1_C0V = cval;
  709. FTM_PINCFG(FTM1_CH0_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  710. break;
  711. #endif
  712. #ifdef FTM1_CH1_PIN
  713. case FTM1_CH1_PIN: // PTA13, FTM1_CH1
  714. FTM1_C1V = cval;
  715. FTM_PINCFG(FTM1_CH1_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  716. break;
  717. #endif
  718. #ifdef FTM2_CH0_PIN
  719. case FTM2_CH0_PIN: // PTB18, FTM2_CH0
  720. FTM2_C0V = cval;
  721. FTM_PINCFG(FTM2_CH0_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  722. break;
  723. #endif
  724. #ifdef FTM2_CH1_PIN
  725. case FTM2_CH1_PIN: // PTB19, FTM1_CH1
  726. FTM2_C1V = cval;
  727. FTM_PINCFG(FTM2_CH1_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  728. break;
  729. #endif
  730. #ifdef FTM3_CH0_PIN
  731. case FTM3_CH0_PIN:
  732. FTM3_C0V = cval;
  733. FTM_PINCFG(FTM3_CH0_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  734. break;
  735. #endif
  736. #ifdef FTM3_CH1_PIN
  737. case FTM3_CH1_PIN:
  738. FTM3_C1V = cval;
  739. FTM_PINCFG(FTM3_CH1_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  740. break;
  741. #endif
  742. #ifdef FTM3_CH2_PIN
  743. case FTM3_CH2_PIN:
  744. FTM3_C2V = cval;
  745. FTM_PINCFG(FTM3_CH2_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  746. break;
  747. #endif
  748. #ifdef FTM3_CH3_PIN
  749. case FTM3_CH3_PIN:
  750. FTM3_C3V = cval;
  751. FTM_PINCFG(FTM3_CH3_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  752. break;
  753. #endif
  754. #ifdef FTM3_CH4_PIN
  755. case FTM3_CH4_PIN:
  756. FTM3_C4V = cval;
  757. FTM_PINCFG(FTM3_CH4_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  758. break;
  759. #endif
  760. #ifdef FTM3_CH5_PIN
  761. case FTM3_CH5_PIN:
  762. FTM3_C5V = cval;
  763. FTM_PINCFG(FTM3_CH5_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  764. break;
  765. #endif
  766. #ifdef FTM3_CH6_PIN
  767. case FTM3_CH6_PIN:
  768. FTM3_C6V = cval;
  769. FTM_PINCFG(FTM3_CH6_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  770. break;
  771. #endif
  772. #ifdef FTM3_CH7_PIN
  773. case FTM3_CH7_PIN:
  774. FTM3_C7V = cval;
  775. FTM_PINCFG(FTM3_CH7_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  776. break;
  777. #endif
  778. default:
  779. digitalWrite(pin, (val > 127) ? HIGH : LOW);
  780. pinMode(pin, OUTPUT);
  781. }
  782. }
  783. void analogWriteRes(uint32_t bits)
  784. {
  785. if (bits < 1) {
  786. bits = 1;
  787. } else if (bits > 16) {
  788. bits = 16;
  789. }
  790. analog_write_res = bits;
  791. }
  792. void analogWriteFrequency(uint8_t pin, float frequency)
  793. {
  794. uint32_t prescale, mod, ftmClock, ftmClockSource;
  795. float minfreq;
  796. //serial_print("analogWriteFrequency: pin = ");
  797. //serial_phex(pin);
  798. //serial_print(", freq = ");
  799. //serial_phex32((uint32_t)frequency);
  800. //serial_print("\n");
  801. if (frequency < (float)(F_TIMER >> 7) / 65536.0f) { //If frequency is too low for working with F_TIMER:
  802. ftmClockSource = 2; //Use alternative 31250Hz clock source
  803. ftmClock = 31250; //Set variable for the actual timer clock frequency
  804. } else { //Else do as before:
  805. ftmClockSource = 1; //Use default F_Timer clock source
  806. ftmClock = F_TIMER; //Set variable for the actual timer clock frequency
  807. }
  808. for (prescale = 0; prescale < 7; prescale++) {
  809. minfreq = (float)(ftmClock >> prescale) / 65536.0f; //Use ftmClock instead of F_TIMER
  810. if (frequency >= minfreq) break;
  811. }
  812. //serial_print("F_TIMER/ftm_Clock = ");
  813. //serial_phex32(ftmClock >> prescale);
  814. //serial_print("\n");
  815. //serial_print("prescale = ");
  816. //serial_phex(prescale);
  817. //serial_print("\n");
  818. mod = (float)(ftmClock >> prescale) / frequency - 0.5f; //Use ftmClock instead of F_TIMER
  819. if (mod > 65535) mod = 65535;
  820. //serial_print("mod = ");
  821. //serial_phex32(mod);
  822. //serial_print("\n");
  823. if (pin == FTM1_CH0_PIN || pin == FTM1_CH1_PIN) {
  824. FTM1_SC = 0;
  825. FTM1_CNT = 0;
  826. FTM1_MOD = mod;
  827. FTM1_SC = FTM_SC_CLKS(ftmClockSource) | FTM_SC_PS(prescale); //Use ftmClockSource instead of 1
  828. } else if (pin == FTM0_CH0_PIN || pin == FTM0_CH1_PIN
  829. || pin == FTM0_CH2_PIN || pin == FTM0_CH3_PIN
  830. || pin == FTM0_CH4_PIN || pin == FTM0_CH5_PIN
  831. #ifdef FTM0_CH6_PIN
  832. || pin == FTM0_CH6_PIN || pin == FTM0_CH7_PIN
  833. #endif
  834. ) {
  835. FTM0_SC = 0;
  836. FTM0_CNT = 0;
  837. FTM0_MOD = mod;
  838. FTM0_SC = FTM_SC_CLKS(ftmClockSource) | FTM_SC_PS(prescale); //Use ftmClockSource instead of 1
  839. }
  840. #ifdef FTM2_CH0_PIN
  841. else if (pin == FTM2_CH0_PIN || pin == FTM2_CH1_PIN) {
  842. FTM2_SC = 0;
  843. FTM2_CNT = 0;
  844. FTM2_MOD = mod;
  845. FTM2_SC = FTM_SC_CLKS(ftmClockSource) | FTM_SC_PS(prescale); //Use ftmClockSource instead of 1
  846. }
  847. #endif
  848. #ifdef FTM3_CH0_PIN
  849. else if (pin == FTM3_CH0_PIN || pin == FTM3_CH1_PIN
  850. || pin == FTM3_CH2_PIN || pin == FTM3_CH3_PIN
  851. || pin == FTM3_CH4_PIN || pin == FTM3_CH5_PIN
  852. || pin == FTM3_CH6_PIN || pin == FTM3_CH7_PIN) {
  853. FTM3_SC = 0;
  854. FTM3_CNT = 0;
  855. FTM3_MOD = mod;
  856. FTM3_SC = FTM_SC_CLKS(ftmClockSource) | FTM_SC_PS(prescale); //Use the new ftmClockSource instead of 1
  857. }
  858. #endif
  859. }
  860. // TODO: startup code needs to initialize all pins to GPIO mode, input by default
  861. void digitalWrite(uint8_t pin, uint8_t val)
  862. {
  863. if (pin >= CORE_NUM_DIGITAL) return;
  864. #ifdef KINETISK
  865. if (*portModeRegister(pin)) {
  866. if (val) {
  867. *portSetRegister(pin) = 1;
  868. } else {
  869. *portClearRegister(pin) = 1;
  870. }
  871. #else
  872. if (*portModeRegister(pin) & digitalPinToBitMask(pin)) {
  873. if (val) {
  874. *portSetRegister(pin) = digitalPinToBitMask(pin);
  875. } else {
  876. *portClearRegister(pin) = digitalPinToBitMask(pin);
  877. }
  878. #endif
  879. } else {
  880. volatile uint32_t *config = portConfigRegister(pin);
  881. if (val) {
  882. // TODO use bitband for atomic read-mod-write
  883. *config |= (PORT_PCR_PE | PORT_PCR_PS);
  884. //*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
  885. } else {
  886. // TODO use bitband for atomic read-mod-write
  887. *config &= ~(PORT_PCR_PE);
  888. //*config = PORT_PCR_MUX(1);
  889. }
  890. }
  891. }
  892. uint8_t digitalRead(uint8_t pin)
  893. {
  894. if (pin >= CORE_NUM_DIGITAL) return 0;
  895. #ifdef KINETISK
  896. return *portInputRegister(pin);
  897. #else
  898. return (*portInputRegister(pin) & digitalPinToBitMask(pin)) ? 1 : 0;
  899. #endif
  900. }
  901. void pinMode(uint8_t pin, uint8_t mode)
  902. {
  903. volatile uint32_t *config;
  904. if (pin >= CORE_NUM_DIGITAL) return;
  905. config = portConfigRegister(pin);
  906. if (mode == OUTPUT || mode == OUTPUT_OPENDRAIN) {
  907. #ifdef KINETISK
  908. *portModeRegister(pin) = 1;
  909. #else
  910. *portModeRegister(pin) |= digitalPinToBitMask(pin); // TODO: atomic
  911. #endif
  912. *config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  913. if (mode == OUTPUT_OPENDRAIN) {
  914. *config |= PORT_PCR_ODE;
  915. } else {
  916. *config &= ~PORT_PCR_ODE;
  917. }
  918. } else {
  919. #ifdef KINETISK
  920. *portModeRegister(pin) = 0;
  921. #else
  922. *portModeRegister(pin) &= ~digitalPinToBitMask(pin);
  923. #endif
  924. if (mode == INPUT || mode == INPUT_PULLUP || mode == INPUT_PULLDOWN) {
  925. *config = PORT_PCR_MUX(1);
  926. if (mode == INPUT_PULLUP) {
  927. *config |= (PORT_PCR_PE | PORT_PCR_PS); // pullup
  928. } else if (mode == INPUT_PULLDOWN) {
  929. *config |= (PORT_PCR_PE); // pulldown
  930. *config &= ~(PORT_PCR_PS);
  931. }
  932. } else {
  933. *config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; // pullup
  934. }
  935. }
  936. }
  937. void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value)
  938. {
  939. if (bitOrder == LSBFIRST) {
  940. shiftOut_lsbFirst(dataPin, clockPin, value);
  941. } else {
  942. shiftOut_msbFirst(dataPin, clockPin, value);
  943. }
  944. }
  945. void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
  946. {
  947. uint8_t mask;
  948. for (mask=0x01; mask; mask <<= 1) {
  949. digitalWrite(dataPin, value & mask);
  950. digitalWrite(clockPin, HIGH);
  951. digitalWrite(clockPin, LOW);
  952. }
  953. }
  954. void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
  955. {
  956. uint8_t mask;
  957. for (mask=0x80; mask; mask >>= 1) {
  958. digitalWrite(dataPin, value & mask);
  959. digitalWrite(clockPin, HIGH);
  960. digitalWrite(clockPin, LOW);
  961. }
  962. }
  963. uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
  964. {
  965. if (bitOrder == LSBFIRST) {
  966. return shiftIn_lsbFirst(dataPin, clockPin);
  967. } else {
  968. return shiftIn_msbFirst(dataPin, clockPin);
  969. }
  970. }
  971. uint8_t shiftIn_lsbFirst(uint8_t dataPin, uint8_t clockPin)
  972. {
  973. uint8_t mask, value=0;
  974. for (mask=0x01; mask; mask <<= 1) {
  975. digitalWrite(clockPin, HIGH);
  976. if (digitalRead(dataPin)) value |= mask;
  977. digitalWrite(clockPin, LOW);
  978. }
  979. return value;
  980. }
  981. uint8_t shiftIn_msbFirst(uint8_t dataPin, uint8_t clockPin)
  982. {
  983. uint8_t mask, value=0;
  984. for (mask=0x80; mask; mask >>= 1) {
  985. digitalWrite(clockPin, HIGH);
  986. if (digitalRead(dataPin)) value |= mask;
  987. digitalWrite(clockPin, LOW);
  988. }
  989. return value;
  990. }
  991. // the systick interrupt is supposed to increment this at 1 kHz rate
  992. volatile uint32_t systick_millis_count = 0;
  993. //uint32_t systick_current, systick_count, systick_istatus; // testing only
  994. uint32_t micros(void)
  995. {
  996. uint32_t count, current, istatus;
  997. __disable_irq();
  998. current = SYST_CVR;
  999. count = systick_millis_count;
  1000. istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
  1001. __enable_irq();
  1002. //systick_current = current;
  1003. //systick_count = count;
  1004. //systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0;
  1005. if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
  1006. current = ((F_CPU / 1000) - 1) - current;
  1007. #if defined(KINETISL) && F_CPU == 48000000
  1008. return count * 1000 + ((current * (uint32_t)87381) >> 22);
  1009. #elif defined(KINETISL) && F_CPU == 24000000
  1010. return count * 1000 + ((current * (uint32_t)174763) >> 22);
  1011. #endif
  1012. return count * 1000 + current / (F_CPU / 1000000);
  1013. }
  1014. void delay(uint32_t ms)
  1015. {
  1016. uint32_t start = micros();
  1017. if (ms > 0) {
  1018. while (1) {
  1019. while ((micros() - start) >= 1000) {
  1020. ms--;
  1021. if (ms == 0) return;
  1022. start += 1000;
  1023. }
  1024. yield();
  1025. }
  1026. }
  1027. }
  1028. // TODO: verify these result in correct timeouts...
  1029. #if F_CPU == 192000000
  1030. #define PULSEIN_LOOPS_PER_USEC 29
  1031. #elif F_CPU == 180000000
  1032. #define PULSEIN_LOOPS_PER_USEC 27
  1033. #elif F_CPU == 168000000
  1034. #define PULSEIN_LOOPS_PER_USEC 25
  1035. #elif F_CPU == 144000000
  1036. #define PULSEIN_LOOPS_PER_USEC 21
  1037. #elif F_CPU == 120000000
  1038. #define PULSEIN_LOOPS_PER_USEC 18
  1039. #elif F_CPU == 96000000
  1040. #define PULSEIN_LOOPS_PER_USEC 14
  1041. #elif F_CPU == 72000000
  1042. #define PULSEIN_LOOPS_PER_USEC 10
  1043. #elif F_CPU == 48000000
  1044. #define PULSEIN_LOOPS_PER_USEC 7
  1045. #elif F_CPU == 24000000
  1046. #define PULSEIN_LOOPS_PER_USEC 4
  1047. #elif F_CPU == 16000000
  1048. #define PULSEIN_LOOPS_PER_USEC 1
  1049. #elif F_CPU == 8000000
  1050. #define PULSEIN_LOOPS_PER_USEC 1
  1051. #elif F_CPU == 4000000
  1052. #define PULSEIN_LOOPS_PER_USEC 1
  1053. #elif F_CPU == 2000000
  1054. #define PULSEIN_LOOPS_PER_USEC 1
  1055. #endif
  1056. uint32_t pulseIn_high(volatile uint8_t *reg, uint32_t timeout)
  1057. {
  1058. uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
  1059. uint32_t usec_start, usec_stop;
  1060. // wait for any previous pulse to end
  1061. while (*reg) {
  1062. if (--timeout_count == 0) return 0;
  1063. }
  1064. // wait for the pulse to start
  1065. while (!*reg) {
  1066. if (--timeout_count == 0) return 0;
  1067. }
  1068. usec_start = micros();
  1069. // wait for the pulse to stop
  1070. while (*reg) {
  1071. if (--timeout_count == 0) return 0;
  1072. }
  1073. usec_stop = micros();
  1074. return usec_stop - usec_start;
  1075. }
  1076. uint32_t pulseIn_low(volatile uint8_t *reg, uint32_t timeout)
  1077. {
  1078. uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
  1079. uint32_t usec_start, usec_stop;
  1080. // wait for any previous pulse to end
  1081. while (!*reg) {
  1082. if (--timeout_count == 0) return 0;
  1083. }
  1084. // wait for the pulse to start
  1085. while (*reg) {
  1086. if (--timeout_count == 0) return 0;
  1087. }
  1088. usec_start = micros();
  1089. // wait for the pulse to stop
  1090. while (!*reg) {
  1091. if (--timeout_count == 0) return 0;
  1092. }
  1093. usec_stop = micros();
  1094. return usec_stop - usec_start;
  1095. }
  1096. // TODO: an inline version should handle the common case where state is const
  1097. uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout)
  1098. {
  1099. if (pin >= CORE_NUM_DIGITAL) return 0;
  1100. if (state) return pulseIn_high(portInputRegister(pin), timeout);
  1101. return pulseIn_low(portInputRegister(pin), timeout);;
  1102. }