您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

302 行
8.5KB

  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() {
  44. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  45. }
  46. //------------------------------------------------------------------------------
  47. /**
  48. * Initialize hardware SPI
  49. *
  50. */
  51. void SdSpi::init(uint8_t sckDivisor) {
  52. uint32_t ctar, ctar0, ctar1;
  53. if (sckDivisor <= 2) {
  54. // 1/2 speed
  55. ctar = SPI_CTAR_DBR | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0);
  56. } else if (sckDivisor <= 4) {
  57. // 1/4 speed
  58. ctar = SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0);
  59. } else if (sckDivisor <= 8) {
  60. // 1/8 speed
  61. ctar = SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  62. } else if (sckDivisor <= 12) {
  63. // 1/12 speed
  64. ctar = SPI_CTAR_BR(2) | SPI_CTAR_CSSCK(2);
  65. } else if (sckDivisor <= 16) {
  66. // 1/16 speed
  67. ctar = SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(3);
  68. } else if (sckDivisor <= 32) {
  69. // 1/32 speed
  70. ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4);
  71. } else if (sckDivisor <= 64) {
  72. // 1/64 speed
  73. ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(5);
  74. } else {
  75. // 1/128 speed
  76. ctar = SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6);
  77. }
  78. // CTAR0 - 8 bit transfer
  79. ctar0 = ctar | SPI_CTAR_FMSZ(7);
  80. // CTAR1 - 16 bit transfer
  81. ctar1 = ctar | SPI_CTAR_FMSZ(15);
  82. if (SPI0_CTAR0 != ctar0 || SPI0_CTAR1 != ctar1) {
  83. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  84. SPI0_CTAR0 = ctar0;
  85. SPI0_CTAR1 = ctar1;
  86. }
  87. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  88. CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  89. CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
  90. CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  91. }
  92. //------------------------------------------------------------------------------
  93. /** SPI receive a byte */
  94. uint8_t SdSpi::receive() {
  95. SPI0_MCR |= SPI_MCR_CLR_RXF;
  96. SPI0_SR = SPI_SR_TCF;
  97. SPI0_PUSHR = 0xFF;
  98. while (!(SPI0_SR & SPI_SR_TCF)) {}
  99. return SPI0_POPR;
  100. }
  101. //------------------------------------------------------------------------------
  102. /** SPI receive multiple bytes */
  103. uint8_t SdSpi::receive(uint8_t* buf, size_t n) {
  104. // clear any data in RX FIFO
  105. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  106. #if SPI_USE_8BIT_FRAME
  107. // initial number of bytes to push into TX FIFO
  108. int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH;
  109. for (int i = 0; i < nf; i++) {
  110. SPI0_PUSHR = 0XFF;
  111. }
  112. // limit for pushing dummy data into TX FIFO
  113. uint8_t* limit = buf + n - nf;
  114. while (buf < limit) {
  115. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  116. SPI0_PUSHR = 0XFF;
  117. *buf++ = SPI0_POPR;
  118. }
  119. // limit for rest of RX data
  120. limit += nf;
  121. while (buf < limit) {
  122. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  123. *buf++ = SPI0_POPR;
  124. }
  125. #else // SPI_USE_8BIT_FRAME
  126. // use 16 bit frame to avoid TD delay between frames
  127. // get one byte if n is odd
  128. if (n & 1) {
  129. *buf++ = receive();
  130. n--;
  131. }
  132. // initial number of words to push into TX FIFO
  133. int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH;
  134. for (int i = 0; i < nf; i++) {
  135. SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF;
  136. }
  137. uint8_t* limit = buf + n - 2*nf;
  138. while (buf < limit) {
  139. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  140. SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | 0XFFFF;
  141. uint16_t w = SPI0_POPR;
  142. *buf++ = w >> 8;
  143. *buf++ = w & 0XFF;
  144. }
  145. // limit for rest of RX data
  146. limit += 2*nf;
  147. while (buf < limit) {
  148. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  149. uint16_t w = SPI0_POPR;
  150. *buf++ = w >> 8;
  151. *buf++ = w & 0XFF;
  152. }
  153. #endif // SPI_USE_8BIT_FRAME
  154. return 0;
  155. }
  156. //------------------------------------------------------------------------------
  157. /** SPI send a byte */
  158. void SdSpi::send(uint8_t b) {
  159. SPI0_MCR |= SPI_MCR_CLR_RXF;
  160. SPI0_SR = SPI_SR_TCF;
  161. SPI0_PUSHR = b;
  162. while (!(SPI0_SR & SPI_SR_TCF)) {}
  163. }
  164. //------------------------------------------------------------------------------
  165. /** SPI send multiple bytes */
  166. void SdSpi::send(const uint8_t* buf , size_t n) {
  167. // clear any data in RX FIFO
  168. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  169. #if SPI_USE_8BIT_FRAME
  170. // initial number of bytes to push into TX FIFO
  171. int nf = n < SPI_INITIAL_FIFO_DEPTH ? n : SPI_INITIAL_FIFO_DEPTH;
  172. // limit for pushing data into TX fifo
  173. const uint8_t* limit = buf + n;
  174. for (int i = 0; i < nf; i++) {
  175. SPI0_PUSHR = *buf++;
  176. }
  177. // write data to TX FIFO
  178. while (buf < limit) {
  179. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  180. SPI0_PUSHR = *buf++;
  181. SPI0_POPR;
  182. }
  183. // wait for data to be sent
  184. while (nf) {
  185. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  186. SPI0_POPR;
  187. nf--;
  188. }
  189. #else // SPI_USE_8BIT_FRAME
  190. // use 16 bit frame to avoid TD delay between frames
  191. // send one byte if n is odd
  192. if (n & 1) {
  193. send(*buf++);
  194. n--;
  195. }
  196. // initial number of words to push into TX FIFO
  197. int nf = n/2 < SPI_INITIAL_FIFO_DEPTH ? n/2 : SPI_INITIAL_FIFO_DEPTH;
  198. // limit for pushing data into TX fifo
  199. const uint8_t* limit = buf + n;
  200. for (int i = 0; i < nf; i++) {
  201. uint16_t w = (*buf++) << 8;
  202. w |= *buf++;
  203. SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w;
  204. }
  205. // write data to TX FIFO
  206. while (buf < limit) {
  207. uint16_t w = *buf++ << 8;
  208. w |= *buf++;
  209. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  210. SPI0_PUSHR = SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1) | w;
  211. SPI0_POPR;
  212. }
  213. // wait for data to be sent
  214. while (nf) {
  215. while (!(SPI0_SR & SPI_SR_RXCTR)) {}
  216. SPI0_POPR;
  217. nf--;
  218. }
  219. #endif // SPI_USE_8BIT_FRAME
  220. }
  221. #else // KINETISK
  222. //==============================================================================
  223. // Use standard SPI library if not KINETISK
  224. #include "SPI.h"
  225. /**
  226. * Initialize SPI pins.
  227. */
  228. void SdSpi::begin() {
  229. SPI.begin();
  230. }
  231. /** Set SPI options for access to SD/SDHC cards.
  232. *
  233. * \param[in] divisor SCK clock divider relative to the system clock.
  234. */
  235. void SdSpi::init(uint8_t divisor) {
  236. SPI.setBitOrder(MSBFIRST);
  237. SPI.setDataMode(SPI_MODE0);
  238. #ifndef SPI_CLOCK_DIV128
  239. SPI.setClockDivider(divisor);
  240. #else // SPI_CLOCK_DIV128
  241. int v;
  242. if (divisor <= 2) {
  243. v = SPI_CLOCK_DIV2;
  244. } else if (divisor <= 4) {
  245. v = SPI_CLOCK_DIV4;
  246. } else if (divisor <= 8) {
  247. v = SPI_CLOCK_DIV8;
  248. } else if (divisor <= 16) {
  249. v = SPI_CLOCK_DIV16;
  250. } else if (divisor <= 32) {
  251. v = SPI_CLOCK_DIV32;
  252. } else if (divisor <= 64) {
  253. v = SPI_CLOCK_DIV64;
  254. } else {
  255. v = SPI_CLOCK_DIV128;
  256. }
  257. SPI.setClockDivider(v);
  258. #endif // SPI_CLOCK_DIV128
  259. }
  260. /** Receive a byte.
  261. *
  262. * \return The byte.
  263. */
  264. uint8_t SdSpi::receive() {
  265. return SPI.transfer(0XFF);
  266. }
  267. /** Receive multiple bytes.
  268. *
  269. * \param[out] buf Buffer to receive the data.
  270. * \param[in] n Number of bytes to receive.
  271. *
  272. * \return Zero for no error or nonzero error code.
  273. */
  274. uint8_t SdSpi::receive(uint8_t* buf, size_t n) {
  275. for (size_t i = 0; i < n; i++) {
  276. buf[i] = SPI.transfer(0XFF);
  277. }
  278. return 0;
  279. }
  280. /** Send a byte.
  281. *
  282. * \param[in] b Byte to send
  283. */
  284. void SdSpi::send(uint8_t b) {
  285. SPI.transfer(b);
  286. }
  287. /** Send multiple bytes.
  288. *
  289. * \param[in] buf Buffer for data to be sent.
  290. * \param[in] n Number of bytes to send.
  291. */
  292. void SdSpi::send(const uint8_t* buf , size_t n) {
  293. for (size_t i = 0; i < n; i++) {
  294. SPI.transfer(buf[i]);
  295. }
  296. }
  297. #endif // KINETISK
  298. #endif // defined(__arm__) && defined(CORE_TEENSY)