Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

190 lines
5.9KB

  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. * SPI Master library for arduino.
  5. *
  6. * This file is free software; you can redistribute it and/or modify
  7. * it under the terms of either the GNU General Public License version 2
  8. * or the GNU Lesser General Public License version 2.1, both as
  9. * published by the Free Software Foundation.
  10. */
  11. #ifndef _SPI_H_INCLUDED
  12. #define _SPI_H_INCLUDED
  13. #include <Arduino.h>
  14. // SPI_HAS_TRANSACTION means SPI has beginTransaction(), endTransaction(),
  15. // usingInterrupt(), and the actual clock speed names
  16. #define SPI_HAS_TRANSACTION 1
  17. // define SPI_AVR_EIMSK for AVR boards with external interrupt pins
  18. #if defined(__AVR__)
  19. #if defined(EIMSK)
  20. #define SPI_AVR_EIMSK EIMSK
  21. #elif defined(GICR)
  22. #define SPI_AVR_EIMSK GICR
  23. #elif defined(GIMSK)
  24. #define SPI_AVR_EIMSK GIMSK
  25. #endif
  26. #endif
  27. #define SPI_MODE0 0x00
  28. #define SPI_MODE1 0x04
  29. #define SPI_MODE2 0x08
  30. #define SPI_MODE3 0x0C
  31. #define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
  32. #define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
  33. #define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
  34. class SPIClass {
  35. public:
  36. // Initialize the SPI library
  37. static void begin();
  38. // If SPI is to used from within an interrupt, this function registers
  39. // that interrupt with the SPI library, so beginTransaction() can
  40. // prevent conflicts. The input interruptNumber is the number used
  41. // with attachInterrupt. If SPI is used from a different interrupt
  42. // (eg, a timer), interruptNumber should be 255.
  43. static void usingInterrupt(uint8_t interruptNumber);
  44. #if defined(__arm__) && defined(CORE_TEENSY)
  45. static void usingInterrupt(IRQ_NUMBER_t interruptName);
  46. #endif
  47. // Before using SPI.transfer() or asserting chip select pins,
  48. // this function is used to gain exclusive access to the SPI bus
  49. // and configure the correct settings.
  50. inline static void beginTransaction(uint8_t clockDiv, uint8_t bitOrder, uint8_t dataMode) {
  51. if (interruptMode > 0) {
  52. #ifdef SPI_AVR_EIMSK
  53. if (interruptMode == 1) {
  54. interruptSave = SPI_AVR_EIMSK;
  55. SPI_AVR_EIMSK &= ~interruptMask;
  56. } else
  57. #endif
  58. {
  59. interruptSave = SREG;
  60. cli();
  61. }
  62. }
  63. // these long expressions each compile to only 2 instructions
  64. SPCR = _BV(SPE) | _BV(MSTR) | ((bitOrder == LSBFIRST) ? _BV(DORD) : 0) |
  65. (dataMode & SPI_MODE_MASK) | (clockDiv & SPI_CLOCK_MASK);
  66. SPSR = (clockDiv >> 2) & SPI_2XCLOCK_MASK;
  67. }
  68. // Write a byte to the SPI bus (MOSI pin) and also receive (MISO pin)
  69. inline static byte transfer(byte data) {
  70. SPDR = data;
  71. while (!(SPSR & _BV(SPIF))) ; // wait
  72. return SPDR;
  73. }
  74. // After performing a group of transfers and releasing the chip select
  75. // signal, this function allows others to access the SPI bus
  76. inline static void endTransaction(void) {
  77. if (interruptMode > 0) {
  78. #ifdef SPI_AVR_EIMSK
  79. if (interruptMode == 1) {
  80. SPI_AVR_EIMSK = interruptSave;
  81. } else
  82. #endif
  83. {
  84. SREG = interruptSave;
  85. }
  86. }
  87. }
  88. // Disable the SPI bus
  89. static void end();
  90. // This function is deprecated. New applications should use
  91. // beginTransaction() to configure SPI settings.
  92. inline static void setBitOrder(uint8_t bitOrder) {
  93. if (bitOrder == LSBFIRST) SPCR |= _BV(DORD);
  94. else SPCR &= ~(_BV(DORD));
  95. }
  96. // This function is deprecated. New applications should use
  97. // beginTransaction() to configure SPI settings.
  98. inline static void setDataMode(uint8_t dataMode) {
  99. SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  100. }
  101. // This function is deprecated. New applications should use
  102. // beginTransaction() to configure SPI settings.
  103. inline static void setClockDivider(uint8_t clockDiv) {
  104. SPCR = (SPCR & ~SPI_CLOCK_MASK) | (clockDiv & SPI_CLOCK_MASK);
  105. SPSR = (SPSR & ~SPI_2XCLOCK_MASK) | ((clockDiv >> 2) & SPI_2XCLOCK_MASK);
  106. }
  107. // These undocumented functions should not be used. SPI.transfer()
  108. // polls the hardware flag which is automatically cleared as the
  109. // AVR responds to SPI's interrupt
  110. inline static void attachInterrupt() { SPCR |= _BV(SPIE); }
  111. inline static void detachInterrupt() { SPCR &= ~_BV(SPIE); }
  112. #if defined(__arm__) && defined(CORE_TEENSY)
  113. inline void setMOSI(uint8_t pin) __attribute__((always_inline)) { SPCR.setMOSI(pin); }
  114. inline void setMISO(uint8_t pin) __attribute__((always_inline)) { SPCR.setMISO(pin); }
  115. inline void setSCK(uint8_t pin) __attribute__((always_inline)) { SPCR.setSCK(pin); }
  116. #endif
  117. private:
  118. static uint8_t interruptMode; // 0=none, 1=mask, 2=global
  119. static uint8_t interruptMask; // which interrupts to mask
  120. static uint8_t interruptSave; // temp storage, to restore state
  121. };
  122. extern SPIClass SPI;
  123. #define SPI_CLOCK_DIV4 0x00
  124. #define SPI_CLOCK_DIV16 0x01
  125. #define SPI_CLOCK_DIV64 0x02
  126. #define SPI_CLOCK_DIV128 0x03
  127. #define SPI_CLOCK_DIV2 0x04
  128. #define SPI_CLOCK_DIV8 0x05
  129. #define SPI_CLOCK_DIV32 0x06
  130. // mapping of interrupt numbers to bits within SPI_AVR_EIMSK
  131. #ifdef SPI_AVR_EIMSK
  132. #if defined(__AVR_ATmega32U4__)
  133. #define SPI_INT0_MASK (1<<INT0)
  134. #define SPI_INT1_MASK (1<<INT1)
  135. #define SPI_INT2_MASK (1<<INT2)
  136. #define SPI_INT3_MASK (1<<INT3)
  137. #define SPI_INT4_MASK (1<<INT6)
  138. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  139. #define SPI_INT0_MASK (1<<INT0)
  140. #define SPI_INT1_MASK (1<<INT1)
  141. #define SPI_INT2_MASK (1<<INT2)
  142. #define SPI_INT3_MASK (1<<INT3)
  143. #define SPI_INT4_MASK (1<<INT4)
  144. #define SPI_INT5_MASK (1<<INT5)
  145. #define SPI_INT6_MASK (1<<INT6)
  146. #define SPI_INT7_MASK (1<<INT7)
  147. #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
  148. #define SPI_INT0_MASK (1<<INT4)
  149. #define SPI_INT1_MASK (1<<INT5)
  150. #define SPI_INT2_MASK (1<<INT0)
  151. #define SPI_INT3_MASK (1<<INT1)
  152. #define SPI_INT4_MASK (1<<INT2)
  153. #define SPI_INT5_MASK (1<<INT3)
  154. #define SPI_INT6_MASK (1<<INT6)
  155. #define SPI_INT7_MASK (1<<INT7)
  156. #else
  157. #ifdef INT0
  158. #define SPI_INT0_MASK (1<<INT0)
  159. #endif
  160. #ifdef INT1
  161. #define SPI_INT1_MASK (1<<INT1)
  162. #endif
  163. #ifdef INT2
  164. #define SPI_INT2_MASK (1<<INT2)
  165. #endif
  166. #endif
  167. #endif //SPI_AVR_EIMSK
  168. #endif