Teensy 4.1 core updated for C++20
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

2310 lines
73KB

  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(16)) 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