Kiibohd Controller
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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

mk20dx.c 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2013 PJRC.COM, LLC.
  4. * Modifications by Jacob Alexander 2014-2015
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * "Software"), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sublicense, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * 1. The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * 2. If the Software is incorporated into a build system that allows
  18. * selection among a list of target devices, then similar target
  19. * devices manufactured by PJRC.COM must be included in the list of
  20. * target devices and selectable in the same manner.
  21. *
  22. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  26. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  27. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  28. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  29. * SOFTWARE.
  30. */
  31. // ----- Includes -----
  32. // Local Includes
  33. #include "mk20dx.h"
  34. // ----- Variables -----
  35. extern unsigned long _stext;
  36. extern unsigned long _etext;
  37. extern unsigned long _sdata;
  38. extern unsigned long _edata;
  39. extern unsigned long _sbss;
  40. extern unsigned long _ebss;
  41. extern unsigned long _estack;
  42. const uint8_t sys_reset_to_loader_magic[22] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff";
  43. // ----- Function Declarations -----
  44. extern int main();
  45. void ResetHandler();
  46. // ----- Interrupts -----
  47. // NVIC - Default ISR
  48. void fault_isr()
  49. {
  50. while ( 1 )
  51. {
  52. // keep polling some communication while in fault
  53. // mode, so we don't completely die.
  54. if ( SIM_SCGC4 & SIM_SCGC4_USBOTG ) usb_isr();
  55. if ( SIM_SCGC4 & SIM_SCGC4_UART0 ) uart0_status_isr();
  56. if ( SIM_SCGC4 & SIM_SCGC4_UART1 ) uart1_status_isr();
  57. if ( SIM_SCGC4 & SIM_SCGC4_UART2 ) uart2_status_isr();
  58. }
  59. }
  60. void unused_isr()
  61. {
  62. fault_isr();
  63. }
  64. // NVIC - SysTick ISR
  65. extern volatile uint32_t systick_millis_count;
  66. void systick_default_isr()
  67. {
  68. systick_millis_count++;
  69. }
  70. // NVIC - Default ISR/Vector Linking
  71. void nmi_isr() __attribute__ ((weak, alias("unused_isr")));
  72. void hard_fault_isr() __attribute__ ((weak, alias("unused_isr")));
  73. void memmanage_fault_isr() __attribute__ ((weak, alias("unused_isr")));
  74. void bus_fault_isr() __attribute__ ((weak, alias("unused_isr")));
  75. void usage_fault_isr() __attribute__ ((weak, alias("unused_isr")));
  76. void svcall_isr() __attribute__ ((weak, alias("unused_isr")));
  77. void debugmonitor_isr() __attribute__ ((weak, alias("unused_isr")));
  78. void pendablesrvreq_isr() __attribute__ ((weak, alias("unused_isr")));
  79. void systick_isr() __attribute__ ((weak, alias("systick_default_isr")));
  80. void dma_ch0_isr() __attribute__ ((weak, alias("unused_isr")));
  81. void dma_ch1_isr() __attribute__ ((weak, alias("unused_isr")));
  82. void dma_ch2_isr() __attribute__ ((weak, alias("unused_isr")));
  83. void dma_ch3_isr() __attribute__ ((weak, alias("unused_isr")));
  84. void dma_ch4_isr() __attribute__ ((weak, alias("unused_isr")));
  85. void dma_ch5_isr() __attribute__ ((weak, alias("unused_isr")));
  86. void dma_ch6_isr() __attribute__ ((weak, alias("unused_isr")));
  87. void dma_ch7_isr() __attribute__ ((weak, alias("unused_isr")));
  88. void dma_ch8_isr() __attribute__ ((weak, alias("unused_isr")));
  89. void dma_ch9_isr() __attribute__ ((weak, alias("unused_isr")));
  90. void dma_ch10_isr() __attribute__ ((weak, alias("unused_isr")));
  91. void dma_ch11_isr() __attribute__ ((weak, alias("unused_isr")));
  92. void dma_ch12_isr() __attribute__ ((weak, alias("unused_isr")));
  93. void dma_ch13_isr() __attribute__ ((weak, alias("unused_isr")));
  94. void dma_ch14_isr() __attribute__ ((weak, alias("unused_isr")));
  95. void dma_ch15_isr() __attribute__ ((weak, alias("unused_isr")));
  96. void dma_error_isr() __attribute__ ((weak, alias("unused_isr")));
  97. void mcm_isr() __attribute__ ((weak, alias("unused_isr")));
  98. void flash_cmd_isr() __attribute__ ((weak, alias("unused_isr")));
  99. void flash_error_isr() __attribute__ ((weak, alias("unused_isr")));
  100. void low_voltage_isr() __attribute__ ((weak, alias("unused_isr")));
  101. void wakeup_isr() __attribute__ ((weak, alias("unused_isr")));
  102. void watchdog_isr() __attribute__ ((weak, alias("unused_isr")));
  103. void i2c0_isr() __attribute__ ((weak, alias("unused_isr")));
  104. void i2c1_isr() __attribute__ ((weak, alias("unused_isr")));
  105. void i2c2_isr() __attribute__ ((weak, alias("unused_isr")));
  106. void spi0_isr() __attribute__ ((weak, alias("unused_isr")));
  107. void spi1_isr() __attribute__ ((weak, alias("unused_isr")));
  108. void spi2_isr() __attribute__ ((weak, alias("unused_isr")));
  109. void sdhc_isr() __attribute__ ((weak, alias("unused_isr")));
  110. void can0_message_isr() __attribute__ ((weak, alias("unused_isr")));
  111. void can0_bus_off_isr() __attribute__ ((weak, alias("unused_isr")));
  112. void can0_error_isr() __attribute__ ((weak, alias("unused_isr")));
  113. void can0_tx_warn_isr() __attribute__ ((weak, alias("unused_isr")));
  114. void can0_rx_warn_isr() __attribute__ ((weak, alias("unused_isr")));
  115. void can0_wakeup_isr() __attribute__ ((weak, alias("unused_isr")));
  116. void i2s0_tx_isr() __attribute__ ((weak, alias("unused_isr")));
  117. void i2s0_rx_isr() __attribute__ ((weak, alias("unused_isr")));
  118. void uart0_lon_isr() __attribute__ ((weak, alias("unused_isr")));
  119. void uart0_status_isr() __attribute__ ((weak, alias("unused_isr")));
  120. void uart0_error_isr() __attribute__ ((weak, alias("unused_isr")));
  121. void uart1_status_isr() __attribute__ ((weak, alias("unused_isr")));
  122. void uart1_error_isr() __attribute__ ((weak, alias("unused_isr")));
  123. void uart2_status_isr() __attribute__ ((weak, alias("unused_isr")));
  124. void uart2_error_isr() __attribute__ ((weak, alias("unused_isr")));
  125. void uart3_status_isr() __attribute__ ((weak, alias("unused_isr")));
  126. void uart3_error_isr() __attribute__ ((weak, alias("unused_isr")));
  127. void uart4_status_isr() __attribute__ ((weak, alias("unused_isr")));
  128. void uart4_error_isr() __attribute__ ((weak, alias("unused_isr")));
  129. void uart5_status_isr() __attribute__ ((weak, alias("unused_isr")));
  130. void uart5_error_isr() __attribute__ ((weak, alias("unused_isr")));
  131. void adc0_isr() __attribute__ ((weak, alias("unused_isr")));
  132. void adc1_isr() __attribute__ ((weak, alias("unused_isr")));
  133. void cmp0_isr() __attribute__ ((weak, alias("unused_isr")));
  134. void cmp1_isr() __attribute__ ((weak, alias("unused_isr")));
  135. void cmp2_isr() __attribute__ ((weak, alias("unused_isr")));
  136. void ftm0_isr() __attribute__ ((weak, alias("unused_isr")));
  137. void ftm1_isr() __attribute__ ((weak, alias("unused_isr")));
  138. void ftm2_isr() __attribute__ ((weak, alias("unused_isr")));
  139. void ftm3_isr() __attribute__ ((weak, alias("unused_isr")));
  140. void cmt_isr() __attribute__ ((weak, alias("unused_isr")));
  141. void rtc_alarm_isr() __attribute__ ((weak, alias("unused_isr")));
  142. void rtc_seconds_isr() __attribute__ ((weak, alias("unused_isr")));
  143. void pit0_isr() __attribute__ ((weak, alias("unused_isr")));
  144. void pit1_isr() __attribute__ ((weak, alias("unused_isr")));
  145. void pit2_isr() __attribute__ ((weak, alias("unused_isr")));
  146. void pit3_isr() __attribute__ ((weak, alias("unused_isr")));
  147. void pdb_isr() __attribute__ ((weak, alias("unused_isr")));
  148. void usb_isr() __attribute__ ((weak, alias("unused_isr")));
  149. void usb_charge_isr() __attribute__ ((weak, alias("unused_isr")));
  150. void dac0_isr() __attribute__ ((weak, alias("unused_isr")));
  151. void dac1_isr() __attribute__ ((weak, alias("unused_isr")));
  152. void tsi0_isr() __attribute__ ((weak, alias("unused_isr")));
  153. void mcg_isr() __attribute__ ((weak, alias("unused_isr")));
  154. void lptmr_isr() __attribute__ ((weak, alias("unused_isr")));
  155. void porta_isr() __attribute__ ((weak, alias("unused_isr")));
  156. void portb_isr() __attribute__ ((weak, alias("unused_isr")));
  157. void portc_isr() __attribute__ ((weak, alias("unused_isr")));
  158. void portd_isr() __attribute__ ((weak, alias("unused_isr")));
  159. void porte_isr() __attribute__ ((weak, alias("unused_isr")));
  160. void software_isr() __attribute__ ((weak, alias("unused_isr")));
  161. // NVIC - Interrupt Vector Table
  162. __attribute__ ((section(".vectors"), used))
  163. void (* const gVectors[])() =
  164. {
  165. (void (*)(void))((unsigned long)&_estack), // 0 ARM: Initial Stack Pointer
  166. ResetHandler, // 1 ARM: Initial Program Counter
  167. nmi_isr, // 2 ARM: Non-maskable Interrupt (NMI)
  168. hard_fault_isr, // 3 ARM: Hard Fault
  169. memmanage_fault_isr, // 4 ARM: MemManage Fault
  170. bus_fault_isr, // 5 ARM: Bus Fault
  171. usage_fault_isr, // 6 ARM: Usage Fault
  172. fault_isr, // 7 --
  173. fault_isr, // 8 --
  174. fault_isr, // 9 --
  175. fault_isr, // 10 --
  176. svcall_isr, // 11 ARM: Supervisor call (SVCall)
  177. debugmonitor_isr, // 12 ARM: Debug Monitor
  178. fault_isr, // 13 --
  179. pendablesrvreq_isr, // 14 ARM: Pendable req serv(PendableSrvReq)
  180. systick_isr, // 15 ARM: System tick timer (SysTick)
  181. #if defined(_mk20dx128_) || defined(_mk20dx128vlf5_)
  182. dma_ch0_isr, // 16 DMA channel 0 transfer complete
  183. dma_ch1_isr, // 17 DMA channel 1 transfer complete
  184. dma_ch2_isr, // 18 DMA channel 2 transfer complete
  185. dma_ch3_isr, // 19 DMA channel 3 transfer complete
  186. dma_error_isr, // 20 DMA error interrupt channel
  187. unused_isr, // 21 DMA --
  188. flash_cmd_isr, // 22 Flash Memory Command complete
  189. flash_error_isr, // 23 Flash Read collision
  190. low_voltage_isr, // 24 Low-voltage detect/warning
  191. wakeup_isr, // 25 Low Leakage Wakeup
  192. watchdog_isr, // 26 Both EWM and WDOG interrupt
  193. i2c0_isr, // 27 I2C0
  194. spi0_isr, // 28 SPI0
  195. i2s0_tx_isr, // 29 I2S0 Transmit
  196. i2s0_rx_isr, // 30 I2S0 Receive
  197. uart0_lon_isr, // 31 UART0 CEA709.1-B (LON) status
  198. uart0_status_isr, // 32 UART0 status
  199. uart0_error_isr, // 33 UART0 error
  200. uart1_status_isr, // 34 UART1 status
  201. uart1_error_isr, // 35 UART1 error
  202. uart2_status_isr, // 36 UART2 status
  203. uart2_error_isr, // 37 UART2 error
  204. adc0_isr, // 38 ADC0
  205. cmp0_isr, // 39 CMP0
  206. cmp1_isr, // 40 CMP1
  207. ftm0_isr, // 41 FTM0
  208. ftm1_isr, // 42 FTM1
  209. cmt_isr, // 43 CMT
  210. rtc_alarm_isr, // 44 RTC Alarm interrupt
  211. rtc_seconds_isr, // 45 RTC Seconds interrupt
  212. pit0_isr, // 46 PIT Channel 0
  213. pit1_isr, // 47 PIT Channel 1
  214. pit2_isr, // 48 PIT Channel 2
  215. pit3_isr, // 49 PIT Channel 3
  216. pdb_isr, // 50 PDB Programmable Delay Block
  217. usb_isr, // 51 USB OTG
  218. usb_charge_isr, // 52 USB Charger Detect
  219. tsi0_isr, // 53 TSI0
  220. mcg_isr, // 54 MCG
  221. lptmr_isr, // 55 Low Power Timer
  222. porta_isr, // 56 Pin detect (Port A)
  223. portb_isr, // 57 Pin detect (Port B)
  224. portc_isr, // 58 Pin detect (Port C)
  225. portd_isr, // 59 Pin detect (Port D)
  226. porte_isr, // 60 Pin detect (Port E)
  227. software_isr, // 61 Software interrupt
  228. #elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_)
  229. dma_ch0_isr, // 16 DMA channel 0 transfer complete
  230. dma_ch1_isr, // 17 DMA channel 1 transfer complete
  231. dma_ch2_isr, // 18 DMA channel 2 transfer complete
  232. dma_ch3_isr, // 19 DMA channel 3 transfer complete
  233. dma_ch4_isr, // 20 DMA channel 4 transfer complete
  234. dma_ch5_isr, // 21 DMA channel 5 transfer complete
  235. dma_ch6_isr, // 22 DMA channel 6 transfer complete
  236. dma_ch7_isr, // 23 DMA channel 7 transfer complete
  237. dma_ch8_isr, // 24 DMA channel 8 transfer complete
  238. dma_ch9_isr, // 25 DMA channel 9 transfer complete
  239. dma_ch10_isr, // 26 DMA channel 10 transfer complete
  240. dma_ch11_isr, // 27 DMA channel 10 transfer complete
  241. dma_ch12_isr, // 28 DMA channel 10 transfer complete
  242. dma_ch13_isr, // 29 DMA channel 10 transfer complete
  243. dma_ch14_isr, // 30 DMA channel 10 transfer complete
  244. dma_ch15_isr, // 31 DMA channel 10 transfer complete
  245. dma_error_isr, // 32 DMA error interrupt channel
  246. unused_isr, // 33 --
  247. flash_cmd_isr, // 34 Flash Memory Command complete
  248. flash_error_isr, // 35 Flash Read collision
  249. low_voltage_isr, // 36 Low-voltage detect/warning
  250. wakeup_isr, // 37 Low Leakage Wakeup
  251. watchdog_isr, // 38 Both EWM and WDOG interrupt
  252. unused_isr, // 39 --
  253. i2c0_isr, // 40 I2C0
  254. i2c1_isr, // 41 I2C1
  255. spi0_isr, // 42 SPI0
  256. spi1_isr, // 43 SPI1
  257. unused_isr, // 44 --
  258. can0_message_isr, // 45 CAN OR'ed Message buffer (0-15)
  259. can0_bus_off_isr, // 46 CAN Bus Off
  260. can0_error_isr, // 47 CAN Error
  261. can0_tx_warn_isr, // 48 CAN Transmit Warning
  262. can0_rx_warn_isr, // 49 CAN Receive Warning
  263. can0_wakeup_isr, // 50 CAN Wake Up
  264. i2s0_tx_isr, // 51 I2S0 Transmit
  265. i2s0_rx_isr, // 52 I2S0 Receive
  266. unused_isr, // 53 --
  267. unused_isr, // 54 --
  268. unused_isr, // 55 --
  269. unused_isr, // 56 --
  270. unused_isr, // 57 --
  271. unused_isr, // 58 --
  272. unused_isr, // 59 --
  273. uart0_lon_isr, // 60 UART0 CEA709.1-B (LON) status
  274. uart0_status_isr, // 61 UART0 status
  275. uart0_error_isr, // 62 UART0 error
  276. uart1_status_isr, // 63 UART1 status
  277. uart1_error_isr, // 64 UART1 error
  278. uart2_status_isr, // 65 UART2 status
  279. uart2_error_isr, // 66 UART2 error
  280. unused_isr, // 67 --
  281. unused_isr, // 68 --
  282. unused_isr, // 69 --
  283. unused_isr, // 70 --
  284. unused_isr, // 71 --
  285. unused_isr, // 72 --
  286. adc0_isr, // 73 ADC0
  287. adc1_isr, // 74 ADC1
  288. cmp0_isr, // 75 CMP0
  289. cmp1_isr, // 76 CMP1
  290. cmp2_isr, // 77 CMP2
  291. ftm0_isr, // 78 FTM0
  292. ftm1_isr, // 79 FTM1
  293. ftm2_isr, // 80 FTM2
  294. cmt_isr, // 81 CMT
  295. rtc_alarm_isr, // 82 RTC Alarm interrupt
  296. rtc_seconds_isr, // 83 RTC Seconds interrupt
  297. pit0_isr, // 84 PIT Channel 0
  298. pit1_isr, // 85 PIT Channel 1
  299. pit2_isr, // 86 PIT Channel 2
  300. pit3_isr, // 87 PIT Channel 3
  301. pdb_isr, // 88 PDB Programmable Delay Block
  302. usb_isr, // 89 USB OTG
  303. usb_charge_isr, // 90 USB Charger Detect
  304. unused_isr, // 91 --
  305. unused_isr, // 92 --
  306. unused_isr, // 93 --
  307. unused_isr, // 94 --
  308. unused_isr, // 95 --
  309. unused_isr, // 96 --
  310. dac0_isr, // 97 DAC0
  311. unused_isr, // 98 --
  312. tsi0_isr, // 99 TSI0
  313. mcg_isr, // 100 MCG
  314. lptmr_isr, // 101 Low Power Timer
  315. unused_isr, // 102 --
  316. porta_isr, // 103 Pin detect (Port A)
  317. portb_isr, // 104 Pin detect (Port B)
  318. portc_isr, // 105 Pin detect (Port C)
  319. portd_isr, // 106 Pin detect (Port D)
  320. porte_isr, // 107 Pin detect (Port E)
  321. unused_isr, // 108 --
  322. unused_isr, // 109 --
  323. software_isr, // 110 Software interrupt
  324. #endif
  325. };
  326. // ----- Flash Configuration -----
  327. // Only necessary for Teensy 3s, MCHCK uses the Bootloader to handle this
  328. #if defined(_mk20dx128_) || defined(_mk20dx256_)
  329. __attribute__ ((section(".flashconfig"), used))
  330. const uint8_t flashconfigbytes[16] = {
  331. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  332. 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF
  333. };
  334. #elif defined(_mk20dx128vlf5_) && defined(_bootloader_)
  335. // XXX Byte labels may be in incorrect positions, double check before modifying
  336. // FSEC is in correct location -Jacob
  337. __attribute__ ((section(".flashconfig"), used))
  338. const uint8_t flashconfigbytes[16] = {
  339. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Backdoor Verif Key 28.3.1
  340. //
  341. // Protecting the first 4k of Flash memory from being over-written while running (bootloader protection)
  342. // Still possible to overwrite the bootloader using an external flashing device
  343. // For more details see:
  344. // http://cache.freescale.com/files/training/doc/dwf/AMF_ENT_T1031_Boston.pdf (page 8)
  345. // http://cache.freescale.com/files/microcontrollers/doc/app_note/AN4507.pdf
  346. // http://cache.freescale.com/files/32bit/doc/ref_manual/K20P48M50SF0RM.pdf (28.34.6)
  347. //
  348. 0xFF, 0xFF, 0xFF, 0xFE, // Program Flash Protection Bytes FPROT0-3
  349. 0xBE, // Flash security byte FSEC
  350. 0x03, // Flash nonvolatile option byte FOPT
  351. 0xFF, // EEPROM Protection Byte FEPROT
  352. 0xFF, // Data Flash Protection Byte FDPROT
  353. };
  354. #elif defined(_mk20dx256vlh7_) && defined(_bootloader_)
  355. // XXX Byte labels may be in incorrect positions, double check before modifying
  356. // FSEC is in correct location -Jacob
  357. __attribute__ ((section(".flashconfig"), used))
  358. const uint8_t flashconfigbytes[16] = {
  359. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // Backdoor Verif Key 28.3.1
  360. //
  361. // Protecting the first 8k of Flash memory from being over-written while running (bootloader protection)
  362. // Still possible to overwrite the bootloader using an external flashing device
  363. // For more details see:
  364. // http://cache.freescale.com/files/training/doc/dwf/AMF_ENT_T1031_Boston.pdf (page 8)
  365. // http://cache.freescale.com/files/microcontrollers/doc/app_note/AN4507.pdf
  366. // http://cache.freescale.com/files/32bit/doc/ref_manual/K20P64M72SF1RM.pdf (28.34.6)
  367. //
  368. 0xFF, 0xFF, 0xFF, 0xFF, // Program Flash Protection Bytes FPROT0-3 // XXX TODO PROTECT
  369. 0xBE, // Flash security byte FSEC
  370. 0x03, // Flash nonvolatile option byte FOPT
  371. 0xFF, // EEPROM Protection Byte FEPROT
  372. 0xFF, // Data Flash Protection Byte FDPROT
  373. };
  374. #endif
  375. // ----- Functions -----
  376. #if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section
  377. __attribute__((noreturn))
  378. static inline void jump_to_app( uintptr_t addr )
  379. {
  380. // addr is in r0
  381. __asm__("ldr sp, [%[addr], #0]\n"
  382. "ldr pc, [%[addr], #4]"
  383. :: [addr] "r" (addr));
  384. // NOTREACHED
  385. __builtin_unreachable();
  386. }
  387. #endif
  388. void *memset( void *addr, int val, unsigned int len )
  389. {
  390. char *buf = addr;
  391. for (; len > 0; --len, ++buf)
  392. *buf = val;
  393. return (addr);
  394. }
  395. int memcmp( const void *a, const void *b, unsigned int len )
  396. {
  397. const uint8_t *ap = a, *bp = b;
  398. int val = 0;
  399. for (; len > 0 && (val = *ap - *bp) == 0; --len, ++ap, ++bp)
  400. /* NOTHING */;
  401. return (val);
  402. }
  403. void *memcpy( void *dst, const void *src, unsigned int len )
  404. {
  405. char *dstbuf = dst;
  406. const char *srcbuf = src;
  407. for (; len > 0; --len, ++dstbuf, ++srcbuf)
  408. *dstbuf = *srcbuf;
  409. return (dst);
  410. }
  411. // ----- Chip Entry Point -----
  412. __attribute__ ((section(".startup")))
  413. void ResetHandler()
  414. {
  415. #if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section
  416. extern uint32_t _app_rom;
  417. // We treat _app_rom as pointer to directly read the stack
  418. // pointer and check for valid app code. This is no fool
  419. // proof method, but it should help for the first flash.
  420. //
  421. // Purposefully disabling the watchdog *after* the reset check this way
  422. // if the chip goes into an odd state we'll reset to the bootloader (invalid firmware image)
  423. // RCM_SRS0 & 0x20
  424. //
  425. // Also checking for ARM lock-up signal (invalid firmware image)
  426. // RCM_SRS1 & 0x02
  427. if ( // PIN (External Reset Pin/Switch)
  428. RCM_SRS0 & 0x40
  429. // WDOG (Watchdog timeout)
  430. || RCM_SRS0 & 0x20
  431. // LOCKUP (ARM Core LOCKUP event)
  432. || RCM_SRS1 & 0x02
  433. // Blank flash check
  434. || _app_rom == 0xffffffff
  435. // Software reset
  436. || memcmp( (uint8_t*)&VBAT, sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic) ) == 0
  437. )
  438. {
  439. memset( (uint8_t*)&VBAT, 0, sizeof(VBAT) );
  440. }
  441. else
  442. {
  443. uint32_t addr = (uintptr_t)&_app_rom;
  444. SCB_VTOR = addr; // relocate vector table
  445. jump_to_app( addr );
  446. }
  447. #endif
  448. // Disable Watchdog
  449. WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
  450. WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
  451. WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE;
  452. uint32_t *src = (uint32_t*)&_etext;
  453. uint32_t *dest = (uint32_t*)&_sdata;
  454. // Enable clocks to always-used peripherals
  455. SIM_SCGC5 = 0x00043F82; // Clocks active to all GPIO
  456. SIM_SCGC6 = SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;
  457. #if defined(_mk20dx128_)
  458. SIM_SCGC6 |= SIM_SCGC6_RTC;
  459. #elif defined(_mk20dx256_)
  460. SIM_SCGC3 = SIM_SCGC3_ADC1 | SIM_SCGC3_FTM2;
  461. SIM_SCGC6 |= SIM_SCGC6_RTC;
  462. #endif
  463. #if defined(_mk20dx128_) || defined(_mk20dx256_) // Teensy 3s
  464. // if the RTC oscillator isn't enabled, get it started early
  465. if ( !(RTC_CR & RTC_CR_OSCE) )
  466. {
  467. RTC_SR = 0;
  468. RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
  469. }
  470. #endif
  471. // release I/O pins hold, if we woke up from VLLS mode
  472. if ( PMC_REGSC & PMC_REGSC_ACKISO )
  473. {
  474. PMC_REGSC |= PMC_REGSC_ACKISO;
  475. }
  476. // Prepare RAM
  477. while ( dest < (uint32_t*)&_edata ) *dest++ = *src++;
  478. dest = (uint32_t*)&_sbss;
  479. while ( dest < (uint32_t*)&_ebss ) *dest++ = 0;
  480. // MCHCK / Kiibohd-dfu
  481. #if defined(_mk20dx128vlf5_)
  482. // Default all interrupts to medium priority level
  483. for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ )
  484. {
  485. NVIC_SET_PRIORITY( i, 128 );
  486. }
  487. // FLL at 48MHz
  488. MCG_C4 = MCG_C4_DMX32 | MCG_C4_DRST_DRS( 1 );
  489. // USB Clock and FLL select
  490. SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_TRACECLKSEL;
  491. // Teensy 3.0 and 3.1 and Kiibohd-dfu (mk20dx256vlh7)
  492. #else
  493. SCB_VTOR = 0; // use vector table in flash
  494. // default all interrupts to medium priority level
  495. for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ )
  496. {
  497. NVIC_SET_PRIORITY( i, 128 );
  498. }
  499. // start in FEI mode
  500. // enable capacitors for crystal
  501. OSC0_CR = OSC_SC8P | OSC_SC2P;
  502. // enable osc, 8-32 MHz range, low power mode
  503. MCG_C2 = MCG_C2_RANGE0( 2 ) | MCG_C2_EREFS;
  504. // switch to crystal as clock source, FLL input = 16 MHz / 512
  505. MCG_C1 = MCG_C1_CLKS( 2 ) | MCG_C1_FRDIV( 4 );
  506. // wait for crystal oscillator to begin
  507. while ( (MCG_S & MCG_S_OSCINIT0) == 0 );
  508. // wait for FLL to use oscillator
  509. while ( (MCG_S & MCG_S_IREFST) != 0 );
  510. // wait for MCGOUT to use oscillator
  511. while ( (MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST( 2 ) );
  512. // now we're in FBE mode
  513. // config PLL input for 16 MHz Crystal / 4 = 4 MHz
  514. MCG_C5 = MCG_C5_PRDIV0( 3 );
  515. // config PLL for 96 MHz output
  516. MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0( 0 );
  517. // wait for PLL to start using xtal as its input
  518. while ( !(MCG_S & MCG_S_PLLST) );
  519. // wait for PLL to lock
  520. while ( !(MCG_S & MCG_S_LOCK0) );
  521. // now we're in PBE mode
  522. #if F_CPU == 96000000
  523. // config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash
  524. SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1( 0 ) | SIM_CLKDIV1_OUTDIV2( 1 ) | SIM_CLKDIV1_OUTDIV4( 3 );
  525. #elif F_CPU == 48000000
  526. // config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash
  527. SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1( 1 ) | SIM_CLKDIV1_OUTDIV2( 1 ) | SIM_CLKDIV1_OUTDIV4( 3 );
  528. #elif F_CPU == 24000000
  529. // config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash
  530. SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1( 3 ) | SIM_CLKDIV1_OUTDIV2( 3 ) | SIM_CLKDIV1_OUTDIV4( 3 );
  531. #else
  532. #error "Error, F_CPU must be 96000000, 48000000, or 24000000"
  533. #endif
  534. // switch to PLL as clock source, FLL input = 16 MHz / 512
  535. MCG_C1 = MCG_C1_CLKS( 0 ) | MCG_C1_FRDIV( 4 );
  536. // wait for PLL clock to be used
  537. while ( (MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST( 3 ) );
  538. // now we're in PEE mode
  539. // configure USB for 48 MHz clock
  540. SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV( 1 ); // USB = 96 MHz PLL / 2
  541. // USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0
  542. SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL( 6 );
  543. #endif
  544. #if !defined(_bootloader_)
  545. // Initialize the SysTick counter
  546. SYST_RVR = (F_CPU / 1000) - 1;
  547. SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE;
  548. __enable_irq();
  549. #else
  550. // Disable Watchdog for bootloader
  551. WDOG_STCTRLH &= ~WDOG_STCTRLH_WDOGEN;
  552. #endif
  553. main();
  554. while ( 1 ); // Shouldn't get here...
  555. }
  556. // ----- RAM Setup -----
  557. char *__brkval = (char *)&_ebss;
  558. void * _sbrk( int incr )
  559. {
  560. char *prev = __brkval;
  561. __brkval += incr;
  562. return prev;
  563. }
  564. // ----- Interrupt Execution Priority -----
  565. int nvic_execution_priority()
  566. {
  567. int priority = 256;
  568. uint32_t primask, faultmask, basepri, ipsr;
  569. // full algorithm in ARM DDI0403D, page B1-639
  570. // this isn't quite complete, but hopefully good enough
  571. asm volatile( "mrs %0, faultmask\n" : "=r" (faultmask):: );
  572. if ( faultmask )
  573. {
  574. return -1;
  575. }
  576. asm volatile( "mrs %0, primask\n" : "=r" (primask):: );
  577. if ( primask )
  578. {
  579. return 0;
  580. }
  581. asm volatile( "mrs %0, ipsr\n" : "=r" (ipsr):: );
  582. if ( ipsr )
  583. {
  584. if ( ipsr < 16)
  585. {
  586. priority = 0; // could be non-zero
  587. }
  588. else
  589. {
  590. priority = NVIC_GET_PRIORITY( ipsr - 16 );
  591. }
  592. }
  593. asm volatile( "mrs %0, basepri\n" : "=r" (basepri):: );
  594. if ( basepri > 0 && basepri < priority )
  595. {
  596. priority = basepri;
  597. }
  598. return priority;
  599. }