From b341d947d7bca9531a77f2024a8f18df7d015c3a Mon Sep 17 00:00:00 2001 From: George Norton Date: Thu, 14 Sep 2023 13:12:44 +0100 Subject: [PATCH] Fix save config --- firmware/code/configuration_manager.c | 69 +++++++++++++++++---------- firmware/code/configuration_manager.h | 1 + firmware/code/run.c | 17 +++++-- firmware/code/run.h | 1 + 4 files changed, 58 insertions(+), 30 deletions(-) diff --git a/firmware/code/configuration_manager.c b/firmware/code/configuration_manager.c index 969a075..d112044 100644 --- a/firmware/code/configuration_manager.c +++ b/firmware/code/configuration_manager.c @@ -96,6 +96,13 @@ static bool reload_config = false; static uint16_t write_offset = 0; static uint16_t read_offset = 0; +typedef enum { + NormalOperation, + SaveRequested, + Saving +} State; +static State saveState = NormalOperation; + bool validate_filter_configuration(filter_configuration_tlv *filters) { if (filters->header.type != FILTER_CONFIGURATION) { @@ -357,37 +364,46 @@ void load_config() { } #ifndef TEST_TARGET -bool __no_inline_not_in_flash_func(save_configuration)() { - - - +bool __no_inline_not_in_flash_func(save_config)() { const uint8_t active_configuration = inactive_working_configuration ? 0 : 1; tlv_header* config = (tlv_header*) working_configuration[active_configuration]; - if (validate_configuration(config)) { + switch (saveState) { + case SaveRequested: + if (validate_configuration(config)) { + /* Turn the DAC off so we don't make a huge noise when disrupting + real time audio operation. */ + power_down_dac(); - const size_t config_length = config->length - ((size_t)config->value - (size_t)config); - // Write data to flash - uint8_t flash_buffer[CFG_BUFFER_SIZE]; - flash_header_tlv* flash_header = (flash_header_tlv*) flash_buffer; - flash_header->header.type = FLASH_HEADER; - flash_header->header.length = sizeof(flash_header_tlv) + config_length; - flash_header->magic = FLASH_MAGIC; - flash_header->version = CONFIG_VERSION; - memcpy((void*)(flash_header->tlvs), config->value, config_length); + const size_t config_length = config->length - ((size_t)config->value - (size_t)config); + // Write data to flash + uint8_t flash_buffer[CFG_BUFFER_SIZE]; + flash_header_tlv* flash_header = (flash_header_tlv*) flash_buffer; + flash_header->header.type = FLASH_HEADER; + flash_header->header.length = sizeof(flash_header_tlv) + config_length; + flash_header->magic = FLASH_MAGIC; + flash_header->version = CONFIG_VERSION; + memcpy((void*)(flash_header->tlvs), config->value, config_length); - /* Turn the DAC off so we don't make a huge noise when disrupting - real time audio operation. */ - power_down_dac(); + uint32_t ints = save_and_disable_interrupts(); + flash_range_erase(USER_CONFIGURATION_OFFSET, FLASH_SECTOR_SIZE); + flash_range_program(USER_CONFIGURATION_OFFSET, flash_buffer, CFG_BUFFER_SIZE); + restore_interrupts(ints); + saveState = Saving; - uint32_t ints = save_and_disable_interrupts(); - flash_range_erase(USER_CONFIGURATION_OFFSET, FLASH_SECTOR_SIZE); - flash_range_program(USER_CONFIGURATION_OFFSET, flash_buffer, CFG_BUFFER_SIZE); - restore_interrupts(ints); - - power_up_dac(); - - return true; + // Return true, so the caller skips processing audio + return true; + } + // Validation failed, give up. + saveState = NormalOperation; + break; + case Saving: + /* Turn the DAC off so we don't make a huge noise when disrupting + real time audio operation. */ + power_up_dac(); + saveState = NormalOperation; + return false; + default: } return false; @@ -415,7 +431,8 @@ bool process_cmd(tlv_header* cmd) { } break; case SAVE_CONFIGURATION: { - if (cmd->length == 4 && save_configuration()) { + if (cmd->length == 4) { + saveState = SaveRequested; result->type = OK; result->length = 4; return true; diff --git a/firmware/code/configuration_manager.h b/firmware/code/configuration_manager.h index 2ff115c..5428e4e 100644 --- a/firmware/code/configuration_manager.h +++ b/firmware/code/configuration_manager.h @@ -52,6 +52,7 @@ void config_in_packet(struct usb_endpoint *ep); void config_out_packet(struct usb_endpoint *ep); void configuration_ep_on_cancel(struct usb_endpoint *ep); extern void load_config(); +extern bool save_config(); extern void apply_config_changes(); #endif // CONFIGURATION_MANAGER_H \ No newline at end of file diff --git a/firmware/code/run.c b/firmware/code/run.c index 1d764ea..ebbb455 100644 --- a/firmware/code/run.c +++ b/firmware/code/run.c @@ -125,6 +125,18 @@ static void __no_inline_not_in_flash_func(_as_audio_packet)(struct usb_endpoint int32_t *out = (int32_t *) userbuf; int samples = usb_buffer->data_len / 2; + // Make sure core 1 is ready for us. + multicore_fifo_pop_blocking(); + + if (save_config()) { + // Skip processing while we are writing to flash + multicore_fifo_push_blocking(CORE0_ABORTED); + // keep on truckin' + usb_grow_transfer(ep->current_transfer, 1); + usb_packet_done(ep); + return; + } + if (preprocessing.reverse_stereo) { for (int i = 0; i < samples; i+=2) { out[i] = in[i+1]; @@ -136,8 +148,6 @@ static void __no_inline_not_in_flash_func(_as_audio_packet)(struct usb_endpoint out[i] = in[i]; } - // Make sure core 1 is ready for us. - multicore_fifo_pop_blocking(); multicore_fifo_push_blocking(CORE0_READY); multicore_fifo_push_blocking(samples); @@ -186,8 +196,7 @@ void __no_inline_not_in_flash_func(core1_entry)() { // Block until the userbuf is filled with data uint32_t ready = multicore_fifo_pop_blocking(); - while (ready != CORE0_READY) - ready = multicore_fifo_pop_blocking(); + if (ready == CORE0_ABORTED) continue; const uint32_t samples = multicore_fifo_pop_blocking(); diff --git a/firmware/code/run.h b/firmware/code/run.h index 2ccd6e3..ff339e9 100644 --- a/firmware/code/run.h +++ b/firmware/code/run.h @@ -149,6 +149,7 @@ static char *descriptor_strings[] = { #define SAMPLING_FREQ (CODEC_FREQ / 192) #define CORE0_READY 19813219 +#define CORE0_ABORTED 91231891 #define CORE1_READY 72965426 /*****************************************************************************