/* * re-program firmware: this entire function and all subroutines must run from RAM * (don't make this static!) */ __attribute__ ((section (".coderam"))) void flashFirmware(uint8_t* source, uint32_t size){ __disable_irq(); // Disable ALL interrupts. Can only be executed in Privileged modes. setLed(RED); eeprom_unlock(); if(size > (16+16+64+128)*1024){ eeprom_erase_sector(FLASH_Sector_6); toggleLed(); // inline } if(size > (16+16+64)*1024){ eeprom_erase_sector(FLASH_Sector_5); toggleLed(); } if(size > (16+16)*1024){ eeprom_erase_sector(FLASH_Sector_4); toggleLed(); } if(size > 16*1024){ eeprom_erase_sector(FLASH_Sector_3); toggleLed(); } eeprom_erase_sector(FLASH_Sector_2); toggleLed(); eeprom_write_block(ADDR_FLASH_SECTOR_2, source, size); eeprom_lock(); eeprom_wait(); NVIC_SystemReset(); // (static inline) } void programFlashTask(void* p){ int sector = flashSectorToWrite; uint32_t size = flashSizeToWrite; uint8_t* source = (uint8_t*)flashAddressToWrite; if(sector >= 0 && sector < MAX_USER_PATCHES && size <= 128*1024){ uint32_t addr = getFlashAddress(sector); eeprom_unlock(); int ret = eeprom_erase(addr); if(ret == 0) ret = eeprom_write_block(addr, source, size); eeprom_lock(); registry.init(); if(ret == 0){ // load and run program int pc = registry.getNumberOfPatches()-MAX_USER_PATCHES+sector; program.loadProgram(pc); // program.loadDynamicProgram(source, size); program.resetProgram(false); }else{ setErrorMessage(PROGRAM_ERROR, "Failed to write program to flash"); } }else if(sector == 0xff && size < MAX_SYSEX_FIRMWARE_SIZE){ flashFirmware(source, size); }else{ setErrorMessage(PROGRAM_ERROR, "Invalid flash program command"); } vTaskDelete(NULL); } void eraseFlashTask(void* p){ int sector = flashSectorToWrite; if(sector == 0xff){ for(int i=0; i<MAX_USER_PATCHES; ++i) eraseFlashProgram(i); settings.clearFlash(); }else if(sector >= 0 && sector < MAX_USER_PATCHES){ eraseFlashProgram(sector); }else{ setErrorMessage(PROGRAM_ERROR, "Invalid flash erase command"); } registry.init(); vTaskDelete(NULL); } // static int midiMessagesToSend = 0; // void sendMidiDataTask(void* p){ // switch(midiMessagesToSend){ // case SYSEX_PRESET_NAME_COMMAND: // midi.sendPatchNames(); // break; // // case 0: // // midi.sendDeviceInfo(); // // break; // // case SYSEX_PARAMETER_NAME_COMMAND: // // midi.sendPatchParameterNames(); // // break; // // case SYSEX_FIRMWARE_VERSION: // // midi.sendFirmwareVersion(); // // break; // // case SYSEX_DEVICE_ID: // // midi.sendDeviceId(); // // break; // // case SYSEX_DEVICE_STATS: // // midi.sendDeviceStats(); // // break; // // case SYSEX_PROGRAM_MESSAGE: // // midi.sendProgramMessage(); // // break; // // case SYSEX_PROGRAM_STATS: // // midi.sendProgramStats(); // // break; // // case PATCH_BUTTON: // // midi.sendCc(PATCH_BUTTON, isPushButtonPressed() ? 127 : 0); // // break; // // case LED: // // midi.sendCc(LED, getLed() == NONE ? 0 : getLed() == GREEN ? 42 : 84); // // break; // // case 127: // // midi.sendSettings(); // // break; // } // midiMessagesToSend = -1; // vTaskDelete(NULL); // } #ifdef BUTTON_PROGRAM_CHANGE #ifndef abs #define abs(x) ((x)>0?(x):-(x)) #endif /* abs */ void programChangeTask(void* p){ setLed(RED); int pc = settings.program_index; int bank = getAnalogValue(0)*5/4096; int prog = getAnalogValue(1)*8/4096+1; do{ float a = getAnalogValue(0)*5/4096.0 - 0.5/5; float b = getAnalogValue(1)*8/4096.0 - 0.5/8; // if(a - (int)a < 0.8) // deadband each segment: [0.8-1.0) if(a > 0 && abs(a - (int)a - 0.1) > 0.2) // deadband each segment: [0.9-1.1] bank = (int)a; if(b > 0 && abs(b-(int)b - 0.1) > 0.2) prog = (int)b+1; if(pc != bank*8+prog){ toggleLed(); pc = bank*8+prog; updateProgramIndex(pc); vTaskDelay(20); } }while(isPushButtonPressed() || pc < 1 || pc >= (int)registry.getNumberOfPatches()); setLed(RED); program.loadProgram(pc); program.resetProgram(false); for(;;); // wait for program manager to delete this task }
void programFlashTask(void* p){ int sector = flashSectorToWrite; uint32_t size = flashSizeToWrite; uint8_t* source = (uint8_t*)flashAddressToWrite; if(sector >= 0 && sector < MAX_USER_PATCHES && size <= 128*1024){ uint32_t addr = getFlashAddress(sector); eeprom_unlock(); int ret = eeprom_erase(addr); if(ret == 0) ret = eeprom_write_block(addr, source, size); eeprom_lock(); registry.init(); if(ret == 0){ // load and run program int pc = registry.getNumberOfPatches()-MAX_USER_PATCHES+sector; program.loadProgram(pc); // program.loadDynamicProgram(source, size); program.resetProgram(false); }else{ setErrorMessage(PROGRAM_ERROR, "Failed to write program to flash"); } }else if(sector == 0xff && size < MAX_SYSEX_FIRMWARE_SIZE){ flashFirmware(source, size); }else{ setErrorMessage(PROGRAM_ERROR, "Invalid flash program command"); } vTaskDelete(NULL); }