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.

406 lines
11KB

  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 "kinetis.h"
  31. #include "core_pins.h"
  32. #include "HardwareSerial.h"
  33. ////////////////////////////////////////////////////////////////
  34. // Tunable parameters (relatively safe to edit these numbers)
  35. ////////////////////////////////////////////////////////////////
  36. #define TX_BUFFER_SIZE 40
  37. #define RX_BUFFER_SIZE 64
  38. #define IRQ_PRIORITY 64 // 0 = highest priority, 255 = lowest
  39. ////////////////////////////////////////////////////////////////
  40. // changes not recommended below this point....
  41. ////////////////////////////////////////////////////////////////
  42. #ifdef SERIAL_9BIT_SUPPORT
  43. static uint8_t use9Bits = 0;
  44. #define BUFTYPE uint16_t
  45. #else
  46. #define BUFTYPE uint8_t
  47. #define use9Bits 0
  48. #endif
  49. static volatile BUFTYPE tx_buffer[TX_BUFFER_SIZE];
  50. static volatile BUFTYPE rx_buffer[RX_BUFFER_SIZE];
  51. static volatile uint8_t transmitting = 0;
  52. static volatile uint8_t *transmit_pin=NULL;
  53. #if TX_BUFFER_SIZE > 255
  54. static volatile uint16_t tx_buffer_head = 0;
  55. static volatile uint16_t tx_buffer_tail = 0;
  56. #else
  57. static volatile uint8_t tx_buffer_head = 0;
  58. static volatile uint8_t tx_buffer_tail = 0;
  59. #endif
  60. #if RX_BUFFER_SIZE > 255
  61. static volatile uint16_t rx_buffer_head = 0;
  62. static volatile uint16_t rx_buffer_tail = 0;
  63. #else
  64. static volatile uint8_t rx_buffer_head = 0;
  65. static volatile uint8_t rx_buffer_tail = 0;
  66. #endif
  67. // UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS
  68. // UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer
  69. #ifdef KINETISK_UART1_FIFO
  70. #define C2_ENABLE UART_C2_TE | UART_C2_RE | UART_C2_RIE | UART_C2_ILIE
  71. #else
  72. #define C2_ENABLE UART_C2_TE | UART_C2_RE | UART_C2_RIE
  73. #endif
  74. #define C2_TX_ACTIVE C2_ENABLE | UART_C2_TIE
  75. #define C2_TX_COMPLETING C2_ENABLE | UART_C2_TCIE
  76. #define C2_TX_INACTIVE C2_ENABLE
  77. void serial2_begin(uint32_t divisor)
  78. {
  79. SIM_SCGC4 |= SIM_SCGC4_UART1; // turn on clock, TODO: use bitband
  80. rx_buffer_head = 0;
  81. rx_buffer_tail = 0;
  82. tx_buffer_head = 0;
  83. tx_buffer_tail = 0;
  84. transmitting = 0;
  85. CORE_PIN9_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3);
  86. CORE_PIN10_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3);
  87. #if defined(KINETISK_UART1)
  88. UART1_BDH = (divisor >> 13) & 0x1F;
  89. UART1_BDL = (divisor >> 5) & 0xFF;
  90. UART1_C4 = divisor & 0x1F;
  91. #ifdef KINETISK_UART1_FIFO
  92. UART1_C1 = UART_C1_ILT;
  93. UART1_TWFIFO = 2; // tx watermark, causes S1_TDRE to set
  94. UART1_RWFIFO = 4; // rx watermark, causes S1_RDRF to set
  95. UART1_PFIFO = UART_PFIFO_TXFE | UART_PFIFO_RXFE;
  96. #else
  97. UART1_C1 = 0;
  98. UART1_PFIFO = 0;
  99. #endif
  100. #elif defined(KINETISL_UART1)
  101. UART1_BDH = (divisor >> 8) & 0x1F;
  102. UART1_BDL = divisor & 0xFF;
  103. UART1_C1 = 0;
  104. #endif
  105. UART1_C2 = C2_TX_INACTIVE;
  106. NVIC_SET_PRIORITY(IRQ_UART1_STATUS, IRQ_PRIORITY);
  107. NVIC_ENABLE_IRQ(IRQ_UART1_STATUS);
  108. }
  109. void serial2_format(uint32_t format)
  110. {
  111. uint8_t c;
  112. c = UART1_C1;
  113. c = (c & ~0x13) | (format & 0x03); // configure parity
  114. if (format & 0x04) c |= 0x10; // 9 bits (might include parity)
  115. UART1_C1 = c;
  116. if ((format & 0x0F) == 0x04) UART1_C3 |= 0x40; // 8N2 is 9 bit with 9th bit always 1
  117. c = UART1_S2 & ~0x10;
  118. if (format & 0x10) c |= 0x10; // rx invert
  119. UART1_S2 = c;
  120. c = UART1_C3 & ~0x10;
  121. if (format & 0x20) c |= 0x10; // tx invert
  122. UART1_C3 = c;
  123. #ifdef SERIAL_9BIT_SUPPORT
  124. c = UART1_C4 & 0x1F;
  125. if (format & 0x08) c |= 0x20; // 9 bit mode with parity (requires 10 bits)
  126. UART1_C4 = c;
  127. use9Bits = format & 0x80;
  128. #endif
  129. // UART1_C1.0 = parity, 0=even, 1=odd
  130. // UART1_C1.1 = parity, 0=disable, 1=enable
  131. // UART1_C1.4 = mode, 1=9bit, 0=8bit
  132. // UART1_C4.5 = mode, 1=10bit, 0=8bit
  133. // UART1_C3.4 = txinv, 0=normal, 1=inverted
  134. // UART1_S2.4 = rxinv, 0=normal, 1=inverted
  135. }
  136. void serial2_end(void)
  137. {
  138. if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return;
  139. while (transmitting) yield(); // wait for buffered data to send
  140. NVIC_DISABLE_IRQ(IRQ_UART1_STATUS);
  141. UART1_C2 = 0;
  142. CORE_PIN9_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
  143. CORE_PIN10_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
  144. rx_buffer_head = 0;
  145. rx_buffer_tail = 0;
  146. }
  147. void serial2_set_transmit_pin(uint8_t pin)
  148. {
  149. while (transmitting) ;
  150. pinMode(pin, OUTPUT);
  151. digitalWrite(pin, LOW);
  152. transmit_pin = portOutputRegister(pin);
  153. }
  154. void serial2_putchar(uint32_t c)
  155. {
  156. uint32_t head, n;
  157. if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return;
  158. if (transmit_pin) *transmit_pin = 1;
  159. head = tx_buffer_head;
  160. if (++head >= TX_BUFFER_SIZE) head = 0;
  161. while (tx_buffer_tail == head) {
  162. int priority = nvic_execution_priority();
  163. if (priority <= IRQ_PRIORITY) {
  164. if ((UART1_S1 & UART_S1_TDRE)) {
  165. uint32_t tail = tx_buffer_tail;
  166. if (++tail >= TX_BUFFER_SIZE) tail = 0;
  167. n = tx_buffer[tail];
  168. if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2);
  169. UART1_D = n;
  170. tx_buffer_tail = tail;
  171. }
  172. } else if (priority >= 256) {
  173. yield(); // wait
  174. }
  175. }
  176. tx_buffer[head] = c;
  177. transmitting = 1;
  178. tx_buffer_head = head;
  179. UART1_C2 = C2_TX_ACTIVE;
  180. }
  181. #ifdef KINETISK_UART1_FIFO
  182. void serial2_write(const void *buf, unsigned int count)
  183. {
  184. const uint8_t *p = (const uint8_t *)buf;
  185. const uint8_t *end = p + count;
  186. uint32_t head, n;
  187. if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return;
  188. if (transmit_pin) *transmit_pin = 1;
  189. while (p < end) {
  190. head = tx_buffer_head;
  191. if (++head >= TX_BUFFER_SIZE) head = 0;
  192. if (tx_buffer_tail == head) {
  193. UART1_C2 = C2_TX_ACTIVE;
  194. do {
  195. int priority = nvic_execution_priority();
  196. if (priority <= IRQ_PRIORITY) {
  197. if ((UART1_S1 & UART_S1_TDRE)) {
  198. uint32_t tail = tx_buffer_tail;
  199. if (++tail >= TX_BUFFER_SIZE) tail = 0;
  200. n = tx_buffer[tail];
  201. if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2);
  202. UART1_D = n;
  203. tx_buffer_tail = tail;
  204. }
  205. } else if (priority >= 256) {
  206. yield();
  207. }
  208. } while (tx_buffer_tail == head);
  209. }
  210. tx_buffer[head] = *p++;
  211. transmitting = 1;
  212. tx_buffer_head = head;
  213. }
  214. UART1_C2 = C2_TX_ACTIVE;
  215. }
  216. #else
  217. void serial2_write(const void *buf, unsigned int count)
  218. {
  219. const uint8_t *p = (const uint8_t *)buf;
  220. while (count-- > 0) serial2_putchar(*p++);
  221. }
  222. #endif
  223. void serial2_flush(void)
  224. {
  225. while (transmitting) yield(); // wait
  226. }
  227. int serial2_write_buffer_free(void)
  228. {
  229. uint32_t head, tail;
  230. head = tx_buffer_head;
  231. tail = tx_buffer_tail;
  232. if (head >= tail) return TX_BUFFER_SIZE - 1 - head + tail;
  233. return tail - head - 1;
  234. }
  235. int serial2_available(void)
  236. {
  237. uint32_t head, tail;
  238. head = rx_buffer_head;
  239. tail = rx_buffer_tail;
  240. if (head >= tail) return head - tail;
  241. return RX_BUFFER_SIZE + head - tail;
  242. }
  243. int serial2_getchar(void)
  244. {
  245. uint32_t head, tail;
  246. int c;
  247. head = rx_buffer_head;
  248. tail = rx_buffer_tail;
  249. if (head == tail) return -1;
  250. if (++tail >= RX_BUFFER_SIZE) tail = 0;
  251. c = rx_buffer[tail];
  252. rx_buffer_tail = tail;
  253. return c;
  254. }
  255. int serial2_peek(void)
  256. {
  257. uint32_t head, tail;
  258. head = rx_buffer_head;
  259. tail = rx_buffer_tail;
  260. if (head == tail) return -1;
  261. if (++tail >= RX_BUFFER_SIZE) tail = 0;
  262. return rx_buffer[tail];
  263. }
  264. void serial2_clear(void)
  265. {
  266. #ifdef KINETISK_UART1_FIFO
  267. if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return;
  268. UART1_C2 &= ~(UART_C2_RE | UART_C2_RIE | UART_C2_ILIE);
  269. UART1_CFIFO = UART_CFIFO_RXFLUSH;
  270. UART1_C2 |= (UART_C2_RE | UART_C2_RIE | UART_C2_ILIE);
  271. #endif
  272. rx_buffer_head = rx_buffer_tail;
  273. }
  274. // status interrupt combines
  275. // Transmit data below watermark UART_S1_TDRE
  276. // Transmit complete UART_S1_TC
  277. // Idle line UART_S1_IDLE
  278. // Receive data above watermark UART_S1_RDRF
  279. // LIN break detect UART_S2_LBKDIF
  280. // RxD pin active edge UART_S2_RXEDGIF
  281. void uart1_status_isr(void)
  282. {
  283. uint32_t head, tail, n;
  284. uint8_t c;
  285. #ifdef KINETISK_UART1_FIFO
  286. uint32_t newhead;
  287. uint8_t avail;
  288. if (UART1_S1 & (UART_S1_RDRF | UART_S1_IDLE)) {
  289. __disable_irq();
  290. avail = UART1_RCFIFO;
  291. if (avail == 0) {
  292. // The only way to clear the IDLE interrupt flag is
  293. // to read the data register. But reading with no
  294. // data causes a FIFO underrun, which causes the
  295. // FIFO to return corrupted data. If anyone from
  296. // Freescale reads this, what a poor design! There
  297. // write should be a write-1-to-clear for IDLE.
  298. c = UART1_D;
  299. // flushing the fifo recovers from the underrun,
  300. // but there's a possible race condition where a
  301. // new character could be received between reading
  302. // RCFIFO == 0 and flushing the FIFO. To minimize
  303. // the chance, interrupts are disabled so a higher
  304. // priority interrupt (hopefully) doesn't delay.
  305. // TODO: change this to disabling the IDLE interrupt
  306. // which won't be simple, since we already manage
  307. // which transmit interrupts are enabled.
  308. UART1_CFIFO = UART_CFIFO_RXFLUSH;
  309. __enable_irq();
  310. } else {
  311. __enable_irq();
  312. head = rx_buffer_head;
  313. tail = rx_buffer_tail;
  314. do {
  315. n = UART1_D;
  316. if (use9Bits && (UART1_C3 & 0x80)) n |= 0x100;
  317. newhead = head + 1;
  318. if (newhead >= RX_BUFFER_SIZE) newhead = 0;
  319. if (newhead != tail) {
  320. head = newhead;
  321. rx_buffer[head] = n;
  322. }
  323. } while (--avail > 0);
  324. rx_buffer_head = head;
  325. }
  326. }
  327. c = UART1_C2;
  328. if ((c & UART_C2_TIE) && (UART1_S1 & UART_S1_TDRE)) {
  329. head = tx_buffer_head;
  330. tail = tx_buffer_tail;
  331. do {
  332. if (tail == head) break;
  333. if (++tail >= TX_BUFFER_SIZE) tail = 0;
  334. avail = UART1_S1;
  335. n = tx_buffer[tail];
  336. if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2);
  337. UART1_D = n;
  338. } while (UART1_TCFIFO < 8);
  339. tx_buffer_tail = tail;
  340. if (UART1_S1 & UART_S1_TDRE) UART1_C2 = C2_TX_COMPLETING;
  341. }
  342. #else
  343. if (UART1_S1 & UART_S1_RDRF) {
  344. n = UART1_D;
  345. if (use9Bits && (UART1_C3 & 0x80)) n |= 0x100;
  346. head = rx_buffer_head + 1;
  347. if (head >= RX_BUFFER_SIZE) head = 0;
  348. if (head != rx_buffer_tail) {
  349. rx_buffer[head] = n;
  350. rx_buffer_head = head;
  351. }
  352. }
  353. c = UART1_C2;
  354. if ((c & UART_C2_TIE) && (UART1_S1 & UART_S1_TDRE)) {
  355. head = tx_buffer_head;
  356. tail = tx_buffer_tail;
  357. if (head == tail) {
  358. UART1_C2 = C2_TX_COMPLETING;
  359. } else {
  360. if (++tail >= TX_BUFFER_SIZE) tail = 0;
  361. n = tx_buffer[tail];
  362. if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2);
  363. UART1_D = n;
  364. tx_buffer_tail = tail;
  365. }
  366. }
  367. #endif
  368. if ((c & UART_C2_TCIE) && (UART1_S1 & UART_S1_TC)) {
  369. transmitting = 0;
  370. if (transmit_pin) *transmit_pin = 0;
  371. UART1_C2 = C2_TX_INACTIVE;
  372. }
  373. }