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 година
пре 8 година
пре 11 година
пре 11 година
пре 11 година
пре 10 година
пре 11 година
пре 11 година
пре 8 година
пре 11 година
пре 9 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 11 година
пре 10 година
пре 11 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  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