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.

379 lines
12KB

  1. /*
  2. * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
  3. * Copyright (c) 2014 by Paul Stoffregen <paul@pjrc.com> (Transaction API)
  4. * Copyright (c) 2014 by Matthijs Kooijman <matthijs@stdin.nl> (SPISettings)
  5. * SPI Master library for arduino.
  6. *
  7. * This file is free software; you can redistribute it and/or modify
  8. * it under the terms of either the GNU General Public License version 2
  9. * or the GNU Lesser General Public License version 2.1, both as
  10. * published by the Free Software Foundation.
  11. */
  12. #ifndef _SPI_H_INCLUDED
  13. #define _SPI_H_INCLUDED
  14. #include <Arduino.h>
  15. // SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
  16. // usingInterrupt(), and the actual clock speed names
  17. #define SPI_HAS_TRANSACTION 1
  18. // define SPI_AVR_EIMSK for AVR boards with external interrupt pins
  19. #if defined(__AVR__)
  20. #if defined(EIMSK)
  21. #define SPI_AVR_EIMSK EIMSK
  22. #elif defined(GICR)
  23. #define SPI_AVR_EIMSK GICR
  24. #elif defined(GIMSK)
  25. #define SPI_AVR_EIMSK GIMSK
  26. #endif
  27. #endif
  28. #ifndef LSBFIRST
  29. #define LSBFIRST 0
  30. #endif
  31. #ifndef MSBFIRST
  32. #define MSBFIRST 1
  33. #endif
  34. #define SPI_MODE0 0x00
  35. #define SPI_MODE1 0x04
  36. #define SPI_MODE2 0x08
  37. #define SPI_MODE3 0x0C
  38. #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
  39. #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
  40. #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
  41. class SPISettings {
  42. public:
  43. SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
  44. if (__builtin_constant_p(clock)) {
  45. init_AlwaysInline(clock, bitOrder, dataMode);
  46. } else {
  47. init_MightInline(clock, bitOrder, dataMode);
  48. }
  49. }
  50. SPISettings() {
  51. init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0);
  52. }
  53. private:
  54. void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
  55. init_AlwaysInline(clock, bitOrder, dataMode);
  56. }
  57. #if defined(__AVR__)
  58. void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
  59. __attribute__((__always_inline__)) {
  60. // Clock settings are defined as follows. Note that this shows SPI2X
  61. // inverted, so the bits form increasing numbers. Also note that
  62. // fosc/64 appears twice
  63. // SPR1 SPR0 ~SPI2X Freq
  64. // 0 0 0 fosc/2
  65. // 0 0 1 fosc/4
  66. // 0 1 0 fosc/8
  67. // 0 1 1 fosc/16
  68. // 1 0 0 fosc/32
  69. // 1 0 1 fosc/64
  70. // 1 1 0 fosc/64
  71. // 1 1 1 fosc/128
  72. // We find the fastest clock that is less than or equal to the
  73. // given clock rate. The clock divider that results in clock_setting
  74. // is 2 ^^ (clock_div + 1). If nothing is slow enough, we'll use the
  75. // slowest (128 == 2 ^^ 7, so clock_div = 6).
  76. uint8_t clockDiv;
  77. // When the clock is known at compiletime, use this if-then-else
  78. // cascade, which the compiler knows how to completely optimize
  79. // away. When clock is not known, use a loop instead, which generates
  80. // shorter code.
  81. if (__builtin_constant_p(clock)) {
  82. if (clock >= F_CPU / 2) {
  83. clockDiv = 0;
  84. } else if (clock >= F_CPU / 4) {
  85. clockDiv = 1;
  86. } else if (clock >= F_CPU / 8) {
  87. clockDiv = 2;
  88. } else if (clock >= F_CPU / 16) {
  89. clockDiv = 3;
  90. } else if (clock >= F_CPU / 32) {
  91. clockDiv = 4;
  92. } else if (clock >= F_CPU / 64) {
  93. clockDiv = 5;
  94. } else {
  95. clockDiv = 6;
  96. }
  97. } else {
  98. uint32_t clockSetting = F_CPU / 2;
  99. clockDiv = 0;
  100. while (clockDiv < 6 && clock < clockSetting) {
  101. clockSetting /= 2;
  102. clockDiv++;
  103. }
  104. }
  105. // Compensate for the duplicate fosc/64
  106. if (clockDiv == 6)
  107. clockDiv = 7;
  108. // Invert the SPI2X bit
  109. clockDiv ^= 0x1;
  110. // Pack into the SPISettings class
  111. spcr = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |
  112. (dataMode & SPI_MODE_MASK) | ((clockDiv >> 1) & SPI_CLOCK_MASK);
  113. spsr = clockDiv & SPI_2XCLOCK_MASK;
  114. }
  115. uint8_t spcr;
  116. uint8_t spsr;
  117. #elif defined(__arm__) && defined(TEENSYDUINO)
  118. void init_AlwaysInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
  119. __attribute__((__always_inline__)) {
  120. uint32_t t, c = SPI_CTAR_FMSZ(7);
  121. if (bitOrder == LSBFIRST) c |= SPI_CTAR_LSBFE;
  122. if (__builtin_constant_p(clock)) {
  123. if (clock >= F_BUS / 2) {
  124. t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0);
  125. } else if (clock >= F_BUS / 3) {
  126. t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0);
  127. } else if (clock >= F_BUS / 4) {
  128. t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0);
  129. } else if (clock >= F_BUS / 5) {
  130. t = SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0);
  131. } else if (clock >= F_BUS / 6) {
  132. t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0);
  133. } else if (clock >= F_BUS / 8) {
  134. t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  135. } else if (clock >= F_BUS / 10) {
  136. t = SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0);
  137. } else if (clock >= F_BUS / 12) {
  138. t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  139. } else if (clock >= F_BUS / 16) {
  140. t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2);
  141. } else if (clock >= F_BUS / 20) {
  142. t = SPI_CTAR_PBR(2) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(0);
  143. } else if (clock >= F_BUS / 24) {
  144. t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2);
  145. } else if (clock >= F_BUS / 32) {
  146. t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(3);
  147. } else if (clock >= F_BUS / 40) {
  148. t = SPI_CTAR_PBR(2) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2);
  149. } else if (clock >= F_BUS / 56) {
  150. t = SPI_CTAR_PBR(3) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2);
  151. } else if (clock >= F_BUS / 64) {
  152. t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4);
  153. } else if (clock >= F_BUS / 96) {
  154. t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4);
  155. } else if (clock >= F_BUS / 128) {
  156. t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5);
  157. } else if (clock >= F_BUS / 192) {
  158. t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5);
  159. } else if (clock >= F_BUS / 256) {
  160. t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6);
  161. } else if (clock >= F_BUS / 384) {
  162. t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6);
  163. } else if (clock >= F_BUS / 512) {
  164. t = SPI_CTAR_PBR(0) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7);
  165. } else if (clock >= F_BUS / 640) {
  166. t = SPI_CTAR_PBR(2) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6);
  167. } else { /* F_BUS / 768 */
  168. t = SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7);
  169. }
  170. } else {
  171. for (uint32_t i=0; i<23; i++) {
  172. t = ctar_clock_table[i];
  173. if (clock >= F_BUS / ctar_div_table[i]) break;
  174. }
  175. }
  176. if (dataMode & 0x08) {
  177. c |= SPI_CTAR_CPOL;
  178. }
  179. if (dataMode & 0x04) {
  180. c |= SPI_CTAR_CPHA;
  181. t = (t & 0xFFFF0FFF) | ((t & 0xF000) >> 4);
  182. }
  183. ctar = c | t;
  184. }
  185. static const uint16_t ctar_div_table[23];
  186. static const uint32_t ctar_clock_table[23];
  187. uint32_t ctar;
  188. #endif
  189. friend class SPIClass;
  190. };
  191. class SPIClass {
  192. public:
  193. // Initialize the SPI library
  194. static void begin();
  195. // If SPI is to used from within an interrupt, this function registers
  196. // that interrupt with the SPI library, so beginTransaction() can
  197. // prevent conflicts. The input interruptNumber is the number used
  198. // with attachInterrupt. If SPI is used from a different interrupt
  199. // (eg, a timer), interruptNumber should be 255.
  200. static void usingInterrupt(uint8_t interruptNumber);
  201. #if defined(__arm__) && defined(TEENSYDUINO)
  202. static void usingInterrupt(IRQ_NUMBER_t interruptName);
  203. #endif
  204. // Before using SPI.transfer() or asserting chip select pins,
  205. // this function is used to gain exclusive access to the SPI bus
  206. // and configure the correct settings.
  207. inline static void beginTransaction(SPISettings settings) {
  208. if (interruptMode > 0) {
  209. #ifdef SPI_AVR_EIMSK
  210. if (interruptMode == 1) {
  211. interruptSave = SPI_AVR_EIMSK;
  212. SPI_AVR_EIMSK &= ~interruptMask;
  213. } else
  214. #endif
  215. {
  216. interruptSave = SREG;
  217. cli();
  218. }
  219. }
  220. #if defined(__AVR__)
  221. SPCR = settings.spcr;
  222. SPSR = settings.spsr;
  223. #elif defined(__arm__) && defined(TEENSYDUINO)
  224. if (SPI0_CTAR0 != settings.ctar) {
  225. SPI0_MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  226. SPI0_CTAR0 = settings.ctar;
  227. SPI0_CTAR1 = settings.ctar | SPI_CTAR_FMSZ(7);
  228. SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  229. }
  230. #endif
  231. }
  232. // Write to the SPI bus (MOSI pin) and also receive (MISO pin)
  233. inline static uint8_t transfer(uint8_t data) {
  234. SPDR = data;
  235. asm volatile("nop");
  236. while (!(SPSR & _BV(SPIF))) ; // wait
  237. return SPDR;
  238. }
  239. inline static void transfer(void *buf, size_t count) {
  240. if (count == 0) return;
  241. uint8_t *p = (uint8_t *)buf;
  242. SPDR = *p;
  243. while (--count > 0) {
  244. uint8_t out = *(p + 1);
  245. while (!(SPSR & _BV(SPIF))) ;
  246. uint8_t in = SPDR;
  247. SPDR = out;
  248. *p++ = in;
  249. }
  250. while (!(SPSR & _BV(SPIF))) ;
  251. *p = SPDR;
  252. }
  253. // After performing a group of transfers and releasing the chip select
  254. // signal, this function allows others to access the SPI bus
  255. inline static void endTransaction(void) {
  256. if (interruptMode > 0) {
  257. #ifdef SPI_AVR_EIMSK
  258. if (interruptMode == 1) {
  259. SPI_AVR_EIMSK = interruptSave;
  260. } else
  261. #endif
  262. {
  263. SREG = interruptSave;
  264. }
  265. }
  266. }
  267. // Disable the SPI bus
  268. static void end();
  269. // This function is deprecated. New applications should use
  270. // beginTransaction() to configure SPI settings.
  271. inline static void setBitOrder(uint8_t bitOrder) {
  272. if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);
  273. else SPCR &= ~(_BV(DORD));
  274. }
  275. // This function is deprecated. New applications should use
  276. // beginTransaction() to configure SPI settings.
  277. inline static void setDataMode(uint8_t dataMode) {
  278. SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  279. }
  280. // This function is deprecated. New applications should use
  281. // beginTransaction() to configure SPI settings.
  282. inline static void setClockDivider(uint8_t clockDiv) {
  283. SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
  284. SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
  285. }
  286. // These undocumented functions should not be used. SPI.transfer()
  287. // polls the hardware flag which is automatically cleared as the
  288. // AVR responds to SPI's interrupt
  289. inline static void attachInterrupt() { SPCR |= _BV(SPIE); }
  290. inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }
  291. #if defined(__arm__) && defined(TEENSYDUINO)
  292. inline void setMOSI(uint8_t pin) __attribute__((always_inline)) { SPCR.setMOSI(pin); }
  293. inline void setMISO(uint8_t pin) __attribute__((always_inline)) { SPCR.setMISO(pin); }
  294. inline void setSCK(uint8_t pin) __attribute__((always_inline)) { SPCR.setSCK(pin); }
  295. #endif
  296. private:
  297. static uint8_t interruptMode; // 0=none, 1=mask, 2=global
  298. static uint8_t interruptMask; // which interrupts to mask
  299. static uint8_t interruptSave; // temp storage, to restore state
  300. };
  301. extern SPIClass SPI;
  302. #define SPI_CLOCK_DIV4 0x00
  303. #define SPI_CLOCK_DIV16 0x01
  304. #define SPI_CLOCK_DIV64 0x02
  305. #define SPI_CLOCK_DIV128 0x03
  306. #define SPI_CLOCK_DIV2 0x04
  307. #define SPI_CLOCK_DIV8 0x05
  308. #define SPI_CLOCK_DIV32 0x06
  309. // mapping of interrupt numbers to bits within SPI_AVR_EIMSK
  310. #ifdef SPI_AVR_EIMSK
  311. #if defined(__AVR_ATmega32U4__)
  312. #define SPI_INT0_MASK (1<<INT0)
  313. #define SPI_INT1_MASK (1<<INT1)
  314. #define SPI_INT2_MASK (1<<INT2)
  315. #define SPI_INT3_MASK (1<<INT3)
  316. #define SPI_INT4_MASK (1<<INT6)
  317. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  318. #define SPI_INT0_MASK (1<<INT0)
  319. #define SPI_INT1_MASK (1<<INT1)
  320. #define SPI_INT2_MASK (1<<INT2)
  321. #define SPI_INT3_MASK (1<<INT3)
  322. #define SPI_INT4_MASK (1<<INT4)
  323. #define SPI_INT5_MASK (1<<INT5)
  324. #define SPI_INT6_MASK (1<<INT6)
  325. #define SPI_INT7_MASK (1<<INT7)
  326. #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
  327. #define SPI_INT0_MASK (1<<INT4)
  328. #define SPI_INT1_MASK (1<<INT5)
  329. #define SPI_INT2_MASK (1<<INT0)
  330. #define SPI_INT3_MASK (1<<INT1)
  331. #define SPI_INT4_MASK (1<<INT2)
  332. #define SPI_INT5_MASK (1<<INT3)
  333. #define SPI_INT6_MASK (1<<INT6)
  334. #define SPI_INT7_MASK (1<<INT7)
  335. #else
  336. #ifdef INT0
  337. #define SPI_INT0_MASK (1<<INT0)
  338. #endif
  339. #ifdef INT1
  340. #define SPI_INT1_MASK (1<<INT1)
  341. #endif
  342. #ifdef INT2
  343. #define SPI_INT2_MASK (1<<INT2)
  344. #endif
  345. #endif
  346. #endif //SPI_AVR_EIMSK
  347. #endif