Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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