void ManipulateFile(void) { sdcard_attemptMountIfUnmounted(); if (FileName[0]) { // backwards compatibility FRESULT err; err = f_open(&pFile, &FileName[0], FA_WRITE | FA_CREATE_ALWAYS); if (err != FR_OK) { report_fatfs_error(err,&FileName[0]); } err = f_lseek(&pFile, pFileSize); if (err != FR_OK) { report_fatfs_error(err,&FileName[0]); } err = f_lseek(&pFile, 0); if (err != FR_OK) { report_fatfs_error(err,&FileName[0]); } } else { // filename[0] == 0 if (FileName[1]=='d') { // create directory FRESULT err; err = f_mkdir(&FileName[6]); if ((err != FR_OK) && (err != FR_EXIST)) { report_fatfs_error(err,&FileName[6]); } // and set timestamp FILINFO fno; fno.fdate = FileName[2] + (FileName[3]<<8); fno.ftime = FileName[4] + (FileName[5]<<8); err = f_utime(&FileName[6],&fno); if (err != FR_OK) { report_fatfs_error(err,&FileName[6]); } } else if (FileName[1]=='f') { // create file FRESULT err; err = f_open(&pFile, &FileName[6], FA_WRITE | FA_CREATE_ALWAYS); if (err != FR_OK) { report_fatfs_error(err,&FileName[6]); } err = f_lseek(&pFile, pFileSize); if (err != FR_OK) { report_fatfs_error(err,&FileName[6]); } err = f_lseek(&pFile, 0); if (err != FR_OK) { report_fatfs_error(err,&FileName[6]); } } else if (FileName[1]=='D') { // delete FRESULT err; err = f_unlink(&FileName[6]); if (err != FR_OK) { report_fatfs_error(err,&FileName[6]); } } else if (FileName[1]=='C') { // change working directory FRESULT err; err = f_chdir(&FileName[6]); if (err != FR_OK) { report_fatfs_error(err,&FileName[6]); } } else if (FileName[1]=='I') { // get file info FRESULT err; FILINFO fno; fno.lfname = &((char*)fbuff)[0]; fno.lfsize = 256; err = f_stat(&FileName[6],&fno); if (err == FR_OK) { char *msg = &((char*)fbuff)[0]; msg[0] = 'A'; msg[1] = 'x'; msg[2] = 'o'; msg[3] = 'f'; *(int32_t *)(&msg[4]) = fno.fsize; *(int32_t *)(&msg[8]) = fno.fdate + (fno.ftime<<16); strcpy(&msg[12], &FileName[6]); int l = strlen(&msg[12]); chSequentialStreamWrite((BaseSequentialStream * )&BDU1, (const unsigned char* )msg, l+13); } } } }
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; } }
int main(void) { // copy vector table to SRAM1! #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnonnull" memcpy((char *)0x20000000, (const char)0x00000000, 0x200); #pragma GCC diagnostic pop // remap SRAM1 to 0x00000000 SYSCFG->MEMRMP |= 0x03; halInit(); chSysInit(); sdcard_init(); sysmon_init(); #if ENABLE_SERIAL_DEBUG // SD2 for serial debug output palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7) | PAL_MODE_INPUT); // RX palSetPadMode(GPIOA, 2, PAL_MODE_OUTPUT_PUSHPULL); // TX palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7)); // TX // 115200 baud static const SerialConfig sd2Cfg = {115200, 0, 0, 0}; sdStart(&SD2, &sd2Cfg); chprintf((BaseSequentialStream * )&SD2,"Hello world!\r\n"); #endif exception_init(); InitPatch0(); InitPConnection(); InitPWM(); // display SPI CS? palSetPadMode(GPIOC, 1, PAL_MODE_OUTPUT_PUSHPULL); palSetPad(GPIOC, 1); chThdSleepMilliseconds(10); palSetPadMode(SW2_PORT, SW2_PIN, PAL_MODE_INPUT_PULLDOWN); axoloti_board_init(); codec_init(); if (!palReadPad(SW2_PORT, SW2_PIN)) { // button S2 not pressed // watchdog_init(); chThdSleepMilliseconds(1); } start_dsp_thread(); adc_init(); axoloti_math_init(); midi_init(); #if ((BOARD_AXOLOTI_V03)||(BOARD_AXOLOTI_V05)) axoloti_control_init(); #endif ui_init(); StartLoadPatchTread(); #if (BOARD_AXOLOTI_V05) configSDRAM(); //memTest(); #endif #ifdef ENABLE_USB_HOST MY_USBH_Init(); #endif if (!exception_check()) { // only try booting a patch when no exception is to be reported #if ((BOARD_AXOLOTI_V03)||(BOARD_AXOLOTI_V05)) sdcard_attemptMountIfUnmounted(); if (fs_ready && !palReadPad(SW2_PORT, SW2_PIN)){ // button S2 not pressed FRESULT res; // res = f_stat("/start.bin", NULL); // if (res == FR_OK) { LoadPatch("/start.bin"); // } } #endif // if no patch booting or running yet // try loading from flash if (patchStatus) { // patch in flash sector 11 memcpy((uint8_t *)PATCHMAINLOC, (uint8_t *)PATCHFLASHLOC, PATCHFLASHSIZE); if ((*(uint32_t *)PATCHMAINLOC != 0xFFFFFFFF) && (*(uint32_t *)PATCHMAINLOC != 0)) { if (!palReadPad(SW2_PORT, SW2_PIN)) // button S2 not pressed StartPatch(); } } } while (1) { chThdSleepMilliseconds(1000); } }