From dc0b8417868192d8b18ace89a4b33b960cedc505 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 13 Jan 2025 17:42:03 -0800 Subject: [PATCH 1/9] Work on flashing firmware --- VortexEngine/VortexEngine.vcxproj | 2 + VortexEngine/VortexEngine.vcxproj.filters | 6 + VortexEngine/src/Leds/LedTypes.h | 45 +++++++ VortexEngine/src/Leds/Leds.cpp | 13 ++ VortexEngine/src/Leds/Leds.h | 8 ++ .../src/Menus/MenuList/EditorConnection.cpp | 112 ++++++++++++++---- .../src/Menus/MenuList/EditorConnection.h | 19 ++- 7 files changed, 180 insertions(+), 25 deletions(-) diff --git a/VortexEngine/VortexEngine.vcxproj b/VortexEngine/VortexEngine.vcxproj index 7b3ec18bfb..b5453b3392 100644 --- a/VortexEngine/VortexEngine.vcxproj +++ b/VortexEngine/VortexEngine.vcxproj @@ -150,6 +150,7 @@ + @@ -221,6 +222,7 @@ + diff --git a/VortexEngine/VortexEngine.vcxproj.filters b/VortexEngine/VortexEngine.vcxproj.filters index d34b25504b..200ea0ec1a 100644 --- a/VortexEngine/VortexEngine.vcxproj.filters +++ b/VortexEngine/VortexEngine.vcxproj.filters @@ -339,6 +339,9 @@ Source Files + + Source Files + @@ -569,5 +572,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/VortexEngine/src/Leds/LedTypes.h b/VortexEngine/src/Leds/LedTypes.h index 59f519be88..9a71f3a000 100644 --- a/VortexEngine/src/Leds/LedTypes.h +++ b/VortexEngine/src/Leds/LedTypes.h @@ -99,6 +99,30 @@ enum Pair : uint8_t // Compile-time check on the number of pairs and leds static_assert(LED_COUNT == (PAIR_COUNT * 2), "Incorrect number of Pairs for Leds! Adjust the Led enum or Pair enum to match"); +enum Radial : uint8_t +{ + RADIAL_FIRST = 0, + + RADIAL_0 = RADIAL_FIRST, + RADIAL_1, + RADIAL_2, + RADIAL_3, + RADIAL_4, + RADIAL_5, + RADIAL_6, + RADIAL_7, + RADIAL_8, + RADIAL_9, + + RADIAL_COUNT, + RADIAL_LAST = (RADIAL_COUNT - 1), +}; + +static_assert(RADIAL_COUNT == (LED_COUNT / 2), "Incorrect number of Radials for Leds! Adjust the Led enum or Radial enum to match"); + +#define radialInner(radial) (LedPos)(LED_10 + radial) +#define radialOuter(radial) (LedPos)(LED_0 + radial) + // check if an led is even or odd #define isEven(pos) ((pos % 2) == 0) #define isOdd(pos) ((pos % 2) != 0) @@ -280,4 +304,25 @@ inline Pair operator-(Pair &c, int b) return (Pair)((uint32_t)c - b); } +// Radial operators +inline Radial &operator++(Radial &c) +{ + c = Radial(((uint32_t)c) + 1); + return c; +} +inline Radial operator++(Radial &c, int) +{ + Radial temp = c; + ++c; + return temp; +} +inline Radial operator+(Radial &c, int b) +{ + return (Radial)((uint32_t)c + b); +} +inline Radial operator-(Radial &c, int b) +{ + return (Radial)((uint32_t)c - b); +} + #endif diff --git a/VortexEngine/src/Leds/Leds.cpp b/VortexEngine/src/Leds/Leds.cpp index 38851915d6..43b92a975b 100644 --- a/VortexEngine/src/Leds/Leds.cpp +++ b/VortexEngine/src/Leds/Leds.cpp @@ -75,6 +75,19 @@ void Leds::setPairs(Pair first, Pair last, RGBColor col) setRange(pairEven(first), pairOdd(last), col); } +void Leds::setRadial(Radial radial, RGBColor col) +{ + setIndex(radialInner(radial), col); + setIndex(radialOuter(radial), col); +} + +void Leds::setRadials(Radial first, Radial last, RGBColor col) +{ + for (Radial rad = first; rad < last; rad++) { + setRadial(rad, col); + } +} + void Leds::setRangeEvens(Pair first, Pair last, RGBColor col) { for (Pair pos = first; pos <= last; pos++) { diff --git a/VortexEngine/src/Leds/Leds.h b/VortexEngine/src/Leds/Leds.h index d7e7cc7c41..3eecd1b328 100644 --- a/VortexEngine/src/Leds/Leds.h +++ b/VortexEngine/src/Leds/Leds.h @@ -37,6 +37,14 @@ class Leds static void clearPair(Pair pair) { setPair(pair, RGB_OFF); } static void clearPairs(Pair first, Pair last) { setPairs(first, last, RGB_OFF); } + // control two LEDs on a pair, these are appropriate for use in internal pattern logic + static void setRadial(Radial radial, RGBColor col); + static void setRadials(Radial first, Radial last, RGBColor col); + + // Turn off both LEDs on a pair, these are appropriate for use in internal pattern logic + static void clearRadial(Radial radial) { setRadial(radial, RGB_OFF); } + static void clearRadials(Radial first, Radial last) { setRadials(first, last, RGB_OFF); } + // Controll pair evens static void setRangeEvens(Pair first, Pair last, RGBColor); static void setAllEvens(RGBColor col); diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp index 824cac59a0..6fd8e450a6 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp @@ -9,6 +9,7 @@ #include "../../Time/TimeControl.h" #include "../../Time/Timings.h" #include "../../Colors/Colorset.h" +#include "../../Modes/DuoDefaultModes.h" #include "../../Modes/Modes.h" #include "../../Modes/Mode.h" #include "../../Leds/Leds.h" @@ -29,7 +30,8 @@ EditorConnection::EditorConnection(const RGBColor &col, bool advanced) : m_numModesToReceive(0), m_curStep(0), m_firmwareSize(0), - m_firmwareOffset(0) + m_firmwareOffset(0), + m_backupModes(true) { } @@ -428,30 +430,55 @@ void EditorConnection::handleState() if (!receiveFirmwareSize(m_firmwareSize)) { break; } - UPDI::eraseMemory(); - - m_curStep = 0; m_firmwareOffset = 0; + m_backupModeNum = 0; + Leds::setAll(RGB_ORANGE3); + m_state = STATE_CHROMALINK_FLASH_FIRMWARE_BACKUP_MODES; + break; + case STATE_CHROMALINK_FLASH_FIRMWARE_BACKUP_MODES: + if (!backupDuoModes()) { + // not done + break; + } + m_state = STATE_CHROMALINK_FLASH_FIRMWARE_ERASE_MEMORY; + break; + case STATE_CHROMALINK_FLASH_FIRMWARE_ERASE_MEMORY: + UPDI::eraseMemory(); m_receiveBuffer.clear(); - Leds::setAll(RGB_YELLOW3); + Leds::setAll(RGB_YELLOW5); SerialComs::write(EDITOR_VERB_READY); - m_state = STATE_CHROMALINK_FLASH_FIRMWARE_RECEIVE; + m_state = STATE_CHROMALINK_FLASH_FIRMWARE_FLASH_CHUNKS; break; - case STATE_CHROMALINK_FLASH_FIRMWARE_RECEIVE: + case STATE_CHROMALINK_FLASH_FIRMWARE_FLASH_CHUNKS: // receive and write a chunk of firwmare if (!writeDuoFirmware()) { break; } - // send ack - SerialComs::write(EDITOR_VERB_FLASH_FIRMWARE_ACK); + m_state = STATE_CHROMALINK_FLASH_FIRMWARE_RESTORE_MODES; + break; + case STATE_CHROMALINK_FLASH_FIRMWARE_RESTORE_MODES: // only once the entire firmware is written - if (m_firmwareOffset >= m_firmwareSize) { - // then done - m_receiveBuffer.clear(); - m_curStep = 0; - m_state = STATE_IDLE; + if (!restoreDuoModes()) { + break; } + m_state = STATE_CHROMALINK_FLASH_FIRMWARE_DONE; + break; + case STATE_CHROMALINK_FLASH_FIRMWARE_DONE: + // done reset everything + m_receiveBuffer.clear(); + m_firmwareOffset = 0; + m_backupModeNum = 0; + m_curStep = 0; + // done with updi + UPDI::reset(); + UPDI::disable(); + // show green + Leds::setAll(RGB_GREEN); + // send ack + SerialComs::write(EDITOR_VERB_FLASH_FIRMWARE_ACK); + // go back to idle + m_state = STATE_IDLE; break; } } @@ -540,26 +567,63 @@ bool EditorConnection::pushModeChromalink() return true; } -bool EditorConnection::writeDuoFirmware() +bool EditorConnection::backupDuoModes() { + Leds::setRadial((Radial)m_backupModeNum, RGB_YELLOW4); + if (m_backupModeNum == 9) { + // reset counter for the restore step later + m_backupModeNum = 0; + // done + return true; + } + // read or just use defaults? + if (!m_backupModes || !UPDI::readMode(m_backupModeNum, m_duoModeBackups[m_backupModeNum])) { + // if not backing up, or backup failed, then store the default mode data in the backup + // because we will always write out the backups after flashing + m_duoModeBackups[m_backupModeNum].init(duo_default_mode_sizes[m_backupModeNum], duo_default_modes[m_backupModeNum]); + } + // go to next mode + m_backupModeNum++; + return false; +} + +bool EditorConnection::restoreDuoModes() +{ + Leds::setRadials(RADIAL_0, (Radial)((m_firmwareOffset / (float)m_firmwareSize) * RADIAL_COUNT), RGB_GREEN6); + if (m_backupModeNum == 9) { + // reset counter for the restore step later + m_backupModeNum = 0; + // done + return true; + } + // each pass write out the backups, these may be the defaults + UPDI::writeMode(m_backupModeNum, m_duoModeBackups[m_backupModeNum]); + // go to next mode + m_backupModeNum++; + return true; +} + +bool EditorConnection::writeDuoFirmware() +{ + Leds::setRadials(RADIAL_0, (Radial)((m_firmwareOffset / (float)m_firmwareSize) * RADIAL_COUNT), RGB_GREEN3); + // first pass and backup modes is enabled + if (m_firmwareOffset >= m_firmwareSize) { + // done + return true; + } // wait for the mode then write it via updi ByteStream buf; if (!receiveBuffer(buf)) { return false; } + // write out the firmware and record it if successful if (!UPDI::writeFirmware(m_firmwareOffset, buf)) { + // big error? this shouldn't happen return false; } m_firmwareOffset += buf.size(); - if (m_firmwareOffset >= m_firmwareSize) { - // done - UPDI::reset(); - UPDI::disable(); - } - // create a progress bar I guess - Leds::setAll(RGB_RED0); - Leds::setRange(LED_0, (LedPos)((m_firmwareOffset / (float)m_firmwareSize) * LED_COUNT), RGB_GREEN3); - return true; + // not done yet + return false; } void EditorConnection::onShortClickM() diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.h b/VortexEngine/src/Menus/MenuList/EditorConnection.h index e73e724cfc..e142bf914d 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.h +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.h @@ -24,7 +24,10 @@ class EditorConnection : public Menu bool pushHeaderChromalink(); bool pullModeChromalink(); bool pushModeChromalink(); + bool writeDuoFirmware(); + bool backupDuoModes(); + bool restoreDuoModes(); // handlers for clicks void onShortClickM() override; @@ -123,7 +126,14 @@ class EditorConnection : public Menu // flash the firmware of the chromalinked duo STATE_CHROMALINK_FLASH_FIRMWARE, STATE_CHROMALINK_FLASH_FIRMWARE_RECEIVE_SIZE, - STATE_CHROMALINK_FLASH_FIRMWARE_RECEIVE, + STATE_CHROMALINK_FLASH_FIRMWARE_BACKUP_MODES, + STATE_CHROMALINK_FLASH_FIRMWARE_ERASE_MEMORY, + STATE_CHROMALINK_FLASH_FIRMWARE_FLASH_CHUNKS, + STATE_CHROMALINK_FLASH_FIRMWARE_RESTORE_MODES, + STATE_CHROMALINK_FLASH_FIRMWARE_DONE, + + // toggle whether flashing firmware will backup modes + STATE_CHROMALINK_FLASH_FIRMWARE_TOGGLE_BACKUP, }; // state of the editor @@ -147,6 +157,13 @@ class EditorConnection : public Menu uint32_t m_firmwareSize; // how much firmware written so far uint32_t m_firmwareOffset; + + // whether to backup duo modes on firmware update + bool m_backupModes; + // backups of duo modes when flashing firmware + ByteStream m_duoModeBackups[9]; + // counter for reading/writing modes during firmware flash + uint8_t m_backupModeNum; }; #endif From f00834e1b3624c0a60eca9f120839fc70b45e938 Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 14 Jan 2025 04:26:53 -0800 Subject: [PATCH 2/9] saving for now --- .../src/Menus/MenuList/EditorConnection.cpp | 47 +++++++++++-------- VortexEngine/src/Serial/Serial.cpp | 10 ++++ 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp index 6fd8e450a6..0a70160ae5 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp @@ -382,9 +382,9 @@ void EditorConnection::handleState() // the trick is to send header after the modes so the reset comes at the end UPDI::reset(); UPDI::disable(); + m_receiveBuffer.clear(); // success modes were received send the done SerialComs::write(EDITOR_VERB_PUSH_CHROMA_HDR_ACK); - m_receiveBuffer.clear(); m_state = STATE_IDLE; break; @@ -410,9 +410,9 @@ void EditorConnection::handleState() if (!pushModeChromalink()) { break; } + m_receiveBuffer.clear(); SerialComs::write(EDITOR_VERB_PUSH_CHROMA_MODE_ACK); // done - m_receiveBuffer.clear(); m_state = STATE_IDLE; break; @@ -437,31 +437,34 @@ void EditorConnection::handleState() m_state = STATE_CHROMALINK_FLASH_FIRMWARE_BACKUP_MODES; break; case STATE_CHROMALINK_FLASH_FIRMWARE_BACKUP_MODES: - if (!backupDuoModes()) { - // not done - break; - } + //if (!backupDuoModes()) { + // // not done + // break; + //} m_state = STATE_CHROMALINK_FLASH_FIRMWARE_ERASE_MEMORY; break; case STATE_CHROMALINK_FLASH_FIRMWARE_ERASE_MEMORY: + Leds::setAll(RGB_CYAN0); UPDI::eraseMemory(); m_receiveBuffer.clear(); - Leds::setAll(RGB_YELLOW5); SerialComs::write(EDITOR_VERB_READY); m_state = STATE_CHROMALINK_FLASH_FIRMWARE_FLASH_CHUNKS; break; case STATE_CHROMALINK_FLASH_FIRMWARE_FLASH_CHUNKS: // receive and write a chunk of firwmare - if (!writeDuoFirmware()) { - break; + if (writeDuoFirmware()) { + // done go to next state + m_state = STATE_CHROMALINK_FLASH_FIRMWARE_RESTORE_MODES; } - m_state = STATE_CHROMALINK_FLASH_FIRMWARE_RESTORE_MODES; + // send ack for each chunk + m_receiveBuffer.clear(); + SerialComs::write(EDITOR_VERB_FLASH_FIRMWARE_ACK); break; case STATE_CHROMALINK_FLASH_FIRMWARE_RESTORE_MODES: - // only once the entire firmware is written - if (!restoreDuoModes()) { - break; - } + //// only once the entire firmware is written + //if (!restoreDuoModes()) { + // break; + //} m_state = STATE_CHROMALINK_FLASH_FIRMWARE_DONE; break; case STATE_CHROMALINK_FLASH_FIRMWARE_DONE: @@ -475,8 +478,6 @@ void EditorConnection::handleState() UPDI::disable(); // show green Leds::setAll(RGB_GREEN); - // send ack - SerialComs::write(EDITOR_VERB_FLASH_FIRMWARE_ACK); // go back to idle m_state = STATE_IDLE; break; @@ -553,6 +554,8 @@ bool EditorConnection::pullModeChromalink() bool EditorConnection::pushModeChromalink() { + // lol just use the mode index as the radial to set + Leds::setRadial((Radial)m_chromaModeIdx, RGB_GREEN4); // wait for the mode then write it via updi ByteStream buf; if (!receiveBuffer(buf)) { @@ -569,7 +572,7 @@ bool EditorConnection::pushModeChromalink() bool EditorConnection::backupDuoModes() { - Leds::setRadial((Radial)m_backupModeNum, RGB_YELLOW4); + Leds::setRadial((Radial)m_backupModeNum, RGB_CYAN0); if (m_backupModeNum == 9) { // reset counter for the restore step later m_backupModeNum = 0; @@ -577,11 +580,11 @@ bool EditorConnection::backupDuoModes() return true; } // read or just use defaults? - if (!m_backupModes || !UPDI::readMode(m_backupModeNum, m_duoModeBackups[m_backupModeNum])) { + //if (!m_backupModes || !UPDI::readMode(m_backupModeNum, m_duoModeBackups[m_backupModeNum])) { // if not backing up, or backup failed, then store the default mode data in the backup // because we will always write out the backups after flashing m_duoModeBackups[m_backupModeNum].init(duo_default_mode_sizes[m_backupModeNum], duo_default_modes[m_backupModeNum]); - } + //} // go to next mode m_backupModeNum++; return false; @@ -589,7 +592,7 @@ bool EditorConnection::backupDuoModes() bool EditorConnection::restoreDuoModes() { - Leds::setRadials(RADIAL_0, (Radial)((m_firmwareOffset / (float)m_firmwareSize) * RADIAL_COUNT), RGB_GREEN6); + Leds::setRadial((Radial)m_backupModeNum, RGB_GREEN6); if (m_backupModeNum == 9) { // reset counter for the restore step later m_backupModeNum = 0; @@ -605,6 +608,8 @@ bool EditorConnection::restoreDuoModes() bool EditorConnection::writeDuoFirmware() { + // render some progress, do it before updating the offset so it starts at 0 + Leds::setAll(RGB_CYAN0); Leds::setRadials(RADIAL_0, (Radial)((m_firmwareOffset / (float)m_firmwareSize) * RADIAL_COUNT), RGB_GREEN3); // first pass and backup modes is enabled if (m_firmwareOffset >= m_firmwareSize) { @@ -766,6 +771,8 @@ bool EditorConnection::receiveBuffer(ByteStream &buffer) // clear the receive buffer m_receiveBuffer.clear(); if (!buffer.checkCRC()) { + // bad! this should never happen! + Leds::holdAll(RGB_RED); return false; } return true; diff --git a/VortexEngine/src/Serial/Serial.cpp b/VortexEngine/src/Serial/Serial.cpp index fdc261a406..1090e2abd6 100644 --- a/VortexEngine/src/Serial/Serial.cpp +++ b/VortexEngine/src/Serial/Serial.cpp @@ -144,8 +144,18 @@ void SerialComs::write(ByteStream &byteStream) Vortex::vcallbacks()->serialWrite((const uint8_t *)&size, sizeof(size)); Vortex::vcallbacks()->serialWrite((const uint8_t *)byteStream.rawData(), byteStream.rawSize()); #else + //uint32_t bufSize = sizeof(size) + size; + //uint8_t *buf = new uint8_t[size]; + //if (!buf) { + // return; + //} + //memcpy(buf, &size, sizeof(size)); + //memcpy(buf + sizeof(size), byteStream.rawData(), size); Serial.write((const uint8_t *)&size, sizeof(size)); Serial.write((const uint8_t *)byteStream.rawData(), byteStream.rawSize()); + //Serial.write(buf, bufSize); + //delete[] buf; + //delay(100); Serial.flush(); #endif #endif From f47904c9d3ff1a2d53cb94869720edb06aa01fbf Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 14 Jan 2025 23:47:17 -0800 Subject: [PATCH 3/9] fixed flashing backup --- .../src/Menus/MenuList/EditorConnection.cpp | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp index 0a70160ae5..d4cb6cfcaa 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp @@ -437,11 +437,9 @@ void EditorConnection::handleState() m_state = STATE_CHROMALINK_FLASH_FIRMWARE_BACKUP_MODES; break; case STATE_CHROMALINK_FLASH_FIRMWARE_BACKUP_MODES: - //if (!backupDuoModes()) { - // // not done - // break; - //} - m_state = STATE_CHROMALINK_FLASH_FIRMWARE_ERASE_MEMORY; + if (backupDuoModes()) { + m_state = STATE_CHROMALINK_FLASH_FIRMWARE_ERASE_MEMORY; + } break; case STATE_CHROMALINK_FLASH_FIRMWARE_ERASE_MEMORY: Leds::setAll(RGB_CYAN0); @@ -456,16 +454,12 @@ void EditorConnection::handleState() // done go to next state m_state = STATE_CHROMALINK_FLASH_FIRMWARE_RESTORE_MODES; } - // send ack for each chunk - m_receiveBuffer.clear(); - SerialComs::write(EDITOR_VERB_FLASH_FIRMWARE_ACK); break; case STATE_CHROMALINK_FLASH_FIRMWARE_RESTORE_MODES: - //// only once the entire firmware is written - //if (!restoreDuoModes()) { - // break; - //} - m_state = STATE_CHROMALINK_FLASH_FIRMWARE_DONE; + // only once the entire firmware is written + if (restoreDuoModes()) { + m_state = STATE_CHROMALINK_FLASH_FIRMWARE_DONE; + } break; case STATE_CHROMALINK_FLASH_FIRMWARE_DONE: // done reset everything @@ -541,6 +535,8 @@ bool EditorConnection::pullModeChromalink() if (!receiveModeIdx(modeIdx) || modeIdx >= 9) { return false; } + // lol just use the mode index as the radial to set + Leds::setRadial((Radial)modeIdx, RGB_GREEN4); ByteStream modeBuffer; // same doesn't matter if this fails still need to send bool success = UPDI::readMode(modeIdx, modeBuffer); @@ -555,7 +551,7 @@ bool EditorConnection::pullModeChromalink() bool EditorConnection::pushModeChromalink() { // lol just use the mode index as the radial to set - Leds::setRadial((Radial)m_chromaModeIdx, RGB_GREEN4); + Leds::setRadials(RADIAL_0, (Radial)m_chromaModeIdx, RGB_GREEN4); // wait for the mode then write it via updi ByteStream buf; if (!receiveBuffer(buf)) { @@ -572,7 +568,7 @@ bool EditorConnection::pushModeChromalink() bool EditorConnection::backupDuoModes() { - Leds::setRadial((Radial)m_backupModeNum, RGB_CYAN0); + Leds::setRadials(RADIAL_0, (Radial)m_backupModeNum, RGB_CYAN0); if (m_backupModeNum == 9) { // reset counter for the restore step later m_backupModeNum = 0; @@ -580,11 +576,11 @@ bool EditorConnection::backupDuoModes() return true; } // read or just use defaults? - //if (!m_backupModes || !UPDI::readMode(m_backupModeNum, m_duoModeBackups[m_backupModeNum])) { + if (!m_backupModes || !UPDI::readMode(m_backupModeNum, m_duoModeBackups[m_backupModeNum])) { // if not backing up, or backup failed, then store the default mode data in the backup // because we will always write out the backups after flashing m_duoModeBackups[m_backupModeNum].init(duo_default_mode_sizes[m_backupModeNum], duo_default_modes[m_backupModeNum]); - //} + } // go to next mode m_backupModeNum++; return false; @@ -592,7 +588,7 @@ bool EditorConnection::backupDuoModes() bool EditorConnection::restoreDuoModes() { - Leds::setRadial((Radial)m_backupModeNum, RGB_GREEN6); + Leds::setRadials(RADIAL_0, (Radial)m_backupModeNum, RGB_GREEN6); if (m_backupModeNum == 9) { // reset counter for the restore step later m_backupModeNum = 0; @@ -603,7 +599,7 @@ bool EditorConnection::restoreDuoModes() UPDI::writeMode(m_backupModeNum, m_duoModeBackups[m_backupModeNum]); // go to next mode m_backupModeNum++; - return true; + return false; } bool EditorConnection::writeDuoFirmware() @@ -627,6 +623,9 @@ bool EditorConnection::writeDuoFirmware() return false; } m_firmwareOffset += buf.size(); + // send ack for each chunk + m_receiveBuffer.clear(); + SerialComs::write(EDITOR_VERB_FLASH_FIRMWARE_ACK); // not done yet return false; } From 3bb675b4ac72054341cbce208734fc79cd06b62f Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 14 Jan 2025 23:50:33 -0800 Subject: [PATCH 4/9] adjusted radial color --- VortexEngine/src/Menus/MenuList/EditorConnection.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp index d4cb6cfcaa..93ed5ec86c 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp @@ -588,7 +588,7 @@ bool EditorConnection::backupDuoModes() bool EditorConnection::restoreDuoModes() { - Leds::setRadials(RADIAL_0, (Radial)m_backupModeNum, RGB_GREEN6); + Leds::setRadials(RADIAL_0, (Radial)m_backupModeNum, RGB_CYAN4); if (m_backupModeNum == 9) { // reset counter for the restore step later m_backupModeNum = 0; From 98fbc8c312db5acf38affdac76ad86f48d50acb9 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 15 Jan 2025 22:31:07 -0800 Subject: [PATCH 5/9] saving for now --- .../src/Menus/MenuList/EditorConnection.cpp | 13 +++-- VortexEngine/src/UPDI/updi.cpp | 57 +++++++++++++------ VortexEngine/src/UPDI/updi.h | 2 +- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp index 93ed5ec86c..6d37839941 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp @@ -338,8 +338,7 @@ void EditorConnection::handleState() // Get Chromalinked Duo Header case STATE_PULL_HEADER_CHROMALINK: if (!pullHeaderChromalink()) { - // error? - break; + Leds::holdAll(RGB_RED); } // done m_receiveBuffer.clear(); @@ -357,7 +356,7 @@ void EditorConnection::handleState() case STATE_PULL_MODE_CHROMALINK_SEND: // send the stuff if (!pullModeChromalink()) { - break; + Leds::holdAll(RGB_RED); } // done m_curStep = 0; @@ -428,6 +427,7 @@ void EditorConnection::handleState() break; case STATE_CHROMALINK_FLASH_FIRMWARE_RECEIVE_SIZE: if (!receiveFirmwareSize(m_firmwareSize)) { + // continue waiting break; } m_curStep = 0; @@ -540,6 +540,11 @@ bool EditorConnection::pullModeChromalink() ByteStream modeBuffer; // same doesn't matter if this fails still need to send bool success = UPDI::readMode(modeIdx, modeBuffer); + if (!success) { + // just send back a 0 if it failed + modeBuffer.init(1); + modeBuffer.serialize8(0); + } // send the mode, could be empty buffer if reading failed SerialComs::write(modeBuffer); UPDI::reset(); @@ -605,7 +610,7 @@ bool EditorConnection::restoreDuoModes() bool EditorConnection::writeDuoFirmware() { // render some progress, do it before updating the offset so it starts at 0 - Leds::setAll(RGB_CYAN0); + Leds::setAll(RGB_YELLOW3); Leds::setRadials(RADIAL_0, (Radial)((m_firmwareOffset / (float)m_firmwareSize) * RADIAL_COUNT), RGB_GREEN3); // first pass and backup modes is enabled if (m_firmwareOffset >= m_firmwareSize) { diff --git a/VortexEngine/src/UPDI/updi.cpp b/VortexEngine/src/UPDI/updi.cpp index a4303794af..406e477c98 100644 --- a/VortexEngine/src/UPDI/updi.cpp +++ b/VortexEngine/src/UPDI/updi.cpp @@ -104,7 +104,11 @@ bool UPDI::readHeader(ByteStream &header) if (!header.init(DUO_HEADER_SIZE)) { return false; } - enterProgrammingMode(); + Leds::holdAll(RGB_PURPLE); + if (!enterProgrammingMode()) { + return false; + } + Leds::holdAll(RGB_YELLOW); uint8_t *ptr = (uint8_t *)header.rawData(); uint16_t addr = DUO_EEPROM_BASE; stptr_p((const uint8_t *)&addr, 2); @@ -115,6 +119,7 @@ bool UPDI::readHeader(ByteStream &header) if (!size) { return false; } + Leds::holdAll(RGB_BLUE); // more than 30 is old old duo where header is combined with save if (size > 30) { return readHeaderLegacy2(header); @@ -123,6 +128,7 @@ bool UPDI::readHeader(ByteStream &header) if (size < 6) { return readHeaderLegacy1(header); } + Leds::holdAll(RGB_GREEN0); // modern duo header is 27 total and separate from modes stptr_p((const uint8_t *)&addr, 2); for (uint16_t i = 0; i < header.rawSize(); ++i) { @@ -132,7 +138,6 @@ bool UPDI::readHeader(ByteStream &header) if (!header.checkCRC()) { header.clear(); ERROR_LOG("ERROR Header CRC Invalid!"); - reset(); return false; } // major.minor are the first two bytes of the buffer @@ -158,7 +163,9 @@ bool UPDI::readHeaderLegacy1(ByteStream &header) if (!header.init(LEGACY_DUO_HEADER_SIZE_1)) { return false; } - enterProgrammingMode(); + if (!enterProgrammingMode()) { + return false; + } uint8_t *ptr = (uint8_t *)header.rawData(); uint16_t addr = DUO_EEPROM_BASE; stptr_p((const uint8_t *)&addr, 2); @@ -191,7 +198,9 @@ bool UPDI::readHeaderLegacy2(ByteStream &header) if (!header.init(LEGACY_DUO_HEADER_SIZE_2)) { return false; } - //enterProgrammingMode(); + //if (!enterProgrammingMode()) { + // return false; + //} uint8_t *ptr = (uint8_t *)header.rawData(); uint16_t addr = DUO_EEPROM_BASE; stptr_p((const uint8_t *)&addr, 2); @@ -230,7 +239,9 @@ bool UPDI::readMode(uint8_t idx, ByteStream &modeBuffer) if (!modeBuffer.init(DUO_MODE_SIZE)) { return false; } - enterProgrammingMode(); + if (!enterProgrammingMode()) { + return false; + } // DUO_MODE_SIZE is the max duo mode size (the slot size) uint8_t *ptr = (uint8_t *)modeBuffer.rawData(); uint16_t numBytes = modeBuffer.rawSize(); @@ -259,7 +270,6 @@ bool UPDI::readMode(uint8_t idx, ByteStream &modeBuffer) if (!modeBuffer.checkCRC()) { modeBuffer.clear(); ERROR_LOG("ERROR Header CRC Invalid!"); - reset(); return false; } #endif @@ -273,7 +283,9 @@ bool UPDI::writeHeader(ByteStream &headerBuffer) // nope! return false; } - enterProgrammingMode(); + if (!enterProgrammingMode()) { + return false; + } // DUO_EEPROM_BASE is eeprom base // DUO_HEADER_FULL_SIZE is size of duo header // DUO_MODE_SIZE is size of each duo mode @@ -330,7 +342,9 @@ bool UPDI::writeMode(uint8_t idx, ByteStream &modeBuffer) #ifdef VORTEX_EMBEDDED bool UPDI::writeModeEeprom(uint8_t idx, ByteStream &modeBuffer) { - enterProgrammingMode(); + if (!enterProgrammingMode()) { + return false; + } // DUO_EEPROM_BASE is eeprom base // DUO_HEADER_FULL_SIZE is size of duo header // DUO_MODE_SIZE is size of each duo mode @@ -448,7 +462,9 @@ bool UPDI::writeModeEeprom(uint8_t idx, ByteStream &modeBuffer) bool UPDI::writeModeFlash(uint8_t idx, ByteStream &modeBuffer) { - enterProgrammingMode(); + if (!enterProgrammingMode()) { + return false; + } // there are 3 modes in the eeprom after the header // DUO_FLASH_STORAGE_BASE is the end of flash, 0x200 before uint16_t base = DUO_FLASH_STORAGE_BASE + ((idx - 3) * DUO_MODE_SIZE); @@ -652,7 +668,9 @@ bool UPDI::writeFirmware(uint32_t position, ByteStream &firmwareBuffer) reset(); return false; } - enterProgrammingMode(); + if (!enterProgrammingMode()) { + return false; + } // DUO_MODE_SIZE is the max duo mode size (the slot size) uint8_t *ptr = (uint8_t *)firmwareBuffer.data(); // there are 3 modes in the eeprom after the header @@ -720,20 +738,20 @@ bool UPDI::disable() } #ifdef VORTEX_EMBEDDED +#define MAX_TRIES 1000 -void UPDI::enterProgrammingMode() +bool UPDI::enterProgrammingMode() { uint8_t mode; - while (1) { + uint32_t tries = 0; + while (tries++ < MAX_TRIES) { sendDoubleBreak(); stcs(Control_A, 0x6); mode = cpu_mode<0xEF>(); if (mode != 0x82 && mode != 0x21 && mode != 0xA2 && mode != 0x08) { - //sendDoubleBreak(); + ERROR_LOGF("Bad CPU Mode 0x%02x... error: 0x%02x", mode, status); sendBreak(); uint8_t status = ldcs(Status_B); - ERROR_LOGF("Bad CPU Mode 0x%02x... error: 0x%02x", mode, status); - //reset(); continue; } if (mode != 0x08) { @@ -741,18 +759,23 @@ void UPDI::enterProgrammingMode() uint8_t status = ldcs(ASI_Key_Status); if (status != 0x10) { ERROR_LOGF("Bad prog key status: 0x%02x", status); - reset(); + sendBreak(); + uint8_t status = ldcs(Status_B); continue; } reset(); } - // break the while (1) break; } + if (tries >= MAX_TRIES) { + Leds::holdAll(RGB_RED); + return false; + } mode = cpu_mode(); while (mode != 0x8) { mode = cpu_mode(); } + return true; } void UPDI::resetOn() diff --git a/VortexEngine/src/UPDI/updi.h b/VortexEngine/src/UPDI/updi.h index eac29a1f10..db675260bf 100644 --- a/VortexEngine/src/UPDI/updi.h +++ b/VortexEngine/src/UPDI/updi.h @@ -109,7 +109,7 @@ class UPDI NVM_WFU /* Write fuse */ }; - static void enterProgrammingMode(); + static bool enterProgrammingMode(); static void resetOn(); static bool resetOff(); From bad1b961334dc9a320e6d18d88ac97e2a0bd151e Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 15 Jan 2025 22:57:24 -0800 Subject: [PATCH 6/9] minor fixes --- .../src/Menus/MenuList/EditorConnection.cpp | 21 +++++++++++++------ .../src/Menus/MenuList/EditorConnection.h | 2 +- VortexEngine/src/UPDI/updi.cpp | 9 +++----- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp index 6d37839941..18b14982ca 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp @@ -580,11 +580,20 @@ bool EditorConnection::backupDuoModes() // done return true; } - // read or just use defaults? - if (!m_backupModes || !UPDI::readMode(m_backupModeNum, m_duoModeBackups[m_backupModeNum])) { - // if not backing up, or backup failed, then store the default mode data in the backup - // because we will always write out the backups after flashing - m_duoModeBackups[m_backupModeNum].init(duo_default_mode_sizes[m_backupModeNum], duo_default_modes[m_backupModeNum]); + // may use the defaults if backing up fails, default is whether backup is enabled + bool useDefault = !m_backupModes; + if (m_backupModes) { + ByteStream &cur = m_modeBackups[m_backupModeNum]; + // if the mode cannot be loaded, or if it's CRC is bad then just use the default + if (!UPDI::readMode(m_backupModeNum, cur) || !cur.checkCRC() || !cur.size()) { + useDefault = true; + } + } + if (useDefault) { + // if not backing up, or backup failed, then store the default mode data in + // the backup because we will always write out the backups after flashing + m_modeBackups[m_backupModeNum].init(duo_default_sizes[m_backupModeNum], + duo_default_modes[m_backupModeNum]); } // go to next mode m_backupModeNum++; @@ -601,7 +610,7 @@ bool EditorConnection::restoreDuoModes() return true; } // each pass write out the backups, these may be the defaults - UPDI::writeMode(m_backupModeNum, m_duoModeBackups[m_backupModeNum]); + UPDI::writeMode(m_backupModeNum, m_modeBackups[m_backupModeNum]); // go to next mode m_backupModeNum++; return false; diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.h b/VortexEngine/src/Menus/MenuList/EditorConnection.h index e142bf914d..3fd06ccf75 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.h +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.h @@ -161,7 +161,7 @@ class EditorConnection : public Menu // whether to backup duo modes on firmware update bool m_backupModes; // backups of duo modes when flashing firmware - ByteStream m_duoModeBackups[9]; + ByteStream m_modeBackups[9]; // counter for reading/writing modes during firmware flash uint8_t m_backupModeNum; }; diff --git a/VortexEngine/src/UPDI/updi.cpp b/VortexEngine/src/UPDI/updi.cpp index 406e477c98..519855b432 100644 --- a/VortexEngine/src/UPDI/updi.cpp +++ b/VortexEngine/src/UPDI/updi.cpp @@ -104,11 +104,9 @@ bool UPDI::readHeader(ByteStream &header) if (!header.init(DUO_HEADER_SIZE)) { return false; } - Leds::holdAll(RGB_PURPLE); if (!enterProgrammingMode()) { return false; } - Leds::holdAll(RGB_YELLOW); uint8_t *ptr = (uint8_t *)header.rawData(); uint16_t addr = DUO_EEPROM_BASE; stptr_p((const uint8_t *)&addr, 2); @@ -119,7 +117,6 @@ bool UPDI::readHeader(ByteStream &header) if (!size) { return false; } - Leds::holdAll(RGB_BLUE); // more than 30 is old old duo where header is combined with save if (size > 30) { return readHeaderLegacy2(header); @@ -128,7 +125,6 @@ bool UPDI::readHeader(ByteStream &header) if (size < 6) { return readHeaderLegacy1(header); } - Leds::holdAll(RGB_GREEN0); // modern duo header is 27 total and separate from modes stptr_p((const uint8_t *)&addr, 2); for (uint16_t i = 0; i < header.rawSize(); ++i) { @@ -759,8 +755,9 @@ bool UPDI::enterProgrammingMode() uint8_t status = ldcs(ASI_Key_Status); if (status != 0x10) { ERROR_LOGF("Bad prog key status: 0x%02x", status); - sendBreak(); - uint8_t status = ldcs(Status_B); + reset(); + //sendBreak(); + //uint8_t status = ldcs(Status_B); continue; } reset(); From fb481293e0744f2143c606c803eac09e9f4186bf Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 17 Jan 2025 05:59:44 -0800 Subject: [PATCH 7/9] fixed serial --- VortexEngine/src/Serial/Serial.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/VortexEngine/src/Serial/Serial.cpp b/VortexEngine/src/Serial/Serial.cpp index 1090e2abd6..fdc261a406 100644 --- a/VortexEngine/src/Serial/Serial.cpp +++ b/VortexEngine/src/Serial/Serial.cpp @@ -144,18 +144,8 @@ void SerialComs::write(ByteStream &byteStream) Vortex::vcallbacks()->serialWrite((const uint8_t *)&size, sizeof(size)); Vortex::vcallbacks()->serialWrite((const uint8_t *)byteStream.rawData(), byteStream.rawSize()); #else - //uint32_t bufSize = sizeof(size) + size; - //uint8_t *buf = new uint8_t[size]; - //if (!buf) { - // return; - //} - //memcpy(buf, &size, sizeof(size)); - //memcpy(buf + sizeof(size), byteStream.rawData(), size); Serial.write((const uint8_t *)&size, sizeof(size)); Serial.write((const uint8_t *)byteStream.rawData(), byteStream.rawSize()); - //Serial.write(buf, bufSize); - //delete[] buf; - //delay(100); Serial.flush(); #endif #endif From ede1e5fefd890cbda5e45448576952f317bb14e6 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 17 Jan 2025 07:47:14 -0800 Subject: [PATCH 8/9] small fixes --- .../src/Menus/MenuList/EditorConnection.cpp | 106 ++++++++++++++---- .../src/Menus/MenuList/EditorConnection.h | 5 + VortexEngine/src/UPDI/updi.cpp | 2 + VortexEngine/src/VortexConfig.h | 4 + 4 files changed, 93 insertions(+), 24 deletions(-) diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp index 18b14982ca..1bdf60df12 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.cpp +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.cpp @@ -334,6 +334,22 @@ void EditorConnection::handleState() m_state = STATE_IDLE; break; + // ------------------------------- + // Set Global Brightness + case STATE_SET_GLOBAL_BRIGHTNESS: + m_receiveBuffer.clear(); + SerialComs::write(EDITOR_VERB_READY); + m_state = STATE_SET_GLOBAL_BRIGHTNESS_RECEIVE; + break; + case STATE_SET_GLOBAL_BRIGHTNESS_RECEIVE: + // set the brightness of the device + if (!receiveBrightness()) { + break; + } + m_receiveBuffer.clear(); + m_state = STATE_IDLE; + break; + // ------------------------------- // Get Chromalinked Duo Header case STATE_PULL_HEADER_CHROMALINK: @@ -356,7 +372,8 @@ void EditorConnection::handleState() case STATE_PULL_MODE_CHROMALINK_SEND: // send the stuff if (!pullModeChromalink()) { - Leds::holdAll(RGB_RED); + // error? + break; } // done m_curStep = 0; @@ -472,6 +489,7 @@ void EditorConnection::handleState() UPDI::disable(); // show green Leds::setAll(RGB_GREEN); + SerialComs::write(EDITOR_VERB_FLASH_FIRMWARE_DONE); // go back to idle m_state = STATE_IDLE; break; @@ -531,24 +549,24 @@ bool EditorConnection::pullModeChromalink() { // try to receive the mode index uint8_t modeIdx = 0; + bool success = false; // only 9 modes on duo, maybe this should be a macro or something - if (!receiveModeIdx(modeIdx) || modeIdx >= 9) { - return false; + if (receiveModeIdx(modeIdx) && modeIdx < 9) { + ByteStream modeBuffer; + // same doesn't matter if this fails still need to send + success = UPDI::readMode(modeIdx, modeBuffer); + UPDI::reset(); + UPDI::disable(); + // lol just use the mode index as the radial to set + Leds::setRadial((Radial)modeIdx, success ? RGB_GREEN4 : RGB_RED4); + if (!success) { + // just send back a 0 if it failed + modeBuffer.init(1); + modeBuffer.serialize8(0); + } + // send the mode, could be empty buffer if reading failed + SerialComs::write(modeBuffer); } - // lol just use the mode index as the radial to set - Leds::setRadial((Radial)modeIdx, RGB_GREEN4); - ByteStream modeBuffer; - // same doesn't matter if this fails still need to send - bool success = UPDI::readMode(modeIdx, modeBuffer); - if (!success) { - // just send back a 0 if it failed - modeBuffer.init(1); - modeBuffer.serialize8(0); - } - // send the mode, could be empty buffer if reading failed - SerialComs::write(modeBuffer); - UPDI::reset(); - UPDI::disable(); // return whether reading the mode was successful return success; } @@ -573,13 +591,28 @@ bool EditorConnection::pushModeChromalink() bool EditorConnection::backupDuoModes() { - Leds::setRadials(RADIAL_0, (Radial)m_backupModeNum, RGB_CYAN0); if (m_backupModeNum == 9) { // reset counter for the restore step later m_backupModeNum = 0; // done return true; } + // backing up the first mode + if (m_backupModeNum == 0) { + // default this to true to begin + m_backupModes = true; + // double check the version and valid header before backing up modes + ByteStream duoHeader; + UPDI::readHeader(duoHeader); + if (duoHeader.size() >= 5) { + uint8_t major = duoHeader.data()[0]; + uint8_t minor = duoHeader.data()[1]; + if (major < 1 || minor < 3) { + // turn off mode backup the version isn't high enough + m_backupModes = false; + } + } + } // may use the defaults if backing up fails, default is whether backup is enabled bool useDefault = !m_backupModes; if (m_backupModes) { @@ -589,12 +622,12 @@ bool EditorConnection::backupDuoModes() useDefault = true; } } + // if not backing up, or backup failed, then store the default mode data in + // the backup because we will always write out the backups after flashing if (useDefault) { - // if not backing up, or backup failed, then store the default mode data in - // the backup because we will always write out the backups after flashing - m_modeBackups[m_backupModeNum].init(duo_default_sizes[m_backupModeNum], - duo_default_modes[m_backupModeNum]); + m_modeBackups[m_backupModeNum].init(duo_default_sizes[m_backupModeNum], duo_default_modes[m_backupModeNum]); } + Leds::setRadials(RADIAL_0, (Radial)m_backupModeNum, useDefault ? RGB_CYAN0 : RGB_PURPLE); // go to next mode m_backupModeNum++; return false; @@ -698,6 +731,8 @@ void EditorConnection::handleCommand() m_state = STATE_PUSH_MODE_CHROMALINK; } else if (receiveMessage(EDITOR_VERB_FLASH_FIRMWARE)) { m_state = STATE_CHROMALINK_FLASH_FIRMWARE; + } else if (receiveMessage(EDITOR_VERB_SET_GLOBAL_BRIGHTNESS)) { + m_state = STATE_SET_GLOBAL_BRIGHTNESS; } } @@ -784,9 +819,13 @@ bool EditorConnection::receiveBuffer(ByteStream &buffer) // clear the receive buffer m_receiveBuffer.clear(); if (!buffer.checkCRC()) { - // bad! this should never happen! + // TODO: this needs a different return value or something, usually false + // just means keep listening but in this case it listened and received bad + // data so we need to report this somehow Leds::holdAll(RGB_RED); - return false; + buffer.clear(); + // return true otherwise we'll get locked in this state forever + return true; } return true; } @@ -915,6 +954,25 @@ void EditorConnection::clearDemo() m_previewMode.init(); } + +bool EditorConnection::receiveBrightness() +{ + // create a new ByteStream that will hold the full buffer of data + ByteStream buf; + if (!receiveBuffer(buf)) { + return false; + } + if (!buf.size()) { + // failure but cannot return false we'll get stuck + return true; + } + uint8_t brightness = buf.data()[0]; + if (brightness > 0) { + Leds::setBrightness(brightness); + } + return true; +} + void EditorConnection::receiveModeVL() { // if reveiving new data set our last data time diff --git a/VortexEngine/src/Menus/MenuList/EditorConnection.h b/VortexEngine/src/Menus/MenuList/EditorConnection.h index 3fd06ccf75..109d819308 100644 --- a/VortexEngine/src/Menus/MenuList/EditorConnection.h +++ b/VortexEngine/src/Menus/MenuList/EditorConnection.h @@ -52,6 +52,7 @@ class EditorConnection : public Menu bool receiveDemoMode(); bool receiveMessage(const char *message); void clearDemo(); + bool receiveBrightness(); void receiveModeVL(); void showReceiveModeVL(); bool receiveModeIdx(uint8_t &idx); @@ -107,6 +108,10 @@ class EditorConnection : public Menu STATE_PUSH_EACH_MODE_WAIT, STATE_PUSH_EACH_MODE_DONE, + // set global brightness + STATE_SET_GLOBAL_BRIGHTNESS, + STATE_SET_GLOBAL_BRIGHTNESS_RECEIVE, + // pull the header from the chromalinked duo STATE_PULL_HEADER_CHROMALINK, diff --git a/VortexEngine/src/UPDI/updi.cpp b/VortexEngine/src/UPDI/updi.cpp index 519855b432..3acc522b72 100644 --- a/VortexEngine/src/UPDI/updi.cpp +++ b/VortexEngine/src/UPDI/updi.cpp @@ -233,9 +233,11 @@ bool UPDI::readMode(uint8_t idx, ByteStream &modeBuffer) } // initialize mode buffer if (!modeBuffer.init(DUO_MODE_SIZE)) { + modeBuffer.clear(); return false; } if (!enterProgrammingMode()) { + modeBuffer.clear(); return false; } // DUO_MODE_SIZE is the max duo mode size (the slot size) diff --git a/VortexEngine/src/VortexConfig.h b/VortexEngine/src/VortexConfig.h index 55404c349a..8e7288aa88 100644 --- a/VortexEngine/src/VortexConfig.h +++ b/VortexEngine/src/VortexConfig.h @@ -540,6 +540,10 @@ // done flashing firmware #define EDITOR_VERB_FLASH_FIRMWARE_DONE "K" +// set the global brightness of the device +#define EDITOR_VERB_SET_GLOBAL_BRIGHTNESS "L" + + // =================================================================== // Manually Configured Sizes // From a32542f39cdfc3fb4ee52b79ddace2dc40f83634 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 17 Jan 2025 07:48:27 -0800 Subject: [PATCH 9/9] missing files --- VortexEngine/src/Modes/DuoDefaultModes.cpp | 83 ++++++++++++++++++++++ VortexEngine/src/Modes/DuoDefaultModes.h | 6 ++ 2 files changed, 89 insertions(+) create mode 100644 VortexEngine/src/Modes/DuoDefaultModes.cpp create mode 100644 VortexEngine/src/Modes/DuoDefaultModes.h diff --git a/VortexEngine/src/Modes/DuoDefaultModes.cpp b/VortexEngine/src/Modes/DuoDefaultModes.cpp new file mode 100644 index 0000000000..9143d0da9a --- /dev/null +++ b/VortexEngine/src/Modes/DuoDefaultModes.cpp @@ -0,0 +1,83 @@ +#include "DuoDefaultModes.h" + +// 14 0 0 0 0 0 0 0 +// 51 31 69 110 2 6 6 3 +// 255 0 0 0 255 0 0 0 +// 255 0 +const uint8_t duo_mode1[] = { + 0x02, 0x06, 0x06, 0x03, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0x00 +}; +const uint8_t duo_mode2[] = { + 0x02, 0x02, 0x1C, 0x03, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x19, 0x03, 0xFF, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00 +}; +const uint8_t duo_mode3[] = { + 0x02, 0x02, 0x00, 0x01, + 0x97, 0x70, 0x9F, 0x00, 0x07, 0x01, 0x4D, 0x00, + 0xB2, 0x00 +}; +const uint8_t duo_mode4[] = { + 0x02, 0x02, 0x00, 0x06, + 0xC4, 0x70, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x00, 0x3B, 0x00, 0x00, 0xE9, + 0x4E, 0x00, 0x00, 0x03, 0x03, 0xC4, 0x4D, 0x00, + 0x00, 0x00, 0x17, 0x3B, 0xB2, 0xE9, 0x00 +}; +const uint8_t duo_mode5[] = { + 0x02, 0x06, 0x0E, 0x07, + 0xFF, 0x23, 0x00, 0x00, 0x06, 0x48, 0xFF, 0xC6, + 0x55, 0xFF, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x55, 0xFF, 0x55, 0x57, 0x00 +}; +const uint8_t duo_mode6[] = { + 0x02, 0x06, 0x0D, 0x05, + 0x9F, 0x00, 0x00, 0x5A, 0xFF, 0xFF, 0xFF, 0x9F, + 0x00, 0x00, 0x00, 0x66, 0xFF, 0xFF, 0x9F, 0x00 +}; +const uint8_t duo_mode7[] = { + 0x02, 0x06, 0x05, 0x05, + 0x00, 0x00, 0x30, 0xFF, 0x54, 0xAA, 0xB1, 0x00, + 0x00, 0x1B, 0x90, 0xFF, 0x55, 0x2D, 0x00, 0x00 +}; +const uint8_t duo_mode8[] = { + 0x02, 0x02, 0x08, 0x05, + 0x00, 0x40, 0x54, 0x52, 0x26, 0x00, 0x00, 0x00, + 0x54, 0xAA, 0xFF, 0x55, 0x0B, 0x00, 0x00, 0x00, + 0x08, 0x07, 0xFF, 0x23, 0x00, 0x00, 0x06, 0x48, + 0xFF, 0xC6, 0x55, 0xFF, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x55, 0xFF, 0x55, 0x57, 0x00 +}; +const uint8_t duo_mode9[] = { + 0x02, 0x02, 0x04, 0x02, + 0xFF, 0x00, 0xF6, 0x08, 0x00, 0x80, 0x00, 0x01, + 0x02, 0xFF, 0x00, 0xF6, 0x08, 0x00, 0x80, 0x00 +}; + +const uint8_t *duo_default_modes[9] = { + duo_mode1, + duo_mode2, + duo_mode3, + duo_mode4, + duo_mode5, + duo_mode6, + duo_mode7, + duo_mode8, + duo_mode9, +}; + +const uint32_t duo_default_sizes[9] = { + sizeof(duo_mode1), + sizeof(duo_mode2), + sizeof(duo_mode3), + sizeof(duo_mode4), + sizeof(duo_mode5), + sizeof(duo_mode6), + sizeof(duo_mode7), + sizeof(duo_mode8), + sizeof(duo_mode9), +}; + diff --git a/VortexEngine/src/Modes/DuoDefaultModes.h b/VortexEngine/src/Modes/DuoDefaultModes.h new file mode 100644 index 0000000000..9f03696bcd --- /dev/null +++ b/VortexEngine/src/Modes/DuoDefaultModes.h @@ -0,0 +1,6 @@ +#pragma once +#include + +// array of the default mode data and sizes +extern const uint8_t *duo_default_modes[9]; +extern const uint32_t duo_default_sizes[9];