Arduboy2 Library  6.0.0
Arduboy2Core.cpp
Go to the documentation of this file.
1 
7 #include "Arduboy2Core.h"
8 
9 #include <avr/wdt.h>
10 
11 
12 //========================================
13 //========== class Arduboy2Core ==========
14 //========================================
15 
16 // Commands sent to the OLED display to initialize it
17 const PROGMEM uint8_t Arduboy2Core::lcdBootProgram[] = {
18  // boot defaults are commented out but left here in case they
19  // might prove useful for reference
20  //
21  // Further reading: https://www.adafruit.com/datasheets/SSD1306.pdf
22  //
23  // Display Off
24  // 0xAE,
25 
26  // Set Display Clock Divisor v = 0xF0
27  // default is 0x80
28  0xD5, 0xF0,
29 
30  // Set Multiplex Ratio v = 0x3F
31  // 0xA8, 0x3F,
32 
33  // Set Display Offset v = 0
34  // 0xD3, 0x00,
35 
36  // Set Start Line (0)
37  // 0x40,
38 
39  // Charge Pump Setting v = enable (0x14)
40  // default is disabled
41  0x8D, 0x14,
42 
43  // Set Segment Re-map (A0) | (b0001)
44  // default is (b0000)
45  0xA1,
46 
47  // Set COM Output Scan Direction
48  0xC8,
49 
50  // Set COM Pins v
51  // 0xDA, 0x12,
52 
53  // Set Contrast v = 0xCF
54  0x81, 0xCF,
55 
56  // Set Precharge = 0xF1
57  0xD9, 0xF1,
58 
59  // Set VCom Detect
60  // 0xDB, 0x40,
61 
62  // Entire Display ON
63  // 0xA4,
64 
65  // Set normal/inverse display
66  // 0xA6,
67 
68  // Display On
69  0xAF,
70 
71  // set display mode = horizontal addressing mode (0x00)
72  0x20, 0x00,
73 
74  // set col address range
75  // 0x21, 0x00, COLUMN_ADDRESS_END,
76 
77  // set page address range
78  // 0x22, 0x00, PAGE_ADDRESS_END
79 };
80 
82 {
83  #ifdef ARDUBOY_SET_CPU_8MHZ
84  // ARDUBOY_SET_CPU_8MHZ will be set by the IDE using boards.txt
85  setCPUSpeed8MHz();
86  #endif
87 
88  // Select the ADC input here so a delay isn't required in generateRandomSeed()
89  ADMUX = RAND_SEED_IN_ADMUX;
90 
91  bootPins();
92  bootSPI();
93  bootOLED();
94  bootPowerSaving();
95 }
96 
97 #ifdef ARDUBOY_SET_CPU_8MHZ
98 // If we're compiling for 8MHz we need to slow the CPU down because the
99 // hardware clock on the Arduboy is 16MHz.
100 // We also need to readjust the PLL prescaler because the Arduino USB code
101 // likely will have incorrectly set it for an 8MHz hardware clock.
102 void Arduboy2Core::setCPUSpeed8MHz()
103 {
104  uint8_t oldSREG = SREG;
105  cli(); // suspend interrupts
106  PLLCSR = _BV(PINDIV); // dissable the PLL and set prescale for 16MHz)
107  CLKPR = _BV(CLKPCE); // allow reprogramming clock
108  CLKPR = 1; // set clock divisor to 2 (0b0001)
109  PLLCSR = _BV(PLLE) | _BV(PINDIV); // enable the PLL (with 16MHz prescale)
110  SREG = oldSREG; // restore interrupts
111 }
112 #endif
113 
114 // Pins are set to the proper modes and levels for the specific hardware.
115 // This routine must be modified if any pins are moved to a different port
116 void Arduboy2Core::bootPins()
117 {
118 #ifdef ARDUBOY_10
119 
120  // Port B INPUT_PULLUP or HIGH
121  PORTB |= _BV(RED_LED_BIT) | _BV(GREEN_LED_BIT) | _BV(BLUE_LED_BIT) |
122  _BV(B_BUTTON_BIT);
123  // Port B INPUT or LOW (none)
124  // Port B inputs
125  DDRB &= ~(_BV(B_BUTTON_BIT) | _BV(SPI_MISO_BIT));
126  // Port B outputs
127  DDRB |= _BV(RED_LED_BIT) | _BV(GREEN_LED_BIT) | _BV(BLUE_LED_BIT) |
128  _BV(SPI_MOSI_BIT) | _BV(SPI_SCK_BIT) | _BV(SPI_SS_BIT);
129 
130  // Port C
131  // Speaker: Not set here. Controlled by audio class
132 
133  // Port D INPUT_PULLUP or HIGH
134  PORTD |= _BV(CS_BIT);
135  // Port D INPUT or LOW
136  PORTD &= ~(_BV(RST_BIT));
137  // Port D inputs (none)
138  // Port D outputs
139  DDRD |= _BV(RST_BIT) | _BV(CS_BIT) | _BV(DC_BIT);
140 
141  // Port E INPUT_PULLUP or HIGH
142  PORTE |= _BV(A_BUTTON_BIT);
143  // Port E INPUT or LOW (none)
144  // Port E inputs
145  DDRE &= ~(_BV(A_BUTTON_BIT));
146  // Port E outputs (none)
147 
148  // Port F INPUT_PULLUP or HIGH
149  PORTF |= _BV(LEFT_BUTTON_BIT) | _BV(RIGHT_BUTTON_BIT) |
150  _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT);
151  // Port F INPUT or LOW
152  PORTF &= ~(_BV(RAND_SEED_IN_BIT));
153  // Port F inputs
154  DDRF &= ~(_BV(LEFT_BUTTON_BIT) | _BV(RIGHT_BUTTON_BIT) |
155  _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT) |
156  _BV(RAND_SEED_IN_BIT));
157  // Port F outputs (none)
158 
159 #elif defined(AB_DEVKIT)
160 
161  // Port B INPUT_PULLUP or HIGH
162  PORTB |= _BV(LEFT_BUTTON_BIT) | _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT) |
163  _BV(BLUE_LED_BIT);
164  // Port B INPUT or LOW (none)
165  // Port B inputs
166  DDRB &= ~(_BV(LEFT_BUTTON_BIT) | _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT) |
167  _BV(SPI_MISO_BIT));
168  // Port B outputs
169  DDRB |= _BV(SPI_MOSI_BIT) | _BV(SPI_SCK_BIT) | _BV(SPI_SS_BIT) |
170  _BV(BLUE_LED_BIT);
171 
172  // Port C INPUT_PULLUP or HIGH
173  PORTC |= _BV(RIGHT_BUTTON_BIT);
174  // Port C INPUT or LOW (none)
175  // Port C inputs
176  DDRC &= ~(_BV(RIGHT_BUTTON_BIT));
177  // Port C outputs (none)
178 
179  // Port D INPUT_PULLUP or HIGH
180  PORTD |= _BV(CS_BIT);
181  // Port D INPUT or LOW
182  PORTD &= ~(_BV(RST_BIT));
183  // Port D inputs (none)
184  // Port D outputs
185  DDRD |= _BV(RST_BIT) | _BV(CS_BIT) | _BV(DC_BIT);
186 
187  // Port E (none)
188 
189  // Port F INPUT_PULLUP or HIGH
190  PORTF |= _BV(A_BUTTON_BIT) | _BV(B_BUTTON_BIT);
191  // Port F INPUT or LOW
192  PORTF &= ~(_BV(RAND_SEED_IN_BIT));
193  // Port F inputs
194  DDRF &= ~(_BV(A_BUTTON_BIT) | _BV(B_BUTTON_BIT) | _BV(RAND_SEED_IN_BIT));
195  // Port F outputs (none)
196  // Speaker: Not set here. Controlled by audio class
197 
198 #endif
199 }
200 
201 void Arduboy2Core::bootOLED()
202 {
203  // reset the display
204  delayShort(5); // reset pin should be low here. let it stay low a while
205  bitSet(RST_PORT, RST_BIT); // set high to come out of reset
206  delayShort(5); // wait a while
207 
208  // select the display (permanently, since nothing else is using SPI)
209  bitClear(CS_PORT, CS_BIT);
210 
211  // run our customized boot-up command sequence against the
212  // OLED to initialize it properly for Arduboy
213  LCDCommandMode();
214  for (uint8_t i = 0; i < sizeof(lcdBootProgram); i++) {
215  SPItransfer(pgm_read_byte(lcdBootProgram + i));
216  }
217  LCDDataMode();
218 }
219 
221 {
222  bitSet(DC_PORT, DC_BIT);
223 }
224 
226 {
227  bitClear(DC_PORT, DC_BIT);
228 }
229 
230 // Initialize the SPI interface for the display
231 void Arduboy2Core::bootSPI()
232 {
233 // master, mode 0, MSB first, CPU clock / 2 (8MHz)
234  SPCR = _BV(SPE) | _BV(MSTR);
235  SPSR = _BV(SPI2X);
236 }
237 
238 // Write to the SPI bus (MOSI pin)
239 void Arduboy2Core::SPItransfer(uint8_t data)
240 {
241  SPDR = data;
242  /*
243  * The following NOP introduces a small delay that can prevent the wait
244  * loop from iterating when running at the maximum speed. This gives
245  * about 10% more speed, even if it seems counter-intuitive. At lower
246  * speeds it is unnoticed.
247  */
248  asm volatile("nop");
249  while (!(SPSR & _BV(SPIF))) { } // wait
250 }
251 
252 // Write to and read from the SPI bus (out to MOSI pin, in from MISO pin)
253 uint8_t Arduboy2Core::SPItransferAndRead(uint8_t data)
254 {
255  SPItransfer(data);
256  return SPDR;
257 }
258 
260 {
261  if (buttonsState() == UP_BUTTON)
262  {
264 
265 #ifndef ARDUBOY_CORE // for Arduboy core timer 0 should remain enabled
266  // prevent the bootloader magic number from being overwritten by timer 0
267  // when a timer variable overlaps the magic number location
268  power_timer0_disable();
269 #endif
270 
271  while (true) { }
272  }
273 }
274 
275 
276 /* Power Management */
277 
279 {
280  SMCR = _BV(SE); // select idle mode and enable sleeping
281  sleep_cpu();
282  SMCR = 0; // disable sleeping
283 }
284 
285 void Arduboy2Core::bootPowerSaving()
286 {
287  // disable Two Wire Interface (I2C) and the ADC
288  // All other bits will be written with 0 so will be enabled
289  PRR0 = _BV(PRTWI) | _BV(PRADC);
290  // disable USART1
291  PRR1 |= _BV(PRUSART1);
292 }
293 
294 // Shut down the display
296 {
297  LCDCommandMode();
298  SPItransfer(0xAE); // display off
299  SPItransfer(0x8D); // charge pump:
300  SPItransfer(0x10); // disable
301  delayShort(250);
302  bitClear(RST_PORT, RST_BIT); // set display reset pin low (reset state)
303 }
304 
305 // Restart the display after a displayOff()
307 {
308  bootOLED();
309 }
310 
311 
312 /* Drawing */
313 
314 void Arduboy2Core::paint8Pixels(uint8_t pixels)
315 {
316  SPItransfer(pixels);
317 }
318 
319 void Arduboy2Core::paintScreen(const uint8_t *image)
320 {
321  for (int i = 0; i < (HEIGHT*WIDTH)/8; i++)
322  {
323  SPItransfer(pgm_read_byte(image + i));
324  }
325 }
326 
327 // paint from a memory buffer, this should be FAST as it's likely what
328 // will be used by any buffer based subclass
329 //
330 // The following assembly code runs "open loop". It relies on instruction
331 // execution times to allow time for each byte of data to be clocked out.
332 // It is specifically tuned for a 16MHz CPU clock and SPI clocking at 8MHz.
333 void Arduboy2Core::paintScreen(uint8_t image[], bool clear)
334 {
335  uint16_t count;
336 
337  asm volatile (
338  " ldi %A[count], %[len_lsb] \n\t" //for (len = WIDTH * HEIGHT / 8)
339  " ldi %B[count], %[len_msb] \n\t"
340  "1: ld __tmp_reg__, %a[ptr] ;2 \n\t" //tmp = *(image)
341  " out %[spdr], __tmp_reg__ ;1 \n\t" //SPDR = tmp
342  " cpse %[clear], __zero_reg__ ;1/2 \n\t" //if (clear) tmp = 0;
343  " mov __tmp_reg__, __zero_reg__ ;1 \n\t"
344  "2: sbiw %A[count], 1 ;2 \n\t" //len --
345  " sbrc %A[count], 0 ;1/2 \n\t" //loop twice for cheap delay
346  " rjmp 2b ;2 \n\t"
347  " st %a[ptr]+, __tmp_reg__ ;2 \n\t" //*(image++) = tmp
348  " brne 1b ;1/2 :18 \n\t" //len > 0
349  " in __tmp_reg__, %[spsr] \n\t" //read SPSR to clear SPIF
350  : [ptr] "+&e" (image),
351  [count] "=&w" (count)
352  : [spdr] "I" (_SFR_IO_ADDR(SPDR)),
353  [spsr] "I" (_SFR_IO_ADDR(SPSR)),
354  [len_msb] "M" (WIDTH * (HEIGHT / 8 * 2) >> 8), // 8: pixels per byte
355  [len_lsb] "M" (WIDTH * (HEIGHT / 8 * 2) & 0xFF), // 2: for delay loop multiplier
356  [clear] "r" (clear)
357  );
358 }
359 #if 0
360 // For reference, this is the "closed loop" C++ version of paintScreen()
361 // used prior to the above version.
362 void Arduboy2Core::paintScreen(uint8_t image[], bool clear)
363 {
364  uint8_t c;
365  int i = 0;
366 
367  if (clear)
368  {
369  SPDR = image[i]; // set the first SPI data byte to get things started
370  image[i++] = 0; // clear the first image byte
371  }
372  else
373  SPDR = image[i++];
374 
375  // the code to iterate the loop and get the next byte from the buffer is
376  // executed while the previous byte is being sent out by the SPI controller
377  while (i < (HEIGHT * WIDTH) / 8)
378  {
379  // get the next byte. It's put in a local variable so it can be sent as
380  // as soon as possible after the sending of the previous byte has completed
381  if (clear)
382  {
383  c = image[i];
384  // clear the byte in the image buffer
385  image[i++] = 0;
386  }
387  else
388  c = image[i++];
389 
390  while (!(SPSR & _BV(SPIF))) { } // wait for the previous byte to be sent
391 
392  // put the next byte in the SPI data register. The SPI controller will
393  // clock it out while the loop continues and gets the next byte ready
394  SPDR = c;
395  }
396  while (!(SPSR & _BV(SPIF))) { } // wait for the last byte to be sent
397 }
398 #endif
399 
401 {
402  for (int i = 0; i < (HEIGHT*WIDTH)/8; i++)
403  SPItransfer(0x00);
404 }
405 
406 void Arduboy2Core::sendLCDCommand(uint8_t command)
407 {
408  LCDCommandMode();
409  SPItransfer(command);
410  LCDDataMode();
411 }
412 
413 // invert the display or set to normal
414 // when inverted, a pixel set to 0 will be on
415 void Arduboy2Core::invert(bool inverse)
416 {
417  sendLCDCommand(inverse ? OLED_PIXELS_INVERTED : OLED_PIXELS_NORMAL);
418 }
419 
420 // turn all display pixels on, ignoring buffer contents
421 // or set to normal buffer display
423 {
424  sendLCDCommand(on ? OLED_ALL_PIXELS_ON : OLED_PIXELS_FROM_RAM);
425 }
426 
427 // flip the display vertically or set to normal
428 void Arduboy2Core::flipVertical(bool flipped)
429 {
430  sendLCDCommand(flipped ? OLED_VERTICAL_FLIPPED : OLED_VERTICAL_NORMAL);
431 }
432 
433 // flip the display horizontally or set to normal
435 {
436  sendLCDCommand(flipped ? OLED_HORIZ_FLIPPED : OLED_HORIZ_NORMAL);
437 }
438 
439 /* RGB LED */
440 
441 void Arduboy2Core::setRGBled(uint8_t red, uint8_t green, uint8_t blue)
442 {
443 #ifdef ARDUBOY_10 // RGB, all the pretty colors
444  // timer 0: Fast PWM, OC0A clear on compare / set at top
445  // We must stay in Fast PWM mode because timer 0 is used for system timing.
446  // We can't use "inverted" mode because it won't allow full shut off.
447  TCCR0A = _BV(COM0A1) | _BV(WGM01) | _BV(WGM00);
448  OCR0A = 255 - green;
449  // timer 1: Phase correct PWM 8 bit
450  // OC1A and OC1B set on up-counting / clear on down-counting (inverted). This
451  // allows the value to be directly loaded into the OCR with common anode LED.
452  TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0) | _BV(WGM10);
453  OCR1AL = blue;
454  OCR1BL = red;
455 #elif defined(AB_DEVKIT)
456  // only blue on DevKit, which is not PWM capable
457  (void)red; // parameter unused
458  (void)green; // parameter unused
459  bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, blue ? RGB_ON : RGB_OFF);
460 #endif
461 }
462 
463 void Arduboy2Core::setRGBled(uint8_t color, uint8_t val)
464 {
465 #ifdef ARDUBOY_10
466  if (color == RED_LED)
467  {
468  OCR1BL = val;
469  }
470  else if (color == GREEN_LED)
471  {
472  OCR0A = 255 - val;
473  }
474  else if (color == BLUE_LED)
475  {
476  OCR1AL = val;
477  }
478 #elif defined(AB_DEVKIT)
479  // only blue on DevKit, which is not PWM capable
480  if (color == BLUE_LED)
481  {
482  bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, val ? RGB_ON : RGB_OFF);
483  }
484 #endif
485 }
486 
488 {
489 #ifdef ARDUBOY_10
490  // clear the COM bits to return the pins to normal I/O mode
491  TCCR0A = _BV(WGM01) | _BV(WGM00);
492  TCCR1A = _BV(WGM10);
493 #endif
494 }
495 
496 void Arduboy2Core::digitalWriteRGB(uint8_t red, uint8_t green, uint8_t blue)
497 {
498 #ifdef ARDUBOY_10
499  bitWrite(RED_LED_PORT, RED_LED_BIT, red);
500  bitWrite(GREEN_LED_PORT, GREEN_LED_BIT, green);
501  bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, blue);
502 #elif defined(AB_DEVKIT)
503  // only blue on DevKit
504  (void)red; // parameter unused
505  (void)green; // parameter unused
506  bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, blue);
507 #endif
508 }
509 
510 void Arduboy2Core::digitalWriteRGB(uint8_t color, uint8_t val)
511 {
512 #ifdef ARDUBOY_10
513  if (color == RED_LED)
514  {
515  bitWrite(RED_LED_PORT, RED_LED_BIT, val);
516  }
517  else if (color == GREEN_LED)
518  {
519  bitWrite(GREEN_LED_PORT, GREEN_LED_BIT, val);
520  }
521  else if (color == BLUE_LED)
522  {
523  bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, val);
524  }
525 #elif defined(AB_DEVKIT)
526  // only blue on DevKit
527  if (color == BLUE_LED)
528  {
529  bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, val);
530  }
531 #endif
532 }
533 
534 /* Buttons */
535 
537 {
538  uint8_t buttons;
539 
540 #ifdef ARDUBOY_10
541  // up, right, left, down
542  buttons = ((~PINF) &
543  (_BV(UP_BUTTON_BIT) | _BV(RIGHT_BUTTON_BIT) |
544  _BV(LEFT_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT)));
545  // A
546  if (bitRead(A_BUTTON_PORTIN, A_BUTTON_BIT) == 0) { buttons |= A_BUTTON; }
547  // B
548  if (bitRead(B_BUTTON_PORTIN, B_BUTTON_BIT) == 0) { buttons |= B_BUTTON; }
549 #elif defined(AB_DEVKIT)
550  // down, left, up
551  buttons = ((~PINB) &
552  (_BV(DOWN_BUTTON_BIT) | _BV(LEFT_BUTTON_BIT) | _BV(UP_BUTTON_BIT)));
553  // right
554  if (bitRead(RIGHT_BUTTON_PORTIN, RIGHT_BUTTON_BIT) == 0) { buttons |= RIGHT_BUTTON; }
555  // A
556  if (bitRead(A_BUTTON_PORTIN, A_BUTTON_BIT) == 0) { buttons |= A_BUTTON; }
557  // B
558  if (bitRead(B_BUTTON_PORTIN, B_BUTTON_BIT) == 0) { buttons |= B_BUTTON; }
559 #endif
560 
561  return buttons;
562 }
563 
565 {
566  unsigned long seed;
567 
568  power_adc_enable(); // ADC on
569 
570  // do an ADC read from an unconnected input pin
571  ADCSRA |= _BV(ADSC); // start conversion (ADMUX has been pre-set in boot())
572  while (bit_is_set(ADCSRA, ADSC)) { } // wait for conversion complete
573 
574  seed = ((unsigned long)ADC << 16) + micros();
575 
576  power_adc_disable(); // ADC off
577 
578  return seed;
579 }
580 
581 // delay in ms with 16 bit duration
582 void Arduboy2Core::delayShort(uint16_t ms)
583 {
584  delay((unsigned long) ms);
585 }
586 
588 {
589  cli();
590  // set bootloader magic key
591  // storing two uint8_t instead of one uint16_t saves an instruction
592  // when high and low bytes of the magic key are the same
593  *(uint8_t *)MAGIC_KEY_POS = lowByte(MAGIC_KEY);
594  *(uint8_t *)(MAGIC_KEY_POS + 1) = highByte(MAGIC_KEY);
595  // enable watchdog timer reset, with 16ms timeout
596  wdt_reset();
597  WDTCSR = (_BV(WDCE) | _BV(WDE));
598  WDTCSR = _BV(WDE);
599  while (true) { }
600 }
601 
602 
603 //=========================================
604 //========== class Arduboy2NoUSB ==========
605 //=========================================
606 
607 void Arduboy2NoUSB::mainNoUSB()
608 {
609  // disable USB
610  UDCON = _BV(DETACH);
611  UDIEN = 0;
612  UDINT = 0;
613  USBCON = _BV(FRZCLK);
614  UHWCON = 0;
615  power_usb_disable();
616 
617  init();
618 
619  // This would normally be done in the USB code that uses the TX and RX LEDs
620  TX_RX_LED_INIT;
621  TXLED0;
622  RXLED0;
623 
624  // Set the DOWN button pin for INPUT_PULLUP
625  bitSet(DOWN_BUTTON_PORT, DOWN_BUTTON_BIT);
626  bitClear(DOWN_BUTTON_DDR, DOWN_BUTTON_BIT);
627 
628  // Delay to give time for the pin to be pulled high if it was floating
630 
631  // if the DOWN button is pressed
632  if (bitRead(DOWN_BUTTON_PORTIN, DOWN_BUTTON_BIT) == 0) {
634  }
635 
636  // The remainder is a copy of the Arduino main() function with the
637  // USB code and other unneeded code commented out.
638  // init() was called above.
639  // The call to function initVariant() is commented out to fix compiler
640  // error: "multiple definition of 'main'".
641  // The return statement is removed since this function is type void.
642 
643 // init();
644 
645 // initVariant();
646 
647 //#if defined(USBCON)
648 // USBDevice.attach();
649 //#endif
650 
651  setup();
652 
653  for (;;) {
654  loop();
655 // if (serialEventRun) serialEventRun();
656  }
657 
658 // return 0;
659 }
660 
Arduboy2Core::boot
static void boot()
Initialize the Arduboy's hardware.
Definition: Arduboy2Core.cpp:81
Arduboy2Core::sendLCDCommand
static void sendLCDCommand(uint8_t command)
Send a single command byte to the display.
Definition: Arduboy2Core.cpp:406
RIGHT_BUTTON
#define RIGHT_BUTTON
Definition: Arduboy2Core.h:68
Arduboy2Core::displayOff
static void displayOff()
Turn the display off.
Definition: Arduboy2Core.cpp:295
RGB_OFF
#define RGB_OFF
Definition: Arduboy2Core.h:35
A_BUTTON
#define A_BUTTON
Definition: Arduboy2Core.h:71
Arduboy2Core::idle
static void idle()
Idle the CPU to save power.
Definition: Arduboy2Core.cpp:278
Arduboy2Core::flipVertical
static void flipVertical(bool flipped)
Flip the display vertically or set it back to normal.
Definition: Arduboy2Core.cpp:428
BLUE_LED
#define BLUE_LED
Definition: Arduboy2Core.h:54
Arduboy2Core::generateRandomSeed
static unsigned long generateRandomSeed()
Create a seed suitable for use with a pseudorandom number generator.
Definition: Arduboy2Core.cpp:564
B_BUTTON
#define B_BUTTON
Definition: Arduboy2Core.h:72
Arduboy2Core::paintScreen
static void paintScreen(const uint8_t *image)
Paints an entire image directly to the display from program memory.
Definition: Arduboy2Core.cpp:319
GREEN_LED
#define GREEN_LED
Definition: Arduboy2Core.h:53
RGB_ON
#define RGB_ON
Definition: Arduboy2Core.h:34
Arduboy2Core::blank
static void blank()
Blank the display screen by setting all pixels off.
Definition: Arduboy2Core.cpp:400
Arduboy2Core::safeMode
static void safeMode()
Allow upload when the bootloader "magic number" could be corrupted.
Definition: Arduboy2Core.cpp:259
WIDTH
#define WIDTH
Definition: Arduboy2Core.h:242
Arduboy2Core::SPItransferAndRead
static uint8_t SPItransferAndRead(uint8_t data)
Transfer a byte to, and read a byte from, the SPI bus.
Definition: Arduboy2Core.cpp:253
Arduboy2Core::invert
static void invert(bool inverse)
Invert the entire display or set it back to normal.
Definition: Arduboy2Core.cpp:415
Arduboy2Core.h
The Arduboy2Core class for Arduboy hardware initilization and control.
Arduboy2Core::displayOn
static void displayOn()
Turn the display on.
Definition: Arduboy2Core.cpp:306
Arduboy2Core::buttonsState
static uint8_t buttonsState()
Get the current state of all buttons as a bitmask.
Definition: Arduboy2Core.cpp:536
Arduboy2Core::flipHorizontal
static void flipHorizontal(bool flipped)
Flip the display horizontally or set it back to normal.
Definition: Arduboy2Core.cpp:434
Arduboy2Core::exitToBootloader
static void exitToBootloader()
Exit the sketch and start the bootloader.
Definition: Arduboy2Core.cpp:587
Arduboy2Core::setRGBled
static void setRGBled(uint8_t red, uint8_t green, uint8_t blue)
Set the light output of the RGB LED.
Definition: Arduboy2Core.cpp:441
UP_BUTTON
#define UP_BUTTON
Definition: Arduboy2Core.h:69
Arduboy2Core::LCDDataMode
static void LCDDataMode()
Put the display into data mode.
Definition: Arduboy2Core.cpp:220
Arduboy2Core::digitalWriteRGB
static void digitalWriteRGB(uint8_t red, uint8_t green, uint8_t blue)
Set the RGB LEDs digitally, to either fully on or fully off.
Definition: Arduboy2Core.cpp:496
RED_LED
#define RED_LED
Definition: Arduboy2Core.h:52
Arduboy2Core::delayShort
static void delayShort(uint16_t ms) __attribute__((noinline))
Delay for the number of milliseconds, specified as a 16 bit value.
Definition: Arduboy2Core.cpp:582
Arduboy2Core::paint8Pixels
static void paint8Pixels(uint8_t pixels)
Paint 8 pixels vertically to the display.
Definition: Arduboy2Core.cpp:314
Arduboy2Core::allPixelsOn
static void allPixelsOn(bool on)
Turn all display pixels on or display the buffer contents.
Definition: Arduboy2Core.cpp:422
Arduboy2Core::freeRGBled
static void freeRGBled()
Relinquish analog control of the RGB LED.
Definition: Arduboy2Core.cpp:487
HEIGHT
#define HEIGHT
Definition: Arduboy2Core.h:243
Arduboy2Core::LCDCommandMode
static void LCDCommandMode()
Put the display into command mode.
Definition: Arduboy2Core.cpp:225
Arduboy2Core::SPItransfer
static void SPItransfer(uint8_t data)
Transfer a byte to the display.
Definition: Arduboy2Core.cpp:239