add IR and "raw" button mode - release

This commit is contained in:
Philippe G
2020-05-09 18:07:26 -07:00
parent be00683b66
commit 5b6ddf0b02
15 changed files with 662 additions and 163 deletions

View File

@@ -20,6 +20,7 @@
#include "esp_log.h"
#include "esp_task.h"
#include "driver/gpio.h"
#include "driver/rmt.h"
#include "buttons.h"
#include "rotary_encoder.h"
#include "globdefs.h"
@@ -56,11 +57,29 @@ static struct {
rotary_handler handler;
} rotary;
static struct {
RingbufHandle_t rb;
infrared_handler handler;
} infrared;
static xQueueHandle button_evt_queue;
static QueueSetHandle_t button_queue_set;
static QueueSetHandle_t common_queue_set;
static void buttons_task(void* arg);
/****************************************************************************************
* Start task needed by button,s rotaty and infrared
*/
static void common_task_init(void) {
static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
static EXT_RAM_ATTR StackType_t xStack[BUTTON_STACK_SIZE] __attribute__ ((aligned (4)));
if (!common_queue_set) {
common_queue_set = xQueueCreateSet(BUTTON_QUEUE_LEN + 1);
xTaskCreateStatic( (TaskFunction_t) buttons_task, "buttons_thread", BUTTON_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer);
}
}
/****************************************************************************************
* GPIO low-level handler
*/
@@ -107,8 +126,8 @@ static void buttons_task(void* arg) {
while (1) {
QueueSetMemberHandle_t xActivatedMember;
// wait on button and rotary queues
if ((xActivatedMember = xQueueSelectFromSet( button_queue_set, portMAX_DELAY )) == NULL) continue;
// wait on button, rotary and infrared queues
if ((xActivatedMember = xQueueSelectFromSet( common_queue_set, portMAX_DELAY )) == NULL) continue;
if (xActivatedMember == button_evt_queue) {
struct button_s button;
@@ -150,7 +169,7 @@ static void buttons_task(void* arg) {
// button is a copy, so need to go to real context
button.self->shifting = false;
}
} else {
} else if (xActivatedMember == rotary.queue) {
rotary_encoder_event_t event = { 0 };
// received a rotary event
@@ -161,6 +180,9 @@ static void buttons_task(void* arg) {
rotary.handler(rotary.client, event.state.direction == ROTARY_ENCODER_DIRECTION_CLOCKWISE ?
ROTARY_RIGHT : ROTARY_LEFT, false);
} else {
// this is IR
infrared_receive(infrared.rb, infrared.handler);
}
}
}
@@ -176,18 +198,14 @@ void dummy_handler(void *id, button_event_e event, button_press_e press) {
* Create buttons
*/
void button_create(void *client, int gpio, int type, bool pull, int debounce, button_handler handler, int long_press, int shifter_gpio) {
static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
static EXT_RAM_ATTR StackType_t xStack[BUTTON_STACK_SIZE] __attribute__ ((aligned (4)));
if (n_buttons >= MAX_BUTTONS) return;
ESP_LOGI(TAG, "Creating button using GPIO %u, type %u, pull-up/down %u, long press %u shifter %d", gpio, type, pull, long_press, shifter_gpio);
if (!n_buttons) {
button_evt_queue = xQueueCreate(BUTTON_QUEUE_LEN, sizeof(struct button_s));
if (!button_queue_set) button_queue_set = xQueueCreateSet(BUTTON_QUEUE_LEN + 1);
xQueueAddToSet( button_evt_queue, button_queue_set );
xTaskCreateStatic( (TaskFunction_t) buttons_task, "buttons_thread", BUTTON_STACK_SIZE, NULL, ESP_TASK_PRIO_MIN + 1, xStack, &xTaskBuffer);
common_task_init();
xQueueAddToSet( button_evt_queue, common_queue_set );
}
// just in case this structure is allocated in a future release
@@ -340,8 +358,8 @@ bool create_rotary(void *id, int A, int B, int SW, int long_press, rotary_handle
rotary.queue = rotary_encoder_create_queue();
rotary_encoder_set_queue(&rotary.info, rotary.queue);
if (!button_queue_set) button_queue_set = xQueueCreateSet(BUTTON_QUEUE_LEN + 1);
xQueueAddToSet( rotary.queue, button_queue_set );
common_task_init();
xQueueAddToSet( rotary.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);
@@ -350,3 +368,18 @@ bool create_rotary(void *id, int A, int B, int SW, int long_press, rotary_handle
return true;
}
/****************************************************************************************
* Create Infrared
*/
bool create_infrared(int gpio, infrared_handler handler) {
// initialize IR infrastructure
infrared_init(&infrared.rb, gpio);
infrared.handler = handler;
// join the queue set
common_task_init();
xRingbufferAddToQueueSetRead(infrared.rb, common_queue_set);
return (infrared.rb != NULL);
}