Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

317 lines
9.1KB

  1. /* Arduino SdSpi Library
  2. * Copyright (C) 2013 by William Greiman
  3. *
  4. * This file is part of the Arduino SdSpi Library
  5. *
  6. * This Library is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This Library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the Arduino SdSpi Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #include "SdSpi.h"
  21. #if defined(__arm__) && defined(CORE_TEENSY)
  22. // SPI definitions
  23. #include "kinetis.h"
  24. #ifdef KINETISK
  25. // use 16-bit frame if SPI_USE_8BIT_FRAME is zero
  26. #define SPI_USE_8BIT_FRAME 0
  27. // Limit initial fifo to three entries to avoid fifo overrun
  28. #define SPI_INITIAL_FIFO_DEPTH 3
  29. // define some symbols that are not in mk20dx128.h
  30. #ifndef SPI_SR_RXCTR
  31. #define SPI_SR_RXCTR 0XF0
  32. #endif // SPI_SR_RXCTR
  33. #ifndef SPI_PUSHR_CONT
  34. #define SPI_PUSHR_CONT 0X80000000
  35. #endif // SPI_PUSHR_CONT
  36. #ifndef SPI_PUSHR_CTAS
  37. #define SPI_PUSHR_CTAS(n) (((n) & 7) << 28)
  38. #endif // SPI_PUSHR_CTAS
  39. //------------------------------------------------------------------------------
  40. /**
  41. * initialize SPI pins
  42. */
  43. void SdSpi::begin(uint8_t chipSelectPin) {
  44. pinMode(chipSelectPin, OUTPUT);
  45. digitalWrite(chipSelectPin, HIGH);
  46. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  47. }
  48. //------------------------------------------------------------------------------
  49. /**
  50. * Initialize hardware SPI
  51. *
  52. */
  53. void SdSpi::beginTransaction(uint8_t sckDivisor) {
  54. uint32_t ctar, ctar0, ctar1;
  55. #if ENABLE_SPI_TRANSACTIONS
  56. SPI.beginTransaction(SPISettings());
  57. #endif // #if ENABLE_SPI_TRANSACTIONS
  58. if (sckDivisor <= 2) {
  59. // 1/2 speed
  60. ctar = SPI_CTAR_DBR | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0);
  61. } else if (sckDivisor <= 4) {
  62. // 1/4 speed
  63. ctar = SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0);
  64. } else if (sckDivisor <= 8) {
  65. // 1/8 speed
  66. ctar = SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  67. } else if (sckDivisor <= 12) {
  68. // 1/12 speed
  69. ctar = SPI_CTAR_BR(2) | SPI_CTAR_CSSCK(2);
  70. } else if (sckDivisor <= 16) {
  71. // 1/16 speed
  72. ctar = SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(3);
  73. } else if (sckDivisor <= 32) {
  74. // 1/32 speed
  75. ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4);
  76. } else if (sckDivisor <= 64) {
  77. // 1/64 speed
  78. ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5);
  79. } else {
  80. // 1/128 speed
  81. ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6);
  82. }
  83. // CTAR0 - 8 bit transfer
  84. ctar0 = ctar | SPI_CTAR_FMSZ(7);
  85. // CTAR1 - 16 bit transfer
  86. ctar1 = ctar | SPI_CTAR_FMSZ(15);
  87. if (SPI0_CTAR0 != ctar0 || SPI0_CTAR1 != ctar1) {
  88. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  89. SPI0_CTAR0 = ctar0;
  90. SPI0_CTAR1 = ctar1;
  91. }
  92. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  93. CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  94. CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
  95. CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  96. }
  97. //------------------------------------------------------------------------------
  98. /** SPI receive a byte */
  99. uint8_t SdSpi::receive() {
  100. SPI0_MCR |= SPI_MCR_CLR_RXF;
  101. SPI0_SR = SPI_SR_TCF;
  102. SPI0_PUSHR = 0xFF;
  103. while (!(SPI0_SR & SPI_SR_TCF)) {}
  104. return SPI0_POPR;
  105. }
  106. //------------------------------------------------------------------------------
  107. /** SPI receive multiple bytes */
  108. uint8_t SdSpi::receive(uint8_t* buf, size_t n) {
  109. // clear any data in RX FIFO
  110. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  111. #if SPI_USE_8BIT_FRAME
  112. // initial number of bytes to push into TX FIFO
  113. int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH;
  114. for (int i = 0; i < nf; i++) {
  115. SPI0_PUSHR = 0XFF;
  116. }
  117. // limit for pushing dummy data into TX FIFO
  118. uint8_t* limit = buf + n - nf;
  119. while (buf < limit) {
  120. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  121. SPI0_PUSHR = 0XFF;
  122. *buf++ = SPI0_POPR;
  123. }
  124. // limit for rest of RX data
  125. limit += nf;
  126. while (buf < limit) {
  127. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  128. *buf++ = SPI0_POPR;
  129. }
  130. #else // SPI_USE_8BIT_FRAME
  131. // use 16 bit frame to avoid TD delay between frames
  132. // get one byte if n is odd
  133. if (n & 1) {
  134. *buf++ = receive();
  135. n--;
  136. }
  137. // initial number of words to push into TX FIFO
  138. int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH;
  139. for (int i = 0; i < nf; i++) {
  140. SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF;
  141. }
  142. uint8_t* limit = buf + n - 2*nf;
  143. while (buf < limit) {
  144. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  145. SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF;
  146. uint16_t w = SPI0_POPR;
  147. *buf++ = w >> 8;
  148. *buf++ = w & 0XFF;
  149. }
  150. // limit for rest of RX data
  151. limit += 2*nf;
  152. while (buf < limit) {
  153. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  154. uint16_t w = SPI0_POPR;
  155. *buf++ = w >> 8;
  156. *buf++ = w & 0XFF;
  157. }
  158. #endif // SPI_USE_8BIT_FRAME
  159. return 0;
  160. }
  161. //------------------------------------------------------------------------------
  162. /** SPI send a byte */
  163. void SdSpi::send(uint8_t b) {
  164. SPI0_MCR |= SPI_MCR_CLR_RXF;
  165. SPI0_SR = SPI_SR_TCF;
  166. SPI0_PUSHR = b;
  167. while (!(SPI0_SR & SPI_SR_TCF)) {}
  168. }
  169. //------------------------------------------------------------------------------
  170. /** SPI send multiple bytes */
  171. void SdSpi::send(const uint8_t* buf , size_t n) {
  172. // clear any data in RX FIFO
  173. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  174. #if SPI_USE_8BIT_FRAME
  175. // initial number of bytes to push into TX FIFO
  176. int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH;
  177. // limit for pushing data into TX fifo
  178. const uint8_t* limit = buf + n;
  179. for (int i = 0; i < nf; i++) {
  180. SPI0_PUSHR = *buf++;
  181. }
  182. // write data to TX FIFO
  183. while (buf < limit) {
  184. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  185. SPI0_PUSHR = *buf++;
  186. SPI0_POPR;
  187. }
  188. // wait for data to be sent
  189. while (nf) {
  190. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  191. SPI0_POPR;
  192. nf--;
  193. }
  194. #else // SPI_USE_8BIT_FRAME
  195. // use 16 bit frame to avoid TD delay between frames
  196. // send one byte if n is odd
  197. if (n & 1) {
  198. send(*buf++);
  199. n--;
  200. }
  201. // initial number of words to push into TX FIFO
  202. int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH;
  203. // limit for pushing data into TX fifo
  204. const uint8_t* limit = buf + n;
  205. for (int i = 0; i < nf; i++) {
  206. uint16_t w = (*buf++) << 8;
  207. w |= *buf++;
  208. SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w;
  209. }
  210. // write data to TX FIFO
  211. while (buf < limit) {
  212. uint16_t w = *buf++ << 8;
  213. w |= *buf++;
  214. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  215. SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w;
  216. SPI0_POPR;
  217. }
  218. // wait for data to be sent
  219. while (nf) {
  220. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  221. SPI0_POPR;
  222. nf--;
  223. }
  224. #endif // SPI_USE_8BIT_FRAME
  225. }
  226. #else // KINETISK
  227. //==============================================================================
  228. // Use standard SPI library if not KINETISK
  229. /**
  230. * Initialize SPI pins.
  231. */
  232. void SdSpi::begin(uint8_t chipSelectPin) {
  233. pinMode(chipSelectPin, OUTPUT);
  234. digitalWrite(chipSelectPin, HIGH);
  235. SPI.begin();
  236. }
  237. /** Set SPI options for access to SD/SDHC cards.
  238. *
  239. * \param[in] divisor SCK clock divider relative to the system clock.
  240. */
  241. void SdSpi::beginTransaction(uint8_t divisor) {
  242. #if ENABLE_SPI_TRANSACTIONS
  243. SPI.beginTransaction(SPISettings());
  244. #else // #if ENABLE_SPI_TRANSACTIONS
  245. SPI.setBitOrder(MSBFIRST);
  246. SPI.setDataMode(SPI_MODE0);
  247. #endif // #if ENABLE_SPI_TRANSACTIONS
  248. #ifndef SPI_CLOCK_DIV128
  249. SPI.setClockDivider(divisor);
  250. #else // SPI_CLOCK_DIV128
  251. int v;
  252. if (divisor <= 2) {
  253. v = SPI_CLOCK_DIV2;
  254. } else if (divisor <= 4) {
  255. v = SPI_CLOCK_DIV4;
  256. } else if (divisor <= 8) {
  257. v = SPI_CLOCK_DIV8;
  258. } else if (divisor <= 16) {
  259. v = SPI_CLOCK_DIV16;
  260. } else if (divisor <= 32) {
  261. v = SPI_CLOCK_DIV32;
  262. } else if (divisor <= 64) {
  263. v = SPI_CLOCK_DIV64;
  264. } else {
  265. v = SPI_CLOCK_DIV128;
  266. }
  267. SPI.setClockDivider(v);
  268. #endif // SPI_CLOCK_DIV128
  269. }
  270. /** Receive a byte.
  271. *
  272. * \return The byte.
  273. */
  274. uint8_t SdSpi::receive() {
  275. return SPI.transfer(0XFF);
  276. }
  277. /** Receive multiple bytes.
  278. *
  279. * \param[out] buf Buffer to receive the data.
  280. * \param[in] n Number of bytes to receive.
  281. *
  282. * \return Zero for no error or nonzero error code.
  283. */
  284. uint8_t SdSpi::receive(uint8_t* buf, size_t n) {
  285. for (size_t i = 0; i < n; i++) {
  286. buf[i] = SPI.transfer(0XFF);
  287. }
  288. return 0;
  289. }
  290. /** Send a byte.
  291. *
  292. * \param[in] b Byte to send
  293. */
  294. void SdSpi::send(uint8_t b) {
  295. SPI.transfer(b);
  296. }
  297. /** Send multiple bytes.
  298. *
  299. * \param[in] buf Buffer for data to be sent.
  300. * \param[in] n Number of bytes to send.
  301. */
  302. void SdSpi::send(const uint8_t* buf , size_t n) {
  303. for (size_t i = 0; i < n; i++) {
  304. SPI.transfer(buf[i]);
  305. }
  306. }
  307. #endif // KINETISK
  308. //------------------------------------------------------------------------------
  309. void SdSpi::endTransaction() {
  310. #if ENABLE_SPI_TRANSACTIONS
  311. SPI.endTransaction();
  312. #endif // ENABLE_SPI_TRANSACTIONS
  313. }
  314. #endif // defined(__arm__) && defined(CORE_TEENSY)