void SDLoadPatch(char *fname) { FIL FileObject; FRESULT err; uint32_t bytes_read; StopPatch(); err = f_open(&FileObject, fname, FA_READ | FA_OPEN_EXISTING); chThdSleepMilliseconds(10); if (err != FR_OK) { return; } err = f_read(&FileObject, (uint8_t *)PATCHMAINLOC, 0xE000, (void *)&bytes_read); if (err != FR_OK) { chSysHalt(); } err = f_close(&FileObject); chThdSleepMilliseconds(10); StartPatch(); }
void PExReceiveByte(unsigned char c) { static char header = 0; static int state = 0; static unsigned int index; static int value; static int position; static int offset; static int length; static int a; static int b; static uint32_t patchid; if (!header) { switch (state) { case 0: if (c == 'A') state++; break; case 1: if (c == 'x') state++; else state = 0; break; case 2: if (c == 'o') state++; else state = 0; break; case 3: header = c; if (c == 'P') { // param change state = 4; } else if (c == 'R') { // preset change state = 4; } else if (c == 'W') { // write state = 4; } else if (c == 'w') { // write file to SD state = 4; } else if (c == 'T') { // change preset state = 4; } else if (c == 'M') { // midi command state = 4; } else if (c == 'B') { // virtual Axoloti Control buttons state = 4; } else if (c == 'C') { // create sdcard file state = 4; } else if (c == 'A') { // append data to sdcard file state = 4; } else if (c == 'r') { // generic read state = 4; } else if (c == 'y') { // generic read state = 4; } else if (c == 'S') { // stop patch state = 0; header = 0; StopPatch(); AckPending = 1; } else if (c == 'D') { // go to DFU mode state = 0; header = 0; StopPatch(); exception_initiate_dfu(); } else if (c == 'F') { // copy to flash state = 0; header = 0; StopPatch(); CopyPatchToFlash(); } else if (c == 'd') { // read directory listing state = 0; header = 0; StopPatch(); ReadDirectoryListing(); } else if (c == 's') { // start patch state = 0; header = 0; loadPatchIndex = LIVE; StartPatch(); AckPending = 1; } else if (c == 'V') { // FW version number state = 0; header = 0; ReplyFWVersion(); AckPending = 1; } else if (c == 'p') { // ping state = 0; header = 0; #ifdef DEBUG_SERIAL chprintf((BaseSequentialStream * )&SD2,"ping\r\n"); #endif AckPending = 1; } else if (c == 'c') { // close sdcard file state = 0; header = 0; CloseFile(); AckPending = 1; } else state = 0; break; } } else if (header == 'P') { // param change switch (state) { case 4: patchid = c; state++; break; case 5: patchid += c << 8; state++; break; case 6: patchid += c << 16; state++; break; case 7: patchid += c << 24; state++; break; case 8: value = c; state++; break; case 9: value += c << 8; state++; break; case 10: value += c << 16; state++; break; case 11: value += c << 24; state++; break; case 12: index = c; state++; break; case 13: index += c << 8; state = 0; header = 0; if ((patchid == patchMeta.patchID) && (index < patchMeta.numPEx)) { PExParameterChange(&(patchMeta.pPExch)[index], value, 0xFFFFFFEE); } break; default: state = 0; header = 0; } } else if (header == 'W') { switch (state) { case 4: offset = c; state++; break; case 5: offset += c << 8; state++; break; case 6: offset += c << 16; state++; break; case 7: offset += c << 24; state++; break; case 8: value = c; state++; break; case 9: value += c << 8; state++; break; case 10: value += c << 16; state++; break; case 11: value += c << 24; state++; break; default: if (value > 0) { value--; *((unsigned char *)offset) = c; offset++; if (value == 0) { header = 0; state = 0; AckPending = 1; } } else { header = 0; state = 0; AckPending = 1; } } } else if (header == 'w') { switch (state) { case 4: offset = c; state++; break; case 5: offset += c << 8; state++; break; case 6: offset += c << 16; state++; break; case 7: offset += c << 24; state++; break; case 8: value = c; state++; break; case 9: value += c << 8; state++; break; case 10: value += c << 16; state++; break; case 11: value += c << 24; length = value; position = offset; state++; break; case 12: case 13: case 14: case 15: case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: FileName[state - 12] = c; state++; break; default: if (value > 0) { value--; *((unsigned char *)position) = c; position++; if (value == 0) { FRESULT err; header = 0; state = 0; sdcard_attemptMountIfUnmounted(); err = f_open(&pFile, &FileName[0], FA_WRITE | FA_CREATE_ALWAYS); if (err != FR_OK) { LogTextMessage("File open failed"); } int bytes_written; err = f_write(&pFile, (char *)offset, length, (void *)&bytes_written); if (err != FR_OK) { LogTextMessage("File write failed"); } err = f_close(&pFile); if (err != FR_OK) { LogTextMessage("File close failed"); } AckPending = 1; } } else { header = 0; state = 0; } } } else if (header == 'T') { // Apply Preset ApplyPreset(c); AckPending = 1; header = 0; state = 0; } else if (header == 'M') { // Midi message static uint8_t midi_r[3]; switch (state) { case 4: midi_r[0] = c; state++; break; case 5: midi_r[1] = c; state++; break; case 6: midi_r[2] = c; MidiInMsgHandler(MIDI_DEVICE_INTERNAL, 1, midi_r[0], midi_r[1], midi_r[2]); header = 0; state = 0; break; default: header = 0; state = 0; } } else if (header == 'C') { switch (state) { case 4: pFileSize = c; state++; break; case 5: pFileSize += c << 8; state++; break; case 6: pFileSize += c << 16; state++; break; case 7: pFileSize += c << 24; state++; break; case 8: FileName[state - 8] = c; // filename starting with null means there are attributes present state++; break; default: if (c || ((!FileName[0])&&(state<14))) { FileName[state - 8] = c; state++; } else { FileName[state - 8] = 0; ManipulateFile(); header = 0; state = 0; AckPending = 1; } } } else if (header == 'A') { switch (state) { case 4: value = c; state++; break; case 5: value += c << 8; state++; break; case 6: value += c << 16; state++; break; case 7: value += c << 24; length = value; position = PATCHMAINLOC; state++; break; default: if (value > 0) { value--; *((unsigned char *)position) = c; position++; if (value == 0) { FRESULT err; header = 0; state = 0; int bytes_written; err = f_write(&pFile, (char *)PATCHMAINLOC, length, (void *)&bytes_written); if (err != FR_OK) { report_fatfs_error(err,0); } AckPending = 1; } } else { header = 0; state = 0; } } } else if (header == 'B') { switch (state) { case 4: a = c; state++; break; case 5: a += c << 8; state++; break; case 6: a += c << 16; state++; break; case 7: a += c << 24; state++; break; case 8: b = c; state++; break; case 9: b += c << 8; state++; break; case 10: b += c << 16; state++; break; case 11: b += c << 24; state++; break; case 12: EncBuffer[0] += c; state++; break; case 13: EncBuffer[1] += c; state++; break; case 14: EncBuffer[2] += c; state++; break; case 15: EncBuffer[3] += c; header = 0; state = 0; Btn_Nav_Or.word = Btn_Nav_Or.word | a; Btn_Nav_And.word = Btn_Nav_And.word & b; break; } } else if (header == 'R') { switch (state) { case 4: length = c; state++; break; case 5: length += c << 8; state++; break; case 6: length += c << 16; state++; break; case 7: length += c << 24; state++; offset = (int)patchMeta.pPresets; break; default: if (length > 0) { length--; if (offset) { *((unsigned char *)offset) = c; offset++; } if (length == 0) { header = 0; state = 0; AckPending = 1; } } else { header = 0; state = 0; AckPending = 1; } } } else if (header == 'r') { // generic read switch (state) { case 4: offset = c; state++; break; case 5: offset += c << 8; state++; break; case 6: offset += c << 16; state++; break; case 7: offset += c << 24; state++; break; case 8: value = c; state++; break; case 9: value += c << 8; state++; break; case 10: value += c << 16; state++; break; case 11: value += c << 24; uint32_t read_repy_header[3]; ((char*)read_repy_header)[0] = 'A'; ((char*)read_repy_header)[1] = 'x'; ((char*)read_repy_header)[2] = 'o'; ((char*)read_repy_header)[3] = 'r'; read_repy_header[1] = offset; read_repy_header[2] = value; chSequentialStreamWrite((BaseSequentialStream * )&BDU1, (const unsigned char* )(&read_repy_header[0]), 3 * 4); chSequentialStreamWrite((BaseSequentialStream * )&BDU1, (const unsigned char* )(offset), value); AckPending = true; header = 0; state = 0; break; } } else if (header == 'y') { // generic read, 32bit switch (state) { case 4: offset = c; state++; break; case 5: offset += c << 8; state++; break; case 6: offset += c << 16; state++; break; case 7: offset += c << 24; uint32_t read_repy_header[3]; ((char*)read_repy_header)[0] = 'A'; ((char*)read_repy_header)[1] = 'x'; ((char*)read_repy_header)[2] = 'o'; ((char*)read_repy_header)[3] = 'y'; read_repy_header[1] = offset; read_repy_header[2] = *((uint32_t*)offset); chSequentialStreamWrite((BaseSequentialStream * )&BDU1, (const unsigned char* )(&read_repy_header[0]), 3 * 4); AckPending = true; header = 0; state = 0; break; } } else { header = 0; state = 0; } }