wip:
This commit is contained in:
@@ -23,6 +23,33 @@ extern "C"
|
|||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef int32_t rotary_encoder_position_t;
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @brief Enum representing the direction of rotation.
|
||||||
|
// */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ROTARY_ENCODER_DIRECTION_NOT_SET = 0, ///< Direction not yet known (stationary since reset)
|
||||||
|
ROTARY_ENCODER_DIRECTION_CLOCKWISE,
|
||||||
|
ROTARY_ENCODER_DIRECTION_COUNTER_CLOCKWISE,
|
||||||
|
} rotary_encoder_direction_t;
|
||||||
|
|
||||||
|
// // Used internally
|
||||||
|
// ///@cond INTERNAL
|
||||||
|
#define TABLE_COLS 4
|
||||||
|
typedef uint8_t table_row_t[TABLE_COLS];
|
||||||
|
// ///@endcond
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @brief Struct represents the current state of the device in terms of incremental position and direction of last movement
|
||||||
|
// */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
rotary_encoder_position_t position; ///< Numerical position since reset. This value increments on clockwise rotation, and decrements on counter-clockewise rotation. Counts full or half steps depending on mode. Set to zero on reset.
|
||||||
|
rotary_encoder_direction_t direction; ///< Direction of last movement. Set to NOT_SET on reset.
|
||||||
|
} rotary_encoder_state_t;
|
||||||
|
|
||||||
typedef struct // Structure for initial initialization of encoder.
|
typedef struct // Structure for initial initialization of encoder.
|
||||||
{
|
{
|
||||||
uint8_t task_priority; // Task priority for the encoder isr processing. @note It is not recommended to set a value less than 10.
|
uint8_t task_priority; // Task priority for the encoder isr processing. @note It is not recommended to set a value less than 10.
|
||||||
@@ -47,6 +74,9 @@ extern "C"
|
|||||||
uint8_t encoder_number; // Encoder unique number.
|
uint8_t encoder_number; // Encoder unique number.
|
||||||
bool is_initialized; // Encoder initialization flag.
|
bool is_initialized; // Encoder initialization flag.
|
||||||
|
|
||||||
|
const table_row_t *table; ///< Pointer to active state transition table
|
||||||
|
uint8_t table_state; ///< Internal state
|
||||||
|
volatile rotary_encoder_state_t state; ///< Device state
|
||||||
} zh_encoder_handle_t;
|
} zh_encoder_handle_t;
|
||||||
|
|
||||||
ESP_EVENT_DECLARE_BASE(ZH_ENCODER);
|
ESP_EVENT_DECLARE_BASE(ZH_ENCODER);
|
||||||
@@ -115,9 +145,9 @@ extern "C"
|
|||||||
|
|
||||||
// typedef int32_t rotary_encoder_position_t;
|
// typedef int32_t rotary_encoder_position_t;
|
||||||
|
|
||||||
// /**
|
// // /**
|
||||||
// * @brief Enum representing the direction of rotation.
|
// // * @brief Enum representing the direction of rotation.
|
||||||
// */
|
// // */
|
||||||
// typedef enum
|
// typedef enum
|
||||||
// {
|
// {
|
||||||
// ROTARY_ENCODER_DIRECTION_NOT_SET = 0, ///< Direction not yet known (stationary since reset)
|
// ROTARY_ENCODER_DIRECTION_NOT_SET = 0, ///< Direction not yet known (stationary since reset)
|
||||||
@@ -125,15 +155,15 @@ extern "C"
|
|||||||
// ROTARY_ENCODER_DIRECTION_COUNTER_CLOCKWISE,
|
// ROTARY_ENCODER_DIRECTION_COUNTER_CLOCKWISE,
|
||||||
// } rotary_encoder_direction_t;
|
// } rotary_encoder_direction_t;
|
||||||
|
|
||||||
// // Used internally
|
// // // Used internally
|
||||||
// ///@cond INTERNAL
|
// // ///@cond INTERNAL
|
||||||
// #define TABLE_COLS 4
|
// #define TABLE_COLS 4
|
||||||
// typedef uint8_t table_row_t[TABLE_COLS];
|
// typedef uint8_t table_row_t[TABLE_COLS];
|
||||||
// ///@endcond
|
// // ///@endcond
|
||||||
|
|
||||||
// /**
|
// // /**
|
||||||
// * @brief Struct represents the current state of the device in terms of incremental position and direction of last movement
|
// // * @brief Struct represents the current state of the device in terms of incremental position and direction of last movement
|
||||||
// */
|
// // */
|
||||||
// typedef struct
|
// typedef struct
|
||||||
// {
|
// {
|
||||||
// rotary_encoder_position_t position; ///< Numerical position since reset. This value increments on clockwise rotation, and decrements on counter-clockewise rotation. Counts full or half steps depending on mode. Set to zero on reset.
|
// rotary_encoder_position_t position; ///< Numerical position since reset. This value increments on clockwise rotation, and decrements on counter-clockewise rotation. Counts full or half steps depending on mode. Set to zero on reset.
|
||||||
|
|||||||
129
zh_encoder.c
129
zh_encoder.c
@@ -104,9 +104,15 @@ esp_err_t zh_encoder_init(const zh_encoder_init_config_t *config, zh_encoder_han
|
|||||||
{
|
{
|
||||||
_zh_encoder_validate_config(config);
|
_zh_encoder_validate_config(config);
|
||||||
_zh_encoder_gpio_init(config);
|
_zh_encoder_gpio_init(config);
|
||||||
|
handle->a_gpio_number = config->a_gpio_number;
|
||||||
|
handle->b_gpio_number = config->b_gpio_number;
|
||||||
_zh_encoder_configure_interrupts(config, handle);
|
_zh_encoder_configure_interrupts(config, handle);
|
||||||
_zh_encoder_init_resources(config);
|
_zh_encoder_init_resources(config);
|
||||||
_zh_encoder_create_task(config);
|
_zh_encoder_create_task(config);
|
||||||
|
handle->table = &_encoder_matrix[0]; // enable_half_step ? &_ttable_half[0] : &_ttable_full[0];
|
||||||
|
handle->table_state = R_START;
|
||||||
|
handle->state.position = 0;
|
||||||
|
handle->state.direction = ROTARY_ENCODER_DIRECTION_NOT_SET;
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,6 +371,8 @@ static esp_err_t _zh_encoder_configure_interrupts(const zh_encoder_init_config_t
|
|||||||
ZH_ENCODER_CHECK(err == ESP_OK, err, "Interrupt initialization failed.");
|
ZH_ENCODER_CHECK(err == ESP_OK, err, "Interrupt initialization failed.");
|
||||||
err = gpio_isr_handler_add(config->b_gpio_number, _zh_encoder_isr_handler, handle);
|
err = gpio_isr_handler_add(config->b_gpio_number, _zh_encoder_isr_handler, handle);
|
||||||
ZH_ENCODER_CHECK(err == ESP_OK, err, "Interrupt initialization failed.");
|
ZH_ENCODER_CHECK(err == ESP_OK, err, "Interrupt initialization failed.");
|
||||||
|
// printf("queue.b_gpio_number %d\n", handle->b_gpio_number);
|
||||||
|
// printf("queue.q_gpio_number %d\n", handle->a_gpio_number);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,8 +405,36 @@ static esp_err_t _zh_encoder_create_task(const zh_encoder_init_config_t *config)
|
|||||||
|
|
||||||
static void _zh_encoder_isr_handler(void *arg)
|
static void _zh_encoder_isr_handler(void *arg)
|
||||||
{
|
{
|
||||||
|
zh_encoder_handle_t *queue = (zh_encoder_handle_t *)arg;
|
||||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
xQueueSendFromISR(_queue_handle, arg, &xHigherPriorityTaskWoken);
|
uint8_t pin_state = (gpio_get_level(queue->b_gpio_number) << 1) | gpio_get_level(queue->a_gpio_number);
|
||||||
|
// printf("pin_state %d\n", pin_state);
|
||||||
|
queue->table_state = queue->table[queue->table_state & 0xf][pin_state];
|
||||||
|
uint8_t event = queue->table_state & 0x30;
|
||||||
|
switch (event)
|
||||||
|
{
|
||||||
|
case DIR_CW:
|
||||||
|
++queue->state.position;
|
||||||
|
queue->state.direction = ROTARY_ENCODER_DIRECTION_CLOCKWISE;
|
||||||
|
// printf("event %d\n", event);
|
||||||
|
// send_event = true;
|
||||||
|
// printf("state.position %ld\n", queue->state.position);
|
||||||
|
xQueueSendFromISR(_queue_handle, queue, &xHigherPriorityTaskWoken);
|
||||||
|
break;
|
||||||
|
case DIR_CCW:
|
||||||
|
--queue->state.position;
|
||||||
|
queue->state.direction = ROTARY_ENCODER_DIRECTION_COUNTER_CLOCKWISE;
|
||||||
|
// printf("event %d\n", event);
|
||||||
|
// send_event = true;
|
||||||
|
// printf("state.position %ld\n", queue.state.position);
|
||||||
|
xQueueSendFromISR(_queue_handle, queue, &xHigherPriorityTaskWoken);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
|
// xQueueSendFromISR(_queue_handle, queue, &xHigherPriorityTaskWoken);
|
||||||
if (xHigherPriorityTaskWoken == pdTRUE)
|
if (xHigherPriorityTaskWoken == pdTRUE)
|
||||||
{
|
{
|
||||||
portYIELD_FROM_ISR();
|
portYIELD_FROM_ISR();
|
||||||
@@ -407,4 +443,95 @@ static void _zh_encoder_isr_handler(void *arg)
|
|||||||
|
|
||||||
static void _zh_encoder_isr_processing_task(void *pvParameter)
|
static void _zh_encoder_isr_processing_task(void *pvParameter)
|
||||||
{
|
{
|
||||||
|
zh_encoder_handle_t queue = {0};
|
||||||
|
while (xQueueReceive(_queue_handle, &queue, portMAX_DELAY) == pdTRUE)
|
||||||
|
{
|
||||||
|
// printf("queue.b_gpio_number %d\n", queue.b_gpio_number);
|
||||||
|
// printf("queue.q_gpio_number %d\n", queue.a_gpio_number);
|
||||||
|
// uint8_t pin_state = (gpio_get_level(queue.b_gpio_number) << 1) | gpio_get_level(queue.a_gpio_number);
|
||||||
|
// // printf("pin_state %d\n", pin_state);
|
||||||
|
// queue.table_state = queue.table[queue.table_state & 0xf][pin_state];
|
||||||
|
// uint8_t event = queue.table_state & 0x30;
|
||||||
|
// switch (event)
|
||||||
|
// {
|
||||||
|
// case DIR_CW:
|
||||||
|
// ++queue.state.position;
|
||||||
|
// queue.state.direction = ROTARY_ENCODER_DIRECTION_CLOCKWISE;
|
||||||
|
// printf("event %d\n", event);
|
||||||
|
// // send_event = true;
|
||||||
|
// printf("state.position %ld\n", queue.state.position);
|
||||||
|
// break;
|
||||||
|
// case DIR_CCW:
|
||||||
|
// --queue.state.position;
|
||||||
|
// queue.state.direction = ROTARY_ENCODER_DIRECTION_COUNTER_CLOCKWISE;
|
||||||
|
// printf("event %d\n", event);
|
||||||
|
// // send_event = true;
|
||||||
|
// printf("state.position %ld\n", queue.state.position);
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
printf("state.position %ld\n", queue.state.position);
|
||||||
|
}
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
|
||||||
|
// rotary_encoder_info_t *info = (rotary_encoder_info_t *)args;
|
||||||
|
|
||||||
|
// uint8_t event = 0;
|
||||||
|
// if (info != NULL)
|
||||||
|
// {
|
||||||
|
// // Get state of input pins.
|
||||||
|
// uint8_t pin_state = (gpio_get_level(info->pin_b) << 1) | gpio_get_level(info->pin_a);
|
||||||
|
|
||||||
|
// // Determine new state from the pins and state table.
|
||||||
|
// #ifdef ROTARY_ENCODER_DEBUG
|
||||||
|
// uint8_t old_state = info->table_state;
|
||||||
|
// #endif
|
||||||
|
// queue.table_state = queue.table[queue.table_state & 0xf][pin_state];
|
||||||
|
|
||||||
|
// // Return emit bits, i.e. the generated event.
|
||||||
|
// event = queue.table_state & 0x30;
|
||||||
|
// #ifdef ROTARY_ENCODER_DEBUG
|
||||||
|
// ESP_EARLY_LOGD(TAG, "BA %d%d, state 0x%02x, new state 0x%02x, event 0x%02x",
|
||||||
|
// pin_state >> 1, pin_state & 1, old_state, info->table_state, event);
|
||||||
|
// #endif
|
||||||
|
// }
|
||||||
|
// return event;
|
||||||
|
|
||||||
|
// uint8_t event = _process(info);
|
||||||
|
// bool send_event = false;
|
||||||
|
|
||||||
|
// switch (event)
|
||||||
|
// {
|
||||||
|
// case DIR_CW:
|
||||||
|
// ++info->state.position;
|
||||||
|
// info->state.direction = ROTARY_ENCODER_DIRECTION_CLOCKWISE;
|
||||||
|
// // send_event = true;
|
||||||
|
// break;
|
||||||
|
// case DIR_CCW:
|
||||||
|
// --info->state.position;
|
||||||
|
// info->state.direction = ROTARY_ENCODER_DIRECTION_COUNTER_CLOCKWISE;
|
||||||
|
// send_event = true;
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (send_event && info->queue)
|
||||||
|
// {
|
||||||
|
// rotary_encoder_event_t queue_event =
|
||||||
|
// {
|
||||||
|
// .state =
|
||||||
|
// {
|
||||||
|
// .position = info->state.position,
|
||||||
|
// .direction = info->state.direction,
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
// BaseType_t task_woken = pdFALSE;
|
||||||
|
// xQueueSendFromISR(info->queue, &queue_event, &task_woken);
|
||||||
|
// if (task_woken)
|
||||||
|
// {
|
||||||
|
// portYIELD_FROM_ISR();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user