diff --git a/main/esp32-sequencer.c b/main/esp32-sequencer.c index fa4c0e6..ce2c35f 100644 --- a/main/esp32-sequencer.c +++ b/main/esp32-sequencer.c @@ -3,10 +3,13 @@ #include "driver/gpio.h" #include "driver/gptimer.h" +#include "esp_attr.h" #include "esp_err.h" #include "esp_random.h" +#include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include "freertos/queue.h" #include "driver/ledc.h" #include "hal/ledc_types.h" @@ -19,6 +22,11 @@ // Clock In // Reset In +/* Controls */ +#define GPIO_MUTATE_BTN (9) // Mutate Button In + +static QueueHandle_t control_event_queue = NULL; + /* Outputs */ #define GPIO_CLK_OUT (7) // Clock Out #define GPIO_GATE_OUT (8) // Gate CV Out @@ -33,6 +41,56 @@ gptimer_handle_t gate_cv_timer = NULL; gptimer_handle_t clk_blink_timer = NULL; gptimer_handle_t gate_blink_timer = NULL; +uint8_t sequence[SEQ_MAX_LEN] = {0}; +uint8_t seq_len = SEQ_MAX_LEN; + +static const char *TAG = "sequencer"; + +static void randomize_seq(uint8_t *sequence) { + for (uint8_t i = 0; i < SEQ_MAX_LEN; i++) { + sequence[i] = esp_random() % 2; + } +} + +static void mutate_seq(uint8_t *sequence) { + ESP_LOGI(TAG, "Mutating Sequence"); + // pick a step to mutate + uint8_t step = esp_random() % SEQ_MAX_LEN; + if (sequence[step] == 1) { + sequence[step] = 0; + } else if (sequence[step] == 0) { + sequence[step] = 1; + } +} + +static void IRAM_ATTR gpio_isr_handler(void* arg) { + uint32_t gpio_num = (uint32_t)arg; + xQueueSendFromISR(control_event_queue, &gpio_num, NULL); +} + +static void control_event_handler(void* arg) { + uint32_t gpio_num; + while (1) { + if(xQueueReceive(control_event_queue, &gpio_num, portMAX_DELAY)) { + ESP_LOGI(TAG, "Handling control from %" PRIu32 , gpio_num); + switch (gpio_num) { + case GPIO_MUTATE_BTN: + mutate_seq(sequence); + } + } + } +} + +static void controls_init(void) { + // install gpio isr hservice + gpio_install_isr_service(0); + // Setup Mutate Button + gpio_reset_pin(GPIO_MUTATE_BTN); + gpio_set_direction(GPIO_MUTATE_BTN, GPIO_MODE_INPUT); + gpio_set_intr_type(GPIO_MUTATE_BTN, GPIO_INTR_POSEDGE); + // Hook in handler for mutate button + gpio_isr_handler_add(GPIO_MUTATE_BTN, gpio_isr_handler, (void*)GPIO_MUTATE_BTN); +} static void clk_cv_off_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data) { gptimer_stop(clk_cv_timer); @@ -45,6 +103,8 @@ static void gate_cv_off_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_eve } static void gpio_init(void) { + // Setup gpio control event queue + control_event_queue = xQueueCreate(10, sizeof(uint32_t)); // Setup Clock CV Output gpio_reset_pin(GPIO_CLK_OUT); gpio_set_direction(GPIO_CLK_OUT, GPIO_MODE_OUTPUT); @@ -181,33 +241,21 @@ static void pulse_cv(uint8_t gpio_num) { } } -static void randomize_seq(uint8_t *sequence) { - for (uint8_t i = 0; i < SEQ_MAX_LEN; i++) { - sequence[i] = esp_random() % 2; - } -} - -static void mutate_seq(uint8_t *sequence) { - // pick a step to mutate - uint8_t step = esp_random() % SEQ_MAX_LEN; - if (sequence[step] == 1) { - sequence[step] = 0; - } else if (sequence[step] == 0) { - sequence[step] = 1; - } -} - void app_main(void) { /* Initialize Peripherals */ /* Initialize GPIO */ gpio_init(); + controls_init(); + // Start task to handle control events + xTaskCreate(control_event_handler, "control event handler", 2048, NULL, 10, NULL); + /* Initialize Monitor LEDs */ ledc_init(); + /* Initialize sequence */ - uint8_t sequence[SEQ_MAX_LEN] = {0}; - uint8_t seq_len = SEQ_MAX_LEN; randomize_seq(sequence); + /* Main Loop */ while (1) { for (uint8_t step = 0; step < seq_len; step++) { @@ -223,7 +271,6 @@ void app_main(void) { printf("%i", sequence[step]); vTaskDelay(500 / portTICK_PERIOD_MS); } - mutate_seq(sequence); printf("\n"); }