Make showing the unit name with the logo optional

- Added a flag in system EEPROM to indicate if the unit name
  should be displayed at the end of the boot logo sequence.
  Function bootLogoExtra() displays the unit name only if the
  flag is set.

- Added functions writeShowUnitNameFlag() and readShowUnitNameFlag()
  to write and read the "Show Unit Name" flag in EEPROM.

- Enhanced the SetNameAndID example sketch to allow setting the
  "Show Unit Name" flag in EEPROM.
This commit is contained in:
Scott Allen 2017-03-29 17:36:13 -04:00
parent 14d5877dae
commit 3572a013e1
4 changed files with 183 additions and 16 deletions

View File

@ -14,7 +14,7 @@
----------------------------------------------------------------------------
*/
// Version 1.0
// Version 2.0
/*
------------------------------------------------------------------------------
@ -61,14 +61,20 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// All the constant stings
const char StrName[] PROGMEM = "NAME";
const char StrID[] PROGMEM = "ID";
const char StrYes[] PROGMEM = "YES";
const char StrNo[] PROGMEM = "NO";
const char StrSaveQ[] PROGMEM = "SAVE?";
const char StrSaved[] PROGMEM = "SAVED";
const char StrShowNameQ1[] PROGMEM = "Show Unit Name";
const char StrShowNameQ2[] PROGMEM = "on logo screen?";
const char StrBtnChangeName[] PROGMEM = "UP:change Unit Name";
const char StrBtnChangeID[] PROGMEM = "DOWN:change Unit ID";
const char StrBtnShowName[] PROGMEM = "LEFT:set \"show name\"";
const char StrBtnMenu[] PROGMEM = "A:menu";
const char StrBtnSave[] PROGMEM = "B:save";
const char StrBtnYes[] PROGMEM = "A:yes";
const char StrBtnNo[] PROGMEM = "B:no";
const char StrBtnLogo[] PROGMEM = "LEFT:show boot logo";
const char StrBtnTestLogo[] PROGMEM = "DOWN:test boot logo";
const char StrHex[] PROGMEM = "hex";
const char StrDecimal[] PROGMEM = "decimal";
@ -91,8 +97,8 @@ const char StrDecimal[] PROGMEM = "decimal";
#define MENU_ID_DECIMAL_X (centerStrLen(5) + (WIDTH / 4))
#define MENU_ID_Y (MENU_HEADINGS_Y + CHAR_HEIGHT + 1)
#define MENU_BTN_LOGO_X 0
#define MENU_BTN_LOGO_Y 56
#define MENU_BTN_SHOW_NAME_X 0
#define MENU_BTN_SHOW_NAME_Y 56
#define NAME_TITLE_X centerStr_P(StrName)
@ -151,13 +157,32 @@ const char StrDecimal[] PROGMEM = "decimal";
#define ID_SAVE_X (ID_SAVE_Q_X + ((strlen_P(StrSaveQ) * CHAR_WIDTH) + CHAR_WIDTH))
#define ID_SAVE_Y (ID_LARGE_Y + 1)
#define SHOW_NAME_BTN_MENU_X 0
#define SHOW_NAME_BTN_MENU_Y 0
#define SHOW_NAME_BTN_SAVE_X rightStr_P(StrBtnSave)
#define SHOW_NAME_BTN_SAVE_Y SHOW_NAME_BTN_MENU_Y
#define SHOW_NAME_Q_1_X centerStr_P(StrShowNameQ1)
#define SHOW_NAME_Q_1_Y 12
#define SHOW_NAME_Q_2_X centerStr_P(StrShowNameQ2)
#define SHOW_NAME_Q_2_Y (SHOW_NAME_Q_1_Y + 8)
#define SHOW_NAME_YES_X ((WIDTH / 2) - ((strlen_P(StrYes) + 1) * CHAR_WIDTH * 2))
#define SHOW_NAME_YES_Y 34
#define SHOW_NAME_NO_X ((WIDTH / 2) + (CHAR_WIDTH * 2))
#define SHOW_NAME_NO_Y SHOW_NAME_YES_Y
#define SHOW_NAME_TEST_X 0
#define SHOW_NAME_TEST_Y 56
#define SHOW_NAME_SAVED_X centerStr2_P(StrSaved)
#define SHOW_NAME_SAVED_Y ((HEIGHT / 2) - CHAR_HEIGHT)
// Calculation of the number of frames to wait before button auto-repeat starts
#define DELAY_FRAMES (REPEAT_DELAY / (1000 / FRAME_RATE))
// The Arduino "magic" has trouble creating prototypes for functions called
// by pointers, so they're declared here manually
void stateMain(), stateName(), stateID(), stateSaveName(), stateSaveID();
void screenMain(), screenName(), screenID(), screenSaveName(), screenSaveID();
void stateMain(), stateName(), stateID(), stateShowName();
void stateSaveName(), stateSaveID();
void screenMain(), screenName(), screenID(), screenShowName();
void screenSaveName(), screenSaveID();
Arduboy2 arduboy;
@ -167,11 +192,14 @@ byte nameIndex;
uint16_t unitID;
byte idIndex;
boolean showNameFlag;
// Assign numbers for each state/screen
enum State : byte {
sMain,
sName,
sID,
sShowName,
sSaveName,
sSaveID,
sMAX = sSaveID
@ -184,6 +212,7 @@ void (*stateFunc[sMAX + 1])() = {
stateMain,
stateName,
stateID,
stateShowName,
stateSaveName,
stateSaveID
};
@ -193,6 +222,7 @@ void (*screenFunc[sMAX + 1])() = {
screenMain,
screenName,
screenID,
screenShowName,
screenSaveName,
screenSaveID
};
@ -246,9 +276,7 @@ void stateMain() {
setState(sID);
}
else if (arduboy.justPressed(LEFT_BUTTON)) {
arduboy.bootLogo();
delay(1000);
setState(sMain);
setState(sShowName);
}
}
@ -322,6 +350,29 @@ void stateID() {
}
}
// STATE: Set "Show Unit Name" flag
void stateShowName() {
if (arduboy.justPressed(RIGHT_BUTTON)) {
showNameToggle();
}
else if (arduboy.justPressed(LEFT_BUTTON)) {
showNameToggle();
}
else if (arduboy.justPressed(A_BUTTON)) {
setState(sMain);
}
else if (arduboy.justPressed(B_BUTTON)) {
saveShowName();
setState(sShowName);
}
else if (arduboy.justPressed(DOWN_BUTTON)) {
showNameFlag = arduboy.readShowUnitNameFlag();
arduboy.bootLogo();
delay(1000);
setState(sShowName);
}
}
// STATE: Prompt to save the unit name
void stateSaveName() {
if (arduboy.justPressed(A_BUTTON)) {
@ -367,7 +418,7 @@ void screenMain() {
printIDHex(MENU_ID_HEX_X, MENU_ID_Y);
printIDDecimal(MENU_ID_DECIMAL_X, MENU_ID_Y);
printStr_P(MENU_BTN_LOGO_X, MENU_BTN_LOGO_Y, StrBtnLogo);
printStr_P(MENU_BTN_SHOW_NAME_X, MENU_BTN_SHOW_NAME_Y, StrBtnShowName);
}
// DISPLAY: Change unit name
@ -389,6 +440,20 @@ void screenID() {
printIDCursors();
}
// DISPLAY: Set "Show Unit Name" flag
void screenShowName() {
printStr_P(SHOW_NAME_BTN_MENU_X, SHOW_NAME_BTN_MENU_Y, StrBtnMenu);
printStr_P(SHOW_NAME_BTN_SAVE_X, SHOW_NAME_BTN_SAVE_Y, StrBtnSave);
printStr_P(SHOW_NAME_Q_1_X, SHOW_NAME_Q_1_Y, StrShowNameQ1);
printStr_P(SHOW_NAME_Q_2_X, SHOW_NAME_Q_2_Y, StrShowNameQ2);
arduboy.setTextSize(2);
printStr_P(SHOW_NAME_YES_X, SHOW_NAME_YES_Y, StrYes);
printStr_P(SHOW_NAME_NO_X, SHOW_NAME_NO_Y, StrNo);
arduboy.setTextSize(1);
printShowNameCursor();
printStr_P(SHOW_NAME_TEST_X, SHOW_NAME_TEST_Y, StrBtnTestLogo);
}
// DISPLAY: Prompt to save the unit name
void screenSaveName() {
printNameScreenCommon();
@ -407,6 +472,21 @@ void screenSaveID() {
printIDLarge(ID_SAVE_X, ID_SAVE_Y);
}
// Save the "Show Unit Name" flag and overlay the "SAVED" message on the screen
void saveShowName() {
arduboy.writeShowUnitNameFlag(showNameFlag);
arduboy.fillRect(SHOW_NAME_SAVED_X - 4, SHOW_NAME_SAVED_Y - 4,
strlen_P(StrSaved) * CHAR_WIDTH * 2 + 6, CHAR_HEIGHT * 2 + 6);
arduboy.setTextColor(BLACK);
arduboy.setTextBackground(WHITE);
arduboy.setTextSize(2);
printStr_P(SHOW_NAME_SAVED_X, SHOW_NAME_SAVED_Y, StrSaved);
arduboy.setTextSize(1);
arduboy.setTextColor(WHITE);
arduboy.setTextBackground(BLACK);
arduboy.display();
delay(1000);
}
// --------------------- Printing Functions ------------------------------
@ -458,6 +538,18 @@ void printIDCursors() {
ID_BINARY_Y + CHAR_HEIGHT + 1, CHAR_WIDTH * 4 - 1);
}
// Print the current "Show Unit Name" cursor
void printShowNameCursor() {
if (showNameFlag) {
arduboy.fillRect(SHOW_NAME_YES_X, SHOW_NAME_YES_Y + (CHAR_HEIGHT * 2),
(strlen_P(StrYes) * CHAR_WIDTH - 1) * 2, 2);
}
else {
arduboy.fillRect(SHOW_NAME_NO_X, SHOW_NAME_NO_Y + (CHAR_HEIGHT * 2),
(strlen_P(StrNo) * CHAR_WIDTH - 1) * 2, 2);
}
}
// Print the unit name in normal size including an extent underline
// at the given location
void printName(int x, int y) {
@ -621,11 +713,12 @@ void printBinaryNybble(int x, int y, byte val) {
// ---------------- Control and Utility Functions ------------------------
// Get the current unit name and ID from EEPROM
// Get the current unit name and ID, and the "Show Unit Name" flag, from EEPROM
void readEEPROM() {
memset(unitName, 0, sizeof(unitName));
arduboy.readUnitName(unitName);
unitID = arduboy.readUnitID();
showNameFlag = arduboy.readShowUnitNameFlag();
}
// Increment the name character at the cursor position
@ -701,6 +794,12 @@ void idCursorLeft() {
drawScreen();
}
// Toggle the "Show Unit Name" selection
void showNameToggle() {
showNameFlag = !showNameFlag;
drawScreen();
}
// Start the button auto-repeat delay
void startButtonDelay() {
delayCount = DELAY_FRAMES;
@ -723,6 +822,12 @@ int centerStr_P(const char* str) {
return (WIDTH / 2) - (strlen_P(str) * CHAR_WIDTH / 2);
}
// Calculate the X coordinate to center a size 2 string located in
// program memory
int centerStr2_P(const char* str) {
return (WIDTH / 2) - (strlen_P(str) * CHAR_WIDTH);
}
// Calculate the X coordinate to right justify a string in program memory
int rightStr_P(const char* str) {
return WIDTH - (strlen_P(str) * CHAR_WIDTH) + 1;

View File

@ -66,6 +66,7 @@ paint8Pixels KEYWORD2
paintScreen KEYWORD2
pollButtons KEYWORD2
pressed KEYWORD2
readShowUnitNameFlag KEYWORD2
readUnitID KEYWORD2
readUnitName KEYWORD2
safeMode KEYWORD2
@ -81,6 +82,7 @@ SPItransfer KEYWORD2
systemButtons KEYWORD2
toggle KEYWORD2
width KEYWORD2
writeShowUnitNameFlag KEYWORD2
writeUnitID KEYWORD2
writeUnitName KEYWORD2

View File

@ -983,6 +983,19 @@ void Arduboy2Base::writeUnitName(char* name)
}
}
bool Arduboy2Base::readShowUnitNameFlag()
{
return (EEPROM.read(EEPROM_SYS_FLAGS) & SYS_FLAG_UNAME_MASK);
}
void Arduboy2Base::writeShowUnitNameFlag(bool val)
{
uint8_t flags = EEPROM.read(EEPROM_SYS_FLAGS);
bitWrite(flags, SYS_FLAG_UNAME, val);
EEPROM.update(EEPROM_SYS_FLAGS, flags);
}
void Arduboy2Base::swap(int16_t& a, int16_t& b)
{
int16_t temp = a;
@ -1051,7 +1064,14 @@ void Arduboy2::bootLogoText()
void Arduboy2::bootLogoExtra()
{
uint8_t c = EEPROM.read(EEPROM_UNIT_NAME);
uint8_t c;
if (!readShowUnitNameFlag())
{
return;
}
c = EEPROM.read(EEPROM_UNIT_NAME);
if (c != 0xFF && c != 0x00)
{
@ -1063,10 +1083,11 @@ void Arduboy2::bootLogoExtra()
{
write(c);
c = EEPROM.read(++i);
} while (i < EEPROM_UNIT_NAME + ARDUBOY_UNIT_NAME_LEN);
}
while (i < EEPROM_UNIT_NAME + ARDUBOY_UNIT_NAME_LEN);
display();
delay(1500);
delay(1000);
}
}

View File

@ -38,13 +38,17 @@
#define ARDUBOY_UNIT_NAME_LEN 6 /**< The maximum length of the unit name string. */
#define EEPROM_VERSION 0
#define EEPROM_BRIGHTNESS 1
#define EEPROM_SYS_FLAGS 1
#define EEPROM_AUDIO_ON_OFF 2
#define EEPROM_UNIT_ID 8 // A uint16_t binary unit ID
#define EEPROM_UNIT_NAME 10 // An up to 6 character unit name. Cannot contain
// 0x00 or 0xFF. Lengths less than 6 are padded
// with 0x00
// EEPROM_SYS_FLAGS values
#define SYS_FLAG_UNAME 0 // Display the unit name on the logo screen
#define SYS_FLAG_UNAME_MASK _BV(SYS_FLAG_UNAME)
/** \brief
* Start of EEPROM storage space for sketches.
*
@ -959,6 +963,38 @@ class Arduboy2Base : public Arduboy2Core
*/
void writeUnitName(char* name);
/** \brief
* Read the "Show Unit Name" flag in system EEPROM.
*
* \return `true` if the flag is set to indicate that the unit name should
* be displayed. `false` if the flag is set to not display the unit name.
*
* \details
* The "Show Unit Name" flag is used to determine whether the system
* unit name is to be displayed at the end of the boot logo sequence.
* This function returns the value of this flag.
*
* \see writeShowUnitNameFlag() writeUnitName() readUnitName()
* Arduboy2::bootLogoExtra()
*/
bool readShowUnitNameFlag();
/** \brief
* Write the "Show Unit Name" flag in system EEPROM.
*
* \param val If `true` the flag is set to indicate that the unit name should
* be displayed. If `false` the flag is set to not display the unit name.
*
* \details
* The "Show Unit Name" flag is used to determine whether the system
* unit name is to be displayed at the end of the boot logo sequence.
* This function allows the flag to be saved with the desired value.
*
* \see readShowUnitNameFlag() writeUnitName() readUnitName()
* Arduboy2::bootLogoExtra()
*/
void writeShowUnitNameFlag(bool val);
/** \brief
* A counter which is incremented once per frame.
*
@ -1113,11 +1149,14 @@ class Arduboy2 : public Print, public Arduboy2Base
* the bottom of the screen. This function pauses for a short time to allow
* the name to be seen.
*
* The name is not displayed if the "Show Unit Name" flag is not set.
*
* \note
* This function would not normally be called directly from within a sketch
* itself.
*
* \see readUnitName() writeUnitName() bootLogo() bootLogoText() begin()
* \see readUnitName() writeUnitName() bootLogo() bootLogoText()
* writeShowUnitNameFlag() begin()
*/
virtual void bootLogoExtra();