From 1e7f251ce0671ee3549c34c59c5a6e1ee8130d80 Mon Sep 17 00:00:00 2001 From: Scott Allen Date: Wed, 15 Mar 2017 14:10:19 -0400 Subject: [PATCH] Direct control of ports and pins This eliminates calls to pinMode(), digitalWrite(), functions to initialize hardware, etc. New 2 parameter version of digitalWriteRGB() added, which sets an individual RGB LED on or off digitally. New function SPItransfer() added to replace Arduino SPI.transfer(). --- keywords.txt | 1 + src/Arduboy2.cpp | 20 ++-- src/Arduboy2Audio.cpp | 18 ++-- src/Arduboy2Core.cpp | 229 +++++++++++++++++++++++++++--------------- src/Arduboy2Core.h | 192 +++++++++++++++++++++++++++-------- 5 files changed, 319 insertions(+), 141 deletions(-) diff --git a/keywords.txt b/keywords.txt index 28442b8..d51ca64 100644 --- a/keywords.txt +++ b/keywords.txt @@ -75,6 +75,7 @@ setTextColor KEYWORD2 setTextBackground KEYWORD2 setTextSize KEYWORD2 setTextWrap KEYWORD2 +SPItransfer KEYWORD2 systemButtons KEYWORD2 toggle KEYWORD2 width KEYWORD2 diff --git a/src/Arduboy2.cpp b/src/Arduboy2.cpp index e3666bb..69b6043 100644 --- a/src/Arduboy2.cpp +++ b/src/Arduboy2.cpp @@ -71,23 +71,23 @@ void Arduboy2Base::flashlight() void Arduboy2Base::systemButtons() { while (pressed(B_BUTTON)) { - digitalWrite(BLUE_LED, RGB_ON); // turn on blue LED + digitalWriteRGB(BLUE_LED, RGB_ON); // turn on blue LED sysCtrlSound(UP_BUTTON + B_BUTTON, GREEN_LED, 0xff); sysCtrlSound(DOWN_BUTTON + B_BUTTON, RED_LED, 0); delay(200); } - digitalWrite(BLUE_LED, RGB_OFF); // turn off blue LED + digitalWriteRGB(BLUE_LED, RGB_OFF); // turn off blue LED } void Arduboy2Base::sysCtrlSound(uint8_t buttons, uint8_t led, uint8_t eeVal) { if (pressed(buttons)) { - digitalWrite(BLUE_LED, RGB_OFF); // turn off blue LED + digitalWriteRGB(BLUE_LED, RGB_OFF); // turn off blue LED delay(200); - digitalWrite(led, RGB_ON); // turn on "acknowledge" LED + digitalWriteRGB(led, RGB_ON); // turn on "acknowledge" LED EEPROM.update(EEPROM_AUDIO_ON_OFF, eeVal); delay(500); - digitalWrite(led, RGB_OFF); // turn off "acknowledge" LED + digitalWriteRGB(led, RGB_OFF); // turn off "acknowledge" LED while (pressed(buttons)) {} // Wait for button release } @@ -95,7 +95,7 @@ void Arduboy2Base::sysCtrlSound(uint8_t buttons, uint8_t led, uint8_t eeVal) { void Arduboy2Base::bootLogo() { - digitalWrite(RED_LED, RGB_ON); + digitalWriteRGB(RED_LED, RGB_ON); for (int8_t y = -18; y <= 24; y++) { if (pressed(RIGHT_BUTTON)) { @@ -104,10 +104,12 @@ void Arduboy2Base::bootLogo() } if (y == -4) { - digitalWriteRGB(RGB_OFF, RGB_ON, RGB_OFF); // green LED on + digitalWriteRGB(RED_LED, RGB_OFF); // red LED off + digitalWriteRGB(GREEN_LED, RGB_ON); // green LED on } else if (y == 24) { - digitalWriteRGB(RGB_OFF, RGB_OFF, RGB_ON); // blue LED on + digitalWriteRGB(GREEN_LED, RGB_OFF); // green LED off + digitalWriteRGB(BLUE_LED, RGB_ON); // blue LED on } clear(); @@ -122,7 +124,7 @@ void Arduboy2Base::bootLogo() } delay(750); - digitalWrite(BLUE_LED, RGB_OFF); + digitalWriteRGB(BLUE_LED, RGB_OFF); bootLogoExtra(); } diff --git a/src/Arduboy2Audio.cpp b/src/Arduboy2Audio.cpp index 901f627..701f806 100644 --- a/src/Arduboy2Audio.cpp +++ b/src/Arduboy2Audio.cpp @@ -11,12 +11,12 @@ bool Arduboy2Audio::audio_enabled = false; void Arduboy2Audio::on() { - // fire up audio pins + // fire up audio pins by seting them as outputs #ifdef ARDUBOY_10 - pinMode(PIN_SPEAKER_1, OUTPUT); - pinMode(PIN_SPEAKER_2, OUTPUT); + bitSet(SPEAKER_1_DDR, SPEAKER_1_BIT); + bitSet(SPEAKER_2_DDR, SPEAKER_2_BIT); #else - pinMode(PIN_SPEAKER_1, OUTPUT); + bitSet(SPEAKER_1_DDR, SPEAKER_1_BIT); #endif audio_enabled = true; } @@ -24,12 +24,12 @@ void Arduboy2Audio::on() void Arduboy2Audio::off() { audio_enabled = false; - // shut off audio pins + // shut off audio pins by setting them as inputs #ifdef ARDUBOY_10 - pinMode(PIN_SPEAKER_1, INPUT); - pinMode(PIN_SPEAKER_2, INPUT); + bitClear(SPEAKER_1_DDR, SPEAKER_1_BIT); + bitClear(SPEAKER_2_DDR, SPEAKER_2_BIT); #else - pinMode(PIN_SPEAKER_1, INPUT); + bitClear(SPEAKER_1_DDR, SPEAKER_1_BIT); #endif } @@ -50,6 +50,8 @@ void Arduboy2Audio::begin() { if (EEPROM.read(EEPROM_AUDIO_ON_OFF)) on(); + else + off(); } bool Arduboy2Audio::enabled() diff --git a/src/Arduboy2Core.cpp b/src/Arduboy2Core.cpp index 0c37a80..4e333f9 100644 --- a/src/Arduboy2Core.cpp +++ b/src/Arduboy2Core.cpp @@ -6,40 +6,6 @@ #include "Arduboy2Core.h" -// need to redeclare these here since we declare them static in .h -volatile uint8_t *Arduboy2Core::csport, *Arduboy2Core::dcport; -uint8_t Arduboy2Core::cspinmask, Arduboy2Core::dcpinmask; - -const uint8_t PROGMEM pinBootProgram[] = { - // buttons - PIN_LEFT_BUTTON, INPUT_PULLUP, - PIN_RIGHT_BUTTON, INPUT_PULLUP, - PIN_UP_BUTTON, INPUT_PULLUP, - PIN_DOWN_BUTTON, INPUT_PULLUP, - PIN_A_BUTTON, INPUT_PULLUP, - PIN_B_BUTTON, INPUT_PULLUP, - - // RGB LED (or single blue LED on the DevKit) -#ifdef ARDUBOY_10 - RED_LED, INPUT_PULLUP, // set INPUT_PULLUP to make the pin high when - RED_LED, OUTPUT, // set to OUTPUT - GREEN_LED, INPUT_PULLUP, - GREEN_LED, OUTPUT, -#endif - BLUE_LED, INPUT_PULLUP, - BLUE_LED, OUTPUT, - - // audio is specifically not included here as those pins are handled - // separately by `audio.begin()`, `audio.on()` and `audio.off()` in order - // to respect the EEPROM audio settings - - // OLED SPI - DC, OUTPUT, - CS, OUTPUT, - RST, OUTPUT, - 0 -}; - const uint8_t PROGMEM lcdBootProgram[] = { // boot defaults are commented out but left here in case they // might prove useful for reference @@ -114,7 +80,6 @@ void Arduboy2Core::boot() setCPUSpeed8MHz(); #endif - SPI.begin(); bootPins(); bootOLED(); @@ -143,58 +108,135 @@ void Arduboy2Core::setCPUSpeed8MHz() } #endif +// Pins are set to the proper modes and levels for the specific hardware. +// This routine must be modified if any pins are moved to a different port void Arduboy2Core::bootPins() { - uint8_t pin, mode; - const uint8_t *i = pinBootProgram; +#ifdef ARDUBOY_10 - while(true) { - pin = pgm_read_byte(i++); - mode = pgm_read_byte(i++); - if (pin==0) break; - pinMode(pin, mode); - } + // Port B INPUT_PULLUP or HIGH + PORTB |= _BV(RED_LED_BIT) | _BV(GREEN_LED_BIT) | _BV(BLUE_LED_BIT) | + _BV(B_BUTTON_BIT); + // Port B INPUT or LOW (none) + // Port B inputs + DDRB &= ~(_BV(B_BUTTON_BIT)); + // Port B outputs + DDRB |= _BV(RED_LED_BIT) | _BV(GREEN_LED_BIT) | _BV(BLUE_LED_BIT) | + _BV(SPI_MOSI_BIT) | _BV(SPI_SCK_BIT); - digitalWrite(RST, HIGH); - delay(1); // VDD (3.3V) goes high at start, lets just chill for a ms - digitalWrite(RST, LOW); // bring reset low - delay(10); // wait 10ms - digitalWrite(RST, HIGH); // bring out of reset + // Port C + // Speaker: Not set here. Controlled by audio class + + // Port D INPUT_PULLUP or HIGH + PORTD |= _BV(CS_BIT); + // Port D INPUT or LOW + PORTD &= ~(_BV(RST_BIT)); + // Port D inputs (none) + // Port D outputs + DDRD |= _BV(RST_BIT) | _BV(CS_BIT) | _BV(DC_BIT); + + // Port E INPUT_PULLUP or HIGH + PORTE |= _BV(A_BUTTON_BIT); + // Port E INPUT or LOW (none) + // Port E inputs + DDRE &= ~(_BV(A_BUTTON_BIT)); + // Port E outputs (none) + + // Port F INPUT_PULLUP or HIGH + PORTF |= _BV(LEFT_BUTTON_BIT) | _BV(RIGHT_BUTTON_BIT) | + _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT); + // Port F INPUT or LOW (none) + // Port F inputs + DDRF &= ~(_BV(LEFT_BUTTON_BIT) | _BV(RIGHT_BUTTON_BIT) | + _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT)); + // Port F outputs (none) + +#elif defined(AB_DEVKIT) + + // Port B INPUT_PULLUP or HIGH + PORTB |= _BV(LEFT_BUTTON_BIT) | _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT) | + _BV(BLUE_LED_BIT); + // Port B INPUT or LOW (none) + // Port B inputs + DDRB &= ~(_BV(LEFT_BUTTON_BIT) | _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT)); + // Port B outputs + DDRB |= _BV(BLUE_LED_BIT) | _BV(SPI_MOSI_BIT) | _BV(SPI_SCK_BIT); + + // Port C INPUT_PULLUP or HIGH + PORTE |= _BV(RIGHT_BUTTON_BIT); + // Port C INPUT or LOW (none) + // Port C inputs + DDRE &= ~(_BV(RIGHT_BUTTON_BIT)); + // Port C outputs (none) + + // Port D INPUT_PULLUP or HIGH + PORTD |= _BV(CS_BIT); + // Port D INPUT or LOW + PORTD &= ~(_BV(RST_BIT)); + // Port D inputs (none) + // Port D outputs + DDRD |= _BV(RST_BIT) | _BV(CS_BIT) | _BV(DC_BIT); + + // Port E (none) + + // Port F INPUT_PULLUP or HIGH + PORTF |= _BV(A_BUTTON_BIT) | _BV(B_BUTTON_BIT); + // Port F INPUT or LOW (none) + // Port F inputs + DDRF &= ~(_BV(A_BUTTON_BIT) | _BV(B_BUTTON_BIT)); + // Port F outputs (none) + // Speaker: Not set here. Controlled by audio class + +#endif } void Arduboy2Core::bootOLED() { - // setup the ports we need to talk to the OLED - csport = portOutputRegister(digitalPinToPort(CS)); - cspinmask = digitalPinToBitMask(CS); - dcport = portOutputRegister(digitalPinToPort(DC)); - dcpinmask = digitalPinToBitMask(DC); + // init SPI + // master, mode 0, MSB first, CPU clock / 2 (8MHz) + SPCR = _BV(SPE) | _BV(MSTR); + SPSR = _BV(SPI2X); - SPI.setClockDivider(SPI_CLOCK_DIV2); + // reset the display + delay(2); // reset pin should be low here. let it stay low a while + bitSet(RST_PORT, RST_BIT); // set high to come out of reset + delay(10); // wait a while + + // select the display (permanently, since nothing else is using SPI) + bitClear(CS_PORT, CS_BIT); - LCDCommandMode(); // run our customized boot-up command sequence against the // OLED to initialize it properly for Arduboy + LCDCommandMode(); for (uint8_t i = 0; i < sizeof(lcdBootProgram); i++) { - SPI.transfer(pgm_read_byte(lcdBootProgram + i)); + SPItransfer(pgm_read_byte(lcdBootProgram + i)); } LCDDataMode(); } void Arduboy2Core::LCDDataMode() { - *dcport |= dcpinmask; - *csport &= ~cspinmask; + bitSet(DC_PORT, DC_BIT); } void Arduboy2Core::LCDCommandMode() { - *csport |= cspinmask; - *dcport &= ~dcpinmask; - *csport &= ~cspinmask; + bitClear(DC_PORT, DC_BIT); } - +// Write to the SPI bus (MOSI pin) +void Arduboy2Core::SPItransfer(uint8_t data) +{ + SPDR = data; + /* + * The following NOP introduces a small delay that can prevent the wait + * loop form iterating when running at the maximum speed. This gives + * about 10% more speed, even if it seems counter-intuitive. At lower + * speeds it is unnoticed. + */ + asm volatile("nop"); + while (!(SPSR & _BV(SPIF))) { } // wait +} void Arduboy2Core::safeMode() { @@ -215,15 +257,11 @@ void Arduboy2Core::idle() void Arduboy2Core::bootPowerSaving() { - power_adc_disable(); - power_usart0_disable(); - power_twi_disable(); - // timer 0 is for millis() - // timers 1 and 3 are for music and sounds - power_timer2_disable(); - power_usart1_disable(); - // we need USB, for now (to allow triggered reboots to reprogram) - // power_usb_disable() + // disable Two Wire Interface (I2C) and the ADC + PRR0 = _BV(PRTWI) | _BV(PRADC); + // disable USART1 + PRR1 = _BV(PRUSART1); + // All other bits will be written with 0 so will be enabled } uint8_t Arduboy2Core::width() { return WIDTH; } @@ -235,14 +273,14 @@ uint8_t Arduboy2Core::height() { return HEIGHT; } void Arduboy2Core::paint8Pixels(uint8_t pixels) { - SPI.transfer(pixels); + SPItransfer(pixels); } void Arduboy2Core::paintScreen(const uint8_t *image) { for (int i = 0; i < (HEIGHT*WIDTH)/8; i++) { - SPI.transfer(pgm_read_byte(image + i)); + SPItransfer(pgm_read_byte(image + i)); } } @@ -288,13 +326,13 @@ void Arduboy2Core::paintScreen(uint8_t image[], bool clear) void Arduboy2Core::blank() { for (int i = 0; i < (HEIGHT*WIDTH)/8; i++) - SPI.transfer(0x00); + SPItransfer(0x00); } void Arduboy2Core::sendLCDCommand(uint8_t command) { LCDCommandMode(); - SPI.transfer(command); + SPItransfer(command); LCDDataMode(); } @@ -334,19 +372,48 @@ void Arduboy2Core::setRGBled(uint8_t red, uint8_t green, uint8_t blue) analogWrite(GREEN_LED, 255 - green); analogWrite(BLUE_LED, 255 - blue); #elif defined(AB_DEVKIT) - // only blue on devkit - digitalWrite(BLUE_LED, ~blue); + // only blue on DevKit, which is not PWM capable + (void)red; // parameter unused + (void)green; // parameter unused + bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, blue ? RGB_ON : RGB_OFF); #endif } void Arduboy2Core::digitalWriteRGB(uint8_t red, uint8_t green, uint8_t blue) { #ifdef ARDUBOY_10 - digitalWrite(RED_LED, red); - digitalWrite(GREEN_LED, green); - digitalWrite(BLUE_LED, blue); + bitWrite(RED_LED_PORT, RED_LED_BIT, red); + bitWrite(GREEN_LED_PORT, GREEN_LED_BIT, green); + bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, blue); #elif defined(AB_DEVKIT) - digitalWrite(BLUE_LED, blue); + // only blue on DevKit + (void)red; // parameter unused + (void)green; // parameter unused + bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, blue); +#endif +} + +void Arduboy2Core::digitalWriteRGB(uint8_t color, uint8_t val) +{ +#ifdef ARDUBOY_10 + if (color == RED_LED) + { + bitWrite(RED_LED_PORT, RED_LED_BIT, val); + } + else if (color == GREEN_LED) + { + bitWrite(GREEN_LED_PORT, GREEN_LED_BIT, val); + } + else if (color == BLUE_LED) + { + bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, val); + } +#elif defined(AB_DEVKIT) + // only blue on DevKit + if (color == BLUE_LED) + { + bitWrite(BLUE_LED_PORT, BLUE_LED_BIT, val); + } #endif } diff --git a/src/Arduboy2Core.h b/src/Arduboy2Core.h index d179358..011d3c4 100644 --- a/src/Arduboy2Core.h +++ b/src/Arduboy2Core.h @@ -9,7 +9,6 @@ #include #include -#include #include #include @@ -41,27 +40,42 @@ #define RGB_ON LOW /**< For digitially setting an RGB LED on using digitalWriteRGB() */ #define RGB_OFF HIGH /**< For digitially setting an RGB LED off using digitalWriteRGB() */ +// ----- Arduboy pins ----- #ifdef ARDUBOY_10 -#define CS 12 -#define DC 4 -#define RST 6 +#define PIN_CS 12 // Display CS Arduino pin number +#define CS_PORT PORTD // Display CS port +#define CS_BIT PORTD6 // Display CS physical bit number + +#define PIN_DC 4 // Display D/C Arduino pin number +#define DC_PORT PORTD // Display D/C port +#define DC_BIT PORTD4 // Display D/C physical bit number + +#define PIN_RST 6 // Display reset Arduino pin number +#define RST_PORT PORTD // Display reset port +#define RST_BIT PORTD7 // Display reset physical bit number + +#define SPI_MOSI_PORT PORTB +#define SPI_MOSI_BIT PORTB2 + +#define SPI_SCK_PORT PORTB +#define SPI_SCK_BIT PORTB1 #define RED_LED 10 /**< The pin number for the red color in the RGB LED. */ #define GREEN_LED 11 /**< The pin number for the greem color in the RGB LED. */ #define BLUE_LED 9 /**< The pin number for the blue color in the RGB LED. */ -#define TX_LED 30 /**< The pin number for the transmit indicator LED. */ -#define RX_LED 17 /**< The pin number for the receive indicator LED. */ -// pin values for buttons, probably shouldn't use these -#define PIN_LEFT_BUTTON A2 -#define PIN_RIGHT_BUTTON A1 -#define PIN_UP_BUTTON A0 -#define PIN_DOWN_BUTTON A3 -#define PIN_A_BUTTON 7 -#define PIN_B_BUTTON 8 +#define RED_LED_PORT PORTB +#define RED_LED_BIT PORTB6 + +#define GREEN_LED_PORT PORTB +#define GREEN_LED_BIT PORTB7 + +#define BLUE_LED_PORT PORTB +#define BLUE_LED_BIT PORTB5 // bit values for button states +// these are determined by the buttonsState() function #define LEFT_BUTTON _BV(5) /**< The Left button value for functions requiring a bitmask */ #define RIGHT_BUTTON _BV(6) /**< The Right button value for functions requiring a bitmask */ #define UP_BUTTON _BV(7) /**< The Up button value for functions requiring a bitmask */ @@ -69,37 +83,73 @@ #define A_BUTTON _BV(3) /**< The A button value for functions requiring a bitmask */ #define B_BUTTON _BV(2) /**< The B button value for functions requiring a bitmask */ +#define PIN_LEFT_BUTTON A2 +#define LEFT_BUTTON_PORT PORTF +#define LEFT_BUTTON_BIT PORTF5 + +#define PIN_RIGHT_BUTTON A1 +#define RIGHT_BUTTON_PORT PORTF +#define RIGHT_BUTTON_BIT PORTF6 + +#define PIN_UP_BUTTON A0 +#define UP_BUTTON_PORT PORTF +#define UP_BUTTON_BIT PORTF7 + +#define PIN_DOWN_BUTTON A3 +#define DOWN_BUTTON_PORT PORTF +#define DOWN_BUTTON_BIT PORTF4 + +#define PIN_A_BUTTON 7 +#define A_BUTTON_PORT PORTE +#define A_BUTTON_BIT PORTE6 + +#define PIN_B_BUTTON 8 +#define B_BUTTON_PORT PORTB +#define B_BUTTON_BIT PORTB4 + #define PIN_SPEAKER_1 5 /**< The pin number of the first lead of the speaker */ #define PIN_SPEAKER_2 13 /**< The pin number of the second lead of the speaker */ -#define PIN_SPEAKER_1_PORT &PORTC -#define PIN_SPEAKER_2_PORT &PORTC +#define SPEAKER_1_PORT PORTC +#define SPEAKER_1_DDR DDRC +#define SPEAKER_1_BIT PORTC6 -#define PIN_SPEAKER_1_BITMASK _BV(6) -#define PIN_SPEAKER_2_BITMASK _BV(7) +#define SPEAKER_2_PORT PORTC +#define SPEAKER_2_DDR DDRC +#define SPEAKER_2_BIT PORTC7 +// ----------------------- +// ----- DevKit pins ----- #elif defined(AB_DEVKIT) -#define CS 6 -#define DC 4 -#define RST 12 +#define PIN_CS 6 // Display CS Arduino pin number +#define CS_PORT PORTD // Display CS port +#define CS_BIT PORTD7 // Display CS physical bit number + +#define PIN_DC 4 // Display D/C Arduino pin number +#define DC_PORT PORTD // Display D/C port +#define DC_BIT PORTD4 // Display D/C physical bit number + +#define PIN_RST 12 // Display reset Arduino pin number +#define RST_PORT PORTD // Display reset port +#define RST_BIT PORTD6 // Display reset physical bit number + +#define SPI_MOSI_PORT PORTB +#define SPI_MOSI_BIT PORTB2 + +#define SPI_SCK_PORT PORTB +#define SPI_SCK_BIT PORTB1 // map all LEDs to the single TX LED on DEVKIT #define RED_LED 17 #define GREEN_LED 17 #define BLUE_LED 17 -#define TX_LED 17 -#define RX_LED 17 -// pin values for buttons, probably shouldn't use these -#define PIN_LEFT_BUTTON 9 -#define PIN_RIGHT_BUTTON 5 -#define PIN_UP_BUTTON 8 -#define PIN_DOWN_BUTTON 10 -#define PIN_A_BUTTON A0 -#define PIN_B_BUTTON A1 +#define BLUE_LED_PORT PORTB +#define BLUE_LED_BIT PORTB0 // bit values for button states +// these are determined by the buttonsState() function #define LEFT_BUTTON _BV(5) #define RIGHT_BUTTON _BV(2) #define UP_BUTTON _BV(4) @@ -107,15 +157,42 @@ #define A_BUTTON _BV(1) #define B_BUTTON _BV(0) +// pin values for buttons, probably shouldn't use these +#define PIN_LEFT_BUTTON 9 +#define LEFT_BUTTON_PORT PORTB +#define LEFT_BUTTON_BIT PORTB5 + +#define PIN_RIGHT_BUTTON 5 +#define RIGHT_BUTTON_PORT PORTC +#define RIGHT_BUTTON_BIT PORTC6 + +#define PIN_UP_BUTTON 8 +#define UP_BUTTON_PORT PORTB +#define UP_BUTTON_BIT PORTB4 + +#define PIN_DOWN_BUTTON 10 +#define DOWN_BUTTON_PORT PORTB +#define DOWN_BUTTON_BIT PORTB6 + +#define PIN_A_BUTTON A0 +#define A_BUTTON_PORT PORTF +#define A_BUTTON_BIT PORTF7 + +#define PIN_B_BUTTON A1 +#define B_BUTTON_PORT PORTF +#define B_BUTTON_BIT PORTF6 + #define PIN_SPEAKER_1 A2 -#define PIN_SPEAKER_1_PORT &PORTF -#define PIN_SPEAKER_1_BITMASK _BV(5) +#define SPEAKER_1_PORT PORTF +#define SPEAKER_1_DDR DDRF +#define SPEAKER_1_BIT PORTF5 // SPEAKER_2 is purposely not defined for DEVKIT as it could potentially // be dangerous and fry your hardware (because of the devkit wiring). // // Reference: https://github.com/Arduboy/Arduboy/issues/108 #endif +// -------------------- // OLED hardware (SSD1306) @@ -183,6 +260,8 @@ class Arduboy2Core * This is a low level function that is not intended for general use in a * sketch. It has been made public and documented for use by derived * classes. + * + * \see LCDCommandMode() SPItransfer() */ void static LCDDataMode(); @@ -206,10 +285,25 @@ class Arduboy2Core * sketch. It has been made public and documented for use by derived * classes. * - * \see sendLCDCommand() + * \see LCDDataMode() sendLCDCommand() SPItransfer() */ void static LCDCommandMode(); + /** \brief + * Transfer a byte to the display. + * + * \param data The byte to be sent to the display. + * + * \details + * Transfer one byte to the display over the SPI port and wait for the + * transfer to complete. The byte will either be interpreted as a command + * or as data to be placed on the screen, depending on the command/data + * mode. + * + * \see LCDDataMode() LCDCommandMode() sendLCDCommand() + */ + void static inline SPItransfer(uint8_t data); + /** \brief * Get the width of the display in pixels. * @@ -233,7 +327,7 @@ class Arduboy2Core uint8_t static height(); /** \brief - * get current state of all buttons as a bitmask. + * Get the current state of all buttons as a bitmask. * * \return A bitmask of the state of all the buttons. * @@ -461,9 +555,9 @@ class Arduboy2Core * * \details * The RGB LED is actually individual red, green and blue LEDs placed - * very close together in a single package. This function will set each - * LED either on or off, to set the RGB LED to 7 different colors at their - * highest brightness or turn it off. + * very close together in a single package. This 3 parameter version of the + * function will set each LED either on or off, to set the RGB LED to + * 7 different colors at their highest brightness or turn it off. * * The colors are as follows: * @@ -486,10 +580,28 @@ class Arduboy2Core * light the red LED. If the green LED is turned on, none of the LEDs * will light. * - * \see setRGBled() + * \see digitalWriteRGB(uint8_t, uint8_t) setRGBled() */ void static digitalWriteRGB(uint8_t red, uint8_t green, uint8_t blue); + /** \brief + * Set one of the RGB LEDs digitally, to either fully on or fully off. + * + * \param color The name of the LED to set. The value given should be one + * of RED_LED, GREEN_LED or BLUE_LED. + * + * \param val Indicates whether to turn the specified LED on or off. + * The value given should be RGB_ON or RGB_OFF. + * + * \details + * This 2 parameter version of the function will set a single LED within + * the RGB LED either fully on or fully off. See the description of the + * 3 parameter version of this function for more details on the RGB LED. + * + * \see digitalWriteRGB(uint8_t, uint8_t, uint8_t) setRGBled() + */ + void static digitalWriteRGB(uint8_t color, uint8_t val); + /** \brief * Initialize the Arduboy's hardware. * @@ -525,12 +637,6 @@ class Arduboy2Core void static inline bootOLED() __attribute__((always_inline)); void static inline bootPins() __attribute__((always_inline)); void static inline bootPowerSaving() __attribute__((always_inline)); - - - private: - volatile static uint8_t *csport, *dcport; - uint8_t static cspinmask, dcpinmask; - }; #endif