Adafruit_SPIDevice.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  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. #ifdef BUSIO_USE_FAST_PINIO
  47. csPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(cspin));
  48. csPinMask = digitalPinToBitMask(cspin);
  49. if (mosipin != -1) {
  50. mosiPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(mosipin));
  51. mosiPinMask = digitalPinToBitMask(mosipin);
  52. }
  53. if (misopin != -1) {
  54. misoPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(misopin));
  55. misoPinMask = digitalPinToBitMask(misopin);
  56. }
  57. clkPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(sckpin));
  58. clkPinMask = digitalPinToBitMask(sckpin);
  59. #endif
  60. _freq = freq;
  61. _dataOrder = dataOrder;
  62. _dataMode = dataMode;
  63. _begun = false;
  64. _spiSetting = new SPISettings(freq, dataOrder, dataMode);
  65. _spi = NULL;
  66. }
  67. /*!
  68. * @brief Initializes SPI bus and sets CS pin high
  69. * @return Always returns true because there's no way to test success of SPI
  70. * init
  71. */
  72. bool Adafruit_SPIDevice::begin(void) {
  73. pinMode(_cs, OUTPUT);
  74. digitalWrite(_cs, HIGH);
  75. if (_spi) { // hardware SPI
  76. _spi->begin();
  77. } else {
  78. pinMode(_sck, OUTPUT);
  79. if ((_dataMode == SPI_MODE0) || (_dataMode == SPI_MODE1)) {
  80. // idle low on mode 0 and 1
  81. digitalWrite(_sck, LOW);
  82. } else {
  83. // idle high on mode 2 or 3
  84. digitalWrite(_sck, HIGH);
  85. }
  86. if (_mosi != -1) {
  87. pinMode(_mosi, OUTPUT);
  88. digitalWrite(_mosi, HIGH);
  89. }
  90. if (_miso != -1) {
  91. pinMode(_miso, INPUT);
  92. }
  93. }
  94. _begun = true;
  95. return true;
  96. }
  97. /*!
  98. * @brief Transfer (send/receive) one byte over hard/soft SPI
  99. * @param buffer The buffer to send and receive at the same time
  100. * @param len The number of bytes to transfer
  101. */
  102. void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
  103. if (_spi) {
  104. // hardware SPI is easy
  105. #if defined(SPARK)
  106. _spi->transfer(buffer, buffer, len, NULL);
  107. #elif defined(STM32)
  108. for (size_t i = 0; i < len; i++) {
  109. _spi->transfer(buffer[i]);
  110. }
  111. #else
  112. _spi->transfer(buffer, len);
  113. #endif
  114. return;
  115. }
  116. uint8_t startbit;
  117. if (_dataOrder == SPI_BITORDER_LSBFIRST) {
  118. startbit = 0x1;
  119. } else {
  120. startbit = 0x80;
  121. }
  122. bool towrite, lastmosi = !(buffer[0] & startbit);
  123. uint8_t bitdelay_us = (1000000 / _freq) / 2;
  124. // for softSPI we'll do it by hand
  125. for (size_t i = 0; i < len; i++) {
  126. // software SPI
  127. uint8_t reply = 0;
  128. uint8_t send = buffer[i];
  129. /*
  130. Serial.print("\tSending software SPI byte 0x");
  131. Serial.print(send, HEX);
  132. Serial.print(" -> 0x");
  133. */
  134. // Serial.print(send, HEX);
  135. for (uint8_t b = startbit; b != 0;
  136. b = (_dataOrder == SPI_BITORDER_LSBFIRST) ? b << 1 : b >> 1) {
  137. if (bitdelay_us) {
  138. delayMicroseconds(bitdelay_us);
  139. }
  140. if (_dataMode == SPI_MODE0 || _dataMode == SPI_MODE2) {
  141. towrite = send & b;
  142. if ((_mosi != -1) && (lastmosi != towrite)) {
  143. #ifdef BUSIO_USE_FAST_PINIO
  144. if (towrite)
  145. *mosiPort |= mosiPinMask;
  146. else
  147. *mosiPort &= ~mosiPinMask;
  148. #else
  149. digitalWrite(_mosi, towrite);
  150. #endif
  151. lastmosi = towrite;
  152. }
  153. #ifdef BUSIO_USE_FAST_PINIO
  154. *clkPort |= clkPinMask; // Clock high
  155. #else
  156. digitalWrite(_sck, HIGH);
  157. #endif
  158. if (bitdelay_us) {
  159. delayMicroseconds(bitdelay_us);
  160. }
  161. if (_miso != -1) {
  162. #ifdef BUSIO_USE_FAST_PINIO
  163. if (*misoPort & misoPinMask) {
  164. #else
  165. if (digitalRead(_miso)) {
  166. #endif
  167. reply |= b;
  168. }
  169. }
  170. #ifdef BUSIO_USE_FAST_PINIO
  171. *clkPort &= ~clkPinMask; // Clock low
  172. #else
  173. digitalWrite(_sck, LOW);
  174. #endif
  175. } else { // if (_dataMode == SPI_MODE1 || _dataMode == SPI_MODE3)
  176. #ifdef BUSIO_USE_FAST_PINIO
  177. *clkPort |= clkPinMask; // Clock high
  178. #else
  179. digitalWrite(_sck, HIGH);
  180. #endif
  181. if (bitdelay_us) {
  182. delayMicroseconds(bitdelay_us);
  183. }
  184. if (_mosi != -1) {
  185. #ifdef BUSIO_USE_FAST_PINIO
  186. if (send & b)
  187. *mosiPort |= mosiPinMask;
  188. else
  189. *mosiPort &= ~mosiPinMask;
  190. #else
  191. digitalWrite(_mosi, send & b);
  192. #endif
  193. }
  194. #ifdef BUSIO_USE_FAST_PINIO
  195. *clkPort &= ~clkPinMask; // Clock low
  196. #else
  197. digitalWrite(_sck, LOW);
  198. #endif
  199. if (_miso != -1) {
  200. #ifdef BUSIO_USE_FAST_PINIO
  201. if (*misoPort & misoPinMask) {
  202. #else
  203. if (digitalRead(_miso)) {
  204. #endif
  205. reply |= b;
  206. }
  207. }
  208. }
  209. if (_miso != -1) {
  210. buffer[i] = reply;
  211. }
  212. }
  213. }
  214. return;
  215. }
  216. /*!
  217. * @brief Transfer (send/receive) one byte over hard/soft SPI
  218. * @param send The byte to send
  219. * @return The byte received while transmitting
  220. */
  221. uint8_t Adafruit_SPIDevice::transfer(uint8_t send) {
  222. uint8_t data = send;
  223. transfer(&data, 1);
  224. return data;
  225. }
  226. /*!
  227. * @brief Manually begin a transaction (calls beginTransaction if hardware
  228. * SPI)
  229. */
  230. void Adafruit_SPIDevice::beginTransaction(void) {
  231. if (_spi) {
  232. _spi->beginTransaction(*_spiSetting);
  233. }
  234. }
  235. /*!
  236. * @brief Manually end a transaction (calls endTransaction if hardware SPI)
  237. */
  238. void Adafruit_SPIDevice::endTransaction(void) {
  239. if (_spi) {
  240. _spi->endTransaction();
  241. }
  242. }
  243. /*!
  244. * @brief Write a buffer or two to the SPI device.
  245. * @param buffer Pointer to buffer of data to write
  246. * @param len Number of bytes from buffer to write
  247. * @param prefix_buffer Pointer to optional array of data to write before
  248. * buffer.
  249. * @param prefix_len Number of bytes from prefix buffer to write
  250. * @return Always returns true because there's no way to test success of SPI
  251. * writes
  252. */
  253. bool Adafruit_SPIDevice::write(uint8_t *buffer, size_t len,
  254. uint8_t *prefix_buffer, size_t prefix_len) {
  255. if (_spi) {
  256. _spi->beginTransaction(*_spiSetting);
  257. }
  258. digitalWrite(_cs, LOW);
  259. // do the writing
  260. for (size_t i = 0; i < prefix_len; i++) {
  261. transfer(prefix_buffer[i]);
  262. }
  263. for (size_t i = 0; i < len; i++) {
  264. transfer(buffer[i]);
  265. }
  266. digitalWrite(_cs, HIGH);
  267. if (_spi) {
  268. _spi->endTransaction();
  269. }
  270. #ifdef DEBUG_SERIAL
  271. DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
  272. if ((prefix_len != 0) && (prefix_buffer != NULL)) {
  273. for (uint16_t i = 0; i < prefix_len; i++) {
  274. DEBUG_SERIAL.print(F("0x"));
  275. DEBUG_SERIAL.print(prefix_buffer[i], HEX);
  276. DEBUG_SERIAL.print(F(", "));
  277. }
  278. }
  279. for (uint16_t i = 0; i < len; i++) {
  280. DEBUG_SERIAL.print(F("0x"));
  281. DEBUG_SERIAL.print(buffer[i], HEX);
  282. DEBUG_SERIAL.print(F(", "));
  283. if (i % 32 == 31) {
  284. DEBUG_SERIAL.println();
  285. }
  286. }
  287. DEBUG_SERIAL.println();
  288. #endif
  289. return true;
  290. }
  291. /*!
  292. * @brief Read from SPI into a buffer from the SPI device.
  293. * @param buffer Pointer to buffer of data to read into
  294. * @param len Number of bytes from buffer to read.
  295. * @param sendvalue The 8-bits of data to write when doing the data read,
  296. * defaults to 0xFF
  297. * @return Always returns true because there's no way to test success of SPI
  298. * writes
  299. */
  300. bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
  301. memset(buffer, sendvalue, len); // clear out existing buffer
  302. if (_spi) {
  303. _spi->beginTransaction(*_spiSetting);
  304. }
  305. digitalWrite(_cs, LOW);
  306. transfer(buffer, len);
  307. digitalWrite(_cs, HIGH);
  308. if (_spi) {
  309. _spi->endTransaction();
  310. }
  311. #ifdef DEBUG_SERIAL
  312. DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
  313. for (uint16_t i = 0; i < len; i++) {
  314. DEBUG_SERIAL.print(F("0x"));
  315. DEBUG_SERIAL.print(buffer[i], HEX);
  316. DEBUG_SERIAL.print(F(", "));
  317. if (len % 32 == 31) {
  318. DEBUG_SERIAL.println();
  319. }
  320. }
  321. DEBUG_SERIAL.println();
  322. #endif
  323. return true;
  324. }
  325. /*!
  326. * @brief Write some data, then read some data from SPI into another buffer.
  327. * The buffers can point to same/overlapping locations. This does not
  328. * transmit-receive at the same time!
  329. * @param write_buffer Pointer to buffer of data to write from
  330. * @param write_len Number of bytes from buffer to write.
  331. * @param read_buffer Pointer to buffer of data to read into.
  332. * @param read_len Number of bytes from buffer to read.
  333. * @param sendvalue The 8-bits of data to write when doing the data read,
  334. * defaults to 0xFF
  335. * @return Always returns true because there's no way to test success of SPI
  336. * writes
  337. */
  338. bool Adafruit_SPIDevice::write_then_read(uint8_t *write_buffer,
  339. size_t write_len, uint8_t *read_buffer,
  340. size_t read_len, uint8_t sendvalue) {
  341. if (_spi) {
  342. _spi->beginTransaction(*_spiSetting);
  343. }
  344. digitalWrite(_cs, LOW);
  345. // do the writing
  346. for (size_t i = 0; i < write_len; i++) {
  347. transfer(write_buffer[i]);
  348. }
  349. #ifdef DEBUG_SERIAL
  350. DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
  351. for (uint16_t i = 0; i < write_len; i++) {
  352. DEBUG_SERIAL.print(F("0x"));
  353. DEBUG_SERIAL.print(write_buffer[i], HEX);
  354. DEBUG_SERIAL.print(F(", "));
  355. if (write_len % 32 == 31) {
  356. DEBUG_SERIAL.println();
  357. }
  358. }
  359. DEBUG_SERIAL.println();
  360. #endif
  361. // do the reading
  362. for (size_t i = 0; i < read_len; i++) {
  363. read_buffer[i] = transfer(sendvalue);
  364. }
  365. #ifdef DEBUG_SERIAL
  366. DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
  367. for (uint16_t i = 0; i < read_len; i++) {
  368. DEBUG_SERIAL.print(F("0x"));
  369. DEBUG_SERIAL.print(read_buffer[i], HEX);
  370. DEBUG_SERIAL.print(F(", "));
  371. if (read_len % 32 == 31) {
  372. DEBUG_SERIAL.println();
  373. }
  374. }
  375. DEBUG_SERIAL.println();
  376. #endif
  377. digitalWrite(_cs, HIGH);
  378. if (_spi) {
  379. _spi->endTransaction();
  380. }
  381. return true;
  382. }