Teensy 4.1 core updated for C++20
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
8 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
10 роки тому
9 роки тому
9 роки тому
10 роки тому
10 роки тому
9 роки тому
9 роки тому
10 роки тому
9 роки тому
10 роки тому
10 роки тому
10 роки тому
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309
  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2017 PJRC.COM, LLC.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #ifndef _avr_emulation_h_
  31. #define _avr_emulation_h_
  32. #include "kinetis.h"
  33. #include "core_pins.h"
  34. #include "pins_arduino.h"
  35. #ifdef __cplusplus
  36. #define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
  37. #define CONFIG_PULLUP (PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS)
  38. #define CONFIG_NOPULLUP (PORT_PCR_MUX(1))
  39. #if defined(KINETISK)
  40. // bitband addressing for atomic access to data direction register
  41. #define GPIO_SETBIT_ATOMIC(reg, bit) (*(uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) = 1)
  42. #define GPIO_CLRBIT_ATOMIC(reg, bit) (*(uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) = 0)
  43. #elif defined(KINETISL)
  44. // bit manipulation engine for atomic access to data direction register
  45. #define GPIO_SETBIT_ATOMIC(reg, bit) (*(uint32_t *)(((uint32_t)&(reg) - 0xF8000000) | 0x480FF000) = 1 << (bit))
  46. #define GPIO_CLRBIT_ATOMIC(reg, bit) (*(uint32_t *)(((uint32_t)&(reg) - 0xF8000000) | 0x440FF000) = ~(1 << (bit)))
  47. #endif
  48. class PORTDemulation
  49. {
  50. public:
  51. inline PORTDemulation & operator = (int val) __attribute__((always_inline)) {
  52. digitalWriteFast(0, (val & (1<<0)));
  53. if (!(CORE_PIN0_DDRREG & CORE_PIN0_BIT))
  54. CORE_PIN0_CONFIG = ((val & (1<<0)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  55. digitalWriteFast(1, (val & (1<<1)));
  56. if (!(CORE_PIN1_DDRREG & CORE_PIN1_BIT))
  57. CORE_PIN1_CONFIG = ((val & (1<<1)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  58. digitalWriteFast(2, (val & (1<<2)));
  59. if (!(CORE_PIN2_DDRREG & CORE_PIN2_BIT))
  60. CORE_PIN2_CONFIG = ((val & (1<<2)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  61. digitalWriteFast(3, (val & (1<<3)));
  62. if (!(CORE_PIN3_DDRREG & CORE_PIN3_BIT))
  63. CORE_PIN3_CONFIG = ((val & (1<<3)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  64. digitalWriteFast(4, (val & (1<<4)));
  65. if (!(CORE_PIN4_DDRREG & CORE_PIN4_BIT))
  66. CORE_PIN4_CONFIG = ((val & (1<<4)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  67. digitalWriteFast(5, (val & (1<<5)));
  68. if (!(CORE_PIN5_DDRREG & CORE_PIN5_BIT))
  69. CORE_PIN5_CONFIG = ((val & (1<<5)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  70. digitalWriteFast(6, (val & (1<<6)));
  71. if (!(CORE_PIN6_DDRREG & CORE_PIN6_BIT))
  72. CORE_PIN6_CONFIG = ((val & (1<<6)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  73. digitalWriteFast(7, (val & (1<<7)));
  74. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT))
  75. CORE_PIN7_CONFIG = ((val & (1<<7)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  76. return *this;
  77. }
  78. inline PORTDemulation & operator |= (int val) __attribute__((always_inline)) {
  79. if (val & (1<<0)) {
  80. digitalWriteFast(0, HIGH);
  81. if (!(CORE_PIN0_DDRREG & CORE_PIN0_BIT)) CORE_PIN0_CONFIG = CONFIG_PULLUP;
  82. }
  83. if (val & (1<<1)) {
  84. digitalWriteFast(1, HIGH);
  85. if (!(CORE_PIN1_DDRREG & CORE_PIN1_BIT)) CORE_PIN1_CONFIG = CONFIG_PULLUP;
  86. }
  87. if (val & (1<<2)) {
  88. digitalWriteFast(2, HIGH);
  89. if (!(CORE_PIN2_DDRREG & CORE_PIN2_BIT)) CORE_PIN2_CONFIG = CONFIG_PULLUP;
  90. }
  91. if (val & (1<<3)) {
  92. digitalWriteFast(3, HIGH);
  93. if (!(CORE_PIN3_DDRREG & CORE_PIN3_BIT)) CORE_PIN3_CONFIG = CONFIG_PULLUP;
  94. }
  95. if (val & (1<<4)) {
  96. digitalWriteFast(4, HIGH);
  97. if (!(CORE_PIN4_DDRREG & CORE_PIN4_BIT)) CORE_PIN4_CONFIG = CONFIG_PULLUP;
  98. }
  99. if (val & (1<<5)) {
  100. digitalWriteFast(5, HIGH);
  101. if (!(CORE_PIN5_DDRREG & CORE_PIN5_BIT)) CORE_PIN5_CONFIG = CONFIG_PULLUP;
  102. }
  103. if (val & (1<<6)) {
  104. digitalWriteFast(6, HIGH);
  105. if (!(CORE_PIN6_DDRREG & CORE_PIN6_BIT)) CORE_PIN6_CONFIG = CONFIG_PULLUP;
  106. }
  107. if (val & (1<<7)) {
  108. digitalWriteFast(7, HIGH);
  109. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT)) CORE_PIN7_CONFIG = CONFIG_PULLUP;
  110. }
  111. return *this;
  112. }
  113. inline PORTDemulation & operator &= (int val) __attribute__((always_inline)) {
  114. if (!(val & (1<<0))) {
  115. digitalWriteFast(0, LOW);
  116. if (!(CORE_PIN0_DDRREG & CORE_PIN0_BIT)) CORE_PIN0_CONFIG = CONFIG_NOPULLUP;
  117. }
  118. if (!(val & (1<<1))) {
  119. digitalWriteFast(1, LOW);
  120. if (!(CORE_PIN1_DDRREG & CORE_PIN1_BIT)) CORE_PIN1_CONFIG = CONFIG_NOPULLUP;
  121. }
  122. if (!(val & (1<<2))) {
  123. digitalWriteFast(2, LOW);
  124. if (!(CORE_PIN2_DDRREG & CORE_PIN2_BIT)) CORE_PIN2_CONFIG = CONFIG_NOPULLUP;
  125. }
  126. if (!(val & (1<<3))) {
  127. digitalWriteFast(3, LOW);
  128. if (!(CORE_PIN3_DDRREG & CORE_PIN3_BIT)) CORE_PIN3_CONFIG = CONFIG_NOPULLUP;
  129. }
  130. if (!(val & (1<<4))) {
  131. digitalWriteFast(4, LOW);
  132. if (!(CORE_PIN4_DDRREG & CORE_PIN4_BIT)) CORE_PIN4_CONFIG = CONFIG_NOPULLUP;
  133. }
  134. if (!(val & (1<<5))) {
  135. digitalWriteFast(5, LOW);
  136. if (!(CORE_PIN5_DDRREG & CORE_PIN5_BIT)) CORE_PIN5_CONFIG = CONFIG_NOPULLUP;
  137. }
  138. if (!(val & (1<<6))) {
  139. digitalWriteFast(6, LOW);
  140. if (!(CORE_PIN6_DDRREG & CORE_PIN6_BIT)) CORE_PIN6_CONFIG = CONFIG_NOPULLUP;
  141. }
  142. if (!(val & (1<<7))) {
  143. digitalWriteFast(7, LOW);
  144. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT)) CORE_PIN7_CONFIG = CONFIG_NOPULLUP;
  145. }
  146. return *this;
  147. }
  148. };
  149. extern PORTDemulation PORTD;
  150. class PINDemulation
  151. {
  152. public:
  153. inline int operator & (int val) const __attribute__((always_inline)) {
  154. int ret = 0;
  155. if ((val & (1<<0)) && digitalReadFast(0)) ret |= (1<<0);
  156. if ((val & (1<<1)) && digitalReadFast(1)) ret |= (1<<1);
  157. if ((val & (1<<2)) && digitalReadFast(2)) ret |= (1<<2);
  158. if ((val & (1<<3)) && digitalReadFast(3)) ret |= (1<<3);
  159. if ((val & (1<<4)) && digitalReadFast(4)) ret |= (1<<4);
  160. if ((val & (1<<5)) && digitalReadFast(5)) ret |= (1<<5);
  161. if ((val & (1<<6)) && digitalReadFast(6)) ret |= (1<<6);
  162. if ((val & (1<<7)) && digitalReadFast(7)) ret |= (1<<7);
  163. return ret;
  164. }
  165. operator int () const __attribute__((always_inline)) {
  166. int ret = 0;
  167. if (digitalReadFast(0)) ret |= (1<<0);
  168. if (digitalReadFast(1)) ret |= (1<<1);
  169. if (digitalReadFast(2)) ret |= (1<<2);
  170. if (digitalReadFast(3)) ret |= (1<<3);
  171. if (digitalReadFast(4)) ret |= (1<<4);
  172. if (digitalReadFast(5)) ret |= (1<<5);
  173. if (digitalReadFast(6)) ret |= (1<<6);
  174. if (digitalReadFast(7)) ret |= (1<<7);
  175. return ret;
  176. }
  177. };
  178. extern PINDemulation PIND;
  179. class DDRDemulation
  180. {
  181. public:
  182. inline DDRDemulation & operator = (int val) __attribute__((always_inline)) {
  183. if (val & (1<<0)) set0(); else clr0();
  184. if (val & (1<<1)) set1(); else clr1();
  185. if (val & (1<<2)) set2(); else clr2();
  186. if (val & (1<<3)) set3(); else clr3();
  187. if (val & (1<<4)) set4(); else clr4();
  188. if (val & (1<<5)) set5(); else clr5();
  189. if (val & (1<<6)) set6(); else clr6();
  190. if (val & (1<<7)) set7(); else clr7();
  191. return *this;
  192. }
  193. inline DDRDemulation & operator |= (int val) __attribute__((always_inline)) {
  194. if (val & (1<<0)) set0();
  195. if (val & (1<<1)) set1();
  196. if (val & (1<<2)) set2();
  197. if (val & (1<<3)) set3();
  198. if (val & (1<<4)) set4();
  199. if (val & (1<<5)) set5();
  200. if (val & (1<<6)) set6();
  201. if (val & (1<<7)) set7();
  202. return *this;
  203. }
  204. inline DDRDemulation & operator &= (int val) __attribute__((always_inline)) {
  205. if (!(val & (1<<0))) clr0();
  206. if (!(val & (1<<1))) clr1();
  207. if (!(val & (1<<2))) clr2();
  208. if (!(val & (1<<3))) clr3();
  209. if (!(val & (1<<4))) clr4();
  210. if (!(val & (1<<5))) clr5();
  211. if (!(val & (1<<6))) clr6();
  212. if (!(val & (1<<7))) clr7();
  213. return *this;
  214. }
  215. private:
  216. inline void set0() __attribute__((always_inline)) {
  217. GPIO_SETBIT_ATOMIC(CORE_PIN0_DDRREG, CORE_PIN0_BIT);
  218. CORE_PIN0_CONFIG = CONFIG_PULLUP;
  219. }
  220. inline void set1() __attribute__((always_inline)) {
  221. GPIO_SETBIT_ATOMIC(CORE_PIN1_DDRREG, CORE_PIN1_BIT);
  222. CORE_PIN1_CONFIG = CONFIG_PULLUP;
  223. }
  224. inline void set2() __attribute__((always_inline)) {
  225. GPIO_SETBIT_ATOMIC(CORE_PIN2_DDRREG, CORE_PIN2_BIT);
  226. CORE_PIN2_CONFIG = CONFIG_PULLUP;
  227. }
  228. inline void set3() __attribute__((always_inline)) {
  229. GPIO_SETBIT_ATOMIC(CORE_PIN3_DDRREG, CORE_PIN3_BIT);
  230. CORE_PIN3_CONFIG = CONFIG_PULLUP;
  231. }
  232. inline void set4() __attribute__((always_inline)) {
  233. GPIO_SETBIT_ATOMIC(CORE_PIN4_DDRREG, CORE_PIN4_BIT);
  234. CORE_PIN4_CONFIG = CONFIG_PULLUP;
  235. }
  236. inline void set5() __attribute__((always_inline)) {
  237. GPIO_SETBIT_ATOMIC(CORE_PIN5_DDRREG, CORE_PIN5_BIT);
  238. CORE_PIN5_CONFIG = CONFIG_PULLUP;
  239. }
  240. inline void set6() __attribute__((always_inline)) {
  241. GPIO_SETBIT_ATOMIC(CORE_PIN6_DDRREG, CORE_PIN6_BIT);
  242. CORE_PIN6_CONFIG = CONFIG_PULLUP;
  243. }
  244. inline void set7() __attribute__((always_inline)) {
  245. GPIO_SETBIT_ATOMIC(CORE_PIN7_DDRREG, CORE_PIN7_BIT);
  246. CORE_PIN7_CONFIG = CONFIG_PULLUP;
  247. }
  248. inline void clr0() __attribute__((always_inline)) {
  249. CORE_PIN0_CONFIG = ((CORE_PIN0_PORTREG & CORE_PIN0_BITMASK)
  250. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  251. GPIO_CLRBIT_ATOMIC(CORE_PIN0_DDRREG, CORE_PIN0_BIT);
  252. }
  253. inline void clr1() __attribute__((always_inline)) {
  254. CORE_PIN1_CONFIG = ((CORE_PIN1_PORTREG & CORE_PIN1_BITMASK)
  255. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  256. GPIO_CLRBIT_ATOMIC(CORE_PIN1_DDRREG, CORE_PIN1_BIT);
  257. }
  258. inline void clr2() __attribute__((always_inline)) {
  259. CORE_PIN2_CONFIG = ((CORE_PIN2_PORTREG & CORE_PIN2_BITMASK)
  260. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  261. GPIO_CLRBIT_ATOMIC(CORE_PIN2_DDRREG, CORE_PIN2_BIT);
  262. }
  263. inline void clr3() __attribute__((always_inline)) {
  264. CORE_PIN3_CONFIG = ((CORE_PIN3_PORTREG & CORE_PIN3_BITMASK)
  265. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  266. GPIO_CLRBIT_ATOMIC(CORE_PIN3_DDRREG, CORE_PIN3_BIT);
  267. }
  268. inline void clr4() __attribute__((always_inline)) {
  269. CORE_PIN4_CONFIG = ((CORE_PIN4_PORTREG & CORE_PIN4_BITMASK)
  270. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  271. GPIO_CLRBIT_ATOMIC(CORE_PIN4_DDRREG, CORE_PIN4_BIT);
  272. }
  273. inline void clr5() __attribute__((always_inline)) {
  274. CORE_PIN5_CONFIG = ((CORE_PIN5_PORTREG & CORE_PIN5_BITMASK)
  275. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  276. GPIO_CLRBIT_ATOMIC(CORE_PIN5_DDRREG, CORE_PIN5_BIT);
  277. }
  278. inline void clr6() __attribute__((always_inline)) {
  279. CORE_PIN6_CONFIG = ((CORE_PIN6_PORTREG & CORE_PIN6_BITMASK)
  280. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  281. GPIO_CLRBIT_ATOMIC(CORE_PIN6_DDRREG, CORE_PIN6_BIT);
  282. }
  283. inline void clr7() __attribute__((always_inline)) {
  284. CORE_PIN7_CONFIG = ((CORE_PIN7_PORTREG & CORE_PIN7_BITMASK)
  285. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  286. GPIO_CLRBIT_ATOMIC(CORE_PIN7_DDRREG, CORE_PIN7_BIT);
  287. }
  288. };
  289. extern DDRDemulation DDRD;
  290. class PORTBemulation
  291. {
  292. public:
  293. inline PORTBemulation & operator = (int val) __attribute__((always_inline)) {
  294. digitalWriteFast(8, (val & (1<<0)));
  295. if (!(CORE_PIN8_DDRREG & CORE_PIN8_BIT))
  296. CORE_PIN8_CONFIG = ((val & (1<<0)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  297. digitalWriteFast(9, (val & (1<<1)));
  298. if (!(CORE_PIN9_DDRREG & CORE_PIN9_BIT))
  299. CORE_PIN9_CONFIG = ((val & (1<<1)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  300. digitalWriteFast(10, (val & (1<<2)));
  301. if (!(CORE_PIN10_DDRREG & CORE_PIN10_BIT))
  302. CORE_PIN10_CONFIG = ((val & (1<<2)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  303. digitalWriteFast(11, (val & (1<<3)));
  304. if (!(CORE_PIN11_DDRREG & CORE_PIN11_BIT))
  305. CORE_PIN11_CONFIG = ((val & (1<<3)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  306. digitalWriteFast(12, (val & (1<<4)));
  307. if (!(CORE_PIN12_DDRREG & CORE_PIN12_BIT))
  308. CORE_PIN12_CONFIG = ((val & (1<<4)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  309. digitalWriteFast(13, (val & (1<<5)));
  310. if (!(CORE_PIN13_DDRREG & CORE_PIN13_BIT))
  311. CORE_PIN13_CONFIG = ((val & (1<<5)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  312. return *this;
  313. }
  314. inline PORTBemulation & operator |= (int val) __attribute__((always_inline)) {
  315. if (val & (1<<0)) {
  316. digitalWriteFast(8, HIGH);
  317. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT)) CORE_PIN8_CONFIG = CONFIG_PULLUP;
  318. }
  319. if (val & (1<<1)) {
  320. digitalWriteFast(9, HIGH);
  321. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT)) CORE_PIN9_CONFIG = CONFIG_PULLUP;
  322. }
  323. if (val & (1<<2)) {
  324. digitalWriteFast(10, HIGH);
  325. if (!(CORE_PIN10_DDRREG & CORE_PIN10_BIT)) CORE_PIN10_CONFIG = CONFIG_PULLUP;
  326. }
  327. if (val & (1<<3)) {
  328. digitalWriteFast(11, HIGH);
  329. if (!(CORE_PIN11_DDRREG & CORE_PIN11_BIT)) CORE_PIN11_CONFIG = CONFIG_PULLUP;
  330. }
  331. if (val & (1<<4)) {
  332. digitalWriteFast(12, HIGH);
  333. if (!(CORE_PIN12_DDRREG & CORE_PIN12_BIT)) CORE_PIN12_CONFIG = CONFIG_PULLUP;
  334. }
  335. if (val & (1<<5)) {
  336. digitalWriteFast(13, HIGH);
  337. if (!(CORE_PIN13_DDRREG & CORE_PIN13_BIT)) CORE_PIN13_CONFIG = CONFIG_PULLUP;
  338. }
  339. return *this;
  340. }
  341. inline PORTBemulation & operator &= (int val) __attribute__((always_inline)) {
  342. if (!(val & (1<<0))) {
  343. digitalWriteFast(8, LOW);
  344. if (!(CORE_PIN8_DDRREG & CORE_PIN8_BIT)) CORE_PIN8_CONFIG = CONFIG_NOPULLUP;
  345. }
  346. if (!(val & (1<<1))) {
  347. digitalWriteFast(9, LOW);
  348. if (!(CORE_PIN9_DDRREG & CORE_PIN9_BIT)) CORE_PIN9_CONFIG = CONFIG_NOPULLUP;
  349. }
  350. if (!(val & (1<<2))) {
  351. digitalWriteFast(10, LOW);
  352. if (!(CORE_PIN10_DDRREG & CORE_PIN10_BIT)) CORE_PIN10_CONFIG = CONFIG_NOPULLUP;
  353. }
  354. if (!(val & (1<<3))) {
  355. digitalWriteFast(11, LOW);
  356. if (!(CORE_PIN11_DDRREG & CORE_PIN11_BIT)) CORE_PIN11_CONFIG = CONFIG_NOPULLUP;
  357. }
  358. if (!(val & (1<<4))) {
  359. digitalWriteFast(12, LOW);
  360. if (!(CORE_PIN12_DDRREG & CORE_PIN12_BIT)) CORE_PIN12_CONFIG = CONFIG_NOPULLUP;
  361. }
  362. if (!(val & (1<<5))) {
  363. digitalWriteFast(13, LOW);
  364. if (!(CORE_PIN13_DDRREG & CORE_PIN13_BIT)) CORE_PIN13_CONFIG = CONFIG_NOPULLUP;
  365. }
  366. return *this;
  367. }
  368. };
  369. extern PORTBemulation PORTB;
  370. class PINBemulation
  371. {
  372. public:
  373. inline int operator & (int val) const __attribute__((always_inline)) {
  374. int ret = 0;
  375. if ((val & (1<<0)) && digitalReadFast(8)) ret |= (1<<0);
  376. if ((val & (1<<1)) && digitalReadFast(9)) ret |= (1<<1);
  377. if ((val & (1<<2)) && digitalReadFast(10)) ret |= (1<<2);
  378. if ((val & (1<<3)) && digitalReadFast(11)) ret |= (1<<3);
  379. if ((val & (1<<4)) && digitalReadFast(12)) ret |= (1<<4);
  380. if ((val & (1<<5)) && digitalReadFast(13)) ret |= (1<<5);
  381. return ret;
  382. }
  383. operator int () const __attribute__((always_inline)) {
  384. int ret = 0;
  385. if (digitalReadFast(8)) ret |= (1<<0);
  386. if (digitalReadFast(9)) ret |= (1<<1);
  387. if (digitalReadFast(10)) ret |= (1<<2);
  388. if (digitalReadFast(11)) ret |= (1<<3);
  389. if (digitalReadFast(12)) ret |= (1<<4);
  390. if (digitalReadFast(13)) ret |= (1<<5);
  391. return ret;
  392. }
  393. };
  394. extern PINBemulation PINB;
  395. class DDRBemulation
  396. {
  397. public:
  398. inline DDRBemulation & operator = (int val) __attribute__((always_inline)) {
  399. if (val & (1<<0)) set0(); else clr0();
  400. if (val & (1<<1)) set1(); else clr1();
  401. if (val & (1<<2)) set2(); else clr2();
  402. if (val & (1<<3)) set3(); else clr3();
  403. if (val & (1<<4)) set4(); else clr4();
  404. if (val & (1<<5)) set5(); else clr5();
  405. return *this;
  406. }
  407. inline DDRBemulation & operator |= (int val) __attribute__((always_inline)) {
  408. if (val & (1<<0)) set0();
  409. if (val & (1<<1)) set1();
  410. if (val & (1<<2)) set2();
  411. if (val & (1<<3)) set3();
  412. if (val & (1<<4)) set4();
  413. if (val & (1<<5)) set5();
  414. return *this;
  415. }
  416. inline DDRBemulation & operator &= (int val) __attribute__((always_inline)) {
  417. if (!(val & (1<<0))) clr0();
  418. if (!(val & (1<<1))) clr1();
  419. if (!(val & (1<<2))) clr2();
  420. if (!(val & (1<<3))) clr3();
  421. if (!(val & (1<<4))) clr4();
  422. if (!(val & (1<<5))) clr5();
  423. return *this;
  424. }
  425. private:
  426. inline void set0() __attribute__((always_inline)) {
  427. GPIO_SETBIT_ATOMIC(CORE_PIN8_DDRREG, CORE_PIN8_BIT);
  428. CORE_PIN8_CONFIG = CONFIG_PULLUP;
  429. }
  430. inline void set1() __attribute__((always_inline)) {
  431. GPIO_SETBIT_ATOMIC(CORE_PIN9_DDRREG, CORE_PIN9_BIT);
  432. CORE_PIN9_CONFIG = CONFIG_PULLUP;
  433. }
  434. inline void set2() __attribute__((always_inline)) {
  435. GPIO_SETBIT_ATOMIC(CORE_PIN10_DDRREG, CORE_PIN10_BIT);
  436. CORE_PIN10_CONFIG = CONFIG_PULLUP;
  437. }
  438. inline void set3() __attribute__((always_inline)) {
  439. GPIO_SETBIT_ATOMIC(CORE_PIN11_DDRREG, CORE_PIN11_BIT);
  440. CORE_PIN11_CONFIG = CONFIG_PULLUP;
  441. }
  442. inline void set4() __attribute__((always_inline)) {
  443. GPIO_SETBIT_ATOMIC(CORE_PIN12_DDRREG, CORE_PIN12_BIT);
  444. CORE_PIN12_CONFIG = CONFIG_PULLUP;
  445. }
  446. inline void set5() __attribute__((always_inline)) {
  447. GPIO_SETBIT_ATOMIC(CORE_PIN13_DDRREG, CORE_PIN13_BIT);
  448. CORE_PIN13_CONFIG = CONFIG_PULLUP;
  449. }
  450. inline void clr0() __attribute__((always_inline)) {
  451. CORE_PIN8_CONFIG = ((CORE_PIN8_PORTREG & CORE_PIN8_BITMASK)
  452. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  453. GPIO_CLRBIT_ATOMIC(CORE_PIN8_DDRREG, CORE_PIN8_BIT);
  454. }
  455. inline void clr1() __attribute__((always_inline)) {
  456. CORE_PIN9_CONFIG = ((CORE_PIN9_PORTREG & CORE_PIN9_BITMASK)
  457. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  458. GPIO_CLRBIT_ATOMIC(CORE_PIN9_DDRREG, CORE_PIN9_BIT);
  459. }
  460. inline void clr2() __attribute__((always_inline)) {
  461. CORE_PIN10_CONFIG = ((CORE_PIN10_PORTREG & CORE_PIN10_BITMASK)
  462. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  463. GPIO_CLRBIT_ATOMIC(CORE_PIN10_DDRREG, CORE_PIN10_BIT);
  464. }
  465. inline void clr3() __attribute__((always_inline)) {
  466. CORE_PIN11_CONFIG = ((CORE_PIN11_PORTREG & CORE_PIN11_BITMASK)
  467. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  468. GPIO_CLRBIT_ATOMIC(CORE_PIN11_DDRREG, CORE_PIN11_BIT);
  469. }
  470. inline void clr4() __attribute__((always_inline)) {
  471. CORE_PIN12_CONFIG = ((CORE_PIN12_PORTREG & CORE_PIN12_BITMASK)
  472. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  473. GPIO_CLRBIT_ATOMIC(CORE_PIN12_DDRREG, CORE_PIN12_BIT);
  474. }
  475. inline void clr5() __attribute__((always_inline)) {
  476. CORE_PIN13_CONFIG = ((CORE_PIN13_PORTREG & CORE_PIN13_BITMASK)
  477. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  478. GPIO_CLRBIT_ATOMIC(CORE_PIN13_DDRREG, CORE_PIN13_BIT);
  479. }
  480. };
  481. extern DDRBemulation DDRB;
  482. class PORTCemulation
  483. {
  484. public:
  485. inline PORTCemulation & operator = (int val) __attribute__((always_inline)) {
  486. digitalWriteFast(14, (val & (1<<0)));
  487. if (!(CORE_PIN14_DDRREG & CORE_PIN14_BIT))
  488. CORE_PIN14_CONFIG = ((val & (1<<0)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  489. digitalWriteFast(15, (val & (1<<1)));
  490. if (!(CORE_PIN15_DDRREG & CORE_PIN15_BIT))
  491. CORE_PIN15_CONFIG = ((val & (1<<1)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  492. digitalWriteFast(16, (val & (1<<2)));
  493. if (!(CORE_PIN16_DDRREG & CORE_PIN16_BIT))
  494. CORE_PIN16_CONFIG = ((val & (1<<2)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  495. digitalWriteFast(17, (val & (1<<3)));
  496. if (!(CORE_PIN17_DDRREG & CORE_PIN17_BIT))
  497. CORE_PIN17_CONFIG = ((val & (1<<3)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  498. digitalWriteFast(18, (val & (1<<4)));
  499. if (!(CORE_PIN18_DDRREG & CORE_PIN18_BIT))
  500. CORE_PIN18_CONFIG = ((val & (1<<4)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  501. digitalWriteFast(19, (val & (1<<5)));
  502. if (!(CORE_PIN19_DDRREG & CORE_PIN19_BIT))
  503. CORE_PIN19_CONFIG = ((val & (1<<5)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  504. return *this;
  505. }
  506. inline PORTCemulation & operator |= (int val) __attribute__((always_inline)) {
  507. if (val & (1<<0)) {
  508. digitalWriteFast(14, HIGH);
  509. if (!(CORE_PIN14_DDRREG & CORE_PIN14_BIT)) CORE_PIN14_CONFIG = CONFIG_PULLUP;
  510. }
  511. if (val & (1<<1)) {
  512. digitalWriteFast(15, HIGH);
  513. if (!(CORE_PIN15_DDRREG & CORE_PIN15_BIT)) CORE_PIN15_CONFIG = CONFIG_PULLUP;
  514. }
  515. if (val & (1<<2)) {
  516. digitalWriteFast(16, HIGH);
  517. if (!(CORE_PIN16_DDRREG & CORE_PIN16_BIT)) CORE_PIN16_CONFIG = CONFIG_PULLUP;
  518. }
  519. if (val & (1<<3)) {
  520. digitalWriteFast(17, HIGH);
  521. if (!(CORE_PIN17_DDRREG & CORE_PIN17_BIT)) CORE_PIN17_CONFIG = CONFIG_PULLUP;
  522. }
  523. if (val & (1<<4)) {
  524. digitalWriteFast(18, HIGH);
  525. if (!(CORE_PIN18_DDRREG & CORE_PIN18_BIT)) CORE_PIN18_CONFIG = CONFIG_PULLUP;
  526. }
  527. if (val & (1<<5)) {
  528. digitalWriteFast(19, HIGH);
  529. if (!(CORE_PIN19_DDRREG & CORE_PIN19_BIT)) CORE_PIN19_CONFIG = CONFIG_PULLUP;
  530. }
  531. return *this;
  532. }
  533. inline PORTCemulation & operator &= (int val) __attribute__((always_inline)) {
  534. if (!(val & (1<<0))) {
  535. digitalWriteFast(14, LOW);
  536. if (!(CORE_PIN14_DDRREG & CORE_PIN14_BIT)) CORE_PIN14_CONFIG = CONFIG_NOPULLUP;
  537. }
  538. if (!(val & (1<<1))) {
  539. digitalWriteFast(15, LOW);
  540. if (!(CORE_PIN15_DDRREG & CORE_PIN15_BIT)) CORE_PIN15_CONFIG = CONFIG_NOPULLUP;
  541. }
  542. if (!(val & (1<<2))) {
  543. digitalWriteFast(16, LOW);
  544. if (!(CORE_PIN16_DDRREG & CORE_PIN16_BIT)) CORE_PIN16_CONFIG = CONFIG_NOPULLUP;
  545. }
  546. if (!(val & (1<<3))) {
  547. digitalWriteFast(17, LOW);
  548. if (!(CORE_PIN17_DDRREG & CORE_PIN17_BIT)) CORE_PIN17_CONFIG = CONFIG_NOPULLUP;
  549. }
  550. if (!(val & (1<<4))) {
  551. digitalWriteFast(18, LOW);
  552. if (!(CORE_PIN18_DDRREG & CORE_PIN18_BIT)) CORE_PIN18_CONFIG = CONFIG_NOPULLUP;
  553. }
  554. if (!(val & (1<<5))) {
  555. digitalWriteFast(19, LOW);
  556. if (!(CORE_PIN19_DDRREG & CORE_PIN19_BIT)) CORE_PIN19_CONFIG = CONFIG_NOPULLUP;
  557. }
  558. return *this;
  559. }
  560. };
  561. extern PORTCemulation PORTC;
  562. class PINCemulation
  563. {
  564. public:
  565. inline int operator & (int val) const __attribute__((always_inline)) {
  566. int ret = 0;
  567. if ((val & (1<<0)) && digitalReadFast(14)) ret |= (1<<0);
  568. if ((val & (1<<1)) && digitalReadFast(15)) ret |= (1<<1);
  569. if ((val & (1<<2)) && digitalReadFast(16)) ret |= (1<<2);
  570. if ((val & (1<<3)) && digitalReadFast(17)) ret |= (1<<3);
  571. if ((val & (1<<4)) && digitalReadFast(18)) ret |= (1<<4);
  572. if ((val & (1<<5)) && digitalReadFast(19)) ret |= (1<<5);
  573. return ret;
  574. }
  575. operator int () const __attribute__((always_inline)) {
  576. int ret = 0;
  577. if (digitalReadFast(14)) ret |= (1<<0);
  578. if (digitalReadFast(15)) ret |= (1<<1);
  579. if (digitalReadFast(15)) ret |= (1<<2);
  580. if (digitalReadFast(17)) ret |= (1<<3);
  581. if (digitalReadFast(18)) ret |= (1<<4);
  582. if (digitalReadFast(19)) ret |= (1<<5);
  583. return ret;
  584. }
  585. };
  586. extern PINCemulation PINC;
  587. class DDRCemulation
  588. {
  589. public:
  590. inline DDRCemulation & operator = (int val) __attribute__((always_inline)) {
  591. if (val & (1<<0)) set0(); else clr0();
  592. if (val & (1<<1)) set1(); else clr1();
  593. if (val & (1<<2)) set2(); else clr2();
  594. if (val & (1<<3)) set3(); else clr3();
  595. if (val & (1<<4)) set4(); else clr4();
  596. if (val & (1<<5)) set5(); else clr5();
  597. return *this;
  598. }
  599. inline DDRCemulation & operator |= (int val) __attribute__((always_inline)) {
  600. if (val & (1<<0)) set0();
  601. if (val & (1<<1)) set1();
  602. if (val & (1<<2)) set2();
  603. if (val & (1<<3)) set3();
  604. if (val & (1<<4)) set4();
  605. if (val & (1<<5)) set5();
  606. return *this;
  607. }
  608. inline DDRCemulation & operator &= (int val) __attribute__((always_inline)) {
  609. if (!(val & (1<<0))) clr0();
  610. if (!(val & (1<<1))) clr1();
  611. if (!(val & (1<<2))) clr2();
  612. if (!(val & (1<<3))) clr3();
  613. if (!(val & (1<<4))) clr4();
  614. if (!(val & (1<<5))) clr5();
  615. return *this;
  616. }
  617. private:
  618. inline void set0() __attribute__((always_inline)) {
  619. GPIO_SETBIT_ATOMIC(CORE_PIN14_DDRREG, CORE_PIN14_BIT);
  620. CORE_PIN14_CONFIG = CONFIG_PULLUP;
  621. }
  622. inline void set1() __attribute__((always_inline)) {
  623. GPIO_SETBIT_ATOMIC(CORE_PIN15_DDRREG, CORE_PIN15_BIT);
  624. CORE_PIN15_CONFIG = CONFIG_PULLUP;
  625. }
  626. inline void set2() __attribute__((always_inline)) {
  627. GPIO_SETBIT_ATOMIC(CORE_PIN16_DDRREG, CORE_PIN16_BIT);
  628. CORE_PIN16_CONFIG = CONFIG_PULLUP;
  629. }
  630. inline void set3() __attribute__((always_inline)) {
  631. GPIO_SETBIT_ATOMIC(CORE_PIN17_DDRREG, CORE_PIN17_BIT);
  632. CORE_PIN17_CONFIG = CONFIG_PULLUP;
  633. }
  634. inline void set4() __attribute__((always_inline)) {
  635. GPIO_SETBIT_ATOMIC(CORE_PIN18_DDRREG, CORE_PIN18_BIT);
  636. CORE_PIN18_CONFIG = CONFIG_PULLUP;
  637. }
  638. inline void set5() __attribute__((always_inline)) {
  639. GPIO_SETBIT_ATOMIC(CORE_PIN19_DDRREG, CORE_PIN19_BIT);
  640. CORE_PIN19_CONFIG = CONFIG_PULLUP;
  641. }
  642. inline void clr0() __attribute__((always_inline)) {
  643. CORE_PIN14_CONFIG = ((CORE_PIN14_PORTREG & CORE_PIN14_BITMASK)
  644. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  645. GPIO_CLRBIT_ATOMIC(CORE_PIN14_DDRREG, CORE_PIN14_BIT);
  646. }
  647. inline void clr1() __attribute__((always_inline)) {
  648. CORE_PIN15_CONFIG = ((CORE_PIN15_PORTREG & CORE_PIN15_BITMASK)
  649. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  650. GPIO_CLRBIT_ATOMIC(CORE_PIN15_DDRREG, CORE_PIN15_BIT);
  651. }
  652. inline void clr2() __attribute__((always_inline)) {
  653. CORE_PIN16_CONFIG = ((CORE_PIN16_PORTREG & CORE_PIN16_BITMASK)
  654. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  655. GPIO_CLRBIT_ATOMIC(CORE_PIN16_DDRREG, CORE_PIN16_BIT);
  656. }
  657. inline void clr3() __attribute__((always_inline)) {
  658. CORE_PIN17_CONFIG = ((CORE_PIN17_PORTREG & CORE_PIN17_BITMASK)
  659. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  660. GPIO_CLRBIT_ATOMIC(CORE_PIN17_DDRREG, CORE_PIN17_BIT);
  661. }
  662. inline void clr4() __attribute__((always_inline)) {
  663. CORE_PIN18_CONFIG = ((CORE_PIN18_PORTREG & CORE_PIN18_BITMASK)
  664. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  665. GPIO_CLRBIT_ATOMIC(CORE_PIN18_DDRREG, CORE_PIN18_BIT);
  666. }
  667. inline void clr5() __attribute__((always_inline)) {
  668. CORE_PIN19_CONFIG = ((CORE_PIN19_PORTREG & CORE_PIN19_BITMASK)
  669. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  670. GPIO_CLRBIT_ATOMIC(CORE_PIN19_DDRREG, CORE_PIN19_BIT);
  671. }
  672. };
  673. extern DDRCemulation DDRC;
  674. #define PINB0 0
  675. #define PINB1 1
  676. #define PINB2 2
  677. #define PINB3 3
  678. #define PINB4 4
  679. #define PINB5 5
  680. #define PINB6 6
  681. #define PINB7 7
  682. #define DDB0 0
  683. #define DDB1 1
  684. #define DDB2 2
  685. #define DDB3 3
  686. #define DDB4 4
  687. #define DDB5 5
  688. #define DDB6 6
  689. #define DDB7 7
  690. #define PORTB0 0
  691. #define PORTB1 1
  692. #define PORTB2 2
  693. #define PORTB3 3
  694. #define PORTB4 4
  695. #define PORTB5 5
  696. #define PORTB6 6
  697. #define PORTB7 7
  698. #define PINC0 0
  699. #define PINC1 1
  700. #define PINC2 2
  701. #define PINC3 3
  702. #define PINC4 4
  703. #define PINC5 5
  704. #define PINC6 6
  705. #define DDC0 0
  706. #define DDC1 1
  707. #define DDC2 2
  708. #define DDC3 3
  709. #define DDC4 4
  710. #define DDC5 5
  711. #define DDC6 6
  712. #define PORTC0 0
  713. #define PORTC1 1
  714. #define PORTC2 2
  715. #define PORTC3 3
  716. #define PORTC4 4
  717. #define PORTC5 5
  718. #define PORTC6 6
  719. #define PIND0 0
  720. #define PIND1 1
  721. #define PIND2 2
  722. #define PIND3 3
  723. #define PIND4 4
  724. #define PIND5 5
  725. #define PIND6 6
  726. #define PIND7 7
  727. #define DDD0 0
  728. #define DDD1 1
  729. #define DDD2 2
  730. #define DDD3 3
  731. #define DDD4 4
  732. #define DDD5 5
  733. #define DDD6 6
  734. #define DDD7 7
  735. #define PORTD0 0
  736. #define PORTD1 1
  737. #define PORTD2 2
  738. #define PORTD3 3
  739. #define PORTD4 4
  740. #define PORTD5 5
  741. #define PORTD6 6
  742. #define PORTD7 7
  743. #if 0
  744. extern "C" {
  745. void serial_print(const char *p);
  746. void serial_phex(uint32_t n);
  747. void serial_phex16(uint32_t n);
  748. void serial_phex32(uint32_t n);
  749. }
  750. #endif
  751. // SPI Control Register ­ SPCR
  752. #define SPIE 7 // SPI Interrupt Enable - not supported
  753. #define SPE 6 // SPI Enable
  754. #define DORD 5 // DORD: Data Order
  755. #define MSTR 4 // MSTR: Master/Slave Select
  756. #define CPOL 3 // CPOL: Clock Polarity
  757. #define CPHA 2 // CPHA: Clock Phase
  758. #define SPR1 1 // Clock: 3 = 125 kHz, 2 = 250 kHz, 1 = 1 MHz, 0->4 MHz
  759. #define SPR0 0
  760. // SPI Status Register ­ SPSR
  761. #define SPIF 7 // SPIF: SPI Interrupt Flag
  762. #define WCOL 6 // WCOL: Write COLlision Flag - not implemented
  763. #define SPI2X 0 // SPI2X: Double SPI Speed Bit
  764. // SPI Data Register ­ SPDR
  765. class SPCRemulation;
  766. class SPSRemulation;
  767. class SPDRemulation;
  768. #if defined(KINETISK)
  769. class SPCRemulation
  770. {
  771. public:
  772. inline SPCRemulation & operator = (int val) __attribute__((always_inline)) {
  773. uint32_t ctar, mcr, sim6;
  774. //serial_print("SPCR=");
  775. //serial_phex(val);
  776. //serial_print("\n");
  777. sim6 = SIM_SCGC6;
  778. if (!(sim6 & SIM_SCGC6_SPI0)) {
  779. //serial_print("init1\n");
  780. SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0;
  781. SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  782. }
  783. if (!(val & (1<<SPE))) {
  784. SPI0_MCR |= SPI_MCR_MDIS; // TODO: use bitband for atomic access
  785. }
  786. ctar = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1);
  787. if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE;
  788. if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL;
  789. if (val & (1<<CPHA)) {
  790. ctar |= SPI_CTAR_CPHA;
  791. if ((val & 3) == 0) {
  792. ctar |= SPI_CTAR_BR(1) | SPI_CTAR_ASC(1);
  793. } else if ((val & 3) == 1) {
  794. ctar |= SPI_CTAR_BR(4) | SPI_CTAR_ASC(4);
  795. } else if ((val & 3) == 2) {
  796. ctar |= SPI_CTAR_BR(6) | SPI_CTAR_ASC(6);
  797. } else {
  798. ctar |= SPI_CTAR_BR(7) | SPI_CTAR_ASC(7);
  799. }
  800. } else {
  801. if ((val & 3) == 0) {
  802. ctar |= SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  803. } else if ((val & 3) == 1) {
  804. ctar |= SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4);
  805. } else if ((val & 3) == 2) {
  806. ctar |= SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6);
  807. } else {
  808. ctar |= SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(7);
  809. }
  810. }
  811. ctar |= (SPI0_CTAR0 & SPI_CTAR_DBR);
  812. update_ctar(ctar);
  813. mcr = SPI_MCR_DCONF(0) | SPI_MCR_PCSIS(0x1F);
  814. if (val & (1<<MSTR)) mcr |= SPI_MCR_MSTR;
  815. if (val & (1<<SPE)) {
  816. mcr &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
  817. SPI0_MCR = mcr;
  818. enable_pins();
  819. } else {
  820. mcr |= (SPI_MCR_MDIS | SPI_MCR_HALT);
  821. SPI0_MCR = mcr;
  822. disable_pins();
  823. }
  824. //serial_print("MCR:");
  825. //serial_phex32(SPI0_MCR);
  826. //serial_print(", CTAR0:");
  827. //serial_phex32(SPI0_CTAR0);
  828. //serial_print("\n");
  829. return *this;
  830. }
  831. inline SPCRemulation & operator |= (int val) __attribute__((always_inline)) {
  832. uint32_t sim6;
  833. //serial_print("SPCR |= ");
  834. //serial_phex(val);
  835. //serial_print("\n");
  836. sim6 = SIM_SCGC6;
  837. if (!(sim6 & SIM_SCGC6_SPI0)) {
  838. //serial_print("init2\n");
  839. SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0;
  840. SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1);
  841. }
  842. if (val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) {
  843. uint32_t ctar = SPI0_CTAR0;
  844. if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE; // TODO: use bitband
  845. if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL;
  846. if (val & (1<<CPHA) && !(ctar & SPI_CTAR_CPHA)) {
  847. ctar |= SPI_CTAR_CPHA;
  848. ctar &= 0xFFFF00FF;
  849. ctar |= SPI_CTAR_ASC(ctar & 15);
  850. }
  851. if ((val & 3) != 0) {
  852. uint32_t br = ctar & 15;
  853. uint32_t priorval;
  854. if (br <= 1) priorval = 0;
  855. else if (br <= 4) priorval = 1;
  856. else if (br <= 6) priorval = 2;
  857. else priorval = 3;
  858. uint32_t newval = priorval | (val & 3);
  859. if (newval != priorval) {
  860. if (newval == 0) br = 1;
  861. else if (newval == 0) br = 4;
  862. else if (newval == 0) br = 6;
  863. else br = 7;
  864. ctar &= 0xFFFF00F0; // clear BR, ASC, CSSCK
  865. if ((ctar & SPI_CTAR_CPHA)) {
  866. ctar |= SPI_CTAR_BR(br) | SPI_CTAR_ASC(br);
  867. } else {
  868. ctar |= SPI_CTAR_BR(br) | SPI_CTAR_CSSCK(br);
  869. }
  870. }
  871. }
  872. update_ctar(ctar);
  873. }
  874. if (val & (1<<MSTR)) SPI0_MCR |= SPI_MCR_MSTR;
  875. if (val & (1<<SPE)) {
  876. SPI0_MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
  877. enable_pins();
  878. }
  879. //serial_print("MCR:");
  880. //serial_phex32(SPI0_MCR);
  881. //serial_print(", CTAR0:");
  882. //serial_phex32(SPI0_CTAR0);
  883. //serial_print("\n");
  884. return *this;
  885. }
  886. inline SPCRemulation & operator &= (int val) __attribute__((always_inline)) {
  887. //serial_print("SPCR &= ");
  888. //serial_phex(val);
  889. //serial_print("\n");
  890. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  891. if (!(val & (1<<SPE))) {
  892. SPI0_MCR |= (SPI_MCR_MDIS | SPI_MCR_HALT);
  893. disable_pins();
  894. }
  895. if ((val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) != ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) {
  896. uint32_t ctar = SPI0_CTAR0;
  897. if (!(val & (1<<DORD))) ctar &= ~SPI_CTAR_LSBFE; // TODO: use bitband
  898. if (!(val & (1<<CPOL))) ctar &= ~SPI_CTAR_CPOL;
  899. if (!(val & (1<<CPHA)) && (ctar & SPI_CTAR_CPHA)) {
  900. ctar &= ~SPI_CTAR_CPHA;
  901. ctar &= 0xFFFF00FF;
  902. ctar |= SPI_CTAR_CSSCK(ctar & 15);
  903. }
  904. if ((val & 3) != 3) {
  905. uint32_t br = ctar & 15;
  906. uint32_t priorval;
  907. if (br <= 1) priorval = 0;
  908. else if (br <= 4) priorval = 1;
  909. else if (br <= 6) priorval = 2;
  910. else priorval = 3;
  911. uint32_t newval = priorval & (val & 3);
  912. if (newval != priorval) {
  913. if (newval == 0) br = 1;
  914. else if (newval == 0) br = 4;
  915. else if (newval == 0) br = 6;
  916. else br = 7;
  917. ctar &= 0xFFFF00F0; // clear BR, ASC, CSSCK
  918. if ((ctar & SPI_CTAR_CPHA)) {
  919. ctar |= SPI_CTAR_BR(br) | SPI_CTAR_ASC(br);
  920. } else {
  921. ctar |= SPI_CTAR_BR(br) | SPI_CTAR_CSSCK(br);
  922. }
  923. }
  924. }
  925. update_ctar(ctar);
  926. }
  927. if (!(val & (1<<MSTR))) SPI0_MCR &= ~SPI_MCR_MSTR;
  928. return *this;
  929. }
  930. inline int operator & (int val) const __attribute__((always_inline)) {
  931. int ret = 0;
  932. //serial_print("SPCR & ");
  933. //serial_phex(val);
  934. //serial_print("\n");
  935. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  936. if ((val & (1<<DORD)) && (SPI0_CTAR0 & SPI_CTAR_LSBFE)) ret |= (1<<DORD);
  937. if ((val & (1<<CPOL)) && (SPI0_CTAR0 & SPI_CTAR_CPOL)) ret |= (1<<CPOL);
  938. if ((val & (1<<CPHA)) && (SPI0_CTAR0 & SPI_CTAR_CPHA)) ret |= (1<<CPHA);
  939. if ((val & 3) != 0) {
  940. uint32_t dbr = SPI0_CTAR0 & 15;
  941. uint32_t spr10;
  942. if (dbr <= 1) {
  943. spr10 = 0;
  944. } else if (dbr <= 4) {
  945. spr10 |= (1<<SPR0);
  946. } else if (dbr <= 6) {
  947. spr10 |= (1<<SPR1);
  948. } else {
  949. spr10 |= (1<<SPR1)|(1<<SPR0);
  950. }
  951. ret |= spr10 & (val & 3);
  952. }
  953. if (val & (1<<SPE) && (!(SPI0_MCR & SPI_MCR_MDIS))) ret |= (1<<SPE);
  954. if (val & (1<<MSTR) && (SPI0_MCR & SPI_MCR_MSTR)) ret |= (1<<MSTR);
  955. //serial_print("ret = ");
  956. //serial_phex(ret);
  957. //serial_print("\n");
  958. return ret;
  959. }
  960. operator int () const __attribute__((always_inline)) {
  961. int ret = 0;
  962. if ((SIM_SCGC6 & SIM_SCGC6_SPI0)) {
  963. int ctar = SPI0_CTAR0;
  964. if (ctar & SPI_CTAR_LSBFE) ret |= (1<<DORD);
  965. if (ctar & SPI_CTAR_CPOL) ret |= (1<<CPOL);
  966. if (ctar & SPI_CTAR_CPHA) ret |= (1<<CPHA);
  967. ctar &= 15;
  968. if (ctar <= 1) {
  969. } else if (ctar <= 4) {
  970. ret |= (1<<SPR0);
  971. } else if (ctar <= 6) {
  972. ret |= (1<<SPR1);
  973. } else {
  974. ret |= (1<<SPR1)|(1<<SPR0);
  975. }
  976. int mcr = SPI0_MCR;
  977. if (!(mcr & SPI_MCR_MDIS)) ret |= (1<<SPE);
  978. if (mcr & SPI_MCR_MSTR) ret |= (1<<MSTR);
  979. }
  980. return ret;
  981. }
  982. inline void setMOSI(uint8_t pin) __attribute__((always_inline)) {
  983. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  984. uint8_t newpinout = pinout;
  985. // More than two options so now 2 bits
  986. if (pin == 11) newpinout &= ~3;
  987. if (pin == 7) newpinout =(newpinout & ~0x3) | 1;
  988. if (pin == 28) newpinout = (newpinout & ~0x3) | 2;
  989. if ((SIM_SCGC6 & SIM_SCGC6_SPI0) && newpinout != pinout) {
  990. // First unconfigure previous pin
  991. switch (pinout & 3) {
  992. case 0: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  993. case 1: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  994. default: CORE_PIN28_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  995. }
  996. switch (newpinout & 3) {
  997. case 0: CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break;
  998. case 1: CORE_PIN7_CONFIG = PORT_PCR_MUX(2); break;
  999. default: CORE_PIN28_CONFIG = PORT_PCR_MUX(2);
  1000. }
  1001. }
  1002. pinout = newpinout;
  1003. #else
  1004. uint8_t newpinout = pinout;
  1005. if (pin == 11) newpinout &= ~1;
  1006. if (pin == 7) newpinout |= 1;
  1007. if ((SIM_SCGC6 & SIM_SCGC6_SPI0) && newpinout != pinout) {
  1008. if ((newpinout & 1) == 0) {
  1009. CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1010. CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  1011. } else {
  1012. CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1013. CORE_PIN7_CONFIG = PORT_PCR_MUX(2);
  1014. }
  1015. }
  1016. pinout = newpinout;
  1017. #endif
  1018. }
  1019. inline void setMOSI_soft(uint8_t pin) __attribute__((always_inline)) {
  1020. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  1021. if (pin == 11) pinout &= ~3;
  1022. if (pin == 7) pinout = (pinout & ~0x3) | 1;
  1023. if (pin == 28) pinout = (pinout & ~0x3) | 2;
  1024. #else
  1025. if (pin == 11) pinout &= ~1;
  1026. if (pin == 7) pinout |= 1;
  1027. #endif
  1028. }
  1029. inline void setMISO(uint8_t pin) __attribute__((always_inline)) {
  1030. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  1031. uint8_t newpinout = pinout;
  1032. // More than two options so now 2 bits
  1033. if (pin == 12) newpinout &= ~0xc;
  1034. if (pin == 8) newpinout =(newpinout & ~0xc) | 4;
  1035. if (pin == 39) newpinout = (newpinout & ~0xc) | 8;
  1036. if ((SIM_SCGC6 & SIM_SCGC6_SPI0) && newpinout != pinout) {
  1037. // First unconfigure previous pin
  1038. switch (pinout & 0xc) {
  1039. case 0: CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1040. case 0x4: CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1041. default: CORE_PIN39_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1042. }
  1043. switch (newpinout & 0xc) {
  1044. case 0: CORE_PIN12_CONFIG = PORT_PCR_MUX(2); break;
  1045. case 0x4: CORE_PIN8_CONFIG = PORT_PCR_MUX(2); break;
  1046. default: CORE_PIN39_CONFIG = PORT_PCR_MUX(2);
  1047. }
  1048. }
  1049. pinout = newpinout;
  1050. #else
  1051. uint8_t newpinout = pinout;
  1052. if (pin == 12) newpinout &= ~2;
  1053. if (pin == 8) newpinout |= 2;
  1054. if ((SIM_SCGC6 & SIM_SCGC6_SPI0) && newpinout != pinout) {
  1055. if ((newpinout & 2) == 0) {
  1056. CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1057. CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
  1058. } else {
  1059. CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1060. CORE_PIN8_CONFIG = PORT_PCR_MUX(2);
  1061. }
  1062. }
  1063. pinout = newpinout;
  1064. #endif
  1065. }
  1066. inline void setMISO_soft(uint8_t pin) __attribute__((always_inline)) {
  1067. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  1068. if (pin == 12) pinout &= ~0xc;
  1069. if (pin == 8) pinout = (pinout & ~0xc) | 4;
  1070. if (pin == 39) pinout = (pinout & ~0xc) | 8;
  1071. #else
  1072. if (pin == 12) pinout &= ~2;
  1073. if (pin == 8) pinout |= 2;
  1074. #endif
  1075. }
  1076. inline void setSCK(uint8_t pin) __attribute__((always_inline)) {
  1077. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  1078. uint8_t newpinout = pinout;
  1079. // More than two options so now 2 bits
  1080. if (pin == 13) newpinout &= ~0x30;
  1081. if (pin == 14) newpinout =(newpinout & ~0x30) | 0x10;
  1082. if (pin == 27) newpinout = (newpinout & ~0x30) | 0x20;
  1083. if ((SIM_SCGC6 & SIM_SCGC6_SPI0) && newpinout != pinout) {
  1084. // First unconfigure previous pin
  1085. switch (pinout & 0x30) {
  1086. case 0: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1087. case 0x10: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1088. default: CORE_PIN27_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1089. }
  1090. switch (newpinout & 0x30) {
  1091. case 0: CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break;
  1092. case 0x10: CORE_PIN14_CONFIG = PORT_PCR_MUX(2); break;
  1093. default: CORE_PIN27_CONFIG = PORT_PCR_MUX(2);
  1094. }
  1095. }
  1096. pinout = newpinout;
  1097. #else
  1098. uint8_t newpinout = pinout;
  1099. if (pin == 13) newpinout &= ~4;
  1100. if (pin == 14) newpinout |= 4;
  1101. if ((SIM_SCGC6 & SIM_SCGC6_SPI0) && newpinout != pinout) {
  1102. if ((newpinout & 4) == 0) {
  1103. CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1104. CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  1105. } else {
  1106. CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1107. CORE_PIN14_CONFIG = PORT_PCR_MUX(2);
  1108. }
  1109. }
  1110. pinout = newpinout;
  1111. #endif
  1112. }
  1113. inline void setSCK_soft(uint8_t pin) __attribute__((always_inline)) {
  1114. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  1115. if (pin == 13) pinout &= ~0x30;
  1116. if (pin == 14) pinout = (pinout & ~0x30) | 0x10;
  1117. if (pin == 27) pinout = (pinout & ~0x30) | 0x20;
  1118. #else
  1119. if (pin == 13) pinout &= ~4;
  1120. if (pin == 14) pinout |= 4;
  1121. #endif
  1122. }
  1123. friend class SPSRemulation;
  1124. friend class SPIFIFOclass;
  1125. private:
  1126. static inline void update_ctar(uint32_t ctar) __attribute__((always_inline)) {
  1127. if (SPI0_CTAR0 == ctar) return;
  1128. uint32_t mcr = SPI0_MCR;
  1129. if (mcr & SPI_MCR_MDIS) {
  1130. SPI0_CTAR0 = ctar;
  1131. } else {
  1132. SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
  1133. SPI0_CTAR0 = ctar;
  1134. SPI0_MCR = mcr;
  1135. }
  1136. }
  1137. static uint8_t pinout;
  1138. public:
  1139. inline void enable_pins(void) __attribute__((always_inline)) {
  1140. //serial_print("enable_pins\n");
  1141. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  1142. switch (pinout & 3) {
  1143. case 0: CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break;
  1144. case 1: CORE_PIN7_CONFIG = PORT_PCR_MUX(2); break;
  1145. default: CORE_PIN28_CONFIG = PORT_PCR_MUX(2);
  1146. }
  1147. switch (pinout & 0xc) {
  1148. case 0: CORE_PIN12_CONFIG = PORT_PCR_MUX(2); break;
  1149. case 0x4: CORE_PIN8_CONFIG = PORT_PCR_MUX(2); break;
  1150. default: CORE_PIN39_CONFIG = PORT_PCR_MUX(2);
  1151. }
  1152. switch (pinout & 0x30) {
  1153. case 0: CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); break;
  1154. case 0x10: CORE_PIN14_CONFIG = PORT_PCR_MUX(2); break;
  1155. default: CORE_PIN27_CONFIG = PORT_PCR_MUX(2);
  1156. }
  1157. #else
  1158. if ((pinout & 1) == 0) {
  1159. CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); // DOUT/MOSI = 11 (PTC6)
  1160. } else {
  1161. CORE_PIN7_CONFIG = PORT_PCR_MUX(2); // DOUT/MOSI = 7 (PTD2)
  1162. }
  1163. if ((pinout & 2) == 0) {
  1164. CORE_PIN12_CONFIG = PORT_PCR_MUX(2); // DIN/MISO = 12 (PTC7)
  1165. } else {
  1166. CORE_PIN8_CONFIG = PORT_PCR_MUX(2); // DIN/MISO = 8 (PTD3)
  1167. }
  1168. if ((pinout & 4) == 0) {
  1169. CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); // SCK = 13 (PTC5)
  1170. } else {
  1171. CORE_PIN14_CONFIG = PORT_PCR_MUX(2); // SCK = 14 (PTD1)
  1172. }
  1173. #endif
  1174. }
  1175. inline void disable_pins(void) __attribute__((always_inline)) {
  1176. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  1177. switch (pinout & 3) {
  1178. case 0: CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1179. case 1: CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1180. default: CORE_PIN28_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1181. }
  1182. switch (pinout & 0xc) {
  1183. case 0: CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1184. case 0x4: CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1185. default: CORE_PIN39_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1186. }
  1187. switch (pinout & 0x30) {
  1188. case 0: CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1189. case 0x10: CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); break;
  1190. default: CORE_PIN27_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1191. }
  1192. #else
  1193. //serial_print("disable_pins\n");
  1194. if ((pinout & 1) == 0) {
  1195. CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1196. } else {
  1197. CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1198. }
  1199. if ((pinout & 2) == 0) {
  1200. CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1201. } else {
  1202. CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1203. }
  1204. if ((pinout & 4) == 0) {
  1205. CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1206. } else {
  1207. CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1208. }
  1209. #endif
  1210. }
  1211. };
  1212. extern SPCRemulation SPCR;
  1213. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  1214. class SPCR1emulation
  1215. {
  1216. public:
  1217. inline SPCR1emulation & operator = (int val) __attribute__((always_inline)) {
  1218. uint32_t ctar, mcr, sim6;
  1219. //serial_print("SPCR=");
  1220. //serial_phex(val);
  1221. //serial_print("\n");
  1222. sim6 = SIM_SCGC6;
  1223. if (!(sim6 & SIM_SCGC6_SPI1)) {
  1224. //serial_print("init1\n");
  1225. SIM_SCGC6 = sim6 | SIM_SCGC6_SPI1;
  1226. SPI1_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  1227. }
  1228. if (!(val & (1<<SPE))) {
  1229. SPI1_MCR |= SPI_MCR_MDIS; // TODO: use bitband for atomic access
  1230. }
  1231. ctar = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1);
  1232. if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE;
  1233. if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL;
  1234. if (val & (1<<CPHA)) {
  1235. ctar |= SPI_CTAR_CPHA;
  1236. if ((val & 3) == 0) {
  1237. ctar |= SPI_CTAR_BR(1) | SPI_CTAR_ASC(1);
  1238. } else if ((val & 3) == 1) {
  1239. ctar |= SPI_CTAR_BR(4) | SPI_CTAR_ASC(4);
  1240. } else if ((val & 3) == 2) {
  1241. ctar |= SPI_CTAR_BR(6) | SPI_CTAR_ASC(6);
  1242. } else {
  1243. ctar |= SPI_CTAR_BR(7) | SPI_CTAR_ASC(7);
  1244. }
  1245. } else {
  1246. if ((val & 3) == 0) {
  1247. ctar |= SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  1248. } else if ((val & 3) == 1) {
  1249. ctar |= SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4);
  1250. } else if ((val & 3) == 2) {
  1251. ctar |= SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6);
  1252. } else {
  1253. ctar |= SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(7);
  1254. }
  1255. }
  1256. ctar |= (SPI1_CTAR0 & SPI_CTAR_DBR);
  1257. update_ctar(ctar);
  1258. mcr = SPI_MCR_DCONF(0) | SPI_MCR_PCSIS(0x1F);
  1259. if (val & (1<<MSTR)) mcr |= SPI_MCR_MSTR;
  1260. if (val & (1<<SPE)) {
  1261. mcr &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
  1262. SPI1_MCR = mcr;
  1263. enable_pins();
  1264. } else {
  1265. mcr |= (SPI_MCR_MDIS | SPI_MCR_HALT);
  1266. SPI1_MCR = mcr;
  1267. disable_pins();
  1268. }
  1269. //serial_print("MCR:");
  1270. //serial_phex32(SPI1_MCR);
  1271. //serial_print(", CTAR0:");
  1272. //serial_phex32(SPI1_CTAR0);
  1273. //serial_print("\n");
  1274. return *this;
  1275. }
  1276. inline SPCR1emulation & operator |= (int val) __attribute__((always_inline)) {
  1277. uint32_t sim6;
  1278. //serial_print("SPCR |= ");
  1279. //serial_phex(val);
  1280. //serial_print("\n");
  1281. sim6 = SIM_SCGC6;
  1282. if (!(sim6 & SIM_SCGC6_SPI1)) {
  1283. //serial_print("init2\n");
  1284. SIM_SCGC6 = sim6 | SIM_SCGC6_SPI1;
  1285. SPI1_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1);
  1286. }
  1287. if (val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) {
  1288. uint32_t ctar = SPI1_CTAR0;
  1289. if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE; // TODO: use bitband
  1290. if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL;
  1291. if ((val & 3) == 1) {
  1292. // TODO: implement - is this ever really needed
  1293. } else if ((val & 3) == 2) {
  1294. // TODO: implement - is this ever really needed
  1295. } else if ((val & 3) == 3) {
  1296. // TODO: implement - is this ever really needed
  1297. }
  1298. if (val & (1<<CPHA) && !(ctar & SPI_CTAR_CPHA)) {
  1299. ctar |= SPI_CTAR_CPHA;
  1300. // TODO: clear SPI_CTAR_CSSCK, set SPI_CTAR_ASC
  1301. }
  1302. update_ctar(ctar);
  1303. }
  1304. if (val & (1<<MSTR)) SPI1_MCR |= SPI_MCR_MSTR;
  1305. if (val & (1<<SPE)) {
  1306. SPI1_MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
  1307. enable_pins();
  1308. }
  1309. //serial_print("MCR:");
  1310. //serial_phex32(SPI1_MCR);
  1311. //serial_print(", CTAR0:");
  1312. //serial_phex32(SPI1_CTAR0);
  1313. //serial_print("\n");
  1314. return *this;
  1315. }
  1316. inline SPCR1emulation & operator &= (int val) __attribute__((always_inline)) {
  1317. //serial_print("SPCR &= ");
  1318. //serial_phex(val);
  1319. //serial_print("\n");
  1320. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  1321. if (!(val & (1<<SPE))) {
  1322. SPI1_MCR |= (SPI_MCR_MDIS | SPI_MCR_HALT);
  1323. disable_pins();
  1324. }
  1325. if ((val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) != ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) {
  1326. uint32_t ctar = SPI1_CTAR0;
  1327. if (!(val & (1<<DORD))) ctar &= ~SPI_CTAR_LSBFE; // TODO: use bitband
  1328. if (!(val & (1<<CPOL))) ctar &= ~SPI_CTAR_CPOL;
  1329. if ((val & 3) == 0) {
  1330. // TODO: implement - is this ever really needed
  1331. } else if ((val & 3) == 1) {
  1332. // TODO: implement - is this ever really needed
  1333. } else if ((val & 3) == 2) {
  1334. // TODO: implement - is this ever really needed
  1335. }
  1336. if (!(val & (1<<CPHA)) && (ctar & SPI_CTAR_CPHA)) {
  1337. ctar &= ~SPI_CTAR_CPHA;
  1338. // TODO: set SPI_CTAR_ASC, clear SPI_CTAR_CSSCK
  1339. }
  1340. update_ctar(ctar);
  1341. }
  1342. if (!(val & (1<<MSTR))) SPI1_MCR &= ~SPI_MCR_MSTR;
  1343. return *this;
  1344. }
  1345. inline int operator & (int val) const __attribute__((always_inline)) {
  1346. int ret = 0;
  1347. //serial_print("SPCR & ");
  1348. //serial_phex(val);
  1349. //serial_print(" MCR:");
  1350. //serial_phex32(SPI1_MCR);
  1351. //serial_print(", CTAR0:");
  1352. //serial_phex32(SPI1_CTAR0);
  1353. //serial_print("\n");
  1354. //serial_print("\n");
  1355. SIM_SCGC6 |= SIM_SCGC6_SPI1;
  1356. if ((val & (1<<DORD)) && (SPI1_CTAR0 & SPI_CTAR_LSBFE)) ret |= (1<<DORD);
  1357. if ((val & (1<<CPOL)) && (SPI1_CTAR0 & SPI_CTAR_CPOL)) ret |= (1<<CPOL);
  1358. if ((val & (1<<CPHA)) && (SPI1_CTAR0 & SPI_CTAR_CPHA)) ret |= (1<<CPHA);
  1359. if ((val & 3) == 3) {
  1360. uint32_t dbr = SPI1_CTAR0 & 15;
  1361. if (dbr <= 1) {
  1362. } else if (dbr <= 4) {
  1363. ret |= (1<<SPR0);
  1364. } else if (dbr <= 6) {
  1365. ret |= (1<<SPR1);
  1366. } else {
  1367. ret |= (1<<SPR1)|(1<<SPR0);
  1368. }
  1369. } else if ((val & 3) == 1) {
  1370. // TODO: implement - is this ever really needed
  1371. } else if ((val & 3) == 2) {
  1372. // TODO: implement - is this ever really needed
  1373. }
  1374. if (val & (1<<SPE) && (!(SPI1_MCR & SPI_MCR_MDIS))) ret |= (1<<SPE);
  1375. if (val & (1<<MSTR) && (SPI1_MCR & SPI_MCR_MSTR)) ret |= (1<<MSTR);
  1376. //serial_print("ret = ");
  1377. //serial_phex(ret);
  1378. //serial_print("\n");
  1379. return ret;
  1380. }
  1381. inline void setMOSI(uint8_t pin) __attribute__((always_inline)) {
  1382. // More options, so 2 bits
  1383. pinout &= ~3;
  1384. switch (pin) {
  1385. case 0: break;
  1386. case 21: pinout |= 1; break;
  1387. case 61: pinout |= 2; break;
  1388. case 59: pinout |= 3; break;
  1389. }
  1390. }
  1391. inline void setMISO(uint8_t pin) __attribute__((always_inline)) {
  1392. // More options, so 2 bits
  1393. pinout &= ~0xc;
  1394. switch (pin) {
  1395. case 1: break;
  1396. case 5: pinout |= 0x4; break;
  1397. case 61: pinout |= 0x8; break;
  1398. case 59: pinout |= 0xc; break;
  1399. }
  1400. }
  1401. inline void setSCK(uint8_t pin) __attribute__((always_inline)) {
  1402. // More options, so 2 bits
  1403. pinout &= ~0x30;
  1404. switch (pin) {
  1405. case 32: break;
  1406. case 20: pinout |= 0x10; break;
  1407. case 60: pinout |= 0x20; break;
  1408. }
  1409. }
  1410. inline void enable_pins(void) __attribute__((always_inline)) {
  1411. //serial_print("enable_pins\n");
  1412. // MOSI (SOUT)
  1413. switch (pinout & 0x3) {
  1414. case 0: CORE_PIN0_CONFIG = PORT_PCR_MUX(2); break;
  1415. case 1: CORE_PIN21_CONFIG = PORT_PCR_MUX(7); break;
  1416. case 2: CORE_PIN61_CONFIG = PORT_PCR_MUX(7); break;
  1417. case 3: CORE_PIN59_CONFIG = PORT_PCR_MUX(2); break;
  1418. }
  1419. // MISO (SIN)
  1420. switch (pinout & 0xc) {
  1421. case 0x0: CORE_PIN1_CONFIG = PORT_PCR_MUX(2); break;
  1422. case 0x4: CORE_PIN5_CONFIG = PORT_PCR_MUX(7); break;
  1423. case 0x8: CORE_PIN61_CONFIG = PORT_PCR_MUX(2); break;
  1424. case 0xc: CORE_PIN59_CONFIG = PORT_PCR_MUX(7); break;
  1425. }
  1426. // SCK
  1427. switch (pinout & 0x30) {
  1428. case 0x0: CORE_PIN32_CONFIG = PORT_PCR_MUX(2); break;
  1429. case 0x10: CORE_PIN20_CONFIG = PORT_PCR_MUX(7); break;
  1430. case 0x20: CORE_PIN60_CONFIG = PORT_PCR_MUX(2); break;
  1431. }
  1432. }
  1433. inline void disable_pins(void) __attribute__((always_inline)) {
  1434. switch (pinout & 0x3) {
  1435. case 0: CORE_PIN0_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1436. case 1: CORE_PIN21_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1437. case 2: CORE_PIN61_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1438. case 3: CORE_PIN59_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1439. }
  1440. switch (pinout & 0xc) {
  1441. case 0x0: CORE_PIN1_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1442. case 0x4: CORE_PIN5_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1443. case 0x8: CORE_PIN61_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1444. case 0xc: CORE_PIN59_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1445. }
  1446. switch (pinout & 0x30) {
  1447. case 0x0: CORE_PIN32_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1448. case 0x10: CORE_PIN20_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1449. case 0x20: CORE_PIN60_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1); break;
  1450. }
  1451. }
  1452. friend class SPIFIFO1class;
  1453. private:
  1454. static uint8_t pinout;
  1455. static inline void update_ctar(uint32_t ctar) __attribute__((always_inline)) {
  1456. if (SPI1_CTAR0 == ctar) return;
  1457. uint32_t mcr = SPI1_MCR;
  1458. if (mcr & SPI_MCR_MDIS) {
  1459. SPI1_CTAR0 = ctar;
  1460. } else {
  1461. SPI1_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
  1462. SPI1_CTAR0 = ctar;
  1463. SPI1_MCR = mcr;
  1464. }
  1465. }
  1466. };
  1467. extern SPCR1emulation SPCR1;
  1468. ////////////////////
  1469. // SPI2
  1470. class SPCR2emulation
  1471. {
  1472. public:
  1473. inline SPCR2emulation & operator = (int val) __attribute__((always_inline)) {
  1474. uint32_t ctar, mcr, sim3;
  1475. //serial_print("SPCR=");
  1476. //serial_phex(val);
  1477. //serial_print("\n");
  1478. sim3 = SIM_SCGC3;
  1479. if (!(sim3 & SIM_SCGC3_SPI2)) {
  1480. //serial_print("init1\n");
  1481. SIM_SCGC3 = sim3 | SIM_SCGC3_SPI2;
  1482. SPI2_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  1483. }
  1484. if (!(val & (1<<SPE))) {
  1485. SPI2_MCR |= SPI_MCR_MDIS; // TODO: use bitband for atomic access
  1486. }
  1487. ctar = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1);
  1488. if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE;
  1489. if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL;
  1490. if (val & (1<<CPHA)) {
  1491. ctar |= SPI_CTAR_CPHA;
  1492. if ((val & 3) == 0) {
  1493. ctar |= SPI_CTAR_BR(1) | SPI_CTAR_ASC(1);
  1494. } else if ((val & 3) == 1) {
  1495. ctar |= SPI_CTAR_BR(4) | SPI_CTAR_ASC(4);
  1496. } else if ((val & 3) == 2) {
  1497. ctar |= SPI_CTAR_BR(6) | SPI_CTAR_ASC(6);
  1498. } else {
  1499. ctar |= SPI_CTAR_BR(7) | SPI_CTAR_ASC(7);
  1500. }
  1501. } else {
  1502. if ((val & 3) == 0) {
  1503. ctar |= SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  1504. } else if ((val & 3) == 1) {
  1505. ctar |= SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4);
  1506. } else if ((val & 3) == 2) {
  1507. ctar |= SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6);
  1508. } else {
  1509. ctar |= SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(7);
  1510. }
  1511. }
  1512. ctar |= (SPI2_CTAR0 & SPI_CTAR_DBR);
  1513. update_ctar(ctar);
  1514. mcr = SPI_MCR_DCONF(0) | SPI_MCR_PCSIS(0x1F);
  1515. if (val & (1<<MSTR)) mcr |= SPI_MCR_MSTR;
  1516. if (val & (1<<SPE)) {
  1517. mcr &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
  1518. SPI2_MCR = mcr;
  1519. enable_pins();
  1520. } else {
  1521. mcr |= (SPI_MCR_MDIS | SPI_MCR_HALT);
  1522. SPI2_MCR = mcr;
  1523. disable_pins();
  1524. }
  1525. //serial_print("MCR:");
  1526. //serial_phex32(SPI2_MCR);
  1527. //serial_print(", CTAR0:");
  1528. //serial_phex32(SPI2_CTAR0);
  1529. //serial_print("\n");
  1530. return *this;
  1531. }
  1532. inline SPCR2emulation & operator |= (int val) __attribute__((always_inline)) {
  1533. uint32_t sim3;
  1534. //serial_print("SPCR |= ");
  1535. //serial_phex(val);
  1536. //serial_print("\n");
  1537. sim3 = SIM_SCGC3;
  1538. if (!(sim3 & SIM_SCGC3_SPI2)) {
  1539. //serial_print("init2\n");
  1540. SIM_SCGC6 = sim3 | SIM_SCGC3_SPI2;
  1541. SPI2_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1);
  1542. }
  1543. if (val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) {
  1544. uint32_t ctar = SPI2_CTAR0;
  1545. if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE; // TODO: use bitband
  1546. if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL;
  1547. if ((val & 3) == 1) {
  1548. // TODO: implement - is this ever really needed
  1549. } else if ((val & 3) == 2) {
  1550. // TODO: implement - is this ever really needed
  1551. } else if ((val & 3) == 3) {
  1552. // TODO: implement - is this ever really needed
  1553. }
  1554. if (val & (1<<CPHA) && !(ctar & SPI_CTAR_CPHA)) {
  1555. ctar |= SPI_CTAR_CPHA;
  1556. // TODO: clear SPI_CTAR_CSSCK, set SPI_CTAR_ASC
  1557. }
  1558. update_ctar(ctar);
  1559. }
  1560. if (val & (1<<MSTR)) SPI2_MCR |= SPI_MCR_MSTR;
  1561. if (val & (1<<SPE)) {
  1562. SPI2_MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
  1563. enable_pins();
  1564. }
  1565. //serial_print("MCR:");
  1566. //serial_phex32(SPI2_MCR);
  1567. //serial_print(", CTAR0:");
  1568. //serial_phex32(SPI2_CTAR0);
  1569. //serial_print("\n");
  1570. return *this;
  1571. }
  1572. inline SPCR2emulation & operator &= (int val) __attribute__((always_inline)) {
  1573. //serial_print("SPCR &= ");
  1574. //serial_phex(val);
  1575. //serial_print("\n");
  1576. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  1577. if (!(val & (1<<SPE))) {
  1578. SPI2_MCR |= (SPI_MCR_MDIS | SPI_MCR_HALT);
  1579. disable_pins();
  1580. }
  1581. if ((val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) != ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) {
  1582. uint32_t ctar = SPI2_CTAR0;
  1583. if (!(val & (1<<DORD))) ctar &= ~SPI_CTAR_LSBFE; // TODO: use bitband
  1584. if (!(val & (1<<CPOL))) ctar &= ~SPI_CTAR_CPOL;
  1585. if ((val & 3) == 0) {
  1586. // TODO: implement - is this ever really needed
  1587. } else if ((val & 3) == 1) {
  1588. // TODO: implement - is this ever really needed
  1589. } else if ((val & 3) == 2) {
  1590. // TODO: implement - is this ever really needed
  1591. }
  1592. if (!(val & (1<<CPHA)) && (ctar & SPI_CTAR_CPHA)) {
  1593. ctar &= ~SPI_CTAR_CPHA;
  1594. // TODO: set SPI_CTAR_ASC, clear SPI_CTAR_CSSCK
  1595. }
  1596. update_ctar(ctar);
  1597. }
  1598. if (!(val & (1<<MSTR))) SPI2_MCR &= ~SPI_MCR_MSTR;
  1599. return *this;
  1600. }
  1601. inline int operator & (int val) const __attribute__((always_inline)) {
  1602. int ret = 0;
  1603. //serial_print("SPCR & ");
  1604. //serial_phex(val);
  1605. //serial_print(" MCR:");
  1606. //serial_phex32(SPI2_MCR);
  1607. //serial_print(", CTAR0:");
  1608. //serial_phex32(SPI2_CTAR0);
  1609. //serial_print("\n");
  1610. //serial_print("\n");
  1611. SIM_SCGC3 |= SIM_SCGC3_SPI2;
  1612. if ((val & (1<<DORD)) && (SPI2_CTAR0 & SPI_CTAR_LSBFE)) ret |= (1<<DORD);
  1613. if ((val & (1<<CPOL)) && (SPI2_CTAR0 & SPI_CTAR_CPOL)) ret |= (1<<CPOL);
  1614. if ((val & (1<<CPHA)) && (SPI2_CTAR0 & SPI_CTAR_CPHA)) ret |= (1<<CPHA);
  1615. if ((val & 3) == 3) {
  1616. uint32_t dbr = SPI2_CTAR0 & 15;
  1617. if (dbr <= 1) {
  1618. } else if (dbr <= 4) {
  1619. ret |= (1<<SPR0);
  1620. } else if (dbr <= 6) {
  1621. ret |= (1<<SPR1);
  1622. } else {
  1623. ret |= (1<<SPR1)|(1<<SPR0);
  1624. }
  1625. } else if ((val & 3) == 1) {
  1626. // TODO: implement - is this ever really needed
  1627. } else if ((val & 3) == 2) {
  1628. // TODO: implement - is this ever really needed
  1629. }
  1630. if (val & (1<<SPE) && (!(SPI2_MCR & SPI_MCR_MDIS))) ret |= (1<<SPE);
  1631. if (val & (1<<MSTR) && (SPI2_MCR & SPI_MCR_MSTR)) ret |= (1<<MSTR);
  1632. //serial_print("ret = ");
  1633. //serial_phex(ret);
  1634. //serial_print("\n");
  1635. return ret;
  1636. }
  1637. inline void setMOSI(uint8_t pin) __attribute__((always_inline)) {
  1638. if (pin == 44) pinout &= ~1;
  1639. if (pin == 52) pinout |= 1;
  1640. }
  1641. inline void setMISO(uint8_t pin) __attribute__((always_inline)) {
  1642. if (pin == 45) pinout &= ~2;
  1643. if (pin == 51) pinout |= 2;
  1644. }
  1645. inline void setSCK(uint8_t pin) __attribute__((always_inline)) {
  1646. if (pin == 46) pinout &= ~4;
  1647. if (pin == 53) pinout |= 4;
  1648. }
  1649. inline void enable_pins(void) __attribute__((always_inline)) {
  1650. //serial_print("enable_pins\n");
  1651. if ((pinout & 1) == 0) {
  1652. CORE_PIN44_CONFIG = PORT_PCR_MUX(2);
  1653. } else {
  1654. CORE_PIN52_CONFIG = PORT_PCR_MUX(2);
  1655. }
  1656. if ((pinout & 2) == 0) {
  1657. CORE_PIN45_CONFIG = PORT_PCR_MUX(2);
  1658. } else {
  1659. CORE_PIN51_CONFIG = PORT_PCR_MUX(2);
  1660. }
  1661. if ((pinout & 4) == 0) {
  1662. CORE_PIN46_CONFIG = PORT_PCR_MUX(2);
  1663. } else {
  1664. CORE_PIN53_CONFIG = PORT_PCR_MUX(2);
  1665. }
  1666. }
  1667. inline void disable_pins(void) __attribute__((always_inline)) {
  1668. //serial_print("disable_pins\n");
  1669. if ((pinout & 1) == 0) {
  1670. CORE_PIN44_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  1671. } else {
  1672. CORE_PIN52_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  1673. }
  1674. if ((pinout & 2) == 0) {
  1675. CORE_PIN45_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  1676. } else {
  1677. CORE_PIN51_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  1678. }
  1679. if ((pinout & 4) == 0) {
  1680. CORE_PIN46_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  1681. } else {
  1682. CORE_PIN53_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  1683. }
  1684. }
  1685. friend class SPIFIFO1class;
  1686. private:
  1687. static uint8_t pinout;
  1688. static inline void update_ctar(uint32_t ctar) __attribute__((always_inline)) {
  1689. if (SPI2_CTAR0 == ctar) return;
  1690. uint32_t mcr = SPI2_MCR;
  1691. if (mcr & SPI_MCR_MDIS) {
  1692. SPI2_CTAR0 = ctar;
  1693. } else {
  1694. SPI2_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT;
  1695. SPI2_CTAR0 = ctar;
  1696. SPI2_MCR = mcr;
  1697. }
  1698. }
  1699. };
  1700. extern SPCR2emulation SPCR2;
  1701. #endif
  1702. class SPSRemulation
  1703. {
  1704. public:
  1705. inline SPSRemulation & operator = (int val) __attribute__((always_inline)) {
  1706. //serial_print("SPSR=");
  1707. //serial_phex(val);
  1708. //serial_print("\n");
  1709. uint32_t ctar = SPI0_CTAR0;
  1710. if (val & (1<<SPI2X)) {
  1711. ctar |= SPI_CTAR_DBR;
  1712. } else {
  1713. ctar &= ~SPI_CTAR_DBR;
  1714. }
  1715. SPCRemulation::update_ctar(ctar);
  1716. //serial_print("MCR:");
  1717. //serial_phex32(SPI0_MCR);
  1718. //serial_print(", CTAR0:");
  1719. //serial_phex32(SPI0_CTAR0);
  1720. //serial_print("\n");
  1721. return *this;
  1722. }
  1723. inline SPSRemulation & operator |= (int val) __attribute__((always_inline)) {
  1724. //serial_print("SPSR |= ");
  1725. //serial_phex(val);
  1726. //serial_print("\n");
  1727. if (val & (1<<SPI2X)) SPCRemulation::update_ctar(SPI0_CTAR0 |= SPI_CTAR_DBR);
  1728. return *this;
  1729. }
  1730. inline SPSRemulation & operator &= (int val) __attribute__((always_inline)) {
  1731. //serial_print("SPSR &= ");
  1732. //serial_phex(val);
  1733. //serial_print("\n");
  1734. if (!(val & (1<<SPI2X))) SPCRemulation::update_ctar(SPI0_CTAR0 &= ~SPI_CTAR_DBR);
  1735. return *this;
  1736. }
  1737. inline int operator & (int val) const __attribute__((always_inline)) {
  1738. int ret = 0;
  1739. //serial_print("SPSR & ");
  1740. //serial_phex(val);
  1741. //serial_print("\n");
  1742. // TODO: using SPI_SR_TCF isn't quite right. Control returns to the
  1743. // caller after the final edge that captures data, which is 1/2 cycle
  1744. // sooner than AVR returns. At 500 kHz and slower SPI, this can make
  1745. // a difference when digitalWrite is used to manually control the CS
  1746. // pin, and perhaps it could matter at high clocks if faster register
  1747. // access is used? But does it really matter? Do any SPI chips in
  1748. // practice really perform differently if CS negates early, after the
  1749. // final bit is clocked, but before the end of the whole clock cycle?
  1750. if ((val & (1<<SPIF)) && (SPI0_SR & SPI_SR_TCF)) ret = (1<<SPIF);
  1751. if ((val & (1<<SPI2X)) && (SPI0_CTAR0 & SPI_CTAR_DBR)) ret |= (1<<SPI2X);
  1752. //delayMicroseconds(50000);
  1753. return ret;
  1754. }
  1755. operator int () const __attribute__((always_inline)) {
  1756. int ret = 0;
  1757. //serial_print("SPSR (int)\n");
  1758. if (SPI0_SR & SPI_SR_TCF) ret = (1<<SPIF);
  1759. if (SPI0_CTAR0 & SPI_CTAR_DBR) ret |= (1<<SPI2X);
  1760. return ret;
  1761. }
  1762. };
  1763. extern SPSRemulation SPSR;
  1764. class SPDRemulation
  1765. {
  1766. public:
  1767. inline SPDRemulation & operator = (int val) __attribute__((always_inline)) {
  1768. //serial_print("SPDR = ");
  1769. //serial_phex(val);
  1770. //serial_print("\n");
  1771. SPI0_MCR |= SPI_MCR_CLR_RXF; // discard any received data
  1772. SPI0_SR = SPI_SR_TCF;
  1773. //SPI0_SR = SPI_SR_EOQF;
  1774. //SPI0_PUSHR = (val & 255) | SPI0_PUSHR_EOQ;
  1775. SPI0_PUSHR = (val & 255);
  1776. return *this;
  1777. }
  1778. operator int () const __attribute__((always_inline)) {
  1779. uint32_t val;
  1780. val = SPI0_POPR & 255;
  1781. //serial_print("SPDR (int) ");
  1782. //serial_phex(val);
  1783. //serial_print("\n");
  1784. return val;
  1785. }
  1786. };
  1787. extern SPDRemulation SPDR;
  1788. #elif defined(KINETISL)
  1789. // SPI Control Register ­ SPCR
  1790. //#define SPIE 7 // SPI Interrupt Enable - not supported
  1791. //#define SPE 6 // SPI Enable
  1792. //#define DORD 5 // DORD: Data Order
  1793. //#define MSTR 4 // MSTR: Master/Slave Select
  1794. //#define CPOL 3 // CPOL: Clock Polarity
  1795. //#define CPHA 2 // CPHA: Clock Phase
  1796. //#define SPR1 1 // Clock: 3 = 125 kHz, 2 = 250 kHz, 1 = 1 MHz, 0->4 MHz
  1797. //#define SPR0 0
  1798. // SPI Status Register ­ SPSR
  1799. //#define SPIF 7 // SPIF: SPI Interrupt Flag
  1800. //#define WCOL 6 // WCOL: Write COLlision Flag - not implemented
  1801. //#define SPI2X 0 // SPI2X: Double SPI Speed Bit
  1802. // SPI Data Register ­ SPDR
  1803. class SPCRemulation
  1804. {
  1805. public:
  1806. inline SPCRemulation & operator = (int val) __attribute__((always_inline)) {
  1807. uint32_t sim4 = SIM_SCGC4;
  1808. if (!(sim4 & SIM_SCGC4_SPI0)) {
  1809. SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
  1810. SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
  1811. }
  1812. uint32_t c1 = 0;
  1813. if (val & (1<<DORD)) c1 |= SPI_C1_LSBFE;
  1814. if (val & (1<<CPOL)) c1 |= SPI_C1_CPOL;
  1815. if (val & (1<<CPHA)) c1 |= SPI_C1_CPHA;
  1816. if (val & (1<<MSTR)) c1 |= SPI_C1_MSTR;
  1817. if (val & (1<<SPE)) c1 |= SPI_C1_SPE;
  1818. SPI0_C1 = c1;
  1819. SPI0_C2 = 0;
  1820. uint32_t br = SPI0_BR & 0x10;
  1821. switch (val & 3) {
  1822. case 0: SPI0_BR = br | SPI_BR_SPR(0); break;
  1823. case 1: SPI0_BR = br | SPI_BR_SPR(2); break;
  1824. case 2: SPI0_BR = br | SPI_BR_SPR(4); break;
  1825. default: SPI0_BR = br | SPI_BR_SPR(5); break;
  1826. }
  1827. if (val & (1<<SPE)) enable_pins();
  1828. else disable_pins();
  1829. return *this;
  1830. }
  1831. inline SPCRemulation & operator |= (int val) __attribute__((always_inline)) {
  1832. uint32_t sim4 = SIM_SCGC4;
  1833. if (!(sim4 & SIM_SCGC4_SPI0)) {
  1834. SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
  1835. SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
  1836. }
  1837. uint32_t c1 = SPI0_C1;
  1838. if (val & (1<<DORD)) c1 |= SPI_C1_LSBFE;
  1839. if (val & (1<<CPOL)) c1 |= SPI_C1_CPOL;
  1840. if (val & (1<<CPHA)) c1 |= SPI_C1_CPHA;
  1841. if (val & (1<<MSTR)) c1 |= SPI_C1_MSTR;
  1842. if (val & (1<<SPE)) {
  1843. enable_pins();
  1844. c1 |= SPI_C1_SPE;
  1845. }
  1846. SPI0_C1 = c1;
  1847. SPI0_C2 = 0;
  1848. val &= 3;
  1849. if (val) {
  1850. uint32_t br = SPI0_BR;
  1851. uint32_t bits = baud2avr(br) | val;
  1852. br &= 0x10;
  1853. switch (bits) {
  1854. case 0: SPI0_BR = br | SPI_BR_SPR(0); break;
  1855. case 1: SPI0_BR = br | SPI_BR_SPR(2); break;
  1856. case 2: SPI0_BR = br | SPI_BR_SPR(4); break;
  1857. default: SPI0_BR = br | SPI_BR_SPR(5); break;
  1858. }
  1859. }
  1860. return *this;
  1861. }
  1862. inline SPCRemulation & operator &= (int val) __attribute__((always_inline)) {
  1863. uint32_t sim4 = SIM_SCGC4;
  1864. if (!(sim4 & SIM_SCGC4_SPI0)) {
  1865. SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
  1866. SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
  1867. }
  1868. uint32_t c1 = SPI0_C1;
  1869. if (!(val & (1<<DORD))) c1 &= ~SPI_C1_LSBFE;
  1870. if (!(val & (1<<CPOL))) c1 &= ~SPI_C1_CPOL;
  1871. if (!(val & (1<<CPHA))) c1 &= ~SPI_C1_CPHA;
  1872. if (!(val & (1<<MSTR))) c1 &= ~SPI_C1_MSTR;
  1873. if (!(val & (1<<SPE))) {
  1874. disable_pins();
  1875. c1 &= ~SPI_C1_SPE;
  1876. }
  1877. SPI0_C1 = c1;
  1878. SPI0_C2 = 0;
  1879. val &= 3;
  1880. if (val < 3) {
  1881. uint32_t br = SPI0_BR;
  1882. uint32_t bits = baud2avr(br) & val;
  1883. br &= 0x10;
  1884. switch (bits) {
  1885. case 0: SPI0_BR = br | SPI_BR_SPR(0); break;
  1886. case 1: SPI0_BR = br | SPI_BR_SPR(2); break;
  1887. case 2: SPI0_BR = br | SPI_BR_SPR(4); break;
  1888. default: SPI0_BR = br | SPI_BR_SPR(5); break;
  1889. }
  1890. }
  1891. return *this;
  1892. }
  1893. inline int operator & (int val) const __attribute__((always_inline)) {
  1894. int ret = 0;
  1895. uint32_t sim4 = SIM_SCGC4;
  1896. if (!(sim4 & SIM_SCGC4_SPI0)) {
  1897. SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
  1898. SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
  1899. }
  1900. uint32_t c1 = SPI0_C1;
  1901. if ((val & (1<<DORD)) && (c1 & SPI_C1_LSBFE)) ret |= (1<<DORD);
  1902. if ((val & (1<<CPOL)) && (c1 & SPI_C1_CPOL)) ret |= (1<<CPOL);
  1903. if ((val & (1<<CPHA)) && (c1 & SPI_C1_CPHA)) ret |= (1<<CPHA);
  1904. if ((val & (1<<MSTR)) && (c1 & SPI_C1_MSTR)) ret |= (1<<MSTR);
  1905. if ((val & (1<<SPE)) && (c1 & SPI_C1_SPE)) ret |= (1<<SPE);
  1906. uint32_t bits = baud2avr(SPI0_BR);
  1907. if ((val & (1<<SPR1)) && (bits & (1<<SPR1))) ret |= (1<<SPR1);
  1908. if ((val & (1<<SPR0)) && (bits & (1<<SPR0))) ret |= (1<<SPR0);
  1909. return ret;
  1910. }
  1911. operator int () const __attribute__((always_inline)) {
  1912. int ret = 0;
  1913. uint32_t sim4 = SIM_SCGC4;
  1914. if (!(sim4 & SIM_SCGC4_SPI0)) {
  1915. SIM_SCGC4 = sim4 | SIM_SCGC4_SPI0;
  1916. SPI0_BR = SPI_BR_SPR(0) | SPI_BR_SPPR(1);
  1917. }
  1918. uint32_t c1 = SPI0_C1;
  1919. if ((c1 & SPI_C1_LSBFE)) ret |= (1<<DORD);
  1920. if ((c1 & SPI_C1_CPOL)) ret |= (1<<CPOL);
  1921. if ((c1 & SPI_C1_CPHA)) ret |= (1<<CPHA);
  1922. if ((c1 & SPI_C1_MSTR)) ret |= (1<<MSTR);
  1923. if ((c1 & SPI_C1_SPE)) ret |= (1<<SPE);
  1924. ret |= baud2avr(SPI0_BR);
  1925. return ret;
  1926. }
  1927. inline void setMOSI(uint8_t pin) __attribute__((always_inline)) {
  1928. uint8_t newpinout = pinout;
  1929. if (pin == 11) newpinout &= ~1;
  1930. if (pin == 7) newpinout |= 1;
  1931. if ((SIM_SCGC4 & SIM_SCGC4_SPI0) && newpinout != pinout) {
  1932. if ((newpinout & 1) == 0) {
  1933. CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1934. CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  1935. } else {
  1936. CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1937. CORE_PIN7_CONFIG = PORT_PCR_MUX(2);
  1938. }
  1939. }
  1940. pinout = newpinout;
  1941. }
  1942. inline void setMISO(uint8_t pin) __attribute__((always_inline)) {
  1943. uint8_t newpinout = pinout;
  1944. if (pin == 12) newpinout &= ~2;
  1945. if (pin == 8) newpinout |= 2;
  1946. if ((SIM_SCGC4 & SIM_SCGC4_SPI0) && newpinout != pinout) {
  1947. if ((newpinout & 2) == 0) {
  1948. CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1949. CORE_PIN12_CONFIG = PORT_PCR_MUX(2);
  1950. } else {
  1951. CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1952. CORE_PIN8_CONFIG = PORT_PCR_MUX(2);
  1953. }
  1954. }
  1955. pinout = newpinout;
  1956. }
  1957. inline void setSCK(uint8_t pin) __attribute__((always_inline)) {
  1958. uint8_t newpinout = pinout;
  1959. if (pin == 13) newpinout &= ~4;
  1960. if (pin == 14) newpinout |= 4;
  1961. if ((SIM_SCGC4 & SIM_SCGC4_SPI0) && newpinout != pinout) {
  1962. if ((newpinout & 4) == 0) {
  1963. CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1964. CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2);
  1965. } else {
  1966. CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1967. CORE_PIN14_CONFIG = PORT_PCR_MUX(2);
  1968. }
  1969. }
  1970. pinout = newpinout;
  1971. }
  1972. friend class SPSRemulation;
  1973. friend class SPIFIFOclass;
  1974. private:
  1975. static inline uint32_t baud2avr(uint32_t br) __attribute__((always_inline)) {
  1976. br &= 15;
  1977. if (br == 0) return 0;
  1978. if (br <= 2) return 1;
  1979. if (br <= 4) return 2;
  1980. return 3;
  1981. }
  1982. static uint8_t pinout;
  1983. public:
  1984. inline void enable_pins(void) __attribute__((always_inline)) {
  1985. //serial_print("enable_pins\n");
  1986. if ((pinout & 1) == 0) {
  1987. CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); // MOSI0 = 11 (PTC6)
  1988. } else {
  1989. CORE_PIN7_CONFIG = PORT_PCR_MUX(2); // MOSI0 = 7 (PTD2)
  1990. }
  1991. if ((pinout & 2) == 0) {
  1992. CORE_PIN12_CONFIG = PORT_PCR_MUX(2); // MISO0 = 12 (PTC7)
  1993. } else {
  1994. CORE_PIN8_CONFIG = PORT_PCR_MUX(2); // MISO0 = 8 (PTD3)
  1995. }
  1996. if ((pinout & 4) == 0) {
  1997. CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); // SCK0 = 13 (PTC5)
  1998. } else {
  1999. CORE_PIN14_CONFIG = PORT_PCR_MUX(2); // SCK0 = 14 (PTD1)
  2000. }
  2001. }
  2002. inline void disable_pins(void) __attribute__((always_inline)) {
  2003. //serial_print("disable_pins\n");
  2004. if ((pinout & 1) == 0) {
  2005. CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2006. } else {
  2007. CORE_PIN7_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2008. }
  2009. if ((pinout & 2) == 0) {
  2010. CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2011. } else {
  2012. CORE_PIN8_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2013. }
  2014. if ((pinout & 4) == 0) {
  2015. CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2016. } else {
  2017. CORE_PIN14_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2018. }
  2019. }
  2020. };
  2021. extern SPCRemulation SPCR;
  2022. class SPCR1emulation
  2023. {
  2024. public:
  2025. inline void setMOSI(uint8_t pin) __attribute__((always_inline)) {
  2026. if (pin == 0) pinout &= ~1; // MOSI1 = 0 (PTB16)
  2027. if (pin == 21) pinout |= 1; // MOSI1 = 21 (PTD6)
  2028. }
  2029. inline void setMISO(uint8_t pin) __attribute__((always_inline)) {
  2030. if (pin == 1) pinout &= ~2; // MISO1 = 1 (PTB17)
  2031. if (pin == 5) pinout |= 2; // MISO1 = 5 (PTD7)
  2032. }
  2033. inline void setSCK(uint8_t pin) __attribute__((always_inline)) {
  2034. // SCK1 = 20 (PTD5) - no alternative pin
  2035. }
  2036. inline void enable_pins(void) __attribute__((always_inline)) {
  2037. //serial_print("enable_pins\n");
  2038. if ((pinout & 1) == 0) {
  2039. CORE_PIN0_CONFIG = PORT_PCR_MUX(2); // MOSI1 = 0 (PTB16)
  2040. } else {
  2041. CORE_PIN21_CONFIG = PORT_PCR_MUX(2); // MOSI1 = 21 (PTD6)
  2042. }
  2043. if ((pinout & 2) == 0) {
  2044. CORE_PIN1_CONFIG = PORT_PCR_MUX(2); // MISO1 = 1 (PTB17)
  2045. } else {
  2046. CORE_PIN5_CONFIG = PORT_PCR_MUX(2); // MISO1 = 5 (PTD7)
  2047. }
  2048. CORE_PIN20_CONFIG = PORT_PCR_MUX(2); // SCK1 = 20 (PTD5)
  2049. }
  2050. inline void disable_pins(void) __attribute__((always_inline)) {
  2051. //serial_print("disable_pins\n");
  2052. if ((pinout & 1) == 0) {
  2053. CORE_PIN0_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2054. } else {
  2055. CORE_PIN21_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2056. }
  2057. if ((pinout & 2) == 0) {
  2058. CORE_PIN1_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2059. } else {
  2060. CORE_PIN5_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2061. }
  2062. CORE_PIN20_CONFIG = PORT_PCR_SRE | PORT_PCR_MUX(1);
  2063. }
  2064. friend class SPIFIFO1class;
  2065. private:
  2066. static uint8_t pinout;
  2067. };
  2068. extern SPCR1emulation SPCR1;
  2069. class SPSRemulation
  2070. {
  2071. public:
  2072. inline SPSRemulation & operator = (int val) __attribute__((always_inline)) {
  2073. if (val & (1<<SPI2X)) {
  2074. SPI0_BR &= ~0x10;
  2075. } else {
  2076. SPI0_BR |= 0x10;
  2077. }
  2078. return *this;
  2079. }
  2080. inline SPSRemulation & operator |= (int val) __attribute__((always_inline)) {
  2081. if (val & (1<<SPI2X)) SPI0_BR &= ~0x10;
  2082. return *this;
  2083. }
  2084. inline SPSRemulation & operator &= (int val) __attribute__((always_inline)) {
  2085. if (!(val & (1<<SPI2X))) SPI0_BR |= 0x10;
  2086. return *this;
  2087. }
  2088. inline int operator & (int val) const __attribute__((always_inline)) {
  2089. int ret = 0;
  2090. if ((val & (1<<SPIF)) && (SPI0_S & SPI_S_SPRF)) ret = (1<<SPIF);
  2091. if ((val & (1<<SPI2X)) && (!(SPI0_BR & 0x10))) ret |= (1<<SPI2X);
  2092. return ret;
  2093. }
  2094. operator int () const __attribute__((always_inline)) {
  2095. int ret = 0;
  2096. if ((SPI0_S & SPI_S_SPRF)) ret = (1<<SPIF);
  2097. if (!(SPI0_BR & 0x10)) ret |= (1<<SPI2X);
  2098. return ret;
  2099. }
  2100. };
  2101. extern SPSRemulation SPSR;
  2102. class SPDRemulation
  2103. {
  2104. public:
  2105. inline SPDRemulation & operator = (int val) __attribute__((always_inline)) {
  2106. if ((SPI0_S & SPI_S_SPTEF)) {
  2107. uint32_t tmp __attribute__((unused)) = SPI0_DL;
  2108. }
  2109. SPI0_DL = val;
  2110. return *this;
  2111. }
  2112. operator int () const __attribute__((always_inline)) {
  2113. return SPI0_DL & 255;
  2114. }
  2115. };
  2116. extern SPDRemulation SPDR;
  2117. #endif // KINETISK
  2118. class SREGemulation
  2119. {
  2120. public:
  2121. operator int () const __attribute__((always_inline)) {
  2122. uint32_t primask;
  2123. asm volatile("mrs %0, primask\n" : "=r" (primask)::);
  2124. if (primask) return 0;
  2125. return (1<<7);
  2126. }
  2127. inline SREGemulation & operator = (int val) __attribute__((always_inline)) {
  2128. if (val & (1<<7)) {
  2129. __enable_irq();
  2130. } else {
  2131. __disable_irq();
  2132. }
  2133. return *this;
  2134. }
  2135. };
  2136. extern SREGemulation SREG;
  2137. // 22211
  2138. // 84062840
  2139. // 322111
  2140. // 17395173
  2141. #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  2142. #if defined(__MK20DX128__) || defined(__MK20DX256__)
  2143. #define EIMSK_pA 0x01000018 // pins 3, 4, 24
  2144. #define EIMSK_pB 0x020F0003 // pins 0, 1, 16-19, 25
  2145. #define EIMSK_pC 0x78C0BE00 // pins 9-13, 15, 22, 23, 27-30
  2146. #define EIMSK_pD 0x003041E4 // pins 2, 5-8, 14, 20, 21
  2147. #define EIMSK_pE 0x84000000 // pins 26, 31
  2148. #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
  2149. #define EIMSK_pA 0x1E000018 // pins 3, 4, 25-28
  2150. #define EIMSK_pB 0xE00F0003 // pins 0, 1, 16-19, 29-31
  2151. #define EIMSK_pC 0x00C0BE00 // pins 9-13, 15, 22, 23
  2152. #define EIMSK_pD 0x003041E4 // pins 2, 5-8, 14, 20, 21
  2153. #define EIMSK_pE 0x01000000 // pins 24
  2154. #endif
  2155. class EIMSKemulation // used by Adafruit_nRF8001 (only supports INT for pins 0 to 31)
  2156. {
  2157. public:
  2158. operator int () const __attribute__((always_inline)) {
  2159. int mask = 0;
  2160. volatile const uint32_t *icer = &NVIC_ICER0;
  2161. if (icer[IRQ_PORTA >> 5] & (1 << (IRQ_PORTA & 31))) mask |= EIMSK_pA;
  2162. if (icer[IRQ_PORTB >> 5] & (1 << (IRQ_PORTB & 31))) mask |= EIMSK_pB;
  2163. if (icer[IRQ_PORTC >> 5] & (1 << (IRQ_PORTC & 31))) mask |= EIMSK_pC;
  2164. if (icer[IRQ_PORTD >> 5] & (1 << (IRQ_PORTD & 31))) mask |= EIMSK_pD;
  2165. if (icer[IRQ_PORTE >> 5] & (1 << (IRQ_PORTE & 31))) mask |= EIMSK_pE;
  2166. return mask;
  2167. }
  2168. inline EIMSKemulation & operator |= (int val) __attribute__((always_inline)) {
  2169. if (val & EIMSK_pA) NVIC_ENABLE_IRQ(IRQ_PORTA);
  2170. if (val & EIMSK_pB) NVIC_ENABLE_IRQ(IRQ_PORTB);
  2171. if (val & EIMSK_pC) NVIC_ENABLE_IRQ(IRQ_PORTC);
  2172. if (val & EIMSK_pD) NVIC_ENABLE_IRQ(IRQ_PORTD);
  2173. if (val & EIMSK_pE) NVIC_ENABLE_IRQ(IRQ_PORTE);
  2174. return *this;
  2175. }
  2176. inline EIMSKemulation & operator &= (int val) __attribute__((always_inline)) {
  2177. uint32_t n = val;
  2178. if ((n | ~EIMSK_pA) != 0xFFFFFFFF) NVIC_DISABLE_IRQ(IRQ_PORTA);
  2179. if ((n | ~EIMSK_pB) != 0xFFFFFFFF) NVIC_DISABLE_IRQ(IRQ_PORTB);
  2180. if ((n | ~EIMSK_pC) != 0xFFFFFFFF) NVIC_DISABLE_IRQ(IRQ_PORTC);
  2181. if ((n | ~EIMSK_pD) != 0xFFFFFFFF) NVIC_DISABLE_IRQ(IRQ_PORTD);
  2182. if ((n | ~EIMSK_pE) != 0xFFFFFFFF) NVIC_DISABLE_IRQ(IRQ_PORTE);
  2183. return *this;
  2184. }
  2185. };
  2186. extern EIMSKemulation EIMSK;
  2187. #elif defined(__MKL26Z64__)
  2188. #define EIMSK_pA 0x00000018 // pins 3, 4, 24
  2189. #define EIMSK_pC 0x00C0BE00 // pins 9-13, 15, 22, 23
  2190. #define EIMSK_pD 0x003041E4 // pins 2, 5-8, 14, 20, 21
  2191. class EIMSKemulation // used by Adafruit_nRF8001
  2192. {
  2193. public:
  2194. operator int () const __attribute__((always_inline)) {
  2195. int mask = 0;
  2196. volatile const uint32_t *icer = &NVIC_ICER0;
  2197. if (icer[IRQ_PORTA >> 5] & (1 << (IRQ_PORTA & 31))) mask |= EIMSK_pA;
  2198. if (icer[IRQ_PORTCD >> 5] & (1 << (IRQ_PORTCD & 31))) mask |= (EIMSK_pC | EIMSK_pD);
  2199. return mask;
  2200. }
  2201. inline EIMSKemulation & operator |= (int val) __attribute__((always_inline)) {
  2202. if (val & EIMSK_pA) NVIC_ENABLE_IRQ(IRQ_PORTA);
  2203. if (val & (EIMSK_pC | EIMSK_pD)) NVIC_ENABLE_IRQ(IRQ_PORTCD);
  2204. return *this;
  2205. }
  2206. inline EIMSKemulation & operator &= (int val) __attribute__((always_inline)) {
  2207. uint32_t n = val;
  2208. if ((n | ~EIMSK_pA) != 0xFFFFFFFF) NVIC_DISABLE_IRQ(IRQ_PORTA);
  2209. if ((n | ~(EIMSK_pC | EIMSK_pD)) != 0xFFFFFFFF) NVIC_DISABLE_IRQ(IRQ_PORTCD);
  2210. return *this;
  2211. }
  2212. };
  2213. extern EIMSKemulation EIMSK;
  2214. #endif
  2215. // these are not intended for public consumption...
  2216. #undef GPIO_BITBAND_ADDR
  2217. #undef CONFIG_PULLUP
  2218. #undef CONFIG_NOPULLUP
  2219. #undef GPIO_SETBIT_ATOMIC
  2220. #undef GPIO_CLRBIT_ATOMIC
  2221. #endif // __cplusplus
  2222. #endif