|
@@ -58,13 +58,13 @@ static struct {
|
|
|
|
|
|
static TimerHandle_t polled_timer;
|
|
|
|
|
|
-static EXT_RAM_ATTR struct {
|
|
|
+static EXT_RAM_ATTR struct encoder {
|
|
|
QueueHandle_t queue;
|
|
|
void *client;
|
|
|
rotary_encoder_info_t info;
|
|
|
int A, B, SW;
|
|
|
rotary_handler handler;
|
|
|
-} rotary;
|
|
|
+} rotary, volume;
|
|
|
|
|
|
static EXT_RAM_ATTR struct {
|
|
|
RingbufHandle_t rb;
|
|
@@ -227,11 +227,22 @@ static void buttons_task(void* arg) {
|
|
|
// received a rotary event
|
|
|
xQueueReceive(rotary.queue, &event, 0);
|
|
|
|
|
|
- ESP_LOGD(TAG, "Event: position %d, direction %s", event.state.position,
|
|
|
+ ESP_LOGD(TAG, "Rotary event: position %d, direction %s", event.state.position,
|
|
|
event.state.direction ? (event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ? "CW" : "CCW") : "NOT_SET");
|
|
|
|
|
|
rotary.handler(rotary.client, event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ?
|
|
|
ROTARY_RIGHT : ROTARY_LEFT, false);
|
|
|
+ } else if (xActivatedMember == volume.queue) {
|
|
|
+ rotary_encoder_event_t event = { 0 };
|
|
|
+
|
|
|
+ // received a volume rotary event
|
|
|
+ xQueueReceive(volume.queue, &event, 0);
|
|
|
+
|
|
|
+ ESP_LOGD(TAG, "Volume event: position %d, direction %s", event.state.position,
|
|
|
+ event.state.direction ? (event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ? "CW" : "CCW") : "NOT_SET");
|
|
|
+
|
|
|
+ volume.handler(volume.client, event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ?
|
|
|
+ ROTARY_RIGHT : ROTARY_LEFT, false);
|
|
|
} else {
|
|
|
// this is IR
|
|
|
active = infrared_receive(infrared.rb, infrared.handler);
|
|
@@ -394,46 +405,68 @@ void *button_remap(void *client, int gpio, button_handler handler, int long_pres
|
|
|
return prev_client;
|
|
|
}
|
|
|
|
|
|
-/****************************************************************************************
|
|
|
- * Rotary encoder handler
|
|
|
- */
|
|
|
-static void rotary_button_handler(void *id, button_event_e event, button_press_e mode, bool long_press) {
|
|
|
- ESP_LOGI(TAG, "Rotary push-button %d", event);
|
|
|
- rotary.handler(id, event == BUTTON_PRESSED ? ROTARY_PRESSED : ROTARY_RELEASED, long_press);
|
|
|
-}
|
|
|
-
|
|
|
/****************************************************************************************
|
|
|
* Create rotary encoder
|
|
|
*/
|
|
|
-bool create_rotary(void *id, int A, int B, int SW, int long_press, rotary_handler handler) {
|
|
|
+static bool create_rotary_encoder(struct encoder *encoder, void *id, int A, int B, int SW, int long_press, rotary_handler handler, button_handler button) {
|
|
|
// nasty ESP32 bug: fire-up constantly INT on GPIO 36/39 if ADC1, AMP, Hall used which WiFi does when PS is activated
|
|
|
if (A == -1 || B == -1 || A == 36 || A == 39 || B == 36 || B == 39) {
|
|
|
ESP_LOGI(TAG, "Cannot create rotary %d %d", A, B);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- rotary.A = A;
|
|
|
- rotary.B = B;
|
|
|
- rotary.SW = SW;
|
|
|
- rotary.client = id;
|
|
|
- rotary.handler = handler;
|
|
|
+ encoder->A = A;
|
|
|
+ encoder->B = B;
|
|
|
+ encoder->SW = SW;
|
|
|
+ encoder->client = id;
|
|
|
+ encoder->handler = handler;
|
|
|
|
|
|
// Initialise the rotary encoder device with the GPIOs for A and B signals
|
|
|
- rotary_encoder_init(&rotary.info, A, B);
|
|
|
+ rotary_encoder_init(&encoder->info, A, B);
|
|
|
|
|
|
// Create a queue for events from the rotary encoder driver.
|
|
|
- rotary.queue = rotary_encoder_create_queue();
|
|
|
- rotary_encoder_set_queue(&rotary.info, rotary.queue);
|
|
|
+ encoder->queue = rotary_encoder_create_queue();
|
|
|
+ rotary_encoder_set_queue(&encoder->info, encoder->queue);
|
|
|
|
|
|
common_task_init();
|
|
|
- xQueueAddToSet( rotary.queue, common_queue_set );
|
|
|
+ xQueueAddToSet( encoder->queue, common_queue_set );
|
|
|
|
|
|
// create companion button if rotary has a switch
|
|
|
- if (SW != -1) button_create(id, SW, BUTTON_LOW, true, 0, rotary_button_handler, long_press, -1);
|
|
|
-
|
|
|
- ESP_LOGI(TAG, "Created rotary encoder A:%d B:%d, SW:%d", A, B, SW);
|
|
|
+ if (SW != -1) button_create(id, SW, BUTTON_LOW, true, 0, button, long_press, -1);
|
|
|
|
|
|
return true;
|
|
|
+}
|
|
|
+
|
|
|
+/****************************************************************************************
|
|
|
+ * Volume button encoder handler
|
|
|
+ */
|
|
|
+static void volume_button_handler(void *id, button_event_e event, button_press_e mode, bool long_press) {
|
|
|
+ ESP_LOGI(TAG, "Volume encoder push-button %d", event);
|
|
|
+ volume.handler(id, event == BUTTON_PRESSED ? ROTARY_PRESSED : ROTARY_RELEASED, long_press);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************************************************************************
|
|
|
+ * Create volume encoder
|
|
|
+ */
|
|
|
+bool create_volume_rotary(void *id, int A, int B, int SW, rotary_handler handler) {
|
|
|
+ ESP_LOGI(TAG, "Created volume encoder A:%d B:%d, SW:%d", A, B, SW);
|
|
|
+ return create_rotary_encoder(&volume, id, A, B, SW, false, handler, volume_button_handler);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************************************************************************
|
|
|
+ * Rotary button encoder handler
|
|
|
+ */
|
|
|
+static void rotary_button_handler(void *id, button_event_e event, button_press_e mode, bool long_press) {
|
|
|
+ ESP_LOGI(TAG, "Rotary push-button %d", event);
|
|
|
+ rotary.handler(id, event == BUTTON_PRESSED ? ROTARY_PRESSED : ROTARY_RELEASED, long_press);
|
|
|
+}
|
|
|
+
|
|
|
+/****************************************************************************************
|
|
|
+ * Create rotary encoder
|
|
|
+ */
|
|
|
+bool create_rotary(void *id, int A, int B, int SW, int long_press, rotary_handler handler) {
|
|
|
+ ESP_LOGI(TAG, "Created rotary encoder A:%d B:%d, SW:%d", A, B, SW);
|
|
|
+ return create_rotary_encoder(&rotary, id, A, B, SW, long_press, handler, rotary_button_handler);
|
|
|
}
|
|
|
|
|
|
/****************************************************************************************
|