keep options behind a semaphore

This commit is contained in:
Killorin 2025-04-17 10:51:51 -04:00
parent 7dd1aee53c
commit d4f1ef17b9
2 changed files with 43 additions and 15 deletions

54
main.c
View file

@ -1,3 +1,4 @@
/* /*
* ECE 3849 Lab2 starter project * ECE 3849 Lab2 starter project
* *
@ -42,9 +43,18 @@ uint32_t cputime_unloaded;
uint16_t adc_buffer_sample[LOCAL_BUF_LEN]; // copy of g adc buffer uint16_t adc_buffer_sample[LOCAL_BUF_LEN]; // copy of g adc buffer
uint8_t adc_buffer_processed[LOCAL_BUF_LEN]; // copy of g adc buffer uint8_t adc_buffer_processed[LOCAL_BUF_LEN]; // copy of g adc buffer
uint8_t voltage_scale = 4; // 2v typedef struct
uint8_t time_scale = 5; // 20us {
uint8_t trigger_mode = 1; // rising uint8_t voltage_scale;
uint8_t time_scale;
uint8_t trigger_mode;
} Options;
Options options = {
.voltage_scale = 4, // 2v
.time_scale = 5, // 20us
.trigger_mode = 1, // rising
};
// assuming square lcd // assuming square lcd
#define HEIGHT LCD_VERTICAL_MAX #define HEIGHT LCD_VERTICAL_MAX
@ -53,7 +63,7 @@ uint8_t trigger_mode = 1; // rising
#define VIN_RANGE 3.3 // volts #define VIN_RANGE 3.3 // volts
#define ADC_BITS 12 #define ADC_BITS 12
#define ADC_OFFSET 30 #define ADC_OFFSET 100
#define VOLTAGE_SCALES 5 #define VOLTAGE_SCALES 5
const char * const gVoltageScaleStr[VOLTAGE_SCALES] = { const char * const gVoltageScaleStr[VOLTAGE_SCALES] = {
@ -162,6 +172,9 @@ void capture_waveform(UArg arg1, UArg arg2)
while(true) { while(true) {
Semaphore_pend(capture_sem, BIOS_WAIT_FOREVER); Semaphore_pend(capture_sem, BIOS_WAIT_FOREVER);
// single read of options is atomic
int32_t trigger_mode = options.trigger_mode;
int32_t adc_current_index; int32_t adc_current_index;
int32_t j; int32_t j;
int trigger; int trigger;
@ -184,7 +197,9 @@ void process_waveform(UArg arg1, UArg arg2) {
while(true) { while(true) {
Semaphore_pend(process_sem, BIOS_WAIT_FOREVER); Semaphore_pend(process_sem, BIOS_WAIT_FOREVER);
float fVoltsPerDiv = gVoltageScale[voltage_scale]; // single read of global options is atomic
float fVoltsPerDiv = gVoltageScale[options.voltage_scale];
float fScale = (VIN_RANGE * PIXELS_PER_DIV)/((1 << ADC_BITS) * fVoltsPerDiv); float fScale = (VIN_RANGE * PIXELS_PER_DIV)/((1 << ADC_BITS) * fVoltsPerDiv);
int j; int j;
@ -204,28 +219,33 @@ void process_waveform(UArg arg1, UArg arg2) {
void handle_user_input() { void handle_user_input() {
// handle buttons // handle buttons
Button button = (Button) 0; Button button = (Button) 0;
Options local_options = options; // this is the only writer
while (true) { while (true) {
Mailbox_pend(button_mailbox, &button, BIOS_WAIT_FOREVER); Mailbox_pend(button_mailbox, &button, BIOS_WAIT_FOREVER);
switch (button) { switch (button) {
case S1: // toggle edge case S1: // toggle edge
trigger_mode = (trigger_mode + 1) % 3; local_options.trigger_mode = (local_options.trigger_mode + 1) % 3;
break; break;
case Up: // next scale case Up: // next scale
voltage_scale = (voltage_scale + 1) % VOLTAGE_SCALES; local_options.voltage_scale = (local_options.voltage_scale + 1) % VOLTAGE_SCALES;
break; break;
case Down: // previous scale case Down: // previous scale
voltage_scale = (voltage_scale + VOLTAGE_SCALES - 1) % VOLTAGE_SCALES; local_options.voltage_scale = (local_options.voltage_scale + VOLTAGE_SCALES - 1) % VOLTAGE_SCALES;
break; break;
case Right: // next scale case Right: // next scale
time_scale = (time_scale + 1) % TIME_SCALES; local_options.time_scale = (local_options.time_scale + 1) % TIME_SCALES;
set_frequency(gTImeScale[time_scale]); set_frequency(gTImeScale[local_options.time_scale]);
break; break;
case Left: // previous scale case Left: // previous scale
time_scale = (time_scale + TIME_SCALES - 1) % TIME_SCALES; local_options.time_scale = (local_options.time_scale + TIME_SCALES - 1) % TIME_SCALES;
set_frequency(gTImeScale[time_scale]); set_frequency(gTImeScale[local_options.time_scale]);
break; break;
} }
Semaphore_pend(options_sem, BIOS_WAIT_FOREVER);
options = local_options;
Semaphore_post(options_sem);
} }
} }
@ -237,6 +257,10 @@ void display_waveform(UArg arg1, UArg arg2)
while(1) { while(1) {
Semaphore_pend(display_sem, BIOS_WAIT_FOREVER); Semaphore_pend(display_sem, BIOS_WAIT_FOREVER);
Semaphore_pend(options_sem, BIOS_WAIT_FOREVER);
Options local_options = options;
Semaphore_post(options_sem);
// calculate cpu usage // calculate cpu usage
uint32_t cputime_loaded; uint32_t cputime_loaded;
cputime_loaded = cpu_load_count(); cputime_loaded = cpu_load_count();
@ -261,12 +285,12 @@ void display_waveform(UArg arg1, UArg arg2)
// info // info
GrContextForegroundSet(&sContext, ClrWheat); GrContextForegroundSet(&sContext, ClrWheat);
GrStringDraw(&sContext, gVoltageScaleStr[voltage_scale], /*length*/ -1, /*x*/ 0, /*y*/ 0, /*opaque*/ false); GrStringDraw(&sContext, gVoltageScaleStr[local_options.voltage_scale], /*length*/ -1, /*x*/ 0, /*y*/ 0, /*opaque*/ false);
GrStringDraw(&sContext, gTimeScaleStr[time_scale], /*length*/ -1, /*x*/ 60, /*y*/ 0, /*opaque*/ false); GrStringDraw(&sContext, gTimeScaleStr[local_options.time_scale], /*length*/ -1, /*x*/ 60, /*y*/ 0, /*opaque*/ false);
snprintf(str, sizeof(str), "CPU Load %.1f%%", usage_percent); snprintf(str, sizeof(str), "CPU Load %.1f%%", usage_percent);
GrStringDraw(&sContext, str, /*length*/ -1, /*x*/ 0, /*y*/ HEIGHT - 10, /*opaque*/ false); GrStringDraw(&sContext, str, /*length*/ -1, /*x*/ 0, /*y*/ HEIGHT - 10, /*opaque*/ false);
switch (trigger_mode) { switch (local_options.trigger_mode) {
case 1: case 1:
GrStringDraw(&sContext, "^", /*length*/ -1, /*x*/ WIDTH - 10, /*y*/ 0, /*opaque*/ false); GrStringDraw(&sContext, "^", /*length*/ -1, /*x*/ WIDTH - 10, /*y*/ 0, /*opaque*/ false);
break; break;

View file

@ -593,3 +593,7 @@ var task5Params = new Task.Params();
task5Params.instance.name = "user_input"; task5Params.instance.name = "user_input";
task5Params.priority = 6; task5Params.priority = 6;
Program.global.user_input = Task.create("&handle_user_input", task5Params); Program.global.user_input = Task.create("&handle_user_input", task5Params);
var semaphore4Params = new Semaphore.Params();
semaphore4Params.instance.name = "options_sem";
semaphore4Params.mode = Semaphore.Mode_BINARY;
Program.global.options_sem = Semaphore.create(1, semaphore4Params);