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