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.

преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 7 години
преди 9 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 10 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 8 години
преди 7 години
преди 8 години
преди 8 години
преди 8 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 6 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 10 години
преди 6 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
преди 5 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719
  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. //#define DEBUG_DMA_TRANSFERS
  13. /**********************************************************/
  14. /* 8 bit AVR-based boards */
  15. /**********************************************************/
  16. #if defined(__AVR__)
  17. SPIClass SPI;
  18. uint8_t SPIClass::interruptMode = 0;
  19. uint8_t SPIClass::interruptMask = 0;
  20. uint8_t SPIClass::interruptSave = 0;
  21. #ifdef SPI_TRANSACTION_MISMATCH_LED
  22. uint8_t SPIClass::inTransactionFlag = 0;
  23. #endif
  24. uint8_t SPIClass::_transferWriteFill = 0;
  25. void SPIClass::begin()
  26. {
  27. // Set SS to high so a connected chip will be "deselected" by default
  28. digitalWrite(SS, HIGH);
  29. // When the SS pin is set as OUTPUT, it can be used as
  30. // a general purpose output port (it doesn't influence
  31. // SPI operations).
  32. pinMode(SS, OUTPUT);
  33. // Warning: if the SS pin ever becomes a LOW INPUT then SPI
  34. // automatically switches to Slave, so the data direction of
  35. // the SS pin MUST be kept as OUTPUT.
  36. SPCR |= _BV(MSTR);
  37. SPCR |= _BV(SPE);
  38. // Set direction register for SCK and MOSI pin.
  39. // MISO pin automatically overrides to INPUT.
  40. // By doing this AFTER enabling SPI, we avoid accidentally
  41. // clocking in a single bit since the lines go directly
  42. // from "input" to SPI control.
  43. // http://code.google.com/p/arduino/issues/detail?id=888
  44. pinMode(SCK, OUTPUT);
  45. pinMode(MOSI, OUTPUT);
  46. }
  47. void SPIClass::end() {
  48. SPCR &= ~_BV(SPE);
  49. }
  50. // mapping of interrupt numbers to bits within SPI_AVR_EIMSK
  51. #if defined(__AVR_ATmega32U4__)
  52. #define SPI_INT0_MASK (1<<INT0)
  53. #define SPI_INT1_MASK (1<<INT1)
  54. #define SPI_INT2_MASK (1<<INT2)
  55. #define SPI_INT3_MASK (1<<INT3)
  56. #define SPI_INT4_MASK (1<<INT6)
  57. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  58. #define SPI_INT0_MASK (1<<INT0)
  59. #define SPI_INT1_MASK (1<<INT1)
  60. #define SPI_INT2_MASK (1<<INT2)
  61. #define SPI_INT3_MASK (1<<INT3)
  62. #define SPI_INT4_MASK (1<<INT4)
  63. #define SPI_INT5_MASK (1<<INT5)
  64. #define SPI_INT6_MASK (1<<INT6)
  65. #define SPI_INT7_MASK (1<<INT7)
  66. #elif defined(EICRA) && defined(EICRB) && defined(EIMSK)
  67. #define SPI_INT0_MASK (1<<INT4)
  68. #define SPI_INT1_MASK (1<<INT5)
  69. #define SPI_INT2_MASK (1<<INT0)
  70. #define SPI_INT3_MASK (1<<INT1)
  71. #define SPI_INT4_MASK (1<<INT2)
  72. #define SPI_INT5_MASK (1<<INT3)
  73. #define SPI_INT6_MASK (1<<INT6)
  74. #define SPI_INT7_MASK (1<<INT7)
  75. #else
  76. #ifdef INT0
  77. #define SPI_INT0_MASK (1<<INT0)
  78. #endif
  79. #ifdef INT1
  80. #define SPI_INT1_MASK (1<<INT1)
  81. #endif
  82. #ifdef INT2
  83. #define SPI_INT2_MASK (1<<INT2)
  84. #endif
  85. #endif
  86. void SPIClass::usingInterrupt(uint8_t interruptNumber)
  87. {
  88. uint8_t stmp, mask;
  89. if (interruptMode > 1) return;
  90. stmp = SREG;
  91. noInterrupts();
  92. switch (interruptNumber) {
  93. #ifdef SPI_INT0_MASK
  94. case 0: mask = SPI_INT0_MASK; break;
  95. #endif
  96. #ifdef SPI_INT1_MASK
  97. case 1: mask = SPI_INT1_MASK; break;
  98. #endif
  99. #ifdef SPI_INT2_MASK
  100. case 2: mask = SPI_INT2_MASK; break;
  101. #endif
  102. #ifdef SPI_INT3_MASK
  103. case 3: mask = SPI_INT3_MASK; break;
  104. #endif
  105. #ifdef SPI_INT4_MASK
  106. case 4: mask = SPI_INT4_MASK; break;
  107. #endif
  108. #ifdef SPI_INT5_MASK
  109. case 5: mask = SPI_INT5_MASK; break;
  110. #endif
  111. #ifdef SPI_INT6_MASK
  112. case 6: mask = SPI_INT6_MASK; break;
  113. #endif
  114. #ifdef SPI_INT7_MASK
  115. case 7: mask = SPI_INT7_MASK; break;
  116. #endif
  117. default:
  118. interruptMode = 2;
  119. SREG = stmp;
  120. return;
  121. }
  122. interruptMode = 1;
  123. interruptMask |= mask;
  124. SREG = stmp;
  125. }
  126. void SPIClass::transfer(const void * buf, void * retbuf, uint32_t count) {
  127. if (count == 0) return;
  128. const uint8_t *p = (const uint8_t *)buf;
  129. uint8_t *pret = (uint8_t *)retbuf;
  130. uint8_t in;
  131. uint8_t out = p ? *p++ : _transferWriteFill;
  132. SPDR = out;
  133. while (--count > 0) {
  134. if (p) {
  135. out = *p++;
  136. }
  137. while (!(SPSR & _BV(SPIF))) ;
  138. in = SPDR;
  139. SPDR = out;
  140. if (pret)*pret++ = in;
  141. }
  142. while (!(SPSR & _BV(SPIF))) ;
  143. in = SPDR;
  144. if (pret)*pret = in;
  145. }
  146. /**********************************************************/
  147. /* 32 bit Teensy 3.x */
  148. /**********************************************************/
  149. #elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISK)
  150. #if defined(KINETISK) && defined( SPI_HAS_TRANSFER_ASYNC)
  151. #ifndef TRANSFER_COUNT_FIXED
  152. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  153. // note does no validation of length...
  154. DMABaseClass::TCD_t *tcd = dmac->TCD;
  155. if (!(tcd->BITER & DMA_TCD_BITER_ELINK)) {
  156. tcd->BITER = len & 0x7fff;
  157. } else {
  158. tcd->BITER = (tcd->BITER & 0xFE00) | (len & 0x1ff);
  159. }
  160. tcd->CITER = tcd->BITER;
  161. }
  162. #else
  163. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  164. dmac->transferCount(len);
  165. }
  166. #endif
  167. #endif
  168. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  169. #ifdef SPI_HAS_TRANSFER_ASYNC
  170. void _spi_dma_rxISR0(void) {SPI.dma_rxisr();}
  171. #else
  172. void _spi_dma_rxISR0(void) {;}
  173. #endif
  174. const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = {
  175. SIM_SCGC6, SIM_SCGC6_SPI0, 4, IRQ_SPI0,
  176. 32767, DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX,
  177. _spi_dma_rxISR0,
  178. 12, 8,
  179. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  180. 11, 7,
  181. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  182. 13, 14,
  183. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  184. 10, 2, 9, 6, 20, 23, 21, 22, 15,
  185. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  186. 0x1, 0x1, 0x2, 0x2, 0x4, 0x4, 0x8, 0x8, 0x10
  187. };
  188. SPIClass SPI((uintptr_t)&KINETISK_SPI0, (uintptr_t)&SPIClass::spi0_hardware);
  189. #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
  190. #ifdef SPI_HAS_TRANSFER_ASYNC
  191. void _spi_dma_rxISR0(void) {SPI.dma_rxisr();}
  192. void _spi_dma_rxISR1(void) {SPI1.dma_rxisr();}
  193. void _spi_dma_rxISR2(void) {SPI2.dma_rxisr();}
  194. #else
  195. void _spi_dma_rxISR0(void) {;}
  196. void _spi_dma_rxISR1(void) {;}
  197. void _spi_dma_rxISR2(void) {;}
  198. #endif
  199. const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = {
  200. SIM_SCGC6, SIM_SCGC6_SPI0, 4, IRQ_SPI0,
  201. 32767, DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX,
  202. _spi_dma_rxISR0,
  203. 12, 8, 39, 255,
  204. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0,
  205. 11, 7, 28, 255,
  206. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0,
  207. 13, 14, 27,
  208. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  209. 10, 2, 9, 6, 20, 23, 21, 22, 15, 26, 45,
  210. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(3),
  211. 0x1, 0x1, 0x2, 0x2, 0x4, 0x4, 0x8, 0x8, 0x10, 0x1, 0x20
  212. };
  213. const SPIClass::SPI_Hardware_t SPIClass::spi1_hardware = {
  214. SIM_SCGC6, SIM_SCGC6_SPI1, 1, IRQ_SPI1,
  215. #if defined(__MK66FX1M0__)
  216. 32767, DMAMUX_SOURCE_SPI1_TX, DMAMUX_SOURCE_SPI1_RX,
  217. #else
  218. // T3.5 does not have good DMA support on 1 and 2
  219. 511, 0, DMAMUX_SOURCE_SPI1,
  220. #endif
  221. _spi_dma_rxISR1,
  222. 1, 5, 61, 59,
  223. PORT_PCR_MUX(2), PORT_PCR_MUX(7), PORT_PCR_MUX(2), PORT_PCR_MUX(7),
  224. 0, 21, 61, 59,
  225. PORT_PCR_MUX(2), PORT_PCR_MUX(7), PORT_PCR_MUX(7), PORT_PCR_MUX(2),
  226. 32, 20, 60,
  227. PORT_PCR_MUX(2), PORT_PCR_MUX(7), PORT_PCR_MUX(2),
  228. 6, 31, 58, 62, 63, 255, 255, 255, 255, 255, 255,
  229. PORT_PCR_MUX(7), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0, 0, 0, 0, 0,
  230. 0x1, 0x1, 0x2, 0x1, 0x4, 0, 0, 0, 0, 0, 0
  231. };
  232. const SPIClass::SPI_Hardware_t SPIClass::spi2_hardware = {
  233. SIM_SCGC3, SIM_SCGC3_SPI2, 1, IRQ_SPI2,
  234. #if defined(__MK66FX1M0__)
  235. 32767, DMAMUX_SOURCE_SPI2_TX, DMAMUX_SOURCE_SPI2_RX,
  236. #else
  237. // T3.5 does not have good DMA support on 1 and 2
  238. 511, 0, DMAMUX_SOURCE_SPI2,
  239. #endif
  240. _spi_dma_rxISR2,
  241. 45, 51, 255, 255,
  242. PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0,
  243. 44, 52, 255, 255,
  244. PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0,
  245. 46, 53, 255,
  246. PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0,
  247. 43, 54, 55, 255, 255, 255, 255, 255, 255, 255, 255,
  248. PORT_PCR_MUX(2), PORT_PCR_MUX(2), PORT_PCR_MUX(2), 0, 0, 0, 0, 0, 0, 0, 0,
  249. 0x1, 0x2, 0x1, 0, 0, 0, 0, 0, 0, 0, 0
  250. };
  251. SPIClass SPI((uintptr_t)&KINETISK_SPI0, (uintptr_t)&SPIClass::spi0_hardware);
  252. SPIClass SPI1((uintptr_t)&KINETISK_SPI1, (uintptr_t)&SPIClass::spi1_hardware);
  253. SPIClass SPI2((uintptr_t)&KINETISK_SPI2, (uintptr_t)&SPIClass::spi2_hardware);
  254. #endif
  255. void SPIClass::begin()
  256. {
  257. volatile uint32_t *reg;
  258. hardware().clock_gate_register |= hardware().clock_gate_mask;
  259. port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  260. port().CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  261. port().CTAR1 = SPI_CTAR_FMSZ(15) | SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  262. port().MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F);
  263. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  264. *reg = hardware().mosi_mux[mosi_pin_index];
  265. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  266. *reg= hardware().miso_mux[miso_pin_index];
  267. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  268. *reg = hardware().sck_mux[sck_pin_index];
  269. }
  270. void SPIClass::end()
  271. {
  272. volatile uint32_t *reg;
  273. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  274. *reg = 0;
  275. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  276. *reg = 0;
  277. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  278. *reg = 0;
  279. port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  280. }
  281. void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName)
  282. {
  283. uint32_t n = (uint32_t)interruptName;
  284. if (n >= NVIC_NUM_INTERRUPTS) return;
  285. //Serial.print("usingInterrupt ");
  286. //Serial.println(n);
  287. interruptMasksUsed |= (1 << (n >> 5));
  288. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  289. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  290. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  291. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  292. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  293. }
  294. void SPIClass::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  295. {
  296. uint32_t n = (uint32_t)interruptName;
  297. if (n >= NVIC_NUM_INTERRUPTS) return;
  298. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  299. if (interruptMask[n >> 5] == 0) {
  300. interruptMasksUsed &= ~(1 << (n >> 5));
  301. }
  302. }
  303. const uint16_t SPISettings::ctar_div_table[23] = {
  304. 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40,
  305. 56, 64, 96, 128, 192, 256, 384, 512, 640, 768
  306. };
  307. const uint32_t SPISettings::ctar_clock_table[23] = {
  308. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  309. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  310. SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  311. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR | SPI_CTAR_CSSCK(0),
  312. SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  313. SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  314. SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_CSSCK(0),
  315. SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1),
  316. SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  317. SPI_CTAR_PBR(2) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(0),
  318. SPI_CTAR_PBR(1) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  319. SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(3),
  320. SPI_CTAR_PBR(2) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  321. SPI_CTAR_PBR(3) | SPI_CTAR_BR(3) | SPI_CTAR_CSSCK(2),
  322. SPI_CTAR_PBR(0) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  323. SPI_CTAR_PBR(1) | SPI_CTAR_BR(5) | SPI_CTAR_CSSCK(4),
  324. SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  325. SPI_CTAR_PBR(1) | SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(5),
  326. SPI_CTAR_PBR(0) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  327. SPI_CTAR_PBR(1) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  328. SPI_CTAR_PBR(0) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7),
  329. SPI_CTAR_PBR(2) | SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(6),
  330. SPI_CTAR_PBR(1) | SPI_CTAR_BR(8) | SPI_CTAR_CSSCK(7)
  331. };
  332. void SPIClass::updateCTAR(uint32_t ctar)
  333. {
  334. if (port().CTAR0 != ctar) {
  335. uint32_t mcr = port().MCR;
  336. if (mcr & SPI_MCR_MDIS) {
  337. port().CTAR0 = ctar;
  338. port().CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  339. } else {
  340. port().MCR = SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
  341. port().CTAR0 = ctar;
  342. port().CTAR1 = ctar | SPI_CTAR_FMSZ(8);
  343. port().MCR = mcr;
  344. }
  345. }
  346. }
  347. void SPIClass::setBitOrder(uint8_t bitOrder)
  348. {
  349. hardware().clock_gate_register |= hardware().clock_gate_mask;
  350. uint32_t ctar = port().CTAR0;
  351. if (bitOrder == LSBFIRST) {
  352. ctar |= SPI_CTAR_LSBFE;
  353. } else {
  354. ctar &= ~SPI_CTAR_LSBFE;
  355. }
  356. updateCTAR(ctar);
  357. }
  358. void SPIClass::setDataMode(uint8_t dataMode)
  359. {
  360. hardware().clock_gate_register |= hardware().clock_gate_mask;
  361. //uint32_t ctar = port().CTAR0;
  362. // TODO: implement with native code
  363. //SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  364. }
  365. void SPIClass::setClockDivider_noInline(uint32_t clk)
  366. {
  367. hardware().clock_gate_register |= hardware().clock_gate_mask;
  368. uint32_t ctar = port().CTAR0;
  369. ctar &= (SPI_CTAR_CPOL | SPI_CTAR_CPHA | SPI_CTAR_LSBFE);
  370. if (ctar & SPI_CTAR_CPHA) {
  371. clk = (clk & 0xFFFF0FFF) | ((clk & 0xF000) >> 4);
  372. }
  373. ctar |= clk;
  374. updateCTAR(ctar);
  375. }
  376. uint8_t SPIClass::pinIsChipSelect(uint8_t pin)
  377. {
  378. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  379. if (pin == hardware().cs_pin[i]) return hardware().cs_mask[i];
  380. }
  381. return 0;
  382. }
  383. bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  384. {
  385. uint8_t pin1_mask, pin2_mask;
  386. if ((pin1_mask = (uint8_t)pinIsChipSelect(pin1)) == 0) return false;
  387. if ((pin2_mask = (uint8_t)pinIsChipSelect(pin2)) == 0) return false;
  388. //Serial.printf("pinIsChipSelect %d %d %x %x\n\r", pin1, pin2, pin1_mask, pin2_mask);
  389. if ((pin1_mask & pin2_mask) != 0) return false;
  390. return true;
  391. }
  392. bool SPIClass::pinIsMOSI(uint8_t pin)
  393. {
  394. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  395. if (pin == hardware().mosi_pin[i]) return true;
  396. }
  397. return false;
  398. }
  399. bool SPIClass::pinIsMISO(uint8_t pin)
  400. {
  401. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  402. if (pin == hardware().miso_pin[i]) return true;
  403. }
  404. return false;
  405. }
  406. bool SPIClass::pinIsSCK(uint8_t pin)
  407. {
  408. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  409. if (pin == hardware().sck_pin[i]) return true;
  410. }
  411. return false;
  412. }
  413. // setCS() is not intended for use from normal Arduino programs/sketches.
  414. uint8_t SPIClass::setCS(uint8_t pin)
  415. {
  416. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  417. if (pin == hardware().cs_pin[i]) {
  418. volatile uint32_t *reg = portConfigRegister(pin);
  419. *reg = hardware().cs_mux[i];
  420. return hardware().cs_mask[i];
  421. }
  422. }
  423. return 0;
  424. }
  425. void SPIClass::setMOSI(uint8_t pin)
  426. {
  427. if (hardware_addr == (uintptr_t)&spi0_hardware) {
  428. SPCR.setMOSI_soft(pin);
  429. }
  430. if (pin != hardware().mosi_pin[mosi_pin_index]) {
  431. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  432. if (pin == hardware().mosi_pin[i]) {
  433. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  434. volatile uint32_t *reg;
  435. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  436. *reg = 0;
  437. reg = portConfigRegister(hardware().mosi_pin[i]);
  438. *reg = hardware().mosi_mux[i];
  439. }
  440. mosi_pin_index = i;
  441. return;
  442. }
  443. }
  444. }
  445. }
  446. void SPIClass::setMISO(uint8_t pin)
  447. {
  448. if (hardware_addr == (uintptr_t)&spi0_hardware) {
  449. SPCR.setMISO_soft(pin);
  450. }
  451. if (pin != hardware().miso_pin[miso_pin_index]) {
  452. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  453. if (pin == hardware().miso_pin[i]) {
  454. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  455. volatile uint32_t *reg;
  456. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  457. *reg = 0;
  458. reg = portConfigRegister(hardware().miso_pin[i]);
  459. *reg = hardware().miso_mux[i];
  460. }
  461. miso_pin_index = i;
  462. return;
  463. }
  464. }
  465. }
  466. }
  467. void SPIClass::setSCK(uint8_t pin)
  468. {
  469. if (hardware_addr == (uintptr_t)&spi0_hardware) {
  470. SPCR.setSCK_soft(pin);
  471. }
  472. if (pin != hardware().sck_pin[sck_pin_index]) {
  473. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  474. if (pin == hardware().sck_pin[i]) {
  475. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  476. volatile uint32_t *reg;
  477. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  478. *reg = 0;
  479. reg = portConfigRegister(hardware().sck_pin[i]);
  480. *reg = hardware().sck_mux[i];
  481. }
  482. sck_pin_index = i;
  483. return;
  484. }
  485. }
  486. }
  487. }
  488. void SPIClass::transfer(const void * buf, void * retbuf, size_t count)
  489. {
  490. if (count == 0) return;
  491. if (!(port().CTAR0 & SPI_CTAR_LSBFE)) {
  492. // We are doing the standard MSB order
  493. const uint8_t *p_write = (const uint8_t *)buf;
  494. uint8_t *p_read = (uint8_t *)retbuf;
  495. size_t count_read = count;
  496. // Lets clear the reader queue
  497. port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  498. uint32_t sr;
  499. // Now lets loop while we still have data to output
  500. if (count & 1) {
  501. if (p_write) {
  502. if (count > 1)
  503. port().PUSHR = *p_write++ | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  504. else
  505. port().PUSHR = *p_write++ | SPI_PUSHR_CTAS(0);
  506. } else {
  507. if (count > 1)
  508. port().PUSHR = _transferWriteFill | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  509. else
  510. port().PUSHR = _transferWriteFill | SPI_PUSHR_CTAS(0);
  511. }
  512. count--;
  513. }
  514. uint16_t w = (uint16_t)(_transferWriteFill << 8) | _transferWriteFill;
  515. while (count > 0) {
  516. // Push out the next byte;
  517. if (p_write) {
  518. w = (*p_write++) << 8;
  519. w |= *p_write++;
  520. }
  521. uint16_t queue_full_status_mask = (hardware().queue_size-1) << 12;
  522. if (count == 2)
  523. port().PUSHR = w | SPI_PUSHR_CTAS(1);
  524. else
  525. port().PUSHR = w | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1);
  526. count -= 2; // how many bytes to output.
  527. // Make sure queue is not full before pushing next byte out
  528. do {
  529. sr = port().SR;
  530. if (sr & 0xF0) {
  531. uint16_t w = port().POPR; // Read any pending RX bytes in
  532. if (count_read & 1) {
  533. if (p_read) {
  534. *p_read++ = w; // Read any pending RX bytes in
  535. }
  536. count_read--;
  537. } else {
  538. if (p_read) {
  539. *p_read++ = w >> 8;
  540. *p_read++ = (w & 0xff);
  541. }
  542. count_read -= 2;
  543. }
  544. }
  545. } while ((sr & (15 << 12)) > queue_full_status_mask);
  546. }
  547. // now lets wait for all of the read bytes to be returned...
  548. while (count_read) {
  549. sr = port().SR;
  550. if (sr & 0xF0) {
  551. uint16_t w = port().POPR; // Read any pending RX bytes in
  552. if (count_read & 1) {
  553. if (p_read)
  554. *p_read++ = w; // Read any pending RX bytes in
  555. count_read--;
  556. } else {
  557. if (p_read) {
  558. *p_read++ = w >> 8;
  559. *p_read++ = (w & 0xff);
  560. }
  561. count_read -= 2;
  562. }
  563. }
  564. }
  565. } else {
  566. // We are doing the less ofen LSB mode
  567. const uint8_t *p_write = (const uint8_t *)buf;
  568. uint8_t *p_read = (uint8_t *)retbuf;
  569. size_t count_read = count;
  570. // Lets clear the reader queue
  571. port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F);
  572. uint32_t sr;
  573. // Now lets loop while we still have data to output
  574. if (count & 1) {
  575. if (p_write) {
  576. if (count > 1)
  577. port().PUSHR = *p_write++ | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  578. else
  579. port().PUSHR = *p_write++ | SPI_PUSHR_CTAS(0);
  580. } else {
  581. if (count > 1)
  582. port().PUSHR = _transferWriteFill | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(0);
  583. else
  584. port().PUSHR = _transferWriteFill | SPI_PUSHR_CTAS(0);
  585. }
  586. count--;
  587. }
  588. uint16_t w = _transferWriteFill;
  589. while (count > 0) {
  590. // Push out the next byte;
  591. if (p_write) {
  592. w = *p_write++;
  593. w |= ((*p_write++) << 8);
  594. }
  595. uint16_t queue_full_status_mask = (hardware().queue_size-1) << 12;
  596. if (count == 2)
  597. port().PUSHR = w | SPI_PUSHR_CTAS(1);
  598. else
  599. port().PUSHR = w | SPI_PUSHR_CONT | SPI_PUSHR_CTAS(1);
  600. count -= 2; // how many bytes to output.
  601. // Make sure queue is not full before pushing next byte out
  602. do {
  603. sr = port().SR;
  604. if (sr & 0xF0) {
  605. uint16_t w = port().POPR; // Read any pending RX bytes in
  606. if (count_read & 1) {
  607. if (p_read) {
  608. *p_read++ = w; // Read any pending RX bytes in
  609. }
  610. count_read--;
  611. } else {
  612. if (p_read) {
  613. *p_read++ = (w & 0xff);
  614. *p_read++ = w >> 8;
  615. }
  616. count_read -= 2;
  617. }
  618. }
  619. } while ((sr & (15 << 12)) > queue_full_status_mask);
  620. }
  621. // now lets wait for all of the read bytes to be returned...
  622. while (count_read) {
  623. sr = port().SR;
  624. if (sr & 0xF0) {
  625. uint16_t w = port().POPR; // Read any pending RX bytes in
  626. if (count_read & 1) {
  627. if (p_read)
  628. *p_read++ = w; // Read any pending RX bytes in
  629. count_read--;
  630. } else {
  631. if (p_read) {
  632. *p_read++ = (w & 0xff);
  633. *p_read++ = w >> 8;
  634. }
  635. count_read -= 2;
  636. }
  637. }
  638. }
  639. }
  640. }
  641. //=============================================================================
  642. // ASYNCH Support
  643. //=============================================================================
  644. //=========================================================================
  645. // Try Transfer using DMA.
  646. //=========================================================================
  647. #ifdef SPI_HAS_TRANSFER_ASYNC
  648. static uint8_t bit_bucket;
  649. #define dontInterruptAtCompletion(dmac) (dmac)->TCD->CSR &= ~DMA_TCD_CSR_INTMAJOR
  650. //=========================================================================
  651. // Init the DMA channels
  652. //=========================================================================
  653. bool SPIClass::initDMAChannels() {
  654. // Allocate our channels.
  655. _dmaTX = new DMAChannel();
  656. if (_dmaTX == nullptr) {
  657. return false;
  658. }
  659. _dmaRX = new DMAChannel();
  660. if (_dmaRX == nullptr) {
  661. delete _dmaTX; // release it
  662. _dmaTX = nullptr;
  663. return false;
  664. }
  665. // Let's setup the RX chain
  666. _dmaRX->disable();
  667. _dmaRX->source((volatile uint8_t&)port().POPR);
  668. _dmaRX->disableOnCompletion();
  669. _dmaRX->triggerAtHardwareEvent(hardware().rx_dma_channel);
  670. _dmaRX->attachInterrupt(hardware().dma_rxisr);
  671. _dmaRX->interruptAtCompletion();
  672. // We may be using settings chain here so lets set it up.
  673. // Now lets setup TX chain. Note if trigger TX is not set
  674. // we need to have the RX do it for us.
  675. _dmaTX->disable();
  676. _dmaTX->destination((volatile uint8_t&)port().PUSHR);
  677. _dmaTX->disableOnCompletion();
  678. if (hardware().tx_dma_channel) {
  679. _dmaTX->triggerAtHardwareEvent(hardware().tx_dma_channel);
  680. } else {
  681. // Serial.printf("SPI InitDMA tx triger by RX: %x\n", (uint32_t)_dmaRX);
  682. _dmaTX->triggerAtTransfersOf(*_dmaRX);
  683. }
  684. _dma_state = DMAState::idle; // Should be first thing set!
  685. return true;
  686. }
  687. //=========================================================================
  688. // Main Async Transfer function
  689. //=========================================================================
  690. bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) {
  691. uint8_t dma_first_byte;
  692. if (_dma_state == DMAState::notAllocated) {
  693. if (!initDMAChannels())
  694. return false;
  695. }
  696. if (_dma_state == DMAState::active)
  697. return false; // already active
  698. event_responder.clearEvent(); // Make sure it is not set yet
  699. if (count < 2) {
  700. // Use non-async version to simplify cases...
  701. transfer(buf, retbuf, count);
  702. event_responder.triggerEvent();
  703. return true;
  704. }
  705. // Now handle the cases where the count > then how many we can output in one DMA request
  706. if (count > hardware().max_dma_count) {
  707. _dma_count_remaining = count - hardware().max_dma_count;
  708. count = hardware().max_dma_count;
  709. } else {
  710. _dma_count_remaining = 0;
  711. }
  712. // Now See if caller passed in a source buffer.
  713. _dmaTX->TCD->ATTR_DST = 0; // Make sure set for 8 bit mode
  714. uint8_t *write_data = (uint8_t*) buf;
  715. if (buf) {
  716. dma_first_byte = *write_data;
  717. _dmaTX->sourceBuffer((uint8_t*)write_data+1, count-1);
  718. _dmaTX->TCD->SLAST = 0; // Finish with it pointing to next location
  719. } else {
  720. dma_first_byte = _transferWriteFill;
  721. _dmaTX->source((uint8_t&)_transferWriteFill); // maybe have setable value
  722. DMAChanneltransferCount(_dmaTX, count-1);
  723. }
  724. if (retbuf) {
  725. // On T3.5 must handle SPI1/2 differently as only one DMA channel
  726. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  727. _dmaRX->destinationBuffer((uint8_t*)retbuf, count);
  728. _dmaRX->TCD->DLASTSGA = 0; // At end point after our bufffer
  729. } else {
  730. // Write only mode
  731. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  732. _dmaRX->destination((uint8_t&)bit_bucket);
  733. DMAChanneltransferCount(_dmaRX, count);
  734. }
  735. _dma_event_responder = &event_responder;
  736. // Now try to start it?
  737. // Setup DMA main object
  738. yield();
  739. port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_CLR_TXF | SPI_MCR_PCSIS(0x1F);
  740. port().SR = 0xFF0F0000;
  741. // Lets try to output the first byte to make sure that we are in 8 bit mode...
  742. port().PUSHR = dma_first_byte | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
  743. if (hardware().tx_dma_channel) {
  744. port().RSER = SPI_RSER_RFDF_RE | SPI_RSER_RFDF_DIRS | SPI_RSER_TFFF_RE | SPI_RSER_TFFF_DIRS;
  745. _dmaRX->enable();
  746. // Get the initial settings.
  747. _dmaTX->enable();
  748. } else {
  749. //T3.5 SP1 and SPI2 - TX is not triggered by SPI but by RX...
  750. port().RSER = SPI_RSER_RFDF_RE | SPI_RSER_RFDF_DIRS ;
  751. _dmaTX->triggerAtTransfersOf(*_dmaRX);
  752. _dmaTX->enable();
  753. _dmaRX->enable();
  754. }
  755. _dma_state = DMAState::active;
  756. return true;
  757. }
  758. //-------------------------------------------------------------------------
  759. // DMA RX ISR
  760. //-------------------------------------------------------------------------
  761. void SPIClass::dma_rxisr(void) {
  762. _dmaRX->clearInterrupt();
  763. _dmaTX->clearComplete();
  764. _dmaRX->clearComplete();
  765. uint8_t should_reenable_tx = true; // should we re-enable TX maybe not if count will be 0...
  766. if (_dma_count_remaining) {
  767. // What do I need to do to start it back up again...
  768. // We will use the BITR/CITR from RX as TX may have prefed some stuff
  769. if (_dma_count_remaining > hardware().max_dma_count) {
  770. _dma_count_remaining -= hardware().max_dma_count;
  771. } else {
  772. DMAChanneltransferCount(_dmaTX, _dma_count_remaining-1);
  773. DMAChanneltransferCount(_dmaRX, _dma_count_remaining);
  774. if (_dma_count_remaining == 1) should_reenable_tx = false;
  775. _dma_count_remaining = 0;
  776. }
  777. // In some cases we need to again start the TX manually to get it to work...
  778. if (_dmaTX->TCD->SADDR == &_transferWriteFill) {
  779. if (port().CTAR0 & SPI_CTAR_FMSZ(8)) {
  780. port().PUSHR = (_transferWriteFill | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  781. } else {
  782. port().PUSHR = (_transferWriteFill | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  783. }
  784. } else {
  785. if (port().CTAR0 & SPI_CTAR_FMSZ(8)) {
  786. // 16 bit mode
  787. uint16_t w = *((uint16_t*)_dmaTX->TCD->SADDR);
  788. _dmaTX->TCD->SADDR = (volatile uint8_t*)(_dmaTX->TCD->SADDR) + 2;
  789. port().PUSHR = (w | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  790. } else {
  791. uint8_t w = *((uint8_t*)_dmaTX->TCD->SADDR);
  792. _dmaTX->TCD->SADDR = (volatile uint8_t*)(_dmaTX->TCD->SADDR) + 1;
  793. port().PUSHR = (w | SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT);
  794. }
  795. }
  796. _dmaRX->enable();
  797. if (should_reenable_tx)
  798. _dmaTX->enable();
  799. } else {
  800. port().RSER = 0;
  801. //port().MCR = SPI_MCR_MSTR | SPI_MCR_CLR_RXF | SPI_MCR_PCSIS(0x1F); // clear out the queue
  802. port().SR = 0xFF0F0000;
  803. port().CTAR0 &= ~(SPI_CTAR_FMSZ(8)); // Hack restore back to 8 bits
  804. _dma_state = DMAState::completed; // set back to 1 in case our call wants to start up dma again
  805. _dma_event_responder->triggerEvent();
  806. }
  807. }
  808. #endif // SPI_HAS_TRANSFER_ASYNC
  809. /**********************************************************/
  810. /* 32 bit Teensy-LC */
  811. /**********************************************************/
  812. #elif defined(__arm__) && defined(TEENSYDUINO) && defined(KINETISL)
  813. #ifdef SPI_HAS_TRANSFER_ASYNC
  814. void _spi_dma_rxISR0(void) {SPI.dma_isr();}
  815. void _spi_dma_rxISR1(void) {SPI1.dma_isr();}
  816. #else
  817. void _spi_dma_rxISR0(void) {;}
  818. void _spi_dma_rxISR1(void) {;}
  819. #endif
  820. const SPIClass::SPI_Hardware_t SPIClass::spi0_hardware = {
  821. SIM_SCGC4, SIM_SCGC4_SPI0,
  822. 0, // BR index 0
  823. DMAMUX_SOURCE_SPI0_TX, DMAMUX_SOURCE_SPI0_RX, _spi_dma_rxISR0,
  824. 12, 8,
  825. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  826. 11, 7,
  827. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  828. 13, 14,
  829. PORT_PCR_DSE | PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  830. 10, 2,
  831. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  832. 0x1, 0x1
  833. };
  834. SPIClass SPI((uintptr_t)&KINETISL_SPI0, (uintptr_t)&SPIClass::spi0_hardware);
  835. const SPIClass::SPI_Hardware_t SPIClass::spi1_hardware = {
  836. SIM_SCGC4, SIM_SCGC4_SPI1,
  837. 1, // BR index 1 in SPI Settings
  838. DMAMUX_SOURCE_SPI1_TX, DMAMUX_SOURCE_SPI1_RX, _spi_dma_rxISR1,
  839. 1, 5,
  840. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  841. 0, 21,
  842. PORT_PCR_MUX(2), PORT_PCR_MUX(2),
  843. 20, 255,
  844. PORT_PCR_MUX(2), 0,
  845. 6, 255,
  846. PORT_PCR_MUX(2), 0,
  847. 0x1, 0
  848. };
  849. SPIClass SPI1((uintptr_t)&KINETISL_SPI1, (uintptr_t)&SPIClass::spi1_hardware);
  850. void SPIClass::begin()
  851. {
  852. volatile uint32_t *reg;
  853. hardware().clock_gate_register |= hardware().clock_gate_mask;
  854. port().C1 = SPI_C1_SPE | SPI_C1_MSTR;
  855. port().C2 = 0;
  856. uint8_t tmp __attribute__((unused)) = port().S;
  857. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  858. *reg = hardware().mosi_mux[mosi_pin_index];
  859. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  860. *reg = hardware().miso_mux[miso_pin_index];
  861. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  862. *reg = hardware().sck_mux[sck_pin_index];
  863. }
  864. void SPIClass::end() {
  865. volatile uint32_t *reg;
  866. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  867. *reg = 0;
  868. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  869. *reg = 0;
  870. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  871. *reg = 0;
  872. port().C1 = 0;
  873. }
  874. const uint16_t SPISettings::br_div_table[30] = {
  875. 2, 4, 6, 8, 10, 12, 14, 16, 20, 24,
  876. 28, 32, 40, 48, 56, 64, 80, 96, 112, 128,
  877. 160, 192, 224, 256, 320, 384, 448, 512, 640, 768,
  878. };
  879. const uint8_t SPISettings::br_clock_table[30] = {
  880. SPI_BR_SPPR(0) | SPI_BR_SPR(0),
  881. SPI_BR_SPPR(1) | SPI_BR_SPR(0),
  882. SPI_BR_SPPR(2) | SPI_BR_SPR(0),
  883. SPI_BR_SPPR(3) | SPI_BR_SPR(0),
  884. SPI_BR_SPPR(4) | SPI_BR_SPR(0),
  885. SPI_BR_SPPR(5) | SPI_BR_SPR(0),
  886. SPI_BR_SPPR(6) | SPI_BR_SPR(0),
  887. SPI_BR_SPPR(7) | SPI_BR_SPR(0),
  888. SPI_BR_SPPR(4) | SPI_BR_SPR(1),
  889. SPI_BR_SPPR(5) | SPI_BR_SPR(1),
  890. SPI_BR_SPPR(6) | SPI_BR_SPR(1),
  891. SPI_BR_SPPR(7) | SPI_BR_SPR(1),
  892. SPI_BR_SPPR(4) | SPI_BR_SPR(2),
  893. SPI_BR_SPPR(5) | SPI_BR_SPR(2),
  894. SPI_BR_SPPR(6) | SPI_BR_SPR(2),
  895. SPI_BR_SPPR(7) | SPI_BR_SPR(2),
  896. SPI_BR_SPPR(4) | SPI_BR_SPR(3),
  897. SPI_BR_SPPR(5) | SPI_BR_SPR(3),
  898. SPI_BR_SPPR(6) | SPI_BR_SPR(3),
  899. SPI_BR_SPPR(7) | SPI_BR_SPR(3),
  900. SPI_BR_SPPR(4) | SPI_BR_SPR(4),
  901. SPI_BR_SPPR(5) | SPI_BR_SPR(4),
  902. SPI_BR_SPPR(6) | SPI_BR_SPR(4),
  903. SPI_BR_SPPR(7) | SPI_BR_SPR(4),
  904. SPI_BR_SPPR(4) | SPI_BR_SPR(5),
  905. SPI_BR_SPPR(5) | SPI_BR_SPR(5),
  906. SPI_BR_SPPR(6) | SPI_BR_SPR(5),
  907. SPI_BR_SPPR(7) | SPI_BR_SPR(5),
  908. SPI_BR_SPPR(4) | SPI_BR_SPR(6),
  909. SPI_BR_SPPR(5) | SPI_BR_SPR(6)
  910. };
  911. void SPIClass::setMOSI(uint8_t pin)
  912. {
  913. if (pin != hardware().mosi_pin[mosi_pin_index]) {
  914. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  915. if (pin == hardware().mosi_pin[i] ) {
  916. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  917. volatile uint32_t *reg;
  918. reg = portConfigRegister(hardware().mosi_pin[mosi_pin_index]);
  919. *reg = 0;
  920. reg = portConfigRegister(hardware().mosi_pin[i]);
  921. *reg = hardware().mosi_mux[i];
  922. }
  923. mosi_pin_index = i;
  924. return;
  925. }
  926. }
  927. }
  928. }
  929. void SPIClass::setMISO(uint8_t pin)
  930. {
  931. if (pin != hardware().miso_pin[miso_pin_index]) {
  932. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  933. if (pin == hardware().miso_pin[i] ) {
  934. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  935. volatile uint32_t *reg;
  936. reg = portConfigRegister(hardware().miso_pin[miso_pin_index]);
  937. *reg = 0;
  938. reg = portConfigRegister(hardware().miso_pin[i]);
  939. *reg = hardware().miso_mux[i];
  940. }
  941. miso_pin_index = i;
  942. return;
  943. }
  944. }
  945. }
  946. }
  947. void SPIClass::setSCK(uint8_t pin)
  948. {
  949. if (pin != hardware().sck_pin[sck_pin_index]) {
  950. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  951. if (pin == hardware().sck_pin[i] ) {
  952. if (hardware().clock_gate_register & hardware().clock_gate_mask) {
  953. volatile uint32_t *reg;
  954. reg = portConfigRegister(hardware().sck_pin[sck_pin_index]);
  955. *reg = 0;
  956. reg = portConfigRegister(hardware().sck_pin[i]);
  957. *reg = hardware().sck_mux[i];
  958. }
  959. sck_pin_index = i;
  960. return;
  961. }
  962. }
  963. }
  964. }
  965. bool SPIClass::pinIsChipSelect(uint8_t pin)
  966. {
  967. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  968. if (pin == hardware().cs_pin[i]) return hardware().cs_mask[i];
  969. }
  970. return 0;
  971. }
  972. bool SPIClass::pinIsMOSI(uint8_t pin)
  973. {
  974. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  975. if (pin == hardware().mosi_pin[i]) return true;
  976. }
  977. return false;
  978. }
  979. bool SPIClass::pinIsMISO(uint8_t pin)
  980. {
  981. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  982. if (pin == hardware().miso_pin[i]) return true;
  983. }
  984. return false;
  985. }
  986. bool SPIClass::pinIsSCK(uint8_t pin)
  987. {
  988. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  989. if (pin == hardware().sck_pin[i]) return true;
  990. }
  991. return false;
  992. }
  993. // setCS() is not intended for use from normal Arduino programs/sketches.
  994. uint8_t SPIClass::setCS(uint8_t pin)
  995. {
  996. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  997. if (pin == hardware().cs_pin[i]) {
  998. volatile uint32_t *reg = portConfigRegister(pin);
  999. *reg = hardware().cs_mux[i];
  1000. return hardware().cs_mask[i];
  1001. }
  1002. }
  1003. return 0;
  1004. }
  1005. void SPIClass::transfer(const void * buf, void * retbuf, size_t count) {
  1006. if (count == 0) return;
  1007. const uint8_t *p = (const uint8_t *)buf;
  1008. uint8_t *pret = (uint8_t *)retbuf;
  1009. uint8_t in;
  1010. while (!(port().S & SPI_S_SPTEF)) ; // wait
  1011. uint8_t out = p ? *p++ : _transferWriteFill;
  1012. port().DL = out;
  1013. while (--count > 0) {
  1014. if (p) {
  1015. out = *p++;
  1016. }
  1017. while (!(port().S & SPI_S_SPTEF)) ; // wait
  1018. __disable_irq();
  1019. port().DL = out;
  1020. while (!(port().S & SPI_S_SPRF)) ; // wait
  1021. in = port().DL;
  1022. __enable_irq();
  1023. if (pret)*pret++ = in;
  1024. }
  1025. while (!(port().S & SPI_S_SPRF)) ; // wait
  1026. in = port().DL;
  1027. if (pret)*pret = in;
  1028. }
  1029. //=============================================================================
  1030. // ASYNCH Support
  1031. //=============================================================================
  1032. //=========================================================================
  1033. // Try Transfer using DMA.
  1034. //=========================================================================
  1035. #ifdef SPI_HAS_TRANSFER_ASYNC
  1036. static uint8_t _dma_dummy_rx;
  1037. void SPIClass::dma_isr(void) {
  1038. // Serial.println("_spi_dma_rxISR");
  1039. _dmaRX->clearInterrupt();
  1040. port().C2 = 0;
  1041. uint8_t tmp __attribute__((unused)) = port().S;
  1042. _dmaTX->clearComplete();
  1043. _dmaRX->clearComplete();
  1044. _dma_state = DMAState::completed; // set back to 1 in case our call wants to start up dma again
  1045. _dma_event_responder->triggerEvent();
  1046. }
  1047. bool SPIClass::initDMAChannels() {
  1048. //Serial.println("First dma call"); Serial.flush();
  1049. _dmaTX = new DMAChannel();
  1050. if (_dmaTX == nullptr) {
  1051. return false;
  1052. }
  1053. _dmaTX->disable();
  1054. _dmaTX->destination((volatile uint8_t&)port().DL);
  1055. _dmaTX->disableOnCompletion();
  1056. _dmaTX->triggerAtHardwareEvent(hardware().tx_dma_channel);
  1057. _dmaRX = new DMAChannel();
  1058. if (_dmaRX == NULL) {
  1059. delete _dmaTX;
  1060. _dmaRX = nullptr;
  1061. return false;
  1062. }
  1063. _dmaRX->disable();
  1064. _dmaRX->source((volatile uint8_t&)port().DL);
  1065. _dmaRX->disableOnCompletion();
  1066. _dmaRX->triggerAtHardwareEvent(hardware().rx_dma_channel);
  1067. _dmaRX->attachInterrupt(hardware().dma_isr);
  1068. _dmaRX->interruptAtCompletion();
  1069. _dma_state = DMAState::idle; // Should be first thing set!
  1070. //Serial.println("end First dma call");
  1071. return true;
  1072. }
  1073. //=========================================================================
  1074. // Main Async Transfer function
  1075. //=========================================================================
  1076. bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) {
  1077. if (_dma_state == DMAState::notAllocated) {
  1078. if (!initDMAChannels()) {
  1079. return false;
  1080. }
  1081. }
  1082. if (_dma_state == DMAState::active)
  1083. return false; // already active
  1084. event_responder.clearEvent(); // Make sure it is not set yet
  1085. if (count < 2) {
  1086. // Use non-async version to simplify cases...
  1087. transfer(buf, retbuf, count);
  1088. event_responder.triggerEvent();
  1089. return true;
  1090. }
  1091. //_dmaTX->destination((volatile uint8_t&)port().DL);
  1092. //_dmaRX->source((volatile uint8_t&)port().DL);
  1093. _dmaTX->CFG->DCR = (_dmaTX->CFG->DCR & ~DMA_DCR_DSIZE(3)) | DMA_DCR_DSIZE(1);
  1094. _dmaRX->CFG->DCR = (_dmaRX->CFG->DCR & ~DMA_DCR_SSIZE(3)) | DMA_DCR_SSIZE(1); // 8 bit transfer
  1095. // Now see if the user passed in TX buffer to send.
  1096. uint8_t first_char;
  1097. if (buf) {
  1098. uint8_t *data_out = (uint8_t*)buf;
  1099. first_char = *data_out++;
  1100. _dmaTX->sourceBuffer(data_out, count-1);
  1101. } else {
  1102. first_char = (_transferWriteFill & 0xff);
  1103. _dmaTX->source((uint8_t&)_transferWriteFill); // maybe have setable value
  1104. _dmaTX->transferCount(count-1);
  1105. }
  1106. if (retbuf) {
  1107. _dmaRX->destinationBuffer((uint8_t*)retbuf, count);
  1108. } else {
  1109. _dmaRX->destination(_dma_dummy_rx); // NULL ?
  1110. _dmaRX->transferCount(count);
  1111. }
  1112. _dma_event_responder = &event_responder;
  1113. //Serial.println("Before DMA C2");
  1114. // Try pushing the first character
  1115. while (!(port().S & SPI_S_SPTEF));
  1116. port().DL = first_char;
  1117. port().C2 |= SPI_C2_TXDMAE | SPI_C2_RXDMAE;
  1118. // Now make sure SPI is enabled.
  1119. port().C1 |= SPI_C1_SPE;
  1120. _dmaRX->enable();
  1121. _dmaTX->enable();
  1122. _dma_state = DMAState::active;
  1123. return true;
  1124. }
  1125. #endif //SPI_HAS_TRANSFER_ASYNC
  1126. /**********************************************************/
  1127. /* 32 bit Teensy 4.x */
  1128. /**********************************************************/
  1129. #elif defined(__arm__) && defined(TEENSYDUINO) && (defined(__IMXRT1052__) || defined(__IMXRT1062__))
  1130. //#include "debug/printf.h"
  1131. void SPIClass::begin()
  1132. {
  1133. // CBCMR[LPSPI_CLK_SEL] - PLL2 = 528 MHz
  1134. // CBCMR[LPSPI_PODF] - div4 = 132 MHz
  1135. hardware().clock_gate_register &= ~hardware().clock_gate_mask;
  1136. CCM_CBCMR = (CCM_CBCMR & ~(CCM_CBCMR_LPSPI_PODF_MASK | CCM_CBCMR_LPSPI_CLK_SEL_MASK)) |
  1137. CCM_CBCMR_LPSPI_PODF(6) | CCM_CBCMR_LPSPI_CLK_SEL(2); // pg 714
  1138. uint32_t fastio = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
  1139. //uint32_t fastio = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
  1140. //Serial.printf("SPI MISO: %d MOSI: %d, SCK: %d\n", hardware().miso_pin[miso_pin_index], hardware().mosi_pin[mosi_pin_index], hardware().sck_pin[sck_pin_index]);
  1141. *(portControlRegister(hardware().miso_pin[miso_pin_index])) = fastio;
  1142. *(portControlRegister(hardware().mosi_pin[mosi_pin_index])) = fastio;
  1143. *(portControlRegister(hardware().sck_pin[sck_pin_index])) = fastio;
  1144. //printf("CBCMR = %08lX\n", CCM_CBCMR);
  1145. hardware().clock_gate_register |= hardware().clock_gate_mask;
  1146. *(portConfigRegister(hardware().miso_pin[miso_pin_index])) = hardware().miso_mux[miso_pin_index];
  1147. *(portConfigRegister(hardware().mosi_pin [mosi_pin_index])) = hardware().mosi_mux[mosi_pin_index];
  1148. *(portConfigRegister(hardware().sck_pin [sck_pin_index])) = hardware().sck_mux[sck_pin_index];
  1149. // Set the Mux pins
  1150. //Serial.println("SPI: Set Input select registers");
  1151. hardware().sck_select_input_register = hardware().sck_select_val;
  1152. hardware().sdi_select_input_register = hardware().sdi_select_val;
  1153. hardware().sdo_select_input_register = hardware().sdo_select_val;
  1154. //digitalWriteFast(10, HIGH);
  1155. //pinMode(10, OUTPUT);
  1156. //digitalWriteFast(10, HIGH);
  1157. port().CR = LPSPI_CR_RST;
  1158. // Lets initialize the Transmit FIFO watermark to FIFO size - 1...
  1159. // BUGBUG:: I assume queue of 16 for now...
  1160. port().FCR = LPSPI_FCR_TXWATER(15);
  1161. }
  1162. uint8_t SPIClass::pinIsChipSelect(uint8_t pin)
  1163. {
  1164. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  1165. if (pin == hardware().cs_pin[i]) return 1;
  1166. }
  1167. return 0;
  1168. }
  1169. bool SPIClass::pinIsChipSelect(uint8_t pin1, uint8_t pin2)
  1170. {
  1171. return false; // only one CS defined
  1172. }
  1173. bool SPIClass::pinIsMOSI(uint8_t pin)
  1174. {
  1175. for (unsigned int i = 0; i < sizeof(hardware().mosi_pin); i++) {
  1176. if (pin == hardware().mosi_pin[i]) return true;
  1177. }
  1178. return false;
  1179. }
  1180. bool SPIClass::pinIsMISO(uint8_t pin)
  1181. {
  1182. for (unsigned int i = 0; i < sizeof(hardware().miso_pin); i++) {
  1183. if (pin == hardware().miso_pin[i]) return true;
  1184. }
  1185. return false;
  1186. }
  1187. bool SPIClass::pinIsSCK(uint8_t pin)
  1188. {
  1189. for (unsigned int i = 0; i < sizeof(hardware().sck_pin); i++) {
  1190. if (pin == hardware().sck_pin[i]) return true;
  1191. }
  1192. return false;
  1193. }
  1194. // setCS() is not intended for use from normal Arduino programs/sketches.
  1195. uint8_t SPIClass::setCS(uint8_t pin)
  1196. {
  1197. for (unsigned int i = 0; i < sizeof(hardware().cs_pin); i++) {
  1198. if (pin == hardware().cs_pin[i]) {
  1199. *(portConfigRegister(pin)) = hardware().sck_mux[i];
  1200. return 1;
  1201. }
  1202. }
  1203. return 0;
  1204. }
  1205. void SPIClass::setMOSI(uint8_t pin)
  1206. {
  1207. // Currently only one defined so just return...
  1208. }
  1209. void SPIClass::setMISO(uint8_t pin)
  1210. {
  1211. // Currently only one defined so just return...
  1212. }
  1213. void SPIClass::setSCK(uint8_t pin)
  1214. {
  1215. // Currently only one defined so just return...
  1216. }
  1217. void SPIClass::setBitOrder(uint8_t bitOrder)
  1218. {
  1219. hardware().clock_gate_register |= hardware().clock_gate_mask;
  1220. if (bitOrder == LSBFIRST) {
  1221. port().TCR |= LPSPI_TCR_LSBF;
  1222. } else {
  1223. port().TCR &= ~LPSPI_TCR_LSBF;
  1224. }
  1225. }
  1226. void SPIClass::setDataMode(uint8_t dataMode)
  1227. {
  1228. hardware().clock_gate_register |= hardware().clock_gate_mask;
  1229. //SPCR = (SPCR & ~SPI_MODE_MASK) | dataMode;
  1230. }
  1231. void _spi_dma_rxISR0(void) {SPI.dma_rxisr();}
  1232. const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi4_hardware = {
  1233. CCM_CCGR1, CCM_CCGR1_LPSPI4(CCM_CCGR_ON),
  1234. DMAMUX_SOURCE_LPSPI4_TX, DMAMUX_SOURCE_LPSPI4_RX, _spi_dma_rxISR0,
  1235. 12,
  1236. 3 | 0x10,
  1237. 11,
  1238. 3 | 0x10,
  1239. 13,
  1240. 3 | 0x10,
  1241. 10,
  1242. 3 | 0x10,
  1243. IOMUXC_LPSPI4_SCK_SELECT_INPUT, IOMUXC_LPSPI4_SDI_SELECT_INPUT, IOMUXC_LPSPI4_SDO_SELECT_INPUT, IOMUXC_LPSPI4_PCS0_SELECT_INPUT,
  1244. 0, 0, 0, 0
  1245. };
  1246. SPIClass SPI((uintptr_t)&IMXRT_LPSPI4_S, (uintptr_t)&SPIClass::spiclass_lpspi4_hardware);
  1247. #if defined(__IMXRT1062__)
  1248. // T4 has two other possible SPI objects...
  1249. void _spi_dma_rxISR1(void) {SPI1.dma_rxisr();}
  1250. const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi3_hardware = {
  1251. CCM_CCGR1, CCM_CCGR1_LPSPI3(CCM_CCGR_ON),
  1252. DMAMUX_SOURCE_LPSPI3_TX, DMAMUX_SOURCE_LPSPI3_RX, _spi_dma_rxISR1,
  1253. 1,
  1254. 7 | 0x10,
  1255. 26,
  1256. 2 | 0x10,
  1257. 27,
  1258. 2 | 0x10,
  1259. 0,
  1260. 7 | 0x10,
  1261. IOMUXC_LPSPI3_SCK_SELECT_INPUT, IOMUXC_LPSPI3_SDI_SELECT_INPUT, IOMUXC_LPSPI3_SDO_SELECT_INPUT, IOMUXC_LPSPI3_PCS0_SELECT_INPUT,
  1262. 1, 0, 1, 0
  1263. };
  1264. SPIClass SPI1((uintptr_t)&IMXRT_LPSPI3_S, (uintptr_t)&SPIClass::spiclass_lpspi3_hardware);
  1265. void _spi_dma_rxISR2(void) {SPI2.dma_rxisr();}
  1266. const SPIClass::SPI_Hardware_t SPIClass::spiclass_lpspi1_hardware = {
  1267. CCM_CCGR1, CCM_CCGR1_LPSPI1(CCM_CCGR_ON),
  1268. DMAMUX_SOURCE_LPSPI1_TX, DMAMUX_SOURCE_LPSPI1_RX, _spi_dma_rxISR1,
  1269. 34,
  1270. 4 | 0x10,
  1271. 35,
  1272. 4 | 0x10,
  1273. 37,
  1274. 4 | 0x10,
  1275. 36,
  1276. 4 | 0x10,
  1277. IOMUXC_LPSPI1_SCK_SELECT_INPUT, IOMUXC_LPSPI1_SDI_SELECT_INPUT, IOMUXC_LPSPI1_SDO_SELECT_INPUT, IOMUXC_LPSPI1_PCS0_SELECT_INPUT,
  1278. 1, 1, 1, 0
  1279. };
  1280. SPIClass SPI2((uintptr_t)&IMXRT_LPSPI1_S, (uintptr_t)&SPIClass::spiclass_lpspi1_hardware);
  1281. #endif
  1282. //SPIClass SPI(&IMXRT_LPSPI4_S, &spiclass_lpspi4_hardware);
  1283. void SPIClass::usingInterrupt(IRQ_NUMBER_t interruptName)
  1284. {
  1285. uint32_t n = (uint32_t)interruptName;
  1286. if (n >= NVIC_NUM_INTERRUPTS) return;
  1287. //Serial.print("usingInterrupt ");
  1288. //Serial.println(n);
  1289. interruptMasksUsed |= (1 << (n >> 5));
  1290. interruptMask[n >> 5] |= (1 << (n & 0x1F));
  1291. //Serial.printf("interruptMasksUsed = %d\n", interruptMasksUsed);
  1292. //Serial.printf("interruptMask[0] = %08X\n", interruptMask[0]);
  1293. //Serial.printf("interruptMask[1] = %08X\n", interruptMask[1]);
  1294. //Serial.printf("interruptMask[2] = %08X\n", interruptMask[2]);
  1295. }
  1296. void SPIClass::notUsingInterrupt(IRQ_NUMBER_t interruptName)
  1297. {
  1298. uint32_t n = (uint32_t)interruptName;
  1299. if (n >= NVIC_NUM_INTERRUPTS) return;
  1300. interruptMask[n >> 5] &= ~(1 << (n & 0x1F));
  1301. if (interruptMask[n >> 5] == 0) {
  1302. interruptMasksUsed &= ~(1 << (n >> 5));
  1303. }
  1304. }
  1305. void SPIClass::transfer(const void * buf, void * retbuf, size_t count)
  1306. {
  1307. if (count == 0) return;
  1308. uint8_t *p_write = (uint8_t*)buf;
  1309. uint8_t *p_read = (uint8_t*)retbuf;
  1310. size_t count_read = count;
  1311. // Pass 1 keep it simple and don't try packing 8 bits into 16 yet..
  1312. // Lets clear the reader queue
  1313. port().CR = LPSPI_CR_RRF | LPSPI_CR_MEN; // clear the queue and make sure still enabled.
  1314. while (count > 0) {
  1315. // Push out the next byte;
  1316. port().TDR = p_write? *p_write++ : _transferWriteFill;
  1317. count--; // how many bytes left to output.
  1318. // Make sure queue is not full before pushing next byte out
  1319. do {
  1320. if ((port().RSR & LPSPI_RSR_RXEMPTY) == 0) {
  1321. uint8_t b = port().RDR; // Read any pending RX bytes in
  1322. if (p_read) *p_read++ = b;
  1323. count_read--;
  1324. }
  1325. } while ((port().SR & LPSPI_SR_TDF) == 0) ;
  1326. }
  1327. // now lets wait for all of the read bytes to be returned...
  1328. while (count_read) {
  1329. if ((port().RSR & LPSPI_RSR_RXEMPTY) == 0) {
  1330. uint8_t b = port().RDR; // Read any pending RX bytes in
  1331. if (p_read) *p_read++ = b;
  1332. count_read--;
  1333. }
  1334. }
  1335. }
  1336. void SPIClass::end(){}
  1337. //=============================================================================
  1338. // ASYNCH Support
  1339. //=============================================================================
  1340. //=========================================================================
  1341. // Try Transfer using DMA.
  1342. //=========================================================================
  1343. #ifdef SPI_HAS_TRANSFER_ASYNC
  1344. static uint8_t bit_bucket;
  1345. #define dontInterruptAtCompletion(dmac) (dmac)->TCD->CSR &= ~DMA_TCD_CSR_INTMAJOR
  1346. //=========================================================================
  1347. // Init the DMA channels
  1348. //=========================================================================
  1349. bool SPIClass::initDMAChannels() {
  1350. // Allocate our channels.
  1351. _dmaTX = new DMAChannel();
  1352. if (_dmaTX == nullptr) {
  1353. return false;
  1354. }
  1355. _dmaRX = new DMAChannel();
  1356. if (_dmaRX == nullptr) {
  1357. delete _dmaTX; // release it
  1358. _dmaTX = nullptr;
  1359. return false;
  1360. }
  1361. // Let's setup the RX chain
  1362. _dmaRX->disable();
  1363. _dmaRX->source((volatile uint8_t&)port().RDR);
  1364. _dmaRX->disableOnCompletion();
  1365. _dmaRX->triggerAtHardwareEvent(hardware().rx_dma_channel);
  1366. _dmaRX->attachInterrupt(hardware().dma_rxisr);
  1367. _dmaRX->interruptAtCompletion();
  1368. // We may be using settings chain here so lets set it up.
  1369. // Now lets setup TX chain. Note if trigger TX is not set
  1370. // we need to have the RX do it for us.
  1371. _dmaTX->disable();
  1372. _dmaTX->destination((volatile uint8_t&)port().TDR);
  1373. _dmaTX->disableOnCompletion();
  1374. if (hardware().tx_dma_channel) {
  1375. _dmaTX->triggerAtHardwareEvent(hardware().tx_dma_channel);
  1376. } else {
  1377. // Serial.printf("SPI InitDMA tx triger by RX: %x\n", (uint32_t)_dmaRX);
  1378. _dmaTX->triggerAtTransfersOf(*_dmaRX);
  1379. }
  1380. _dma_state = DMAState::idle; // Should be first thing set!
  1381. return true;
  1382. }
  1383. //=========================================================================
  1384. // Main Async Transfer function
  1385. //=========================================================================
  1386. #ifndef TRANSFER_COUNT_FIXED
  1387. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  1388. // note does no validation of length...
  1389. DMABaseClass::TCD_t *tcd = dmac->TCD;
  1390. if (!(tcd->BITER & DMA_TCD_BITER_ELINK)) {
  1391. tcd->BITER = len & 0x7fff;
  1392. } else {
  1393. tcd->BITER = (tcd->BITER & 0xFE00) | (len & 0x1ff);
  1394. }
  1395. tcd->CITER = tcd->BITER;
  1396. }
  1397. #else
  1398. inline void DMAChanneltransferCount(DMAChannel * dmac, unsigned int len) {
  1399. dmac->transferCount(len);
  1400. }
  1401. #endif
  1402. #ifdef DEBUG_DMA_TRANSFERS
  1403. void dumpDMA_TCD(DMABaseClass *dmabc)
  1404. {
  1405. Serial4.printf("%x %x:", (uint32_t)dmabc, (uint32_t)dmabc->TCD);
  1406. Serial4.printf("SA:%x SO:%d AT:%x NB:%x SL:%d DA:%x DO: %d CI:%x DL:%x CS:%x BI:%x\n", (uint32_t)dmabc->TCD->SADDR,
  1407. dmabc->TCD->SOFF, dmabc->TCD->ATTR, dmabc->TCD->NBYTES, dmabc->TCD->SLAST, (uint32_t)dmabc->TCD->DADDR,
  1408. dmabc->TCD->DOFF, dmabc->TCD->CITER, dmabc->TCD->DLASTSGA, dmabc->TCD->CSR, dmabc->TCD->BITER);
  1409. }
  1410. #endif
  1411. bool SPIClass::transfer(const void *buf, void *retbuf, size_t count, EventResponderRef event_responder) {
  1412. if (_dma_state == DMAState::notAllocated) {
  1413. if (!initDMAChannels())
  1414. return false;
  1415. }
  1416. if (_dma_state == DMAState::active)
  1417. return false; // already active
  1418. event_responder.clearEvent(); // Make sure it is not set yet
  1419. if (count < 2) {
  1420. // Use non-async version to simplify cases...
  1421. transfer(buf, retbuf, count);
  1422. event_responder.triggerEvent();
  1423. return true;
  1424. }
  1425. // Now handle the cases where the count > then how many we can output in one DMA request
  1426. if (count > MAX_DMA_COUNT) {
  1427. _dma_count_remaining = count - MAX_DMA_COUNT;
  1428. count = MAX_DMA_COUNT;
  1429. } else {
  1430. _dma_count_remaining = 0;
  1431. }
  1432. // Now See if caller passed in a source buffer.
  1433. _dmaTX->TCD->ATTR_DST = 0; // Make sure set for 8 bit mode
  1434. uint8_t *write_data = (uint8_t*) buf;
  1435. if (buf) {
  1436. _dmaTX->sourceBuffer((uint8_t*)write_data, count);
  1437. _dmaTX->TCD->SLAST = 0; // Finish with it pointing to next location
  1438. if ((uint32_t)write_data >= 0x20200000u) arm_dcache_flush(write_data, count);
  1439. } else {
  1440. _dmaTX->source((uint8_t&)_transferWriteFill); // maybe have setable value
  1441. DMAChanneltransferCount(_dmaTX, count);
  1442. }
  1443. if (retbuf) {
  1444. // On T3.5 must handle SPI1/2 differently as only one DMA channel
  1445. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  1446. _dmaRX->destinationBuffer((uint8_t*)retbuf, count);
  1447. _dmaRX->TCD->DLASTSGA = 0; // At end point after our bufffer
  1448. if ((uint32_t)retbuf >= 0x20200000u) arm_dcache_delete(retbuf, count);
  1449. } else {
  1450. // Write only mode
  1451. _dmaRX->TCD->ATTR_SRC = 0; //Make sure set for 8 bit mode...
  1452. _dmaRX->destination((uint8_t&)bit_bucket);
  1453. DMAChanneltransferCount(_dmaRX, count);
  1454. }
  1455. _dma_event_responder = &event_responder;
  1456. // Now try to start it?
  1457. // Setup DMA main object
  1458. yield();
  1459. #ifdef DEBUG_DMA_TRANSFERS
  1460. // Lets dump TX, RX
  1461. dumpDMA_TCD(_dmaTX);
  1462. dumpDMA_TCD(_dmaRX);
  1463. #endif
  1464. // Make sure port is in 8 bit mode and clear watermark
  1465. port().TCR = (port().TCR & ~(LPSPI_TCR_FRAMESZ(31))) | LPSPI_TCR_FRAMESZ(7);
  1466. port().FCR = 0;
  1467. // Lets try to output the first byte to make sure that we are in 8 bit mode...
  1468. port().DER = LPSPI_DER_TDDE | LPSPI_DER_RDDE; //enable DMA on both TX and RX
  1469. port().SR = 0x3f00; // clear out all of the other status...
  1470. _dmaRX->enable();
  1471. _dmaTX->enable();
  1472. _dma_state = DMAState::active;
  1473. return true;
  1474. }
  1475. //-------------------------------------------------------------------------
  1476. // DMA RX ISR
  1477. //-------------------------------------------------------------------------
  1478. void SPIClass::dma_rxisr(void) {
  1479. _dmaRX->clearInterrupt();
  1480. _dmaTX->clearComplete();
  1481. _dmaRX->clearComplete();
  1482. if (_dma_count_remaining) {
  1483. // What do I need to do to start it back up again...
  1484. // We will use the BITR/CITR from RX as TX may have prefed some stuff
  1485. if (_dma_count_remaining > MAX_DMA_COUNT) {
  1486. _dma_count_remaining -= MAX_DMA_COUNT;
  1487. } else {
  1488. DMAChanneltransferCount(_dmaTX, _dma_count_remaining);
  1489. DMAChanneltransferCount(_dmaRX, _dma_count_remaining);
  1490. _dma_count_remaining = 0;
  1491. }
  1492. _dmaRX->enable();
  1493. _dmaTX->enable();
  1494. } else {
  1495. port().FCR = LPSPI_FCR_TXWATER(15); // _spi_fcr_save; // restore the FSR status...
  1496. port().DER = 0; // DMA no longer doing TX (or RX)
  1497. port().CR = LPSPI_CR_MEN | LPSPI_CR_RRF | LPSPI_CR_RTF; // actually clear both...
  1498. port().SR = 0x3f00; // clear out all of the other status...
  1499. _dma_state = DMAState::completed; // set back to 1 in case our call wants to start up dma again
  1500. _dma_event_responder->triggerEvent();
  1501. }
  1502. }
  1503. #endif // SPI_HAS_TRANSFER_ASYNC
  1504. #endif