You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1123 lines
31KB

  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. void SPIClass::begin()
  24. {
  25. // Set SS to high so a connected chip will be "deselected" by default
  26. digitalWrite(SS, HIGH);
  27. // When the SS pin is set as OUTPUT, it can be used as
  28. // a general purpose output port (it doesn't influence
  29. // SPI operations).
  30. pinMode(SS, OUTPUT);
  31. // Warning: if the SS pin ever becomes a LOW INPUT then SPI
  32. // automatically switches to Slave, so the data direction of
  33. // the SS pin MUST be kept as OUTPUT.
  34. SPCR |= _BV(MSTR);
  35. SPCR |= _BV(SPE);
  36. // Set direction register for SCK and MOSI pin.
  37. // MISO pin automatically overrides to INPUT.
  38. // By doing this AFTER enabling SPI, we avoid accidentally
  39. // clocking in a single bit since the lines go directly
  40. // from "input" to SPI control.
  41. // http://code.google.com/p/arduino/issues/detail?id=888
  42. pinMode(SCK, OUTPUT);
  43. pinMode(MOSI, OUTPUT);
  44. }
  45. void SPIClass::end() {
  46. SPCR &= ~_BV(SPE);
  47. }
  48. // mapping of interrupt numbers to bits within SPI_AVR_EIMSK
  49. #if defined(__AVR_ATmega32U4__)
  50. #define SPI_INT0_MASK (1<<INT0)
  51. #define SPI_INT1_MASK (1<<INT1)
  52. #define SPI_INT2_MASK (1<<INT2)
  53. #define SPI_INT3_MASK (1<<INT3)
  54. #define SPI_INT4_MASK (1<<INT6)
  55. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  56. #define SPI_INT0_MASK (1<<INT0)
  57. #define SPI_INT1_MASK (1<<INT1)
  58. #define SPI_INT2_MASK (1<<INT2)
  59. #define SPI_INT3_MASK (1<<INT3)
  60. #define SPI_INT4_MASK (1<<INT4)
  61. #define SPI_INT5_MASK (1<<INT5)
  62. #define SPI_INT6_MASK (1<<INT6)
  63. #define SPI_INT7_MASK (1<<INT7)
  64. #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
  65. #define SPI_INT0_MASK (1<<INT4)
  66. #define SPI_INT1_MASK (1<<INT5)
  67. #define SPI_INT2_MASK (1<<INT0)
  68. #define SPI_INT3_MASK (1<<INT1)
  69. #define SPI_INT4_MASK (1<<INT2)
  70. #define SPI_INT5_MASK (1<<INT3)
  71. #define SPI_INT6_MASK (1<<INT6)
  72. #define SPI_INT7_MASK (1<<INT7)
  73. #else
  74. #ifdef INT0
  75. #define SPI_INT0_MASK (1<<INT0)
  76. #endif
  77. #ifdef INT1
  78. #define SPI_INT1_MASK (1<<INT1)
  79. #endif
  80. #ifdef INT2
  81. #define SPI_INT2_MASK (1<<INT2)
  82. #endif
  83. #endif
  84. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  85. {
  86. uint8_t stmp, mask;
  87. if (interruptMode > 1) return;
  88. stmp = SREG;
  89. noInterrupts();
  90. switch (interruptNumber) {
  91. #ifdef SPI_INT0_MASK
  92. case 0: mask = SPI_INT0_MASK; break;
  93. #endif
  94. #ifdef SPI_INT1_MASK
  95. case 1: mask = SPI_INT1_MASK; break;
  96. #endif
  97. #ifdef SPI_INT2_MASK
  98. case 2: mask = SPI_INT2_MASK; break;
  99. #endif
  100. #ifdef SPI_INT3_MASK
  101. case 3: mask = SPI_INT3_MASK; break;
  102. #endif
  103. #ifdef SPI_INT4_MASK
  104. case 4: mask = SPI_INT4_MASK; break;
  105. #endif
  106. #ifdef SPI_INT5_MASK
  107. case 5: mask = SPI_INT5_MASK; break;
  108. #endif
  109. #ifdef SPI_INT6_MASK
  110. case 6: mask = SPI_INT6_MASK; break;
  111. #endif
  112. #ifdef SPI_INT7_MASK
  113. case 7: mask = SPI_INT7_MASK; break;
  114. #endif
  115. default:
  116. interruptMode = 2;
  117. SREG = stmp;
  118. return;
  119. }
  120. interruptMode = 1;
  121. interruptMask |= mask;
  122. SREG = stmp;
  123. }
  124. /**********************************************************/
  125. /* 32 bit Teensy 3.0 and 3.1 */
  126. /**********************************************************/
  127. #elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISK)
  128. SPIClass SPI;
  129. uint8_t SPIClass::interruptMasksUsed = 0;
  130. uint32_t SPIClass::interruptMask[(NVIC_NUM_INTERRUPTS+31)/32];
  131. uint32_t SPIClass::interruptSave[(NVIC_NUM_INTERRUPTS+31)/32];
  132. #ifdef SPI_TRANSACTION_MISMATCH_LED
  133. uint8_t SPIClass::inTransactionFlag = 0;
  134. #endif
  135. void SPIClass::begin()
  136. {
  137. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  138. SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  139. SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  140. SPI0_CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  141. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  142. SPCR.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  143. }
  144. void SPIClass::end() {
  145. SPCR.disable_pins();
  146. SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  147. }
  148. void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName)
  149. {
  150. uint32_t n = (uint32_t)interruptName;
  151. if (n >= NVIC_NUM_INTERRUPTS) return;
  152. //Serial.print("usingInterrupt ");
  153. //Serial.println(n);
  154. interruptMasksUsed |= (1 << (n >> 5));
  155. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  156. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  157. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  158. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  159. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  160. }
  161. void SPIClass::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  162. {
  163. uint32_t n = (uint32_t)interruptName;
  164. if (n >= NVIC_NUM_INTERRUPTS) return;
  165. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  166. if (interruptMask[n >> 5] == 0) {
  167. interruptMasksUsed &= ~(1 << (n >> 5));
  168. }
  169. }
  170. const uint16_t SPISettings::ctar_div_table[23] = {
  171. 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40,
  172. 56, 64, 96, 128, 192, 256, 384, 512, 640, 768
  173. };
  174. const uint32_t SPISettings::ctar_clock_table[23] = {
  175. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  176. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  177. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  178. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  179. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  180. SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  181. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  182. SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  183. SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  184. SPI_CTAR_PBR(2) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(0),
  185. SPI_CTAR_PBR(1) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  186. SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(3),
  187. SPI_CTAR_PBR(2) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  188. SPI_CTAR_PBR(3) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  189. SPI_CTAR_PBR(0) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  190. SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  191. SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  192. SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  193. SPI_CTAR_PBR(0) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  194. SPI_CTAR_PBR(1) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  195. SPI_CTAR_PBR(0) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7),
  196. SPI_CTAR_PBR(2) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  197. SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7)
  198. };
  199. static void updateCTAR(uint32_t ctar)
  200. {
  201. if (SPI0_CTAR0 != ctar) {
  202. uint32_t mcr = SPI0_MCR;
  203. if (mcr & SPI_MCR_MDIS) {
  204. SPI0_CTAR0 = ctar;
  205. SPI0_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  206. } else {
  207. SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  208. SPI0_CTAR0 = ctar;
  209. SPI0_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  210. SPI0_MCR = mcr;
  211. }
  212. }
  213. }
  214. void SPIClass::setBitOrder(uint8_t bitOrder)
  215. {
  216. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  217. uint32_t ctar = SPI0_CTAR0;
  218. if (bitOrder == LSBFIRST) {
  219. ctar |= SPI_CTAR_LSBFE;
  220. } else {
  221. ctar &= ~SPI_CTAR_LSBFE;
  222. }
  223. updateCTAR(ctar);
  224. }
  225. void SPIClass::setDataMode(uint8_t dataMode)
  226. {
  227. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  228. // TODO: implement with native code
  229. SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  230. }
  231. void SPIClass::setClockDivider_noInline(uint32_t clk)
  232. {
  233. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  234. uint32_t ctar = SPI0_CTAR0;
  235. ctar &= (SPI_CTAR_CPOL | SPI_CTAR_CPHA | SPI_CTAR_LSBFE);
  236. if (ctar & SPI_CTAR_CPHA) {
  237. clk = (clk & 0xFFFF0FFF) | ((clk & 0xF000) >> 4);
  238. }
  239. ctar |= clk;
  240. updateCTAR(ctar);
  241. }
  242. uint8_t SPIClass::pinIsChipSelect(uint8_t pin)
  243. {
  244. switch (pin) {
  245. case 10: return 0x01; // PTC4
  246. case 2: return 0x01; // PTD0
  247. case 9: return 0x02; // PTC3
  248. case 6: return 0x02; // PTD4
  249. case 20: return 0x04; // PTD5
  250. case 23: return 0x04; // PTC2
  251. case 21: return 0x08; // PTD6
  252. case 22: return 0x08; // PTC1
  253. case 15: return 0x10; // PTC0
  254. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  255. case 26: return 0x01;
  256. case 45: return 0x20; // CS5
  257. #endif
  258. }
  259. return 0;
  260. }
  261. bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  262. {
  263. uint8_t pin1_mask, pin2_mask;
  264. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  265. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  266. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  267. if ((pin1_mask & pin2_mask) != 0) return false;
  268. return true;
  269. }
  270. // setCS() is not intended for use from normal Arduino programs/sketches.
  271. uint8_t SPIClass::setCS(uint8_t pin)
  272. {
  273. switch (pin) {
  274. case 10: CORE_PIN10_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTC4
  275. case 2: CORE_PIN2_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD0
  276. case 9: CORE_PIN9_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTC3
  277. case 6: CORE_PIN6_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTD4
  278. case 20: CORE_PIN20_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTD5
  279. case 23: CORE_PIN23_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTC2
  280. case 21: CORE_PIN21_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTD6
  281. case 22: CORE_PIN22_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTC1
  282. case 15: CORE_PIN15_CONFIG = PORT_PCR_MUX(2); return 0x10; // PTC0
  283. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  284. case 26: CORE_PIN26_CONFIG = PORT_PCR_MUX(2);return 0x01;
  285. case 45: CORE_PIN45_CONFIG = PORT_PCR_MUX(3);return 0x20;
  286. #endif
  287. }
  288. return 0;
  289. }
  290. void SPIClass::transfer(void *buf, size_t count)
  291. {
  292. if (count == 0) return;
  293. uint8_t *p_write = (uint8_t *)buf;
  294. uint8_t *p_read = p_write;
  295. size_t count_read = count;
  296. bool lsbfirst = (SPI0_CTAR0 & SPI_CTAR_LSBFE) ? true : false;
  297. // Lets clear the reader queue
  298. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  299. uint32_t sr;
  300. // Now lets loop while we still have data to output
  301. if (count & 1) {
  302. if (count > 1)
  303. KINETISK_SPI0.PUSHR = *p_write++ | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  304. else
  305. KINETISK_SPI0.PUSHR = *p_write++ | SPI_PUSHR_CTAS(0);
  306. count--;
  307. }
  308. while (count > 0) {
  309. // Push out the next byte;
  310. uint16_t w = (*p_write++) << 8;
  311. w |= *p_write++;
  312. if (lsbfirst) w = __builtin_bswap16(w);
  313. if (count == 2)
  314. KINETISK_SPI0.PUSHR = w | SPI_PUSHR_CTAS(1);
  315. else
  316. KINETISK_SPI0.PUSHR = w | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1);
  317. count -= 2; // how many bytes to output.
  318. // Make sure queue is not full before pushing next byte out
  319. do {
  320. sr = KINETISK_SPI0.SR;
  321. if (sr & 0xF0) {
  322. uint16_t w = KINETISK_SPI0.POPR; // Read any pending RX bytes in
  323. if (count_read & 1) {
  324. *p_read++ = w; // Read any pending RX bytes in
  325. count_read--;
  326. } else {
  327. if (lsbfirst) w = __builtin_bswap16(w);
  328. *p_read++ = w >> 8;
  329. *p_read++ = (w & 0xff);
  330. count_read -= 2;
  331. }
  332. }
  333. } while ((sr & (15 << 12)) > (3 << 12));
  334. }
  335. // now lets wait for all of the read bytes to be returned...
  336. while (count_read) {
  337. sr = KINETISK_SPI0.SR;
  338. if (sr & 0xF0) {
  339. uint16_t w = KINETISK_SPI0.POPR; // Read any pending RX bytes in
  340. if (count_read & 1) {
  341. *p_read++ = w; // Read any pending RX bytes in
  342. count_read--;
  343. } else {
  344. if (lsbfirst) w = __builtin_bswap16(w);
  345. *p_read++ = w >> 8;
  346. *p_read++ = (w & 0xff);
  347. count_read -= 2;
  348. }
  349. }
  350. }
  351. }
  352. /**********************************************************/
  353. /* 32 bit Teensy-3.5/3.6 */
  354. /**********************************************************/
  355. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  356. SPI1Class SPI1;
  357. uint8_t SPI1Class::interruptMasksUsed = 0;
  358. uint32_t SPI1Class::interruptMask[(NVIC_NUM_INTERRUPTS+31)/32];
  359. uint32_t SPI1Class::interruptSave[(NVIC_NUM_INTERRUPTS+31)/32];
  360. #ifdef SPI_TRANSACTION_MISMATCH_LED
  361. uint8_t SPI1Class::inTransactionFlag = 0;
  362. #endif
  363. void SPI1Class::begin()
  364. {
  365. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  366. SPI1_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  367. SPI1_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  368. SPI1_CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  369. SPI1_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  370. SPCR1.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  371. }
  372. void SPI1Class::end() {
  373. SPCR1.disable_pins();
  374. SPI1_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  375. }
  376. void SPI1Class::usingInterrupt(IRQ_NUMBER_t interruptName)
  377. {
  378. uint32_t n = (uint32_t)interruptName;
  379. if (n >= NVIC_NUM_INTERRUPTS) return;
  380. //Serial.print("usingInterrupt ");
  381. //Serial.println(n);
  382. interruptMasksUsed |= (1 << (n >> 5));
  383. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  384. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  385. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  386. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  387. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  388. }
  389. void SPI1Class::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  390. {
  391. uint32_t n = (uint32_t)interruptName;
  392. if (n >= NVIC_NUM_INTERRUPTS) return;
  393. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  394. if (interruptMask[n >> 5] == 0) {
  395. interruptMasksUsed &= ~(1 << (n >> 5));
  396. }
  397. }
  398. static void updateCTAR1(uint32_t ctar)
  399. {
  400. if (SPI1_CTAR0 != ctar) {
  401. uint32_t mcr = SPI1_MCR;
  402. if (mcr & SPI_MCR_MDIS) {
  403. SPI1_CTAR0 = ctar;
  404. SPI1_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  405. } else {
  406. SPI1_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  407. SPI1_CTAR0 = ctar;
  408. SPI1_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  409. SPI1_MCR = mcr;
  410. }
  411. }
  412. }
  413. void SPI1Class::setBitOrder(uint8_t bitOrder)
  414. {
  415. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  416. uint32_t ctar = SPI1_CTAR0;
  417. if (bitOrder == LSBFIRST) {
  418. ctar |= SPI_CTAR_LSBFE;
  419. } else {
  420. ctar &= ~SPI_CTAR_LSBFE;
  421. }
  422. updateCTAR1(ctar);
  423. }
  424. void SPI1Class::setDataMode(uint8_t dataMode)
  425. {
  426. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  427. // TODO: implement with native code
  428. SPCR1 = (SPCR1 & ~SPI_MODE_MASK) | dataMode;
  429. }
  430. void SPI1Class::setClockDivider_noInline(uint32_t clk)
  431. {
  432. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  433. uint32_t ctar = SPI1_CTAR0;
  434. ctar &= (SPI_CTAR_CPOL | SPI_CTAR_CPHA | SPI_CTAR_LSBFE);
  435. if (ctar & SPI_CTAR_CPHA) {
  436. clk = (clk & 0xFFFF0FFF) | ((clk & 0xF000) >> 4);
  437. }
  438. ctar |= clk;
  439. updateCTAR1(ctar);
  440. }
  441. uint8_t SPI1Class::pinIsChipSelect(uint8_t pin)
  442. {
  443. switch (pin) {
  444. case 6: return 0x01; // CS0
  445. case 31: return 0x01; // CS0
  446. case 58: return 0x02; //CS1
  447. case 62: return 0x01; //CS0
  448. case 63: return 0x04; //CS2
  449. }
  450. return 0;
  451. }
  452. bool SPI1Class::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  453. {
  454. uint8_t pin1_mask, pin2_mask;
  455. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  456. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  457. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  458. if ((pin1_mask & pin2_mask) != 0) return false;
  459. return true;
  460. }
  461. // setCS() is not intended for use from normal Arduino programs/sketches.
  462. uint8_t SPI1Class::setCS(uint8_t pin)
  463. {
  464. switch (pin) {
  465. case 6: CORE_PIN6_CONFIG = PORT_PCR_MUX(7); return 0x01; // PTD4
  466. case 31: CORE_PIN31_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD5
  467. case 58: CORE_PIN58_CONFIG = PORT_PCR_MUX(2); return 0x02; //CS1
  468. case 62: CORE_PIN62_CONFIG = PORT_PCR_MUX(2); return 0x01; //CS0
  469. case 63: CORE_PIN63_CONFIG = PORT_PCR_MUX(2); return 0x04; //CS2
  470. }
  471. return 0;
  472. }
  473. void SPI1Class::transfer(void *buf, size_t count)
  474. {
  475. if (count == 0) return;
  476. uint8_t *p_write = (uint8_t *)buf;
  477. uint8_t *p_read = p_write;
  478. size_t count_read = count;
  479. bool lsbfirst = (SPI1_CTAR0 & SPI_CTAR_LSBFE) ? true : false;
  480. // Lets clear the reader queue
  481. SPI1_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  482. uint32_t sr;
  483. // Now lets loop while we still have data to output
  484. if (count & 1) {
  485. KINETISK_SPI1.PUSHR = *p_write++ | SPI_PUSHR_CTAS(0);
  486. count--;
  487. }
  488. while (count > 0) {
  489. // Push out the next byte;
  490. uint16_t w = (*p_write++) << 8;
  491. w |= *p_write++;
  492. if (lsbfirst) w = __builtin_bswap16(w);
  493. KINETISK_SPI1.PUSHR = w | SPI_PUSHR_CTAS(1);
  494. count -= 2; // how many bytes to output.
  495. // Make sure queue is not full before pushing next byte out
  496. do {
  497. sr = KINETISK_SPI1.SR;
  498. if (sr & 0xF0) {
  499. uint16_t w = KINETISK_SPI1.POPR; // Read any pending RX bytes in
  500. if (count_read & 1) {
  501. *p_read++ = w; // Read any pending RX bytes in
  502. count_read--;
  503. } else {
  504. if (lsbfirst) w = __builtin_bswap16(w);
  505. *p_read++ = w >> 8;
  506. *p_read++ = (w & 0xff);
  507. count_read -= 2;
  508. }
  509. }
  510. } while ((sr & (15 << 12)) > (0 << 12)); // SPI1 and 2 only have 1 item queue
  511. }
  512. // now lets wait for all of the read bytes to be returned...
  513. while (count_read) {
  514. sr = KINETISK_SPI1.SR;
  515. if (sr & 0xF0) {
  516. uint16_t w = KINETISK_SPI1.POPR; // Read any pending RX bytes in
  517. if (count_read & 1) {
  518. *p_read++ = w; // Read any pending RX bytes in
  519. count_read--;
  520. } else {
  521. if (lsbfirst) w = __builtin_bswap16(w);
  522. *p_read++ = w >> 8;
  523. *p_read++ = (w & 0xff);
  524. count_read -= 2;
  525. }
  526. }
  527. }
  528. }
  529. // SPI2 Class
  530. SPI2Class SPI2;
  531. uint8_t SPI2Class::interruptMasksUsed = 0;
  532. uint32_t SPI2Class::interruptMask[(NVIC_NUM_INTERRUPTS+31)/32];
  533. uint32_t SPI2Class::interruptSave[(NVIC_NUM_INTERRUPTS+31)/32];
  534. #ifdef SPI_TRANSACTION_MISMATCH_LED
  535. uint8_t SPI2Class::inTransactionFlag = 0;
  536. #endif
  537. void SPI2Class::begin()
  538. {
  539. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  540. SPI2_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  541. SPI2_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  542. SPI2_CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  543. SPI2_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  544. SPCR2.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  545. }
  546. void SPI2Class::end() {
  547. SPCR2.disable_pins();
  548. SPI2_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  549. }
  550. void SPI2Class::usingInterrupt(IRQ_NUMBER_t interruptName)
  551. {
  552. uint32_t n = (uint32_t)interruptName;
  553. if (n >= NVIC_NUM_INTERRUPTS) return;
  554. //Serial.print("usingInterrupt ");
  555. //Serial.println(n);
  556. interruptMasksUsed |= (1 << (n >> 5));
  557. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  558. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  559. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  560. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  561. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  562. }
  563. void SPI2Class::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  564. {
  565. uint32_t n = (uint32_t)interruptName;
  566. if (n >= NVIC_NUM_INTERRUPTS) return;
  567. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  568. if (interruptMask[n >> 5] == 0) {
  569. interruptMasksUsed &= ~(1 << (n >> 5));
  570. }
  571. }
  572. static void updateCTAR2(uint32_t ctar)
  573. {
  574. if (SPI2_CTAR0 != ctar) {
  575. uint32_t mcr = SPI2_MCR;
  576. if (mcr & SPI_MCR_MDIS) {
  577. SPI2_CTAR0 = ctar;
  578. SPI2_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  579. } else {
  580. SPI2_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  581. SPI2_CTAR0 = ctar;
  582. SPI2_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  583. SPI2_MCR = mcr;
  584. }
  585. }
  586. }
  587. void SPI2Class::setBitOrder(uint8_t bitOrder)
  588. {
  589. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  590. uint32_t ctar = SPI2_CTAR0;
  591. if (bitOrder == LSBFIRST) {
  592. ctar |= SPI_CTAR_LSBFE;
  593. } else {
  594. ctar &= ~SPI_CTAR_LSBFE;
  595. }
  596. updateCTAR2(ctar);
  597. }
  598. void SPI2Class::setDataMode(uint8_t dataMode)
  599. {
  600. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  601. // TODO: implement with native code
  602. SPCR2 = (SPCR2 & ~SPI_MODE_MASK) | dataMode;
  603. }
  604. void SPI2Class::setClockDivider_noInline(uint32_t clk)
  605. {
  606. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  607. uint32_t ctar = SPI2_CTAR0;
  608. ctar &= (SPI_CTAR_CPOL | SPI_CTAR_CPHA | SPI_CTAR_LSBFE);
  609. if (ctar & SPI_CTAR_CPHA) {
  610. clk = (clk & 0xFFFF0FFF) | ((clk & 0xF000) >> 4);
  611. }
  612. ctar |= clk;
  613. updateCTAR2(ctar);
  614. }
  615. uint8_t SPI2Class::pinIsChipSelect(uint8_t pin)
  616. {
  617. switch (pin) {
  618. case 43: return 0x01; // CS0
  619. case 54: return 0x02; // CS1
  620. case 55: return 0x01; // CS0
  621. }
  622. return 0;
  623. }
  624. bool SPI2Class::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  625. {
  626. uint8_t pin1_mask, pin2_mask;
  627. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  628. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  629. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  630. if ((pin1_mask & pin2_mask) != 0) return false;
  631. return true;
  632. }
  633. // setCS() is not intended for use from normal Arduino programs/sketches.
  634. uint8_t SPI2Class::setCS(uint8_t pin)
  635. {
  636. switch (pin) {
  637. case 43: CORE_PIN43_CONFIG = PORT_PCR_MUX(2); return 0x01; // CS0
  638. case 54: CORE_PIN54_CONFIG = PORT_PCR_MUX(2); return 0x02; // CS1
  639. case 55: CORE_PIN55_CONFIG = PORT_PCR_MUX(2); return 0x01; // CS0
  640. }
  641. return 0;
  642. }
  643. void SPI2Class::transfer(void *buf, size_t count)
  644. {
  645. if (count == 0) return;
  646. uint8_t *p_write = (uint8_t *)buf;
  647. uint8_t *p_read = p_write;
  648. size_t count_read = count;
  649. bool lsbfirst = (SPI2_CTAR0 & SPI_CTAR_LSBFE) ? true : false;
  650. // Lets clear the reader queue
  651. SPI2_MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  652. uint32_t sr;
  653. // Now lets loop while we still have data to output
  654. if (count & 1) {
  655. KINETISK_SPI2.PUSHR = *p_write++ | SPI_PUSHR_CTAS(0);
  656. count--;
  657. }
  658. while (count > 0) {
  659. // Push out the next byte;
  660. uint16_t w = (*p_write++) << 8;
  661. w |= *p_write++;
  662. if (lsbfirst) w = __builtin_bswap16(w);
  663. KINETISK_SPI2.PUSHR = w | SPI_PUSHR_CTAS(1);
  664. count -= 2; // how many bytes to output.
  665. // Make sure queue is not full before pushing next byte out
  666. do {
  667. sr = KINETISK_SPI2.SR;
  668. if (sr & 0xF0) {
  669. uint16_t w = KINETISK_SPI2.POPR; // Read any pending RX bytes in
  670. if (count_read & 1) {
  671. *p_read++ = w; // Read any pending RX bytes in
  672. count_read--;
  673. } else {
  674. if (lsbfirst) w = __builtin_bswap16(w);
  675. *p_read++ = w >> 8;
  676. *p_read++ = (w & 0xff);
  677. count_read -= 2;
  678. }
  679. }
  680. } while ((sr & (15 << 12)) > (0 << 12)); // SPI2 and 2 only have 1 item queue
  681. }
  682. // now lets wait for all of the read bytes to be returned...
  683. while (count_read) {
  684. sr = KINETISK_SPI2.SR;
  685. if (sr & 0xF0) {
  686. uint16_t w = KINETISK_SPI2.POPR; // Read any pending RX bytes in
  687. if (count_read & 1) {
  688. *p_read++ = w; // Read any pending RX bytes in
  689. count_read--;
  690. } else {
  691. if (lsbfirst) w = __builtin_bswap16(w);
  692. *p_read++ = w >> 8;
  693. *p_read++ = (w & 0xff);
  694. count_read -= 2;
  695. }
  696. }
  697. }
  698. }
  699. #endif
  700. /**********************************************************/
  701. /* 32 bit Teensy-LC */
  702. /**********************************************************/
  703. #elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISL)
  704. SPIClass SPI;
  705. SPI1Class SPI1;
  706. uint32_t SPIClass::interruptMask = 0;
  707. uint32_t SPIClass::interruptSave = 0;
  708. uint32_t SPI1Class::interruptMask = 0;
  709. uint32_t SPI1Class::interruptSave = 0;
  710. #ifdef SPI_TRANSACTION_MISMATCH_LED
  711. uint8_t SPIClass::inTransactionFlag = 0;
  712. uint8_t SPI1Class::inTransactionFlag = 0;
  713. #endif
  714. void SPIClass::begin()
  715. {
  716. SIM_SCGC4 |= SIM_SCGC4_SPI0;
  717. SPI0_C1 = SPI_C1_SPE | SPI_C1_MSTR;
  718. SPI0_C2 = 0;
  719. uint8_t tmp __attribute__((unused)) = SPI0_S;
  720. SPCR.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  721. }
  722. void SPIClass::end() {
  723. SPCR.disable_pins();
  724. SPI0_C1 = 0;
  725. }
  726. const uint16_t SPISettings::br_div_table[30] = {
  727. 2, 4, 6, 8, 10, 12, 14, 16, 20, 24,
  728. 28, 32, 40, 48, 56, 64, 80, 96, 112, 128,
  729. 160, 192, 224, 256, 320, 384, 448, 512, 640, 768,
  730. };
  731. const uint8_t SPISettings::br_clock_table[30] = {
  732. SPI_BR_SPPR(0) | SPI_BR_SPR(0),
  733. SPI_BR_SPPR(1) | SPI_BR_SPR(0),
  734. SPI_BR_SPPR(2) | SPI_BR_SPR(0),
  735. SPI_BR_SPPR(3) | SPI_BR_SPR(0),
  736. SPI_BR_SPPR(4) | SPI_BR_SPR(0),
  737. SPI_BR_SPPR(5) | SPI_BR_SPR(0),
  738. SPI_BR_SPPR(6) | SPI_BR_SPR(0),
  739. SPI_BR_SPPR(7) | SPI_BR_SPR(0),
  740. SPI_BR_SPPR(4) | SPI_BR_SPR(1),
  741. SPI_BR_SPPR(5) | SPI_BR_SPR(1),
  742. SPI_BR_SPPR(6) | SPI_BR_SPR(1),
  743. SPI_BR_SPPR(7) | SPI_BR_SPR(1),
  744. SPI_BR_SPPR(4) | SPI_BR_SPR(2),
  745. SPI_BR_SPPR(5) | SPI_BR_SPR(2),
  746. SPI_BR_SPPR(6) | SPI_BR_SPR(2),
  747. SPI_BR_SPPR(7) | SPI_BR_SPR(2),
  748. SPI_BR_SPPR(4) | SPI_BR_SPR(3),
  749. SPI_BR_SPPR(5) | SPI_BR_SPR(3),
  750. SPI_BR_SPPR(6) | SPI_BR_SPR(3),
  751. SPI_BR_SPPR(7) | SPI_BR_SPR(3),
  752. SPI_BR_SPPR(4) | SPI_BR_SPR(4),
  753. SPI_BR_SPPR(5) | SPI_BR_SPR(4),
  754. SPI_BR_SPPR(6) | SPI_BR_SPR(4),
  755. SPI_BR_SPPR(7) | SPI_BR_SPR(4),
  756. SPI_BR_SPPR(4) | SPI_BR_SPR(5),
  757. SPI_BR_SPPR(5) | SPI_BR_SPR(5),
  758. SPI_BR_SPPR(6) | SPI_BR_SPR(5),
  759. SPI_BR_SPPR(7) | SPI_BR_SPR(5),
  760. SPI_BR_SPPR(4) | SPI_BR_SPR(6),
  761. SPI_BR_SPPR(5) | SPI_BR_SPR(6)
  762. };
  763. // setCS() is not intended for use from normal Arduino programs/sketches.
  764. uint8_t SPIClass::setCS(uint8_t pin)
  765. {
  766. switch (pin) {
  767. case 10: CORE_PIN10_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTC4
  768. case 2: CORE_PIN2_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD0
  769. }
  770. return 0;
  771. }
  772. void SPI1Class::begin()
  773. {
  774. SIM_SCGC4 |= SIM_SCGC4_SPI1;
  775. SPI1_C1 = SPI_C1_SPE | SPI_C1_MSTR;
  776. SPI1_C2 = 0;
  777. uint8_t tmp __attribute__((unused)) = SPI1_S;
  778. SPCR1.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  779. }
  780. void SPI1Class::end() {
  781. SPCR1.disable_pins();
  782. SPI1_C1 = 0;
  783. }
  784. // setCS() is not intended for use from normal Arduino programs/sketches.
  785. uint8_t SPI1Class::setCS(uint8_t pin)
  786. {
  787. switch (pin) {
  788. case 6: CORE_PIN6_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD4
  789. }
  790. return 0;
  791. }
  792. /**********************************************************/
  793. /* 32 bit Arduino Due */
  794. /**********************************************************/
  795. #elif defined(__arm__) && defined(__SAM3X8E__)
  796. #include "SPI.h"
  797. SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)) :
  798. spi(_spi), id(_id), initCb(_initCb), initialized(false)
  799. {
  800. // Empty
  801. }
  802. void SPIClass::begin() {
  803. init();
  804. // NPCS control is left to the user
  805. // Default speed set to 4Mhz
  806. setClockDivider(BOARD_SPI_DEFAULT_SS, 21);
  807. setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0);
  808. setBitOrder(BOARD_SPI_DEFAULT_SS, MSBFIRST);
  809. }
  810. void SPIClass::begin(uint8_t _pin) {
  811. init();
  812. uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
  813. PIO_Configure(
  814. g_APinDescription[spiPin].pPort,
  815. g_APinDescription[spiPin].ulPinType,
  816. g_APinDescription[spiPin].ulPin,
  817. g_APinDescription[spiPin].ulPinConfiguration);
  818. // Default speed set to 4Mhz
  819. setClockDivider(_pin, 21);
  820. setDataMode(_pin, SPI_MODE0);
  821. setBitOrder(_pin, MSBFIRST);
  822. }
  823. void SPIClass::init() {
  824. if (initialized)
  825. return;
  826. interruptMode = 0;
  827. interruptMask = 0;
  828. interruptSave = 0;
  829. initCb();
  830. SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS);
  831. SPI_Enable(spi);
  832. initialized = true;
  833. }
  834. #ifndef interruptsStatus
  835. #define interruptsStatus() __interruptsStatus()
  836. static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
  837. static inline unsigned char __interruptsStatus(void) {
  838. unsigned int primask;
  839. asm volatile ("mrs %0, primask" : "=r" (primask));
  840. if (primask) return 0;
  841. return 1;
  842. }
  843. #endif
  844. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  845. {
  846. uint8_t irestore;
  847. irestore = interruptsStatus();
  848. noInterrupts();
  849. if (interruptMode < 2) {
  850. if (interruptNumber > NUM_DIGITAL_PINS) {
  851. interruptMode = 2;
  852. } else {
  853. uint8_t imask = interruptMask;
  854. Pio *pio = g_APinDescription[interruptNumber].pPort;
  855. if (pio == PIOA) {
  856. imask |= 1;
  857. } else if (pio == PIOB) {
  858. imask |= 2;
  859. } else if (pio == PIOC) {
  860. imask |= 4;
  861. } else if (pio == PIOD) {
  862. imask |= 8;
  863. }
  864. interruptMask = imask;
  865. interruptMode = 1;
  866. }
  867. }
  868. if (irestore) interrupts();
  869. }
  870. void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
  871. {
  872. if (interruptMode > 0) {
  873. if (interruptMode == 1) {
  874. uint8_t imask = interruptMask;
  875. if (imask & 1) NVIC_DisableIRQ(PIOA_IRQn);
  876. if (imask & 2) NVIC_DisableIRQ(PIOB_IRQn);
  877. if (imask & 4) NVIC_DisableIRQ(PIOC_IRQn);
  878. if (imask & 8) NVIC_DisableIRQ(PIOD_IRQn);
  879. } else {
  880. interruptSave = interruptsStatus();
  881. noInterrupts();
  882. }
  883. }
  884. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(pin);
  885. bitOrder[ch] = settings.border;
  886. SPI_ConfigureNPCS(spi, ch, settings.config);
  887. }
  888. void SPIClass::endTransaction(void)
  889. {
  890. if (interruptMode > 0) {
  891. if (interruptMode == 1) {
  892. uint8_t imask = interruptMask;
  893. if (imask & 1) NVIC_EnableIRQ(PIOA_IRQn);
  894. if (imask & 2) NVIC_EnableIRQ(PIOB_IRQn);
  895. if (imask & 4) NVIC_EnableIRQ(PIOC_IRQn);
  896. if (imask & 8) NVIC_EnableIRQ(PIOD_IRQn);
  897. } else {
  898. if (interruptSave) interrupts();
  899. }
  900. }
  901. }
  902. void SPIClass::end(uint8_t _pin) {
  903. uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
  904. // Setting the pin as INPUT will disconnect it from SPI peripheral
  905. pinMode(spiPin, INPUT);
  906. }
  907. void SPIClass::end() {
  908. SPI_Disable(spi);
  909. initialized = false;
  910. }
  911. void SPIClass::setBitOrder(uint8_t _pin, BitOrder _bitOrder) {
  912. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  913. bitOrder[ch] = _bitOrder;
  914. }
  915. void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) {
  916. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  917. mode[ch] = _mode | SPI_CSR_CSAAT;
  918. // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
  919. // transfer. Some device needs that for working properly.
  920. SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
  921. }
  922. void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) {
  923. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  924. divider[ch] = _divider;
  925. // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
  926. // transfer. Some device needs that for working properly.
  927. SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
  928. }
  929. byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
  930. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  931. // Reverse bit order
  932. if (bitOrder[ch] == LSBFIRST)
  933. _data = __REV(__RBIT(_data));
  934. uint32_t d = _data | SPI_PCS(ch);
  935. if (_mode == SPI_LAST)
  936. d |= SPI_TDR_LASTXFER;
  937. // SPI_Write(spi, _channel, _data);
  938. while ((spi->SPI_SR & SPI_SR_TDRE) == 0)
  939. ;
  940. spi->SPI_TDR = d;
  941. // return SPI_Read(spi);
  942. while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
  943. ;
  944. d = spi->SPI_RDR;
  945. // Reverse bit order
  946. if (bitOrder[ch] == LSBFIRST)
  947. d = __REV(__RBIT(d));
  948. return d & 0xFF;
  949. }
  950. void SPIClass::attachInterrupt(void) {
  951. // Should be enableInterrupt()
  952. }
  953. void SPIClass::detachInterrupt(void) {
  954. // Should be disableInterrupt()
  955. }
  956. #if SPI_INTERFACES_COUNT > 0
  957. static void SPI_0_Init(void) {
  958. PIO_Configure(
  959. g_APinDescription[PIN_SPI_MOSI].pPort,
  960. g_APinDescription[PIN_SPI_MOSI].ulPinType,
  961. g_APinDescription[PIN_SPI_MOSI].ulPin,
  962. g_APinDescription[PIN_SPI_MOSI].ulPinConfiguration);
  963. PIO_Configure(
  964. g_APinDescription[PIN_SPI_MISO].pPort,
  965. g_APinDescription[PIN_SPI_MISO].ulPinType,
  966. g_APinDescription[PIN_SPI_MISO].ulPin,
  967. g_APinDescription[PIN_SPI_MISO].ulPinConfiguration);
  968. PIO_Configure(
  969. g_APinDescription[PIN_SPI_SCK].pPort,
  970. g_APinDescription[PIN_SPI_SCK].ulPinType,
  971. g_APinDescription[PIN_SPI_SCK].ulPin,
  972. g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
  973. }
  974. SPIClass SPI(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init);
  975. #endif
  976. #endif