Files
2026-10-04 12:52:16 +03:00

186 lines
7.2 KiB
C

/**
* @file zh_ttp229.h
*
* @brief Driver for TTP229 capacitive touch pad controller via SPI-like
* interface (SCL/SDO) using ESP-IDF RMT peripheral.
*
* This module provides a FreeRTOS-based driver for the TTP229 touch
* controller. It uses the RMT transmitter to generate SCL clock pulses
* and the RMT receiver to capture SDO data, enabling reading of touch
* status from 8 or 16 pad configurations. A positive edge on SDO triggers
* an ISR that starts the RMT transfer; a dedicated FreeRTOS task then
* decodes the touched pad number and posts an event with it.
*
* Key features:
* - Supports 8-pad and 16-pad TTP229 configurations
* - RMT-based SPI-like communication (no GPIO bit-banging)
* - FreeRTOS task for decoding, debouncing and event dispatching
* - Per-device unique numbering for multi-device support
* - Error statistics tracking (RMT, queue, stack)
*/
#pragma once
#include "esp_log.h"
#include "esp_heap_caps.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/rmt_tx.h"
#include "driver/rmt_rx.h"
#include "driver/gpio.h"
#include "esp_event.h"
#include "zh_vector.h"
#define ZH_TTP229_INIT_CONFIG_DEFAULT() \
{ \
.task_priority = 1, \
.stack_size = configMINIMAL_STACK_SIZE, \
.queue_size = 5, \
.work_mode = ZH_TTP229_8_PAD, \
.rmt_tx_start_delay = 15, \
.debounce_time = 100, \
.device_number = 1, \
.scl_gpio = GPIO_NUM_MAX, \
.sdo_gpio = GPIO_NUM_MAX}
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Handle of the shared TTP229 event processing task.
*
* Created when the first device is initialized and set back to NULL
* when the last device is deinitialized or the first device
* initialization fails.
*/
extern TaskHandle_t zh_ttp229;
/**
* @brief Opaque handle returned by zh_ttp229_init().
*
* Internal fields are defined in zh_ttp229.c. Users must not access
* the handle's members directly.
*/
typedef struct _zh_ttp229_handle_t zh_ttp229_handle_t;
/**
* @brief TTP229 touch pad work mode (number of pads).
*
* Selects the number of capacitive touch pads configured on the
* TTP229 controller. The value determines how many SCL clock pulses
* are generated during a read cycle.
*/
typedef enum
{
ZH_TTP229_8_PAD = 8, /*!< 8-pad TTP229 configuration */
ZH_TTP229_16_PAD = 16, /*!< 16-pad TTP229 configuration */
} zh_ttp229_work_mode_t;
/**
* @brief Configuration structure for TTP229 initialization.
*
* Use ZH_TTP229_INIT_CONFIG_DEFAULT() to obtain sensible defaults
* and override only the fields that differ from defaults.
*
* @note Minimum values: stack_size >= configMINIMAL_STACK_SIZE, debounce_time >= 10 ms,
* task_priority >= 1, queue_size >= 1, rmt_tx_start_delay >= 15 us, device_number > 0.
*/
typedef struct
{
uint16_t stack_size; /*!< Task stack size in bytes */
uint16_t debounce_time; /*!< Button debounce time in milliseconds */
uint8_t task_priority; /*!< FreeRTOS task priority */
uint8_t queue_size; /*!< Event queue depth */
uint8_t device_number; /*!< Unique device identifier */
uint8_t rmt_tx_start_delay; /*!< RMT TX delay in microseconds after SDO interrupt */
gpio_num_t sdo_gpio; /*!< SDO (Serial Data Out) GPIO pin */
gpio_num_t scl_gpio; /*!< SCL (Serial Clock) GPIO pin */
zh_ttp229_work_mode_t work_mode; /*!< Touch pad configuration (8 or 16 pads) */
} zh_ttp229_init_config_t;
/**
* @brief Error and runtime statistics for the TTP229 driver.
*
* Retrieved via zh_ttp229_get_stats(). Reset with zh_ttp229_reset_stats().
*/
typedef struct
{
uint32_t rmt_driver_error; /*!< Count of RMT driver errors */
uint32_t event_post_error; /*!< Count of esp_event_post failures */
uint32_t queue_overflow_error; /*!< Count of event queue overflows */
uint32_t min_stack_size; /*!< Minimum free stack (bytes) observed */
} zh_ttp229_stats_t;
ESP_EVENT_DECLARE_BASE(ZH_TTP229);
/**
* @brief Event payload delivered on touch detection.
*
* Should be used with the ZH_TTP229 event base.
*/
typedef struct
{
uint8_t pad_number; /*!< Number of the pad that triggered the interrupt (1-based) */
uint8_t device_number; /*!< Unique device identifier matching the init config */
} zh_ttp229_event_on_isr_t;
/**
* @brief Initialize the TTP229 touch pad driver.
*
* Allocates a handle, validates the configuration, creates the shared
* queue and the processing task on the first device, initializes GPIO
* with the ISR handler, and creates the RMT TX/RX channels. Supports
* multiple devices via unique device numbers.
*
* @param[in] config Pointer to initialization configuration (must not be NULL)
* @param[out] handle Pointer to a handle location that must be NULL on input (must not be NULL)
*
* @return ESP_OK on success
* @return ESP_ERR_INVALID_ARG if config or handle is NULL, or if any configuration value is out of range
* @return ESP_ERR_INVALID_STATE if *handle is not NULL
* @return ESP_ERR_NO_MEM if handle allocation fails
* @return ESP_FAIL if creating the shared resources fails, or on GPIO or RMT initialization failure
*/
esp_err_t zh_ttp229_init(const zh_ttp229_init_config_t *config, zh_ttp229_handle_t **handle);
/**
* @brief Deinitialize a TTP229 touch pad instance.
*
* Removes the device from the internal device list, removes the GPIO
* ISR handler, disables and deletes the RMT channels and the encoder,
* resets the GPIO pins, and frees the handle. The processing task,
* the queue, and the device list are deleted only when the last
* device is deinitialized.
*
* @param[in,out] handle Pointer to unique touch pad handle (must not be NULL)
*
* @return ESP_OK on success
* @return ESP_ERR_INVALID_ARG if handle or *handle is NULL
* @return ESP_FAIL if the device is not found in the internal device list, or if deleting the device list entries or the shared resources fails
*/
esp_err_t zh_ttp229_deinit(zh_ttp229_handle_t **handle);
/**
* @brief Retrieve a pointer to the current error statistics.
*
* The returned pointer refers to a module static structure and
* remains valid for the lifetime of the application.
*
* @return Pointer to the static zh_ttp229_stats_t structure
*/
const zh_ttp229_stats_t *zh_ttp229_get_stats(void);
/**
* @brief Reset all error and runtime statistics to zero.
*
* Call this function to clear accumulated counters. The
* min_stack_size field is also cleared and will be updated on the
* next processing cycle.
*/
void zh_ttp229_reset_stats(void);
#ifdef __cplusplus
}
#endif