Adafruit_SPIDevice.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. #include <Adafruit_SPIDevice.h>
  2. #include <Arduino.h>
  3. //#define DEBUG_SERIAL Serial
  4. /*!
  5. * @brief Create an SPI device with the given CS pin and settins
  6. * @param cspin The arduino pin number to use for chip select
  7. * @param freq The SPI clock frequency to use, defaults to 1MHz
  8. * @param dataOrder The SPI data order to use for bits within each byte,
  9. * defaults to SPI_BITORDER_MSBFIRST
  10. * @param dataMode The SPI mode to use, defaults to SPI_MODE0
  11. * @param theSPI The SPI bus to use, defaults to &theSPI
  12. */
  13. Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq,
  14. BitOrder dataOrder, uint8_t dataMode,
  15. SPIClass *theSPI) {
  16. _cs = cspin;
  17. _sck = _mosi = _miso = -1;
  18. _spi = theSPI;
  19. _begun = false;
  20. _spiSetting = new SPISettings(freq, dataOrder, dataMode);
  21. _freq = freq;
  22. _dataOrder = dataOrder;
  23. _dataMode = dataMode;
  24. }
  25. /*!
  26. * @brief Create an SPI device with the given CS pin and settins
  27. * @param cspin The arduino pin number to use for chip select
  28. * @param sckpin The arduino pin number to use for SCK
  29. * @param misopin The arduino pin number to use for MISO, set to -1 if not
  30. * used
  31. * @param mosipin The arduino pin number to use for MOSI, set to -1 if not
  32. * used
  33. * @param freq The SPI clock frequency to use, defaults to 1MHz
  34. * @param dataOrder The SPI data order to use for bits within each byte,
  35. * defaults to SPI_BITORDER_MSBFIRST
  36. * @param dataMode The SPI mode to use, defaults to SPI_MODE0
  37. */
  38. Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin,
  39. int8_t misopin, int8_t mosipin,
  40. uint32_t freq, BitOrder dataOrder,
  41. uint8_t dataMode) {
  42. _cs = cspin;
  43. _sck = sckpin;
  44. _miso = misopin;
  45. _mosi = mosipin;
  46. _freq = freq;
  47. _dataOrder = dataOrder;
  48. _dataMode = dataMode;
  49. _begun = false;
  50. _spiSetting = new SPISettings(freq, dataOrder, dataMode);
  51. _spi = NULL;
  52. }
  53. /*!
  54. * @brief Initializes SPI bus and sets CS pin high
  55. * @return Always returns true because there's no way to test success of SPI
  56. * init
  57. */
  58. bool Adafruit_SPIDevice::begin(void) {
  59. pinMode(_cs, OUTPUT);
  60. digitalWrite(_cs, HIGH);
  61. if (_spi) { // hardware SPI
  62. _spi->begin();
  63. } else {
  64. pinMode(_sck, OUTPUT);
  65. if ((_dataMode == SPI_MODE0) || (_dataMode == SPI_MODE1)) {
  66. // idle low on mode 0 and 1
  67. digitalWrite(_sck, LOW);
  68. } else {
  69. // idle high on mode 2 or 3
  70. digitalWrite(_sck, HIGH);
  71. }
  72. if (_mosi != -1) {
  73. pinMode(_mosi, OUTPUT);
  74. digitalWrite(_mosi, HIGH);
  75. }
  76. if (_miso != -1) {
  77. pinMode(_miso, INPUT);
  78. }
  79. }
  80. _begun = true;
  81. return true;
  82. }
  83. /*!
  84. * @brief Transfer (send/receive) one byte over hard/soft SPI
  85. * @param buffer The buffer to send and receive at the same time
  86. * @param len The number of bytes to transfer
  87. */
  88. void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
  89. if (_spi) {
  90. // hardware SPI is easy
  91. _spi->transfer(buffer, len);
  92. return;
  93. }
  94. // for softSPI we'll do it by hand
  95. for (size_t i = 0; i < len; i++) {
  96. // software SPI
  97. uint8_t reply = 0;
  98. uint8_t send = buffer[i];
  99. /*
  100. Serial.print("\tSending software SPI byte 0x");
  101. Serial.print(send, HEX);
  102. Serial.print(" -> 0x");
  103. */
  104. if (_dataOrder == SPI_BITORDER_LSBFIRST) {
  105. // LSB is rare, if it happens we'll just flip the bits around for them
  106. uint8_t temp = 0;
  107. for (uint8_t b = 0; b < 8; b++) {
  108. temp |= ((send >> b) & 0x1) << (7 - b);
  109. }
  110. send = temp;
  111. }
  112. // Serial.print(send, HEX);
  113. for (int b = 7; b >= 0; b--) {
  114. reply <<= 1;
  115. if (_dataMode == SPI_MODE0 || _dataMode == SPI_MODE2) {
  116. if (_mosi != -1) {
  117. digitalWrite(_mosi, send & (1 << b));
  118. }
  119. digitalWrite(_sck, HIGH);
  120. if ((_miso != -1) && digitalRead(_miso)) {
  121. reply |= 1;
  122. }
  123. digitalWrite(_sck, LOW);
  124. }
  125. if (_dataMode == SPI_MODE1 || _dataMode == SPI_MODE3) {
  126. digitalWrite(_sck, HIGH);
  127. if (_mosi != -1) {
  128. digitalWrite(_mosi, send & (1 << b));
  129. }
  130. digitalWrite(_sck, LOW);
  131. if ((_miso != -1) && digitalRead(_miso)) {
  132. reply |= 1;
  133. }
  134. }
  135. }
  136. // Serial.print(" : 0x"); Serial.print(reply, HEX);
  137. if (_dataOrder == SPI_BITORDER_LSBFIRST) {
  138. // LSB is rare, if it happens we'll just flip the bits around for them
  139. uint8_t temp = 0;
  140. for (uint8_t b = 0; b < 8; b++) {
  141. temp |= ((reply >> b) & 0x1) << (7 - b);
  142. }
  143. reply = temp;
  144. }
  145. // Serial.print(" -> "); Serial.println(reply, HEX);
  146. buffer[i] = reply;
  147. }
  148. return;
  149. }
  150. /*!
  151. * @brief Transfer (send/receive) one byte over hard/soft SPI
  152. * @param send The byte to send
  153. * @return The byte received while transmitting
  154. */
  155. uint8_t Adafruit_SPIDevice::transfer(uint8_t send) {
  156. uint8_t data = send;
  157. transfer(&data, 1);
  158. return data;
  159. }
  160. /*!
  161. * @brief Write a buffer or two to the SPI device.
  162. * @param buffer Pointer to buffer of data to write
  163. * @param len Number of bytes from buffer to write
  164. * @param prefix_buffer Pointer to optional array of data to write before
  165. * buffer.
  166. * @param prefix_len Number of bytes from prefix buffer to write
  167. * @return Always returns true because there's no way to test success of SPI
  168. * writes
  169. */
  170. bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len,
  171. uint8_t *prefix_buffer, size_t prefix_len) {
  172. if (_spi) {
  173. _spi->beginTransaction(*_spiSetting);
  174. }
  175. digitalWrite(_cs, LOW);
  176. // do the writing
  177. for (size_t i = 0; i < prefix_len; i++) {
  178. transfer(prefix_buffer[i]);
  179. }
  180. for (size_t i = 0; i < len; i++) {
  181. transfer(buffer[i]);
  182. }
  183. digitalWrite(_cs, HIGH);
  184. if (_spi) {
  185. _spi->endTransaction();
  186. }
  187. #ifdef DEBUG_SERIAL
  188. DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
  189. if ((prefix_len != 0) && (prefix_buffer != NULL)) {
  190. for (uint16_t i = 0; i < prefix_len; i++) {
  191. DEBUG_SERIAL.print(F("0x"));
  192. DEBUG_SERIAL.print(prefix_buffer[i], HEX);
  193. DEBUG_SERIAL.print(F(", "));
  194. }
  195. }
  196. for (uint16_t i = 0; i < len; i++) {
  197. DEBUG_SERIAL.print(F("0x"));
  198. DEBUG_SERIAL.print(buffer[i], HEX);
  199. DEBUG_SERIAL.print(F(", "));
  200. if (i % 32 == 31) {
  201. DEBUG_SERIAL.println();
  202. }
  203. }
  204. DEBUG_SERIAL.println();
  205. #endif
  206. return true;
  207. }
  208. /*!
  209. * @brief Read from SPI into a buffer from the SPI device.
  210. * @param buffer Pointer to buffer of data to read into
  211. * @param len Number of bytes from buffer to read.
  212. * @param sendvalue The 8-bits of data to write when doing the data read,
  213. * defaults to 0xFF
  214. * @return Always returns true because there's no way to test success of SPI
  215. * writes
  216. */
  217. bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
  218. memset(buffer, sendvalue, len); // clear out existing buffer
  219. if (_spi) {
  220. _spi->beginTransaction(*_spiSetting);
  221. }
  222. digitalWrite(_cs, LOW);
  223. transfer(buffer, len);
  224. digitalWrite(_cs, HIGH);
  225. if (_spi) {
  226. _spi->endTransaction();
  227. }
  228. #ifdef DEBUG_SERIAL
  229. DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
  230. for (uint16_t i = 0; i < len; i++) {
  231. DEBUG_SERIAL.print(F("0x"));
  232. DEBUG_SERIAL.print(buffer[i], HEX);
  233. DEBUG_SERIAL.print(F(", "));
  234. if (len % 32 == 31) {
  235. DEBUG_SERIAL.println();
  236. }
  237. }
  238. DEBUG_SERIAL.println();
  239. #endif
  240. return true;
  241. }
  242. /*!
  243. * @brief Write some data, then read some data from SPI into another buffer.
  244. * The buffers can point to same/overlapping locations. This does not
  245. * transmit-receive at the same time!
  246. * @param write_buffer Pointer to buffer of data to write from
  247. * @param write_len Number of bytes from buffer to write.
  248. * @param read_buffer Pointer to buffer of data to read into.
  249. * @param read_len Number of bytes from buffer to read.
  250. * @param sendvalue The 8-bits of data to write when doing the data read,
  251. * defaults to 0xFF
  252. * @return Always returns true because there's no way to test success of SPI
  253. * writes
  254. */
  255. bool Adafruit_SPIDevice::write_then_read(uint8_t *write_buffer,
  256. size_t write_len, uint8_t *read_buffer,
  257. size_t read_len, uint8_t sendvalue) {
  258. if (_spi) {
  259. _spi->beginTransaction(*_spiSetting);
  260. }
  261. digitalWrite(_cs, LOW);
  262. // do the writing
  263. for (size_t i = 0; i < write_len; i++) {
  264. transfer(write_buffer[i]);
  265. }
  266. #ifdef DEBUG_SERIAL
  267. DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
  268. for (uint16_t i = 0; i < write_len; i++) {
  269. DEBUG_SERIAL.print(F("0x"));
  270. DEBUG_SERIAL.print(write_buffer[i], HEX);
  271. DEBUG_SERIAL.print(F(", "));
  272. if (write_len % 32 == 31) {
  273. DEBUG_SERIAL.println();
  274. }
  275. }
  276. DEBUG_SERIAL.println();
  277. #endif
  278. // do the reading
  279. for (size_t i = 0; i < read_len; i++) {
  280. read_buffer[i] = transfer(sendvalue);
  281. }
  282. #ifdef DEBUG_SERIAL
  283. DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
  284. for (uint16_t i = 0; i < read_len; i++) {
  285. DEBUG_SERIAL.print(F("0x"));
  286. DEBUG_SERIAL.print(read_buffer[i], HEX);
  287. DEBUG_SERIAL.print(F(", "));
  288. if (read_len % 32 == 31) {
  289. DEBUG_SERIAL.println();
  290. }
  291. }
  292. DEBUG_SERIAL.println();
  293. #endif
  294. digitalWrite(_cs, HIGH);
  295. if (_spi) {
  296. _spi->endTransaction();
  297. }
  298. return true;
  299. }