Skip to content

Commit

Permalink
Fix save config (#27)
Browse files Browse the repository at this point in the history
* Fix save config

* Fix save config when no audio is playing

* Fix build issue with the github workflow compiler
  • Loading branch information
george-norton authored Oct 16, 2023
1 parent 84306c0 commit 9c036f0
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 33 deletions.
82 changes: 53 additions & 29 deletions firmware/code/configuration_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -357,37 +364,47 @@ 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)) {

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);

power_up_dac();

return true;
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);

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;

// 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:
break;
}

return false;
Expand Down Expand Up @@ -415,7 +432,14 @@ bool process_cmd(tlv_header* cmd) {
}
break;
case SAVE_CONFIGURATION: {
if (cmd->length == 4 && save_configuration()) {
if (cmd->length == 4) {
saveState = SaveRequested;
if (audio_state.interface == 0) {
// The OS will configure the alternate "zero" interface when the device is not in use
// in this sate we can write to flash now. Otherwise, defer the save until we get the next
// usb packet.
save_config();
}
result->type = OK;
result->length = 4;
return true;
Expand Down
1 change: 1 addition & 0 deletions firmware/code/configuration_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
19 changes: 15 additions & 4 deletions firmware/code/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ static uint8_t *userbuf;
audio_state_config audio_state = {
.freq = 48000,
.de_emphasis_frequency = 0x1, // 48khz
.interface = 0
};

preprocessing_config preprocessing = {
Expand Down Expand Up @@ -125,6 +126,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];
Expand All @@ -136,8 +149,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);

Expand Down Expand Up @@ -186,8 +197,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();

Expand Down Expand Up @@ -760,6 +770,7 @@ static const struct usb_transfer_type _audio_cmd_transfer_type = {

static bool as_set_alternate(struct usb_interface *interface, uint alt) {
assert(interface == &as_op_interface);
audio_state.interface = alt;
switch (alt) {
case 0: power_down_dac(); return true;
case 1: power_up_dac(); return true;
Expand Down
2 changes: 2 additions & 0 deletions firmware/code/run.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ typedef struct _audio_state_config {
int16_t _target_pcm3060_registers;
};
int16_t pcm3060_registers;
int8_t interface;
} audio_state_config;
extern audio_state_config audio_state;

Expand Down Expand Up @@ -149,6 +150,7 @@ static char *descriptor_strings[] = {
#define SAMPLING_FREQ (CODEC_FREQ / 192)

#define CORE0_READY 19813219
#define CORE0_ABORTED 91231891
#define CORE1_READY 72965426

/*****************************************************************************
Expand Down

0 comments on commit 9c036f0

Please sign in to comment.