void MidiController::sendSettings(){ sendCc(PATCH_PARAMETER_A, (uint8_t)(patches.getCurrentPatchProcessor()->getParameterValue(PARAMETER_A)*127.0) & 0x7f); sendCc(PATCH_PARAMETER_B, (uint8_t)(patches.getCurrentPatchProcessor()->getParameterValue(PARAMETER_B)*127.0) & 0x7f); sendCc(PATCH_PARAMETER_C, (uint8_t)(patches.getCurrentPatchProcessor()->getParameterValue(PARAMETER_C)*127.0) & 0x7f); sendCc(PATCH_PARAMETER_D, (uint8_t)(patches.getCurrentPatchProcessor()->getParameterValue(PARAMETER_D)*127.0) & 0x7f); sendCc(PATCH_PARAMETER_E, (uint8_t)(patches.getCurrentPatchProcessor()->getParameterValue(PARAMETER_E)*127.0) & 0x7f); sendCc(PATCH_BUTTON, isPushButtonPressed() ? 127 : 0); sendCc(LED, getLed() == NONE ? 0 : getLed() == GREEN ? 42 : 84); sendCc(PATCH_MODE, settings.patch_mode << 5); sendCc(PATCH_SLOT_GREEN, settings.patch_green); sendCc(PATCH_SLOT_RED, settings.patch_red); sendCc(ACTIVE_SLOT, patches.getActiveSlot() == GREEN ? 0 : 127); sendCc(LEFT_INPUT_GAIN, codec.getInputGainLeft()<<2); sendCc(RIGHT_INPUT_GAIN, codec.getInputGainRight()<<2); sendCc(LEFT_OUTPUT_GAIN, codec.getOutputGainLeft()); sendCc(RIGHT_OUTPUT_GAIN, codec.getOutputGainRight()); sendCc(LEFT_INPUT_MUTE, codec.getInputMuteLeft() ? 127 : 0); sendCc(RIGHT_INPUT_MUTE, codec.getInputMuteRight() ? 127 : 0); sendCc(LEFT_OUTPUT_MUTE, codec.getOutputMuteLeft() ? 127 : 0); sendCc(RIGHT_OUTPUT_MUTE, codec.getOutputMuteRight() ? 127 : 0); sendCc(BYPASS, codec.getBypass() ? 127 : 0); sendCc(SAMPLING_RATE, (codec.getSamplingRate() >> 10) + 20); sendCc(SAMPLING_BITS, (codec.getFormat() << 4) + 20); sendCc(CODEC_MASTER, codec.isMaster() ? 127 : 0); sendCc(CODEC_PROTOCOL, codec.getProtocol() == I2S_PROTOCOL_PHILIPS ? 0 : 127); sendCc(SAMPLING_SIZE, settings.audio_blocksize>>4); sendCc(LEFT_RIGHT_SWAP, codec.getSwapLeftRight()); }
/* * 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 pushButtonCallback(){ DEBOUNCE(pushbutton, 200); if(isPushButtonPressed() && settings.patch_mode != PATCHMODE_SINGLE) toggleActiveSlot(); }
void setup(){ // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 0 bits for preemption, 4 bits for subpriority /* Set up interrupt controller: 2 bits for priority (0-3), * 2 bits for sub-priority (0-3). Priorities control which * interrupts are allowed to preempt one another. */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Increase SysTick priority to be higher than USB interrupt * priority. USB code stalls inside interrupt and we can't let * this throw off the SysTick timer. */ NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, SYSTICK_PRIORITY, SYSTICK_SUBPRIORITY)); NVIC_SetPriority(DMA1_Stream3_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 0, 0)); NVIC_SetPriority(DMA1_Stream4_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 0, 0)); NVIC_SetPriority(SPI2_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 1, 0)); NVIC_SetPriority(ADC_IRQn, NVIC_EncodePriority(NVIC_PriorityGroup_2, 2, 0)); ledSetup(); setLed(RED); /* check if we need to DFU boot */ configureDigitalInput(SWITCH_B_PORT, SWITCH_B_PIN, GPIO_PuPd_UP); if(isPushButtonPressed()) jump_to_bootloader(); adcSetup(); clockSetup(); setupSwitchA(footSwitchCallback); setupSwitchB(pushButtonCallback); settings.init(); midi.init(MIDI_CHANNEL); patches.init(); #ifdef EXPRESSION_PEDAL #ifndef OWLMODULAR setupExpressionPedal(); #endif #endif RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // DEBUG configureDigitalOutput(GPIOB, GPIO_Pin_1); // PB1, DEBUG LED debugClear(); #ifdef DEBUG_AUDIO RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // DEBUG configureDigitalOutput(GPIOA, GPIO_Pin_7); // PA7 DEBUG configureDigitalOutput(GPIOC, GPIO_Pin_5); // PC5 DEBUG clearPin(GPIOC, GPIO_Pin_5); // DEBUG clearPin(GPIOA, GPIO_Pin_7); // DEBUG #endif /* DEBUG_AUDIO */ usb_init(); #if SERIAL_PORT == 1 setupSerialPort1(115200); #elif SERIAL_PORT == 2 setupSerialPort2(115200); // expression pedal #warning expression pedal jack configured as serial port #ifdef EXPRESSION_PEDAL #error invalid configuration #endif #endif #ifdef OWLMODULAR configureDigitalInput(GPIOB, GPIO_Pin_6, GPIO_PuPd_NOPULL); // PB6 OWL Modular digital input configureDigitalOutput(GPIOB, GPIO_Pin_7); // PB7 OWL Modular digital output setPin(GPIOB, GPIO_Pin_7); // PB7 OWL Modular digital output #endif codec.setup(); codec.init(settings); printString("startup\n"); updateBypassMode(); codec.start(); }