PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

1928 行
56KB

  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. //#define DEBUG_DMA_TRANSFERS
  13. /**********************************************************/
  14. /* 8 bit AVR-based boards */
  15. /**********************************************************/
  16. #if defined(__AVR__)
  17. SPIClass SPI;
  18. uint8_t SPIClass::interruptMode = 0;
  19. uint8_t SPIClass::interruptMask = 0;
  20. uint8_t SPIClass::interruptSave = 0;
  21. #ifdef SPI_TRANSACTION_MISMATCH_LED
  22. uint8_t SPIClass::inTransactionFlag = 0;
  23. #endif
  24. uint8_t SPIClass::_transferWriteFill = 0;
  25. void SPIClass::begin()
  26. {
  27. // Set SS to high so a connected chip will be "deselected" by default
  28. digitalWrite(SS, HIGH);
  29. // When the SS pin is set as OUTPUT, it can be used as
  30. // a general purpose output port (it doesn't influence
  31. // SPI operations).
  32. pinMode(SS, OUTPUT);
  33. // Warning: if the SS pin ever becomes a LOW INPUT then SPI
  34. // automatically switches to Slave, so the data direction of
  35. // the SS pin MUST be kept as OUTPUT.
  36. SPCR |= _BV(MSTR);
  37. SPCR |= _BV(SPE);
  38. // Set direction register for SCK and MOSI pin.
  39. // MISO pin automatically overrides to INPUT.
  40. // By doing this AFTER enabling SPI, we avoid accidentally
  41. // clocking in a single bit since the lines go directly
  42. // from "input" to SPI control.
  43. // http://code.google.com/p/arduino/issues/detail?id=888
  44. pinMode(SCK, OUTPUT);
  45. pinMode(MOSI, OUTPUT);
  46. }
  47. void SPIClass::end() {
  48. SPCR &= ~_BV(SPE);
  49. }
  50. // mapping of interrupt numbers to bits within SPI_AVR_EIMSK
  51. #if defined(__AVR_ATmega32U4__)
  52. #define SPI_INT0_MASK (1<<INT0)
  53. #define SPI_INT1_MASK (1<<INT1)
  54. #define SPI_INT2_MASK (1<<INT2)
  55. #define SPI_INT3_MASK (1<<INT3)
  56. #define SPI_INT4_MASK (1<<INT6)
  57. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  58. #define SPI_INT0_MASK (1<<INT0)
  59. #define SPI_INT1_MASK (1<<INT1)
  60. #define SPI_INT2_MASK (1<<INT2)
  61. #define SPI_INT3_MASK (1<<INT3)
  62. #define SPI_INT4_MASK (1<<INT4)
  63. #define SPI_INT5_MASK (1<<INT5)
  64. #define SPI_INT6_MASK (1<<INT6)
  65. #define SPI_INT7_MASK (1<<INT7)
  66. #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
  67. #define SPI_INT0_MASK (1<<INT4)
  68. #define SPI_INT1_MASK (1<<INT5)
  69. #define SPI_INT2_MASK (1<<INT0)
  70. #define SPI_INT3_MASK (1<<INT1)
  71. #define SPI_INT4_MASK (1<<INT2)
  72. #define SPI_INT5_MASK (1<<INT3)
  73. #define SPI_INT6_MASK (1<<INT6)
  74. #define SPI_INT7_MASK (1<<INT7)
  75. #else
  76. #ifdef INT0
  77. #define SPI_INT0_MASK (1<<INT0)
  78. #endif
  79. #ifdef INT1
  80. #define SPI_INT1_MASK (1<<INT1)
  81. #endif
  82. #ifdef INT2
  83. #define SPI_INT2_MASK (1<<INT2)
  84. #endif
  85. #endif
  86. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  87. {
  88. uint8_t stmp, mask;
  89. if (interruptMode > 1) return;
  90. stmp = SREG;
  91. noInterrupts();
  92. switch (interruptNumber) {
  93. #ifdef SPI_INT0_MASK
  94. case 0: mask = SPI_INT0_MASK; break;
  95. #endif
  96. #ifdef SPI_INT1_MASK
  97. case 1: mask = SPI_INT1_MASK; break;
  98. #endif
  99. #ifdef SPI_INT2_MASK
  100. case 2: mask = SPI_INT2_MASK; break;
  101. #endif
  102. #ifdef SPI_INT3_MASK
  103. case 3: mask = SPI_INT3_MASK; break;
  104. #endif
  105. #ifdef SPI_INT4_MASK
  106. case 4: mask = SPI_INT4_MASK; break;
  107. #endif
  108. #ifdef SPI_INT5_MASK
  109. case 5: mask = SPI_INT5_MASK; break;
  110. #endif
  111. #ifdef SPI_INT6_MASK
  112. case 6: mask = SPI_INT6_MASK; break;
  113. #endif
  114. #ifdef SPI_INT7_MASK
  115. case 7: mask = SPI_INT7_MASK; break;
  116. #endif
  117. default:
  118. interruptMode = 2;
  119. SREG = stmp;
  120. return;
  121. }
  122. interruptMode = 1;
  123. interruptMask |= mask;
  124. SREG = stmp;
  125. }
  126. void SPIClass::transfer(const void * buf, void * retbuf, uint32_t count) {
  127. if (count == 0) return;
  128. const uint8_t *p = (const uint8_t *)buf;
  129. uint8_t *pret = (uint8_t *)retbuf;
  130. uint8_t in;
  131. uint8_t out = p ? *p++ : _transferWriteFill;
  132. SPDR = out;
  133. while (--count > 0) {
  134. if (p) {
  135. out = *p++;
  136. }
  137. while (!(SPSR & _BV(SPIF))) ;
  138. in = SPDR;
  139. SPDR = out;
  140. if (pret)*pret++ = in;
  141. }
  142. while (!(SPSR & _BV(SPIF))) ;
  143. in = SPDR;
  144. if (pret)*pret = in;
  145. }
  146. /**********************************************************/
  147. /* 32 bit Teensy 3.x */
  148. /**********************************************************/
  149. #elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISK)
  150. #if defined(KINETISK) && defined( SPI_HAS_TRANSFER_ASYNC)
  151. #ifndef TRANSFER_COUNT_FIXED
  152. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  153. // note does no validation of length...
  154. DMABaseClass::TCD_t *tcd = dmac->TCD;
  155. if (!(tcd->BITER & DMA_TCD_BITER_ELINK)) {
  156. tcd->BITER = len & 0x7fff;
  157. } else {
  158. tcd->BITER = (tcd->BITER & 0xFE00) | (len & 0x1ff);
  159. }
  160. tcd->CITER = tcd->BITER;
  161. }
  162. #else
  163. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  164. dmac->transferCount(len);
  165. }
  166. #endif
  167. #endif
  168. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  169. #ifdef SPI_HAS_TRANSFER_ASYNC
  170. void _spi_dma_rxISR0(void) {SPI.dma_rxisr();}
  171. #else
  172. void _spi_dma_rxISR0(void) {;}
  173. #endif
  174. const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = {
  175. SIM_SCGC6, SIM_SCGC6_SPI0, 4, IRQ_SPI0,
  176. 32767, DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX,
  177. _spi_dma_rxISR0,
  178. 12, 8,
  179. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  180. 11, 7,
  181. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  182. 13, 14,
  183. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  184. 10, 2, 9, 6, 20, 23, 21, 22, 15,
  185. 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),
  186. 0x1, 0x1, 0x2, 0x2, 0x4, 0x4, 0x8, 0x8, 0x10
  187. };
  188. SPIClass SPI((uintptr_t)&KINETISK_SPI0, (uintptr_t)&SPIClass::spi0_hardware);
  189. #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
  190. #ifdef SPI_HAS_TRANSFER_ASYNC
  191. void _spi_dma_rxISR0(void) {SPI.dma_rxisr();}
  192. void _spi_dma_rxISR1(void) {SPI1.dma_rxisr();}
  193. void _spi_dma_rxISR2(void) {SPI2.dma_rxisr();}
  194. #else
  195. void _spi_dma_rxISR0(void) {;}
  196. void _spi_dma_rxISR1(void) {;}
  197. void _spi_dma_rxISR2(void) {;}
  198. #endif
  199. const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = {
  200. SIM_SCGC6, SIM_SCGC6_SPI0, 4, IRQ_SPI0,
  201. 32767, DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX,
  202. _spi_dma_rxISR0,
  203. 12, 8, 39, 255,
  204. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0,
  205. 11, 7, 28, 255,
  206. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0,
  207. 13, 14, 27,
  208. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  209. 10, 2, 9, 6, 20, 23, 21, 22, 15, 26, 45,
  210. 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),
  211. 0x1, 0x1, 0x2, 0x2, 0x4, 0x4, 0x8, 0x8, 0x10, 0x1, 0x20
  212. };
  213. const SPIClass::SPI_Hardware_t SPIClass::spi1_hardware = {
  214. SIM_SCGC6, SIM_SCGC6_SPI1, 1, IRQ_SPI1,
  215. #if defined(__MK66FX1M0__)
  216. 32767, DMAMUX_SOURCE_SPI1_TX, DMAMUX_SOURCE_SPI1_RX,
  217. #else
  218. // T3.5 does not have good DMA support on 1 and 2
  219. 511, 0, DMAMUX_SOURCE_SPI1,
  220. #endif
  221. _spi_dma_rxISR1,
  222. 1, 5, 61, 59,
  223. PORT_PCR_MUX(2), PORT_PCR_MUX(7), PORT_PCR_MUX(2), PORT_PCR_MUX(7),
  224. 0, 21, 61, 59,
  225. PORT_PCR_MUX(2), PORT_PCR_MUX(7), PORT_PCR_MUX(7), PORT_PCR_MUX(2),
  226. 32, 20, 60,
  227. PORT_PCR_MUX(2), PORT_PCR_MUX(7), PORT_PCR_MUX(2),
  228. 6, 31, 58, 62, 63, 255, 255, 255, 255, 255, 255,
  229. 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,
  230. 0x1, 0x1, 0x2, 0x1, 0x4, 0, 0, 0, 0, 0, 0
  231. };
  232. const SPIClass::SPI_Hardware_t SPIClass::spi2_hardware = {
  233. SIM_SCGC3, SIM_SCGC3_SPI2, 1, IRQ_SPI2,
  234. #if defined(__MK66FX1M0__)
  235. 32767, DMAMUX_SOURCE_SPI2_TX, DMAMUX_SOURCE_SPI2_RX,
  236. #else
  237. // T3.5 does not have good DMA support on 1 and 2
  238. 511, 0, DMAMUX_SOURCE_SPI2,
  239. #endif
  240. _spi_dma_rxISR2,
  241. 45, 51, 255, 255,
  242. PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0,
  243. 44, 52, 255, 255,
  244. PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0,
  245. 46, 53, 255,
  246. PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0,
  247. 43, 54, 55, 255, 255, 255, 255, 255, 255, 255, 255,
  248. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0, 0, 0, 0, 0, 0, 0,
  249. 0x1, 0x2, 0x1, 0, 0, 0, 0, 0, 0, 0, 0
  250. };
  251. SPIClass SPI((uintptr_t)&KINETISK_SPI0, (uintptr_t)&SPIClass::spi0_hardware);
  252. SPIClass SPI1((uintptr_t)&KINETISK_SPI1, (uintptr_t)&SPIClass::spi1_hardware);
  253. SPIClass SPI2((uintptr_t)&KINETISK_SPI2, (uintptr_t)&SPIClass::spi2_hardware);
  254. #endif
  255. void SPIClass::begin()
  256. {
  257. volatile uint32_t *reg;
  258. hardware().clock_gate_register |= hardware().clock_gate_mask;
  259. port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  260. port().CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  261. port().CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  262. port().MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  263. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  264. *reg = hardware().mosi_mux[mosi_pin_index];
  265. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  266. *reg= hardware().miso_mux[miso_pin_index];
  267. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  268. *reg = hardware().sck_mux[sck_pin_index];
  269. }
  270. void SPIClass::end()
  271. {
  272. volatile uint32_t *reg;
  273. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  274. *reg = 0;
  275. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  276. *reg = 0;
  277. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  278. *reg = 0;
  279. port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  280. }
  281. void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName)
  282. {
  283. uint32_t n = (uint32_t)interruptName;
  284. if (n >= NVIC_NUM_INTERRUPTS) return;
  285. //Serial.print("usingInterrupt ");
  286. //Serial.println(n);
  287. interruptMasksUsed |= (1 << (n >> 5));
  288. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  289. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  290. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  291. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  292. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  293. }
  294. void SPIClass::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  295. {
  296. uint32_t n = (uint32_t)interruptName;
  297. if (n >= NVIC_NUM_INTERRUPTS) return;
  298. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  299. if (interruptMask[n >> 5] == 0) {
  300. interruptMasksUsed &= ~(1 << (n >> 5));
  301. }
  302. }
  303. const uint16_t SPISettings::ctar_div_table[23] = {
  304. 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40,
  305. 56, 64, 96, 128, 192, 256, 384, 512, 640, 768
  306. };
  307. const uint32_t SPISettings::ctar_clock_table[23] = {
  308. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  309. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  310. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  311. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  312. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  313. SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  314. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  315. SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  316. SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  317. SPI_CTAR_PBR(2) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(0),
  318. SPI_CTAR_PBR(1) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  319. SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(3),
  320. SPI_CTAR_PBR(2) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  321. SPI_CTAR_PBR(3) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  322. SPI_CTAR_PBR(0) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  323. SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  324. SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  325. SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  326. SPI_CTAR_PBR(0) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  327. SPI_CTAR_PBR(1) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  328. SPI_CTAR_PBR(0) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7),
  329. SPI_CTAR_PBR(2) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  330. SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7)
  331. };
  332. void SPIClass::updateCTAR(uint32_t ctar)
  333. {
  334. if (port().CTAR0 != ctar) {
  335. uint32_t mcr = port().MCR;
  336. if (mcr & SPI_MCR_MDIS) {
  337. port().CTAR0 = ctar;
  338. port().CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  339. } else {
  340. port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  341. port().CTAR0 = ctar;
  342. port().CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  343. port().MCR = mcr;
  344. }
  345. }
  346. }
  347. void SPIClass::setBitOrder(uint8_t bitOrder)
  348. {
  349. hardware().clock_gate_register |= hardware().clock_gate_mask;
  350. uint32_t ctar = port().CTAR0;
  351. if (bitOrder == LSBFIRST) {
  352. ctar |= SPI_CTAR_LSBFE;
  353. } else {
  354. ctar &= ~SPI_CTAR_LSBFE;
  355. }
  356. updateCTAR(ctar);
  357. }
  358. void SPIClass::setDataMode(uint8_t dataMode)
  359. {
  360. hardware().clock_gate_register |= hardware().clock_gate_mask;
  361. //uint32_t ctar = port().CTAR0;
  362. // TODO: implement with native code
  363. //SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  364. }
  365. void SPIClass::setClockDivider_noInline(uint32_t clk)
  366. {
  367. hardware().clock_gate_register |= hardware().clock_gate_mask;
  368. uint32_t ctar = port().CTAR0;
  369. ctar &= (SPI_CTAR_CPOL | SPI_CTAR_CPHA | SPI_CTAR_LSBFE);
  370. if (ctar & SPI_CTAR_CPHA) {
  371. clk = (clk & 0xFFFF0FFF) | ((clk & 0xF000) >> 4);
  372. }
  373. ctar |= clk;
  374. updateCTAR(ctar);
  375. }
  376. uint8_t SPIClass::pinIsChipSelect(uint8_t pin)
  377. {
  378. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  379. if (pin == hardware().cs_pin[i]) return hardware().cs_mask[i];
  380. }
  381. return 0;
  382. }
  383. bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  384. {
  385. uint8_t pin1_mask, pin2_mask;
  386. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  387. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  388. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  389. if ((pin1_mask & pin2_mask) != 0) return false;
  390. return true;
  391. }
  392. bool SPIClass::pinIsMOSI(uint8_t pin)
  393. {
  394. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  395. if (pin == hardware().mosi_pin[i]) return true;
  396. }
  397. return false;
  398. }
  399. bool SPIClass::pinIsMISO(uint8_t pin)
  400. {
  401. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  402. if (pin == hardware().miso_pin[i]) return true;
  403. }
  404. return false;
  405. }
  406. bool SPIClass::pinIsSCK(uint8_t pin)
  407. {
  408. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  409. if (pin == hardware().sck_pin[i]) return true;
  410. }
  411. return false;
  412. }
  413. // setCS() is not intended for use from normal Arduino programs/sketches.
  414. uint8_t SPIClass::setCS(uint8_t pin)
  415. {
  416. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  417. if (pin == hardware().cs_pin[i]) {
  418. volatile uint32_t *reg = portConfigRegister(pin);
  419. *reg = hardware().cs_mux[i];
  420. return hardware().cs_mask[i];
  421. }
  422. }
  423. return 0;
  424. }
  425. void SPIClass::setMOSI(uint8_t pin)
  426. {
  427. if (hardware_addr == (uintptr_t)&spi0_hardware) {
  428. SPCR.setMOSI_soft(pin);
  429. }
  430. if (pin != hardware().mosi_pin[mosi_pin_index]) {
  431. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  432. if (pin == hardware().mosi_pin[i]) {
  433. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  434. volatile uint32_t *reg;
  435. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  436. *reg = 0;
  437. reg = portConfigRegister(hardware().mosi_pin[i]);
  438. *reg = hardware().mosi_mux[i];
  439. }
  440. mosi_pin_index = i;
  441. return;
  442. }
  443. }
  444. }
  445. }
  446. void SPIClass::setMISO(uint8_t pin)
  447. {
  448. if (hardware_addr == (uintptr_t)&spi0_hardware) {
  449. SPCR.setMISO_soft(pin);
  450. }
  451. if (pin != hardware().miso_pin[miso_pin_index]) {
  452. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  453. if (pin == hardware().miso_pin[i]) {
  454. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  455. volatile uint32_t *reg;
  456. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  457. *reg = 0;
  458. reg = portConfigRegister(hardware().miso_pin[i]);
  459. *reg = hardware().miso_mux[i];
  460. }
  461. miso_pin_index = i;
  462. return;
  463. }
  464. }
  465. }
  466. }
  467. void SPIClass::setSCK(uint8_t pin)
  468. {
  469. if (hardware_addr == (uintptr_t)&spi0_hardware) {
  470. SPCR.setSCK_soft(pin);
  471. }
  472. if (pin != hardware().sck_pin[sck_pin_index]) {
  473. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  474. if (pin == hardware().sck_pin[i]) {
  475. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  476. volatile uint32_t *reg;
  477. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  478. *reg = 0;
  479. reg = portConfigRegister(hardware().sck_pin[i]);
  480. *reg = hardware().sck_mux[i];
  481. }
  482. sck_pin_index = i;
  483. return;
  484. }
  485. }
  486. }
  487. }
  488. void SPIClass::transfer(const void * buf, void * retbuf, size_t count)
  489. {
  490. if (count == 0) return;
  491. if (!(port().CTAR0 & SPI_CTAR_LSBFE)) {
  492. // We are doing the standard MSB order
  493. const uint8_t *p_write = (const uint8_t *)buf;
  494. uint8_t *p_read = (uint8_t *)retbuf;
  495. size_t count_read = count;
  496. // Lets clear the reader queue
  497. port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  498. uint32_t sr;
  499. // Now lets loop while we still have data to output
  500. if (count & 1) {
  501. if (p_write) {
  502. if (count > 1)
  503. port().PUSHR = *p_write++ | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  504. else
  505. port().PUSHR = *p_write++ | SPI_PUSHR_CTAS(0);
  506. } else {
  507. if (count > 1)
  508. port().PUSHR = _transferWriteFill | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  509. else
  510. port().PUSHR = _transferWriteFill | SPI_PUSHR_CTAS(0);
  511. }
  512. count--;
  513. }
  514. uint16_t w = (uint16_t)(_transferWriteFill << 8) | _transferWriteFill;
  515. while (count > 0) {
  516. // Push out the next byte;
  517. if (p_write) {
  518. w = (*p_write++) << 8;
  519. w |= *p_write++;
  520. }
  521. uint16_t queue_full_status_mask = (hardware().queue_size-1) << 12;
  522. if (count == 2)
  523. port().PUSHR = w | SPI_PUSHR_CTAS(1);
  524. else
  525. port().PUSHR = w | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1);
  526. count -= 2; // how many bytes to output.
  527. // Make sure queue is not full before pushing next byte out
  528. do {
  529. sr = port().SR;
  530. if (sr & 0xF0) {
  531. uint16_t w = port().POPR; // Read any pending RX bytes in
  532. if (count_read & 1) {
  533. if (p_read) {
  534. *p_read++ = w; // Read any pending RX bytes in
  535. }
  536. count_read--;
  537. } else {
  538. if (p_read) {
  539. *p_read++ = w >> 8;
  540. *p_read++ = (w & 0xff);
  541. }
  542. count_read -= 2;
  543. }
  544. }
  545. } while ((sr & (15 << 12)) > queue_full_status_mask);
  546. }
  547. // now lets wait for all of the read bytes to be returned...
  548. while (count_read) {
  549. sr = port().SR;
  550. if (sr & 0xF0) {
  551. uint16_t w = port().POPR; // Read any pending RX bytes in
  552. if (count_read & 1) {
  553. if (p_read)
  554. *p_read++ = w; // Read any pending RX bytes in
  555. count_read--;
  556. } else {
  557. if (p_read) {
  558. *p_read++ = w >> 8;
  559. *p_read++ = (w & 0xff);
  560. }
  561. count_read -= 2;
  562. }
  563. }
  564. }
  565. } else {
  566. // We are doing the less ofen LSB mode
  567. const uint8_t *p_write = (const uint8_t *)buf;
  568. uint8_t *p_read = (uint8_t *)retbuf;
  569. size_t count_read = count;
  570. // Lets clear the reader queue
  571. port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  572. uint32_t sr;
  573. // Now lets loop while we still have data to output
  574. if (count & 1) {
  575. if (p_write) {
  576. if (count > 1)
  577. port().PUSHR = *p_write++ | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  578. else
  579. port().PUSHR = *p_write++ | SPI_PUSHR_CTAS(0);
  580. } else {
  581. if (count > 1)
  582. port().PUSHR = _transferWriteFill | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  583. else
  584. port().PUSHR = _transferWriteFill | SPI_PUSHR_CTAS(0);
  585. }
  586. count--;
  587. }
  588. uint16_t w = _transferWriteFill;
  589. while (count > 0) {
  590. // Push out the next byte;
  591. if (p_write) {
  592. w = *p_write++;
  593. w |= ((*p_write++) << 8);
  594. }
  595. uint16_t queue_full_status_mask = (hardware().queue_size-1) << 12;
  596. if (count == 2)
  597. port().PUSHR = w | SPI_PUSHR_CTAS(1);
  598. else
  599. port().PUSHR = w | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1);
  600. count -= 2; // how many bytes to output.
  601. // Make sure queue is not full before pushing next byte out
  602. do {
  603. sr = port().SR;
  604. if (sr & 0xF0) {
  605. uint16_t w = port().POPR; // Read any pending RX bytes in
  606. if (count_read & 1) {
  607. if (p_read) {
  608. *p_read++ = w; // Read any pending RX bytes in
  609. }
  610. count_read--;
  611. } else {
  612. if (p_read) {
  613. *p_read++ = (w & 0xff);
  614. *p_read++ = w >> 8;
  615. }
  616. count_read -= 2;
  617. }
  618. }
  619. } while ((sr & (15 << 12)) > queue_full_status_mask);
  620. }
  621. // now lets wait for all of the read bytes to be returned...
  622. while (count_read) {
  623. sr = port().SR;
  624. if (sr & 0xF0) {
  625. uint16_t w = port().POPR; // Read any pending RX bytes in
  626. if (count_read & 1) {
  627. if (p_read)
  628. *p_read++ = w; // Read any pending RX bytes in
  629. count_read--;
  630. } else {
  631. if (p_read) {
  632. *p_read++ = (w & 0xff);
  633. *p_read++ = w >> 8;
  634. }
  635. count_read -= 2;
  636. }
  637. }
  638. }
  639. }
  640. }
  641. //=============================================================================
  642. // ASYNCH Support
  643. //=============================================================================
  644. //=========================================================================
  645. // Try Transfer using DMA.
  646. //=========================================================================
  647. #ifdef SPI_HAS_TRANSFER_ASYNC
  648. static uint8_t bit_bucket;
  649. #define dontInterruptAtCompletion(dmac) (dmac)->TCD->CSR &= ~DMA_TCD_CSR_INTMAJOR
  650. //=========================================================================
  651. // Init the DMA channels
  652. //=========================================================================
  653. bool SPIClass::initDMAChannels() {
  654. // Allocate our channels.
  655. _dmaTX = new DMAChannel();
  656. if (_dmaTX == nullptr) {
  657. return false;
  658. }
  659. _dmaRX = new DMAChannel();
  660. if (_dmaRX == nullptr) {
  661. delete _dmaTX; // release it
  662. _dmaTX = nullptr;
  663. return false;
  664. }
  665. // Let's setup the RX chain
  666. _dmaRX->disable();
  667. _dmaRX->source((volatile uint8_t&)port().POPR);
  668. _dmaRX->disableOnCompletion();
  669. _dmaRX->triggerAtHardwareEvent(hardware().rx_dma_channel);
  670. _dmaRX->attachInterrupt(hardware().dma_rxisr);
  671. _dmaRX->interruptAtCompletion();
  672. // We may be using settings chain here so lets set it up.
  673. // Now lets setup TX chain. Note if trigger TX is not set
  674. // we need to have the RX do it for us.
  675. _dmaTX->disable();
  676. _dmaTX->destination((volatile uint8_t&)port().PUSHR);
  677. _dmaTX->disableOnCompletion();
  678. if (hardware().tx_dma_channel) {
  679. _dmaTX->triggerAtHardwareEvent(hardware().tx_dma_channel);
  680. } else {
  681. // Serial.printf("SPI InitDMA tx triger by RX: %x\n", (uint32_t)_dmaRX);
  682. _dmaTX->triggerAtTransfersOf(*_dmaRX);
  683. }
  684. _dma_state = DMAState::idle; // Should be first thing set!
  685. return true;
  686. }
  687. //=========================================================================
  688. // Main Async Transfer function
  689. //=========================================================================
  690. bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) {
  691. uint8_t dma_first_byte;
  692. if (_dma_state == DMAState::notAllocated) {
  693. if (!initDMAChannels())
  694. return false;
  695. }
  696. if (_dma_state == DMAState::active)
  697. return false; // already active
  698. event_responder.clearEvent(); // Make sure it is not set yet
  699. if (count < 2) {
  700. // Use non-async version to simplify cases...
  701. transfer(buf, retbuf, count);
  702. event_responder.triggerEvent();
  703. return true;
  704. }
  705. // Now handle the cases where the count > then how many we can output in one DMA request
  706. if (count > hardware().max_dma_count) {
  707. _dma_count_remaining = count - hardware().max_dma_count;
  708. count = hardware().max_dma_count;
  709. } else {
  710. _dma_count_remaining = 0;
  711. }
  712. // Now See if caller passed in a source buffer.
  713. _dmaTX->TCD->ATTR_DST = 0; // Make sure set for 8 bit mode
  714. uint8_t *write_data = (uint8_t*) buf;
  715. if (buf) {
  716. dma_first_byte = *write_data;
  717. _dmaTX->sourceBuffer((uint8_t*)write_data+1, count-1);
  718. _dmaTX->TCD->SLAST = 0; // Finish with it pointing to next location
  719. } else {
  720. dma_first_byte = _transferWriteFill;
  721. _dmaTX->source((uint8_t&)_transferWriteFill); // maybe have setable value
  722. DMAChanneltransferCount(_dmaTX, count-1);
  723. }
  724. if (retbuf) {
  725. // On T3.5 must handle SPI1/2 differently as only one DMA channel
  726. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  727. _dmaRX->destinationBuffer((uint8_t*)retbuf, count);
  728. _dmaRX->TCD->DLASTSGA = 0; // At end point after our bufffer
  729. } else {
  730. // Write only mode
  731. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  732. _dmaRX->destination((uint8_t&)bit_bucket);
  733. DMAChanneltransferCount(_dmaRX, count);
  734. }
  735. _dma_event_responder = &event_responder;
  736. // Now try to start it?
  737. // Setup DMA main object
  738. yield();
  739. port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_CLR_TXF | SPI_MCR_PCSIS(0x1F);
  740. port().SR = 0xFF0F0000;
  741. // Lets try to output the first byte to make sure that we are in 8 bit mode...
  742. port().PUSHR = dma_first_byte | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
  743. if (hardware().tx_dma_channel) {
  744. port().RSER = SPI_RSER_RFDF_RE | SPI_RSER_RFDF_DIRS | SPI_RSER_TFFF_RE | SPI_RSER_TFFF_DIRS;
  745. _dmaRX->enable();
  746. // Get the initial settings.
  747. _dmaTX->enable();
  748. } else {
  749. //T3.5 SP1 and SPI2 - TX is not triggered by SPI but by RX...
  750. port().RSER = SPI_RSER_RFDF_RE | SPI_RSER_RFDF_DIRS ;
  751. _dmaTX->triggerAtTransfersOf(*_dmaRX);
  752. _dmaTX->enable();
  753. _dmaRX->enable();
  754. }
  755. _dma_state = DMAState::active;
  756. return true;
  757. }
  758. //-------------------------------------------------------------------------
  759. // DMA RX ISR
  760. //-------------------------------------------------------------------------
  761. void SPIClass::dma_rxisr(void) {
  762. _dmaRX->clearInterrupt();
  763. _dmaTX->clearComplete();
  764. _dmaRX->clearComplete();
  765. uint8_t should_reenable_tx = true; // should we re-enable TX maybe not if count will be 0...
  766. if (_dma_count_remaining) {
  767. // What do I need to do to start it back up again...
  768. // We will use the BITR/CITR from RX as TX may have prefed some stuff
  769. if (_dma_count_remaining > hardware().max_dma_count) {
  770. _dma_count_remaining -= hardware().max_dma_count;
  771. } else {
  772. DMAChanneltransferCount(_dmaTX, _dma_count_remaining-1);
  773. DMAChanneltransferCount(_dmaRX, _dma_count_remaining);
  774. if (_dma_count_remaining == 1) should_reenable_tx = false;
  775. _dma_count_remaining = 0;
  776. }
  777. // In some cases we need to again start the TX manually to get it to work...
  778. if (_dmaTX->TCD->SADDR == &_transferWriteFill) {
  779. if (port().CTAR0 & SPI_CTAR_FMSZ(8)) {
  780. port().PUSHR = (_transferWriteFill | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  781. } else {
  782. port().PUSHR = (_transferWriteFill | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  783. }
  784. } else {
  785. if (port().CTAR0 & SPI_CTAR_FMSZ(8)) {
  786. // 16 bit mode
  787. uint16_t w = *((uint16_t*)_dmaTX->TCD->SADDR);
  788. _dmaTX->TCD->SADDR = (volatile uint8_t*)(_dmaTX->TCD->SADDR) + 2;
  789. port().PUSHR = (w | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  790. } else {
  791. uint8_t w = *((uint8_t*)_dmaTX->TCD->SADDR);
  792. _dmaTX->TCD->SADDR = (volatile uint8_t*)(_dmaTX->TCD->SADDR) + 1;
  793. port().PUSHR = (w | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  794. }
  795. }
  796. _dmaRX->enable();
  797. if (should_reenable_tx)
  798. _dmaTX->enable();
  799. } else {
  800. port().RSER = 0;
  801. //port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); // clear out the queue
  802. port().SR = 0xFF0F0000;
  803. port().CTAR0 &= ~(SPI_CTAR_FMSZ(8)); // Hack restore back to 8 bits
  804. _dma_state = DMAState::completed; // set back to 1 in case our call wants to start up dma again
  805. _dma_event_responder->triggerEvent();
  806. }
  807. }
  808. #endif // SPI_HAS_TRANSFER_ASYNC
  809. /**********************************************************/
  810. /* 32 bit Teensy-LC */
  811. /**********************************************************/
  812. #elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISL)
  813. #ifdef SPI_HAS_TRANSFER_ASYNC
  814. void _spi_dma_rxISR0(void) {SPI.dma_isr();}
  815. void _spi_dma_rxISR1(void) {SPI1.dma_isr();}
  816. #else
  817. void _spi_dma_rxISR0(void) {;}
  818. void _spi_dma_rxISR1(void) {;}
  819. #endif
  820. const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = {
  821. SIM_SCGC4, SIM_SCGC4_SPI0,
  822. 0, // BR index 0
  823. DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX, _spi_dma_rxISR0,
  824. 12, 8,
  825. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  826. 11, 7,
  827. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  828. 13, 14,
  829. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  830. 10, 2,
  831. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  832. 0x1, 0x1
  833. };
  834. SPIClass SPI((uintptr_t)&KINETISL_SPI0, (uintptr_t)&SPIClass::spi0_hardware);
  835. const SPIClass::SPI_Hardware_t SPIClass::spi1_hardware = {
  836. SIM_SCGC4, SIM_SCGC4_SPI1,
  837. 1, // BR index 1 in SPI Settings
  838. DMAMUX_SOURCE_SPI1_TX, DMAMUX_SOURCE_SPI1_RX, _spi_dma_rxISR1,
  839. 1, 5,
  840. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  841. 0, 21,
  842. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  843. 20, 255,
  844. PORT_PCR_MUX(2), 0,
  845. 6, 255,
  846. PORT_PCR_MUX(2), 0,
  847. 0x1, 0
  848. };
  849. SPIClass SPI1((uintptr_t)&KINETISL_SPI1, (uintptr_t)&SPIClass::spi1_hardware);
  850. void SPIClass::begin()
  851. {
  852. volatile uint32_t *reg;
  853. hardware().clock_gate_register |= hardware().clock_gate_mask;
  854. port().C1 = SPI_C1_SPE | SPI_C1_MSTR;
  855. port().C2 = 0;
  856. uint8_t tmp __attribute__((unused)) = port().S;
  857. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  858. *reg = hardware().mosi_mux[mosi_pin_index];
  859. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  860. *reg = hardware().miso_mux[miso_pin_index];
  861. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  862. *reg = hardware().sck_mux[sck_pin_index];
  863. }
  864. void SPIClass::end() {
  865. volatile uint32_t *reg;
  866. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  867. *reg = 0;
  868. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  869. *reg = 0;
  870. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  871. *reg = 0;
  872. port().C1 = 0;
  873. }
  874. const uint16_t SPISettings::br_div_table[30] = {
  875. 2, 4, 6, 8, 10, 12, 14, 16, 20, 24,
  876. 28, 32, 40, 48, 56, 64, 80, 96, 112, 128,
  877. 160, 192, 224, 256, 320, 384, 448, 512, 640, 768,
  878. };
  879. const uint8_t SPISettings::br_clock_table[30] = {
  880. SPI_BR_SPPR(0) | SPI_BR_SPR(0),
  881. SPI_BR_SPPR(1) | SPI_BR_SPR(0),
  882. SPI_BR_SPPR(2) | SPI_BR_SPR(0),
  883. SPI_BR_SPPR(3) | SPI_BR_SPR(0),
  884. SPI_BR_SPPR(4) | SPI_BR_SPR(0),
  885. SPI_BR_SPPR(5) | SPI_BR_SPR(0),
  886. SPI_BR_SPPR(6) | SPI_BR_SPR(0),
  887. SPI_BR_SPPR(7) | SPI_BR_SPR(0),
  888. SPI_BR_SPPR(4) | SPI_BR_SPR(1),
  889. SPI_BR_SPPR(5) | SPI_BR_SPR(1),
  890. SPI_BR_SPPR(6) | SPI_BR_SPR(1),
  891. SPI_BR_SPPR(7) | SPI_BR_SPR(1),
  892. SPI_BR_SPPR(4) | SPI_BR_SPR(2),
  893. SPI_BR_SPPR(5) | SPI_BR_SPR(2),
  894. SPI_BR_SPPR(6) | SPI_BR_SPR(2),
  895. SPI_BR_SPPR(7) | SPI_BR_SPR(2),
  896. SPI_BR_SPPR(4) | SPI_BR_SPR(3),
  897. SPI_BR_SPPR(5) | SPI_BR_SPR(3),
  898. SPI_BR_SPPR(6) | SPI_BR_SPR(3),
  899. SPI_BR_SPPR(7) | SPI_BR_SPR(3),
  900. SPI_BR_SPPR(4) | SPI_BR_SPR(4),
  901. SPI_BR_SPPR(5) | SPI_BR_SPR(4),
  902. SPI_BR_SPPR(6) | SPI_BR_SPR(4),
  903. SPI_BR_SPPR(7) | SPI_BR_SPR(4),
  904. SPI_BR_SPPR(4) | SPI_BR_SPR(5),
  905. SPI_BR_SPPR(5) | SPI_BR_SPR(5),
  906. SPI_BR_SPPR(6) | SPI_BR_SPR(5),
  907. SPI_BR_SPPR(7) | SPI_BR_SPR(5),
  908. SPI_BR_SPPR(4) | SPI_BR_SPR(6),
  909. SPI_BR_SPPR(5) | SPI_BR_SPR(6)
  910. };
  911. void SPIClass::setMOSI(uint8_t pin)
  912. {
  913. if (pin != hardware().mosi_pin[mosi_pin_index]) {
  914. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  915. if (pin == hardware().mosi_pin[i] ) {
  916. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  917. volatile uint32_t *reg;
  918. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  919. *reg = 0;
  920. reg = portConfigRegister(hardware().mosi_pin[i]);
  921. *reg = hardware().mosi_mux[i];
  922. }
  923. mosi_pin_index = i;
  924. return;
  925. }
  926. }
  927. }
  928. }
  929. void SPIClass::setMISO(uint8_t pin)
  930. {
  931. if (pin != hardware().miso_pin[miso_pin_index]) {
  932. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  933. if (pin == hardware().miso_pin[i] ) {
  934. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  935. volatile uint32_t *reg;
  936. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  937. *reg = 0;
  938. reg = portConfigRegister(hardware().miso_pin[i]);
  939. *reg = hardware().miso_mux[i];
  940. }
  941. miso_pin_index = i;
  942. return;
  943. }
  944. }
  945. }
  946. }
  947. void SPIClass::setSCK(uint8_t pin)
  948. {
  949. if (pin != hardware().sck_pin[sck_pin_index]) {
  950. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  951. if (pin == hardware().sck_pin[i] ) {
  952. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  953. volatile uint32_t *reg;
  954. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  955. *reg = 0;
  956. reg = portConfigRegister(hardware().sck_pin[i]);
  957. *reg = hardware().sck_mux[i];
  958. }
  959. sck_pin_index = i;
  960. return;
  961. }
  962. }
  963. }
  964. }
  965. bool SPIClass::pinIsChipSelect(uint8_t pin)
  966. {
  967. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  968. if (pin == hardware().cs_pin[i]) return hardware().cs_mask[i];
  969. }
  970. return 0;
  971. }
  972. bool SPIClass::pinIsMOSI(uint8_t pin)
  973. {
  974. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  975. if (pin == hardware().mosi_pin[i]) return true;
  976. }
  977. return false;
  978. }
  979. bool SPIClass::pinIsMISO(uint8_t pin)
  980. {
  981. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  982. if (pin == hardware().miso_pin[i]) return true;
  983. }
  984. return false;
  985. }
  986. bool SPIClass::pinIsSCK(uint8_t pin)
  987. {
  988. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  989. if (pin == hardware().sck_pin[i]) return true;
  990. }
  991. return false;
  992. }
  993. // setCS() is not intended for use from normal Arduino programs/sketches.
  994. uint8_t SPIClass::setCS(uint8_t pin)
  995. {
  996. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  997. if (pin == hardware().cs_pin[i]) {
  998. volatile uint32_t *reg = portConfigRegister(pin);
  999. *reg = hardware().cs_mux[i];
  1000. return hardware().cs_mask[i];
  1001. }
  1002. }
  1003. return 0;
  1004. }
  1005. void SPIClass::transfer(const void * buf, void * retbuf, size_t count) {
  1006. if (count == 0) return;
  1007. const uint8_t *p = (const uint8_t *)buf;
  1008. uint8_t *pret = (uint8_t *)retbuf;
  1009. uint8_t in;
  1010. while (!(port().S & SPI_S_SPTEF)) ; // wait
  1011. uint8_t out = p ? *p++ : _transferWriteFill;
  1012. port().DL = out;
  1013. while (--count > 0) {
  1014. if (p) {
  1015. out = *p++;
  1016. }
  1017. while (!(port().S & SPI_S_SPTEF)) ; // wait
  1018. __disable_irq();
  1019. port().DL = out;
  1020. while (!(port().S & SPI_S_SPRF)) ; // wait
  1021. in = port().DL;
  1022. __enable_irq();
  1023. if (pret)*pret++ = in;
  1024. }
  1025. while (!(port().S & SPI_S_SPRF)) ; // wait
  1026. in = port().DL;
  1027. if (pret)*pret = in;
  1028. }
  1029. //=============================================================================
  1030. // ASYNCH Support
  1031. //=============================================================================
  1032. //=========================================================================
  1033. // Try Transfer using DMA.
  1034. //=========================================================================
  1035. #ifdef SPI_HAS_TRANSFER_ASYNC
  1036. static uint8_t _dma_dummy_rx;
  1037. void SPIClass::dma_isr(void) {
  1038. // Serial.println("_spi_dma_rxISR");
  1039. _dmaRX->clearInterrupt();
  1040. port().C2 = 0;
  1041. uint8_t tmp __attribute__((unused)) = port().S;
  1042. _dmaTX->clearComplete();
  1043. _dmaRX->clearComplete();
  1044. _dma_state = DMAState::completed; // set back to 1 in case our call wants to start up dma again
  1045. _dma_event_responder->triggerEvent();
  1046. }
  1047. bool SPIClass::initDMAChannels() {
  1048. //Serial.println("First dma call"); Serial.flush();
  1049. _dmaTX = new DMAChannel();
  1050. if (_dmaTX == nullptr) {
  1051. return false;
  1052. }
  1053. _dmaTX->disable();
  1054. _dmaTX->destination((volatile uint8_t&)port().DL);
  1055. _dmaTX->disableOnCompletion();
  1056. _dmaTX->triggerAtHardwareEvent(hardware().tx_dma_channel);
  1057. _dmaRX = new DMAChannel();
  1058. if (_dmaRX == NULL) {
  1059. delete _dmaTX;
  1060. _dmaRX = nullptr;
  1061. return false;
  1062. }
  1063. _dmaRX->disable();
  1064. _dmaRX->source((volatile uint8_t&)port().DL);
  1065. _dmaRX->disableOnCompletion();
  1066. _dmaRX->triggerAtHardwareEvent(hardware().rx_dma_channel);
  1067. _dmaRX->attachInterrupt(hardware().dma_isr);
  1068. _dmaRX->interruptAtCompletion();
  1069. _dma_state = DMAState::idle; // Should be first thing set!
  1070. //Serial.println("end First dma call");
  1071. return true;
  1072. }
  1073. //=========================================================================
  1074. // Main Async Transfer function
  1075. //=========================================================================
  1076. bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) {
  1077. if (_dma_state == DMAState::notAllocated) {
  1078. if (!initDMAChannels()) {
  1079. return false;
  1080. }
  1081. }
  1082. if (_dma_state == DMAState::active)
  1083. return false; // already active
  1084. event_responder.clearEvent(); // Make sure it is not set yet
  1085. if (count < 2) {
  1086. // Use non-async version to simplify cases...
  1087. transfer(buf, retbuf, count);
  1088. event_responder.triggerEvent();
  1089. return true;
  1090. }
  1091. //_dmaTX->destination((volatile uint8_t&)port().DL);
  1092. //_dmaRX->source((volatile uint8_t&)port().DL);
  1093. _dmaTX->CFG->DCR = (_dmaTX->CFG->DCR & ~DMA_DCR_DSIZE(3)) | DMA_DCR_DSIZE(1);
  1094. _dmaRX->CFG->DCR = (_dmaRX->CFG->DCR & ~DMA_DCR_SSIZE(3)) | DMA_DCR_SSIZE(1); // 8 bit transfer
  1095. // Now see if the user passed in TX buffer to send.
  1096. uint8_t first_char;
  1097. if (buf) {
  1098. uint8_t *data_out = (uint8_t*)buf;
  1099. first_char = *data_out++;
  1100. _dmaTX->sourceBuffer(data_out, count-1);
  1101. } else {
  1102. first_char = (_transferWriteFill & 0xff);
  1103. _dmaTX->source((uint8_t&)_transferWriteFill); // maybe have setable value
  1104. _dmaTX->transferCount(count-1);
  1105. }
  1106. if (retbuf) {
  1107. _dmaRX->destinationBuffer((uint8_t*)retbuf, count);
  1108. } else {
  1109. _dmaRX->destination(_dma_dummy_rx); // NULL ?
  1110. _dmaRX->transferCount(count);
  1111. }
  1112. _dma_event_responder = &event_responder;
  1113. //Serial.println("Before DMA C2");
  1114. // Try pushing the first character
  1115. while (!(port().S & SPI_S_SPTEF));
  1116. port().DL = first_char;
  1117. port().C2 |= SPI_C2_TXDMAE | SPI_C2_RXDMAE;
  1118. // Now make sure SPI is enabled.
  1119. port().C1 |= SPI_C1_SPE;
  1120. _dmaRX->enable();
  1121. _dmaTX->enable();
  1122. _dma_state = DMAState::active;
  1123. return true;
  1124. }
  1125. #endif //SPI_HAS_TRANSFER_ASYNC
  1126. /**********************************************************/
  1127. /* 32 bit Teensy 4.x */
  1128. /**********************************************************/
  1129. #elif defined(__arm__) && defined(TEENSYDUINO) && (defined(__IMXRT1052__) || defined(__IMXRT1062__))
  1130. //#include "debug/printf.h"
  1131. void SPIClass::begin()
  1132. {
  1133. // CBCMR[LPSPI_CLK_SEL] - PLL2 = 528 MHz
  1134. // CBCMR[LPSPI_PODF] - div4 = 132 MHz
  1135. hardware().clock_gate_register &= ~hardware().clock_gate_mask;
  1136. CCM_CBCMR = (CCM_CBCMR & ~(CCM_CBCMR_LPSPI_PODF_MASK | CCM_CBCMR_LPSPI_CLK_SEL_MASK)) |
  1137. CCM_CBCMR_LPSPI_PODF(2) | CCM_CBCMR_LPSPI_CLK_SEL(1); // pg 714
  1138. // CCM_CBCMR_LPSPI_PODF(6) | CCM_CBCMR_LPSPI_CLK_SEL(2); // pg 714
  1139. uint32_t fastio = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_SPEED(2);
  1140. //uint32_t fastio = IOMUXC_PAD_DSE(6) | IOMUXC_PAD_SPEED(1);
  1141. //uint32_t fastio = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
  1142. //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]);
  1143. *(portControlRegister(hardware().miso_pin[miso_pin_index])) = fastio;
  1144. *(portControlRegister(hardware().mosi_pin[mosi_pin_index])) = fastio;
  1145. *(portControlRegister(hardware().sck_pin[sck_pin_index])) = fastio;
  1146. //printf("CBCMR = %08lX\n", CCM_CBCMR);
  1147. hardware().clock_gate_register |= hardware().clock_gate_mask;
  1148. *(portConfigRegister(hardware().miso_pin[miso_pin_index])) = hardware().miso_mux[miso_pin_index];
  1149. *(portConfigRegister(hardware().mosi_pin [mosi_pin_index])) = hardware().mosi_mux[mosi_pin_index];
  1150. *(portConfigRegister(hardware().sck_pin [sck_pin_index])) = hardware().sck_mux[sck_pin_index];
  1151. // Set the Mux pins
  1152. //Serial.println("SPI: Set Input select registers");
  1153. hardware().sck_select_input_register = hardware().sck_select_val[sck_pin_index];
  1154. hardware().miso_select_input_register = hardware().miso_select_val[miso_pin_index];
  1155. hardware().mosi_select_input_register = hardware().mosi_select_val[mosi_pin_index];
  1156. //digitalWriteFast(10, HIGH);
  1157. //pinMode(10, OUTPUT);
  1158. //digitalWriteFast(10, HIGH);
  1159. port().CR = LPSPI_CR_RST;
  1160. // Lets initialize the Transmit FIFO watermark to FIFO size - 1...
  1161. // BUGBUG:: I assume queue of 16 for now...
  1162. port().FCR = LPSPI_FCR_TXWATER(15);
  1163. // We should initialize the SPI to be in a known default state.
  1164. beginTransaction(SPISettings());
  1165. endTransaction();
  1166. }
  1167. void SPIClass::setClockDivider_noInline(uint32_t clk) {
  1168. // Again depreciated, but...
  1169. hardware().clock_gate_register |= hardware().clock_gate_mask;
  1170. if (clk != _clock) {
  1171. static const uint32_t clk_sel[4] = {664615384, // PLL3 PFD1
  1172. 720000000, // PLL3 PFD0
  1173. 528000000, // PLL2
  1174. 396000000}; // PLL2 PFD2
  1175. // First save away the new settings..
  1176. _clock = clk;
  1177. uint32_t cbcmr = CCM_CBCMR;
  1178. uint32_t clkhz = clk_sel[(cbcmr >> 4) & 0x03] / (((cbcmr >> 26 ) & 0x07 ) + 1); // LPSPI peripheral clock
  1179. uint32_t d, div;
  1180. d = _clock ? clkhz/_clock : clkhz;
  1181. if (d && clkhz/d > _clock) d++;
  1182. if (d > 257) d= 257; // max div
  1183. if (d > 2) {
  1184. div = d-2;
  1185. } else {
  1186. div =0;
  1187. }
  1188. _ccr = LPSPI_CCR_SCKDIV(div) | LPSPI_CCR_DBT(div/2) | LPSPI_CCR_PCSSCK(div/2);
  1189. }
  1190. //Serial.printf("SPI.setClockDivider_noInline CCR:%x TCR:%x\n", _ccr, port().TCR);
  1191. port().CR = 0;
  1192. port().CFGR1 = LPSPI_CFGR1_MASTER | LPSPI_CFGR1_SAMPLE;
  1193. port().CCR = _ccr;
  1194. port().CR = LPSPI_CR_MEN;
  1195. }
  1196. uint8_t SPIClass::pinIsChipSelect(uint8_t pin)
  1197. {
  1198. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  1199. if (pin == hardware().cs_pin[i]) return hardware().cs_mask[i];
  1200. }
  1201. return 0;
  1202. }
  1203. bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  1204. {
  1205. uint8_t pin1_mask, pin2_mask;
  1206. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  1207. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  1208. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  1209. if ((pin1_mask & pin2_mask) != 0) return false;
  1210. return true;
  1211. }
  1212. bool SPIClass::pinIsMOSI(uint8_t pin)
  1213. {
  1214. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  1215. if (pin == hardware().mosi_pin[i]) return true;
  1216. }
  1217. return false;
  1218. }
  1219. bool SPIClass::pinIsMISO(uint8_t pin)
  1220. {
  1221. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  1222. if (pin == hardware().miso_pin[i]) return true;
  1223. }
  1224. return false;
  1225. }
  1226. bool SPIClass::pinIsSCK(uint8_t pin)
  1227. {
  1228. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  1229. if (pin == hardware().sck_pin[i]) return true;
  1230. }
  1231. return false;
  1232. }
  1233. // setCS() is not intended for use from normal Arduino programs/sketches.
  1234. uint8_t SPIClass::setCS(uint8_t pin)
  1235. {
  1236. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  1237. if (pin == hardware().cs_pin[i]) {
  1238. *(portConfigRegister(pin)) = hardware().cs_mux[i];
  1239. if (hardware().pcs_select_input_register[i])
  1240. *hardware().pcs_select_input_register[i] = hardware().pcs_select_val[i];
  1241. return hardware().cs_mask[i];
  1242. }
  1243. }
  1244. return 0;
  1245. }
  1246. void SPIClass::setMOSI(uint8_t pin)
  1247. {
  1248. if (pin != hardware().mosi_pin[mosi_pin_index]) {
  1249. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  1250. if (pin == hardware().mosi_pin[i] ) {
  1251. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  1252. // BUGBUG:: Unclear what to do with previous pin as there is no unused setting like t3.x
  1253. uint32_t fastio = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_SPEED(2);
  1254. *(portControlRegister(hardware().mosi_pin[i])) = fastio;
  1255. *(portConfigRegister(hardware().mosi_pin [i])) = hardware().mosi_mux[i];
  1256. hardware().mosi_select_input_register = hardware().mosi_select_val[i];
  1257. }
  1258. mosi_pin_index = i;
  1259. return;
  1260. }
  1261. }
  1262. }
  1263. }
  1264. void SPIClass::setMISO(uint8_t pin)
  1265. {
  1266. if (pin != hardware().miso_pin[miso_pin_index]) {
  1267. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  1268. if (pin == hardware().miso_pin[i] ) {
  1269. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  1270. // BUGBUG:: Unclear what to do with previous pin as there is no unused setting like t3.x
  1271. uint32_t fastio = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_SPEED(2);
  1272. *(portControlRegister(hardware().miso_pin[i])) = fastio;
  1273. *(portConfigRegister(hardware().miso_pin[i])) = hardware().miso_mux[i];
  1274. hardware().miso_select_input_register = hardware().miso_select_val[i];
  1275. }
  1276. miso_pin_index = i;
  1277. return;
  1278. }
  1279. }
  1280. }
  1281. }
  1282. void SPIClass::setSCK(uint8_t pin)
  1283. {
  1284. if (pin != hardware().sck_pin[sck_pin_index]) {
  1285. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  1286. if (pin == hardware().sck_pin[i] ) {
  1287. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  1288. // BUGBUG:: Unclear what to do with previous pin as there is no unused setting like t3.x
  1289. uint32_t fastio = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_SPEED(2);
  1290. *(portControlRegister(hardware().sck_pin[i])) = fastio;
  1291. *(portConfigRegister(hardware().sck_pin [i])) = hardware().sck_mux[i];
  1292. hardware().sck_select_input_register = hardware().sck_select_val[i];
  1293. }
  1294. sck_pin_index = i;
  1295. return;
  1296. }
  1297. }
  1298. }
  1299. }
  1300. void SPIClass::setBitOrder(uint8_t bitOrder)
  1301. {
  1302. hardware().clock_gate_register |= hardware().clock_gate_mask;
  1303. if (bitOrder == LSBFIRST) {
  1304. port().TCR |= LPSPI_TCR_LSBF;
  1305. } else {
  1306. port().TCR &= ~LPSPI_TCR_LSBF;
  1307. }
  1308. }
  1309. void SPIClass::setDataMode(uint8_t dataMode)
  1310. {
  1311. hardware().clock_gate_register |= hardware().clock_gate_mask;
  1312. //SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  1313. // Handle Data Mode
  1314. uint32_t tcr = port().TCR & ~(LPSPI_TCR_CPOL | LPSPI_TCR_CPHA);
  1315. if (dataMode & 0x08) tcr |= LPSPI_TCR_CPOL;
  1316. // Note: On T3.2 when we set CPHA it also updated the timing. It moved the
  1317. // PCS to SCK Delay Prescaler into the After SCK Delay Prescaler
  1318. if (dataMode & 0x04) tcr |= LPSPI_TCR_CPHA;
  1319. // Save back out
  1320. port().TCR = tcr;
  1321. }
  1322. void _spi_dma_rxISR0(void) {SPI.dma_rxisr();}
  1323. // NOTE pin definitions are in the order MISO, MOSI, SCK, CS
  1324. // With each group, having pin number[n], setting[n], INPUT_SELECT_MUX settings[n], SELECT INPUT register
  1325. #if defined(ARDUINO_TEENSY41)
  1326. const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi4_hardware = {
  1327. CCM_CCGR1, CCM_CCGR1_LPSPI4(CCM_CCGR_ON),
  1328. DMAMUX_SOURCE_LPSPI4_TX, DMAMUX_SOURCE_LPSPI4_RX, _spi_dma_rxISR0,
  1329. 12, 255, // MISO
  1330. 3 | 0x10, 0,
  1331. 0, 0,
  1332. IOMUXC_LPSPI4_SDI_SELECT_INPUT,
  1333. 11, 255, // MOSI
  1334. 3 | 0x10, 0,
  1335. 0, 0,
  1336. IOMUXC_LPSPI4_SDO_SELECT_INPUT,
  1337. 13, 255, // SCK
  1338. 3 | 0x10, 0,
  1339. 0, 0,
  1340. IOMUXC_LPSPI4_SCK_SELECT_INPUT,
  1341. 10, 37, 36, // CS
  1342. 3 | 0x10, 2 | 0x10, 2 | 0x10,
  1343. 1, 2, 3,
  1344. 0, 0, 0,
  1345. &IOMUXC_LPSPI4_PCS0_SELECT_INPUT, 0, 0
  1346. };
  1347. #else
  1348. const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi4_hardware = {
  1349. CCM_CCGR1, CCM_CCGR1_LPSPI4(CCM_CCGR_ON),
  1350. DMAMUX_SOURCE_LPSPI4_TX, DMAMUX_SOURCE_LPSPI4_RX, _spi_dma_rxISR0,
  1351. 12,
  1352. 3 | 0x10,
  1353. 0,
  1354. IOMUXC_LPSPI4_SDI_SELECT_INPUT,
  1355. 11,
  1356. 3 | 0x10,
  1357. 0,
  1358. IOMUXC_LPSPI4_SDO_SELECT_INPUT,
  1359. 13,
  1360. 3 | 0x10,
  1361. 0,
  1362. IOMUXC_LPSPI4_SCK_SELECT_INPUT,
  1363. 10,
  1364. 3 | 0x10,
  1365. 1,
  1366. 0,
  1367. &IOMUXC_LPSPI4_PCS0_SELECT_INPUT
  1368. };
  1369. #endif
  1370. SPIClass SPI((uintptr_t)&IMXRT_LPSPI4_S, (uintptr_t)&SPIClass::spiclass_lpspi4_hardware);
  1371. #if defined(__IMXRT1062__)
  1372. // T4 has two other possible SPI objects...
  1373. void _spi_dma_rxISR1(void) {SPI1.dma_rxisr();}
  1374. #if defined(ARDUINO_TEENSY41)
  1375. const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi3_hardware = {
  1376. CCM_CCGR1, CCM_CCGR1_LPSPI3(CCM_CCGR_ON),
  1377. DMAMUX_SOURCE_LPSPI3_TX, DMAMUX_SOURCE_LPSPI3_RX, _spi_dma_rxISR1,
  1378. 1, 39,
  1379. 7 | 0x10, 2 | 0x10,
  1380. 0, 1,
  1381. IOMUXC_LPSPI3_SDI_SELECT_INPUT,
  1382. 26, 255,
  1383. 2 | 0x10, 0,
  1384. 1, 0,
  1385. IOMUXC_LPSPI3_SDO_SELECT_INPUT,
  1386. 27, 255,
  1387. 2 | 0x10, 0,
  1388. 1, 0,
  1389. IOMUXC_LPSPI3_SCK_SELECT_INPUT,
  1390. 0, 38, 255,
  1391. 7 | 0x10, 2 | 0x10, 0,
  1392. 1, 1, 0,
  1393. 0, 1, 0,
  1394. &IOMUXC_LPSPI3_PCS0_SELECT_INPUT, &IOMUXC_LPSPI3_PCS0_SELECT_INPUT, 0
  1395. };
  1396. #else
  1397. const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi3_hardware = {
  1398. CCM_CCGR1, CCM_CCGR1_LPSPI3(CCM_CCGR_ON),
  1399. DMAMUX_SOURCE_LPSPI3_TX, DMAMUX_SOURCE_LPSPI3_RX, _spi_dma_rxISR1,
  1400. 1,
  1401. 7 | 0x10,
  1402. 0,
  1403. IOMUXC_LPSPI3_SDI_SELECT_INPUT,
  1404. 26,
  1405. 2 | 0x10,
  1406. 1,
  1407. IOMUXC_LPSPI3_SDO_SELECT_INPUT,
  1408. 27,
  1409. 2 | 0x10,
  1410. 1,
  1411. IOMUXC_LPSPI3_SCK_SELECT_INPUT,
  1412. 0,
  1413. 7 | 0x10,
  1414. 1,
  1415. 0,
  1416. &IOMUXC_LPSPI3_PCS0_SELECT_INPUT
  1417. };
  1418. #endif
  1419. SPIClass SPI1((uintptr_t)&IMXRT_LPSPI3_S, (uintptr_t)&SPIClass::spiclass_lpspi3_hardware);
  1420. void _spi_dma_rxISR2(void) {SPI2.dma_rxisr();}
  1421. #if defined(ARDUINO_TEENSY41)
  1422. const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi1_hardware = {
  1423. CCM_CCGR1, CCM_CCGR1_LPSPI1(CCM_CCGR_ON),
  1424. DMAMUX_SOURCE_LPSPI1_TX, DMAMUX_SOURCE_LPSPI1_RX, _spi_dma_rxISR1,
  1425. 42, 54,
  1426. 4 | 0x10, 3 | 0x10,
  1427. 1, 0,
  1428. IOMUXC_LPSPI1_SDI_SELECT_INPUT,
  1429. 43, 50,
  1430. 4 | 0x10, 3 | 0x10,
  1431. 1, 0,
  1432. IOMUXC_LPSPI1_SDO_SELECT_INPUT,
  1433. 45, 49,
  1434. 4 | 0x10, 3 | 0x10,
  1435. 1, 0,
  1436. IOMUXC_LPSPI1_SCK_SELECT_INPUT,
  1437. 44, 255, 255,
  1438. 4 | 0x10, 0, 0,
  1439. 1, 0, 0,
  1440. 0, 0, 0,
  1441. &IOMUXC_LPSPI1_PCS0_SELECT_INPUT, 0, 0
  1442. };
  1443. #else
  1444. const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi1_hardware = {
  1445. CCM_CCGR1, CCM_CCGR1_LPSPI1(CCM_CCGR_ON),
  1446. DMAMUX_SOURCE_LPSPI1_TX, DMAMUX_SOURCE_LPSPI1_RX, _spi_dma_rxISR1,
  1447. 34,
  1448. 4 | 0x10,
  1449. 1,
  1450. IOMUXC_LPSPI1_SDI_SELECT_INPUT,
  1451. 35,
  1452. 4 | 0x10,
  1453. 1,
  1454. IOMUXC_LPSPI1_SDO_SELECT_INPUT,
  1455. 37,
  1456. 4 | 0x10,
  1457. 1,
  1458. IOMUXC_LPSPI1_SCK_SELECT_INPUT,
  1459. 36,
  1460. 4 | 0x10,
  1461. 1,
  1462. 0,
  1463. &IOMUXC_LPSPI1_PCS0_SELECT_INPUT
  1464. };
  1465. #endif
  1466. SPIClass SPI2((uintptr_t)&IMXRT_LPSPI1_S, (uintptr_t)&SPIClass::spiclass_lpspi1_hardware);
  1467. #endif
  1468. //SPIClass SPI(&IMXRT_LPSPI4_S, &spiclass_lpspi4_hardware);
  1469. void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName)
  1470. {
  1471. uint32_t n = (uint32_t)interruptName;
  1472. if (n >= NVIC_NUM_INTERRUPTS) return;
  1473. //Serial.print("usingInterrupt ");
  1474. //Serial.println(n);
  1475. interruptMasksUsed |= (1 << (n >> 5));
  1476. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  1477. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  1478. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  1479. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  1480. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  1481. }
  1482. void SPIClass::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  1483. {
  1484. uint32_t n = (uint32_t)interruptName;
  1485. if (n >= NVIC_NUM_INTERRUPTS) return;
  1486. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  1487. if (interruptMask[n >> 5] == 0) {
  1488. interruptMasksUsed &= ~(1 << (n >> 5));
  1489. }
  1490. }
  1491. void SPIClass::transfer(const void * buf, void * retbuf, size_t count)
  1492. {
  1493. if (count == 0) return;
  1494. uint8_t *p_write = (uint8_t*)buf;
  1495. uint8_t *p_read = (uint8_t*)retbuf;
  1496. size_t count_read = count;
  1497. // Pass 1 keep it simple and don't try packing 8 bits into 16 yet..
  1498. // Lets clear the reader queue
  1499. port().CR = LPSPI_CR_RRF | LPSPI_CR_MEN; // clear the queue and make sure still enabled.
  1500. while (count > 0) {
  1501. // Push out the next byte;
  1502. port().TDR = p_write? *p_write++ : _transferWriteFill;
  1503. count--; // how many bytes left to output.
  1504. // Make sure queue is not full before pushing next byte out
  1505. do {
  1506. if ((port().RSR & LPSPI_RSR_RXEMPTY) == 0) {
  1507. uint8_t b = port().RDR; // Read any pending RX bytes in
  1508. if (p_read) *p_read++ = b;
  1509. count_read--;
  1510. }
  1511. } while ((port().SR & LPSPI_SR_TDF) == 0) ;
  1512. }
  1513. // now lets wait for all of the read bytes to be returned...
  1514. while (count_read) {
  1515. if ((port().RSR & LPSPI_RSR_RXEMPTY) == 0) {
  1516. uint8_t b = port().RDR; // Read any pending RX bytes in
  1517. if (p_read) *p_read++ = b;
  1518. count_read--;
  1519. }
  1520. }
  1521. }
  1522. void SPIClass::end() {
  1523. // only do something if we have begun
  1524. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  1525. port().CR = 0; // turn off the enable
  1526. pinMode(hardware().miso_pin[miso_pin_index], INPUT_DISABLE);
  1527. pinMode(hardware().mosi_pin[mosi_pin_index], INPUT_DISABLE);
  1528. pinMode(hardware().sck_pin[sck_pin_index], INPUT_DISABLE);
  1529. }
  1530. }
  1531. //=============================================================================
  1532. // ASYNCH Support
  1533. //=============================================================================
  1534. //=========================================================================
  1535. // Try Transfer using DMA.
  1536. //=========================================================================
  1537. #ifdef SPI_HAS_TRANSFER_ASYNC
  1538. static uint8_t bit_bucket;
  1539. #define dontInterruptAtCompletion(dmac) (dmac)->TCD->CSR &= ~DMA_TCD_CSR_INTMAJOR
  1540. //=========================================================================
  1541. // Init the DMA channels
  1542. //=========================================================================
  1543. bool SPIClass::initDMAChannels() {
  1544. // Allocate our channels.
  1545. _dmaTX = new DMAChannel();
  1546. if (_dmaTX == nullptr) {
  1547. return false;
  1548. }
  1549. _dmaRX = new DMAChannel();
  1550. if (_dmaRX == nullptr) {
  1551. delete _dmaTX; // release it
  1552. _dmaTX = nullptr;
  1553. return false;
  1554. }
  1555. // Let's setup the RX chain
  1556. _dmaRX->disable();
  1557. _dmaRX->source((volatile uint8_t&)port().RDR);
  1558. _dmaRX->disableOnCompletion();
  1559. _dmaRX->triggerAtHardwareEvent(hardware().rx_dma_channel);
  1560. _dmaRX->attachInterrupt(hardware().dma_rxisr);
  1561. _dmaRX->interruptAtCompletion();
  1562. // We may be using settings chain here so lets set it up.
  1563. // Now lets setup TX chain. Note if trigger TX is not set
  1564. // we need to have the RX do it for us.
  1565. _dmaTX->disable();
  1566. _dmaTX->destination((volatile uint8_t&)port().TDR);
  1567. _dmaTX->disableOnCompletion();
  1568. if (hardware().tx_dma_channel) {
  1569. _dmaTX->triggerAtHardwareEvent(hardware().tx_dma_channel);
  1570. } else {
  1571. // Serial.printf("SPI InitDMA tx triger by RX: %x\n", (uint32_t)_dmaRX);
  1572. _dmaTX->triggerAtTransfersOf(*_dmaRX);
  1573. }
  1574. _dma_state = DMAState::idle; // Should be first thing set!
  1575. return true;
  1576. }
  1577. //=========================================================================
  1578. // Main Async Transfer function
  1579. //=========================================================================
  1580. #ifndef TRANSFER_COUNT_FIXED
  1581. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  1582. // note does no validation of length...
  1583. DMABaseClass::TCD_t *tcd = dmac->TCD;
  1584. if (!(tcd->BITER & DMA_TCD_BITER_ELINK)) {
  1585. tcd->BITER = len & 0x7fff;
  1586. } else {
  1587. tcd->BITER = (tcd->BITER & 0xFE00) | (len & 0x1ff);
  1588. }
  1589. tcd->CITER = tcd->BITER;
  1590. }
  1591. #else
  1592. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  1593. dmac->transferCount(len);
  1594. }
  1595. #endif
  1596. #ifdef DEBUG_DMA_TRANSFERS
  1597. void dumpDMA_TCD(DMABaseClass *dmabc)
  1598. {
  1599. Serial4.printf("%x %x:", (uint32_t)dmabc, (uint32_t)dmabc->TCD);
  1600. Serial4.printf("SA:%x SO:%d AT:%x NB:%x SL:%d DA:%x DO: %d CI:%x DL:%x CS:%x BI:%x\n", (uint32_t)dmabc->TCD->SADDR,
  1601. dmabc->TCD->SOFF, dmabc->TCD->ATTR, dmabc->TCD->NBYTES, dmabc->TCD->SLAST, (uint32_t)dmabc->TCD->DADDR,
  1602. dmabc->TCD->DOFF, dmabc->TCD->CITER, dmabc->TCD->DLASTSGA, dmabc->TCD->CSR, dmabc->TCD->BITER);
  1603. }
  1604. #endif
  1605. bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) {
  1606. if (_dma_state == DMAState::notAllocated) {
  1607. if (!initDMAChannels())
  1608. return false;
  1609. }
  1610. if (_dma_state == DMAState::active)
  1611. return false; // already active
  1612. event_responder.clearEvent(); // Make sure it is not set yet
  1613. if (count < 2) {
  1614. // Use non-async version to simplify cases...
  1615. transfer(buf, retbuf, count);
  1616. event_responder.triggerEvent();
  1617. return true;
  1618. }
  1619. // Now handle the cases where the count > then how many we can output in one DMA request
  1620. if (count > MAX_DMA_COUNT) {
  1621. _dma_count_remaining = count - MAX_DMA_COUNT;
  1622. count = MAX_DMA_COUNT;
  1623. } else {
  1624. _dma_count_remaining = 0;
  1625. }
  1626. // Now See if caller passed in a source buffer.
  1627. _dmaTX->TCD->ATTR_DST = 0; // Make sure set for 8 bit mode
  1628. uint8_t *write_data = (uint8_t*) buf;
  1629. if (buf) {
  1630. _dmaTX->sourceBuffer((uint8_t*)write_data, count);
  1631. _dmaTX->TCD->SLAST = 0; // Finish with it pointing to next location
  1632. if ((uint32_t)write_data >= 0x20200000u) arm_dcache_flush(write_data, count);
  1633. } else {
  1634. _dmaTX->source((uint8_t&)_transferWriteFill); // maybe have setable value
  1635. DMAChanneltransferCount(_dmaTX, count);
  1636. }
  1637. if (retbuf) {
  1638. // On T3.5 must handle SPI1/2 differently as only one DMA channel
  1639. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  1640. _dmaRX->destinationBuffer((uint8_t*)retbuf, count);
  1641. _dmaRX->TCD->DLASTSGA = 0; // At end point after our bufffer
  1642. if ((uint32_t)retbuf >= 0x20200000u) arm_dcache_delete(retbuf, count);
  1643. } else {
  1644. // Write only mode
  1645. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  1646. _dmaRX->destination((uint8_t&)bit_bucket);
  1647. DMAChanneltransferCount(_dmaRX, count);
  1648. }
  1649. _dma_event_responder = &event_responder;
  1650. // Now try to start it?
  1651. // Setup DMA main object
  1652. yield();
  1653. #ifdef DEBUG_DMA_TRANSFERS
  1654. // Lets dump TX, RX
  1655. dumpDMA_TCD(_dmaTX);
  1656. dumpDMA_TCD(_dmaRX);
  1657. #endif
  1658. // Make sure port is in 8 bit mode and clear watermark
  1659. port().TCR = (port().TCR & ~(LPSPI_TCR_FRAMESZ(31))) | LPSPI_TCR_FRAMESZ(7);
  1660. port().FCR = 0;
  1661. // Lets try to output the first byte to make sure that we are in 8 bit mode...
  1662. port().DER = LPSPI_DER_TDDE | LPSPI_DER_RDDE; //enable DMA on both TX and RX
  1663. port().SR = 0x3f00; // clear out all of the other status...
  1664. _dmaRX->enable();
  1665. _dmaTX->enable();
  1666. _dma_state = DMAState::active;
  1667. return true;
  1668. }
  1669. //-------------------------------------------------------------------------
  1670. // DMA RX ISR
  1671. //-------------------------------------------------------------------------
  1672. void SPIClass::dma_rxisr(void) {
  1673. _dmaRX->clearInterrupt();
  1674. _dmaTX->clearComplete();
  1675. _dmaRX->clearComplete();
  1676. if (_dma_count_remaining) {
  1677. // What do I need to do to start it back up again...
  1678. // We will use the BITR/CITR from RX as TX may have prefed some stuff
  1679. if (_dma_count_remaining > MAX_DMA_COUNT) {
  1680. _dma_count_remaining -= MAX_DMA_COUNT;
  1681. } else {
  1682. DMAChanneltransferCount(_dmaTX, _dma_count_remaining);
  1683. DMAChanneltransferCount(_dmaRX, _dma_count_remaining);
  1684. _dma_count_remaining = 0;
  1685. }
  1686. _dmaRX->enable();
  1687. _dmaTX->enable();
  1688. } else {
  1689. port().FCR = LPSPI_FCR_TXWATER(15); // _spi_fcr_save; // restore the FSR status...
  1690. port().DER = 0; // DMA no longer doing TX (or RX)
  1691. port().CR = LPSPI_CR_MEN | LPSPI_CR_RRF | LPSPI_CR_RTF; // actually clear both...
  1692. port().SR = 0x3f00; // clear out all of the other status...
  1693. _dma_state = DMAState::completed; // set back to 1 in case our call wants to start up dma again
  1694. _dma_event_responder->triggerEvent();
  1695. }
  1696. }
  1697. #endif // SPI_HAS_TRANSFER_ASYNC
  1698. #endif