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 години
преди 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 години
преди 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 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 10 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 10 години
преди 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 години
преди 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 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 10 години
преди 11 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  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. };
  74. #elif defined(KINETISL)
  75. const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
  76. {((volatile uint8_t *)&CORE_PIN0_PORTREG + (CORE_PIN0_BIT >> 3)), &CORE_PIN0_CONFIG, (1<<(CORE_PIN0_BIT & 7))},
  77. {((volatile uint8_t *)&CORE_PIN1_PORTREG + (CORE_PIN1_BIT >> 3)), &CORE_PIN1_CONFIG, (1<<(CORE_PIN1_BIT & 7))},
  78. {((volatile uint8_t *)&CORE_PIN2_PORTREG + (CORE_PIN2_BIT >> 3)), &CORE_PIN2_CONFIG, (1<<(CORE_PIN2_BIT & 7))},
  79. {((volatile uint8_t *)&CORE_PIN3_PORTREG + (CORE_PIN3_BIT >> 3)), &CORE_PIN3_CONFIG, (1<<(CORE_PIN3_BIT & 7))},
  80. {((volatile uint8_t *)&CORE_PIN4_PORTREG + (CORE_PIN4_BIT >> 3)), &CORE_PIN4_CONFIG, (1<<(CORE_PIN4_BIT & 7))},
  81. {((volatile uint8_t *)&CORE_PIN5_PORTREG + (CORE_PIN5_BIT >> 3)), &CORE_PIN5_CONFIG, (1<<(CORE_PIN5_BIT & 7))},
  82. {((volatile uint8_t *)&CORE_PIN6_PORTREG + (CORE_PIN6_BIT >> 3)), &CORE_PIN6_CONFIG, (1<<(CORE_PIN6_BIT & 7))},
  83. {((volatile uint8_t *)&CORE_PIN7_PORTREG + (CORE_PIN7_BIT >> 3)), &CORE_PIN7_CONFIG, (1<<(CORE_PIN7_BIT & 7))},
  84. {((volatile uint8_t *)&CORE_PIN8_PORTREG + (CORE_PIN8_BIT >> 3)), &CORE_PIN8_CONFIG, (1<<(CORE_PIN8_BIT & 7))},
  85. {((volatile uint8_t *)&CORE_PIN9_PORTREG + (CORE_PIN9_BIT >> 3)), &CORE_PIN9_CONFIG, (1<<(CORE_PIN9_BIT & 7))},
  86. {((volatile uint8_t *)&CORE_PIN10_PORTREG + (CORE_PIN10_BIT >> 3)), &CORE_PIN10_CONFIG, (1<<(CORE_PIN10_BIT & 7))},
  87. {((volatile uint8_t *)&CORE_PIN11_PORTREG + (CORE_PIN11_BIT >> 3)), &CORE_PIN11_CONFIG, (1<<(CORE_PIN11_BIT & 7))},
  88. {((volatile uint8_t *)&CORE_PIN12_PORTREG + (CORE_PIN12_BIT >> 3)), &CORE_PIN12_CONFIG, (1<<(CORE_PIN12_BIT & 7))},
  89. {((volatile uint8_t *)&CORE_PIN13_PORTREG + (CORE_PIN13_BIT >> 3)), &CORE_PIN13_CONFIG, (1<<(CORE_PIN13_BIT & 7))},
  90. {((volatile uint8_t *)&CORE_PIN14_PORTREG + (CORE_PIN14_BIT >> 3)), &CORE_PIN14_CONFIG, (1<<(CORE_PIN14_BIT & 7))},
  91. {((volatile uint8_t *)&CORE_PIN15_PORTREG + (CORE_PIN15_BIT >> 3)), &CORE_PIN15_CONFIG, (1<<(CORE_PIN15_BIT & 7))},
  92. {((volatile uint8_t *)&CORE_PIN16_PORTREG + (CORE_PIN16_BIT >> 3)), &CORE_PIN16_CONFIG, (1<<(CORE_PIN16_BIT & 7))},
  93. {((volatile uint8_t *)&CORE_PIN17_PORTREG + (CORE_PIN17_BIT >> 3)), &CORE_PIN17_CONFIG, (1<<(CORE_PIN17_BIT & 7))},
  94. {((volatile uint8_t *)&CORE_PIN18_PORTREG + (CORE_PIN18_BIT >> 3)), &CORE_PIN18_CONFIG, (1<<(CORE_PIN18_BIT & 7))},
  95. {((volatile uint8_t *)&CORE_PIN19_PORTREG + (CORE_PIN19_BIT >> 3)), &CORE_PIN19_CONFIG, (1<<(CORE_PIN19_BIT & 7))},
  96. {((volatile uint8_t *)&CORE_PIN20_PORTREG + (CORE_PIN20_BIT >> 3)), &CORE_PIN20_CONFIG, (1<<(CORE_PIN20_BIT & 7))},
  97. {((volatile uint8_t *)&CORE_PIN21_PORTREG + (CORE_PIN21_BIT >> 3)), &CORE_PIN21_CONFIG, (1<<(CORE_PIN21_BIT & 7))},
  98. {((volatile uint8_t *)&CORE_PIN22_PORTREG + (CORE_PIN22_BIT >> 3)), &CORE_PIN22_CONFIG, (1<<(CORE_PIN22_BIT & 7))},
  99. {((volatile uint8_t *)&CORE_PIN23_PORTREG + (CORE_PIN23_BIT >> 3)), &CORE_PIN23_CONFIG, (1<<(CORE_PIN23_BIT & 7))},
  100. {((volatile uint8_t *)&CORE_PIN24_PORTREG + (CORE_PIN24_BIT >> 3)), &CORE_PIN24_CONFIG, (1<<(CORE_PIN24_BIT & 7))},
  101. {((volatile uint8_t *)&CORE_PIN25_PORTREG + (CORE_PIN25_BIT >> 3)), &CORE_PIN25_CONFIG, (1<<(CORE_PIN25_BIT & 7))},
  102. {((volatile uint8_t *)&CORE_PIN26_PORTREG + (CORE_PIN26_BIT >> 3)), &CORE_PIN26_CONFIG, (1<<(CORE_PIN26_BIT & 7))}
  103. };
  104. #endif
  105. typedef void (*voidFuncPtr)(void);
  106. volatile static voidFuncPtr intFunc[CORE_NUM_DIGITAL];
  107. #if defined(KINETISK)
  108. static void porta_interrupt(void);
  109. static void portb_interrupt(void);
  110. static void portc_interrupt(void);
  111. static void portd_interrupt(void);
  112. static void porte_interrupt(void);
  113. #elif defined(KINETISL)
  114. static void porta_interrupt(void);
  115. static void portcd_interrupt(void);
  116. #endif
  117. void attachInterruptVector(enum IRQ_NUMBER_t irq, void (*function)(void))
  118. {
  119. _VectorsRam[irq + 16] = function;
  120. }
  121. void attachInterrupt(uint8_t pin, void (*function)(void), int mode)
  122. {
  123. volatile uint32_t *config;
  124. uint32_t cfg, mask;
  125. if (pin >= CORE_NUM_DIGITAL) return;
  126. switch (mode) {
  127. case CHANGE: mask = 0x0B; break;
  128. case RISING: mask = 0x09; break;
  129. case FALLING: mask = 0x0A; break;
  130. case LOW: mask = 0x08; break;
  131. case HIGH: mask = 0x0C; break;
  132. default: return;
  133. }
  134. mask = (mask << 16) | 0x01000000;
  135. config = portConfigRegister(pin);
  136. #if defined(KINETISK)
  137. attachInterruptVector(IRQ_PORTA, porta_interrupt);
  138. attachInterruptVector(IRQ_PORTB, portb_interrupt);
  139. attachInterruptVector(IRQ_PORTC, portc_interrupt);
  140. attachInterruptVector(IRQ_PORTD, portd_interrupt);
  141. attachInterruptVector(IRQ_PORTE, porte_interrupt);
  142. #elif defined(KINETISL)
  143. attachInterruptVector(IRQ_PORTA, porta_interrupt);
  144. attachInterruptVector(IRQ_PORTCD, portcd_interrupt);
  145. #endif
  146. __disable_irq();
  147. cfg = *config;
  148. cfg &= ~0x000F0000; // disable any previous interrupt
  149. *config = cfg;
  150. intFunc[pin] = function; // set the function pointer
  151. cfg |= mask;
  152. *config = cfg; // enable the new interrupt
  153. __enable_irq();
  154. }
  155. void detachInterrupt(uint8_t pin)
  156. {
  157. volatile uint32_t *config;
  158. config = portConfigRegister(pin);
  159. __disable_irq();
  160. *config = ((*config & ~0x000F0000) | 0x01000000);
  161. intFunc[pin] = NULL;
  162. __enable_irq();
  163. }
  164. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  165. static void porta_interrupt(void)
  166. {
  167. uint32_t isfr = PORTA_ISFR;
  168. PORTA_ISFR = isfr;
  169. if ((isfr & CORE_PIN3_BITMASK) && intFunc[3]) intFunc[3]();
  170. if ((isfr & CORE_PIN4_BITMASK) && intFunc[4]) intFunc[4]();
  171. if ((isfr & CORE_PIN24_BITMASK) && intFunc[24]) intFunc[24]();
  172. if ((isfr & CORE_PIN33_BITMASK) && intFunc[33]) intFunc[33]();
  173. }
  174. static void portb_interrupt(void)
  175. {
  176. uint32_t isfr = PORTB_ISFR;
  177. PORTB_ISFR = isfr;
  178. if ((isfr & CORE_PIN0_BITMASK) && intFunc[0]) intFunc[0]();
  179. if ((isfr & CORE_PIN1_BITMASK) && intFunc[1]) intFunc[1]();
  180. if ((isfr & CORE_PIN16_BITMASK) && intFunc[16]) intFunc[16]();
  181. if ((isfr & CORE_PIN17_BITMASK) && intFunc[17]) intFunc[17]();
  182. if ((isfr & CORE_PIN18_BITMASK) && intFunc[18]) intFunc[18]();
  183. if ((isfr & CORE_PIN19_BITMASK) && intFunc[19]) intFunc[19]();
  184. if ((isfr & CORE_PIN25_BITMASK) && intFunc[25]) intFunc[25]();
  185. if ((isfr & CORE_PIN32_BITMASK) && intFunc[32]) intFunc[32]();
  186. }
  187. static void portc_interrupt(void)
  188. {
  189. // TODO: these are inefficent. Use CLZ somehow....
  190. uint32_t isfr = PORTC_ISFR;
  191. PORTC_ISFR = isfr;
  192. if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9]();
  193. if ((isfr & CORE_PIN10_BITMASK) && intFunc[10]) intFunc[10]();
  194. if ((isfr & CORE_PIN11_BITMASK) && intFunc[11]) intFunc[11]();
  195. if ((isfr & CORE_PIN12_BITMASK) && intFunc[12]) intFunc[12]();
  196. if ((isfr & CORE_PIN13_BITMASK) && intFunc[13]) intFunc[13]();
  197. if ((isfr & CORE_PIN15_BITMASK) && intFunc[15]) intFunc[15]();
  198. if ((isfr & CORE_PIN22_BITMASK) && intFunc[22]) intFunc[22]();
  199. if ((isfr & CORE_PIN23_BITMASK) && intFunc[23]) intFunc[23]();
  200. if ((isfr & CORE_PIN27_BITMASK) && intFunc[27]) intFunc[27]();
  201. if ((isfr & CORE_PIN28_BITMASK) && intFunc[28]) intFunc[28]();
  202. if ((isfr & CORE_PIN29_BITMASK) && intFunc[29]) intFunc[29]();
  203. if ((isfr & CORE_PIN30_BITMASK) && intFunc[30]) intFunc[30]();
  204. }
  205. static void portd_interrupt(void)
  206. {
  207. uint32_t isfr = PORTD_ISFR;
  208. PORTD_ISFR = isfr;
  209. if ((isfr & CORE_PIN2_BITMASK) && intFunc[2]) intFunc[2]();
  210. if ((isfr & CORE_PIN5_BITMASK) && intFunc[5]) intFunc[5]();
  211. if ((isfr & CORE_PIN6_BITMASK) && intFunc[6]) intFunc[6]();
  212. if ((isfr & CORE_PIN7_BITMASK) && intFunc[7]) intFunc[7]();
  213. if ((isfr & CORE_PIN8_BITMASK) && intFunc[8]) intFunc[8]();
  214. if ((isfr & CORE_PIN14_BITMASK) && intFunc[14]) intFunc[14]();
  215. if ((isfr & CORE_PIN20_BITMASK) && intFunc[20]) intFunc[20]();
  216. if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21]();
  217. }
  218. static void porte_interrupt(void)
  219. {
  220. uint32_t isfr = PORTE_ISFR;
  221. PORTE_ISFR = isfr;
  222. if ((isfr & CORE_PIN26_BITMASK) && intFunc[26]) intFunc[26]();
  223. if ((isfr & CORE_PIN31_BITMASK) && intFunc[31]) intFunc[31]();
  224. }
  225. #elif defined(__MKL26Z64__)
  226. static void porta_interrupt(void)
  227. {
  228. uint32_t isfr = PORTA_ISFR;
  229. PORTA_ISFR = isfr;
  230. if ((isfr & CORE_PIN3_BITMASK) && intFunc[3]) intFunc[3]();
  231. if ((isfr & CORE_PIN4_BITMASK) && intFunc[4]) intFunc[4]();
  232. }
  233. static void portcd_interrupt(void)
  234. {
  235. uint32_t isfr = PORTC_ISFR;
  236. PORTC_ISFR = isfr;
  237. if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9]();
  238. if ((isfr & CORE_PIN10_BITMASK) && intFunc[10]) intFunc[10]();
  239. if ((isfr & CORE_PIN11_BITMASK) && intFunc[11]) intFunc[11]();
  240. if ((isfr & CORE_PIN12_BITMASK) && intFunc[12]) intFunc[12]();
  241. if ((isfr & CORE_PIN13_BITMASK) && intFunc[13]) intFunc[13]();
  242. if ((isfr & CORE_PIN15_BITMASK) && intFunc[15]) intFunc[15]();
  243. if ((isfr & CORE_PIN22_BITMASK) && intFunc[22]) intFunc[22]();
  244. if ((isfr & CORE_PIN23_BITMASK) && intFunc[23]) intFunc[23]();
  245. isfr = PORTD_ISFR;
  246. PORTD_ISFR = isfr;
  247. if ((isfr & CORE_PIN2_BITMASK) && intFunc[2]) intFunc[2]();
  248. if ((isfr & CORE_PIN5_BITMASK) && intFunc[5]) intFunc[5]();
  249. if ((isfr & CORE_PIN6_BITMASK) && intFunc[6]) intFunc[6]();
  250. if ((isfr & CORE_PIN7_BITMASK) && intFunc[7]) intFunc[7]();
  251. if ((isfr & CORE_PIN8_BITMASK) && intFunc[8]) intFunc[8]();
  252. if ((isfr & CORE_PIN14_BITMASK) && intFunc[14]) intFunc[14]();
  253. if ((isfr & CORE_PIN20_BITMASK) && intFunc[20]) intFunc[20]();
  254. if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21]();
  255. }
  256. #endif
  257. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  258. unsigned long rtc_get(void)
  259. {
  260. return RTC_TSR;
  261. }
  262. void rtc_set(unsigned long t)
  263. {
  264. RTC_SR = 0;
  265. RTC_TPR = 0;
  266. RTC_TSR = t;
  267. RTC_SR = RTC_SR_TCE;
  268. }
  269. // adjust is the amount of crystal error to compensate, 1 = 0.1192 ppm
  270. // For example, adjust = -100 is slows the clock by 11.92 ppm
  271. //
  272. void rtc_compensate(int adjust)
  273. {
  274. uint32_t comp, interval, tcr;
  275. // This simple approach tries to maximize the interval.
  276. // Perhaps minimizing TCR would be better, so the
  277. // compensation is distributed more evenly across
  278. // many seconds, rather than saving it all up and then
  279. // altering one second up to +/- 0.38%
  280. if (adjust >= 0) {
  281. comp = adjust;
  282. interval = 256;
  283. while (1) {
  284. tcr = comp * interval;
  285. if (tcr < 128*256) break;
  286. if (--interval == 1) break;
  287. }
  288. tcr = tcr >> 8;
  289. } else {
  290. comp = -adjust;
  291. interval = 256;
  292. while (1) {
  293. tcr = comp * interval;
  294. if (tcr < 129*256) break;
  295. if (--interval == 1) break;
  296. }
  297. tcr = tcr >> 8;
  298. tcr = 256 - tcr;
  299. }
  300. RTC_TCR = ((interval - 1) << 8) | tcr;
  301. }
  302. #else
  303. unsigned long rtc_get(void) { return 0; }
  304. void rtc_set(unsigned long t) { }
  305. void rtc_compensate(int adjust) { }
  306. #endif
  307. #if 0
  308. // TODO: build system should define this
  309. // so RTC is automatically initialized to approx correct time
  310. // at least when the program begins running right after upload
  311. #ifndef TIME_T
  312. #define TIME_T 1350160272
  313. #endif
  314. void init_rtc(void)
  315. {
  316. serial_print("init_rtc\n");
  317. //SIM_SCGC6 |= SIM_SCGC6_RTC;
  318. // enable the RTC crystal oscillator, for approx 12pf crystal
  319. if (!(RTC_CR & RTC_CR_OSCE)) {
  320. serial_print("start RTC oscillator\n");
  321. RTC_SR = 0;
  322. RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
  323. }
  324. // should wait for crystal to stabilize.....
  325. serial_print("SR=");
  326. serial_phex32(RTC_SR);
  327. serial_print("\n");
  328. serial_print("CR=");
  329. serial_phex32(RTC_CR);
  330. serial_print("\n");
  331. serial_print("TSR=");
  332. serial_phex32(RTC_TSR);
  333. serial_print("\n");
  334. serial_print("TCR=");
  335. serial_phex32(RTC_TCR);
  336. serial_print("\n");
  337. if (RTC_SR & RTC_SR_TIF) {
  338. // enable the RTC
  339. RTC_SR = 0;
  340. RTC_TPR = 0;
  341. RTC_TSR = TIME_T;
  342. RTC_SR = RTC_SR_TCE;
  343. }
  344. }
  345. #endif
  346. extern void usb_init(void);
  347. // create a default PWM at the same 488.28 Hz as Arduino Uno
  348. #if defined(KINETISK)
  349. #define F_TIMER F_BUS
  350. #elif defined(KINETISL)
  351. #if F_CPU > 16000000
  352. #define F_TIMER (F_PLL/2)
  353. #else
  354. #define F_TIMER (F_PLL)
  355. #endif//Low Power
  356. #endif
  357. #if F_TIMER == 60000000
  358. #define DEFAULT_FTM_MOD (61440 - 1)
  359. #define DEFAULT_FTM_PRESCALE 1
  360. #elif F_TIMER == 56000000
  361. #define DEFAULT_FTM_MOD (57344 - 1)
  362. #define DEFAULT_FTM_PRESCALE 1
  363. #elif F_TIMER == 48000000
  364. #define DEFAULT_FTM_MOD (49152 - 1)
  365. #define DEFAULT_FTM_PRESCALE 1
  366. #elif F_TIMER == 40000000
  367. #define DEFAULT_FTM_MOD (40960 - 1)
  368. #define DEFAULT_FTM_PRESCALE 1
  369. #elif F_TIMER == 36000000
  370. #define DEFAULT_FTM_MOD (36864 - 1)
  371. #define DEFAULT_FTM_PRESCALE 1
  372. #elif F_TIMER == 24000000
  373. #define DEFAULT_FTM_MOD (49152 - 1)
  374. #define DEFAULT_FTM_PRESCALE 0
  375. #elif F_TIMER == 16000000
  376. #define DEFAULT_FTM_MOD (32768 - 1)
  377. #define DEFAULT_FTM_PRESCALE 0
  378. #elif F_TIMER == 8000000
  379. #define DEFAULT_FTM_MOD (16384 - 1)
  380. #define DEFAULT_FTM_PRESCALE 0
  381. #elif F_TIMER == 4000000
  382. #define DEFAULT_FTM_MOD (8192 - 1)
  383. #define DEFAULT_FTM_PRESCALE 0
  384. #elif F_TIMER == 2000000
  385. #define DEFAULT_FTM_MOD (4096 - 1)
  386. #define DEFAULT_FTM_PRESCALE 0
  387. #endif
  388. //void init_pins(void)
  389. void _init_Teensyduino_internal_(void)
  390. {
  391. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  392. NVIC_ENABLE_IRQ(IRQ_PORTA);
  393. NVIC_ENABLE_IRQ(IRQ_PORTB);
  394. NVIC_ENABLE_IRQ(IRQ_PORTC);
  395. NVIC_ENABLE_IRQ(IRQ_PORTD);
  396. NVIC_ENABLE_IRQ(IRQ_PORTE);
  397. #elif defined(__MKL26Z64__)
  398. NVIC_ENABLE_IRQ(IRQ_PORTA);
  399. NVIC_ENABLE_IRQ(IRQ_PORTCD);
  400. #endif
  401. //SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write
  402. //SIM_SCGC6 |= SIM_SCGC6_FTM1;
  403. FTM0_CNT = 0;
  404. FTM0_MOD = DEFAULT_FTM_MOD;
  405. FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
  406. FTM0_C1SC = 0x28;
  407. FTM0_C2SC = 0x28;
  408. FTM0_C3SC = 0x28;
  409. FTM0_C4SC = 0x28;
  410. FTM0_C5SC = 0x28;
  411. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  412. FTM0_C6SC = 0x28;
  413. FTM0_C7SC = 0x28;
  414. #endif
  415. FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  416. FTM1_CNT = 0;
  417. FTM1_MOD = DEFAULT_FTM_MOD;
  418. FTM1_C0SC = 0x28;
  419. FTM1_C1SC = 0x28;
  420. FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  421. #if defined(__MK20DX256__) || defined(__MKL26Z64__)
  422. FTM2_CNT = 0;
  423. FTM2_MOD = DEFAULT_FTM_MOD;
  424. FTM2_C0SC = 0x28;
  425. FTM2_C1SC = 0x28;
  426. FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  427. #endif
  428. analog_init();
  429. //delay(100); // TODO: this is not necessary, right?
  430. delay(4);
  431. usb_init();
  432. }
  433. #if defined(__MK20DX128__)
  434. #define FTM0_CH0_PIN 22
  435. #define FTM0_CH1_PIN 23
  436. #define FTM0_CH2_PIN 9
  437. #define FTM0_CH3_PIN 10
  438. #define FTM0_CH4_PIN 6
  439. #define FTM0_CH5_PIN 20
  440. #define FTM0_CH6_PIN 21
  441. #define FTM0_CH7_PIN 5
  442. #define FTM1_CH0_PIN 3
  443. #define FTM1_CH1_PIN 4
  444. #elif defined(__MK20DX256__)
  445. #define FTM0_CH0_PIN 22
  446. #define FTM0_CH1_PIN 23
  447. #define FTM0_CH2_PIN 9
  448. #define FTM0_CH3_PIN 10
  449. #define FTM0_CH4_PIN 6
  450. #define FTM0_CH5_PIN 20
  451. #define FTM0_CH6_PIN 21
  452. #define FTM0_CH7_PIN 5
  453. #define FTM1_CH0_PIN 3
  454. #define FTM1_CH1_PIN 4
  455. #define FTM2_CH0_PIN 32
  456. #define FTM2_CH1_PIN 25
  457. #elif defined(__MKL26Z64__)
  458. #define FTM0_CH0_PIN 22
  459. #define FTM0_CH1_PIN 23
  460. #define FTM0_CH2_PIN 9
  461. #define FTM0_CH3_PIN 10
  462. #define FTM0_CH4_PIN 6
  463. #define FTM0_CH5_PIN 20
  464. #define FTM1_CH0_PIN 16
  465. #define FTM1_CH1_PIN 17
  466. #define FTM2_CH0_PIN 3
  467. #define FTM2_CH1_PIN 4
  468. #endif
  469. #define FTM_PINCFG(pin) FTM_PINCFG2(pin)
  470. #define FTM_PINCFG2(pin) CORE_PIN ## pin ## _CONFIG
  471. static uint8_t analog_write_res = 8;
  472. // SOPT4 is SIM select clocks?
  473. // FTM is clocked by the bus clock, either 24 or 48 MHz
  474. // input capture can be FTM1_CH0, CMP0 or CMP1 or USB start of frame
  475. // 24 MHz with reload 49152 to match Arduino's speed = 488.28125 Hz
  476. void analogWrite(uint8_t pin, int val)
  477. {
  478. uint32_t cval, max;
  479. #if defined(__MK20DX256__)
  480. if (pin == A14) {
  481. uint8_t res = analog_write_res;
  482. if (res < 12) {
  483. val <<= 12 - res;
  484. } else if (res > 12) {
  485. val >>= res - 12;
  486. }
  487. analogWriteDAC0(val);
  488. return;
  489. }
  490. #elif defined(__MKL26Z64__)
  491. if (pin == A12) {
  492. uint8_t res = analog_write_res;
  493. if (res < 12) {
  494. val <<= 12 - res;
  495. } else if (res > 12) {
  496. val >>= res - 12;
  497. }
  498. analogWriteDAC0(val);
  499. return;
  500. }
  501. #endif
  502. max = 1 << analog_write_res;
  503. if (val <= 0) {
  504. digitalWrite(pin, LOW);
  505. pinMode(pin, OUTPUT); // TODO: implement OUTPUT_LOW
  506. return;
  507. } else if (val >= max) {
  508. digitalWrite(pin, HIGH);
  509. pinMode(pin, OUTPUT); // TODO: implement OUTPUT_HIGH
  510. return;
  511. }
  512. //serial_print("analogWrite\n");
  513. //serial_print("val = ");
  514. //serial_phex32(val);
  515. //serial_print("\n");
  516. //serial_print("analog_write_res = ");
  517. //serial_phex(analog_write_res);
  518. //serial_print("\n");
  519. if (pin == FTM1_CH0_PIN || pin == FTM1_CH1_PIN) {
  520. cval = ((uint32_t)val * (uint32_t)(FTM1_MOD + 1)) >> analog_write_res;
  521. #if defined(FTM2_CH0_PIN)
  522. } else if (pin == FTM2_CH0_PIN || pin == FTM2_CH1_PIN) {
  523. cval = ((uint32_t)val * (uint32_t)(FTM2_MOD + 1)) >> analog_write_res;
  524. #endif
  525. } else {
  526. cval = ((uint32_t)val * (uint32_t)(FTM0_MOD + 1)) >> analog_write_res;
  527. }
  528. //serial_print("cval = ");
  529. //serial_phex32(cval);
  530. //serial_print("\n");
  531. switch (pin) {
  532. #ifdef FTM0_CH0_PIN
  533. case FTM0_CH0_PIN: // PTC1, FTM0_CH0
  534. FTM0_C0V = cval;
  535. FTM_PINCFG(FTM0_CH0_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  536. break;
  537. #endif
  538. #ifdef FTM0_CH1_PIN
  539. case FTM0_CH1_PIN: // PTC2, FTM0_CH1
  540. FTM0_C1V = cval;
  541. FTM_PINCFG(FTM0_CH1_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  542. break;
  543. #endif
  544. #ifdef FTM0_CH2_PIN
  545. case FTM0_CH2_PIN: // PTC3, FTM0_CH2
  546. FTM0_C2V = cval;
  547. FTM_PINCFG(FTM0_CH2_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  548. break;
  549. #endif
  550. #ifdef FTM0_CH3_PIN
  551. case FTM0_CH3_PIN: // PTC4, FTM0_CH3
  552. FTM0_C3V = cval;
  553. FTM_PINCFG(FTM0_CH3_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  554. break;
  555. #endif
  556. #ifdef FTM0_CH4_PIN
  557. case FTM0_CH4_PIN: // PTD4, FTM0_CH4
  558. FTM0_C4V = cval;
  559. FTM_PINCFG(FTM0_CH4_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  560. break;
  561. #endif
  562. #ifdef FTM0_CH5_PIN
  563. case FTM0_CH5_PIN: // PTD5, FTM0_CH5
  564. FTM0_C5V = cval;
  565. FTM_PINCFG(FTM0_CH5_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  566. break;
  567. #endif
  568. #ifdef FTM0_CH6_PIN
  569. case FTM0_CH6_PIN: // PTD6, FTM0_CH6
  570. FTM0_C6V = cval;
  571. FTM_PINCFG(FTM0_CH6_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  572. break;
  573. #endif
  574. #ifdef FTM0_CH7_PIN
  575. case FTM0_CH7_PIN: // PTD7, FTM0_CH7
  576. FTM0_C7V = cval;
  577. FTM_PINCFG(FTM0_CH7_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  578. break;
  579. #endif
  580. #ifdef FTM1_CH0_PIN
  581. case FTM1_CH0_PIN: // PTA12, FTM1_CH0
  582. FTM1_C0V = cval;
  583. FTM_PINCFG(FTM1_CH0_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  584. break;
  585. #endif
  586. #ifdef FTM1_CH1_PIN
  587. case FTM1_CH1_PIN: // PTA13, FTM1_CH1
  588. FTM1_C1V = cval;
  589. FTM_PINCFG(FTM1_CH1_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  590. break;
  591. #endif
  592. #ifdef FTM2_CH0_PIN
  593. case FTM2_CH0_PIN: // PTB18, FTM2_CH0
  594. FTM2_C0V = cval;
  595. FTM_PINCFG(FTM2_CH0_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  596. break;
  597. #endif
  598. #ifdef FTM2_CH1_PIN
  599. case FTM2_CH1_PIN: // PTB19, FTM1_CH1
  600. FTM2_C1V = cval;
  601. FTM_PINCFG(FTM2_CH1_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  602. break;
  603. #endif
  604. default:
  605. digitalWrite(pin, (val > 127) ? HIGH : LOW);
  606. pinMode(pin, OUTPUT);
  607. }
  608. }
  609. void analogWriteRes(uint32_t bits)
  610. {
  611. if (bits < 1) {
  612. bits = 1;
  613. } else if (bits > 16) {
  614. bits = 16;
  615. }
  616. analog_write_res = bits;
  617. }
  618. void analogWriteFrequency(uint8_t pin, uint32_t frequency)
  619. {
  620. uint32_t minfreq, prescale, mod;
  621. //serial_print("analogWriteFrequency: pin = ");
  622. //serial_phex(pin);
  623. //serial_print(", freq = ");
  624. //serial_phex32(frequency);
  625. //serial_print("\n");
  626. for (prescale = 0; prescale < 7; prescale++) {
  627. minfreq = (F_TIMER >> 16) >> prescale;
  628. if (frequency > minfreq) break;
  629. }
  630. //serial_print("F_TIMER = ");
  631. //serial_phex32(F_TIMER >> prescale);
  632. //serial_print("\n");
  633. //serial_print("prescale = ");
  634. //serial_phex(prescale);
  635. //serial_print("\n");
  636. //mod = ((F_TIMER >> prescale) / frequency) - 1;
  637. mod = (((F_TIMER >> prescale) + (frequency >> 1)) / frequency) - 1;
  638. if (mod > 65535) mod = 65535;
  639. //serial_print("mod = ");
  640. //serial_phex32(mod);
  641. //serial_print("\n");
  642. if (pin == FTM1_CH0_PIN || pin == FTM1_CH1_PIN) {
  643. FTM1_SC = 0;
  644. FTM1_CNT = 0;
  645. FTM1_MOD = mod;
  646. FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
  647. } else if (pin == FTM0_CH0_PIN || pin == FTM0_CH1_PIN
  648. || pin == FTM0_CH2_PIN || pin == FTM0_CH3_PIN
  649. || pin == FTM0_CH4_PIN || pin == FTM0_CH5_PIN
  650. #ifdef FTM0_CH6_PIN
  651. || pin == FTM0_CH6_PIN || pin == FTM0_CH7_PIN
  652. #endif
  653. ) {
  654. FTM0_SC = 0;
  655. FTM0_CNT = 0;
  656. FTM0_MOD = mod;
  657. FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
  658. }
  659. #ifdef FTM2_CH0_PIN
  660. else if (pin == FTM2_CH0_PIN || pin == FTM2_CH1_PIN) {
  661. FTM2_SC = 0;
  662. FTM2_CNT = 0;
  663. FTM2_MOD = mod;
  664. FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
  665. }
  666. #endif
  667. }
  668. // TODO: startup code needs to initialize all pins to GPIO mode, input by default
  669. void digitalWrite(uint8_t pin, uint8_t val)
  670. {
  671. if (pin >= CORE_NUM_DIGITAL) return;
  672. #ifdef KINETISK
  673. if (*portModeRegister(pin)) {
  674. if (val) {
  675. *portSetRegister(pin) = 1;
  676. } else {
  677. *portClearRegister(pin) = 1;
  678. }
  679. #else
  680. if (*portModeRegister(pin) & digitalPinToBitMask(pin)) {
  681. if (val) {
  682. *portSetRegister(pin) = digitalPinToBitMask(pin);
  683. } else {
  684. *portClearRegister(pin) = digitalPinToBitMask(pin);
  685. }
  686. #endif
  687. } else {
  688. volatile uint32_t *config = portConfigRegister(pin);
  689. if (val) {
  690. // TODO use bitband for atomic read-mod-write
  691. *config |= (PORT_PCR_PE | PORT_PCR_PS);
  692. //*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
  693. } else {
  694. // TODO use bitband for atomic read-mod-write
  695. *config &= ~(PORT_PCR_PE);
  696. //*config = PORT_PCR_MUX(1);
  697. }
  698. }
  699. }
  700. uint8_t digitalRead(uint8_t pin)
  701. {
  702. if (pin >= CORE_NUM_DIGITAL) return 0;
  703. #ifdef KINETISK
  704. return *portInputRegister(pin);
  705. #else
  706. return (*portInputRegister(pin) & digitalPinToBitMask(pin)) ? 1 : 0;
  707. #endif
  708. }
  709. void pinMode(uint8_t pin, uint8_t mode)
  710. {
  711. volatile uint32_t *config;
  712. if (pin >= CORE_NUM_DIGITAL) return;
  713. config = portConfigRegister(pin);
  714. if (mode == OUTPUT) {
  715. #ifdef KINETISK
  716. *portModeRegister(pin) = 1;
  717. #else
  718. *portModeRegister(pin) |= digitalPinToBitMask(pin); // TODO: atomic
  719. #endif
  720. *config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  721. } else {
  722. #ifdef KINETISK
  723. *portModeRegister(pin) = 0;
  724. #else
  725. *portModeRegister(pin) &= ~digitalPinToBitMask(pin);
  726. #endif
  727. if (mode == INPUT) {
  728. *config = PORT_PCR_MUX(1);
  729. } else {
  730. *config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; // pullup
  731. }
  732. }
  733. }
  734. void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value)
  735. {
  736. if (bitOrder == LSBFIRST) {
  737. shiftOut_lsbFirst(dataPin, clockPin, value);
  738. } else {
  739. shiftOut_msbFirst(dataPin, clockPin, value);
  740. }
  741. }
  742. void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
  743. {
  744. uint8_t mask;
  745. for (mask=0x01; mask; mask <<= 1) {
  746. digitalWrite(dataPin, value & mask);
  747. digitalWrite(clockPin, HIGH);
  748. digitalWrite(clockPin, LOW);
  749. }
  750. }
  751. void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
  752. {
  753. uint8_t mask;
  754. for (mask=0x80; mask; mask >>= 1) {
  755. digitalWrite(dataPin, value & mask);
  756. digitalWrite(clockPin, HIGH);
  757. digitalWrite(clockPin, LOW);
  758. }
  759. }
  760. uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
  761. {
  762. if (bitOrder == LSBFIRST) {
  763. return shiftIn_lsbFirst(dataPin, clockPin);
  764. } else {
  765. return shiftIn_msbFirst(dataPin, clockPin);
  766. }
  767. }
  768. uint8_t shiftIn_lsbFirst(uint8_t dataPin, uint8_t clockPin)
  769. {
  770. uint8_t mask, value=0;
  771. for (mask=0x01; mask; mask <<= 1) {
  772. digitalWrite(clockPin, HIGH);
  773. if (digitalRead(dataPin)) value |= mask;
  774. digitalWrite(clockPin, LOW);
  775. }
  776. return value;
  777. }
  778. uint8_t shiftIn_msbFirst(uint8_t dataPin, uint8_t clockPin)
  779. {
  780. uint8_t mask, value=0;
  781. for (mask=0x80; mask; mask >>= 1) {
  782. digitalWrite(clockPin, HIGH);
  783. if (digitalRead(dataPin)) value |= mask;
  784. digitalWrite(clockPin, LOW);
  785. }
  786. return value;
  787. }
  788. // the systick interrupt is supposed to increment this at 1 kHz rate
  789. volatile uint32_t systick_millis_count = 0;
  790. //uint32_t systick_current, systick_count, systick_istatus; // testing only
  791. uint32_t micros(void)
  792. {
  793. uint32_t count, current, istatus;
  794. __disable_irq();
  795. current = SYST_CVR;
  796. count = systick_millis_count;
  797. istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
  798. __enable_irq();
  799. //systick_current = current;
  800. //systick_count = count;
  801. //systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0;
  802. if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
  803. current = ((F_CPU / 1000) - 1) - current;
  804. return count * 1000 + current / (F_CPU / 1000000);
  805. }
  806. void delay(uint32_t ms)
  807. {
  808. uint32_t start = micros();
  809. if (ms > 0) {
  810. while (1) {
  811. if ((micros() - start) >= 1000) {
  812. ms--;
  813. if (ms == 0) return;
  814. start += 1000;
  815. }
  816. yield();
  817. }
  818. }
  819. }
  820. // TODO: verify these result in correct timeouts...
  821. #if F_CPU == 168000000
  822. #define PULSEIN_LOOPS_PER_USEC 25
  823. #elif F_CPU == 144000000
  824. #define PULSEIN_LOOPS_PER_USEC 21
  825. #elif F_CPU == 120000000
  826. #define PULSEIN_LOOPS_PER_USEC 18
  827. #elif F_CPU == 96000000
  828. #define PULSEIN_LOOPS_PER_USEC 14
  829. #elif F_CPU == 72000000
  830. #define PULSEIN_LOOPS_PER_USEC 10
  831. #elif F_CPU == 48000000
  832. #define PULSEIN_LOOPS_PER_USEC 7
  833. #elif F_CPU == 24000000
  834. #define PULSEIN_LOOPS_PER_USEC 4
  835. #elif F_CPU == 16000000
  836. #define PULSEIN_LOOPS_PER_USEC 1
  837. #elif F_CPU == 8000000
  838. #define PULSEIN_LOOPS_PER_USEC 1
  839. #elif F_CPU == 4000000
  840. #define PULSEIN_LOOPS_PER_USEC 1
  841. #elif F_CPU == 2000000
  842. #define PULSEIN_LOOPS_PER_USEC 1
  843. #endif
  844. uint32_t pulseIn_high(volatile uint8_t *reg, uint32_t timeout)
  845. {
  846. uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
  847. uint32_t usec_start, usec_stop;
  848. // wait for any previous pulse to end
  849. while (*reg) {
  850. if (--timeout_count == 0) return 0;
  851. }
  852. // wait for the pulse to start
  853. while (!*reg) {
  854. if (--timeout_count == 0) return 0;
  855. }
  856. usec_start = micros();
  857. // wait for the pulse to stop
  858. while (*reg) {
  859. if (--timeout_count == 0) return 0;
  860. }
  861. usec_stop = micros();
  862. return usec_stop - usec_start;
  863. }
  864. uint32_t pulseIn_low(volatile uint8_t *reg, uint32_t timeout)
  865. {
  866. uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
  867. uint32_t usec_start, usec_stop;
  868. // wait for any previous pulse to end
  869. while (!*reg) {
  870. if (--timeout_count == 0) return 0;
  871. }
  872. // wait for the pulse to start
  873. while (*reg) {
  874. if (--timeout_count == 0) return 0;
  875. }
  876. usec_start = micros();
  877. // wait for the pulse to stop
  878. while (!*reg) {
  879. if (--timeout_count == 0) return 0;
  880. }
  881. usec_stop = micros();
  882. return usec_stop - usec_start;
  883. }
  884. // TODO: an inline version should handle the common case where state is const
  885. uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout)
  886. {
  887. if (pin >= CORE_NUM_DIGITAL) return 0;
  888. if (state) return pulseIn_high(portInputRegister(pin), timeout);
  889. return pulseIn_low(portInputRegister(pin), timeout);;
  890. }