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

909 rindas
24KB

  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. #endif
  257. }
  258. return 0;
  259. }
  260. bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  261. {
  262. uint8_t pin1_mask, pin2_mask;
  263. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  264. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  265. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  266. if ((pin1_mask & pin2_mask) != 0) return false;
  267. return true;
  268. }
  269. uint8_t SPIClass::setCS(uint8_t pin)
  270. {
  271. switch (pin) {
  272. case 10: CORE_PIN10_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTC4
  273. case 2: CORE_PIN2_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD0
  274. case 9: CORE_PIN9_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTC3
  275. case 6: CORE_PIN6_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTD4
  276. case 20: CORE_PIN20_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTD5
  277. case 23: CORE_PIN23_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTC2
  278. case 21: CORE_PIN21_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTD6
  279. case 22: CORE_PIN22_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTC1
  280. case 15: CORE_PIN15_CONFIG = PORT_PCR_MUX(2); return 0x10; // PTC0
  281. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  282. case 26: CORE_PIN26_CONFIG = PORT_PCR_MUX(2);return 0x01;
  283. #endif
  284. }
  285. return 0;
  286. }
  287. /**********************************************************/
  288. /* 32 bit Teensy-3.5/3.6 */
  289. /**********************************************************/
  290. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  291. SPI1Class SPI1;
  292. uint8_t SPI1Class::interruptMasksUsed = 0;
  293. uint32_t SPI1Class::interruptMask[(NVIC_NUM_INTERRUPTS+31)/32];
  294. uint32_t SPI1Class::interruptSave[(NVIC_NUM_INTERRUPTS+31)/32];
  295. #ifdef SPI_TRANSACTION_MISMATCH_LED
  296. uint8_t SPI1Class::inTransactionFlag = 0;
  297. #endif
  298. void SPI1Class::begin()
  299. {
  300. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  301. SPI1_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  302. SPI1_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  303. SPI1_CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  304. SPI1_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  305. SPCR1.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  306. }
  307. void SPI1Class::end() {
  308. SPCR1.disable_pins();
  309. SPI1_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  310. }
  311. void SPI1Class::usingInterrupt(IRQ_NUMBER_t interruptName)
  312. {
  313. uint32_t n = (uint32_t)interruptName;
  314. if (n >= NVIC_NUM_INTERRUPTS) return;
  315. //Serial.print("usingInterrupt ");
  316. //Serial.println(n);
  317. interruptMasksUsed |= (1 << (n >> 5));
  318. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  319. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  320. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  321. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  322. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  323. }
  324. void SPI1Class::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  325. {
  326. uint32_t n = (uint32_t)interruptName;
  327. if (n >= NVIC_NUM_INTERRUPTS) return;
  328. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  329. if (interruptMask[n >> 5] == 0) {
  330. interruptMasksUsed &= ~(1 << (n >> 5));
  331. }
  332. }
  333. static void updateCTAR1(uint32_t ctar)
  334. {
  335. if (SPI1_CTAR0 != ctar) {
  336. uint32_t mcr = SPI1_MCR;
  337. if (mcr & SPI_MCR_MDIS) {
  338. SPI1_CTAR0 = ctar;
  339. SPI1_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  340. } else {
  341. SPI1_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  342. SPI1_CTAR0 = ctar;
  343. SPI1_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  344. SPI1_MCR = mcr;
  345. }
  346. }
  347. }
  348. void SPI1Class::setBitOrder(uint8_t bitOrder)
  349. {
  350. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  351. uint32_t ctar = SPI1_CTAR0;
  352. if (bitOrder == LSBFIRST) {
  353. ctar |= SPI_CTAR_LSBFE;
  354. } else {
  355. ctar &= ~SPI_CTAR_LSBFE;
  356. }
  357. updateCTAR1(ctar);
  358. }
  359. void SPI1Class::setDataMode(uint8_t dataMode)
  360. {
  361. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  362. // TODO: implement with native code
  363. SPCR1 = (SPCR1 & ~SPI_MODE_MASK) | dataMode;
  364. }
  365. void SPI1Class::setClockDivider_noInline(uint32_t clk)
  366. {
  367. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  368. uint32_t ctar = SPI1_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. updateCTAR1(ctar);
  375. }
  376. bool SPI1Class::pinIsChipSelect(uint8_t pin)
  377. {
  378. if (pin == 6 || pin == 31) return true;
  379. return false;
  380. }
  381. bool SPI1Class::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  382. {
  383. return false; // only one CS bith 6 and 31 or logially the same.
  384. }
  385. uint8_t SPI1Class::setCS(uint8_t pin)
  386. {
  387. switch (pin) {
  388. case 6: CORE_PIN6_CONFIG = PORT_PCR_MUX(7); return 0x01; // PTD4
  389. case 31: CORE_PIN31_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD5
  390. }
  391. return 0;
  392. }
  393. // SPI2 Class
  394. SPI2Class SPI2;
  395. uint8_t SPI2Class::interruptMasksUsed = 0;
  396. uint32_t SPI2Class::interruptMask[(NVIC_NUM_INTERRUPTS+31)/32];
  397. uint32_t SPI2Class::interruptSave[(NVIC_NUM_INTERRUPTS+31)/32];
  398. #ifdef SPI_TRANSACTION_MISMATCH_LED
  399. uint8_t SPI2Class::inTransactionFlag = 0;
  400. #endif
  401. void SPI2Class::begin()
  402. {
  403. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  404. SPI2_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  405. SPI2_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  406. SPI2_CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  407. SPI2_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  408. SPCR2.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  409. }
  410. void SPI2Class::end() {
  411. SPCR2.disable_pins();
  412. SPI2_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  413. }
  414. void SPI2Class::usingInterrupt(IRQ_NUMBER_t interruptName)
  415. {
  416. uint32_t n = (uint32_t)interruptName;
  417. if (n >= NVIC_NUM_INTERRUPTS) return;
  418. //Serial.print("usingInterrupt ");
  419. //Serial.println(n);
  420. interruptMasksUsed |= (1 << (n >> 5));
  421. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  422. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  423. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  424. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  425. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  426. }
  427. void SPI2Class::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  428. {
  429. uint32_t n = (uint32_t)interruptName;
  430. if (n >= NVIC_NUM_INTERRUPTS) return;
  431. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  432. if (interruptMask[n >> 5] == 0) {
  433. interruptMasksUsed &= ~(1 << (n >> 5));
  434. }
  435. }
  436. static void updateCTAR2(uint32_t ctar)
  437. {
  438. if (SPI2_CTAR0 != ctar) {
  439. uint32_t mcr = SPI2_MCR;
  440. if (mcr & SPI_MCR_MDIS) {
  441. SPI2_CTAR0 = ctar;
  442. SPI2_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  443. } else {
  444. SPI2_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  445. SPI2_CTAR0 = ctar;
  446. SPI2_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  447. SPI2_MCR = mcr;
  448. }
  449. }
  450. }
  451. void SPI2Class::setBitOrder(uint8_t bitOrder)
  452. {
  453. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  454. uint32_t ctar = SPI2_CTAR0;
  455. if (bitOrder == LSBFIRST) {
  456. ctar |= SPI_CTAR_LSBFE;
  457. } else {
  458. ctar &= ~SPI_CTAR_LSBFE;
  459. }
  460. updateCTAR2(ctar);
  461. }
  462. void SPI2Class::setDataMode(uint8_t dataMode)
  463. {
  464. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  465. // TODO: implement with native code
  466. SPCR2 = (SPCR2 & ~SPI_MODE_MASK) | dataMode;
  467. }
  468. void SPI2Class::setClockDivider_noInline(uint32_t clk)
  469. {
  470. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  471. uint32_t ctar = SPI2_CTAR0;
  472. ctar &= (SPI_CTAR_CPOL | SPI_CTAR_CPHA | SPI_CTAR_LSBFE);
  473. if (ctar & SPI_CTAR_CPHA) {
  474. clk = (clk & 0xFFFF0FFF) | ((clk & 0xF000) >> 4);
  475. }
  476. ctar |= clk;
  477. updateCTAR2(ctar);
  478. }
  479. uint8_t SPI2Class::pinIsChipSelect(uint8_t pin)
  480. {
  481. switch (pin) {
  482. case 43: return 0x01; // CS0
  483. case 54: return 0x02; // CS1
  484. case 55: return 0x01; // CS0
  485. }
  486. return 0;
  487. }
  488. bool SPI2Class::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  489. {
  490. uint8_t pin1_mask, pin2_mask;
  491. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  492. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  493. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  494. if ((pin1_mask & pin2_mask) != 0) return false;
  495. return true;
  496. }
  497. uint8_t SPI2Class::setCS(uint8_t pin)
  498. {
  499. switch (pin) {
  500. case 43: CORE_PIN43_CONFIG = PORT_PCR_MUX(2); return 0x01; // CS0
  501. case 54: CORE_PIN54_CONFIG = PORT_PCR_MUX(2); return 0x02; // CS1
  502. case 55: CORE_PIN55_CONFIG = PORT_PCR_MUX(2); return 0x01; // CS0
  503. }
  504. return 0;
  505. }
  506. #endif
  507. /**********************************************************/
  508. /* 32 bit Teensy-LC */
  509. /**********************************************************/
  510. #elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISL)
  511. SPIClass SPI;
  512. SPI1Class SPI1;
  513. uint32_t SPIClass::interruptMask = 0;
  514. uint32_t SPIClass::interruptSave = 0;
  515. uint32_t SPI1Class::interruptMask = 0;
  516. uint32_t SPI1Class::interruptSave = 0;
  517. #ifdef SPI_TRANSACTION_MISMATCH_LED
  518. uint8_t SPIClass::inTransactionFlag = 0;
  519. uint8_t SPI1Class::inTransactionFlag = 0;
  520. #endif
  521. void SPIClass::begin()
  522. {
  523. SIM_SCGC4 |= SIM_SCGC4_SPI0;
  524. SPI0_C1 = SPI_C1_SPE | SPI_C1_MSTR;
  525. SPI0_C2 = 0;
  526. uint8_t tmp __attribute__((unused)) = SPI0_S;
  527. SPCR.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  528. }
  529. void SPIClass::end() {
  530. SPCR.disable_pins();
  531. SPI0_C1 = 0;
  532. }
  533. const uint16_t SPISettings::br_div_table[30] = {
  534. 2, 4, 6, 8, 10, 12, 14, 16, 20, 24,
  535. 28, 32, 40, 48, 56, 64, 80, 96, 112, 128,
  536. 160, 192, 224, 256, 320, 384, 448, 512, 640, 768,
  537. };
  538. const uint8_t SPISettings::br_clock_table[30] = {
  539. SPI_BR_SPPR(0) | SPI_BR_SPR(0),
  540. SPI_BR_SPPR(1) | SPI_BR_SPR(0),
  541. SPI_BR_SPPR(2) | SPI_BR_SPR(0),
  542. SPI_BR_SPPR(3) | SPI_BR_SPR(0),
  543. SPI_BR_SPPR(4) | SPI_BR_SPR(0),
  544. SPI_BR_SPPR(5) | SPI_BR_SPR(0),
  545. SPI_BR_SPPR(6) | SPI_BR_SPR(0),
  546. SPI_BR_SPPR(7) | SPI_BR_SPR(0),
  547. SPI_BR_SPPR(4) | SPI_BR_SPR(1),
  548. SPI_BR_SPPR(5) | SPI_BR_SPR(1),
  549. SPI_BR_SPPR(6) | SPI_BR_SPR(1),
  550. SPI_BR_SPPR(7) | SPI_BR_SPR(1),
  551. SPI_BR_SPPR(4) | SPI_BR_SPR(2),
  552. SPI_BR_SPPR(5) | SPI_BR_SPR(2),
  553. SPI_BR_SPPR(6) | SPI_BR_SPR(2),
  554. SPI_BR_SPPR(7) | SPI_BR_SPR(2),
  555. SPI_BR_SPPR(4) | SPI_BR_SPR(3),
  556. SPI_BR_SPPR(5) | SPI_BR_SPR(3),
  557. SPI_BR_SPPR(6) | SPI_BR_SPR(3),
  558. SPI_BR_SPPR(7) | SPI_BR_SPR(3),
  559. SPI_BR_SPPR(4) | SPI_BR_SPR(4),
  560. SPI_BR_SPPR(5) | SPI_BR_SPR(4),
  561. SPI_BR_SPPR(6) | SPI_BR_SPR(4),
  562. SPI_BR_SPPR(7) | SPI_BR_SPR(4),
  563. SPI_BR_SPPR(4) | SPI_BR_SPR(5),
  564. SPI_BR_SPPR(5) | SPI_BR_SPR(5),
  565. SPI_BR_SPPR(6) | SPI_BR_SPR(5),
  566. SPI_BR_SPPR(7) | SPI_BR_SPR(5),
  567. SPI_BR_SPPR(4) | SPI_BR_SPR(6),
  568. SPI_BR_SPPR(5) | SPI_BR_SPR(6)
  569. };
  570. uint8_t SPIClass::setCS(uint8_t pin)
  571. {
  572. switch (pin) {
  573. case 10: CORE_PIN10_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTC4
  574. case 2: CORE_PIN2_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD0
  575. }
  576. return 0;
  577. }
  578. void SPI1Class::begin()
  579. {
  580. SIM_SCGC4 |= SIM_SCGC4_SPI1;
  581. SPI1_C1 = SPI_C1_SPE | SPI_C1_MSTR;
  582. SPI1_C2 = 0;
  583. uint8_t tmp __attribute__((unused)) = SPI1_S;
  584. SPCR1.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  585. }
  586. void SPI1Class::end() {
  587. SPCR1.disable_pins();
  588. SPI1_C1 = 0;
  589. }
  590. uint8_t SPI1Class::setCS(uint8_t pin)
  591. {
  592. switch (pin) {
  593. case 6: CORE_PIN6_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD4
  594. }
  595. return 0;
  596. }
  597. /**********************************************************/
  598. /* 32 bit Arduino Due */
  599. /**********************************************************/
  600. #elif defined(__arm__) && defined(__SAM3X8E__)
  601. #include "SPI.h"
  602. SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)) :
  603. spi(_spi), id(_id), initCb(_initCb), initialized(false)
  604. {
  605. // Empty
  606. }
  607. void SPIClass::begin() {
  608. init();
  609. // NPCS control is left to the user
  610. // Default speed set to 4Mhz
  611. setClockDivider(BOARD_SPI_DEFAULT_SS, 21);
  612. setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0);
  613. setBitOrder(BOARD_SPI_DEFAULT_SS, MSBFIRST);
  614. }
  615. void SPIClass::begin(uint8_t _pin) {
  616. init();
  617. uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
  618. PIO_Configure(
  619. g_APinDescription[spiPin].pPort,
  620. g_APinDescription[spiPin].ulPinType,
  621. g_APinDescription[spiPin].ulPin,
  622. g_APinDescription[spiPin].ulPinConfiguration);
  623. // Default speed set to 4Mhz
  624. setClockDivider(_pin, 21);
  625. setDataMode(_pin, SPI_MODE0);
  626. setBitOrder(_pin, MSBFIRST);
  627. }
  628. void SPIClass::init() {
  629. if (initialized)
  630. return;
  631. interruptMode = 0;
  632. interruptMask = 0;
  633. interruptSave = 0;
  634. initCb();
  635. SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS);
  636. SPI_Enable(spi);
  637. initialized = true;
  638. }
  639. #ifndef interruptsStatus
  640. #define interruptsStatus() __interruptsStatus()
  641. static inline unsigned char __interruptsStatus(void) __attribute__((always_inline, unused));
  642. static inline unsigned char __interruptsStatus(void) {
  643. unsigned int primask;
  644. asm volatile ("mrs %0, primask" : "=r" (primask));
  645. if (primask) return 0;
  646. return 1;
  647. }
  648. #endif
  649. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  650. {
  651. uint8_t irestore;
  652. irestore = interruptsStatus();
  653. noInterrupts();
  654. if (interruptMode < 2) {
  655. if (interruptNumber > NUM_DIGITAL_PINS) {
  656. interruptMode = 2;
  657. } else {
  658. uint8_t imask = interruptMask;
  659. Pio *pio = g_APinDescription[interruptNumber].pPort;
  660. if (pio == PIOA) {
  661. imask |= 1;
  662. } else if (pio == PIOB) {
  663. imask |= 2;
  664. } else if (pio == PIOC) {
  665. imask |= 4;
  666. } else if (pio == PIOD) {
  667. imask |= 8;
  668. }
  669. interruptMask = imask;
  670. interruptMode = 1;
  671. }
  672. }
  673. if (irestore) interrupts();
  674. }
  675. void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
  676. {
  677. if (interruptMode > 0) {
  678. if (interruptMode == 1) {
  679. uint8_t imask = interruptMask;
  680. if (imask & 1) NVIC_DisableIRQ(PIOA_IRQn);
  681. if (imask & 2) NVIC_DisableIRQ(PIOB_IRQn);
  682. if (imask & 4) NVIC_DisableIRQ(PIOC_IRQn);
  683. if (imask & 8) NVIC_DisableIRQ(PIOD_IRQn);
  684. } else {
  685. interruptSave = interruptsStatus();
  686. noInterrupts();
  687. }
  688. }
  689. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(pin);
  690. bitOrder[ch] = settings.border;
  691. SPI_ConfigureNPCS(spi, ch, settings.config);
  692. }
  693. void SPIClass::endTransaction(void)
  694. {
  695. if (interruptMode > 0) {
  696. if (interruptMode == 1) {
  697. uint8_t imask = interruptMask;
  698. if (imask & 1) NVIC_EnableIRQ(PIOA_IRQn);
  699. if (imask & 2) NVIC_EnableIRQ(PIOB_IRQn);
  700. if (imask & 4) NVIC_EnableIRQ(PIOC_IRQn);
  701. if (imask & 8) NVIC_EnableIRQ(PIOD_IRQn);
  702. } else {
  703. if (interruptSave) interrupts();
  704. }
  705. }
  706. }
  707. void SPIClass::end(uint8_t _pin) {
  708. uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
  709. // Setting the pin as INPUT will disconnect it from SPI peripheral
  710. pinMode(spiPin, INPUT);
  711. }
  712. void SPIClass::end() {
  713. SPI_Disable(spi);
  714. initialized = false;
  715. }
  716. void SPIClass::setBitOrder(uint8_t _pin, BitOrder _bitOrder) {
  717. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  718. bitOrder[ch] = _bitOrder;
  719. }
  720. void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) {
  721. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  722. mode[ch] = _mode | SPI_CSR_CSAAT;
  723. // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
  724. // transfer. Some device needs that for working properly.
  725. SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
  726. }
  727. void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) {
  728. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  729. divider[ch] = _divider;
  730. // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
  731. // transfer. Some device needs that for working properly.
  732. SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
  733. }
  734. byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
  735. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  736. // Reverse bit order
  737. if (bitOrder[ch] == LSBFIRST)
  738. _data = __REV(__RBIT(_data));
  739. uint32_t d = _data | SPI_PCS(ch);
  740. if (_mode == SPI_LAST)
  741. d |= SPI_TDR_LASTXFER;
  742. // SPI_Write(spi, _channel, _data);
  743. while ((spi->SPI_SR & SPI_SR_TDRE) == 0)
  744. ;
  745. spi->SPI_TDR = d;
  746. // return SPI_Read(spi);
  747. while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
  748. ;
  749. d = spi->SPI_RDR;
  750. // Reverse bit order
  751. if (bitOrder[ch] == LSBFIRST)
  752. d = __REV(__RBIT(d));
  753. return d & 0xFF;
  754. }
  755. void SPIClass::attachInterrupt(void) {
  756. // Should be enableInterrupt()
  757. }
  758. void SPIClass::detachInterrupt(void) {
  759. // Should be disableInterrupt()
  760. }
  761. #if SPI_INTERFACES_COUNT > 0
  762. static void SPI_0_Init(void) {
  763. PIO_Configure(
  764. g_APinDescription[PIN_SPI_MOSI].pPort,
  765. g_APinDescription[PIN_SPI_MOSI].ulPinType,
  766. g_APinDescription[PIN_SPI_MOSI].ulPin,
  767. g_APinDescription[PIN_SPI_MOSI].ulPinConfiguration);
  768. PIO_Configure(
  769. g_APinDescription[PIN_SPI_MISO].pPort,
  770. g_APinDescription[PIN_SPI_MISO].ulPinType,
  771. g_APinDescription[PIN_SPI_MISO].ulPin,
  772. g_APinDescription[PIN_SPI_MISO].ulPinConfiguration);
  773. PIO_Configure(
  774. g_APinDescription[PIN_SPI_SCK].pPort,
  775. g_APinDescription[PIN_SPI_SCK].ulPinType,
  776. g_APinDescription[PIN_SPI_SCK].ulPin,
  777. g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
  778. }
  779. SPIClass SPI(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init);
  780. #endif
  781. #endif