Teensy 4.1 core updated for C++20
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

336 lines
16KB

  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2017 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. #ifndef _SPIFIFO_h_
  31. #define _SPIFIFO_h_
  32. #include "avr_emulation.h"
  33. #ifdef KINETISK
  34. #if F_BUS == 120000000
  35. #define HAS_SPIFIFO
  36. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(120 / 5) * ((1+1)/2)
  37. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2)) //(120 / 2) * ((1+0)/4) = 15 MHz
  38. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0)) //(120 / 5) * ((1+0)/2)
  39. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(120 / 5) * ((1+1)/6)
  40. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(2)) //(120 / 5) * ((1+0)/4)
  41. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(4)) //(120 / 5) * ((1+0)/6)
  42. #elif F_BUS == 108000000
  43. #define HAS_SPIFIFO
  44. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(108 / 5) * ((1+1)/2) = 21.6 MHz
  45. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2)) //(108 / 2) * ((1+0)/4) = 13.5 MHz
  46. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(108 / 3) * ((1+1)/6)
  47. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(108 / 5) * ((1+1)/6) = 7.2 MHz
  48. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(4)) //(108 / 3) * ((1+0)/6)
  49. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(5) | SPI_CTAR_BR(2)) //(108 / 7) * ((1+0)/4) = 3.86 MHz
  50. #elif F_BUS == 96000000
  51. #define HAS_SPIFIFO
  52. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(96 / 2) * ((1+0)/2)
  53. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(96 / 2) * ((1+1)/6)
  54. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_DBR) //(96 / 2) * ((1+1)/8)
  55. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(2)) //(96 / 3) * ((1+0)/4)
  56. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(6)) //(96 / 2) * ((1+0)/8)
  57. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(6)) //(96 / 3) * ((1+0)/8)
  58. #elif F_BUS == 90000000
  59. #define HAS_SPIFIFO
  60. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(90 / 2) * ((1+0)/2) = 22.5 MHz
  61. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(90 / 2) * ((1+1)/6) = 15 MHz
  62. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_DBR) //(90 / 2) * ((1+1)/8) = 11.25 MHz
  63. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4)) //(90 / 2) * ((1+0)/6) = 7.5 MHz
  64. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(90 / 5) * ((1+1)/6)
  65. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(6)) //(90 / 3) * ((1+0)/8) = 3.75 MHz
  66. #elif F_BUS == 80000000
  67. #define HAS_SPIFIFO
  68. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(80 / 2) * ((1+0)/2) = 20 MHz
  69. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(80 / 5) * ((1+1)/2)
  70. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(5) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(80 / 7) * ((1+1)/2) = 11.42 MHz
  71. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0)) //(80 / 5) * ((1+0)/2)
  72. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(5) | SPI_CTAR_BR(0)) //(80 / 7) * ((1+0)/2) = 5.7 MHz
  73. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(2)) //(80 / 5) * ((1+0)/4)
  74. #elif F_BUS == 72000000
  75. #define HAS_SPIFIFO
  76. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(72 / 3) * ((1+1)/2)
  77. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(72 / 2) * ((1+1)/6) = 12 MHz
  78. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(72 / 2) * ((1+1)/6)
  79. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(72 / 3) * ((1+1)/6)
  80. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4)) //(72 / 2) * ((1+0)/6)
  81. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(4)) //(72 / 3) * ((1+0)/6)
  82. #elif F_BUS == 64000000
  83. #define HAS_SPIFIFO
  84. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(64 / 3) * ((1+1)/2) = 21.3 MHz
  85. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(64 / 2) * ((1+0)/2)
  86. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0)) //(64 / 3) * ((1+0)/2) = 10.67 MHz
  87. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2)) //(64 / 2) * ((1+0)/4)
  88. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4)) //(64 / 2) * ((1+0)/6) = 5.3 MHz
  89. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(6)) //(64 / 2) * ((1+0)/8)
  90. #elif F_BUS == 60000000
  91. #define HAS_SPIFIFO
  92. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(60 / 3) * ((1+1)/2) = 20 MHz
  93. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(60 / 2) * ((1+0)/2) = 15 MHz
  94. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(60 / 5) * ((1+1)/2)
  95. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1)) //(60 / 2) * ((1+0)/4) = 7.5 MHz
  96. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0)) //(60 / 5) * ((1+0)/2)
  97. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(60 / 5) * ((1+1)/6)
  98. #elif F_BUS == 56000000
  99. #define HAS_SPIFIFO
  100. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(56 / 3) * ((1+1)/2) = 18.67
  101. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(56 / 2) * ((1+0)/2) = 14
  102. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(56 / 5) * ((1+1)/2) = 11.2
  103. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(56 / 7) * ((1+1)/2)
  104. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0)) //(56 / 5) * ((1+0)/2)
  105. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0)) //(56 / 7) * ((1+0)/2)
  106. #elif F_BUS == 48000000
  107. #define HAS_SPIFIFO
  108. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(48 / 2) * ((1+1)/2)
  109. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(48 / 3) * ((1+1)/2)
  110. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(48 / 2) * ((1+0)/2)
  111. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(48 / 2) * ((1+1)/6)
  112. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1)) //(48 / 2) * ((1+0)/4)
  113. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2)) //(48 / 2) * ((1+0)/6)
  114. #elif F_BUS == 40000000
  115. #define HAS_SPIFIFO
  116. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(40 / 2) * ((1+1)/2) = 20
  117. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(40 / 3) * ((1+1)/2) = 13.33
  118. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(40 / 2) * ((1+0)/2) = 10
  119. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(40 / 5) * ((1+1)/2)
  120. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(40 / 7) * ((1+1)/2) = 5.71
  121. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(1)) //(40 / 5) * ((1+0)/2)
  122. #elif F_BUS == 36000000
  123. #define HAS_SPIFIFO
  124. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(36 / 2) * ((1+1)/2) = 18
  125. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(36 / 3) * ((1+1)/2) = 12
  126. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(36 / 3) * ((1+1)/2) = 12
  127. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(36 / 5) * ((1+1)/2) = 7.2
  128. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(36 / 2) * ((1+1)/6)
  129. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(36 / 3) * ((1+1)/6)
  130. #elif F_BUS == 24000000
  131. #define HAS_SPIFIFO
  132. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/2) 12 MHz
  133. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/2) 12 MHz
  134. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/2)
  135. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(24 / 3) * ((1+1)/2)
  136. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(24 / 2) * ((1+0)/2)
  137. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/6)
  138. #elif F_BUS == 16000000
  139. #define HAS_SPIFIFO
  140. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
  141. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
  142. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
  143. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
  144. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
  145. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
  146. #elif F_BUS == 8000000
  147. #define HAS_SPIFIFO
  148. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
  149. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
  150. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
  151. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
  152. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
  153. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
  154. #elif F_BUS == 4000000
  155. #define HAS_SPIFIFO
  156. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
  157. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
  158. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
  159. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
  160. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
  161. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
  162. #elif F_BUS == 2000000
  163. #define HAS_SPIFIFO
  164. #define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
  165. #define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
  166. #define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
  167. #define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
  168. #define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
  169. #define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
  170. #endif // F_BUS
  171. #endif // KINETISK
  172. /*
  173. #! /usr/bin/perl
  174. $clock = 60;
  175. for $i (2, 3, 5, 7) {
  176. for $j (0, 1) {
  177. for $k (2, 4, 6, 8, 16, 32) {
  178. $out = $clock / $i * (1 + $j) / $k;
  179. printf "%0.2f : ", $out;
  180. print "$clock / $i * (1 + $j) / $k = $out\n";
  181. }
  182. }
  183. }
  184. */
  185. // sck = F_BUS / PBR * ((1+DBR)/BR)
  186. // PBR = 2, 3, 5, 7
  187. // DBR = 0, 1 -- zero preferred
  188. // BR = 2, 4, 6, 8, 16, 32, 64, 128, 256, 512
  189. #ifdef HAS_SPIFIFO
  190. #ifndef SPI_MODE0
  191. #define SPI_MODE0 0x00 // CPOL = 0, CPHA = 0
  192. #define SPI_MODE1 0x04 // CPOL = 0, CPHA = 1
  193. #define SPI_MODE2 0x08 // CPOL = 1, CPHA = 0
  194. #define SPI_MODE3 0x0C // CPOL = 1, CPHA = 1
  195. #endif
  196. #define SPI_CONTINUE 1
  197. class SPIFIFOclass
  198. {
  199. public:
  200. inline void begin(uint8_t pin, uint32_t speed, uint32_t mode=SPI_MODE0) __attribute__((always_inline)) {
  201. uint32_t p, ctar = speed;
  202. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  203. KINETISK_SPI0.MCR = SPI_MCR_MSTR | SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  204. if (mode & 0x08) ctar |= SPI_CTAR_CPOL;
  205. if (mode & 0x04) {
  206. ctar |= SPI_CTAR_CPHA;
  207. ctar |= (ctar & 0x0F) << 8;
  208. } else {
  209. ctar |= (ctar & 0x0F) << 12;
  210. }
  211. KINETISK_SPI0.CTAR0 = ctar | SPI_CTAR_FMSZ(7);
  212. KINETISK_SPI0.CTAR1 = ctar | SPI_CTAR_FMSZ(15);
  213. if (pin == 10) { // PTC4
  214. CORE_PIN10_CONFIG = PORT_PCR_MUX(2);
  215. p = 0x01;
  216. } else if (pin == 2) { // PTD0
  217. CORE_PIN2_CONFIG = PORT_PCR_MUX(2);
  218. p = 0x01;
  219. } else if (pin == 9) { // PTC3
  220. CORE_PIN9_CONFIG = PORT_PCR_MUX(2);
  221. p = 0x02;
  222. } else if (pin == 6) { // PTD4
  223. CORE_PIN6_CONFIG = PORT_PCR_MUX(2);
  224. p = 0x02;
  225. } else if (pin == 20) { // PTD5
  226. CORE_PIN20_CONFIG = PORT_PCR_MUX(2);
  227. p = 0x04;
  228. } else if (pin == 23) { // PTC2
  229. CORE_PIN23_CONFIG = PORT_PCR_MUX(2);
  230. p = 0x04;
  231. } else if (pin == 21) { // PTD6
  232. CORE_PIN21_CONFIG = PORT_PCR_MUX(2);
  233. p = 0x08;
  234. } else if (pin == 22) { // PTC1
  235. CORE_PIN22_CONFIG = PORT_PCR_MUX(2);
  236. p = 0x08;
  237. } else if (pin == 15) { // PTC0
  238. CORE_PIN15_CONFIG = PORT_PCR_MUX(2);
  239. p = 0x10;
  240. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  241. } else if (pin == 26) {
  242. CORE_PIN26_CONFIG = PORT_PCR_MUX(2);
  243. p = 0x01;
  244. #endif
  245. } else {
  246. reg = portOutputRegister(pin);
  247. pinMode(pin, OUTPUT);
  248. *reg = 1;
  249. p = 0;
  250. }
  251. pcs = p;
  252. clear();
  253. SPCR.enable_pins();
  254. }
  255. inline void write(uint32_t b, uint32_t cont=0) __attribute__((always_inline)) {
  256. uint32_t pcsbits = pcs << 16;
  257. if (pcsbits) {
  258. KINETISK_SPI0.PUSHR = (b & 0xFF) | pcsbits | (cont ? SPI_PUSHR_CONT : 0);
  259. while (((KINETISK_SPI0.SR) & (15 << 12)) > (3 << 12)) ; // wait if FIFO full
  260. } else {
  261. *reg = 0;
  262. KINETISK_SPI0.SR = SPI_SR_EOQF;
  263. KINETISK_SPI0.PUSHR = (b & 0xFF) | (cont ? 0 : SPI_PUSHR_EOQ);
  264. if (cont) {
  265. while (((KINETISK_SPI0.SR) & (15 << 12)) > (3 << 12)) ;
  266. } else {
  267. while (!(KINETISK_SPI0.SR & SPI_SR_EOQF)) ;
  268. *reg = 1;
  269. }
  270. }
  271. }
  272. inline void write16(uint32_t b, uint32_t cont=0) __attribute__((always_inline)) {
  273. uint32_t pcsbits = pcs << 16;
  274. if (pcsbits) {
  275. KINETISK_SPI0.PUSHR = (b & 0xFFFF) | (pcs << 16) |
  276. (cont ? SPI_PUSHR_CONT : 0) | SPI_PUSHR_CTAS(1);
  277. while (((KINETISK_SPI0.SR) & (15 << 12)) > (3 << 12)) ;
  278. } else {
  279. *reg = 0;
  280. KINETISK_SPI0.SR = SPI_SR_EOQF;
  281. KINETISK_SPI0.PUSHR = (b & 0xFFFF) | (cont ? 0 : SPI_PUSHR_EOQ) | SPI_PUSHR_CTAS(1);
  282. if (cont) {
  283. while (((KINETISK_SPI0.SR) & (15 << 12)) > (3 << 12)) ;
  284. } else {
  285. while (!(KINETISK_SPI0.SR & SPI_SR_EOQF)) ;
  286. *reg = 1;
  287. }
  288. }
  289. }
  290. inline uint32_t read(void) __attribute__((always_inline)) {
  291. while ((KINETISK_SPI0.SR & (15 << 4)) == 0) ; // TODO, could wait forever
  292. return KINETISK_SPI0.POPR;
  293. }
  294. inline void clear(void) __attribute__((always_inline)) {
  295. KINETISK_SPI0.MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F) | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF;
  296. }
  297. private:
  298. static uint8_t pcs;
  299. static volatile uint8_t *reg;
  300. };
  301. extern SPIFIFOclass SPIFIFO;
  302. #endif // HAS_SPIFIFO
  303. #endif