Refactor: beat tempo now works off of a timer instead of manual delay
parent
d1ac219547
commit
f7559f71d4
|
|
@ -77,6 +77,7 @@ static QueueHandle_t control_event_queue = NULL;
|
|||
/* Timers */
|
||||
static gptimer_handle_t tap_tempo_timer = NULL;
|
||||
static gptimer_handle_t gate_timer = NULL;
|
||||
static gptimer_handle_t tempo_timer = NULL;
|
||||
|
||||
static const uint16_t DEBOUNCE_TIMEOUT = 10; /* polling period length when debouncing in ms */
|
||||
static uint64_t debounce_time = 0; /* system time of last intterupt */
|
||||
|
|
@ -88,9 +89,12 @@ static const uint32_t DEFAULT_BPM = 120;
|
|||
static uint16_t current_bpm = DEFAULT_BPM;
|
||||
lv_obj_t * bpm_label = NULL;
|
||||
|
||||
TaskHandle_t tempo_handle;
|
||||
|
||||
#define SEQ_MAX_LEN 8
|
||||
static uint8_t sequence[SEQ_MAX_LEN] = {0};
|
||||
static uint8_t seq_len = SEQ_MAX_LEN;
|
||||
uint8_t current_step = 0;
|
||||
lv_obj_t * sequence_label = NULL;
|
||||
lv_obj_t * sequence_tracker = NULL;
|
||||
|
||||
|
|
@ -105,8 +109,26 @@ uint32_t ms_to_bpm(uint32_t ms) {
|
|||
return 60000 / ms;
|
||||
}
|
||||
|
||||
static void pulse_cv(bool triggered) {
|
||||
ESP_ERROR_CHECK(gptimer_start(gate_timer));
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 4095));
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));
|
||||
gpio_set_level(GPIO_CLK_OUT, 1);
|
||||
if (triggered) {
|
||||
gpio_set_level(GPIO_GATE_OUT, 1);
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1, 4095));
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1));
|
||||
}
|
||||
}
|
||||
|
||||
static void update_bpm(void) {
|
||||
lv_label_set_text_fmt(bpm_label, "BPM: %d", current_bpm);
|
||||
gptimer_alarm_config_t tempo_alarm_config = {
|
||||
.reload_count = 0,
|
||||
.flags.auto_reload_on_alarm = true,
|
||||
.alarm_count = bpm_to_ms(current_bpm) * 1000
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_set_alarm_action(tempo_timer, &tempo_alarm_config));
|
||||
}
|
||||
|
||||
/* updates the sequence for the GUI display */
|
||||
|
|
@ -159,6 +181,70 @@ static void tap_tempo_handler(){
|
|||
}
|
||||
}
|
||||
|
||||
/* Essentially the Main Loop. Runs the tempo timer to trigger beat related events */
|
||||
static void tempo_task(void *pvParameter) {
|
||||
/* Start the timer */
|
||||
ESP_ERROR_CHECK(gptimer_start(tempo_timer));
|
||||
uint32_t ulInterruptStatus;
|
||||
|
||||
/* Loop that waits for notification of beat end */
|
||||
while (1) {
|
||||
xTaskNotifyWait(0, ULONG_MAX, &ulInterruptStatus , portMAX_DELAY);
|
||||
|
||||
/* Pulse outputs if step is active */
|
||||
if (sequence[current_step] == 1) {
|
||||
pulse_cv(true);
|
||||
} else {
|
||||
pulse_cv(false);
|
||||
}
|
||||
|
||||
/* Construct a string for the sequence tracker display */
|
||||
char tracker_str[] = " ";
|
||||
tracker_str[current_step] = '_';
|
||||
|
||||
/* set the new sequence label */
|
||||
lv_label_set_text(sequence_tracker, tracker_str);
|
||||
|
||||
/* Advance the Step */
|
||||
if (current_step == seq_len - 1) {
|
||||
current_step = 0;
|
||||
} else {
|
||||
current_step++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handler that runs when the tempo timer goes off */
|
||||
static void tempo_timer_cb(void * arg) {
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
xTaskNotifyFromISR(tempo_handle , 0, eSetBits, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
/* Initialize tempo timer */
|
||||
static void tempo_init(void) {
|
||||
/* Setup timer */
|
||||
gptimer_config_t tempo_timer_config = {
|
||||
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
|
||||
.direction = GPTIMER_COUNT_UP,
|
||||
.resolution_hz = 1 * 1000 * 1000 /* 1MHz; 1 tick = 1µs */
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_new_timer(&tempo_timer_config, &tempo_timer));
|
||||
|
||||
/* Configure alarm to go off based on BPM */
|
||||
gptimer_alarm_config_t tempo_alarm_config = {
|
||||
.reload_count = 0,
|
||||
.flags.auto_reload_on_alarm = true,
|
||||
.alarm_count = bpm_to_ms(current_bpm) * 1000};
|
||||
ESP_ERROR_CHECK(gptimer_set_alarm_action(tempo_timer, &tempo_alarm_config));
|
||||
|
||||
/* Setup tempo callback */
|
||||
gptimer_event_callbacks_t cb_config = {
|
||||
.on_alarm = tempo_timer_cb
|
||||
};
|
||||
ESP_ERROR_CHECK(gptimer_register_event_callbacks(tempo_timer, &cb_config, NULL));
|
||||
ESP_ERROR_CHECK(gptimer_enable(tempo_timer));
|
||||
}
|
||||
|
||||
static void IRAM_ATTR gpio_isr_handler(void* arg) {
|
||||
uint32_t gpio_num = (uint32_t)arg;
|
||||
portENTER_CRITICAL_ISR(&mux);
|
||||
|
|
@ -466,18 +552,6 @@ static void gui_task(void *pvParameter) {
|
|||
}
|
||||
}
|
||||
|
||||
static void pulse_cv(bool triggered) {
|
||||
ESP_ERROR_CHECK(gptimer_start(gate_timer));
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 4095));
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));
|
||||
gpio_set_level(GPIO_CLK_OUT, 1);
|
||||
if (triggered) {
|
||||
gpio_set_level(GPIO_GATE_OUT, 1);
|
||||
ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1, 4095));
|
||||
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_1));
|
||||
}
|
||||
}
|
||||
|
||||
void app_main(void) {
|
||||
/* Initialize Peripherals */
|
||||
/* Initialize GPIO */
|
||||
|
|
@ -498,28 +572,9 @@ void app_main(void) {
|
|||
/* Initialize sequence */
|
||||
randomize_seq(sequence);
|
||||
|
||||
/* Main Loop */
|
||||
while (1) {
|
||||
char tracker_str[seq_len];
|
||||
for (uint8_t step = 0; step < seq_len; step++) {
|
||||
/* advance step tracker */
|
||||
if (step == 0) {
|
||||
tracker_str[seq_len - 1] = ' ';
|
||||
} else {
|
||||
tracker_str[step - 1] = ' ';
|
||||
}
|
||||
tracker_str[step] = '_';
|
||||
/* Initialize tempo timer */
|
||||
tempo_init();
|
||||
|
||||
/* set the new sequence label */
|
||||
lv_label_set_text(sequence_tracker, tracker_str);
|
||||
|
||||
/* if step has been set for sequence */
|
||||
if (sequence[step] == 1) {
|
||||
pulse_cv(true);
|
||||
} else {
|
||||
pulse_cv(false);
|
||||
}
|
||||
vTaskDelay(bpm_to_ms(current_bpm)/ portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
/* start main beat tempo loop task */
|
||||
xTaskCreate(tempo_task, "tempo", 2048, NULL, 0, &tempo_handle);
|
||||
}
|
||||
|
|
|
|||
Reference in New Issue