Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

1449 rindas
42KB

  1. /*
  2. * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
  3. * SPI Master library for arduino.
  4. *
  5. * This file is free software; you can redistribute it and/or modify
  6. * it under the terms of either the GNU General Public License version 2
  7. * or the GNU Lesser General Public License version 2.1, both as
  8. * published by the Free Software Foundation.
  9. */
  10. #include "SPI.h"
  11. #include "pins_arduino.h"
  12. /**********************************************************/
  13. /* 8 bit AVR-based boards */
  14. /**********************************************************/
  15. #if defined(__AVR__)
  16. SPIClass SPI;
  17. uint8_t SPIClass::interruptMode = 0;
  18. uint8_t SPIClass::interruptMask = 0;
  19. uint8_t SPIClass::interruptSave = 0;
  20. #ifdef SPI_TRANSACTION_MISMATCH_LED
  21. uint8_t SPIClass::inTransactionFlag = 0;
  22. #endif
  23. uint8_t SPIClass::_transferWriteFill = 0;
  24. void SPIClass::begin()
  25. {
  26. // Set SS to high so a connected chip will be "deselected" by default
  27. digitalWrite(SS, HIGH);
  28. // When the SS pin is set as OUTPUT, it can be used as
  29. // a general purpose output port (it doesn't influence
  30. // SPI operations).
  31. pinMode(SS, OUTPUT);
  32. // Warning: if the SS pin ever becomes a LOW INPUT then SPI
  33. // automatically switches to Slave, so the data direction of
  34. // the SS pin MUST be kept as OUTPUT.
  35. SPCR |= _BV(MSTR);
  36. SPCR |= _BV(SPE);
  37. // Set direction register for SCK and MOSI pin.
  38. // MISO pin automatically overrides to INPUT.
  39. // By doing this AFTER enabling SPI, we avoid accidentally
  40. // clocking in a single bit since the lines go directly
  41. // from "input" to SPI control.
  42. // http://code.google.com/p/arduino/issues/detail?id=888
  43. pinMode(SCK, OUTPUT);
  44. pinMode(MOSI, OUTPUT);
  45. }
  46. void SPIClass::end() {
  47. SPCR &= ~_BV(SPE);
  48. }
  49. // mapping of interrupt numbers to bits within SPI_AVR_EIMSK
  50. #if defined(__AVR_ATmega32U4__)
  51. #define SPI_INT0_MASK (1<<INT0)
  52. #define SPI_INT1_MASK (1<<INT1)
  53. #define SPI_INT2_MASK (1<<INT2)
  54. #define SPI_INT3_MASK (1<<INT3)
  55. #define SPI_INT4_MASK (1<<INT6)
  56. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  57. #define SPI_INT0_MASK (1<<INT0)
  58. #define SPI_INT1_MASK (1<<INT1)
  59. #define SPI_INT2_MASK (1<<INT2)
  60. #define SPI_INT3_MASK (1<<INT3)
  61. #define SPI_INT4_MASK (1<<INT4)
  62. #define SPI_INT5_MASK (1<<INT5)
  63. #define SPI_INT6_MASK (1<<INT6)
  64. #define SPI_INT7_MASK (1<<INT7)
  65. #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
  66. #define SPI_INT0_MASK (1<<INT4)
  67. #define SPI_INT1_MASK (1<<INT5)
  68. #define SPI_INT2_MASK (1<<INT0)
  69. #define SPI_INT3_MASK (1<<INT1)
  70. #define SPI_INT4_MASK (1<<INT2)
  71. #define SPI_INT5_MASK (1<<INT3)
  72. #define SPI_INT6_MASK (1<<INT6)
  73. #define SPI_INT7_MASK (1<<INT7)
  74. #else
  75. #ifdef INT0
  76. #define SPI_INT0_MASK (1<<INT0)
  77. #endif
  78. #ifdef INT1
  79. #define SPI_INT1_MASK (1<<INT1)
  80. #endif
  81. #ifdef INT2
  82. #define SPI_INT2_MASK (1<<INT2)
  83. #endif
  84. #endif
  85. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  86. {
  87. uint8_t stmp, mask;
  88. if (interruptMode > 1) return;
  89. stmp = SREG;
  90. noInterrupts();
  91. switch (interruptNumber) {
  92. #ifdef SPI_INT0_MASK
  93. case 0: mask = SPI_INT0_MASK; break;
  94. #endif
  95. #ifdef SPI_INT1_MASK
  96. case 1: mask = SPI_INT1_MASK; break;
  97. #endif
  98. #ifdef SPI_INT2_MASK
  99. case 2: mask = SPI_INT2_MASK; break;
  100. #endif
  101. #ifdef SPI_INT3_MASK
  102. case 3: mask = SPI_INT3_MASK; break;
  103. #endif
  104. #ifdef SPI_INT4_MASK
  105. case 4: mask = SPI_INT4_MASK; break;
  106. #endif
  107. #ifdef SPI_INT5_MASK
  108. case 5: mask = SPI_INT5_MASK; break;
  109. #endif
  110. #ifdef SPI_INT6_MASK
  111. case 6: mask = SPI_INT6_MASK; break;
  112. #endif
  113. #ifdef SPI_INT7_MASK
  114. case 7: mask = SPI_INT7_MASK; break;
  115. #endif
  116. default:
  117. interruptMode = 2;
  118. SREG = stmp;
  119. return;
  120. }
  121. interruptMode = 1;
  122. interruptMask |= mask;
  123. SREG = stmp;
  124. }
  125. void SPIClass::transfer(const void * buf, void * retbuf, uint32_t count) {
  126. if (count == 0) return;
  127. const uint8_t *p = (const uint8_t *)buf;
  128. uint8_t *pret = (uint8_t *)retbuf;
  129. uint8_t in;
  130. uint8_t out = p ? *p++ : _transferWriteFill;
  131. SPDR = out;
  132. while (--count > 0) {
  133. if (p) {
  134. out = *p++;
  135. }
  136. while (!(SPSR & _BV(SPIF))) ;
  137. in = SPDR;
  138. SPDR = out;
  139. if (pret)*pret++ = in;
  140. }
  141. while (!(SPSR & _BV(SPIF))) ;
  142. in = SPDR;
  143. if (pret)*pret = in;
  144. }
  145. /**********************************************************/
  146. /* 32 bit Teensy 3.x */
  147. /**********************************************************/
  148. #elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISK)
  149. #if defined(KINETISK) && defined( SPI_HAS_TRANSFER_ASYNC)
  150. #ifndef TRANSFER_COUNT_FIXED
  151. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  152. // note does no validation of length...
  153. DMABaseClass::TCD_t *tcd = dmac->TCD;
  154. if (!(tcd->BITER & DMA_TCD_BITER_ELINK)) {
  155. tcd->BITER = len & 0x7fff;
  156. } else {
  157. tcd->BITER = (tcd->BITER & 0xFE00) | (len & 0x1ff);
  158. }
  159. tcd->CITER = tcd->BITER;
  160. }
  161. #else
  162. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  163. dmac->transferCount(len);
  164. }
  165. #endif
  166. #endif
  167. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  168. #ifdef SPI_HAS_TRANSFER_ASYNC
  169. void _spi_dma_rxISR0(void) {SPI.dma_rxisr();}
  170. #else
  171. void _spi_dma_rxISR0(void) {;}
  172. #endif
  173. const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = {
  174. SIM_SCGC6, SIM_SCGC6_SPI0, 4, IRQ_SPI0,
  175. 32767, DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX,
  176. _spi_dma_rxISR0,
  177. 12, 8,
  178. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  179. 11, 7,
  180. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  181. 13, 14,
  182. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  183. 10, 2, 9, 6, 20, 23, 21, 22, 15,
  184. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  185. 0x1, 0x1, 0x2, 0x2, 0x4, 0x4, 0x8, 0x8, 0x10
  186. };
  187. SPIClass SPI((uintptr_t)&KINETISK_SPI0, (uintptr_t)&SPIClass::spi0_hardware);
  188. #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
  189. #ifdef SPI_HAS_TRANSFER_ASYNC
  190. void _spi_dma_rxISR0(void) {SPI.dma_rxisr();}
  191. void _spi_dma_rxISR1(void) {SPI1.dma_rxisr();}
  192. void _spi_dma_rxISR2(void) {SPI2.dma_rxisr();}
  193. #else
  194. void _spi_dma_rxISR0(void) {;}
  195. void _spi_dma_rxISR1(void) {;}
  196. void _spi_dma_rxISR2(void) {;}
  197. #endif
  198. const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = {
  199. SIM_SCGC6, SIM_SCGC6_SPI0, 4, IRQ_SPI0,
  200. 32767, DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX,
  201. _spi_dma_rxISR0,
  202. 12, 8, 39, 255,
  203. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0,
  204. 11, 7, 28, 255,
  205. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0,
  206. 13, 14, 27,
  207. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  208. 10, 2, 9, 6, 20, 23, 21, 22, 15, 26, 45,
  209. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(3),
  210. 0x1, 0x1, 0x2, 0x2, 0x4, 0x4, 0x8, 0x8, 0x10, 0x1, 0x20
  211. };
  212. const SPIClass::SPI_Hardware_t SPIClass::spi1_hardware = {
  213. SIM_SCGC6, SIM_SCGC6_SPI1, 1, IRQ_SPI1,
  214. #if defined(__MK66FX1M0__)
  215. 32767, DMAMUX_SOURCE_SPI1_TX, DMAMUX_SOURCE_SPI1_RX,
  216. #else
  217. // T3.5 does not have good DMA support on 1 and 2
  218. 511, 0, DMAMUX_SOURCE_SPI1,
  219. #endif
  220. _spi_dma_rxISR1,
  221. 1, 5, 61, 59,
  222. PORT_PCR_MUX(2), PORT_PCR_MUX(7), PORT_PCR_MUX(2), PORT_PCR_MUX(7),
  223. 0, 21, 61, 59,
  224. PORT_PCR_MUX(2), PORT_PCR_MUX(7), PORT_PCR_MUX(7), PORT_PCR_MUX(2),
  225. 32, 20, 60,
  226. PORT_PCR_MUX(2), PORT_PCR_MUX(7), PORT_PCR_MUX(2),
  227. 6, 31, 58, 62, 63, 255, 255, 255, 255, 255, 255,
  228. PORT_PCR_MUX(7), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0, 0, 0, 0, 0,
  229. 0x1, 0x1, 0x2, 0x1, 0x4, 0, 0, 0, 0, 0, 0
  230. };
  231. const SPIClass::SPI_Hardware_t SPIClass::spi2_hardware = {
  232. SIM_SCGC3, SIM_SCGC3_SPI2, 1, IRQ_SPI2,
  233. #if defined(__MK66FX1M0__)
  234. 32767, DMAMUX_SOURCE_SPI2_TX, DMAMUX_SOURCE_SPI2_RX,
  235. #else
  236. // T3.5 does not have good DMA support on 1 and 2
  237. 511, 0, DMAMUX_SOURCE_SPI2,
  238. #endif
  239. _spi_dma_rxISR2,
  240. 45, 51, 255, 255,
  241. PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0,
  242. 44, 52, 255, 255,
  243. PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0,
  244. 46, 53, 255,
  245. PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0,
  246. 43, 54, 55, 255, 255, 255, 255, 255, 255, 255, 255,
  247. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0, 0, 0, 0, 0, 0, 0,
  248. 0x1, 0x2, 0x1, 0, 0, 0, 0, 0, 0, 0, 0
  249. };
  250. SPIClass SPI((uintptr_t)&KINETISK_SPI0, (uintptr_t)&SPIClass::spi0_hardware);
  251. SPIClass SPI1((uintptr_t)&KINETISK_SPI1, (uintptr_t)&SPIClass::spi1_hardware);
  252. SPIClass SPI2((uintptr_t)&KINETISK_SPI2, (uintptr_t)&SPIClass::spi2_hardware);
  253. #endif
  254. void SPIClass::begin()
  255. {
  256. volatile uint32_t *reg;
  257. hardware().clock_gate_register |= hardware().clock_gate_mask;
  258. port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  259. port().CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  260. port().CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  261. port().MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  262. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  263. *reg = hardware().mosi_mux[mosi_pin_index];
  264. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  265. *reg= hardware().miso_mux[miso_pin_index];
  266. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  267. *reg = hardware().sck_mux[sck_pin_index];
  268. }
  269. void SPIClass::end()
  270. {
  271. volatile uint32_t *reg;
  272. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  273. *reg = 0;
  274. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  275. *reg = 0;
  276. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  277. *reg = 0;
  278. port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  279. }
  280. void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName)
  281. {
  282. uint32_t n = (uint32_t)interruptName;
  283. if (n >= NVIC_NUM_INTERRUPTS) return;
  284. //Serial.print("usingInterrupt ");
  285. //Serial.println(n);
  286. interruptMasksUsed |= (1 << (n >> 5));
  287. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  288. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  289. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  290. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  291. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  292. }
  293. void SPIClass::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  294. {
  295. uint32_t n = (uint32_t)interruptName;
  296. if (n >= NVIC_NUM_INTERRUPTS) return;
  297. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  298. if (interruptMask[n >> 5] == 0) {
  299. interruptMasksUsed &= ~(1 << (n >> 5));
  300. }
  301. }
  302. const uint16_t SPISettings::ctar_div_table[23] = {
  303. 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40,
  304. 56, 64, 96, 128, 192, 256, 384, 512, 640, 768
  305. };
  306. const uint32_t SPISettings::ctar_clock_table[23] = {
  307. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  308. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  309. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  310. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  311. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  312. SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  313. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  314. SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  315. SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  316. SPI_CTAR_PBR(2) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(0),
  317. SPI_CTAR_PBR(1) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  318. SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(3),
  319. SPI_CTAR_PBR(2) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  320. SPI_CTAR_PBR(3) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  321. SPI_CTAR_PBR(0) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  322. SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  323. SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  324. SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  325. SPI_CTAR_PBR(0) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  326. SPI_CTAR_PBR(1) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  327. SPI_CTAR_PBR(0) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7),
  328. SPI_CTAR_PBR(2) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  329. SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7)
  330. };
  331. void SPIClass::updateCTAR(uint32_t ctar)
  332. {
  333. if (port().CTAR0 != ctar) {
  334. uint32_t mcr = port().MCR;
  335. if (mcr & SPI_MCR_MDIS) {
  336. port().CTAR0 = ctar;
  337. port().CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  338. } else {
  339. port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  340. port().CTAR0 = ctar;
  341. port().CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  342. port().MCR = mcr;
  343. }
  344. }
  345. }
  346. void SPIClass::setBitOrder(uint8_t bitOrder)
  347. {
  348. hardware().clock_gate_register |= hardware().clock_gate_mask;
  349. uint32_t ctar = port().CTAR0;
  350. if (bitOrder == LSBFIRST) {
  351. ctar |= SPI_CTAR_LSBFE;
  352. } else {
  353. ctar &= ~SPI_CTAR_LSBFE;
  354. }
  355. updateCTAR(ctar);
  356. }
  357. void SPIClass::setDataMode(uint8_t dataMode)
  358. {
  359. hardware().clock_gate_register |= hardware().clock_gate_mask;
  360. //uint32_t ctar = port().CTAR0;
  361. // TODO: implement with native code
  362. //SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  363. }
  364. void SPIClass::setClockDivider_noInline(uint32_t clk)
  365. {
  366. hardware().clock_gate_register |= hardware().clock_gate_mask;
  367. uint32_t ctar = port().CTAR0;
  368. ctar &= (SPI_CTAR_CPOL | SPI_CTAR_CPHA | SPI_CTAR_LSBFE);
  369. if (ctar & SPI_CTAR_CPHA) {
  370. clk = (clk & 0xFFFF0FFF) | ((clk & 0xF000) >> 4);
  371. }
  372. ctar |= clk;
  373. updateCTAR(ctar);
  374. }
  375. uint8_t SPIClass::pinIsChipSelect(uint8_t pin)
  376. {
  377. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  378. if (pin == hardware().cs_pin[i]) return hardware().cs_mask[i];
  379. }
  380. return 0;
  381. }
  382. bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  383. {
  384. uint8_t pin1_mask, pin2_mask;
  385. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  386. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  387. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  388. if ((pin1_mask & pin2_mask) != 0) return false;
  389. return true;
  390. }
  391. bool SPIClass::pinIsMOSI(uint8_t pin)
  392. {
  393. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  394. if (pin == hardware().mosi_pin[i]) return true;
  395. }
  396. return false;
  397. }
  398. bool SPIClass::pinIsMISO(uint8_t pin)
  399. {
  400. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  401. if (pin == hardware().miso_pin[i]) return true;
  402. }
  403. return false;
  404. }
  405. bool SPIClass::pinIsSCK(uint8_t pin)
  406. {
  407. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  408. if (pin == hardware().sck_pin[i]) return true;
  409. }
  410. return false;
  411. }
  412. // setCS() is not intended for use from normal Arduino programs/sketches.
  413. uint8_t SPIClass::setCS(uint8_t pin)
  414. {
  415. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  416. if (pin == hardware().cs_pin[i]) {
  417. volatile uint32_t *reg = portConfigRegister(pin);
  418. *reg = hardware().cs_mux[i];
  419. return hardware().cs_mask[i];
  420. }
  421. }
  422. return 0;
  423. }
  424. void SPIClass::setMOSI(uint8_t pin)
  425. {
  426. if (hardware_addr == (uintptr_t)&spi0_hardware) {
  427. SPCR.setMOSI_soft(pin);
  428. }
  429. if (pin != hardware().mosi_pin[mosi_pin_index]) {
  430. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  431. if (pin == hardware().mosi_pin[i]) {
  432. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  433. volatile uint32_t *reg;
  434. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  435. *reg = 0;
  436. reg = portConfigRegister(hardware().mosi_pin[i]);
  437. *reg = hardware().mosi_mux[i];
  438. }
  439. mosi_pin_index = i;
  440. return;
  441. }
  442. }
  443. }
  444. }
  445. void SPIClass::setMISO(uint8_t pin)
  446. {
  447. if (hardware_addr == (uintptr_t)&spi0_hardware) {
  448. SPCR.setMISO_soft(pin);
  449. }
  450. if (pin != hardware().miso_pin[miso_pin_index]) {
  451. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  452. if (pin == hardware().miso_pin[i]) {
  453. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  454. volatile uint32_t *reg;
  455. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  456. *reg = 0;
  457. reg = portConfigRegister(hardware().miso_pin[i]);
  458. *reg = hardware().miso_mux[i];
  459. }
  460. miso_pin_index = i;
  461. return;
  462. }
  463. }
  464. }
  465. }
  466. void SPIClass::setSCK(uint8_t pin)
  467. {
  468. if (hardware_addr == (uintptr_t)&spi0_hardware) {
  469. SPCR.setSCK_soft(pin);
  470. }
  471. if (pin != hardware().sck_pin[sck_pin_index]) {
  472. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  473. if (pin == hardware().sck_pin[i]) {
  474. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  475. volatile uint32_t *reg;
  476. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  477. *reg = 0;
  478. reg = portConfigRegister(hardware().sck_pin[i]);
  479. *reg = hardware().sck_mux[i];
  480. }
  481. sck_pin_index = i;
  482. return;
  483. }
  484. }
  485. }
  486. }
  487. void SPIClass::transfer(const void * buf, void * retbuf, size_t count)
  488. {
  489. if (count == 0) return;
  490. if (!(port().CTAR0 & SPI_CTAR_LSBFE)) {
  491. // We are doing the standard MSB order
  492. const uint8_t *p_write = (const uint8_t *)buf;
  493. uint8_t *p_read = (uint8_t *)retbuf;
  494. size_t count_read = count;
  495. // Lets clear the reader queue
  496. port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  497. uint32_t sr;
  498. // Now lets loop while we still have data to output
  499. if (count & 1) {
  500. if (p_write) {
  501. if (count > 1)
  502. port().PUSHR = *p_write++ | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  503. else
  504. port().PUSHR = *p_write++ | SPI_PUSHR_CTAS(0);
  505. } else {
  506. if (count > 1)
  507. port().PUSHR = _transferWriteFill | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  508. else
  509. port().PUSHR = _transferWriteFill | SPI_PUSHR_CTAS(0);
  510. }
  511. count--;
  512. }
  513. uint16_t w = (uint16_t)(_transferWriteFill << 8) | _transferWriteFill;
  514. while (count > 0) {
  515. // Push out the next byte;
  516. if (p_write) {
  517. w = (*p_write++) << 8;
  518. w |= *p_write++;
  519. }
  520. uint16_t queue_full_status_mask = (hardware().queue_size-1) << 12;
  521. if (count == 2)
  522. port().PUSHR = w | SPI_PUSHR_CTAS(1);
  523. else
  524. port().PUSHR = w | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1);
  525. count -= 2; // how many bytes to output.
  526. // Make sure queue is not full before pushing next byte out
  527. do {
  528. sr = port().SR;
  529. if (sr & 0xF0) {
  530. uint16_t w = port().POPR; // Read any pending RX bytes in
  531. if (count_read & 1) {
  532. if (p_read) {
  533. *p_read++ = w; // Read any pending RX bytes in
  534. }
  535. count_read--;
  536. } else {
  537. if (p_read) {
  538. *p_read++ = w >> 8;
  539. *p_read++ = (w & 0xff);
  540. }
  541. count_read -= 2;
  542. }
  543. }
  544. } while ((sr & (15 << 12)) > queue_full_status_mask);
  545. }
  546. // now lets wait for all of the read bytes to be returned...
  547. while (count_read) {
  548. sr = port().SR;
  549. if (sr & 0xF0) {
  550. uint16_t w = port().POPR; // Read any pending RX bytes in
  551. if (count_read & 1) {
  552. if (p_read)
  553. *p_read++ = w; // Read any pending RX bytes in
  554. count_read--;
  555. } else {
  556. if (p_read) {
  557. *p_read++ = w >> 8;
  558. *p_read++ = (w & 0xff);
  559. }
  560. count_read -= 2;
  561. }
  562. }
  563. }
  564. } else {
  565. // We are doing the less ofen LSB mode
  566. const uint8_t *p_write = (const uint8_t *)buf;
  567. uint8_t *p_read = (uint8_t *)retbuf;
  568. size_t count_read = count;
  569. // Lets clear the reader queue
  570. port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  571. uint32_t sr;
  572. // Now lets loop while we still have data to output
  573. if (count & 1) {
  574. if (p_write) {
  575. if (count > 1)
  576. port().PUSHR = *p_write++ | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  577. else
  578. port().PUSHR = *p_write++ | SPI_PUSHR_CTAS(0);
  579. } else {
  580. if (count > 1)
  581. port().PUSHR = _transferWriteFill | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  582. else
  583. port().PUSHR = _transferWriteFill | SPI_PUSHR_CTAS(0);
  584. }
  585. count--;
  586. }
  587. uint16_t w = _transferWriteFill;
  588. while (count > 0) {
  589. // Push out the next byte;
  590. if (p_write) {
  591. w = *p_write++;
  592. w |= ((*p_write++) << 8);
  593. }
  594. uint16_t queue_full_status_mask = (hardware().queue_size-1) << 12;
  595. if (count == 2)
  596. port().PUSHR = w | SPI_PUSHR_CTAS(1);
  597. else
  598. port().PUSHR = w | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1);
  599. count -= 2; // how many bytes to output.
  600. // Make sure queue is not full before pushing next byte out
  601. do {
  602. sr = port().SR;
  603. if (sr & 0xF0) {
  604. uint16_t w = port().POPR; // Read any pending RX bytes in
  605. if (count_read & 1) {
  606. if (p_read) {
  607. *p_read++ = w; // Read any pending RX bytes in
  608. }
  609. count_read--;
  610. } else {
  611. if (p_read) {
  612. *p_read++ = (w & 0xff);
  613. *p_read++ = w >> 8;
  614. }
  615. count_read -= 2;
  616. }
  617. }
  618. } while ((sr & (15 << 12)) > queue_full_status_mask);
  619. }
  620. // now lets wait for all of the read bytes to be returned...
  621. while (count_read) {
  622. sr = port().SR;
  623. if (sr & 0xF0) {
  624. uint16_t w = port().POPR; // Read any pending RX bytes in
  625. if (count_read & 1) {
  626. if (p_read)
  627. *p_read++ = w; // Read any pending RX bytes in
  628. count_read--;
  629. } else {
  630. if (p_read) {
  631. *p_read++ = (w & 0xff);
  632. *p_read++ = w >> 8;
  633. }
  634. count_read -= 2;
  635. }
  636. }
  637. }
  638. }
  639. }
  640. //=============================================================================
  641. // ASYNCH Support
  642. //=============================================================================
  643. //=========================================================================
  644. // Try Transfer using DMA.
  645. //=========================================================================
  646. #ifdef SPI_HAS_TRANSFER_ASYNC
  647. static uint8_t bit_bucket;
  648. #define dontInterruptAtCompletion(dmac) (dmac)->TCD->CSR &= ~DMA_TCD_CSR_INTMAJOR
  649. //=========================================================================
  650. // Init the DMA channels
  651. //=========================================================================
  652. bool SPIClass::initDMAChannels() {
  653. // Allocate our channels.
  654. _dmaTX = new DMAChannel();
  655. if (_dmaTX == nullptr) {
  656. return false;
  657. }
  658. _dmaRX = new DMAChannel();
  659. if (_dmaRX == nullptr) {
  660. delete _dmaTX; // release it
  661. _dmaTX = nullptr;
  662. return false;
  663. }
  664. // Let's setup the RX chain
  665. _dmaRX->disable();
  666. _dmaRX->source((volatile uint8_t&)port().POPR);
  667. _dmaRX->disableOnCompletion();
  668. _dmaRX->triggerAtHardwareEvent(hardware().rx_dma_channel);
  669. _dmaRX->attachInterrupt(hardware().dma_rxisr);
  670. _dmaRX->interruptAtCompletion();
  671. // We may be using settings chain here so lets set it up.
  672. // Now lets setup TX chain. Note if trigger TX is not set
  673. // we need to have the RX do it for us.
  674. _dmaTX->disable();
  675. _dmaTX->destination((volatile uint8_t&)port().PUSHR);
  676. _dmaTX->disableOnCompletion();
  677. if (hardware().tx_dma_channel) {
  678. _dmaTX->triggerAtHardwareEvent(hardware().tx_dma_channel);
  679. } else {
  680. // Serial.printf("SPI InitDMA tx triger by RX: %x\n", (uint32_t)_dmaRX);
  681. _dmaTX->triggerAtTransfersOf(*_dmaRX);
  682. }
  683. _dma_state = DMAState::idle; // Should be first thing set!
  684. return true;
  685. }
  686. //=========================================================================
  687. // Main Async Transfer function
  688. //=========================================================================
  689. bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) {
  690. uint8_t dma_first_byte;
  691. if (_dma_state == DMAState::notAllocated) {
  692. if (!initDMAChannels())
  693. return false;
  694. }
  695. if (_dma_state == DMAState::active)
  696. return false; // already active
  697. event_responder.clearEvent(); // Make sure it is not set yet
  698. if (count < 2) {
  699. // Use non-async version to simplify cases...
  700. transfer(buf, retbuf, count);
  701. event_responder.triggerEvent();
  702. return true;
  703. }
  704. // Now handle the cases where the count > then how many we can output in one DMA request
  705. if (count > hardware().max_dma_count) {
  706. _dma_count_remaining = count - hardware().max_dma_count;
  707. count = hardware().max_dma_count;
  708. } else {
  709. _dma_count_remaining = 0;
  710. }
  711. // Now See if caller passed in a source buffer.
  712. _dmaTX->TCD->ATTR_DST = 0; // Make sure set for 8 bit mode
  713. uint8_t *write_data = (uint8_t*) buf;
  714. if (buf) {
  715. dma_first_byte = *write_data;
  716. _dmaTX->sourceBuffer((uint8_t*)write_data+1, count-1);
  717. _dmaTX->TCD->SLAST = 0; // Finish with it pointing to next location
  718. } else {
  719. dma_first_byte = _transferWriteFill;
  720. _dmaTX->source((uint8_t&)_transferWriteFill); // maybe have setable value
  721. DMAChanneltransferCount(_dmaTX, count-1);
  722. }
  723. if (retbuf) {
  724. // On T3.5 must handle SPI1/2 differently as only one DMA channel
  725. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  726. _dmaRX->destinationBuffer((uint8_t*)retbuf, count);
  727. _dmaRX->TCD->DLASTSGA = 0; // At end point after our bufffer
  728. } else {
  729. // Write only mode
  730. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  731. _dmaRX->destination((uint8_t&)bit_bucket);
  732. DMAChanneltransferCount(_dmaRX, count);
  733. }
  734. _dma_event_responder = &event_responder;
  735. // Now try to start it?
  736. // Setup DMA main object
  737. yield();
  738. port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_CLR_TXF | SPI_MCR_PCSIS(0x1F);
  739. port().SR = 0xFF0F0000;
  740. // Lets try to output the first byte to make sure that we are in 8 bit mode...
  741. port().PUSHR = dma_first_byte | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
  742. if (hardware().tx_dma_channel) {
  743. port().RSER = SPI_RSER_RFDF_RE | SPI_RSER_RFDF_DIRS | SPI_RSER_TFFF_RE | SPI_RSER_TFFF_DIRS;
  744. _dmaRX->enable();
  745. // Get the initial settings.
  746. _dmaTX->enable();
  747. } else {
  748. //T3.5 SP1 and SPI2 - TX is not triggered by SPI but by RX...
  749. port().RSER = SPI_RSER_RFDF_RE | SPI_RSER_RFDF_DIRS ;
  750. _dmaTX->triggerAtTransfersOf(*_dmaRX);
  751. _dmaTX->enable();
  752. _dmaRX->enable();
  753. }
  754. _dma_state = DMAState::active;
  755. return true;
  756. }
  757. //-------------------------------------------------------------------------
  758. // DMA RX ISR
  759. //-------------------------------------------------------------------------
  760. void SPIClass::dma_rxisr(void) {
  761. _dmaRX->clearInterrupt();
  762. _dmaTX->clearComplete();
  763. _dmaRX->clearComplete();
  764. uint8_t should_reenable_tx = true; // should we re-enable TX maybe not if count will be 0...
  765. if (_dma_count_remaining) {
  766. // What do I need to do to start it back up again...
  767. // We will use the BITR/CITR from RX as TX may have prefed some stuff
  768. if (_dma_count_remaining > hardware().max_dma_count) {
  769. _dma_count_remaining -= hardware().max_dma_count;
  770. } else {
  771. DMAChanneltransferCount(_dmaTX, _dma_count_remaining-1);
  772. DMAChanneltransferCount(_dmaRX, _dma_count_remaining);
  773. if (_dma_count_remaining == 1) should_reenable_tx = false;
  774. _dma_count_remaining = 0;
  775. }
  776. // In some cases we need to again start the TX manually to get it to work...
  777. if (_dmaTX->TCD->SADDR == &_transferWriteFill) {
  778. if (port().CTAR0 & SPI_CTAR_FMSZ(8)) {
  779. port().PUSHR = (_transferWriteFill | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  780. } else {
  781. port().PUSHR = (_transferWriteFill | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  782. }
  783. } else {
  784. if (port().CTAR0 & SPI_CTAR_FMSZ(8)) {
  785. // 16 bit mode
  786. uint16_t w = *((uint16_t*)_dmaTX->TCD->SADDR);
  787. _dmaTX->TCD->SADDR = (volatile uint8_t*)(_dmaTX->TCD->SADDR) + 2;
  788. port().PUSHR = (w | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  789. } else {
  790. uint8_t w = *((uint8_t*)_dmaTX->TCD->SADDR);
  791. _dmaTX->TCD->SADDR = (volatile uint8_t*)(_dmaTX->TCD->SADDR) + 1;
  792. port().PUSHR = (w | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  793. }
  794. }
  795. _dmaRX->enable();
  796. if (should_reenable_tx)
  797. _dmaTX->enable();
  798. } else {
  799. port().RSER = 0;
  800. //port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); // clear out the queue
  801. port().SR = 0xFF0F0000;
  802. port().CTAR0 &= ~(SPI_CTAR_FMSZ(8)); // Hack restore back to 8 bits
  803. _dma_state = DMAState::completed; // set back to 1 in case our call wants to start up dma again
  804. _dma_event_responder->triggerEvent();
  805. }
  806. }
  807. #endif // SPI_HAS_TRANSFER_ASYNC
  808. /**********************************************************/
  809. /* 32 bit Teensy-LC */
  810. /**********************************************************/
  811. #elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISL)
  812. #ifdef SPI_HAS_TRANSFER_ASYNC
  813. void _spi_dma_rxISR0(void) {SPI.dma_isr();}
  814. void _spi_dma_rxISR1(void) {SPI1.dma_isr();}
  815. #else
  816. void _spi_dma_rxISR0(void) {;}
  817. void _spi_dma_rxISR1(void) {;}
  818. #endif
  819. const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = {
  820. SIM_SCGC4, SIM_SCGC4_SPI0,
  821. 0, // BR index 0
  822. DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX, _spi_dma_rxISR0,
  823. 12, 8,
  824. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  825. 11, 7,
  826. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  827. 13, 14,
  828. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  829. 10, 2,
  830. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  831. 0x1, 0x1
  832. };
  833. SPIClass SPI((uintptr_t)&KINETISL_SPI0, (uintptr_t)&SPIClass::spi0_hardware);
  834. const SPIClass::SPI_Hardware_t SPIClass::spi1_hardware = {
  835. SIM_SCGC4, SIM_SCGC4_SPI1,
  836. 1, // BR index 1 in SPI Settings
  837. DMAMUX_SOURCE_SPI1_TX, DMAMUX_SOURCE_SPI1_RX, _spi_dma_rxISR1,
  838. 1, 5,
  839. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  840. 0, 21,
  841. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  842. 20, 255,
  843. PORT_PCR_MUX(2), 0,
  844. 6, 255,
  845. PORT_PCR_MUX(2), 0,
  846. 0x1, 0
  847. };
  848. SPIClass SPI1((uintptr_t)&KINETISL_SPI1, (uintptr_t)&SPIClass::spi1_hardware);
  849. void SPIClass::begin()
  850. {
  851. volatile uint32_t *reg;
  852. hardware().clock_gate_register |= hardware().clock_gate_mask;
  853. port().C1 = SPI_C1_SPE | SPI_C1_MSTR;
  854. port().C2 = 0;
  855. uint8_t tmp __attribute__((unused)) = port().S;
  856. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  857. *reg = hardware().mosi_mux[mosi_pin_index];
  858. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  859. *reg = hardware().miso_mux[miso_pin_index];
  860. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  861. *reg = hardware().sck_mux[sck_pin_index];
  862. }
  863. void SPIClass::end() {
  864. volatile uint32_t *reg;
  865. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  866. *reg = 0;
  867. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  868. *reg = 0;
  869. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  870. *reg = 0;
  871. port().C1 = 0;
  872. }
  873. const uint16_t SPISettings::br_div_table[30] = {
  874. 2, 4, 6, 8, 10, 12, 14, 16, 20, 24,
  875. 28, 32, 40, 48, 56, 64, 80, 96, 112, 128,
  876. 160, 192, 224, 256, 320, 384, 448, 512, 640, 768,
  877. };
  878. const uint8_t SPISettings::br_clock_table[30] = {
  879. SPI_BR_SPPR(0) | SPI_BR_SPR(0),
  880. SPI_BR_SPPR(1) | SPI_BR_SPR(0),
  881. SPI_BR_SPPR(2) | SPI_BR_SPR(0),
  882. SPI_BR_SPPR(3) | SPI_BR_SPR(0),
  883. SPI_BR_SPPR(4) | SPI_BR_SPR(0),
  884. SPI_BR_SPPR(5) | SPI_BR_SPR(0),
  885. SPI_BR_SPPR(6) | SPI_BR_SPR(0),
  886. SPI_BR_SPPR(7) | SPI_BR_SPR(0),
  887. SPI_BR_SPPR(4) | SPI_BR_SPR(1),
  888. SPI_BR_SPPR(5) | SPI_BR_SPR(1),
  889. SPI_BR_SPPR(6) | SPI_BR_SPR(1),
  890. SPI_BR_SPPR(7) | SPI_BR_SPR(1),
  891. SPI_BR_SPPR(4) | SPI_BR_SPR(2),
  892. SPI_BR_SPPR(5) | SPI_BR_SPR(2),
  893. SPI_BR_SPPR(6) | SPI_BR_SPR(2),
  894. SPI_BR_SPPR(7) | SPI_BR_SPR(2),
  895. SPI_BR_SPPR(4) | SPI_BR_SPR(3),
  896. SPI_BR_SPPR(5) | SPI_BR_SPR(3),
  897. SPI_BR_SPPR(6) | SPI_BR_SPR(3),
  898. SPI_BR_SPPR(7) | SPI_BR_SPR(3),
  899. SPI_BR_SPPR(4) | SPI_BR_SPR(4),
  900. SPI_BR_SPPR(5) | SPI_BR_SPR(4),
  901. SPI_BR_SPPR(6) | SPI_BR_SPR(4),
  902. SPI_BR_SPPR(7) | SPI_BR_SPR(4),
  903. SPI_BR_SPPR(4) | SPI_BR_SPR(5),
  904. SPI_BR_SPPR(5) | SPI_BR_SPR(5),
  905. SPI_BR_SPPR(6) | SPI_BR_SPR(5),
  906. SPI_BR_SPPR(7) | SPI_BR_SPR(5),
  907. SPI_BR_SPPR(4) | SPI_BR_SPR(6),
  908. SPI_BR_SPPR(5) | SPI_BR_SPR(6)
  909. };
  910. void SPIClass::setMOSI(uint8_t pin)
  911. {
  912. if (pin != hardware().mosi_pin[mosi_pin_index]) {
  913. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  914. if (pin == hardware().mosi_pin[i] ) {
  915. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  916. volatile uint32_t *reg;
  917. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  918. *reg = 0;
  919. reg = portConfigRegister(hardware().mosi_pin[i]);
  920. *reg = hardware().mosi_mux[i];
  921. }
  922. mosi_pin_index = i;
  923. return;
  924. }
  925. }
  926. }
  927. }
  928. void SPIClass::setMISO(uint8_t pin)
  929. {
  930. if (pin != hardware().miso_pin[miso_pin_index]) {
  931. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  932. if (pin == hardware().miso_pin[i] ) {
  933. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  934. volatile uint32_t *reg;
  935. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  936. *reg = 0;
  937. reg = portConfigRegister(hardware().miso_pin[i]);
  938. *reg = hardware().miso_mux[i];
  939. }
  940. miso_pin_index = i;
  941. return;
  942. }
  943. }
  944. }
  945. }
  946. void SPIClass::setSCK(uint8_t pin)
  947. {
  948. if (pin != hardware().sck_pin[sck_pin_index]) {
  949. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  950. if (pin == hardware().sck_pin[i] ) {
  951. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  952. volatile uint32_t *reg;
  953. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  954. *reg = 0;
  955. reg = portConfigRegister(hardware().sck_pin[i]);
  956. *reg = hardware().sck_mux[i];
  957. }
  958. sck_pin_index = i;
  959. return;
  960. }
  961. }
  962. }
  963. }
  964. bool SPIClass::pinIsChipSelect(uint8_t pin)
  965. {
  966. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  967. if (pin == hardware().cs_pin[i]) return hardware().cs_mask[i];
  968. }
  969. return 0;
  970. }
  971. bool SPIClass::pinIsMOSI(uint8_t pin)
  972. {
  973. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  974. if (pin == hardware().mosi_pin[i]) return true;
  975. }
  976. return false;
  977. }
  978. bool SPIClass::pinIsMISO(uint8_t pin)
  979. {
  980. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  981. if (pin == hardware().miso_pin[i]) return true;
  982. }
  983. return false;
  984. }
  985. bool SPIClass::pinIsSCK(uint8_t pin)
  986. {
  987. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  988. if (pin == hardware().sck_pin[i]) return true;
  989. }
  990. return false;
  991. }
  992. // setCS() is not intended for use from normal Arduino programs/sketches.
  993. uint8_t SPIClass::setCS(uint8_t pin)
  994. {
  995. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  996. if (pin == hardware().cs_pin[i]) {
  997. volatile uint32_t *reg = portConfigRegister(pin);
  998. *reg = hardware().cs_mux[i];
  999. return hardware().cs_mask[i];
  1000. }
  1001. }
  1002. return 0;
  1003. }
  1004. void SPIClass::transfer(const void * buf, void * retbuf, size_t count) {
  1005. if (count == 0) return;
  1006. const uint8_t *p = (const uint8_t *)buf;
  1007. uint8_t *pret = (uint8_t *)retbuf;
  1008. uint8_t in;
  1009. while (!(port().S & SPI_S_SPTEF)) ; // wait
  1010. uint8_t out = p ? *p++ : _transferWriteFill;
  1011. port().DL = out;
  1012. while (--count > 0) {
  1013. if (p) {
  1014. out = *p++;
  1015. }
  1016. while (!(port().S & SPI_S_SPTEF)) ; // wait
  1017. __disable_irq();
  1018. port().DL = out;
  1019. while (!(port().S & SPI_S_SPRF)) ; // wait
  1020. in = port().DL;
  1021. __enable_irq();
  1022. if (pret)*pret++ = in;
  1023. }
  1024. while (!(port().S & SPI_S_SPRF)) ; // wait
  1025. in = port().DL;
  1026. if (pret)*pret = in;
  1027. }
  1028. //=============================================================================
  1029. // ASYNCH Support
  1030. //=============================================================================
  1031. //=========================================================================
  1032. // Try Transfer using DMA.
  1033. //=========================================================================
  1034. #ifdef SPI_HAS_TRANSFER_ASYNC
  1035. static uint8_t _dma_dummy_rx;
  1036. void SPIClass::dma_isr(void) {
  1037. // Serial.println("_spi_dma_rxISR");
  1038. _dmaRX->clearInterrupt();
  1039. port().C2 = 0;
  1040. uint8_t tmp __attribute__((unused)) = port().S;
  1041. _dmaTX->clearComplete();
  1042. _dmaRX->clearComplete();
  1043. _dma_state = DMAState::completed; // set back to 1 in case our call wants to start up dma again
  1044. _dma_event_responder->triggerEvent();
  1045. }
  1046. bool SPIClass::initDMAChannels() {
  1047. //Serial.println("First dma call"); Serial.flush();
  1048. _dmaTX = new DMAChannel();
  1049. if (_dmaTX == nullptr) {
  1050. return false;
  1051. }
  1052. _dmaTX->disable();
  1053. _dmaTX->destination((volatile uint8_t&)port().DL);
  1054. _dmaTX->disableOnCompletion();
  1055. _dmaTX->triggerAtHardwareEvent(hardware().tx_dma_channel);
  1056. _dmaRX = new DMAChannel();
  1057. if (_dmaRX == NULL) {
  1058. delete _dmaTX;
  1059. _dmaRX = nullptr;
  1060. return false;
  1061. }
  1062. _dmaRX->disable();
  1063. _dmaRX->source((volatile uint8_t&)port().DL);
  1064. _dmaRX->disableOnCompletion();
  1065. _dmaRX->triggerAtHardwareEvent(hardware().rx_dma_channel);
  1066. _dmaRX->attachInterrupt(hardware().dma_isr);
  1067. _dmaRX->interruptAtCompletion();
  1068. _dma_state = DMAState::idle; // Should be first thing set!
  1069. //Serial.println("end First dma call");
  1070. return true;
  1071. }
  1072. //=========================================================================
  1073. // Main Async Transfer function
  1074. //=========================================================================
  1075. bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) {
  1076. if (_dma_state == DMAState::notAllocated) {
  1077. if (!initDMAChannels()) {
  1078. return false;
  1079. }
  1080. }
  1081. if (_dma_state == DMAState::active)
  1082. return false; // already active
  1083. event_responder.clearEvent(); // Make sure it is not set yet
  1084. if (count < 2) {
  1085. // Use non-async version to simplify cases...
  1086. transfer(buf, retbuf, count);
  1087. event_responder.triggerEvent();
  1088. return true;
  1089. }
  1090. //_dmaTX->destination((volatile uint8_t&)port().DL);
  1091. //_dmaRX->source((volatile uint8_t&)port().DL);
  1092. _dmaTX->CFG->DCR = (_dmaTX->CFG->DCR & ~DMA_DCR_DSIZE(3)) | DMA_DCR_DSIZE(1);
  1093. _dmaRX->CFG->DCR = (_dmaRX->CFG->DCR & ~DMA_DCR_SSIZE(3)) | DMA_DCR_SSIZE(1); // 8 bit transfer
  1094. // Now see if the user passed in TX buffer to send.
  1095. uint8_t first_char;
  1096. if (buf) {
  1097. uint8_t *data_out = (uint8_t*)buf;
  1098. first_char = *data_out++;
  1099. _dmaTX->sourceBuffer(data_out, count-1);
  1100. } else {
  1101. first_char = (_transferWriteFill & 0xff);
  1102. _dmaTX->source((uint8_t&)_transferWriteFill); // maybe have setable value
  1103. _dmaTX->transferCount(count-1);
  1104. }
  1105. if (retbuf) {
  1106. _dmaRX->destinationBuffer((uint8_t*)retbuf, count);
  1107. } else {
  1108. _dmaRX->destination(_dma_dummy_rx); // NULL ?
  1109. _dmaRX->transferCount(count);
  1110. }
  1111. _dma_event_responder = &event_responder;
  1112. //Serial.println("Before DMA C2");
  1113. // Try pushing the first character
  1114. while (!(port().S & SPI_S_SPTEF));
  1115. port().DL = first_char;
  1116. port().C2 |= SPI_C2_TXDMAE | SPI_C2_RXDMAE;
  1117. // Now make sure SPI is enabled.
  1118. port().C1 |= SPI_C1_SPE;
  1119. _dmaRX->enable();
  1120. _dmaTX->enable();
  1121. _dma_state = DMAState::active;
  1122. return true;
  1123. }
  1124. #endif //SPI_HAS_TRANSFER_ASYNC
  1125. /**********************************************************/
  1126. /* 32 bit Teensy 4.x */
  1127. /**********************************************************/
  1128. #elif defined(__arm__) && defined(TEENSYDUINO) && (defined(__IMXRT1052__) || defined(__IMXRT1062__))
  1129. //#include "debug/printf.h"
  1130. void SPIClass::begin()
  1131. {
  1132. // CBCMR[LPSPI_CLK_SEL] - PLL2 = 528 MHz
  1133. // CBCMR[LPSPI_PODF] - div4 = 132 MHz
  1134. hardware->clock_gate_register &= ~hardware->clock_gate_mask;
  1135. CCM_CBCMR = (CCM_CBCMR & ~(CCM_CBCMR_LPSPI_PODF_MASK | CCM_CBCMR_LPSPI_CLK_SEL_MASK)) |
  1136. CCM_CBCMR_LPSPI_PODF(6) | CCM_CBCMR_LPSPI_CLK_SEL(2); // pg 714
  1137. uint32_t fastio = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
  1138. //uint32_t fastio = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
  1139. Serial.printf("SPI MISO: %d MOSI: %d, SCK: %d\n", hardware->miso_pin[miso_pin_index], hardware->mosi_pin[mosi_pin_index], hardware->sck_pin[sck_pin_index]);
  1140. *(portControlRegister(hardware->miso_pin[miso_pin_index])) = fastio;
  1141. *(portControlRegister(hardware->mosi_pin[mosi_pin_index])) = fastio;
  1142. *(portControlRegister(hardware->sck_pin[sck_pin_index])) = fastio;
  1143. //printf("CBCMR = %08lX\n", CCM_CBCMR);
  1144. hardware->clock_gate_register |= hardware->clock_gate_mask;
  1145. *(portConfigRegister(hardware->miso_pin[miso_pin_index])) = hardware->miso_mux[miso_pin_index];
  1146. *(portConfigRegister(hardware->mosi_pin [mosi_pin_index])) = hardware->mosi_mux[mosi_pin_index];
  1147. *(portConfigRegister(hardware->sck_pin [sck_pin_index])) = hardware->sck_mux[sck_pin_index];
  1148. //digitalWriteFast(10, HIGH);
  1149. //pinMode(10, OUTPUT);
  1150. //digitalWriteFast(10, HIGH);
  1151. port->CR = LPSPI_CR_RST;
  1152. // Lets initialize the Transmit FIFO watermark to FIFO size - 1...
  1153. // BUGBUG:: I assume queue of 16 for now...
  1154. port->FCR = LPSPI_FCR_TXWATER(15);
  1155. }
  1156. uint8_t SPIClass::pinIsChipSelect(uint8_t pin)
  1157. {
  1158. return 0;
  1159. }
  1160. bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  1161. {
  1162. uint8_t pin1_mask, pin2_mask;
  1163. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  1164. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  1165. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  1166. if ((pin1_mask & pin2_mask) != 0) return false;
  1167. return true;
  1168. }
  1169. bool SPIClass::pinIsMOSI(uint8_t pin)
  1170. {
  1171. for (unsigned int i = 0; i < sizeof(hardware->mosi_pin); i++) {
  1172. if (pin == hardware->mosi_pin[i]) return true;
  1173. }
  1174. return false;
  1175. }
  1176. bool SPIClass::pinIsMISO(uint8_t pin)
  1177. {
  1178. for (unsigned int i = 0; i < sizeof(hardware->miso_pin); i++) {
  1179. if (pin == hardware->miso_pin[i]) return true;
  1180. }
  1181. return false;
  1182. }
  1183. bool SPIClass::pinIsSCK(uint8_t pin)
  1184. {
  1185. for (unsigned int i = 0; i < sizeof(hardware->sck_pin); i++) {
  1186. if (pin == hardware->sck_pin[i]) return true;
  1187. }
  1188. return false;
  1189. }
  1190. // setCS() is not intended for use from normal Arduino programs/sketches.
  1191. uint8_t SPIClass::setCS(uint8_t pin)
  1192. {
  1193. /*
  1194. for (unsigned int i = 0; i < sizeof(hardware->cs_pin); i++) {
  1195. if (pin == hardware->cs_pin[i]) {
  1196. volatile uint32_t *reg = portConfigRegister(pin);
  1197. *reg = hardware->cs_mux[i];
  1198. return hardware->cs_mask[i];
  1199. }
  1200. } */
  1201. return 0;
  1202. }
  1203. void SPIClass::setMOSI(uint8_t pin)
  1204. {
  1205. // Currently only one defined so just return...
  1206. }
  1207. void SPIClass::setMISO(uint8_t pin)
  1208. {
  1209. // Currently only one defined so just return...
  1210. }
  1211. void SPIClass::setSCK(uint8_t pin)
  1212. {
  1213. // Currently only one defined so just return...
  1214. }
  1215. void SPIClass::setBitOrder(uint8_t bitOrder)
  1216. {
  1217. hardware->clock_gate_register |= hardware->clock_gate_mask;
  1218. if (bitOrder == LSBFIRST) {
  1219. port->TCR |= LPSPI_TCR_LSBF;
  1220. } else {
  1221. port->TCR &= ~LPSPI_TCR_LSBF;
  1222. }
  1223. }
  1224. void SPIClass::setDataMode(uint8_t dataMode)
  1225. {
  1226. hardware->clock_gate_register |= hardware->clock_gate_mask;
  1227. //SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  1228. }
  1229. const SPIClass::SPI_Hardware_t spiclass_lpspi4_hardware = {
  1230. CCM_CCGR1, CCM_CCGR1_LPSPI4(CCM_CCGR_ON),
  1231. 12,
  1232. 3 | 0x10,
  1233. 11,
  1234. 3 | 0x10,
  1235. 13,
  1236. 3 | 0x10,
  1237. 10,
  1238. 3 | 0x10,
  1239. };
  1240. SPIClass SPI(&IMXRT_LPSPI4_S, &spiclass_lpspi4_hardware);
  1241. void SPIClass::transfer(const void * buf, void * retbuf, size_t count)
  1242. {
  1243. if (count == 0) return;
  1244. uint8_t *p_write = (uint8_t*)buf;
  1245. uint8_t *p_read = (uint8_t*)retbuf;
  1246. size_t count_read = count;
  1247. // Pass 1 keep it simple and don't try packing 8 bits into 16 yet..
  1248. // Lets clear the reader queue
  1249. //port->CR = LPSPI_CR_RRF;
  1250. while (count > 0) {
  1251. // Push out the next byte;
  1252. port->TDR = p_write? *p_write++ : _transferWriteFill;
  1253. count--; // how many bytes left to output.
  1254. // Make sure queue is not full before pushing next byte out
  1255. do {
  1256. if ((port->RSR & LPSPI_RSR_RXEMPTY) == 0) {
  1257. uint8_t b = port->RDR; // Read any pending RX bytes in
  1258. if (p_read) *p_read++ = b;
  1259. count_read--;
  1260. }
  1261. } while ((port->SR & LPSPI_SR_TDF) == 0) ;
  1262. }
  1263. // now lets wait for all of the read bytes to be returned...
  1264. while (count_read) {
  1265. if ((port->RSR & LPSPI_RSR_RXEMPTY) == 0) {
  1266. uint8_t b = port->RDR; // Read any pending RX bytes in
  1267. if (p_read) *p_read++ = b;
  1268. count_read--;
  1269. }
  1270. }
  1271. }
  1272. #endif