Teensy 4.1 core updated for C++20
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

1175 lines
37KB

  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2019 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 "imxrt.h"
  33. #include "core_pins.h"
  34. #include "pins_arduino.h"
  35. #ifdef __cplusplus
  36. // bitband addressing for atomic access to data direction register
  37. static inline void GPIO_SETBIT_ATOMIC(volatile uint32_t *reg, uint32_t mask) {
  38. __disable_irq();
  39. *reg |= mask;
  40. __enable_irq();
  41. }
  42. static inline void GPIO_CLRBIT_ATOMIC(volatile uint32_t *reg, uint32_t mask) {
  43. __disable_irq();
  44. *reg &= ~mask;
  45. __enable_irq();
  46. }
  47. #define CONFIG_PULLUP ( IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS )
  48. #define CONFIG_NOPULLUP ( IOMUXC_PAD_DSE(7))
  49. // SPI Control Register ­ SPCR
  50. #define SPIE 7 // SPI Interrupt Enable - not supported
  51. #define SPE 6 // SPI Enable
  52. #define DORD 5 // DORD: Data Order
  53. #define MSTR 4 // MSTR: Master/Slave Select
  54. #define CPOL 3 // CPOL: Clock Polarity
  55. #define CPHA 2 // CPHA: Clock Phase
  56. #define SPR1 1 // Clock: 3 = 125 kHz, 2 = 250 kHz, 1 = 1 MHz, 0->4 MHz
  57. #define SPR0 0
  58. // SPI Status Register ­ SPSR
  59. #define SPIF 7 // SPIF: SPI Interrupt Flag
  60. #define WCOL 6 // WCOL: Write COLlision Flag - not implemented
  61. #define SPI2X 0 // SPI2X: Double SPI Speed Bit
  62. // SPI Data Register ­ SPDR
  63. class SPCRemulation;
  64. class SPSRemulation;
  65. class SPDRemulation;
  66. class SPCRemulation
  67. {
  68. public:
  69. inline SPCRemulation & operator = (int val) __attribute__((always_inline)) {
  70. /*
  71. uint32_t ctar, mcr, sim6;
  72. //serial_print("SPCR=");
  73. //serial_phex(val);
  74. //serial_print("\n");
  75. sim6 = SIM_SCGC6;
  76. if (!(sim6 & SIM_SCGC6_SPI0)) {
  77. //serial_print("init1\n");
  78. SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0;
  79. SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  80. }
  81. if (!(val & (1<<SPE))) {
  82. SPI0_MCR |= SPI_MCR_MDIS; // TODO: use bitband for atomic access
  83. }
  84. ctar = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1);
  85. if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE;
  86. if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL;
  87. if (val & (1<<CPHA)) {
  88. ctar |= SPI_CTAR_CPHA;
  89. if ((val & 3) == 0) {
  90. ctar |= SPI_CTAR_BR(1) | SPI_CTAR_ASC(1);
  91. } else if ((val & 3) == 1) {
  92. ctar |= SPI_CTAR_BR(4) | SPI_CTAR_ASC(4);
  93. } else if ((val & 3) == 2) {
  94. ctar |= SPI_CTAR_BR(6) | SPI_CTAR_ASC(6);
  95. } else {
  96. ctar |= SPI_CTAR_BR(7) | SPI_CTAR_ASC(7);
  97. }
  98. } else {
  99. if ((val & 3) == 0) {
  100. ctar |= SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1);
  101. } else if ((val & 3) == 1) {
  102. ctar |= SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4);
  103. } else if ((val & 3) == 2) {
  104. ctar |= SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6);
  105. } else {
  106. ctar |= SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(7);
  107. }
  108. }
  109. ctar |= (SPI0_CTAR0 & SPI_CTAR_DBR);
  110. update_ctar(ctar);
  111. mcr = SPI_MCR_DCONF(0) | SPI_MCR_PCSIS(0x1F);
  112. if (val & (1<<MSTR)) mcr |= SPI_MCR_MSTR;
  113. if (val & (1<<SPE)) {
  114. mcr &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
  115. SPI0_MCR = mcr;
  116. enable_pins();
  117. } else {
  118. mcr |= (SPI_MCR_MDIS | SPI_MCR_HALT);
  119. SPI0_MCR = mcr;
  120. disable_pins();
  121. }
  122. //serial_print("MCR:");
  123. //serial_phex32(SPI0_MCR);
  124. //serial_print(", CTAR0:");
  125. //serial_phex32(SPI0_CTAR0);
  126. //serial_print("\n");
  127. */
  128. return *this;
  129. }
  130. inline SPCRemulation & operator |= (int val) __attribute__((always_inline)) {
  131. /*
  132. uint32_t sim6;
  133. //serial_print("SPCR |= ");
  134. //serial_phex(val);
  135. //serial_print("\n");
  136. sim6 = SIM_SCGC6;
  137. if (!(sim6 & SIM_SCGC6_SPI0)) {
  138. //serial_print("init2\n");
  139. SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0;
  140. SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1);
  141. }
  142. if (val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) {
  143. uint32_t ctar = SPI0_CTAR0;
  144. if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE; // TODO: use bitband
  145. if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL;
  146. if (val & (1<<CPHA) && !(ctar & SPI_CTAR_CPHA)) {
  147. ctar |= SPI_CTAR_CPHA;
  148. ctar &= 0xFFFF00FF;
  149. ctar |= SPI_CTAR_ASC(ctar & 15);
  150. }
  151. if ((val & 3) != 0) {
  152. uint32_t br = ctar & 15;
  153. uint32_t priorval;
  154. if (br <= 1) priorval = 0;
  155. else if (br <= 4) priorval = 1;
  156. else if (br <= 6) priorval = 2;
  157. else priorval = 3;
  158. uint32_t newval = priorval | (val & 3);
  159. if (newval != priorval) {
  160. if (newval == 0) br = 1;
  161. else if (newval == 0) br = 4;
  162. else if (newval == 0) br = 6;
  163. else br = 7;
  164. ctar &= 0xFFFF00F0; // clear BR, ASC, CSSCK
  165. if ((ctar & SPI_CTAR_CPHA)) {
  166. ctar |= SPI_CTAR_BR(br) | SPI_CTAR_ASC(br);
  167. } else {
  168. ctar |= SPI_CTAR_BR(br) | SPI_CTAR_CSSCK(br);
  169. }
  170. }
  171. }
  172. update_ctar(ctar);
  173. }
  174. if (val & (1<<MSTR)) SPI0_MCR |= SPI_MCR_MSTR;
  175. if (val & (1<<SPE)) {
  176. SPI0_MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT);
  177. enable_pins();
  178. }
  179. //serial_print("MCR:");
  180. //serial_phex32(SPI0_MCR);
  181. //serial_print(", CTAR0:");
  182. //serial_phex32(SPI0_CTAR0);
  183. //serial_print("\n");
  184. */
  185. return *this;
  186. }
  187. inline SPCRemulation & operator &= (int val) __attribute__((always_inline)) {
  188. /*
  189. //serial_print("SPCR &= ");
  190. //serial_phex(val);
  191. //serial_print("\n");
  192. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  193. if (!(val & (1<<SPE))) {
  194. SPI0_MCR |= (SPI_MCR_MDIS | SPI_MCR_HALT);
  195. disable_pins();
  196. }
  197. if ((val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) != ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) {
  198. uint32_t ctar = SPI0_CTAR0;
  199. if (!(val & (1<<DORD))) ctar &= ~SPI_CTAR_LSBFE; // TODO: use bitband
  200. if (!(val & (1<<CPOL))) ctar &= ~SPI_CTAR_CPOL;
  201. if (!(val & (1<<CPHA)) && (ctar & SPI_CTAR_CPHA)) {
  202. ctar &= ~SPI_CTAR_CPHA;
  203. ctar &= 0xFFFF00FF;
  204. ctar |= SPI_CTAR_CSSCK(ctar & 15);
  205. }
  206. if ((val & 3) != 3) {
  207. uint32_t br = ctar & 15;
  208. uint32_t priorval;
  209. if (br <= 1) priorval = 0;
  210. else if (br <= 4) priorval = 1;
  211. else if (br <= 6) priorval = 2;
  212. else priorval = 3;
  213. uint32_t newval = priorval & (val & 3);
  214. if (newval != priorval) {
  215. if (newval == 0) br = 1;
  216. else if (newval == 0) br = 4;
  217. else if (newval == 0) br = 6;
  218. else br = 7;
  219. ctar &= 0xFFFF00F0; // clear BR, ASC, CSSCK
  220. if ((ctar & SPI_CTAR_CPHA)) {
  221. ctar |= SPI_CTAR_BR(br) | SPI_CTAR_ASC(br);
  222. } else {
  223. ctar |= SPI_CTAR_BR(br) | SPI_CTAR_CSSCK(br);
  224. }
  225. }
  226. }
  227. update_ctar(ctar);
  228. }
  229. if (!(val & (1<<MSTR))) SPI0_MCR &= ~SPI_MCR_MSTR;
  230. */
  231. return *this;
  232. }
  233. inline int operator & (int val) const __attribute__((always_inline)) {
  234. int ret = 0;
  235. /*
  236. //serial_print("SPCR & ");
  237. //serial_phex(val);
  238. //serial_print("\n");
  239. SIM_SCGC6 |= SIM_SCGC6_SPI0;
  240. if ((val & (1<<DORD)) && (SPI0_CTAR0 & SPI_CTAR_LSBFE)) ret |= (1<<DORD);
  241. if ((val & (1<<CPOL)) && (SPI0_CTAR0 & SPI_CTAR_CPOL)) ret |= (1<<CPOL);
  242. if ((val & (1<<CPHA)) && (SPI0_CTAR0 & SPI_CTAR_CPHA)) ret |= (1<<CPHA);
  243. if ((val & 3) != 0) {
  244. uint32_t dbr = SPI0_CTAR0 & 15;
  245. uint32_t spr10;
  246. if (dbr <= 1) {
  247. spr10 = 0;
  248. } else if (dbr <= 4) {
  249. spr10 |= (1<<SPR0);
  250. } else if (dbr <= 6) {
  251. spr10 |= (1<<SPR1);
  252. } else {
  253. spr10 |= (1<<SPR1)|(1<<SPR0);
  254. }
  255. ret |= spr10 & (val & 3);
  256. }
  257. if (val & (1<<SPE) && (!(SPI0_MCR & SPI_MCR_MDIS))) ret |= (1<<SPE);
  258. if (val & (1<<MSTR) && (SPI0_MCR & SPI_MCR_MSTR)) ret |= (1<<MSTR);
  259. //serial_print("ret = ");
  260. //serial_phex(ret);
  261. //serial_print("\n");
  262. */
  263. return ret;
  264. }
  265. operator int () const __attribute__((always_inline)) {
  266. int ret = 0;
  267. /*
  268. if ((SIM_SCGC6 & SIM_SCGC6_SPI0)) {
  269. int ctar = SPI0_CTAR0;
  270. if (ctar & SPI_CTAR_LSBFE) ret |= (1<<DORD);
  271. if (ctar & SPI_CTAR_CPOL) ret |= (1<<CPOL);
  272. if (ctar & SPI_CTAR_CPHA) ret |= (1<<CPHA);
  273. ctar &= 15;
  274. if (ctar <= 1) {
  275. } else if (ctar <= 4) {
  276. ret |= (1<<SPR0);
  277. } else if (ctar <= 6) {
  278. ret |= (1<<SPR1);
  279. } else {
  280. ret |= (1<<SPR1)|(1<<SPR0);
  281. }
  282. int mcr = SPI0_MCR;
  283. if (!(mcr & SPI_MCR_MDIS)) ret |= (1<<SPE);
  284. if (mcr & SPI_MCR_MSTR) ret |= (1<<MSTR);
  285. }
  286. */
  287. return ret;
  288. }
  289. inline void setMOSI(uint8_t pin) __attribute__((always_inline)) {
  290. }
  291. inline void setMOSI_soft(uint8_t pin) __attribute__((always_inline)) {
  292. }
  293. inline void setMISO(uint8_t pin) __attribute__((always_inline)) {
  294. }
  295. inline void setSCK(uint8_t pin) __attribute__((always_inline)) {
  296. }
  297. friend class SPSRemulation;
  298. friend class SPIFIFOclass;
  299. private:
  300. static uint8_t pinout;
  301. public:
  302. inline void enable_pins(void) __attribute__((always_inline)) {
  303. //serial_print("enable_pins\n");
  304. }
  305. inline void disable_pins(void) __attribute__((always_inline)) {
  306. }
  307. };
  308. extern SPCRemulation SPCR;
  309. class SPSRemulation
  310. {
  311. public:
  312. inline SPSRemulation & operator = (int val) __attribute__((always_inline)) {
  313. //serial_print("SPSR=");
  314. //serial_phex(val);
  315. //serial_print("\n");
  316. /*
  317. uint32_t ctar = SPI0_CTAR0;
  318. if (val & (1<<SPI2X)) {
  319. ctar |= SPI_CTAR_DBR;
  320. } else {
  321. ctar &= ~SPI_CTAR_DBR;
  322. }
  323. SPCRemulation::update_ctar(ctar);
  324. //serial_print("MCR:");
  325. //serial_phex32(SPI0_MCR);
  326. //serial_print(", CTAR0:");
  327. //serial_phex32(SPI0_CTAR0);
  328. //serial_print("\n");
  329. */
  330. return *this;
  331. }
  332. inline SPSRemulation & operator |= (int val) __attribute__((always_inline)) {
  333. /*
  334. //serial_print("SPSR |= ");
  335. //serial_phex(val);
  336. //serial_print("\n");
  337. if (val & (1<<SPI2X)) SPCRemulation::update_ctar(SPI0_CTAR0 |= SPI_CTAR_DBR);
  338. */
  339. return *this;
  340. }
  341. inline SPSRemulation & operator &= (int val) __attribute__((always_inline)) {
  342. /*
  343. //serial_print("SPSR &= ");
  344. //serial_phex(val);
  345. //serial_print("\n");
  346. if (!(val & (1<<SPI2X))) SPCRemulation::update_ctar(SPI0_CTAR0 &= ~SPI_CTAR_DBR);
  347. */
  348. return *this;
  349. }
  350. inline int operator & (int val) const __attribute__((always_inline)) {
  351. int ret = 0;
  352. //serial_print("SPSR & ");
  353. //serial_phex(val);
  354. //serial_print("\n");
  355. // TODO: using SPI_SR_TCF isn't quite right. Control returns to the
  356. // caller after the final edge that captures data, which is 1/2 cycle
  357. // sooner than AVR returns. At 500 kHz and slower SPI, this can make
  358. // a difference when digitalWrite is used to manually control the CS
  359. // pin, and perhaps it could matter at high clocks if faster register
  360. // access is used? But does it really matter? Do any SPI chips in
  361. // practice really perform differently if CS negates early, after the
  362. // final bit is clocked, but before the end of the whole clock cycle?
  363. if ((val & (1<<SPIF)) && ((LPSPI4_RSR & LPSPI_RSR_RXEMPTY) == 0)) ret = (1<<SPIF);
  364. //if ((val & (1<<SPI2X)) && (SPI0_CTAR0 & SPI_CTAR_DBR)) ret |= (1<<SPI2X);
  365. //delayMicroseconds(50000);
  366. return ret;
  367. }
  368. operator int () const __attribute__((always_inline)) {
  369. int ret = 0;
  370. //serial_print("SPSR (int)\n");
  371. if ((LPSPI4_RSR & LPSPI_RSR_RXEMPTY) == 0) ret = (1<<SPIF);
  372. //if (SPI0_CTAR0 & SPI_CTAR_DBR) ret |= (1<<SPI2X);
  373. return ret;
  374. }
  375. };
  376. extern SPSRemulation SPSR;
  377. class SPDRemulation
  378. {
  379. public:
  380. inline SPDRemulation & operator = (int val) __attribute__((always_inline)) {
  381. //serial_print("SPDR = ");
  382. //serial_phex(val);
  383. //serial_print("\n");
  384. LPSPI4_CR = LPSPI_CR_RRF | LPSPI_CR_MEN; // Module enabled anc clear the receive.
  385. LPSPI4_TDR = (val & 255);
  386. return *this;
  387. }
  388. operator int () const __attribute__((always_inline)) {
  389. uint32_t val;
  390. val = LPSPI4_RDR & 255;
  391. return val;
  392. }
  393. };
  394. extern SPDRemulation SPDR;
  395. class PORTDemulation
  396. {
  397. public:
  398. inline PORTDemulation & operator = (int val) __attribute__((always_inline)) {
  399. digitalWriteFast(0, (val & (1<<0)));
  400. if (!(CORE_PIN0_DDRREG & CORE_PIN0_BITMASK))
  401. CORE_PIN0_PADCONFIG = ((val & (1<<0)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  402. digitalWriteFast(1, (val & (1<<1)));
  403. if (!(CORE_PIN1_DDRREG & CORE_PIN1_BITMASK))
  404. CORE_PIN1_PADCONFIG = ((val & (1<<1)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  405. digitalWriteFast(2, (val & (1<<2)));
  406. if (!(CORE_PIN2_DDRREG & CORE_PIN2_BITMASK))
  407. CORE_PIN2_PADCONFIG = ((val & (1<<2)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  408. digitalWriteFast(3, (val & (1<<3)));
  409. if (!(CORE_PIN3_DDRREG & CORE_PIN3_BITMASK))
  410. CORE_PIN3_PADCONFIG = ((val & (1<<3)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  411. digitalWriteFast(4, (val & (1<<4)));
  412. if (!(CORE_PIN4_DDRREG & CORE_PIN4_BITMASK))
  413. CORE_PIN4_PADCONFIG = ((val & (1<<4)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  414. digitalWriteFast(5, (val & (1<<5)));
  415. if (!(CORE_PIN5_DDRREG & CORE_PIN5_BITMASK))
  416. CORE_PIN5_PADCONFIG = ((val & (1<<5)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  417. digitalWriteFast(6, (val & (1<<6)));
  418. if (!(CORE_PIN6_DDRREG & CORE_PIN6_BITMASK))
  419. CORE_PIN6_PADCONFIG = ((val & (1<<6)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  420. digitalWriteFast(7, (val & (1<<7)));
  421. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BITMASK))
  422. CORE_PIN7_PADCONFIG = ((val & (1<<7)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  423. return *this;
  424. }
  425. inline PORTDemulation & operator |= (int val) __attribute__((always_inline)) {
  426. if (val & (1<<0)) {
  427. digitalWriteFast(0, HIGH);
  428. if (!(CORE_PIN0_DDRREG & CORE_PIN0_BITMASK)) CORE_PIN0_CONFIG = CONFIG_PULLUP;
  429. }
  430. if (val & (1<<1)) {
  431. digitalWriteFast(1, HIGH);
  432. if (!(CORE_PIN1_DDRREG & CORE_PIN1_BITMASK)) CORE_PIN1_CONFIG = CONFIG_PULLUP;
  433. }
  434. if (val & (1<<2)) {
  435. digitalWriteFast(2, HIGH);
  436. if (!(CORE_PIN2_DDRREG & CORE_PIN2_BITMASK)) CORE_PIN2_CONFIG = CONFIG_PULLUP;
  437. }
  438. if (val & (1<<3)) {
  439. digitalWriteFast(3, HIGH);
  440. if (!(CORE_PIN3_DDRREG & CORE_PIN3_BITMASK)) CORE_PIN3_CONFIG = CONFIG_PULLUP;
  441. }
  442. if (val & (1<<4)) {
  443. digitalWriteFast(4, HIGH);
  444. if (!(CORE_PIN4_DDRREG & CORE_PIN4_BITMASK)) CORE_PIN4_CONFIG = CONFIG_PULLUP;
  445. }
  446. if (val & (1<<5)) {
  447. digitalWriteFast(5, HIGH);
  448. if (!(CORE_PIN5_DDRREG & CORE_PIN5_BITMASK)) CORE_PIN5_CONFIG = CONFIG_PULLUP;
  449. }
  450. if (val & (1<<6)) {
  451. digitalWriteFast(6, HIGH);
  452. if (!(CORE_PIN6_DDRREG & CORE_PIN6_BITMASK)) CORE_PIN6_CONFIG = CONFIG_PULLUP;
  453. }
  454. if (val & (1<<7)) {
  455. digitalWriteFast(7, HIGH);
  456. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BITMASK)) CORE_PIN7_CONFIG = CONFIG_PULLUP;
  457. }
  458. return *this;
  459. }
  460. inline PORTDemulation & operator &= (int val) __attribute__((always_inline)) {
  461. if (!(val & (1<<0))) {
  462. digitalWriteFast(0, LOW);
  463. if (!(CORE_PIN0_DDRREG & CORE_PIN0_BITMASK)) CORE_PIN0_CONFIG = CONFIG_NOPULLUP;
  464. }
  465. if (!(val & (1<<1))) {
  466. digitalWriteFast(1, LOW);
  467. if (!(CORE_PIN1_DDRREG & CORE_PIN1_BITMASK)) CORE_PIN1_CONFIG = CONFIG_NOPULLUP;
  468. }
  469. if (!(val & (1<<2))) {
  470. digitalWriteFast(2, LOW);
  471. if (!(CORE_PIN2_DDRREG & CORE_PIN2_BITMASK)) CORE_PIN2_CONFIG = CONFIG_NOPULLUP;
  472. }
  473. if (!(val & (1<<3))) {
  474. digitalWriteFast(3, LOW);
  475. if (!(CORE_PIN3_DDRREG & CORE_PIN3_BITMASK)) CORE_PIN3_CONFIG = CONFIG_NOPULLUP;
  476. }
  477. if (!(val & (1<<4))) {
  478. digitalWriteFast(4, LOW);
  479. if (!(CORE_PIN4_DDRREG & CORE_PIN4_BITMASK)) CORE_PIN4_CONFIG = CONFIG_NOPULLUP;
  480. }
  481. if (!(val & (1<<5))) {
  482. digitalWriteFast(5, LOW);
  483. if (!(CORE_PIN5_DDRREG & CORE_PIN5_BITMASK)) CORE_PIN5_CONFIG = CONFIG_NOPULLUP;
  484. }
  485. if (!(val & (1<<6))) {
  486. digitalWriteFast(6, LOW);
  487. if (!(CORE_PIN6_DDRREG & CORE_PIN6_BITMASK)) CORE_PIN6_CONFIG = CONFIG_NOPULLUP;
  488. }
  489. if (!(val & (1<<7))) {
  490. digitalWriteFast(7, LOW);
  491. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BITMASK)) CORE_PIN7_CONFIG = CONFIG_NOPULLUP;
  492. }
  493. return *this;
  494. }
  495. };
  496. extern PORTDemulation PORTD;
  497. class PINDemulation
  498. {
  499. public:
  500. inline int operator & (int val) const __attribute__((always_inline)) {
  501. int ret = 0;
  502. if ((val & (1<<0)) && digitalReadFast(0)) ret |= (1<<0);
  503. if ((val & (1<<1)) && digitalReadFast(1)) ret |= (1<<1);
  504. if ((val & (1<<2)) && digitalReadFast(2)) ret |= (1<<2);
  505. if ((val & (1<<3)) && digitalReadFast(3)) ret |= (1<<3);
  506. if ((val & (1<<4)) && digitalReadFast(4)) ret |= (1<<4);
  507. if ((val & (1<<5)) && digitalReadFast(5)) ret |= (1<<5);
  508. if ((val & (1<<6)) && digitalReadFast(6)) ret |= (1<<6);
  509. if ((val & (1<<7)) && digitalReadFast(7)) ret |= (1<<7);
  510. return ret;
  511. }
  512. operator int () const __attribute__((always_inline)) {
  513. int ret = 0;
  514. if (digitalReadFast(0)) ret |= (1<<0);
  515. if (digitalReadFast(1)) ret |= (1<<1);
  516. if (digitalReadFast(2)) ret |= (1<<2);
  517. if (digitalReadFast(3)) ret |= (1<<3);
  518. if (digitalReadFast(4)) ret |= (1<<4);
  519. if (digitalReadFast(5)) ret |= (1<<5);
  520. if (digitalReadFast(6)) ret |= (1<<6);
  521. if (digitalReadFast(7)) ret |= (1<<7);
  522. return ret;
  523. }
  524. };
  525. extern PINDemulation PIND;
  526. class DDRDemulation
  527. {
  528. public:
  529. inline DDRDemulation & operator = (int val) __attribute__((always_inline)) {
  530. if (val & (1<<0)) set0(); else clr0();
  531. if (val & (1<<1)) set1(); else clr1();
  532. if (val & (1<<2)) set2(); else clr2();
  533. if (val & (1<<3)) set3(); else clr3();
  534. if (val & (1<<4)) set4(); else clr4();
  535. if (val & (1<<5)) set5(); else clr5();
  536. if (val & (1<<6)) set6(); else clr6();
  537. if (val & (1<<7)) set7(); else clr7();
  538. return *this;
  539. }
  540. inline DDRDemulation & operator |= (int val) __attribute__((always_inline)) {
  541. if (val & (1<<0)) set0();
  542. if (val & (1<<1)) set1();
  543. if (val & (1<<2)) set2();
  544. if (val & (1<<3)) set3();
  545. if (val & (1<<4)) set4();
  546. if (val & (1<<5)) set5();
  547. if (val & (1<<6)) set6();
  548. if (val & (1<<7)) set7();
  549. return *this;
  550. }
  551. inline DDRDemulation & operator &= (int val) __attribute__((always_inline)) {
  552. if (!(val & (1<<0))) clr0();
  553. if (!(val & (1<<1))) clr1();
  554. if (!(val & (1<<2))) clr2();
  555. if (!(val & (1<<3))) clr3();
  556. if (!(val & (1<<4))) clr4();
  557. if (!(val & (1<<5))) clr5();
  558. if (!(val & (1<<6))) clr6();
  559. if (!(val & (1<<7))) clr7();
  560. return *this;
  561. }
  562. private:
  563. inline void set0() __attribute__((always_inline)) {
  564. GPIO_SETBIT_ATOMIC(&CORE_PIN0_DDRREG, CORE_PIN0_BITMASK);
  565. CORE_PIN0_CONFIG = 5 | 0x10;
  566. CORE_PIN0_PADCONFIG = CONFIG_PULLUP;
  567. }
  568. inline void set1() __attribute__((always_inline)) {
  569. GPIO_SETBIT_ATOMIC(&CORE_PIN1_DDRREG, CORE_PIN1_BITMASK);
  570. CORE_PIN1_CONFIG = 5 | 0x10;
  571. CORE_PIN1_PADCONFIG = CONFIG_PULLUP;
  572. }
  573. inline void set2() __attribute__((always_inline)) {
  574. GPIO_SETBIT_ATOMIC(&CORE_PIN2_DDRREG, CORE_PIN2_BITMASK);
  575. CORE_PIN2_CONFIG = 5 | 0x10;
  576. CORE_PIN2_PADCONFIG = CONFIG_PULLUP;
  577. }
  578. inline void set3() __attribute__((always_inline)) {
  579. GPIO_SETBIT_ATOMIC(&CORE_PIN3_DDRREG, CORE_PIN3_BITMASK);
  580. CORE_PIN3_CONFIG = 5 | 0x10;
  581. CORE_PIN3_PADCONFIG = CONFIG_PULLUP;
  582. }
  583. inline void set4() __attribute__((always_inline)) {
  584. GPIO_SETBIT_ATOMIC(&CORE_PIN4_DDRREG, CORE_PIN4_BITMASK);
  585. CORE_PIN4_CONFIG = 5 | 0x10;
  586. CORE_PIN4_PADCONFIG = CONFIG_PULLUP;
  587. }
  588. inline void set5() __attribute__((always_inline)) {
  589. GPIO_SETBIT_ATOMIC(&CORE_PIN5_DDRREG, CORE_PIN5_BITMASK);
  590. CORE_PIN5_CONFIG = 5 | 0x10;
  591. CORE_PIN5_PADCONFIG = CONFIG_PULLUP;
  592. }
  593. inline void set6() __attribute__((always_inline)) {
  594. GPIO_SETBIT_ATOMIC(&CORE_PIN6_DDRREG, CORE_PIN6_BITMASK);
  595. CORE_PIN6_CONFIG = 5 | 0x10;
  596. CORE_PIN6_PADCONFIG = CONFIG_PULLUP;
  597. }
  598. inline void set7() __attribute__((always_inline)) {
  599. GPIO_SETBIT_ATOMIC(&CORE_PIN7_DDRREG, CORE_PIN7_BITMASK);
  600. CORE_PIN7_CONFIG = 5 | 0x10;
  601. CORE_PIN7_PADCONFIG = CONFIG_PULLUP;
  602. }
  603. inline void clr0() __attribute__((always_inline)) {
  604. CORE_PIN0_CONFIG = 5 | 0x10;
  605. CORE_PIN0_PADCONFIG = ((CORE_PIN0_PORTREG & CORE_PIN0_BITMASK)
  606. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  607. GPIO_CLRBIT_ATOMIC(&CORE_PIN0_DDRREG, CORE_PIN0_BITMASK);
  608. }
  609. inline void clr1() __attribute__((always_inline)) {
  610. CORE_PIN1_CONFIG = 5 | 0x10;
  611. CORE_PIN1_PADCONFIG = ((CORE_PIN1_PORTREG & CORE_PIN1_BITMASK)
  612. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  613. GPIO_CLRBIT_ATOMIC(&CORE_PIN1_DDRREG, CORE_PIN1_BITMASK);
  614. }
  615. inline void clr2() __attribute__((always_inline)) {
  616. CORE_PIN2_CONFIG = 5 | 0x10;
  617. CORE_PIN2_PADCONFIG = ((CORE_PIN2_PORTREG & CORE_PIN2_BITMASK)
  618. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  619. GPIO_CLRBIT_ATOMIC(&CORE_PIN2_DDRREG, CORE_PIN2_BITMASK);
  620. }
  621. inline void clr3() __attribute__((always_inline)) {
  622. CORE_PIN3_CONFIG = 5 | 0x10;
  623. CORE_PIN3_PADCONFIG = ((CORE_PIN3_PORTREG & CORE_PIN3_BITMASK)
  624. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  625. GPIO_CLRBIT_ATOMIC(&CORE_PIN3_DDRREG, CORE_PIN3_BITMASK);
  626. }
  627. inline void clr4() __attribute__((always_inline)) {
  628. CORE_PIN4_CONFIG = 5 | 0x10;
  629. CORE_PIN4_PADCONFIG = ((CORE_PIN4_PORTREG & CORE_PIN4_BITMASK)
  630. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  631. GPIO_CLRBIT_ATOMIC(&CORE_PIN4_DDRREG, CORE_PIN4_BITMASK);
  632. }
  633. inline void clr5() __attribute__((always_inline)) {
  634. CORE_PIN5_CONFIG = 5 | 0x10;
  635. CORE_PIN5_PADCONFIG = ((CORE_PIN5_PORTREG & CORE_PIN5_BITMASK)
  636. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  637. GPIO_CLRBIT_ATOMIC(&CORE_PIN5_DDRREG, CORE_PIN5_BITMASK);
  638. }
  639. inline void clr6() __attribute__((always_inline)) {
  640. CORE_PIN6_CONFIG = 5 | 0x10;
  641. CORE_PIN6_PADCONFIG = ((CORE_PIN6_PORTREG & CORE_PIN6_BITMASK)
  642. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  643. GPIO_CLRBIT_ATOMIC(&CORE_PIN6_DDRREG, CORE_PIN6_BITMASK);
  644. }
  645. inline void clr7() __attribute__((always_inline)) {
  646. CORE_PIN7_CONFIG = 5 | 0x10;
  647. CORE_PIN7_PADCONFIG = ((CORE_PIN7_PORTREG & CORE_PIN7_BITMASK)
  648. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  649. GPIO_CLRBIT_ATOMIC(&CORE_PIN7_DDRREG, CORE_PIN7_BITMASK);
  650. }
  651. };
  652. extern DDRDemulation DDRD;
  653. class PORTBemulation
  654. {
  655. public:
  656. inline PORTBemulation & operator = (int val) __attribute__((always_inline)) {
  657. digitalWriteFast(8, (val & (1<<0)));
  658. if (!(CORE_PIN8_DDRREG & CORE_PIN8_BITMASK))
  659. CORE_PIN8_PADCONFIG = ((val & (1<<0)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  660. digitalWriteFast(9, (val & (1<<1)));
  661. if (!(CORE_PIN9_DDRREG & CORE_PIN9_BITMASK))
  662. CORE_PIN9_PADCONFIG = ((val & (1<<1)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  663. digitalWriteFast(10, (val & (1<<2)));
  664. if (!(CORE_PIN10_DDRREG & CORE_PIN10_BITMASK))
  665. CORE_PIN10_PADCONFIG = ((val & (1<<2)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  666. digitalWriteFast(11, (val & (1<<3)));
  667. if (!(CORE_PIN11_DDRREG & CORE_PIN11_BITMASK))
  668. CORE_PIN11_PADCONFIG = ((val & (1<<3)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  669. digitalWriteFast(12, (val & (1<<4)));
  670. if (!(CORE_PIN12_DDRREG & CORE_PIN12_BITMASK))
  671. CORE_PIN12_PADCONFIG = ((val & (1<<4)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  672. digitalWriteFast(13, (val & (1<<5)));
  673. if (!(CORE_PIN13_DDRREG & CORE_PIN13_BITMASK))
  674. CORE_PIN13_PADCONFIG = ((val & (1<<5)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  675. return *this;
  676. }
  677. inline PORTBemulation & operator |= (int val) __attribute__((always_inline)) {
  678. if (val & (1<<0)) {
  679. digitalWriteFast(8, HIGH);
  680. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BITMASK)) CORE_PIN8_CONFIG = CONFIG_PULLUP;
  681. }
  682. if (val & (1<<1)) {
  683. digitalWriteFast(9, HIGH);
  684. if (!(CORE_PIN7_DDRREG & CORE_PIN7_BITMASK)) CORE_PIN9_CONFIG = CONFIG_PULLUP;
  685. }
  686. if (val & (1<<2)) {
  687. digitalWriteFast(10, HIGH);
  688. if (!(CORE_PIN10_DDRREG & CORE_PIN10_BITMASK)) CORE_PIN10_CONFIG = CONFIG_PULLUP;
  689. }
  690. if (val & (1<<3)) {
  691. digitalWriteFast(11, HIGH);
  692. if (!(CORE_PIN11_DDRREG & CORE_PIN11_BITMASK)) CORE_PIN11_CONFIG = CONFIG_PULLUP;
  693. }
  694. if (val & (1<<4)) {
  695. digitalWriteFast(12, HIGH);
  696. if (!(CORE_PIN12_DDRREG & CORE_PIN12_BITMASK)) CORE_PIN12_CONFIG = CONFIG_PULLUP;
  697. }
  698. if (val & (1<<5)) {
  699. digitalWriteFast(13, HIGH);
  700. if (!(CORE_PIN13_DDRREG & CORE_PIN13_BITMASK)) CORE_PIN13_CONFIG = CONFIG_PULLUP;
  701. }
  702. return *this;
  703. }
  704. inline PORTBemulation & operator &= (int val) __attribute__((always_inline)) {
  705. if (!(val & (1<<0))) {
  706. digitalWriteFast(8, LOW);
  707. if (!(CORE_PIN8_DDRREG & CORE_PIN8_BITMASK)) CORE_PIN8_CONFIG = CONFIG_NOPULLUP;
  708. }
  709. if (!(val & (1<<1))) {
  710. digitalWriteFast(9, LOW);
  711. if (!(CORE_PIN9_DDRREG & CORE_PIN9_BITMASK)) CORE_PIN9_CONFIG = CONFIG_NOPULLUP;
  712. }
  713. if (!(val & (1<<2))) {
  714. digitalWriteFast(10, LOW);
  715. if (!(CORE_PIN10_DDRREG & CORE_PIN10_BITMASK)) CORE_PIN10_CONFIG = CONFIG_NOPULLUP;
  716. }
  717. if (!(val & (1<<3))) {
  718. digitalWriteFast(11, LOW);
  719. if (!(CORE_PIN11_DDRREG & CORE_PIN11_BITMASK)) CORE_PIN11_CONFIG = CONFIG_NOPULLUP;
  720. }
  721. if (!(val & (1<<4))) {
  722. digitalWriteFast(12, LOW);
  723. if (!(CORE_PIN12_DDRREG & CORE_PIN12_BITMASK)) CORE_PIN12_CONFIG = CONFIG_NOPULLUP;
  724. }
  725. if (!(val & (1<<5))) {
  726. digitalWriteFast(13, LOW);
  727. if (!(CORE_PIN13_DDRREG & CORE_PIN13_BITMASK)) CORE_PIN13_CONFIG = CONFIG_NOPULLUP;
  728. }
  729. return *this;
  730. }
  731. };
  732. extern PORTBemulation PORTB;
  733. class PINBemulation
  734. {
  735. public:
  736. inline int operator & (int val) const __attribute__((always_inline)) {
  737. int ret = 0;
  738. if ((val & (1<<0)) && digitalReadFast(8)) ret |= (1<<0);
  739. if ((val & (1<<1)) && digitalReadFast(9)) ret |= (1<<1);
  740. if ((val & (1<<2)) && digitalReadFast(10)) ret |= (1<<2);
  741. if ((val & (1<<3)) && digitalReadFast(11)) ret |= (1<<3);
  742. if ((val & (1<<4)) && digitalReadFast(12)) ret |= (1<<4);
  743. if ((val & (1<<5)) && digitalReadFast(13)) ret |= (1<<5);
  744. return ret;
  745. }
  746. operator int () const __attribute__((always_inline)) {
  747. int ret = 0;
  748. if (digitalReadFast(8)) ret |= (1<<0);
  749. if (digitalReadFast(9)) ret |= (1<<1);
  750. if (digitalReadFast(10)) ret |= (1<<2);
  751. if (digitalReadFast(11)) ret |= (1<<3);
  752. if (digitalReadFast(12)) ret |= (1<<4);
  753. if (digitalReadFast(13)) ret |= (1<<5);
  754. return ret;
  755. }
  756. };
  757. extern PINBemulation PINB;
  758. class DDRBemulation
  759. {
  760. public:
  761. inline DDRBemulation & operator = (int val) __attribute__((always_inline)) {
  762. if (val & (1<<0)) set0(); else clr0();
  763. if (val & (1<<1)) set1(); else clr1();
  764. if (val & (1<<2)) set2(); else clr2();
  765. if (val & (1<<3)) set3(); else clr3();
  766. if (val & (1<<4)) set4(); else clr4();
  767. if (val & (1<<5)) set5(); else clr5();
  768. return *this;
  769. }
  770. inline DDRBemulation & operator |= (int val) __attribute__((always_inline)) {
  771. if (val & (1<<0)) set0();
  772. if (val & (1<<1)) set1();
  773. if (val & (1<<2)) set2();
  774. if (val & (1<<3)) set3();
  775. if (val & (1<<4)) set4();
  776. if (val & (1<<5)) set5();
  777. return *this;
  778. }
  779. inline DDRBemulation & operator &= (int val) __attribute__((always_inline)) {
  780. if (!(val & (1<<0))) clr0();
  781. if (!(val & (1<<1))) clr1();
  782. if (!(val & (1<<2))) clr2();
  783. if (!(val & (1<<3))) clr3();
  784. if (!(val & (1<<4))) clr4();
  785. if (!(val & (1<<5))) clr5();
  786. return *this;
  787. }
  788. private:
  789. inline void set0() __attribute__((always_inline)) {
  790. GPIO_SETBIT_ATOMIC(&CORE_PIN8_DDRREG, CORE_PIN8_BITMASK);
  791. CORE_PIN8_CONFIG = 5 | 0x10;
  792. CORE_PIN8_PADCONFIG = CONFIG_PULLUP;
  793. }
  794. inline void set1() __attribute__((always_inline)) {
  795. GPIO_SETBIT_ATOMIC(&CORE_PIN9_DDRREG, CORE_PIN9_BITMASK);
  796. CORE_PIN9_CONFIG = 5 | 0x10;
  797. CORE_PIN9_PADCONFIG = CONFIG_PULLUP;
  798. }
  799. inline void set2() __attribute__((always_inline)) {
  800. GPIO_SETBIT_ATOMIC(&CORE_PIN10_DDRREG, CORE_PIN10_BITMASK);
  801. CORE_PIN10_CONFIG = 5 | 0x10;
  802. CORE_PIN10_PADCONFIG = CONFIG_PULLUP;
  803. }
  804. inline void set3() __attribute__((always_inline)) {
  805. GPIO_SETBIT_ATOMIC(&CORE_PIN11_DDRREG, CORE_PIN11_BITMASK);
  806. CORE_PIN11_CONFIG = 5 | 0x10;
  807. CORE_PIN11_PADCONFIG = CONFIG_PULLUP;
  808. }
  809. inline void set4() __attribute__((always_inline)) {
  810. GPIO_SETBIT_ATOMIC(&CORE_PIN12_DDRREG, CORE_PIN12_BITMASK);
  811. CORE_PIN12_CONFIG = 5 | 0x10;
  812. CORE_PIN12_PADCONFIG = CONFIG_PULLUP;
  813. }
  814. inline void set5() __attribute__((always_inline)) {
  815. GPIO_SETBIT_ATOMIC(&CORE_PIN13_DDRREG, CORE_PIN13_BITMASK);
  816. CORE_PIN13_CONFIG = 5 | 0x10;
  817. CORE_PIN13_PADCONFIG = CONFIG_PULLUP;
  818. }
  819. inline void clr0() __attribute__((always_inline)) {
  820. CORE_PIN8_CONFIG = 5 | 0x10;
  821. CORE_PIN8_PADCONFIG = ((CORE_PIN8_PORTREG & CORE_PIN8_BITMASK)
  822. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  823. GPIO_CLRBIT_ATOMIC(&CORE_PIN8_DDRREG, CORE_PIN8_BITMASK);
  824. }
  825. inline void clr1() __attribute__((always_inline)) {
  826. CORE_PIN9_CONFIG = 5 | 0x10;
  827. CORE_PIN9_PADCONFIG = ((CORE_PIN9_PORTREG & CORE_PIN9_BITMASK)
  828. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  829. GPIO_CLRBIT_ATOMIC(&CORE_PIN9_DDRREG, CORE_PIN9_BITMASK);
  830. }
  831. inline void clr2() __attribute__((always_inline)) {
  832. CORE_PIN10_CONFIG = 5 | 0x10;
  833. CORE_PIN10_PADCONFIG = ((CORE_PIN10_PORTREG & CORE_PIN10_BITMASK)
  834. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  835. GPIO_CLRBIT_ATOMIC(&CORE_PIN10_DDRREG, CORE_PIN10_BITMASK);
  836. }
  837. inline void clr3() __attribute__((always_inline)) {
  838. CORE_PIN11_CONFIG = 5 | 0x10;
  839. CORE_PIN11_PADCONFIG = ((CORE_PIN11_PORTREG & CORE_PIN11_BITMASK)
  840. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  841. GPIO_CLRBIT_ATOMIC(&CORE_PIN11_DDRREG, CORE_PIN11_BITMASK);
  842. }
  843. inline void clr4() __attribute__((always_inline)) {
  844. CORE_PIN12_CONFIG = 5 | 0x10;
  845. CORE_PIN12_PADCONFIG = ((CORE_PIN12_PORTREG & CORE_PIN12_BITMASK)
  846. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  847. GPIO_CLRBIT_ATOMIC(&CORE_PIN12_DDRREG, CORE_PIN12_BITMASK);
  848. }
  849. inline void clr5() __attribute__((always_inline)) {
  850. CORE_PIN13_CONFIG = 5 | 0x10;
  851. CORE_PIN13_PADCONFIG = ((CORE_PIN13_PORTREG & CORE_PIN13_BITMASK)
  852. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  853. GPIO_CLRBIT_ATOMIC(&CORE_PIN13_DDRREG, CORE_PIN13_BITMASK);
  854. }
  855. };
  856. extern DDRBemulation DDRB;
  857. class PORTCemulation
  858. {
  859. public:
  860. inline PORTCemulation & operator = (int val) __attribute__((always_inline)) {
  861. digitalWriteFast(14, (val & (1<<0)));
  862. if (!(CORE_PIN14_DDRREG & CORE_PIN14_BITMASK))
  863. CORE_PIN14_PADCONFIG = ((val & (1<<0)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  864. digitalWriteFast(15, (val & (1<<1)));
  865. if (!(CORE_PIN15_DDRREG & CORE_PIN15_BITMASK))
  866. CORE_PIN15_PADCONFIG = ((val & (1<<1)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  867. digitalWriteFast(16, (val & (1<<2)));
  868. if (!(CORE_PIN16_DDRREG & CORE_PIN16_BITMASK))
  869. CORE_PIN16_PADCONFIG = ((val & (1<<2)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  870. digitalWriteFast(17, (val & (1<<3)));
  871. if (!(CORE_PIN17_DDRREG & CORE_PIN17_BITMASK))
  872. CORE_PIN17_PADCONFIG = ((val & (1<<3)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  873. digitalWriteFast(18, (val & (1<<4)));
  874. if (!(CORE_PIN18_DDRREG & CORE_PIN18_BITMASK))
  875. CORE_PIN18_PADCONFIG = ((val & (1<<4)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  876. digitalWriteFast(19, (val & (1<<5)));
  877. if (!(CORE_PIN19_DDRREG & CORE_PIN19_BITMASK))
  878. CORE_PIN19_PADCONFIG = ((val & (1<<5)) ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  879. return *this;
  880. }
  881. inline PORTCemulation & operator |= (int val) __attribute__((always_inline)) {
  882. if (val & (1<<0)) {
  883. digitalWriteFast(14, HIGH);
  884. if (!(CORE_PIN14_DDRREG & CORE_PIN14_BITMASK)) CORE_PIN14_CONFIG = CONFIG_PULLUP;
  885. }
  886. if (val & (1<<1)) {
  887. digitalWriteFast(15, HIGH);
  888. if (!(CORE_PIN15_DDRREG & CORE_PIN15_BITMASK)) CORE_PIN15_CONFIG = CONFIG_PULLUP;
  889. }
  890. if (val & (1<<2)) {
  891. digitalWriteFast(16, HIGH);
  892. if (!(CORE_PIN16_DDRREG & CORE_PIN16_BITMASK)) CORE_PIN16_CONFIG = CONFIG_PULLUP;
  893. }
  894. if (val & (1<<3)) {
  895. digitalWriteFast(17, HIGH);
  896. if (!(CORE_PIN17_DDRREG & CORE_PIN17_BITMASK)) CORE_PIN17_CONFIG = CONFIG_PULLUP;
  897. }
  898. if (val & (1<<4)) {
  899. digitalWriteFast(18, HIGH);
  900. if (!(CORE_PIN18_DDRREG & CORE_PIN18_BITMASK)) CORE_PIN18_CONFIG = CONFIG_PULLUP;
  901. }
  902. if (val & (1<<5)) {
  903. digitalWriteFast(19, HIGH);
  904. if (!(CORE_PIN19_DDRREG & CORE_PIN19_BITMASK)) CORE_PIN19_CONFIG = CONFIG_PULLUP;
  905. }
  906. return *this;
  907. }
  908. inline PORTCemulation & operator &= (int val) __attribute__((always_inline)) {
  909. if (!(val & (1<<0))) {
  910. digitalWriteFast(14, LOW);
  911. if (!(CORE_PIN14_DDRREG & CORE_PIN14_BITMASK)) CORE_PIN14_CONFIG = CONFIG_NOPULLUP;
  912. }
  913. if (!(val & (1<<1))) {
  914. digitalWriteFast(15, LOW);
  915. if (!(CORE_PIN15_DDRREG & CORE_PIN15_BITMASK)) CORE_PIN15_CONFIG = CONFIG_NOPULLUP;
  916. }
  917. if (!(val & (1<<2))) {
  918. digitalWriteFast(16, LOW);
  919. if (!(CORE_PIN16_DDRREG & CORE_PIN16_BITMASK)) CORE_PIN16_CONFIG = CONFIG_NOPULLUP;
  920. }
  921. if (!(val & (1<<3))) {
  922. digitalWriteFast(17, LOW);
  923. if (!(CORE_PIN17_DDRREG & CORE_PIN17_BITMASK)) CORE_PIN17_CONFIG = CONFIG_NOPULLUP;
  924. }
  925. if (!(val & (1<<4))) {
  926. digitalWriteFast(18, LOW);
  927. if (!(CORE_PIN18_DDRREG & CORE_PIN18_BITMASK)) CORE_PIN18_CONFIG = CONFIG_NOPULLUP;
  928. }
  929. if (!(val & (1<<5))) {
  930. digitalWriteFast(19, LOW);
  931. if (!(CORE_PIN19_DDRREG & CORE_PIN19_BITMASK)) CORE_PIN19_CONFIG = CONFIG_NOPULLUP;
  932. }
  933. return *this;
  934. }
  935. };
  936. extern PORTCemulation PORTC;
  937. class PINCemulation
  938. {
  939. public:
  940. inline int operator & (int val) const __attribute__((always_inline)) {
  941. int ret = 0;
  942. if ((val & (1<<0)) && digitalReadFast(14)) ret |= (1<<0);
  943. if ((val & (1<<1)) && digitalReadFast(15)) ret |= (1<<1);
  944. if ((val & (1<<2)) && digitalReadFast(16)) ret |= (1<<2);
  945. if ((val & (1<<3)) && digitalReadFast(17)) ret |= (1<<3);
  946. if ((val & (1<<4)) && digitalReadFast(18)) ret |= (1<<4);
  947. if ((val & (1<<5)) && digitalReadFast(19)) ret |= (1<<5);
  948. return ret;
  949. }
  950. operator int () const __attribute__((always_inline)) {
  951. int ret = 0;
  952. if (digitalReadFast(14)) ret |= (1<<0);
  953. if (digitalReadFast(15)) ret |= (1<<1);
  954. if (digitalReadFast(16)) ret |= (1<<2);
  955. if (digitalReadFast(17)) ret |= (1<<3);
  956. if (digitalReadFast(18)) ret |= (1<<4);
  957. if (digitalReadFast(19)) ret |= (1<<5);
  958. return ret;
  959. }
  960. };
  961. extern PINCemulation PINC;
  962. class DDRCemulation
  963. {
  964. public:
  965. inline DDRCemulation & operator = (int val) __attribute__((always_inline)) {
  966. if (val & (1<<0)) set0(); else clr0();
  967. if (val & (1<<1)) set1(); else clr1();
  968. if (val & (1<<2)) set2(); else clr2();
  969. if (val & (1<<3)) set3(); else clr3();
  970. if (val & (1<<4)) set4(); else clr4();
  971. if (val & (1<<5)) set5(); else clr5();
  972. return *this;
  973. }
  974. inline DDRCemulation & operator |= (int val) __attribute__((always_inline)) {
  975. if (val & (1<<0)) set0();
  976. if (val & (1<<1)) set1();
  977. if (val & (1<<2)) set2();
  978. if (val & (1<<3)) set3();
  979. if (val & (1<<4)) set4();
  980. if (val & (1<<5)) set5();
  981. return *this;
  982. }
  983. inline DDRCemulation & operator &= (int val) __attribute__((always_inline)) {
  984. if (!(val & (1<<0))) clr0();
  985. if (!(val & (1<<1))) clr1();
  986. if (!(val & (1<<2))) clr2();
  987. if (!(val & (1<<3))) clr3();
  988. if (!(val & (1<<4))) clr4();
  989. if (!(val & (1<<5))) clr5();
  990. return *this;
  991. }
  992. private:
  993. inline void set0() __attribute__((always_inline)) {
  994. GPIO_SETBIT_ATOMIC(&CORE_PIN14_DDRREG, CORE_PIN14_BITMASK);
  995. CORE_PIN14_CONFIG = 5 | 0x10;
  996. CORE_PIN14_PADCONFIG = CONFIG_PULLUP;
  997. }
  998. inline void set1() __attribute__((always_inline)) {
  999. GPIO_SETBIT_ATOMIC(&CORE_PIN15_DDRREG, CORE_PIN15_BITMASK);
  1000. CORE_PIN15_CONFIG = 5 | 0x10;
  1001. CORE_PIN15_PADCONFIG = CONFIG_PULLUP;
  1002. }
  1003. inline void set2() __attribute__((always_inline)) {
  1004. GPIO_SETBIT_ATOMIC(&CORE_PIN16_DDRREG, CORE_PIN16_BITMASK);
  1005. CORE_PIN16_CONFIG = 5 | 0x10;
  1006. CORE_PIN16_PADCONFIG = CONFIG_PULLUP;
  1007. }
  1008. inline void set3() __attribute__((always_inline)) {
  1009. GPIO_SETBIT_ATOMIC(&CORE_PIN17_DDRREG, CORE_PIN17_BITMASK);
  1010. CORE_PIN17_CONFIG = 5 | 0x10;
  1011. CORE_PIN17_PADCONFIG = CONFIG_PULLUP;
  1012. }
  1013. inline void set4() __attribute__((always_inline)) {
  1014. GPIO_SETBIT_ATOMIC(&CORE_PIN18_DDRREG, CORE_PIN18_BITMASK);
  1015. CORE_PIN18_CONFIG = 5 | 0x10;
  1016. CORE_PIN18_PADCONFIG = CONFIG_PULLUP;
  1017. }
  1018. inline void set5() __attribute__((always_inline)) {
  1019. GPIO_SETBIT_ATOMIC(&CORE_PIN19_DDRREG, CORE_PIN19_BITMASK);
  1020. CORE_PIN19_CONFIG = 5 | 0x10;
  1021. CORE_PIN19_PADCONFIG = CONFIG_PULLUP;
  1022. }
  1023. inline void clr0() __attribute__((always_inline)) {
  1024. CORE_PIN14_CONFIG = 5 | 0x10;
  1025. CORE_PIN14_PADCONFIG = ((CORE_PIN14_PORTREG & CORE_PIN14_BITMASK)
  1026. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  1027. GPIO_CLRBIT_ATOMIC(&CORE_PIN14_DDRREG, CORE_PIN14_BITMASK);
  1028. }
  1029. inline void clr1() __attribute__((always_inline)) {
  1030. CORE_PIN15_CONFIG = 5 | 0x10;
  1031. CORE_PIN15_PADCONFIG = ((CORE_PIN15_PORTREG & CORE_PIN15_BITMASK)
  1032. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  1033. GPIO_CLRBIT_ATOMIC(&CORE_PIN15_DDRREG, CORE_PIN15_BITMASK);
  1034. }
  1035. inline void clr2() __attribute__((always_inline)) {
  1036. CORE_PIN16_CONFIG = 5 | 0x10;
  1037. CORE_PIN16_PADCONFIG = ((CORE_PIN16_PORTREG & CORE_PIN16_BITMASK)
  1038. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  1039. GPIO_CLRBIT_ATOMIC(&CORE_PIN16_DDRREG, CORE_PIN16_BITMASK);
  1040. }
  1041. inline void clr3() __attribute__((always_inline)) {
  1042. CORE_PIN17_CONFIG = 5 | 0x10;
  1043. CORE_PIN17_PADCONFIG = ((CORE_PIN17_PORTREG & CORE_PIN17_BITMASK)
  1044. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  1045. GPIO_CLRBIT_ATOMIC(&CORE_PIN17_DDRREG, CORE_PIN17_BITMASK);
  1046. }
  1047. inline void clr4() __attribute__((always_inline)) {
  1048. CORE_PIN18_CONFIG = 5 | 0x10;
  1049. CORE_PIN18_PADCONFIG = ((CORE_PIN18_PORTREG & CORE_PIN18_BITMASK)
  1050. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  1051. GPIO_CLRBIT_ATOMIC(&CORE_PIN18_DDRREG, CORE_PIN18_BITMASK);
  1052. }
  1053. inline void clr5() __attribute__((always_inline)) {
  1054. CORE_PIN19_CONFIG = 5 | 0x10;
  1055. CORE_PIN19_PADCONFIG = ((CORE_PIN19_PORTREG & CORE_PIN19_BITMASK)
  1056. ? CONFIG_PULLUP : CONFIG_NOPULLUP);
  1057. GPIO_CLRBIT_ATOMIC(&CORE_PIN19_DDRREG, CORE_PIN19_BITMASK);
  1058. }
  1059. };
  1060. extern DDRCemulation DDRC;
  1061. #define PINB0 0
  1062. #define PINB1 1
  1063. #define PINB2 2
  1064. #define PINB3 3
  1065. #define PINB4 4
  1066. #define PINB5 5
  1067. #define PINB6 6
  1068. #define PINB7 7
  1069. #define DDB0 0
  1070. #define DDB1 1
  1071. #define DDB2 2
  1072. #define DDB3 3
  1073. #define DDB4 4
  1074. #define DDB5 5
  1075. #define DDB6 6
  1076. #define DDB7 7
  1077. #define PORTB0 0
  1078. #define PORTB1 1
  1079. #define PORTB2 2
  1080. #define PORTB3 3
  1081. #define PORTB4 4
  1082. #define PORTB5 5
  1083. #define PORTB6 6
  1084. #define PORTB7 7
  1085. #define PINC0 0
  1086. #define PINC1 1
  1087. #define PINC2 2
  1088. #define PINC3 3
  1089. #define PINC4 4
  1090. #define PINC5 5
  1091. #define PINC6 6
  1092. #define DDC0 0
  1093. #define DDC1 1
  1094. #define DDC2 2
  1095. #define DDC3 3
  1096. #define DDC4 4
  1097. #define DDC5 5
  1098. #define DDC6 6
  1099. #define PORTC0 0
  1100. #define PORTC1 1
  1101. #define PORTC2 2
  1102. #define PORTC3 3
  1103. #define PORTC4 4
  1104. #define PORTC5 5
  1105. #define PORTC6 6
  1106. #define PIND0 0
  1107. #define PIND1 1
  1108. #define PIND2 2
  1109. #define PIND3 3
  1110. #define PIND4 4
  1111. #define PIND5 5
  1112. #define PIND6 6
  1113. #define PIND7 7
  1114. #define DDD0 0
  1115. #define DDD1 1
  1116. #define DDD2 2
  1117. #define DDD3 3
  1118. #define DDD4 4
  1119. #define DDD5 5
  1120. #define DDD6 6
  1121. #define DDD7 7
  1122. #define PORTD0 0
  1123. #define PORTD1 1
  1124. #define PORTD2 2
  1125. #define PORTD3 3
  1126. #define PORTD4 4
  1127. #define PORTD5 5
  1128. #define PORTD6 6
  1129. #define PORTD7 7
  1130. #endif // __cplusplus
  1131. #endif