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.

499 lines
14KB

  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. void SPIClass::begin()
  21. {
  22. // Set SS to high so a connected chip will be "deselected" by default
  23. digitalWrite(SS, HIGH);
  24. // When the SS pin is set as OUTPUT, it can be used as
  25. // a general purpose output port (it doesn't influence
  26. // SPI operations).
  27. pinMode(SS, OUTPUT);
  28. // Warning: if the SS pin ever becomes a LOW INPUT then SPI
  29. // automatically switches to Slave, so the data direction of
  30. // the SS pin MUST be kept as OUTPUT.
  31. SPCR |= _BV(MSTR);
  32. SPCR |= _BV(SPE);
  33. // Set direction register for SCK and MOSI pin.
  34. // MISO pin automatically overrides to INPUT.
  35. // By doing this AFTER enabling SPI, we avoid accidentally
  36. // clocking in a single bit since the lines go directly
  37. // from "input" to SPI control.
  38. // http://code.google.com/p/arduino/issues/detail?id=888
  39. pinMode(SCK, OUTPUT);
  40. pinMode(MOSI, OUTPUT);
  41. }
  42. void SPIClass::end() {
  43. SPCR &= ~_BV(SPE);
  44. }
  45. // mapping of interrupt numbers to bits within SPI_AVR_EIMSK
  46. #if defined(__AVR_ATmega32U4__)
  47. #define SPI_INT0_MASK (1<<INT0)
  48. #define SPI_INT1_MASK (1<<INT1)
  49. #define SPI_INT2_MASK (1<<INT2)
  50. #define SPI_INT3_MASK (1<<INT3)
  51. #define SPI_INT4_MASK (1<<INT6)
  52. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  53. #define SPI_INT0_MASK (1<<INT0)
  54. #define SPI_INT1_MASK (1<<INT1)
  55. #define SPI_INT2_MASK (1<<INT2)
  56. #define SPI_INT3_MASK (1<<INT3)
  57. #define SPI_INT4_MASK (1<<INT4)
  58. #define SPI_INT5_MASK (1<<INT5)
  59. #define SPI_INT6_MASK (1<<INT6)
  60. #define SPI_INT7_MASK (1<<INT7)
  61. #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
  62. #define SPI_INT0_MASK (1<<INT4)
  63. #define SPI_INT1_MASK (1<<INT5)
  64. #define SPI_INT2_MASK (1<<INT0)
  65. #define SPI_INT3_MASK (1<<INT1)
  66. #define SPI_INT4_MASK (1<<INT2)
  67. #define SPI_INT5_MASK (1<<INT3)
  68. #define SPI_INT6_MASK (1<<INT6)
  69. #define SPI_INT7_MASK (1<<INT7)
  70. #else
  71. #ifdef INT0
  72. #define SPI_INT0_MASK (1<<INT0)
  73. #endif
  74. #ifdef INT1
  75. #define SPI_INT1_MASK (1<<INT1)
  76. #endif
  77. #ifdef INT2
  78. #define SPI_INT2_MASK (1<<INT2)
  79. #endif
  80. #endif
  81. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  82. {
  83. uint8_t mask;
  84. if (interruptMode > 1) return;
  85. noInterrupts();
  86. switch (interruptNumber) {
  87. #ifdef SPI_INT0_MASK
  88. case 0: mask = SPI_INT0_MASK; break;
  89. #endif
  90. #ifdef SPI_INT1_MASK
  91. case 1: mask = SPI_INT1_MASK; break;
  92. #endif
  93. #ifdef SPI_INT2_MASK
  94. case 2: mask = SPI_INT2_MASK; break;
  95. #endif
  96. #ifdef SPI_INT3_MASK
  97. case 3: mask = SPI_INT3_MASK; break;
  98. #endif
  99. #ifdef SPI_INT4_MASK
  100. case 4: mask = SPI_INT4_MASK; break;
  101. #endif
  102. #ifdef SPI_INT5_MASK
  103. case 5: mask = SPI_INT5_MASK; break;
  104. #endif
  105. #ifdef SPI_INT6_MASK
  106. case 6: mask = SPI_INT6_MASK; break;
  107. #endif
  108. #ifdef SPI_INT7_MASK
  109. case 7: mask = SPI_INT7_MASK; break;
  110. #endif
  111. default:
  112. interruptMode = 2;
  113. interrupts();
  114. return;
  115. }
  116. interruptMode = 1;
  117. interruptMask |= mask;
  118. interrupts();
  119. }
  120. /**********************************************************/
  121. /* 32 bit Teensy 3.0 and 3.1 */
  122. /**********************************************************/
  123. #elif defined(__arm__) && defined(TEENSYDUINO)
  124. SPIClass SPI;
  125. uint8_t SPIClass::interruptMode = 0;
  126. uint8_t SPIClass::interruptMask = 0;
  127. uint8_t SPIClass::interruptSave = 0;
  128. void SPIClass::begin()
  129. {
  130. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  131. SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  132. SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  133. SPI0_CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  134. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  135. SPCR.enable_pins(); // pins managed by SPCRemulation in avr_emulation.h
  136. }
  137. void SPIClass::end() {
  138. SPCR.disable_pins();
  139. SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  140. }
  141. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  142. {
  143. // TODO: implement this...
  144. }
  145. void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName)
  146. {
  147. // TODO: implement this...
  148. }
  149. const uint16_t SPISettings::ctar_div_table[23] = {
  150. 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40,
  151. 56, 64, 96, 128, 192, 256, 384, 512, 640, 768
  152. };
  153. const uint32_t SPISettings::ctar_clock_table[23] = {
  154. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  155. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  156. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  157. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  158. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  159. SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  160. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  161. SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  162. SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  163. SPI_CTAR_PBR(2) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(0),
  164. SPI_CTAR_PBR(1) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  165. SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(3),
  166. SPI_CTAR_PBR(2) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  167. SPI_CTAR_PBR(3) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  168. SPI_CTAR_PBR(0) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  169. SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  170. SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  171. SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  172. SPI_CTAR_PBR(0) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  173. SPI_CTAR_PBR(1) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  174. SPI_CTAR_PBR(0) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7),
  175. SPI_CTAR_PBR(2) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  176. SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7)
  177. };
  178. static void updateCTAR(uint32_t ctar)
  179. {
  180. if (SPI0_CTAR0 != ctar) {
  181. uint32_t mcr = SPI0_MCR;
  182. if (mcr & SPI_MCR_MDIS) {
  183. SPI0_CTAR0 = ctar;
  184. SPI0_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  185. } else {
  186. SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  187. SPI0_CTAR0 = ctar;
  188. SPI0_CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  189. SPI0_MCR = mcr;
  190. }
  191. }
  192. }
  193. void SPIClass::setBitOrder(uint8_t bitOrder)
  194. {
  195. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  196. uint32_t ctar = SPI0_CTAR0;
  197. if (bitOrder == LSBFIRST) {
  198. ctar |= SPI_CTAR_LSBFE;
  199. } else {
  200. ctar &= ~SPI_CTAR_LSBFE;
  201. }
  202. updateCTAR(ctar);
  203. }
  204. void SPIClass::setDataMode(uint8_t dataMode)
  205. {
  206. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  207. // TODO: implement with native code
  208. SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  209. }
  210. void SPIClass::setClockDivider_noInline(uint32_t clk)
  211. {
  212. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  213. uint32_t ctar = SPI0_CTAR0;
  214. ctar &= (SPI_CTAR_CPOL | SPI_CTAR_CPHA | SPI_CTAR_LSBFE);
  215. if (ctar & SPI_CTAR_CPHA) {
  216. clk = (clk & 0xFFFF0FFF) | ((clk & 0xF000) >> 4);
  217. }
  218. ctar |= clk;
  219. updateCTAR(ctar);
  220. }
  221. bool SPIClass::pinIsChipSelect(uint8_t pin)
  222. {
  223. if (pin == 10 || pin == 9 || pin == 6 || pin == 2 || pin == 15) return true;
  224. if (pin >= 20 && pin <= 23) return true;
  225. return false;
  226. }
  227. bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  228. {
  229. if (!pinIsChipSelect(pin1) || !pinIsChipSelect(pin2)) return false;
  230. if ((pin1 == 2 && pin2 == 10) || (pin1 == 10 && pin2 == 2)) return false;
  231. if ((pin1 == 6 && pin2 == 9) || (pin1 == 9 && pin2 == 6)) return false;
  232. if ((pin1 == 20 && pin2 == 23) || (pin1 == 23 && pin2 == 20)) return false;
  233. if ((pin1 == 21 && pin2 == 22) || (pin1 == 22 && pin2 == 21)) return false;
  234. return true;
  235. }
  236. uint8_t SPIClass::setCS(uint8_t pin)
  237. {
  238. switch (pin) {
  239. case 10: CORE_PIN10_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTC4
  240. case 2: CORE_PIN2_CONFIG = PORT_PCR_MUX(2); return 0x01; // PTD0
  241. case 9: CORE_PIN9_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTC3
  242. case 6: CORE_PIN6_CONFIG = PORT_PCR_MUX(2); return 0x02; // PTD4
  243. case 20: CORE_PIN20_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTD5
  244. case 23: CORE_PIN23_CONFIG = PORT_PCR_MUX(2); return 0x04; // PTC2
  245. case 21: CORE_PIN21_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTD6
  246. case 22: CORE_PIN22_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTC1
  247. case 15: CORE_PIN15_CONFIG = PORT_PCR_MUX(2); return 0x10; // PTC0
  248. }
  249. return 0;
  250. }
  251. /**********************************************************/
  252. /* 32 bit Arduino Due */
  253. /**********************************************************/
  254. #elif defined(__arm__) && defined(__SAM3X8E__)
  255. #include "SPI.h"
  256. uint8_t SPIClass::interruptMode = 0;
  257. uint8_t SPIClass::interruptMask = 0;
  258. uint8_t SPIClass::interruptSave = 0;
  259. SPIClass::SPIClass(Spi *_spi, uint32_t _id, void(*_initCb)(void)) :
  260. spi(_spi), id(_id), initCb(_initCb), initialized(false)
  261. {
  262. // Empty
  263. }
  264. void SPIClass::begin() {
  265. init();
  266. // NPCS control is left to the user
  267. // Default speed set to 4Mhz
  268. setClockDivider(BOARD_SPI_DEFAULT_SS, 21);
  269. setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0);
  270. setBitOrder(BOARD_SPI_DEFAULT_SS, MSBFIRST);
  271. }
  272. void SPIClass::begin(uint8_t _pin) {
  273. init();
  274. uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
  275. PIO_Configure(
  276. g_APinDescription[spiPin].pPort,
  277. g_APinDescription[spiPin].ulPinType,
  278. g_APinDescription[spiPin].ulPin,
  279. g_APinDescription[spiPin].ulPinConfiguration);
  280. // Default speed set to 4Mhz
  281. setClockDivider(_pin, 21);
  282. setDataMode(_pin, SPI_MODE0);
  283. setBitOrder(_pin, MSBFIRST);
  284. }
  285. void SPIClass::init() {
  286. if (initialized)
  287. return;
  288. initCb();
  289. SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS);
  290. SPI_Enable(spi);
  291. initialized = true;
  292. }
  293. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  294. {
  295. uint8_t irestore;
  296. irestore = interruptsStatus();
  297. noInterrupts();
  298. if (interruptMode < 2) {
  299. if (interruptNumber > NUM_DIGITAL_PINS) {
  300. interruptMode = 2;
  301. } else {
  302. uint8_t imask = interruptMask;
  303. Pio *pio = g_APinDescription[interruptNumber].pPort;
  304. if (pio == PIOA) {
  305. imask |= 1;
  306. } else if (pio == PIOB) {
  307. imask |= 2;
  308. } else if (pio == PIOC) {
  309. imask |= 4;
  310. } else if (pio == PIOD) {
  311. imask |= 8;
  312. }
  313. interruptMask = imask;
  314. interruptMode = 1;
  315. }
  316. }
  317. if (irestore) interrupts();
  318. }
  319. void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
  320. {
  321. if (interruptMode > 0) {
  322. if (interruptMode == 1) {
  323. uint8_t imask = interruptMask;
  324. if (imask & 1) NVIC_DisableIRQ(PIOA_IRQn);
  325. if (imask & 2) NVIC_DisableIRQ(PIOB_IRQn);
  326. if (imask & 4) NVIC_DisableIRQ(PIOC_IRQn);
  327. if (imask & 8) NVIC_DisableIRQ(PIOD_IRQn);
  328. } else {
  329. interruptSave = interruptsStatus();
  330. noInterrupts();
  331. }
  332. }
  333. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(pin);
  334. bitOrder[ch] = settings.border;
  335. SPI_ConfigureNPCS(spi, ch, settings.config);
  336. }
  337. void SPIClass::endTransaction(void)
  338. {
  339. if (interruptMode > 0) {
  340. if (interruptMode == 1) {
  341. uint8_t imask = interruptMask;
  342. if (imask & 1) NVIC_EnableIRQ(PIOA_IRQn);
  343. if (imask & 2) NVIC_EnableIRQ(PIOB_IRQn);
  344. if (imask & 4) NVIC_EnableIRQ(PIOC_IRQn);
  345. if (imask & 8) NVIC_EnableIRQ(PIOD_IRQn);
  346. } else {
  347. if (interruptSave) interrupts();
  348. }
  349. }
  350. }
  351. void SPIClass::end(uint8_t _pin) {
  352. uint32_t spiPin = BOARD_PIN_TO_SPI_PIN(_pin);
  353. // Setting the pin as INPUT will disconnect it from SPI peripheral
  354. pinMode(spiPin, INPUT);
  355. }
  356. void SPIClass::end() {
  357. SPI_Disable(spi);
  358. initialized = false;
  359. }
  360. void SPIClass::setBitOrder(uint8_t _pin, BitOrder _bitOrder) {
  361. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  362. bitOrder[ch] = _bitOrder;
  363. }
  364. void SPIClass::setDataMode(uint8_t _pin, uint8_t _mode) {
  365. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  366. mode[ch] = _mode | SPI_CSR_CSAAT;
  367. // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
  368. // transfer. Some device needs that for working properly.
  369. SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
  370. }
  371. void SPIClass::setClockDivider(uint8_t _pin, uint8_t _divider) {
  372. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  373. divider[ch] = _divider;
  374. // SPI_CSR_DLYBCT(1) keeps CS enabled for 32 MCLK after a completed
  375. // transfer. Some device needs that for working properly.
  376. SPI_ConfigureNPCS(spi, ch, mode[ch] | SPI_CSR_SCBR(divider[ch]) | SPI_CSR_DLYBCT(1));
  377. }
  378. byte SPIClass::transfer(byte _pin, uint8_t _data, SPITransferMode _mode) {
  379. uint32_t ch = BOARD_PIN_TO_SPI_CHANNEL(_pin);
  380. // Reverse bit order
  381. if (bitOrder[ch] == LSBFIRST)
  382. _data = __REV(__RBIT(_data));
  383. uint32_t d = _data | SPI_PCS(ch);
  384. if (_mode == SPI_LAST)
  385. d |= SPI_TDR_LASTXFER;
  386. // SPI_Write(spi, _channel, _data);
  387. while ((spi->SPI_SR & SPI_SR_TDRE) == 0)
  388. ;
  389. spi->SPI_TDR = d;
  390. // return SPI_Read(spi);
  391. while ((spi->SPI_SR & SPI_SR_RDRF) == 0)
  392. ;
  393. d = spi->SPI_RDR;
  394. // Reverse bit order
  395. if (bitOrder[ch] == LSBFIRST)
  396. d = __REV(__RBIT(d));
  397. return d & 0xFF;
  398. }
  399. void SPIClass::attachInterrupt(void) {
  400. // Should be enableInterrupt()
  401. }
  402. void SPIClass::detachInterrupt(void) {
  403. // Should be disableInterrupt()
  404. }
  405. #if SPI_INTERFACES_COUNT > 0
  406. static void SPI_0_Init(void) {
  407. PIO_Configure(
  408. g_APinDescription[PIN_SPI_MOSI].pPort,
  409. g_APinDescription[PIN_SPI_MOSI].ulPinType,
  410. g_APinDescription[PIN_SPI_MOSI].ulPin,
  411. g_APinDescription[PIN_SPI_MOSI].ulPinConfiguration);
  412. PIO_Configure(
  413. g_APinDescription[PIN_SPI_MISO].pPort,
  414. g_APinDescription[PIN_SPI_MISO].ulPinType,
  415. g_APinDescription[PIN_SPI_MISO].ulPin,
  416. g_APinDescription[PIN_SPI_MISO].ulPinConfiguration);
  417. PIO_Configure(
  418. g_APinDescription[PIN_SPI_SCK].pPort,
  419. g_APinDescription[PIN_SPI_SCK].ulPinType,
  420. g_APinDescription[PIN_SPI_SCK].ulPin,
  421. g_APinDescription[PIN_SPI_SCK].ulPinConfiguration);
  422. }
  423. SPIClass SPI(SPI_INTERFACE, SPI_INTERFACE_ID, SPI_0_Init);
  424. #endif
  425. #endif