Teensy 4.1 core updated for C++20
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

1898 Zeilen
56KB

  1. /* Pin functions for the Teensy and Teensy++
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2008-2010 PJRC.COM, LLC
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. */
  23. #include <avr/io.h>
  24. #include <avr/pgmspace.h>
  25. #include <avr/sleep.h>
  26. #include "wiring_private.h"
  27. #include "pins_arduino.h"
  28. #include "usb_private.h"
  29. #include "core_pins.h"
  30. // this doubles the analog input speed
  31. #define USE_ADC_HIGH_SPEED
  32. #ifdef USE_ADC_HIGH_SPEED
  33. #define DEFAULT_ADCSRB 0x80 // ADHSM
  34. #define ADC_PRESCALE_ADJUST (-1)
  35. #else
  36. #define DEFAULT_ADCSRB 0
  37. #define ADC_PRESCALE_ADJUST 0
  38. #endif
  39. void _init_Teensyduino_internal_(void)
  40. {
  41. cli();
  42. CLKPR = 0x80;
  43. CLKPR = CPU_PRESCALER;
  44. // timer 0, fast pwm mode
  45. TCCR0A = (1<<WGM01) | (1<<WGM00);
  46. TCCR0B = (1<<CS01) | (1<<CS00); // div 64 prescaler
  47. sbi(TIMSK0, TOIE0);
  48. // timer 1, 8 bit phase correct pwm
  49. TCCR1A = (1<<WGM10);
  50. TCCR1B = (1<<CS11); // div 8 prescaler
  51. #if defined(__AVR_ATmega32U4__)
  52. // timer 3, 8 bit phase correct pwm
  53. TCCR3A = (1<<WGM30);
  54. TCCR3B = (1<<CS31); // div 8 prescaler
  55. // timer 4, 8 bit phase correct pwm
  56. TCCR4A = (1<<PWM4A);
  57. TCCR4B = (1<<CS42); // div 8 prescaler
  58. TCCR4C = (1<<PWM4D);
  59. TCCR4D = (1<<WGM40); // phase correct pwm
  60. TCCR4E = 0;
  61. // ADC
  62. ADCSRA = (1<<ADEN) | (ADC_PRESCALER + ADC_PRESCALE_ADJUST);
  63. ADCSRB = DEFAULT_ADCSRB;
  64. DIDR0 = 0;
  65. DIDR2 = 0;
  66. #endif
  67. #if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  68. // timer 2, 8 bit phase correct pwm
  69. TCCR2A = (1<<WGM20);
  70. TCCR2B = (1<<CS21); // div 8 prescaler
  71. // timer 3, 8 bit phase correct pwm
  72. TCCR3A = (1<<WGM30);
  73. TCCR3B = (1<<CS31); // div 8 prescaler
  74. // ADC
  75. ADCSRA = (1<<ADEN) | (ADC_PRESCALER + ADC_PRESCALE_ADJUST);
  76. ADCSRB = DEFAULT_ADCSRB;
  77. DIDR0 = 0;
  78. #endif
  79. // initialize USB
  80. usb_init();
  81. sei();
  82. }
  83. void _analogWrite(uint8_t pin, int val)
  84. {
  85. pinMode(pin, OUTPUT);
  86. switch (pin) {
  87. case CORE_OC0B_PIN:
  88. if (val == 0) {
  89. CORE_PORTREG(CORE_OC0B_PIN) &= ~CORE_BITMASK(CORE_OC0B_PIN);
  90. cbi(TCCR0A, COM0B1);
  91. } else {
  92. OCR0B = val;
  93. sbi(TCCR0A, COM0B1);
  94. }
  95. break;
  96. case CORE_OC1A_PIN: //TIMER1A:
  97. OCR1A = val;
  98. sbi(TCCR1A, COM1A1);
  99. break;
  100. case CORE_OC1B_PIN: //TIMER1B:
  101. OCR1B = val;
  102. sbi(TCCR1A, COM1B1);
  103. break;
  104. case CORE_OC1C_PIN: //TIMER1C:
  105. OCR1C = val;
  106. sbi(TCCR1A, COM1C1);
  107. break;
  108. #if defined(__AVR_ATmega32U4__)
  109. case CORE_OC3A_PIN: //TIMER3A:
  110. OCR3A = val;
  111. sbi(TCCR3A, COM3A1);
  112. break;
  113. case CORE_OC4A_PIN: //TIMER4A
  114. OCR4A = val;
  115. sbi(TCCR4A, COM4A1);
  116. break;
  117. case CORE_OC4D_PIN: //TIMER4D
  118. OCR4D = val;
  119. sbi(TCCR4C, COM4D1);
  120. break;
  121. #endif
  122. #if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  123. case CORE_OC2A_PIN: //TIMER2A:
  124. OCR2A = val;
  125. sbi(TCCR2A, COM2A1);
  126. break;
  127. case CORE_OC2B_PIN: //TIMER2B:
  128. OCR2B = val;
  129. sbi(TCCR2A, COM2B1);
  130. break;
  131. case CORE_OC3A_PIN: //TIMER3A:
  132. OCR3A = val;
  133. sbi(TCCR3A, COM3A1);
  134. break;
  135. case CORE_OC3B_PIN: //TIMER3B:
  136. OCR3B = val;
  137. sbi(TCCR3A, COM3B1);
  138. break;
  139. case CORE_OC3C_PIN: //TIMER3C:
  140. OCR3C = val;
  141. sbi(TCCR3A, COM3C1);
  142. break;
  143. #endif
  144. default:
  145. if (val < 128) {
  146. digitalWrite(pin, LOW);
  147. } else {
  148. digitalWrite(pin, HIGH);
  149. }
  150. }
  151. }
  152. #if defined(__AVR_ATmega32U4__)
  153. uint8_t w_analog_reference = 0x40;
  154. static const uint8_t PROGMEM adc_mapping[] = {
  155. // 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8
  156. 0, 1, 4, 5, 6, 7, 13, 12, 11, 10, 9, 8, 10, 11, 12, 13, 7, 6, 5, 4, 1, 0, 8
  157. };
  158. int analogRead(uint8_t pin)
  159. {
  160. uint8_t low, high, adc;
  161. if (pin >= sizeof(adc_mapping)) return 0;
  162. adc = pgm_read_byte(adc_mapping + pin);
  163. if (adc < 8) {
  164. DIDR0 |= (1 << adc);
  165. //DDRF &= ~(1 << adc);
  166. //PORTF &= ~(1 << adc);
  167. ADCSRB = DEFAULT_ADCSRB;
  168. ADMUX = w_analog_reference | adc;
  169. } else {
  170. adc -= 8;
  171. DIDR2 |= (1 << adc);
  172. ADCSRB = DEFAULT_ADCSRB | (1<<MUX5);
  173. ADMUX = w_analog_reference | adc;
  174. }
  175. ADCSRA |= (1<<ADSC);
  176. while (ADCSRA & (1<<ADSC)) ;
  177. low = ADCL;
  178. high = ADCH;
  179. return (high << 8) | low;
  180. }
  181. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  182. uint8_t w_analog_reference = 0x40;
  183. int analogRead(uint8_t pin)
  184. {
  185. uint8_t low, high;
  186. if (pin >= PIN_F0 && pin <= PIN_F7) pin -= PIN_F0;
  187. if (pin < 8) {
  188. DIDR0 |= (1 << pin);
  189. //DDRF &= ~(1 << pin);
  190. //PORTF &= ~(1 << pin);
  191. }
  192. ADMUX = w_analog_reference | (pin & 0x1F);
  193. ADCSRA |= (1<<ADSC);
  194. while (ADCSRA & (1<<ADSC)) ;
  195. low = ADCL;
  196. high = ADCH;
  197. return (high << 8) | low;
  198. }
  199. #elif defined(__AVR_AT90USB162__)
  200. int analogRead(uint8_t pin)
  201. {
  202. return 0;
  203. }
  204. #endif
  205. void _pinMode(uint8_t pin, uint8_t mode)
  206. {
  207. if (mode == OUTPUT) {
  208. _pinMode_output(pin);
  209. } else if (mode == INPUT_PULLUP) {
  210. _pinMode_input_pullup(pin);
  211. } else {
  212. _pinMode_input(pin);
  213. }
  214. }
  215. #define PIN_REG_AND_MASK_LOOKUP(pin, reg, mask) \
  216. asm volatile( \
  217. "lsl %2" "\n\t" \
  218. "add %A3, %2" "\n\t" \
  219. "adc %B3, __zero_reg__" "\n\n" \
  220. "lpm %1, Z+" "\n\t" \
  221. "lpm %A0, Z" "\n\t" \
  222. "ldi %B0, 0" "\n" \
  223. : "=z" (reg), "=r" (mask), "+r" (pin) \
  224. : "z" (digital_pin_table_PGM), "2" (pin))
  225. void _pinMode_output(uint8_t pin)
  226. {
  227. volatile uint8_t *reg;
  228. uint8_t mask, status;
  229. if (pin >= CORE_NUM_TOTAL_PINS) return;
  230. PIN_REG_AND_MASK_LOOKUP(pin, reg, mask);
  231. status = SREG;
  232. cli();
  233. *(reg + 1) |= mask;
  234. SREG = status;
  235. }
  236. #if defined(__AVR_ATmega32U4__)
  237. static const uint8_t PROGMEM didr_table_PGM[] = {
  238. (int)&DIDR2, ~0x02,
  239. (int)&DIDR2, ~0x04,
  240. (int)&DIDR2, ~0x08,
  241. (int)&DIDR2, ~0x10,
  242. (int)&DIDR2, ~0x20,
  243. (int)&DIDR0, 0x7F, // ~0x80,
  244. (int)&DIDR0, ~0x40,
  245. (int)&DIDR0, ~0x20,
  246. (int)&DIDR0, ~0x10,
  247. (int)&DIDR0, ~0x02,
  248. (int)&DIDR0, ~0x01,
  249. (int)&DIDR2, ~0x01
  250. };
  251. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  252. static const uint8_t PROGMEM didr_table_PGM[] = {
  253. (int)&DIDR0, ~0x01,
  254. (int)&DIDR0, ~0x02,
  255. (int)&DIDR0, ~0x04,
  256. (int)&DIDR0, ~0x08,
  257. (int)&DIDR0, ~0x10,
  258. (int)&DIDR0, ~0x20,
  259. (int)&DIDR0, ~0x40,
  260. (int)&DIDR0, 0x7F // ~0x80
  261. };
  262. #endif
  263. #define PIN_DIDR_AND_MASK_LOOKUP(pin, didreg, didmask) \
  264. asm volatile( \
  265. "lsl %3" "\n\t" \
  266. "add %A2, %3" "\n\t" \
  267. "adc %B2, __zero_reg__" "\n\n" \
  268. "lpm %A0, Z+" "\n\t" \
  269. "ldi %B0, 0" "\n\t" \
  270. "lpm %1, Z+" "\n\t" \
  271. : "=x" (didreg), "=r" (didmask) \
  272. : "z" (didr_table_PGM), "r" (pin))
  273. void _pinMode_input(uint8_t pin)
  274. {
  275. volatile uint8_t *reg, *didr=0;
  276. uint8_t mask, didrmask=0xFF, status;
  277. if (pin >= CORE_NUM_TOTAL_PINS) return;
  278. #if defined(__AVR_ATmega32U4__)
  279. if (pin >= 11 && pin <= 22) {
  280. PIN_DIDR_AND_MASK_LOOKUP((uint8_t)(pin - 11), didr, didrmask);
  281. }
  282. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  283. if (pin >= PIN_F0 && pin <= PIN_F7) {
  284. PIN_DIDR_AND_MASK_LOOKUP((uint8_t)(pin - PIN_F0), didr, didrmask);
  285. }
  286. #endif
  287. PIN_REG_AND_MASK_LOOKUP(pin, reg, mask);
  288. status = SREG;
  289. cli();
  290. *(reg + 1) &= ~mask;
  291. *(reg + 2) &= ~mask;
  292. *didr &= didrmask;
  293. SREG = status;
  294. }
  295. void _pinMode_input_pullup(uint8_t pin)
  296. {
  297. volatile uint8_t *reg, *didr=0;
  298. uint8_t mask, didrmask=0xFF, status;
  299. if (pin >= CORE_NUM_TOTAL_PINS) return;
  300. #if defined(__AVR_ATmega32U4__)
  301. if (pin >= 11 && pin <= 22) {
  302. PIN_DIDR_AND_MASK_LOOKUP((uint8_t)(pin - 11), didr, didrmask);
  303. }
  304. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  305. if (pin >= PIN_F0 && pin <= PIN_F7) {
  306. PIN_DIDR_AND_MASK_LOOKUP((uint8_t)(pin - PIN_F0), didr, didrmask);
  307. }
  308. #endif
  309. PIN_REG_AND_MASK_LOOKUP(pin, reg, mask);
  310. status = SREG;
  311. cli();
  312. *(reg + 1) &= ~mask;
  313. *(reg + 2) |= mask;
  314. *didr &= didrmask;
  315. SREG = status;
  316. }
  317. void _digitalWrite(void) __attribute__((naked));
  318. void _digitalWrite_HIGH(void) __attribute__((naked));
  319. void _digitalWrite_LOW(void) __attribute__((naked));
  320. void _digitalWrite_bailout(void);
  321. void _digitalWrite_HIGH_TABLE(void) __attribute__((naked));
  322. void _digitalWrite_LOW_TABLE(void) __attribute__((naked));
  323. void _digitalWrite_OC0B(void) __attribute__((naked));
  324. void _digitalWrite_OC1A(void) __attribute__((naked));
  325. void _digitalWrite_OC1B(void) __attribute__((naked));
  326. void _digitalWrite_OC1C(void) __attribute__((naked));
  327. void _digitalWrite_OC2A(void) __attribute__((naked));
  328. void _digitalWrite_OC2B(void) __attribute__((naked));
  329. void _digitalWrite_OC3A(void) __attribute__((naked));
  330. void _digitalWrite_OC3B(void) __attribute__((naked));
  331. void _digitalWrite_OC3C(void) __attribute__((naked));
  332. void _digitalWrite_OC4A(void) __attribute__((naked));
  333. void _digitalWrite_OC4D(void) __attribute__((naked));
  334. void _digitalWrite(void)
  335. {
  336. asm volatile(
  337. "tst r0" "\n\t"
  338. "breq _digitalWrite_LOW" "\n\t"
  339. "rjmp _digitalWrite_HIGH" "\n\t"
  340. );
  341. }
  342. void _digitalWrite_HIGH(void)
  343. {
  344. asm volatile (
  345. #if !defined(DIGITAL_WRITE_RISKY_OMIT_OVERFLOW_CHECK)
  346. "cpi r30, %0" "\n\t"
  347. "brsh _digitalWrite_bailout" "\n\t"
  348. #endif
  349. "lsl r30" "\n\t"
  350. //"clr r31" "\n\t"
  351. "subi r30, lo8(-(pm(_digitalWrite_HIGH_TABLE)))" "\n\t"
  352. "sbci r31, hi8(-(pm(_digitalWrite_HIGH_TABLE)))" "\n\t"
  353. "ijmp" "\n\t"
  354. : : "M" (CORE_NUM_TOTAL_PINS)
  355. );
  356. }
  357. void _digitalWrite_LOW(void)
  358. {
  359. asm volatile (
  360. #if !defined(DIGITAL_WRITE_RISKY_OMIT_OVERFLOW_CHECK)
  361. "cpi r30, %0" "\n\t"
  362. "brsh _digitalWrite_bailout" "\n\t"
  363. #endif
  364. "lsl r30" "\n\t"
  365. //"clr r31" "\n\t"
  366. "subi r30, lo8(-(pm(_digitalWrite_LOW_TABLE)))" "\n\t"
  367. "sbci r31, hi8(-(pm(_digitalWrite_LOW_TABLE)))" "\n\t"
  368. "ijmp" "\n\t"
  369. : : "M" (CORE_NUM_TOTAL_PINS)
  370. );
  371. }
  372. void _digitalWrite_bailout(void) {}
  373. #if defined(__AVR_ATmega32U4__)
  374. void _digitalWrite_HIGH_TABLE(void)
  375. {
  376. asm volatile (
  377. "sbi %0, %1" "\n\t" // pin 0
  378. "ret" "\n\t"
  379. "sbi %2, %3" "\n\t" // pin 1
  380. "ret" "\n\t"
  381. "sbi %4, %5" "\n\t" // pin 2
  382. "ret" "\n\t"
  383. "sbi %6, %7" "\n\t" // pin 3
  384. "ret" "\n\t"
  385. "sbi %8, %9" "\n\t" // pin 4
  386. "rjmp _digitalWrite_OC1C" "\n\t"
  387. :: "I" (_SFR_IO_ADDR(CORE_PIN0_PORTREG)), "I" (CORE_PIN0_BIT),
  388. "I" (_SFR_IO_ADDR(CORE_PIN1_PORTREG)), "I" (CORE_PIN1_BIT),
  389. "I" (_SFR_IO_ADDR(CORE_PIN2_PORTREG)), "I" (CORE_PIN2_BIT),
  390. "I" (_SFR_IO_ADDR(CORE_PIN3_PORTREG)), "I" (CORE_PIN3_BIT),
  391. "I" (_SFR_IO_ADDR(CORE_PIN4_PORTREG)), "I" (CORE_PIN4_BIT)
  392. );
  393. asm volatile (
  394. "sbi %0, %1" "\n\t" // pin 5
  395. "rjmp _digitalWrite_OC0B" "\n\t"
  396. "sbi %2, %3" "\n\t" // pin 6
  397. "ret" "\n\t"
  398. "sbi %4, %5" "\n\t" // pin 7
  399. "ret" "\n\t"
  400. "sbi %6, %7" "\n\t" // pin 8
  401. "ret" "\n\t"
  402. "sbi %8, %9" "\n\t" // pin 9
  403. "rjmp _digitalWrite_OC3A" "\n\t"
  404. :: "I" (_SFR_IO_ADDR(CORE_PIN5_PORTREG)), "I" (CORE_PIN5_BIT),
  405. "I" (_SFR_IO_ADDR(CORE_PIN6_PORTREG)), "I" (CORE_PIN6_BIT),
  406. "I" (_SFR_IO_ADDR(CORE_PIN7_PORTREG)), "I" (CORE_PIN7_BIT),
  407. "I" (_SFR_IO_ADDR(CORE_PIN8_PORTREG)), "I" (CORE_PIN8_BIT),
  408. "I" (_SFR_IO_ADDR(CORE_PIN9_PORTREG)), "I" (CORE_PIN9_BIT)
  409. );
  410. asm volatile (
  411. "sbi %0, %1" "\n\t" // pin 10
  412. "rjmp _digitalWrite_OC4A" "\n\t"
  413. "sbi %2, %3" "\n\t" // pin 11
  414. "ret" "\n\t"
  415. "sbi %4, %5" "\n\t" // pin 12
  416. "rjmp _digitalWrite_OC4D" "\n\t"
  417. "sbi %6, %7" "\n\t" // pin 13
  418. "ret" "\n\t"
  419. "sbi %8, %9" "\n\t" // pin 14
  420. "rjmp _digitalWrite_OC1A" "\n\t"
  421. :: "I" (_SFR_IO_ADDR(CORE_PIN10_PORTREG)), "I" (CORE_PIN10_BIT),
  422. "I" (_SFR_IO_ADDR(CORE_PIN11_PORTREG)), "I" (CORE_PIN11_BIT),
  423. "I" (_SFR_IO_ADDR(CORE_PIN12_PORTREG)), "I" (CORE_PIN12_BIT),
  424. "I" (_SFR_IO_ADDR(CORE_PIN13_PORTREG)), "I" (CORE_PIN13_BIT),
  425. "I" (_SFR_IO_ADDR(CORE_PIN14_PORTREG)), "I" (CORE_PIN14_BIT)
  426. );
  427. asm volatile (
  428. "sbi %0, %1" "\n\t" // pin 15
  429. "rjmp _digitalWrite_OC1B" "\n\t"
  430. "sbi %2, %3" "\n\t" // pin 16
  431. "ret" "\n\t"
  432. "sbi %4, %5" "\n\t" // pin 17
  433. "ret" "\n\t"
  434. "sbi %6, %7" "\n\t" // pin 18
  435. "ret" "\n\t"
  436. "sbi %8, %9" "\n\t" // pin 19
  437. "ret" "\n\t"
  438. :: "I" (_SFR_IO_ADDR(CORE_PIN15_PORTREG)), "I" (CORE_PIN15_BIT),
  439. "I" (_SFR_IO_ADDR(CORE_PIN16_PORTREG)), "I" (CORE_PIN16_BIT),
  440. "I" (_SFR_IO_ADDR(CORE_PIN17_PORTREG)), "I" (CORE_PIN17_BIT),
  441. "I" (_SFR_IO_ADDR(CORE_PIN18_PORTREG)), "I" (CORE_PIN18_BIT),
  442. "I" (_SFR_IO_ADDR(CORE_PIN19_PORTREG)), "I" (CORE_PIN19_BIT)
  443. );
  444. asm volatile (
  445. "sbi %0, %1" "\n\t" // pin 20
  446. "ret" "\n\t"
  447. "sbi %2, %3" "\n\t" // pin 21
  448. "ret" "\n\t"
  449. "sbi %4, %5" "\n\t" // pin 22
  450. "ret" "\n\t"
  451. "sbi %6, %7" "\n\t" // pin 23
  452. "ret" "\n\t"
  453. "sbi %8, %9" "\n\t" // pin 24
  454. "ret" "\n\t"
  455. :: "I" (_SFR_IO_ADDR(CORE_PIN20_PORTREG)), "I" (CORE_PIN20_BIT),
  456. "I" (_SFR_IO_ADDR(CORE_PIN21_PORTREG)), "I" (CORE_PIN21_BIT),
  457. "I" (_SFR_IO_ADDR(CORE_PIN22_PORTREG)), "I" (CORE_PIN22_BIT),
  458. "I" (_SFR_IO_ADDR(CORE_PIN23_PORTREG)), "I" (CORE_PIN23_BIT),
  459. "I" (_SFR_IO_ADDR(CORE_PIN24_PORTREG)), "I" (CORE_PIN24_BIT)
  460. );
  461. }
  462. void _digitalWrite_LOW_TABLE(void)
  463. {
  464. asm volatile (
  465. "cbi %0, %1" "\n\t" // pin 0
  466. "ret" "\n\t"
  467. "cbi %2, %3" "\n\t" // pin 1
  468. "ret" "\n\t"
  469. "cbi %4, %5" "\n\t" // pin 2
  470. "ret" "\n\t"
  471. "cbi %6, %7" "\n\t" // pin 3
  472. "ret" "\n\t"
  473. "cbi %8, %9" "\n\t" // pin 4
  474. "rjmp _digitalWrite_OC1C" "\n\t"
  475. :: "I" (_SFR_IO_ADDR(CORE_PIN0_PORTREG)), "I" (CORE_PIN0_BIT),
  476. "I" (_SFR_IO_ADDR(CORE_PIN1_PORTREG)), "I" (CORE_PIN1_BIT),
  477. "I" (_SFR_IO_ADDR(CORE_PIN2_PORTREG)), "I" (CORE_PIN2_BIT),
  478. "I" (_SFR_IO_ADDR(CORE_PIN3_PORTREG)), "I" (CORE_PIN3_BIT),
  479. "I" (_SFR_IO_ADDR(CORE_PIN4_PORTREG)), "I" (CORE_PIN4_BIT)
  480. );
  481. asm volatile (
  482. "cbi %0, %1" "\n\t" // pin 5
  483. "rjmp _digitalWrite_OC0B" "\n\t"
  484. "cbi %2, %3" "\n\t" // pin 6
  485. "ret" "\n\t"
  486. "cbi %4, %5" "\n\t" // pin 7
  487. "ret" "\n\t"
  488. "cbi %6, %7" "\n\t" // pin 8
  489. "ret" "\n\t"
  490. "cbi %8, %9" "\n\t" // pin 9
  491. "rjmp _digitalWrite_OC3A" "\n\t"
  492. :: "I" (_SFR_IO_ADDR(CORE_PIN5_PORTREG)), "I" (CORE_PIN5_BIT),
  493. "I" (_SFR_IO_ADDR(CORE_PIN6_PORTREG)), "I" (CORE_PIN6_BIT),
  494. "I" (_SFR_IO_ADDR(CORE_PIN7_PORTREG)), "I" (CORE_PIN7_BIT),
  495. "I" (_SFR_IO_ADDR(CORE_PIN8_PORTREG)), "I" (CORE_PIN8_BIT),
  496. "I" (_SFR_IO_ADDR(CORE_PIN9_PORTREG)), "I" (CORE_PIN9_BIT)
  497. );
  498. asm volatile (
  499. "cbi %0, %1" "\n\t" // pin 10
  500. "rjmp _digitalWrite_OC4A" "\n\t"
  501. "cbi %2, %3" "\n\t" // pin 11
  502. "ret" "\n\t"
  503. "cbi %4, %5" "\n\t" // pin 12
  504. "rjmp _digitalWrite_OC4D" "\n\t"
  505. "cbi %6, %7" "\n\t" // pin 13
  506. "ret" "\n\t"
  507. "cbi %8, %9" "\n\t" // pin 14
  508. "rjmp _digitalWrite_OC1A" "\n\t"
  509. :: "I" (_SFR_IO_ADDR(CORE_PIN10_PORTREG)), "I" (CORE_PIN10_BIT),
  510. "I" (_SFR_IO_ADDR(CORE_PIN11_PORTREG)), "I" (CORE_PIN11_BIT),
  511. "I" (_SFR_IO_ADDR(CORE_PIN12_PORTREG)), "I" (CORE_PIN12_BIT),
  512. "I" (_SFR_IO_ADDR(CORE_PIN13_PORTREG)), "I" (CORE_PIN13_BIT),
  513. "I" (_SFR_IO_ADDR(CORE_PIN14_PORTREG)), "I" (CORE_PIN14_BIT)
  514. );
  515. asm volatile (
  516. "cbi %0, %1" "\n\t" // pin 15
  517. "rjmp _digitalWrite_OC1B" "\n\t"
  518. "cbi %2, %3" "\n\t" // pin 16
  519. "ret" "\n\t"
  520. "cbi %4, %5" "\n\t" // pin 17
  521. "ret" "\n\t"
  522. "cbi %6, %7" "\n\t" // pin 18
  523. "ret" "\n\t"
  524. "cbi %8, %9" "\n\t" // pin 19
  525. "ret" "\n\t"
  526. :: "I" (_SFR_IO_ADDR(CORE_PIN15_PORTREG)), "I" (CORE_PIN15_BIT),
  527. "I" (_SFR_IO_ADDR(CORE_PIN16_PORTREG)), "I" (CORE_PIN16_BIT),
  528. "I" (_SFR_IO_ADDR(CORE_PIN17_PORTREG)), "I" (CORE_PIN17_BIT),
  529. "I" (_SFR_IO_ADDR(CORE_PIN18_PORTREG)), "I" (CORE_PIN18_BIT),
  530. "I" (_SFR_IO_ADDR(CORE_PIN19_PORTREG)), "I" (CORE_PIN19_BIT)
  531. );
  532. asm volatile (
  533. "cbi %0, %1" "\n\t" // pin 20
  534. "ret" "\n\t"
  535. "cbi %2, %3" "\n\t" // pin 21
  536. "ret" "\n\t"
  537. "cbi %4, %5" "\n\t" // pin 22
  538. "ret" "\n\t"
  539. "cbi %6, %7" "\n\t" // pin 23
  540. "ret" "\n\t"
  541. "cbi %8, %9" "\n\t" // pin 24
  542. "ret" "\n\t"
  543. :: "I" (_SFR_IO_ADDR(CORE_PIN20_PORTREG)), "I" (CORE_PIN20_BIT),
  544. "I" (_SFR_IO_ADDR(CORE_PIN21_PORTREG)), "I" (CORE_PIN21_BIT),
  545. "I" (_SFR_IO_ADDR(CORE_PIN22_PORTREG)), "I" (CORE_PIN22_BIT),
  546. "I" (_SFR_IO_ADDR(CORE_PIN23_PORTREG)), "I" (CORE_PIN23_BIT),
  547. "I" (_SFR_IO_ADDR(CORE_PIN24_PORTREG)), "I" (CORE_PIN24_BIT)
  548. );
  549. }
  550. #elif defined(__AVR_AT90USB162__)
  551. void _digitalWrite_HIGH_TABLE(void)
  552. {
  553. asm volatile (
  554. "sbi %0, %1" "\n\t" // pin 0
  555. "rjmp _digitalWrite_OC0B" "\n\t"
  556. "sbi %2, %3" "\n\t" // pin 1
  557. "ret" "\n\t"
  558. "sbi %4, %5" "\n\t" // pin 2
  559. "ret" "\n\t"
  560. "sbi %6, %7" "\n\t" // pin 3
  561. "ret" "\n\t"
  562. "sbi %8, %9" "\n\t" // pin 4
  563. "ret" "\n\t"
  564. :: "I" (_SFR_IO_ADDR(CORE_PIN0_PORTREG)), "I" (CORE_PIN0_BIT),
  565. "I" (_SFR_IO_ADDR(CORE_PIN1_PORTREG)), "I" (CORE_PIN1_BIT),
  566. "I" (_SFR_IO_ADDR(CORE_PIN2_PORTREG)), "I" (CORE_PIN2_BIT),
  567. "I" (_SFR_IO_ADDR(CORE_PIN3_PORTREG)), "I" (CORE_PIN3_BIT),
  568. "I" (_SFR_IO_ADDR(CORE_PIN4_PORTREG)), "I" (CORE_PIN4_BIT)
  569. );
  570. asm volatile (
  571. "sbi %0, %1" "\n\t" // pin 5
  572. "ret" "\n\t"
  573. "sbi %2, %3" "\n\t" // pin 6
  574. "ret" "\n\t"
  575. "sbi %4, %5" "\n\t" // pin 7
  576. "ret" "\n\t"
  577. "sbi %6, %7" "\n\t" // pin 8
  578. "ret" "\n\t"
  579. "sbi %8, %9" "\n\t" // pin 9
  580. "ret" "\n\t"
  581. :: "I" (_SFR_IO_ADDR(CORE_PIN5_PORTREG)), "I" (CORE_PIN5_BIT),
  582. "I" (_SFR_IO_ADDR(CORE_PIN6_PORTREG)), "I" (CORE_PIN6_BIT),
  583. "I" (_SFR_IO_ADDR(CORE_PIN7_PORTREG)), "I" (CORE_PIN7_BIT),
  584. "I" (_SFR_IO_ADDR(CORE_PIN8_PORTREG)), "I" (CORE_PIN8_BIT),
  585. "I" (_SFR_IO_ADDR(CORE_PIN9_PORTREG)), "I" (CORE_PIN9_BIT)
  586. );
  587. asm volatile (
  588. "sbi %0, %1" "\n\t" // pin 10
  589. "ret" "\n\t"
  590. "sbi %2, %3" "\n\t" // pin 11
  591. "ret" "\n\t"
  592. "sbi %4, %5" "\n\t" // pin 12
  593. "ret" "\n\t"
  594. "sbi %6, %7" "\n\t" // pin 13
  595. "ret" "\n\t"
  596. "sbi %8, %9" "\n\t" // pin 14
  597. "ret" "\n\t"
  598. :: "I" (_SFR_IO_ADDR(CORE_PIN10_PORTREG)), "I" (CORE_PIN10_BIT),
  599. "I" (_SFR_IO_ADDR(CORE_PIN11_PORTREG)), "I" (CORE_PIN11_BIT),
  600. "I" (_SFR_IO_ADDR(CORE_PIN12_PORTREG)), "I" (CORE_PIN12_BIT),
  601. "I" (_SFR_IO_ADDR(CORE_PIN13_PORTREG)), "I" (CORE_PIN13_BIT),
  602. "I" (_SFR_IO_ADDR(CORE_PIN14_PORTREG)), "I" (CORE_PIN14_BIT)
  603. );
  604. asm volatile (
  605. "sbi %0, %1" "\n\t" // pin 15
  606. "rjmp _digitalWrite_OC1C" "\n\t"
  607. "sbi %2, %3" "\n\t" // pin 16
  608. "ret" "\n\t"
  609. "sbi %4, %5" "\n\t" // pin 17
  610. "rjmp _digitalWrite_OC1A" "\n\t"
  611. "sbi %6, %7" "\n\t" // pin 18
  612. "rjmp _digitalWrite_OC1B" "\n\t"
  613. "sbi %8, %9" "\n\t" // pin 19
  614. "ret" "\n\t"
  615. "sbi %10, %11" "\n\t" // pin 20
  616. "ret" "\n\t"
  617. :: "I" (_SFR_IO_ADDR(CORE_PIN15_PORTREG)), "I" (CORE_PIN15_BIT),
  618. "I" (_SFR_IO_ADDR(CORE_PIN16_PORTREG)), "I" (CORE_PIN16_BIT),
  619. "I" (_SFR_IO_ADDR(CORE_PIN17_PORTREG)), "I" (CORE_PIN17_BIT),
  620. "I" (_SFR_IO_ADDR(CORE_PIN18_PORTREG)), "I" (CORE_PIN18_BIT),
  621. "I" (_SFR_IO_ADDR(CORE_PIN19_PORTREG)), "I" (CORE_PIN19_BIT),
  622. "I" (_SFR_IO_ADDR(CORE_PIN20_PORTREG)), "I" (CORE_PIN20_BIT)
  623. );
  624. }
  625. void _digitalWrite_LOW_TABLE(void)
  626. {
  627. asm volatile (
  628. "cbi %0, %1" "\n\t" // pin 0
  629. "rjmp _digitalWrite_OC0B" "\n\t"
  630. "cbi %2, %3" "\n\t" // pin 1
  631. "ret" "\n\t"
  632. "cbi %4, %5" "\n\t" // pin 2
  633. "ret" "\n\t"
  634. "cbi %6, %7" "\n\t" // pin 3
  635. "ret" "\n\t"
  636. "cbi %8, %9" "\n\t" // pin 4
  637. "ret" "\n\t"
  638. :: "I" (_SFR_IO_ADDR(CORE_PIN0_PORTREG)), "I" (CORE_PIN0_BIT),
  639. "I" (_SFR_IO_ADDR(CORE_PIN1_PORTREG)), "I" (CORE_PIN1_BIT),
  640. "I" (_SFR_IO_ADDR(CORE_PIN2_PORTREG)), "I" (CORE_PIN2_BIT),
  641. "I" (_SFR_IO_ADDR(CORE_PIN3_PORTREG)), "I" (CORE_PIN3_BIT),
  642. "I" (_SFR_IO_ADDR(CORE_PIN4_PORTREG)), "I" (CORE_PIN4_BIT)
  643. );
  644. asm volatile (
  645. "cbi %0, %1" "\n\t" // pin 5
  646. "ret" "\n\t"
  647. "cbi %2, %3" "\n\t" // pin 6
  648. "ret" "\n\t"
  649. "cbi %4, %5" "\n\t" // pin 7
  650. "ret" "\n\t"
  651. "cbi %6, %7" "\n\t" // pin 8
  652. "ret" "\n\t"
  653. "cbi %8, %9" "\n\t" // pin 9
  654. "ret" "\n\t"
  655. :: "I" (_SFR_IO_ADDR(CORE_PIN5_PORTREG)), "I" (CORE_PIN5_BIT),
  656. "I" (_SFR_IO_ADDR(CORE_PIN6_PORTREG)), "I" (CORE_PIN6_BIT),
  657. "I" (_SFR_IO_ADDR(CORE_PIN7_PORTREG)), "I" (CORE_PIN7_BIT),
  658. "I" (_SFR_IO_ADDR(CORE_PIN8_PORTREG)), "I" (CORE_PIN8_BIT),
  659. "I" (_SFR_IO_ADDR(CORE_PIN9_PORTREG)), "I" (CORE_PIN9_BIT)
  660. );
  661. asm volatile (
  662. "cbi %0, %1" "\n\t" // pin 10
  663. "ret" "\n\t"
  664. "cbi %2, %3" "\n\t" // pin 11
  665. "ret" "\n\t"
  666. "cbi %4, %5" "\n\t" // pin 12
  667. "ret" "\n\t"
  668. "cbi %6, %7" "\n\t" // pin 13
  669. "ret" "\n\t"
  670. "cbi %8, %9" "\n\t" // pin 14
  671. "ret" "\n\t"
  672. :: "I" (_SFR_IO_ADDR(CORE_PIN10_PORTREG)), "I" (CORE_PIN10_BIT),
  673. "I" (_SFR_IO_ADDR(CORE_PIN11_PORTREG)), "I" (CORE_PIN11_BIT),
  674. "I" (_SFR_IO_ADDR(CORE_PIN12_PORTREG)), "I" (CORE_PIN12_BIT),
  675. "I" (_SFR_IO_ADDR(CORE_PIN13_PORTREG)), "I" (CORE_PIN13_BIT),
  676. "I" (_SFR_IO_ADDR(CORE_PIN14_PORTREG)), "I" (CORE_PIN14_BIT)
  677. );
  678. asm volatile (
  679. "cbi %0, %1" "\n\t" // pin 15
  680. "rjmp _digitalWrite_OC1C" "\n\t"
  681. "cbi %2, %3" "\n\t" // pin 16
  682. "ret" "\n\t"
  683. "cbi %4, %5" "\n\t" // pin 17
  684. "rjmp _digitalWrite_OC1A" "\n\t"
  685. "cbi %6, %7" "\n\t" // pin 18
  686. "rjmp _digitalWrite_OC1B" "\n\t"
  687. "cbi %8, %9" "\n\t" // pin 19
  688. "ret" "\n\t"
  689. "cbi %10, %11" "\n\t" // pin 20
  690. "ret" "\n\t"
  691. :: "I" (_SFR_IO_ADDR(CORE_PIN15_PORTREG)), "I" (CORE_PIN15_BIT),
  692. "I" (_SFR_IO_ADDR(CORE_PIN16_PORTREG)), "I" (CORE_PIN16_BIT),
  693. "I" (_SFR_IO_ADDR(CORE_PIN17_PORTREG)), "I" (CORE_PIN17_BIT),
  694. "I" (_SFR_IO_ADDR(CORE_PIN18_PORTREG)), "I" (CORE_PIN18_BIT),
  695. "I" (_SFR_IO_ADDR(CORE_PIN19_PORTREG)), "I" (CORE_PIN19_BIT),
  696. "I" (_SFR_IO_ADDR(CORE_PIN20_PORTREG)), "I" (CORE_PIN20_BIT)
  697. );
  698. }
  699. #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  700. void _digitalWrite_HIGH_TABLE(void)
  701. {
  702. asm volatile (
  703. "sbi %0, %1" "\n\t" // pin 0
  704. "rjmp _digitalWrite_OC0B" "\n\t"
  705. "sbi %2, %3" "\n\t" // pin 1
  706. "rjmp _digitalWrite_OC2B" "\n\t"
  707. "sbi %4, %5" "\n\t" // pin 2
  708. "ret" "\n\t"
  709. "sbi %6, %7" "\n\t" // pin 3
  710. "ret" "\n\t"
  711. "sbi %8, %9" "\n\t" // pin 4
  712. "ret" "\n\t"
  713. :: "I" (_SFR_IO_ADDR(CORE_PIN0_PORTREG)), "I" (CORE_PIN0_BIT),
  714. "I" (_SFR_IO_ADDR(CORE_PIN1_PORTREG)), "I" (CORE_PIN1_BIT),
  715. "I" (_SFR_IO_ADDR(CORE_PIN2_PORTREG)), "I" (CORE_PIN2_BIT),
  716. "I" (_SFR_IO_ADDR(CORE_PIN3_PORTREG)), "I" (CORE_PIN3_BIT),
  717. "I" (_SFR_IO_ADDR(CORE_PIN4_PORTREG)), "I" (CORE_PIN4_BIT)
  718. );
  719. asm volatile (
  720. "sbi %0, %1" "\n\t" // pin 5
  721. "ret" "\n\t"
  722. "sbi %2, %3" "\n\t" // pin 6
  723. "ret" "\n\t"
  724. "sbi %4, %5" "\n\t" // pin 7
  725. "ret" "\n\t"
  726. "sbi %6, %7" "\n\t" // pin 8
  727. "ret" "\n\t"
  728. "sbi %8, %9" "\n\t" // pin 9
  729. "ret" "\n\t"
  730. :: "I" (_SFR_IO_ADDR(CORE_PIN5_PORTREG)), "I" (CORE_PIN5_BIT),
  731. "I" (_SFR_IO_ADDR(CORE_PIN6_PORTREG)), "I" (CORE_PIN6_BIT),
  732. "I" (_SFR_IO_ADDR(CORE_PIN7_PORTREG)), "I" (CORE_PIN7_BIT),
  733. "I" (_SFR_IO_ADDR(CORE_PIN8_PORTREG)), "I" (CORE_PIN8_BIT),
  734. "I" (_SFR_IO_ADDR(CORE_PIN9_PORTREG)), "I" (CORE_PIN9_BIT)
  735. );
  736. asm volatile (
  737. "sbi %0, %1" "\n\t" // pin 10
  738. "ret" "\n\t"
  739. "sbi %2, %3" "\n\t" // pin 11
  740. "ret" "\n\t"
  741. "sbi %4, %5" "\n\t" // pin 12
  742. "ret" "\n\t"
  743. "sbi %6, %7" "\n\t" // pin 13
  744. "ret" "\n\t"
  745. "sbi %8, %9" "\n\t" // pin 14
  746. "rjmp _digitalWrite_OC3C" "\n\t"
  747. :: "I" (_SFR_IO_ADDR(CORE_PIN10_PORTREG)), "I" (CORE_PIN10_BIT),
  748. "I" (_SFR_IO_ADDR(CORE_PIN11_PORTREG)), "I" (CORE_PIN11_BIT),
  749. "I" (_SFR_IO_ADDR(CORE_PIN12_PORTREG)), "I" (CORE_PIN12_BIT),
  750. "I" (_SFR_IO_ADDR(CORE_PIN13_PORTREG)), "I" (CORE_PIN13_BIT),
  751. "I" (_SFR_IO_ADDR(CORE_PIN14_PORTREG)), "I" (CORE_PIN14_BIT)
  752. );
  753. asm volatile (
  754. "sbi %0, %1" "\n\t" // pin 15
  755. "rjmp _digitalWrite_OC3B" "\n\t"
  756. "sbi %2, %3" "\n\t" // pin 16
  757. "rjmp _digitalWrite_OC3A" "\n\t"
  758. "sbi %4, %5" "\n\t" // pin 17
  759. "ret" "\n\t"
  760. "sbi %6, %7" "\n\t" // pin 18
  761. "ret" "\n\t"
  762. "sbi %8, %9" "\n\t" // pin 19
  763. "ret" "\n\t"
  764. :: "I" (_SFR_IO_ADDR(CORE_PIN15_PORTREG)), "I" (CORE_PIN15_BIT),
  765. "I" (_SFR_IO_ADDR(CORE_PIN16_PORTREG)), "I" (CORE_PIN16_BIT),
  766. "I" (_SFR_IO_ADDR(CORE_PIN17_PORTREG)), "I" (CORE_PIN17_BIT),
  767. "I" (_SFR_IO_ADDR(CORE_PIN18_PORTREG)), "I" (CORE_PIN18_BIT),
  768. "I" (_SFR_IO_ADDR(CORE_PIN19_PORTREG)), "I" (CORE_PIN19_BIT)
  769. );
  770. asm volatile (
  771. "sbi %0, %1" "\n\t" // pin 20
  772. "ret" "\n\t"
  773. "sbi %2, %3" "\n\t" // pin 21
  774. "ret" "\n\t"
  775. "sbi %4, %5" "\n\t" // pin 22
  776. "ret" "\n\t"
  777. "sbi %6, %7" "\n\t" // pin 23
  778. "ret" "\n\t"
  779. "sbi %8, %9" "\n\t" // pin 24
  780. "rjmp _digitalWrite_OC2A" "\n\t"
  781. :: "I" (_SFR_IO_ADDR(CORE_PIN20_PORTREG)), "I" (CORE_PIN20_BIT),
  782. "I" (_SFR_IO_ADDR(CORE_PIN21_PORTREG)), "I" (CORE_PIN21_BIT),
  783. "I" (_SFR_IO_ADDR(CORE_PIN22_PORTREG)), "I" (CORE_PIN22_BIT),
  784. "I" (_SFR_IO_ADDR(CORE_PIN23_PORTREG)), "I" (CORE_PIN23_BIT),
  785. "I" (_SFR_IO_ADDR(CORE_PIN24_PORTREG)), "I" (CORE_PIN24_BIT)
  786. );
  787. asm volatile (
  788. "sbi %0, %1" "\n\t" // pin 25
  789. "rjmp _digitalWrite_OC1A" "\n\t"
  790. "sbi %2, %3" "\n\t" // pin 26
  791. "rjmp _digitalWrite_OC1B" "\n\t"
  792. "sbi %4, %5" "\n\t" // pin 27
  793. "rjmp _digitalWrite_OC1C" "\n\t"
  794. "sbi %6, %7" "\n\t" // pin 28
  795. "ret" "\n\t"
  796. "sbi %8, %9" "\n\t" // pin 29
  797. "ret" "\n\t"
  798. :: "I" (_SFR_IO_ADDR(CORE_PIN25_PORTREG)), "I" (CORE_PIN25_BIT),
  799. "I" (_SFR_IO_ADDR(CORE_PIN26_PORTREG)), "I" (CORE_PIN26_BIT),
  800. "I" (_SFR_IO_ADDR(CORE_PIN27_PORTREG)), "I" (CORE_PIN27_BIT),
  801. "I" (_SFR_IO_ADDR(CORE_PIN28_PORTREG)), "I" (CORE_PIN28_BIT),
  802. "I" (_SFR_IO_ADDR(CORE_PIN29_PORTREG)), "I" (CORE_PIN29_BIT)
  803. );
  804. asm volatile (
  805. "sbi %0, %1" "\n\t" // pin 30
  806. "ret" "\n\t"
  807. "sbi %2, %3" "\n\t" // pin 31
  808. "ret" "\n\t"
  809. "sbi %4, %5" "\n\t" // pin 32
  810. "ret" "\n\t"
  811. "sbi %6, %7" "\n\t" // pin 33
  812. "ret" "\n\t"
  813. "sbi %8, %9" "\n\t" // pin 34
  814. "ret" "\n\t"
  815. :: "I" (_SFR_IO_ADDR(CORE_PIN30_PORTREG)), "I" (CORE_PIN30_BIT),
  816. "I" (_SFR_IO_ADDR(CORE_PIN31_PORTREG)), "I" (CORE_PIN31_BIT),
  817. "I" (_SFR_IO_ADDR(CORE_PIN32_PORTREG)), "I" (CORE_PIN32_BIT),
  818. "I" (_SFR_IO_ADDR(CORE_PIN33_PORTREG)), "I" (CORE_PIN33_BIT),
  819. "I" (_SFR_IO_ADDR(CORE_PIN34_PORTREG)), "I" (CORE_PIN34_BIT)
  820. );
  821. asm volatile (
  822. "sbi %0, %1" "\n\t" // pin 35
  823. "ret" "\n\t"
  824. "sbi %2, %3" "\n\t" // pin 36
  825. "ret" "\n\t"
  826. "sbi %4, %5" "\n\t" // pin 37
  827. "ret" "\n\t"
  828. "sbi %6, %7" "\n\t" // pin 38
  829. "ret" "\n\t"
  830. "sbi %8, %9" "\n\t" // pin 39
  831. "ret" "\n\t"
  832. :: "I" (_SFR_IO_ADDR(CORE_PIN35_PORTREG)), "I" (CORE_PIN35_BIT),
  833. "I" (_SFR_IO_ADDR(CORE_PIN36_PORTREG)), "I" (CORE_PIN36_BIT),
  834. "I" (_SFR_IO_ADDR(CORE_PIN37_PORTREG)), "I" (CORE_PIN37_BIT),
  835. "I" (_SFR_IO_ADDR(CORE_PIN38_PORTREG)), "I" (CORE_PIN38_BIT),
  836. "I" (_SFR_IO_ADDR(CORE_PIN39_PORTREG)), "I" (CORE_PIN39_BIT)
  837. );
  838. asm volatile (
  839. "sbi %0, %1" "\n\t" // pin 40
  840. "ret" "\n\t"
  841. "sbi %2, %3" "\n\t" // pin 41
  842. "ret" "\n\t"
  843. "sbi %4, %5" "\n\t" // pin 42
  844. "ret" "\n\t"
  845. "sbi %6, %7" "\n\t" // pin 43
  846. "ret" "\n\t"
  847. "sbi %8, %9" "\n\t" // pin 44
  848. "ret" "\n\t"
  849. "sbi %10, %11" "\n\t" // pin 45
  850. "ret" "\n\t"
  851. :: "I" (_SFR_IO_ADDR(CORE_PIN40_PORTREG)), "I" (CORE_PIN40_BIT),
  852. "I" (_SFR_IO_ADDR(CORE_PIN41_PORTREG)), "I" (CORE_PIN41_BIT),
  853. "I" (_SFR_IO_ADDR(CORE_PIN42_PORTREG)), "I" (CORE_PIN42_BIT),
  854. "I" (_SFR_IO_ADDR(CORE_PIN43_PORTREG)), "I" (CORE_PIN43_BIT),
  855. "I" (_SFR_IO_ADDR(CORE_PIN44_PORTREG)), "I" (CORE_PIN44_BIT),
  856. "I" (_SFR_IO_ADDR(CORE_PIN45_PORTREG)), "I" (CORE_PIN45_BIT)
  857. );
  858. }
  859. void _digitalWrite_LOW_TABLE(void)
  860. {
  861. asm volatile (
  862. "cbi %0, %1" "\n\t" // pin 0
  863. "rjmp _digitalWrite_OC0B" "\n\t"
  864. "cbi %2, %3" "\n\t" // pin 1
  865. "rjmp _digitalWrite_OC2B" "\n\t"
  866. "cbi %4, %5" "\n\t" // pin 2
  867. "ret" "\n\t"
  868. "cbi %6, %7" "\n\t" // pin 3
  869. "ret" "\n\t"
  870. "cbi %8, %9" "\n\t" // pin 4
  871. "ret" "\n\t"
  872. :: "I" (_SFR_IO_ADDR(CORE_PIN0_PORTREG)), "I" (CORE_PIN0_BIT),
  873. "I" (_SFR_IO_ADDR(CORE_PIN1_PORTREG)), "I" (CORE_PIN1_BIT),
  874. "I" (_SFR_IO_ADDR(CORE_PIN2_PORTREG)), "I" (CORE_PIN2_BIT),
  875. "I" (_SFR_IO_ADDR(CORE_PIN3_PORTREG)), "I" (CORE_PIN3_BIT),
  876. "I" (_SFR_IO_ADDR(CORE_PIN4_PORTREG)), "I" (CORE_PIN4_BIT)
  877. );
  878. asm volatile (
  879. "cbi %0, %1" "\n\t" // pin 5
  880. "ret" "\n\t"
  881. "cbi %2, %3" "\n\t" // pin 6
  882. "ret" "\n\t"
  883. "cbi %4, %5" "\n\t" // pin 7
  884. "ret" "\n\t"
  885. "cbi %6, %7" "\n\t" // pin 8
  886. "ret" "\n\t"
  887. "cbi %8, %9" "\n\t" // pin 9
  888. "ret" "\n\t"
  889. :: "I" (_SFR_IO_ADDR(CORE_PIN5_PORTREG)), "I" (CORE_PIN5_BIT),
  890. "I" (_SFR_IO_ADDR(CORE_PIN6_PORTREG)), "I" (CORE_PIN6_BIT),
  891. "I" (_SFR_IO_ADDR(CORE_PIN7_PORTREG)), "I" (CORE_PIN7_BIT),
  892. "I" (_SFR_IO_ADDR(CORE_PIN8_PORTREG)), "I" (CORE_PIN8_BIT),
  893. "I" (_SFR_IO_ADDR(CORE_PIN9_PORTREG)), "I" (CORE_PIN9_BIT)
  894. );
  895. asm volatile (
  896. "cbi %0, %1" "\n\t" // pin 10
  897. "ret" "\n\t"
  898. "cbi %2, %3" "\n\t" // pin 11
  899. "ret" "\n\t"
  900. "cbi %4, %5" "\n\t" // pin 12
  901. "ret" "\n\t"
  902. "cbi %6, %7" "\n\t" // pin 13
  903. "ret" "\n\t"
  904. "cbi %8, %9" "\n\t" // pin 14
  905. "rjmp _digitalWrite_OC3C" "\n\t"
  906. :: "I" (_SFR_IO_ADDR(CORE_PIN10_PORTREG)), "I" (CORE_PIN10_BIT),
  907. "I" (_SFR_IO_ADDR(CORE_PIN11_PORTREG)), "I" (CORE_PIN11_BIT),
  908. "I" (_SFR_IO_ADDR(CORE_PIN12_PORTREG)), "I" (CORE_PIN12_BIT),
  909. "I" (_SFR_IO_ADDR(CORE_PIN13_PORTREG)), "I" (CORE_PIN13_BIT),
  910. "I" (_SFR_IO_ADDR(CORE_PIN14_PORTREG)), "I" (CORE_PIN14_BIT)
  911. );
  912. asm volatile (
  913. "cbi %0, %1" "\n\t" // pin 15
  914. "rjmp _digitalWrite_OC3B" "\n\t"
  915. "cbi %2, %3" "\n\t" // pin 16
  916. "rjmp _digitalWrite_OC3A" "\n\t"
  917. "cbi %4, %5" "\n\t" // pin 17
  918. "ret" "\n\t"
  919. "cbi %6, %7" "\n\t" // pin 18
  920. "ret" "\n\t"
  921. "cbi %8, %9" "\n\t" // pin 19
  922. "ret" "\n\t"
  923. :: "I" (_SFR_IO_ADDR(CORE_PIN15_PORTREG)), "I" (CORE_PIN15_BIT),
  924. "I" (_SFR_IO_ADDR(CORE_PIN16_PORTREG)), "I" (CORE_PIN16_BIT),
  925. "I" (_SFR_IO_ADDR(CORE_PIN17_PORTREG)), "I" (CORE_PIN17_BIT),
  926. "I" (_SFR_IO_ADDR(CORE_PIN18_PORTREG)), "I" (CORE_PIN18_BIT),
  927. "I" (_SFR_IO_ADDR(CORE_PIN19_PORTREG)), "I" (CORE_PIN19_BIT)
  928. );
  929. asm volatile (
  930. "cbi %0, %1" "\n\t" // pin 20
  931. "ret" "\n\t"
  932. "cbi %2, %3" "\n\t" // pin 21
  933. "ret" "\n\t"
  934. "cbi %4, %5" "\n\t" // pin 22
  935. "ret" "\n\t"
  936. "cbi %6, %7" "\n\t" // pin 23
  937. "ret" "\n\t"
  938. "cbi %8, %9" "\n\t" // pin 24
  939. "rjmp _digitalWrite_OC2A" "\n\t"
  940. :: "I" (_SFR_IO_ADDR(CORE_PIN20_PORTREG)), "I" (CORE_PIN20_BIT),
  941. "I" (_SFR_IO_ADDR(CORE_PIN21_PORTREG)), "I" (CORE_PIN21_BIT),
  942. "I" (_SFR_IO_ADDR(CORE_PIN22_PORTREG)), "I" (CORE_PIN22_BIT),
  943. "I" (_SFR_IO_ADDR(CORE_PIN23_PORTREG)), "I" (CORE_PIN23_BIT),
  944. "I" (_SFR_IO_ADDR(CORE_PIN24_PORTREG)), "I" (CORE_PIN24_BIT)
  945. );
  946. asm volatile (
  947. "cbi %0, %1" "\n\t" // pin 25
  948. "rjmp _digitalWrite_OC1A" "\n\t"
  949. "cbi %2, %3" "\n\t" // pin 26
  950. "rjmp _digitalWrite_OC1B" "\n\t"
  951. "cbi %4, %5" "\n\t" // pin 27
  952. "rjmp _digitalWrite_OC1C" "\n\t"
  953. "cbi %6, %7" "\n\t" // pin 28
  954. "ret" "\n\t"
  955. "cbi %8, %9" "\n\t" // pin 29
  956. "ret" "\n\t"
  957. :: "I" (_SFR_IO_ADDR(CORE_PIN25_PORTREG)), "I" (CORE_PIN25_BIT),
  958. "I" (_SFR_IO_ADDR(CORE_PIN26_PORTREG)), "I" (CORE_PIN26_BIT),
  959. "I" (_SFR_IO_ADDR(CORE_PIN27_PORTREG)), "I" (CORE_PIN27_BIT),
  960. "I" (_SFR_IO_ADDR(CORE_PIN28_PORTREG)), "I" (CORE_PIN28_BIT),
  961. "I" (_SFR_IO_ADDR(CORE_PIN29_PORTREG)), "I" (CORE_PIN29_BIT)
  962. );
  963. asm volatile (
  964. "cbi %0, %1" "\n\t" // pin 30
  965. "ret" "\n\t"
  966. "cbi %2, %3" "\n\t" // pin 31
  967. "ret" "\n\t"
  968. "cbi %4, %5" "\n\t" // pin 32
  969. "ret" "\n\t"
  970. "cbi %6, %7" "\n\t" // pin 33
  971. "ret" "\n\t"
  972. "cbi %8, %9" "\n\t" // pin 34
  973. "ret" "\n\t"
  974. :: "I" (_SFR_IO_ADDR(CORE_PIN30_PORTREG)), "I" (CORE_PIN30_BIT),
  975. "I" (_SFR_IO_ADDR(CORE_PIN31_PORTREG)), "I" (CORE_PIN31_BIT),
  976. "I" (_SFR_IO_ADDR(CORE_PIN32_PORTREG)), "I" (CORE_PIN32_BIT),
  977. "I" (_SFR_IO_ADDR(CORE_PIN33_PORTREG)), "I" (CORE_PIN33_BIT),
  978. "I" (_SFR_IO_ADDR(CORE_PIN34_PORTREG)), "I" (CORE_PIN34_BIT)
  979. );
  980. asm volatile (
  981. "cbi %0, %1" "\n\t" // pin 35
  982. "ret" "\n\t"
  983. "cbi %2, %3" "\n\t" // pin 36
  984. "ret" "\n\t"
  985. "cbi %4, %5" "\n\t" // pin 37
  986. "ret" "\n\t"
  987. "cbi %6, %7" "\n\t" // pin 38
  988. "ret" "\n\t"
  989. "cbi %8, %9" "\n\t" // pin 39
  990. "ret" "\n\t"
  991. :: "I" (_SFR_IO_ADDR(CORE_PIN35_PORTREG)), "I" (CORE_PIN35_BIT),
  992. "I" (_SFR_IO_ADDR(CORE_PIN36_PORTREG)), "I" (CORE_PIN36_BIT),
  993. "I" (_SFR_IO_ADDR(CORE_PIN37_PORTREG)), "I" (CORE_PIN37_BIT),
  994. "I" (_SFR_IO_ADDR(CORE_PIN38_PORTREG)), "I" (CORE_PIN38_BIT),
  995. "I" (_SFR_IO_ADDR(CORE_PIN39_PORTREG)), "I" (CORE_PIN39_BIT)
  996. );
  997. asm volatile (
  998. "cbi %0, %1" "\n\t" // pin 40
  999. "ret" "\n\t"
  1000. "cbi %2, %3" "\n\t" // pin 41
  1001. "ret" "\n\t"
  1002. "cbi %4, %5" "\n\t" // pin 42
  1003. "ret" "\n\t"
  1004. "cbi %6, %7" "\n\t" // pin 43
  1005. "ret" "\n\t"
  1006. "cbi %8, %9" "\n\t" // pin 44
  1007. "ret" "\n\t"
  1008. "cbi %10, %11" "\n\t" // pin 45
  1009. "ret" "\n\t"
  1010. :: "I" (_SFR_IO_ADDR(CORE_PIN40_PORTREG)), "I" (CORE_PIN40_BIT),
  1011. "I" (_SFR_IO_ADDR(CORE_PIN41_PORTREG)), "I" (CORE_PIN41_BIT),
  1012. "I" (_SFR_IO_ADDR(CORE_PIN42_PORTREG)), "I" (CORE_PIN42_BIT),
  1013. "I" (_SFR_IO_ADDR(CORE_PIN43_PORTREG)), "I" (CORE_PIN43_BIT),
  1014. "I" (_SFR_IO_ADDR(CORE_PIN44_PORTREG)), "I" (CORE_PIN44_BIT),
  1015. "I" (_SFR_IO_ADDR(CORE_PIN45_PORTREG)), "I" (CORE_PIN45_BIT)
  1016. );
  1017. }
  1018. #endif
  1019. void _digitalWrite_OC0B(void)
  1020. {
  1021. asm volatile (
  1022. "in r30, %0" "\n\t"
  1023. "andi r30, ~(1 << %1)" "\n\t"
  1024. "out %0, r30" "\n\t"
  1025. "ret"
  1026. :: "I" (_SFR_IO_ADDR(TCCR0A)), "I" (COM0B1)
  1027. );
  1028. }
  1029. void _digitalWrite_OC1A(void)
  1030. {
  1031. asm volatile (
  1032. "lds r30, %0" "\n\t"
  1033. "andi r30, ~(1 << %1)" "\n\t"
  1034. "sts %0, r30" "\n\t"
  1035. "ret"
  1036. :: "M" (&TCCR1A), "I" (COM1A1)
  1037. );
  1038. }
  1039. void _digitalWrite_OC1B(void)
  1040. {
  1041. asm volatile (
  1042. "lds r30, %0" "\n\t"
  1043. "andi r30, ~(1 << %1)" "\n\t"
  1044. "sts %0, r30" "\n\t"
  1045. "ret"
  1046. :: "M" (&TCCR1A), "I" (COM1B1)
  1047. );
  1048. }
  1049. void _digitalWrite_OC1C(void)
  1050. {
  1051. asm volatile (
  1052. "lds r30, %0" "\n\t"
  1053. "andi r30, ~(1 << %1)" "\n\t"
  1054. "sts %0, r30" "\n\t"
  1055. "ret"
  1056. :: "M" (&TCCR1A), "I" (COM1C1)
  1057. );
  1058. }
  1059. #if defined(__AVR_ATmega32U4__)
  1060. void _digitalWrite_OC3A(void)
  1061. {
  1062. asm volatile (
  1063. "lds r30, %0" "\n\t"
  1064. "andi r30, ~(1 << %1)" "\n\t"
  1065. "sts %0, r30" "\n\t"
  1066. "ret"
  1067. :: "M" (&TCCR3A), "I" (COM3A1)
  1068. );
  1069. }
  1070. void _digitalWrite_OC4A(void)
  1071. {
  1072. asm volatile (
  1073. "lds r30, %0" "\n\t"
  1074. "andi r30, ~(1 << %1)" "\n\t"
  1075. "sts %0, r30" "\n\t"
  1076. "ret"
  1077. :: "M" (&TCCR4A), "I" (COM4A1)
  1078. );
  1079. }
  1080. void _digitalWrite_OC4D(void)
  1081. {
  1082. asm volatile (
  1083. "lds r30, %0" "\n\t"
  1084. "andi r30, ~(1 << %1)" "\n\t"
  1085. "sts %0, r30" "\n\t"
  1086. "ret"
  1087. :: "M" (&TCCR4C), "I" (COM4D1)
  1088. );
  1089. }
  1090. #endif
  1091. #if defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
  1092. void _digitalWrite_OC2A(void)
  1093. {
  1094. asm volatile (
  1095. "lds r30, %0" "\n\t"
  1096. "andi r30, ~(1 << %1)" "\n\t"
  1097. "sts %0, r30" "\n\t"
  1098. "ret"
  1099. :: "M" (&TCCR2A), "I" (COM3A1)
  1100. );
  1101. }
  1102. void _digitalWrite_OC2B(void)
  1103. {
  1104. asm volatile (
  1105. "lds r30, %0" "\n\t"
  1106. "andi r30, ~(1 << %1)" "\n\t"
  1107. "sts %0, r30" "\n\t"
  1108. "ret"
  1109. :: "M" (&TCCR2A), "I" (COM3B1)
  1110. );
  1111. }
  1112. void _digitalWrite_OC3A(void)
  1113. {
  1114. asm volatile (
  1115. "lds r30, %0" "\n\t"
  1116. "andi r30, ~(1 << %1)" "\n\t"
  1117. "sts %0, r30" "\n\t"
  1118. "ret"
  1119. :: "M" (&TCCR3A), "I" (COM3A1)
  1120. );
  1121. }
  1122. void _digitalWrite_OC3B(void)
  1123. {
  1124. asm volatile (
  1125. "lds r30, %0" "\n\t"
  1126. "andi r30, ~(1 << %1)" "\n\t"
  1127. "sts %0, r30" "\n\t"
  1128. "ret"
  1129. :: "M" (&TCCR3A), "I" (COM3B1)
  1130. );
  1131. }
  1132. void _digitalWrite_OC3C(void)
  1133. {
  1134. asm volatile (
  1135. "lds r30, %0" "\n\t"
  1136. "andi r30, ~(1 << %1)" "\n\t"
  1137. "sts %0, r30" "\n\t"
  1138. "ret"
  1139. :: "M" (&TCCR3A), "I" (COM3C1)
  1140. );
  1141. }
  1142. #endif
  1143. void _digitalRead(void) __attribute__((naked));
  1144. void _digitalRead_false(void) __attribute__((naked));
  1145. void _digitalRead_true(void) __attribute__((naked));
  1146. void _digitalRead_TABLE(void) __attribute__((naked));
  1147. void _digitalRead_true2(void) __attribute__((naked));
  1148. void _digitalRead_TABLE2(void) __attribute__((naked));
  1149. void _digitalRead(void)
  1150. {
  1151. asm volatile (
  1152. #if !defined(DIGITAL_WRITE_RISKY_OMIT_OVERFLOW_CHECK)
  1153. "cpi r30, %0" "\n\t"
  1154. "brsh _digitalRead_false" "\n\t"
  1155. #endif
  1156. "lsl r30" "\n\t"
  1157. "lsl r30" "\n\t"
  1158. "clr r31" "\n\t"
  1159. #if CORE_NUM_TOTAL_PINS > 25
  1160. "cpi r30, 124" "\n\t"
  1161. "brsh L%=2" "\n\t"
  1162. #endif
  1163. "subi r30, lo8(-(pm(_digitalRead_TABLE)))" "\n\t"
  1164. "sbci r31, hi8(-(pm(_digitalRead_TABLE)))" "\n\t"
  1165. "ijmp" "\n"
  1166. #if CORE_NUM_TOTAL_PINS > 25
  1167. "L%=2:" "\n\t"
  1168. "subi r30, lo8(-(pm(_digitalRead_TABLE2 - 248)))" "\n\t"
  1169. "sbci r31, hi8(-(pm(_digitalRead_TABLE2 - 248)))" "\n\t"
  1170. "ijmp" "\n"
  1171. #endif
  1172. : : "M" (CORE_NUM_TOTAL_PINS)
  1173. );
  1174. }
  1175. #if !defined(DIGITAL_WRITE_RISKY_OMIT_OVERFLOW_CHECK)
  1176. void _digitalRead_false(void)
  1177. {
  1178. asm volatile (
  1179. "clr r30" "\n\t"
  1180. "ret" "\n"
  1181. );
  1182. }
  1183. #endif
  1184. void _digitalRead_true(void)
  1185. {
  1186. asm volatile (
  1187. "ldi r30, 1" "\n\t"
  1188. "ret" "\n"
  1189. );
  1190. }
  1191. void _digitalRead_TABLE(void)
  1192. {
  1193. asm volatile (
  1194. "in r30, %0" "\n\t" // pin 0
  1195. "andi r30, %1" "\n\t"
  1196. "brne _digitalRead_true" "\n\t"
  1197. "ret" "\n\t"
  1198. "in r30, %2" "\n\t" // pin 1
  1199. "andi r30, %3" "\n\t"
  1200. "brne _digitalRead_true" "\n\t"
  1201. "ret" "\n\t"
  1202. "in r30, %4" "\n\t" // pin 2
  1203. "andi r30, %5" "\n\t"
  1204. "brne _digitalRead_true" "\n\t"
  1205. "ret" "\n\t"
  1206. "in r30, %6" "\n\t" // pin 3
  1207. "andi r30, %7" "\n\t"
  1208. "brne _digitalRead_true" "\n\t"
  1209. "ret" "\n\t"
  1210. "in r30, %8" "\n\t" // pin 4
  1211. "andi r30, %9" "\n\t"
  1212. "brne _digitalRead_true" "\n\t"
  1213. "ret" "\n\t"
  1214. :: "I" (_SFR_IO_ADDR(CORE_PIN0_PINREG)), "M" (CORE_PIN0_BITMASK),
  1215. "I" (_SFR_IO_ADDR(CORE_PIN1_PINREG)), "M" (CORE_PIN1_BITMASK),
  1216. "I" (_SFR_IO_ADDR(CORE_PIN2_PINREG)), "M" (CORE_PIN2_BITMASK),
  1217. "I" (_SFR_IO_ADDR(CORE_PIN3_PINREG)), "M" (CORE_PIN3_BITMASK),
  1218. "I" (_SFR_IO_ADDR(CORE_PIN4_PINREG)), "M" (CORE_PIN4_BITMASK)
  1219. );
  1220. asm volatile (
  1221. "in r30, %0" "\n\t" // pin 5
  1222. "andi r30, %1" "\n\t"
  1223. "brne _digitalRead_true" "\n\t"
  1224. "ret" "\n\t"
  1225. "in r30, %2" "\n\t" // pin 6
  1226. "andi r30, %3" "\n\t"
  1227. "brne _digitalRead_true" "\n\t"
  1228. "ret" "\n\t"
  1229. "in r30, %4" "\n\t" // pin 7
  1230. "andi r30, %5" "\n\t"
  1231. "brne _digitalRead_true" "\n\t"
  1232. "ret" "\n\t"
  1233. "in r30, %6" "\n\t" // pin 8
  1234. "andi r30, %7" "\n\t"
  1235. "brne _digitalRead_true" "\n\t"
  1236. "ret" "\n\t"
  1237. "in r30, %8" "\n\t" // pin 9
  1238. "andi r30, %9" "\n\t"
  1239. "brne _digitalRead_true" "\n\t"
  1240. "ret" "\n\t"
  1241. :: "I" (_SFR_IO_ADDR(CORE_PIN5_PINREG)), "M" (CORE_PIN5_BITMASK),
  1242. "I" (_SFR_IO_ADDR(CORE_PIN6_PINREG)), "M" (CORE_PIN6_BITMASK),
  1243. "I" (_SFR_IO_ADDR(CORE_PIN7_PINREG)), "M" (CORE_PIN7_BITMASK),
  1244. "I" (_SFR_IO_ADDR(CORE_PIN8_PINREG)), "M" (CORE_PIN8_BITMASK),
  1245. "I" (_SFR_IO_ADDR(CORE_PIN9_PINREG)), "M" (CORE_PIN9_BITMASK)
  1246. );
  1247. asm volatile (
  1248. "in r30, %0" "\n\t" // pin 10
  1249. "andi r30, %1" "\n\t"
  1250. "brne _digitalRead_true" "\n\t"
  1251. "ret" "\n\t"
  1252. "in r30, %2" "\n\t" // pin 11
  1253. "andi r30, %3" "\n\t"
  1254. "brne _digitalRead_true" "\n\t"
  1255. "ret" "\n\t"
  1256. "in r30, %4" "\n\t" // pin 12
  1257. "andi r30, %5" "\n\t"
  1258. "brne _digitalRead_true" "\n\t"
  1259. "ret" "\n\t"
  1260. "in r30, %6" "\n\t" // pin 13
  1261. "andi r30, %7" "\n\t"
  1262. "brne _digitalRead_true" "\n\t"
  1263. "ret" "\n\t"
  1264. "in r30, %8" "\n\t" // pin 14
  1265. "andi r30, %9" "\n\t"
  1266. "brne _digitalRead_true" "\n\t"
  1267. "ret" "\n\t"
  1268. :: "I" (_SFR_IO_ADDR(CORE_PIN10_PINREG)), "M" (CORE_PIN10_BITMASK),
  1269. "I" (_SFR_IO_ADDR(CORE_PIN11_PINREG)), "M" (CORE_PIN11_BITMASK),
  1270. "I" (_SFR_IO_ADDR(CORE_PIN12_PINREG)), "M" (CORE_PIN12_BITMASK),
  1271. "I" (_SFR_IO_ADDR(CORE_PIN13_PINREG)), "M" (CORE_PIN13_BITMASK),
  1272. "I" (_SFR_IO_ADDR(CORE_PIN14_PINREG)), "M" (CORE_PIN14_BITMASK)
  1273. );
  1274. asm volatile (
  1275. "in r30, %0" "\n\t" // pin 15
  1276. "andi r30, %1" "\n\t"
  1277. "brne _digitalRead_true2" "\n\t"
  1278. "ret" "\n\t"
  1279. "in r30, %2" "\n\t" // pin 16
  1280. "andi r30, %3" "\n\t"
  1281. "brne _digitalRead_true2" "\n\t"
  1282. "ret" "\n\t"
  1283. "in r30, %4" "\n\t" // pin 17
  1284. "andi r30, %5" "\n\t"
  1285. "brne _digitalRead_true2" "\n\t"
  1286. "ret" "\n\t"
  1287. "in r30, %6" "\n\t" // pin 18
  1288. "andi r30, %7" "\n\t"
  1289. "brne _digitalRead_true2" "\n\t"
  1290. "ret" "\n\t"
  1291. "in r30, %8" "\n\t" // pin 19
  1292. "andi r30, %9" "\n\t"
  1293. "brne _digitalRead_true2" "\n\t"
  1294. "ret" "\n\t"
  1295. "in r30, %10" "\n\t" // pin 20
  1296. "andi r30, %11" "\n\t"
  1297. "brne _digitalRead_true2" "\n\t"
  1298. "ret" "\n\t"
  1299. :: "I" (_SFR_IO_ADDR(CORE_PIN15_PINREG)), "M" (CORE_PIN15_BITMASK),
  1300. "I" (_SFR_IO_ADDR(CORE_PIN16_PINREG)), "M" (CORE_PIN16_BITMASK),
  1301. "I" (_SFR_IO_ADDR(CORE_PIN17_PINREG)), "M" (CORE_PIN17_BITMASK),
  1302. "I" (_SFR_IO_ADDR(CORE_PIN18_PINREG)), "M" (CORE_PIN18_BITMASK),
  1303. "I" (_SFR_IO_ADDR(CORE_PIN19_PINREG)), "M" (CORE_PIN19_BITMASK),
  1304. "I" (_SFR_IO_ADDR(CORE_PIN20_PINREG)), "M" (CORE_PIN20_BITMASK)
  1305. );
  1306. #if CORE_NUM_TOTAL_PINS > 21
  1307. asm volatile (
  1308. "in r30, %0" "\n\t" // pin 21
  1309. "andi r30, %1" "\n\t"
  1310. "brne _digitalRead_true2" "\n\t"
  1311. "ret" "\n\t"
  1312. "in r30, %2" "\n\t" // pin 22
  1313. "andi r30, %3" "\n\t"
  1314. "brne _digitalRead_true2" "\n\t"
  1315. "ret" "\n\t"
  1316. "in r30, %4" "\n\t" // pin 23
  1317. "andi r30, %5" "\n\t"
  1318. "brne _digitalRead_true2" "\n\t"
  1319. "ret" "\n\t"
  1320. "in r30, %6" "\n\t" // pin 24
  1321. "andi r30, %7" "\n\t"
  1322. "brne _digitalRead_true2" "\n\t"
  1323. "ret" "\n\t"
  1324. :: "I" (_SFR_IO_ADDR(CORE_PIN21_PINREG)), "M" (CORE_PIN21_BITMASK),
  1325. "I" (_SFR_IO_ADDR(CORE_PIN22_PINREG)), "M" (CORE_PIN22_BITMASK),
  1326. "I" (_SFR_IO_ADDR(CORE_PIN23_PINREG)), "M" (CORE_PIN23_BITMASK),
  1327. "I" (_SFR_IO_ADDR(CORE_PIN24_PINREG)), "M" (CORE_PIN24_BITMASK)
  1328. );
  1329. #endif
  1330. #if CORE_NUM_TOTAL_PINS > 25
  1331. asm volatile (
  1332. "in r30, %0" "\n\t" // pin 25
  1333. "andi r30, %1" "\n\t"
  1334. "brne _digitalRead_true2" "\n\t"
  1335. "ret" "\n\t"
  1336. "in r30, %2" "\n\t" // pin 26
  1337. "andi r30, %3" "\n\t"
  1338. "brne _digitalRead_true2" "\n\t"
  1339. "ret" "\n\t"
  1340. "in r30, %4" "\n\t" // pin 27
  1341. "andi r30, %5" "\n\t"
  1342. "brne _digitalRead_true2" "\n\t"
  1343. "ret" "\n\t"
  1344. "in r30, %6" "\n\t" // pin 28
  1345. "andi r30, %7" "\n\t"
  1346. "brne _digitalRead_true2" "\n\t"
  1347. "ret" "\n\t"
  1348. "in r30, %8" "\n\t" // pin 29
  1349. "andi r30, %9" "\n\t"
  1350. "brne _digitalRead_true2" "\n\t"
  1351. "ret" "\n\t"
  1352. "in r30, %10" "\n\t" // pin 30
  1353. "andi r30, %11" "\n\t"
  1354. "brne _digitalRead_true2" "\n\t"
  1355. "ret" "\n\t"
  1356. :: "I" (_SFR_IO_ADDR(CORE_PIN25_PINREG)), "M" (CORE_PIN25_BITMASK),
  1357. "I" (_SFR_IO_ADDR(CORE_PIN26_PINREG)), "M" (CORE_PIN26_BITMASK),
  1358. "I" (_SFR_IO_ADDR(CORE_PIN27_PINREG)), "M" (CORE_PIN27_BITMASK),
  1359. "I" (_SFR_IO_ADDR(CORE_PIN28_PINREG)), "M" (CORE_PIN28_BITMASK),
  1360. "I" (_SFR_IO_ADDR(CORE_PIN29_PINREG)), "M" (CORE_PIN29_BITMASK),
  1361. "I" (_SFR_IO_ADDR(CORE_PIN30_PINREG)), "M" (CORE_PIN30_BITMASK)
  1362. );
  1363. #endif
  1364. }
  1365. void _digitalRead_true2(void)
  1366. {
  1367. asm volatile (
  1368. "ldi r30, 1" "\n\t"
  1369. "ret" "\n"
  1370. );
  1371. }
  1372. #if CORE_NUM_TOTAL_PINS > 25
  1373. void _digitalRead_TABLE2(void)
  1374. {
  1375. asm volatile (
  1376. "in r30, %0" "\n\t" // pin 31
  1377. "andi r30, %1" "\n\t"
  1378. "brne _digitalRead_true2" "\n\t"
  1379. "ret" "\n\t"
  1380. "in r30, %2" "\n\t" // pin 32
  1381. "andi r30, %3" "\n\t"
  1382. "brne _digitalRead_true2" "\n\t"
  1383. "ret" "\n\t"
  1384. "in r30, %4" "\n\t" // pin 33
  1385. "andi r30, %5" "\n\t"
  1386. "brne _digitalRead_true2" "\n\t"
  1387. "ret" "\n\t"
  1388. "in r30, %6" "\n\t" // pin 34
  1389. "andi r30, %7" "\n\t"
  1390. "brne _digitalRead_true2" "\n\t"
  1391. "ret" "\n\t"
  1392. :: "I" (_SFR_IO_ADDR(CORE_PIN31_PINREG)), "M" (CORE_PIN31_BITMASK),
  1393. "I" (_SFR_IO_ADDR(CORE_PIN32_PINREG)), "M" (CORE_PIN32_BITMASK),
  1394. "I" (_SFR_IO_ADDR(CORE_PIN33_PINREG)), "M" (CORE_PIN33_BITMASK),
  1395. "I" (_SFR_IO_ADDR(CORE_PIN34_PINREG)), "M" (CORE_PIN34_BITMASK)
  1396. );
  1397. asm volatile (
  1398. "in r30, %0" "\n\t" // pin 35
  1399. "andi r30, %1" "\n\t"
  1400. "brne _digitalRead_true2" "\n\t"
  1401. "ret" "\n\t"
  1402. "in r30, %2" "\n\t" // pin 36
  1403. "andi r30, %3" "\n\t"
  1404. "brne _digitalRead_true2" "\n\t"
  1405. "ret" "\n\t"
  1406. "in r30, %4" "\n\t" // pin 37
  1407. "andi r30, %5" "\n\t"
  1408. "brne _digitalRead_true2" "\n\t"
  1409. "ret" "\n\t"
  1410. "in r30, %6" "\n\t" // pin 38
  1411. "andi r30, %7" "\n\t"
  1412. "brne _digitalRead_true2" "\n\t"
  1413. "ret" "\n\t"
  1414. "in r30, %8" "\n\t" // pin 39
  1415. "andi r30, %9" "\n\t"
  1416. "brne _digitalRead_true2" "\n\t"
  1417. "ret" "\n\t"
  1418. :: "I" (_SFR_IO_ADDR(CORE_PIN35_PINREG)), "M" (CORE_PIN35_BITMASK),
  1419. "I" (_SFR_IO_ADDR(CORE_PIN36_PINREG)), "M" (CORE_PIN36_BITMASK),
  1420. "I" (_SFR_IO_ADDR(CORE_PIN37_PINREG)), "M" (CORE_PIN37_BITMASK),
  1421. "I" (_SFR_IO_ADDR(CORE_PIN38_PINREG)), "M" (CORE_PIN38_BITMASK),
  1422. "I" (_SFR_IO_ADDR(CORE_PIN39_PINREG)), "M" (CORE_PIN39_BITMASK)
  1423. );
  1424. asm volatile (
  1425. "in r30, %0" "\n\t" // pin 40
  1426. "andi r30, %1" "\n\t"
  1427. "brne _digitalRead_true2" "\n\t"
  1428. "ret" "\n\t"
  1429. "in r30, %2" "\n\t" // pin 41
  1430. "andi r30, %3" "\n\t"
  1431. "brne _digitalRead_true2" "\n\t"
  1432. "ret" "\n\t"
  1433. "in r30, %4" "\n\t" // pin 42
  1434. "andi r30, %5" "\n\t"
  1435. "brne _digitalRead_true2" "\n\t"
  1436. "ret" "\n\t"
  1437. "in r30, %6" "\n\t" // pin 43
  1438. "andi r30, %7" "\n\t"
  1439. "brne _digitalRead_true2" "\n\t"
  1440. "ret" "\n\t"
  1441. "in r30, %8" "\n\t" // pin 44
  1442. "andi r30, %9" "\n\t"
  1443. "brne _digitalRead_true2" "\n\t"
  1444. "ret" "\n\t"
  1445. "in r30, %10" "\n\t" // pin 45
  1446. "andi r30, %11" "\n\t"
  1447. "brne _digitalRead_true2" "\n\t"
  1448. "ret" "\n\t"
  1449. :: "I" (_SFR_IO_ADDR(CORE_PIN40_PINREG)), "M" (CORE_PIN40_BITMASK),
  1450. "I" (_SFR_IO_ADDR(CORE_PIN41_PINREG)), "M" (CORE_PIN41_BITMASK),
  1451. "I" (_SFR_IO_ADDR(CORE_PIN42_PINREG)), "M" (CORE_PIN42_BITMASK),
  1452. "I" (_SFR_IO_ADDR(CORE_PIN43_PINREG)), "M" (CORE_PIN43_BITMASK),
  1453. "I" (_SFR_IO_ADDR(CORE_PIN44_PINREG)), "M" (CORE_PIN44_BITMASK),
  1454. "I" (_SFR_IO_ADDR(CORE_PIN45_PINREG)), "M" (CORE_PIN45_BITMASK)
  1455. );
  1456. }
  1457. #endif
  1458. const uint8_t PROGMEM digital_pin_table_PGM[] = {
  1459. CORE_PIN0_BITMASK, (int)&CORE_PIN0_PINREG,
  1460. CORE_PIN1_BITMASK, (int)&CORE_PIN1_PINREG,
  1461. CORE_PIN2_BITMASK, (int)&CORE_PIN2_PINREG,
  1462. CORE_PIN3_BITMASK, (int)&CORE_PIN3_PINREG,
  1463. CORE_PIN4_BITMASK, (int)&CORE_PIN4_PINREG,
  1464. CORE_PIN5_BITMASK, (int)&CORE_PIN5_PINREG,
  1465. CORE_PIN6_BITMASK, (int)&CORE_PIN6_PINREG,
  1466. CORE_PIN7_BITMASK, (int)&CORE_PIN7_PINREG,
  1467. CORE_PIN8_BITMASK, (int)&CORE_PIN8_PINREG,
  1468. CORE_PIN9_BITMASK, (int)&CORE_PIN9_PINREG,
  1469. CORE_PIN10_BITMASK, (int)&CORE_PIN10_PINREG,
  1470. CORE_PIN11_BITMASK, (int)&CORE_PIN11_PINREG,
  1471. CORE_PIN12_BITMASK, (int)&CORE_PIN12_PINREG,
  1472. CORE_PIN13_BITMASK, (int)&CORE_PIN13_PINREG,
  1473. CORE_PIN14_BITMASK, (int)&CORE_PIN14_PINREG,
  1474. CORE_PIN15_BITMASK, (int)&CORE_PIN15_PINREG,
  1475. CORE_PIN16_BITMASK, (int)&CORE_PIN16_PINREG,
  1476. CORE_PIN17_BITMASK, (int)&CORE_PIN17_PINREG,
  1477. CORE_PIN18_BITMASK, (int)&CORE_PIN18_PINREG,
  1478. CORE_PIN19_BITMASK, (int)&CORE_PIN19_PINREG,
  1479. CORE_PIN20_BITMASK, (int)&CORE_PIN20_PINREG,
  1480. #if CORE_NUM_TOTAL_PINS > 21
  1481. CORE_PIN21_BITMASK, (int)&CORE_PIN21_PINREG,
  1482. CORE_PIN22_BITMASK, (int)&CORE_PIN22_PINREG,
  1483. CORE_PIN23_BITMASK, (int)&CORE_PIN23_PINREG,
  1484. CORE_PIN24_BITMASK, (int)&CORE_PIN24_PINREG,
  1485. #endif
  1486. #if CORE_NUM_TOTAL_PINS > 25
  1487. CORE_PIN25_BITMASK, (int)&CORE_PIN25_PINREG,
  1488. CORE_PIN26_BITMASK, (int)&CORE_PIN26_PINREG,
  1489. CORE_PIN27_BITMASK, (int)&CORE_PIN27_PINREG,
  1490. CORE_PIN28_BITMASK, (int)&CORE_PIN28_PINREG,
  1491. CORE_PIN29_BITMASK, (int)&CORE_PIN29_PINREG,
  1492. CORE_PIN30_BITMASK, (int)&CORE_PIN30_PINREG,
  1493. CORE_PIN31_BITMASK, (int)&CORE_PIN31_PINREG,
  1494. CORE_PIN32_BITMASK, (int)&CORE_PIN32_PINREG,
  1495. CORE_PIN33_BITMASK, (int)&CORE_PIN33_PINREG,
  1496. CORE_PIN34_BITMASK, (int)&CORE_PIN34_PINREG,
  1497. CORE_PIN35_BITMASK, (int)&CORE_PIN35_PINREG,
  1498. CORE_PIN36_BITMASK, (int)&CORE_PIN36_PINREG,
  1499. CORE_PIN37_BITMASK, (int)&CORE_PIN37_PINREG,
  1500. CORE_PIN38_BITMASK, (int)&CORE_PIN38_PINREG,
  1501. CORE_PIN39_BITMASK, (int)&CORE_PIN39_PINREG,
  1502. CORE_PIN40_BITMASK, (int)&CORE_PIN40_PINREG,
  1503. CORE_PIN41_BITMASK, (int)&CORE_PIN41_PINREG,
  1504. CORE_PIN42_BITMASK, (int)&CORE_PIN42_PINREG,
  1505. CORE_PIN43_BITMASK, (int)&CORE_PIN43_PINREG,
  1506. CORE_PIN44_BITMASK, (int)&CORE_PIN44_PINREG,
  1507. CORE_PIN45_BITMASK, (int)&CORE_PIN45_PINREG
  1508. #endif
  1509. };
  1510. void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value)
  1511. {
  1512. if (bitOrder == LSBFIRST) {
  1513. shiftOut_lsbFirst(dataPin, clockPin, value);
  1514. } else {
  1515. shiftOut_msbFirst(dataPin, clockPin, value);
  1516. }
  1517. }
  1518. void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
  1519. {
  1520. uint8_t mask;
  1521. for (mask=0x01; mask; mask <<= 1) {
  1522. digitalWrite(dataPin, value & mask);
  1523. digitalWrite(clockPin, HIGH);
  1524. digitalWrite(clockPin, LOW);
  1525. }
  1526. }
  1527. void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
  1528. {
  1529. uint8_t mask;
  1530. for (mask=0x80; mask; mask >>= 1) {
  1531. digitalWrite(dataPin, value & mask);
  1532. digitalWrite(clockPin, HIGH);
  1533. digitalWrite(clockPin, LOW);
  1534. }
  1535. }
  1536. uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
  1537. {
  1538. if (bitOrder == LSBFIRST) {
  1539. return shiftIn_lsbFirst(dataPin, clockPin);
  1540. } else {
  1541. return shiftIn_msbFirst(dataPin, clockPin);
  1542. }
  1543. }
  1544. uint8_t shiftIn_lsbFirst(uint8_t dataPin, uint8_t clockPin)
  1545. {
  1546. uint8_t mask, value=0;
  1547. for (mask=0x01; mask; mask <<= 1) {
  1548. digitalWrite(clockPin, HIGH);
  1549. if (digitalRead(dataPin)) value |= mask;
  1550. digitalWrite(clockPin, LOW);
  1551. }
  1552. return value;
  1553. }
  1554. uint8_t shiftIn_msbFirst(uint8_t dataPin, uint8_t clockPin)
  1555. {
  1556. uint8_t mask, value=0;
  1557. for (mask=0x80; mask; mask >>= 1) {
  1558. digitalWrite(clockPin, HIGH);
  1559. if (digitalRead(dataPin)) value |= mask;
  1560. digitalWrite(clockPin, LOW);
  1561. }
  1562. return value;
  1563. }
  1564. static void disable_peripherals(void) __attribute__((noinline));
  1565. static void disable_peripherals(void)
  1566. {
  1567. #if defined(__AVR_AT90USB162__)
  1568. EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
  1569. TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
  1570. DDRB = 0; DDRC = 0; DDRD = 0;
  1571. PORTB = 0; PORTC = 0; PORTD = 0;
  1572. #elif defined(__AVR_ATmega32U4__)
  1573. EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
  1574. TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
  1575. DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
  1576. PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
  1577. #elif defined(__AVR_AT90USB646__)
  1578. EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
  1579. TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
  1580. DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
  1581. PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
  1582. #elif defined(__AVR_AT90USB1286__)
  1583. EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
  1584. TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
  1585. DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
  1586. PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
  1587. #endif
  1588. }
  1589. #ifndef WDFR
  1590. #define WDFR 3
  1591. #endif
  1592. void _reboot_Teensyduino_(void)
  1593. {
  1594. cli();
  1595. // stop watchdog timer, if running
  1596. MCUSR &= ~(1<<WDFR);
  1597. WDTCSR |= (1<<WDCE);
  1598. WDTCSR = 0;
  1599. delayMicroseconds(5000);
  1600. UDCON = 1;
  1601. USBCON = (1<<FRZCLK);
  1602. delayMicroseconds(15000);
  1603. disable_peripherals();
  1604. #if defined(__AVR_AT90USB162__)
  1605. asm volatile("jmp 0x3E00");
  1606. #elif defined(__AVR_ATmega32U4__)
  1607. asm volatile("jmp 0x7E00");
  1608. #elif defined(__AVR_AT90USB646__)
  1609. asm volatile("jmp 0xFC00");
  1610. #elif defined(__AVR_AT90USB1286__)
  1611. asm volatile("jmp 0x1FC00");
  1612. #endif
  1613. //__builtin_unreachable(); // available in gcc 4.5
  1614. while (1) ;
  1615. }
  1616. void _restart_Teensyduino_(void)
  1617. {
  1618. cli();
  1619. disable_peripherals(); // but leave USB intact
  1620. delayMicroseconds(15000);
  1621. asm volatile("jmp 0");
  1622. //__builtin_unreachable(); // available in gcc 4.5
  1623. while (1) ;
  1624. }
  1625. #if F_CPU == 16000000L
  1626. #define TIMER0_MILLIS_INC 1
  1627. #define TIMER0_FRACT_INC 3
  1628. #define TIMER0_MICROS_INC 4
  1629. #elif F_CPU == 8000000L
  1630. #define TIMER0_MILLIS_INC 2
  1631. #define TIMER0_FRACT_INC 6
  1632. #define TIMER0_MICROS_INC 8
  1633. #elif F_CPU == 4000000L
  1634. #define TIMER0_MILLIS_INC 4
  1635. #define TIMER0_FRACT_INC 12
  1636. #define TIMER0_MICROS_INC 16
  1637. #elif F_CPU == 2000000L
  1638. #define TIMER0_MILLIS_INC 8
  1639. #define TIMER0_FRACT_INC 24
  1640. #define TIMER0_MICROS_INC 32
  1641. #elif F_CPU == 1000000L
  1642. #define TIMER0_MILLIS_INC 16
  1643. #define TIMER0_FRACT_INC 48
  1644. #define TIMER0_MICROS_INC 64
  1645. #endif
  1646. volatile unsigned long timer0_micros_count = 0;
  1647. volatile unsigned long timer0_millis_count = 0;
  1648. volatile unsigned char timer0_fract_count = 0;
  1649. void TIMER0_OVF_vect() __attribute__((naked));
  1650. void TIMER0_OVF_vect()
  1651. {
  1652. asm volatile(
  1653. "push r24" "\n\t"
  1654. "in r24, __SREG__" "\n\t"
  1655. "push r24" "\n\t"
  1656. "lds r24, timer0_fract_count" "\n\t"
  1657. "subi r24, 256 - %0" "\n\t"
  1658. "cpi r24, 125" "\n\t"
  1659. "brsh L_%=_fract_roll" "\n\t"
  1660. "L_%=_fract_noroll:" "\n\t"
  1661. "sts timer0_fract_count, r24" "\n\t"
  1662. "lds r24, timer0_millis_count" "\n\t"
  1663. "subi r24, 256 - %1" "\n\t"
  1664. "sts timer0_millis_count, r24" "\n\t"
  1665. "brcs L_%=_ovcount" "\n\t"
  1666. "L_%=_millis_inc_sext:"
  1667. "lds r24, timer0_millis_count+1" "\n\t"
  1668. "sbci r24, 255" "\n\t"
  1669. "sts timer0_millis_count+1, r24" "\n\t"
  1670. "brcs L_%=_ovcount" "\n\t"
  1671. "lds r24, timer0_millis_count+2" "\n\t"
  1672. "sbci r24, 255" "\n\t"
  1673. "sts timer0_millis_count+2, r24" "\n\t"
  1674. "brcs L_%=_ovcount" "\n\t"
  1675. "lds r24, timer0_millis_count+3" "\n\t"
  1676. "sbci r24, 255" "\n\t"
  1677. "sts timer0_millis_count+3, r24" "\n\t"
  1678. "rjmp L_%=_ovcount" "\n\t"
  1679. "L_%=_fract_roll:" "\n\t"
  1680. "subi r24, 125" "\n\t"
  1681. "sts timer0_fract_count, r24" "\n\t"
  1682. "lds r24, timer0_millis_count" "\n\t"
  1683. "subi r24, 256 - %1 - 1" "\n\t"
  1684. "sts timer0_millis_count, r24" "\n\t"
  1685. "brcc L_%=_millis_inc_sext" "\n\t"
  1686. "L_%=_ovcount:"
  1687. "lds r24, timer0_micros_count" "\n\t"
  1688. "subi r24, 256 - %2" "\n\t"
  1689. "sts timer0_micros_count, r24" "\n\t"
  1690. "brcs L_%=_end" "\n\t"
  1691. "lds r24, timer0_micros_count+1" "\n\t"
  1692. "sbci r24, 255" "\n\t"
  1693. "sts timer0_micros_count+1, r24" "\n\t"
  1694. "brcs L_%=_end" "\n\t"
  1695. "lds r24, timer0_micros_count+2" "\n\t"
  1696. "sbci r24, 255" "\n\t"
  1697. "sts timer0_micros_count+2, r24" "\n\t"
  1698. "L_%=_end:"
  1699. "pop r24" "\n\t"
  1700. "out __SREG__, r24" "\n\t"
  1701. "pop r24" "\n\t"
  1702. "reti"
  1703. :
  1704. : "M" (TIMER0_FRACT_INC), "M" (TIMER0_MILLIS_INC),
  1705. "M" (TIMER0_MICROS_INC)
  1706. );
  1707. }
  1708. void delay(uint32_t ms)
  1709. {
  1710. uint16_t start = (uint16_t)micros();
  1711. while (ms > 0) {
  1712. if (((uint16_t)micros() - start) >= 1000) {
  1713. ms--;
  1714. start += 1000;
  1715. }
  1716. }
  1717. #if 0
  1718. // This doesn't save a lot of power on Teensy, which
  1719. // lacks the power saving flash memory of some newer
  1720. // chips, and also usually consumes lots of power for
  1721. // the USB port. There is also some strange (probably
  1722. // hardware) bug involving the A/D mux for the first
  1723. // conversion after the processor wakes from idle mode.
  1724. uint32_t start;
  1725. if (!(SREG & 0x80)) {
  1726. // if interrupts are disabled, busy loop
  1727. while (ms--) delayMicroseconds(1000);
  1728. return;
  1729. }
  1730. // if interrupt are enabled, use low power idle mode
  1731. cli();
  1732. start = timer0_millis_count;
  1733. do {
  1734. _SLEEP_CONTROL_REG = SLEEP_MODE_IDLE | _SLEEP_ENABLE_MASK;
  1735. sei();
  1736. sleep_cpu();
  1737. _SLEEP_CONTROL_REG = SLEEP_MODE_IDLE;
  1738. cli();
  1739. } while (timer0_millis_count - start <= ms);
  1740. sei();
  1741. #endif
  1742. }
  1743. uint32_t _micros(void)
  1744. {
  1745. register uint32_t out asm("r22");
  1746. asm volatile(
  1747. "in __tmp_reg__, __SREG__" "\n\t"
  1748. "cli" "\n\t"
  1749. "in %A0, %2" "\n\t"
  1750. "in __zero_reg__, %3" "\n\t"
  1751. "lds %B0, timer0_micros_count" "\n\t"
  1752. "lds %C0, timer0_micros_count+1" "\n\t"
  1753. "lds %D0, timer0_micros_count+2" "\n\t"
  1754. "out __SREG__, __tmp_reg__" "\n\t"
  1755. "sbrs __zero_reg__, %4" "\n\t"
  1756. "rjmp L_%=_skip" "\n\t"
  1757. "cpi %A0, 255" "\n\t"
  1758. "breq L_%=_skip" "\n\t"
  1759. "subi %B0, 256 - %1" "\n\t"
  1760. "sbci %C0, 255" "\n\t"
  1761. "sbci %D0, 255" "\n\t"
  1762. "L_%=_skip:"
  1763. "clr __zero_reg__" "\n\t"
  1764. "clr __tmp_reg__" "\n\t"
  1765. #if F_CPU == 16000000L || F_CPU == 8000000L || F_CPU == 4000000L
  1766. "lsl %A0" "\n\t"
  1767. "rol __tmp_reg__" "\n\t"
  1768. "lsl %A0" "\n\t"
  1769. "rol __tmp_reg__" "\n\t"
  1770. #if F_CPU == 8000000L || F_CPU == 4000000L
  1771. "lsl %A0" "\n\t"
  1772. "rol __tmp_reg__" "\n\t"
  1773. #endif
  1774. #if F_CPU == 4000000L
  1775. "lsl %A0" "\n\t"
  1776. "rol __tmp_reg__" "\n\t"
  1777. #endif
  1778. "or %B0, __tmp_reg__" "\n\t"
  1779. #endif
  1780. #if F_CPU == 1000000L || F_CPU == 2000000L
  1781. "lsr %A0" "\n\t"
  1782. "ror __tmp_reg__" "\n\t"
  1783. "lsr %A0" "\n\t"
  1784. "ror __tmp_reg__" "\n\t"
  1785. #if F_CPU == 2000000L
  1786. "lsr %A0" "\n\t"
  1787. "ror __tmp_reg__" "\n\t"
  1788. #endif
  1789. "or %B0, %A0" "\n\t"
  1790. "mov %A0, __tmp_reg__" "\n\t"
  1791. #endif
  1792. : "=d" (out)
  1793. : "M" (TIMER0_MICROS_INC),
  1794. "I" (_SFR_IO_ADDR(TCNT0)),
  1795. "I" (_SFR_IO_ADDR(TIFR0)),
  1796. "I" (TOV0)
  1797. : "r0"
  1798. );
  1799. return out;
  1800. }