Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

SPI.cpp 50KB

il y a 6 ans
il y a 6 ans
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