driver: pack peripherals

This commit is contained in:
laokaiyao
2023-01-31 14:36:21 +08:00
parent b97a98a703
commit f27cd67c00
116 changed files with 262 additions and 174 deletions
@@ -0,0 +1,83 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "driver/rmt_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief RMT carrier wave configuration (for either modulation or demodulation)
*/
typedef struct {
uint32_t frequency_hz; /*!< Carrier wave frequency, in Hz, 0 means disabling the carrier */
float duty_cycle; /*!< Carrier wave duty cycle (0~100%) */
struct {
uint32_t polarity_active_low: 1; /*!< Specify the polarity of carrier, by default it's modulated to base signal's high level */
uint32_t always_on: 1; /*!< If set, the carrier can always exist even there's not transfer undergoing */
} flags; /*!< Carrier config flags */
} rmt_carrier_config_t;
/**
* @brief Delete an RMT channel
*
* @param[in] channel RMT generic channel that created by `rmt_new_tx_channel()` or `rmt_new_rx_channel()`
* @return
* - ESP_OK: Delete RMT channel successfully
* - ESP_ERR_INVALID_ARG: Delete RMT channel failed because of invalid argument
* - ESP_ERR_INVALID_STATE: Delete RMT channel failed because it is still in working
* - ESP_FAIL: Delete RMT channel failed because of other error
*/
esp_err_t rmt_del_channel(rmt_channel_handle_t channel);
/**
* @brief Apply modulation feature for TX channel or demodulation feature for RX channel
*
* @param[in] channel RMT generic channel that created by `rmt_new_tx_channel()` or `rmt_new_rx_channel()`
* @param[in] config Carrier configuration. Specially, a NULL config means to disable the carrier modulation or demodulation feature
* @return
* - ESP_OK: Apply carrier configuration successfully
* - ESP_ERR_INVALID_ARG: Apply carrier configuration failed because of invalid argument
* - ESP_FAIL: Apply carrier configuration failed because of other error
*/
esp_err_t rmt_apply_carrier(rmt_channel_handle_t channel, const rmt_carrier_config_t *config);
/**
* @brief Enable the RMT channel
*
* @note This function will acquire a PM lock that might be installed during channel allocation
*
* @param[in] channel RMT generic channel that created by `rmt_new_tx_channel()` or `rmt_new_rx_channel()`
* @return
* - ESP_OK: Enable RMT channel successfully
* - ESP_ERR_INVALID_ARG: Enable RMT channel failed because of invalid argument
* - ESP_ERR_INVALID_STATE: Enable RMT channel failed because it's enabled already
* - ESP_FAIL: Enable RMT channel failed because of other error
*/
esp_err_t rmt_enable(rmt_channel_handle_t channel);
/**
* @brief Disable the RMT channel
*
* @note This function will release a PM lock that might be installed during channel allocation
*
* @param[in] channel RMT generic channel that created by `rmt_new_tx_channel()` or `rmt_new_rx_channel()`
* @return
* - ESP_OK: Disable RMT channel successfully
* - ESP_ERR_INVALID_ARG: Disable RMT channel failed because of invalid argument
* - ESP_ERR_INVALID_STATE: Disable RMT channel failed because it's not enabled yet
* - ESP_FAIL: Disable RMT channel failed because of other error
*/
esp_err_t rmt_disable(rmt_channel_handle_t channel);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,137 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "esp_err.h"
#include "hal/rmt_types.h"
#include "driver/rmt_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/** @cond */
typedef struct rmt_encoder_t rmt_encoder_t;
/** @endcond */
/**
* @brief RMT encoding state
*/
typedef enum {
RMT_ENCODING_COMPLETE = (1 << 0), /*!< The encoding session is finished, the caller can continue with subsequent encoding */
RMT_ENCODING_MEM_FULL = (1 << 1), /*!< The encoding artifact memory is full, the caller should return from current encoding session */
} rmt_encode_state_t;
/**
* @brief Interface of RMT encoder
*/
struct rmt_encoder_t {
/**
* @brief Encode the user data into RMT symbols and write into RMT memory
*
* @note The encoding function will also be called from an ISR context, thus the function must not call any blocking API.
* @note It's recommended to put this function implementation in the IRAM, to achieve a high performance and less interrupt latency.
*
* @param[in] encoder Encoder handle
* @param[in] tx_channel RMT TX channel handle, returned from `rmt_new_tx_channel()`
* @param[in] primary_data App data to be encoded into RMT symbols
* @param[in] data_size Size of primary_data, in bytes
* @param[out] ret_state Returned current encoder's state
* @return Number of RMT symbols that the primary data has been encoded into
*/
size_t (*encode)(rmt_encoder_t *encoder, rmt_channel_handle_t tx_channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state);
/**
* @brief Reset encoding state
*
* @param[in] encoder Encoder handle
* @return
* - ESP_OK: reset encoder successfully
* - ESP_FAIL: reset encoder failed
*/
esp_err_t (*reset)(rmt_encoder_t *encoder);
/**
* @brief Delete encoder object
*
* @param[in] encoder Encoder handle
* @return
* - ESP_OK: delete encoder successfully
* - ESP_FAIL: delete encoder failed
*/
esp_err_t (*del)(rmt_encoder_t *encoder);
};
/**
* @brief Bytes encoder configuration
*/
typedef struct {
rmt_symbol_word_t bit0; /*!< How to represent BIT0 in RMT symbol */
rmt_symbol_word_t bit1; /*!< How to represent BIT1 in RMT symbol */
struct {
uint32_t msb_first: 1; /*!< Whether to encode MSB bit first */
} flags; /*!< Encoder config flag */
} rmt_bytes_encoder_config_t;
/**
* @brief Copy encoder configuration
*/
typedef struct {
} rmt_copy_encoder_config_t;
/**
* @brief Create RMT bytes encoder, which can encode byte stream into RMT symbols
*
* @param[in] config Bytes encoder configuration
* @param[out] ret_encoder Returned encoder handle
* @return
* - ESP_OK: Create RMT bytes encoder successfully
* - ESP_ERR_INVALID_ARG: Create RMT bytes encoder failed because of invalid argument
* - ESP_ERR_NO_MEM: Create RMT bytes encoder failed because out of memory
* - ESP_FAIL: Create RMT bytes encoder failed because of other error
*/
esp_err_t rmt_new_bytes_encoder(const rmt_bytes_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder);
/**
* @brief Create RMT copy encoder, which copies the given RMT symbols into RMT memory
*
* @param[in] config Copy encoder configuration
* @param[out] ret_encoder Returned encoder handle
* @return
* - ESP_OK: Create RMT copy encoder successfully
* - ESP_ERR_INVALID_ARG: Create RMT copy encoder failed because of invalid argument
* - ESP_ERR_NO_MEM: Create RMT copy encoder failed because out of memory
* - ESP_FAIL: Create RMT copy encoder failed because of other error
*/
esp_err_t rmt_new_copy_encoder(const rmt_copy_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder);
/**
* @brief Delete RMT encoder
*
* @param[in] encoder RMT encoder handle, created by e.g `rmt_new_bytes_encoder()`
* @return
* - ESP_OK: Delete RMT encoder successfully
* - ESP_ERR_INVALID_ARG: Delete RMT encoder failed because of invalid argument
* - ESP_FAIL: Delete RMT encoder failed because of other error
*/
esp_err_t rmt_del_encoder(rmt_encoder_handle_t encoder);
/**
* @brief Reset RMT encoder
*
* @param[in] encoder RMT encoder handle, created by e.g `rmt_new_bytes_encoder()`
* @return
* - ESP_OK: Reset RMT encoder successfully
* - ESP_ERR_INVALID_ARG: Reset RMT encoder failed because of invalid argument
* - ESP_FAIL: Reset RMT encoder failed because of other error
*/
esp_err_t rmt_encoder_reset(rmt_encoder_handle_t encoder);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,103 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_err.h"
#include "driver/rmt_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Group of RMT RX callbacks
* @note The callbacks are all running under ISR environment
* @note When CONFIG_RMT_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
* The variables used in the function should be in the SRAM as well.
*/
typedef struct {
rmt_rx_done_callback_t on_recv_done; /*!< Event callback, invoked when one RMT channel receiving transaction completes */
} rmt_rx_event_callbacks_t;
/**
* @brief RMT RX channel specific configuration
*/
typedef struct {
int gpio_num; /*!< GPIO number used by RMT RX channel. Set to -1 if unused */
rmt_clock_source_t clk_src; /*!< Clock source of RMT RX channel, channels in the same group must use the same clock source */
uint32_t resolution_hz; /*!< Channel clock resolution, in Hz */
size_t mem_block_symbols; /*!< Size of memory block, in number of `rmt_symbol_word_t`, must be an even */
struct {
uint32_t invert_in: 1; /*!< Whether to invert the incoming RMT channel signal */
uint32_t with_dma: 1; /*!< If set, the driver will allocate an RMT channel with DMA capability */
uint32_t io_loop_back: 1; /*!< For debug/test, the signal output from the GPIO will be fed to the input path as well */
} flags; /*!< RX channel config flags */
} rmt_rx_channel_config_t;
/**
* @brief RMT receive specific configuration
*/
typedef struct {
uint32_t signal_range_min_ns; /*!< A pulse whose width is smaller than this threshold will be treated as glitch and ignored */
uint32_t signal_range_max_ns; /*!< RMT will stop receiving if one symbol level has kept more than `signal_range_max_ns` */
} rmt_receive_config_t;
/**
* @brief Create a RMT RX channel
*
* @param[in] config RX channel configurations
* @param[out] ret_chan Returned generic RMT channel handle
* @return
* - ESP_OK: Create RMT RX channel successfully
* - ESP_ERR_INVALID_ARG: Create RMT RX channel failed because of invalid argument
* - ESP_ERR_NO_MEM: Create RMT RX channel failed because out of memory
* - ESP_ERR_NOT_FOUND: Create RMT RX channel failed because all RMT channels are used up and no more free one
* - ESP_ERR_NOT_SUPPORTED: Create RMT RX channel failed because some feature is not supported by hardware, e.g. DMA feature is not supported by hardware
* - ESP_FAIL: Create RMT RX channel failed because of other error
*/
esp_err_t rmt_new_rx_channel(const rmt_rx_channel_config_t *config, rmt_channel_handle_t *ret_chan);
/**
* @brief Initiate a receive job for RMT RX channel
*
* @note This function is non-blocking, it initiates a new receive job and then returns.
* User should check the received data from the `on_recv_done` callback that registered by `rmt_rx_register_event_callbacks()`.
*
* @param[in] rx_channel RMT RX channel that created by `rmt_new_rx_channel()`
* @param[in] buffer The buffer to store the received RMT symbols
* @param[in] buffer_size size of the `buffer`, in bytes
* @param[in] config Receive specific configurations
* @return
* - ESP_OK: Initiate receive job successfully
* - ESP_ERR_INVALID_ARG: Initiate receive job failed because of invalid argument
* - ESP_ERR_INVALID_STATE: Initiate receive job failed because channel is not enabled
* - ESP_FAIL: Initiate receive job failed because of other error
*/
esp_err_t rmt_receive(rmt_channel_handle_t rx_channel, void *buffer, size_t buffer_size, const rmt_receive_config_t *config);
/**
* @brief Set callbacks for RMT RX channel
*
* @note User can deregister a previously registered callback by calling this function and setting the callback member in the `cbs` structure to NULL.
* @note When CONFIG_RMT_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
* The variables used in the function should be in the SRAM as well. The `user_data` should also reside in SRAM.
*
* @param[in] rx_channel RMT generic channel that created by `rmt_new_rx_channel()`
* @param[in] cbs Group of callback functions
* @param[in] user_data User data, which will be passed to callback functions directly
* @return
* - ESP_OK: Set event callbacks successfully
* - ESP_ERR_INVALID_ARG: Set event callbacks failed because of invalid argument
* - ESP_FAIL: Set event callbacks failed because of other error
*/
esp_err_t rmt_rx_register_event_callbacks(rmt_channel_handle_t rx_channel, const rmt_rx_event_callbacks_t *cbs, void *user_data);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,175 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "esp_err.h"
#include "driver/rmt_common.h"
#include "driver/rmt_encoder.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Group of RMT TX callbacks
* @note The callbacks are all running under ISR environment
* @note When CONFIG_RMT_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
* The variables used in the function should be in the SRAM as well.
*/
typedef struct {
rmt_tx_done_callback_t on_trans_done; /*!< Event callback, invoked when transmission is finished */
} rmt_tx_event_callbacks_t;
/**
* @brief RMT TX channel specific configuration
*/
typedef struct {
int gpio_num; /*!< GPIO number used by RMT TX channel. Set to -1 if unused */
rmt_clock_source_t clk_src; /*!< Clock source of RMT TX channel, channels in the same group must use the same clock source */
uint32_t resolution_hz; /*!< Channel clock resolution, in Hz */
size_t mem_block_symbols; /*!< Size of memory block, in number of `rmt_symbol_word_t`, must be an even */
size_t trans_queue_depth; /*!< Depth of internal transfer queue, increase this value can support more transfers pending in the background */
struct {
uint32_t invert_out: 1; /*!< Whether to invert the RMT channel signal before output to GPIO pad */
uint32_t with_dma: 1; /*!< If set, the driver will allocate an RMT channel with DMA capability */
uint32_t io_loop_back: 1; /*!< The signal output from the GPIO will be fed to the input path as well */
uint32_t io_od_mode: 1; /*!< Configure the GPIO as open-drain mode */
} flags; /*!< TX channel config flags */
} rmt_tx_channel_config_t;
/**
* @brief RMT transmit specific configuration
*/
typedef struct {
int loop_count; /*!< Specify the times of transmission in a loop, -1 means transmitting in an infinite loop */
struct {
uint32_t eot_level : 1; /*!< Set the output level for the "End Of Transmission" */
} flags; /*!< Transmit config flags */
} rmt_transmit_config_t;
/**
* @brief Synchronous manager configuration
*/
typedef struct {
const rmt_channel_handle_t *tx_channel_array; /*!< Array of TX channels that are about to be managed by a synchronous controller */
size_t array_size; /*!< Size of the `tx_channel_array` */
} rmt_sync_manager_config_t;
/**
* @brief Create a RMT TX channel
*
* @param[in] config TX channel configurations
* @param[out] ret_chan Returned generic RMT channel handle
* @return
* - ESP_OK: Create RMT TX channel successfully
* - ESP_ERR_INVALID_ARG: Create RMT TX channel failed because of invalid argument
* - ESP_ERR_NO_MEM: Create RMT TX channel failed because out of memory
* - ESP_ERR_NOT_FOUND: Create RMT TX channel failed because all RMT channels are used up and no more free one
* - ESP_ERR_NOT_SUPPORTED: Create RMT TX channel failed because some feature is not supported by hardware, e.g. DMA feature is not supported by hardware
* - ESP_FAIL: Create RMT TX channel failed because of other error
*/
esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_handle_t *ret_chan);
/**
* @brief Transmit data by RMT TX channel
*
* @note This function will construct a transaction descriptor and push to a queue. The transaction will not start immediately until it's dispatched in the ISR.
* If there're too many transactions pending in the queue, this function will block until the queue has free space.
* @note The data to be transmitted will be encoded into RMT symbols by the specific `encoder`.
*
* @param[in] tx_channel RMT TX channel that created by `rmt_new_tx_channel()`
* @param[in] encoder RMT encoder that created by various factory APIs like `rmt_new_bytes_encoder()`
* @param[in] payload The raw data to be encoded into RMT symbols
* @param[in] payload_bytes Size of the `payload` in bytes
* @param[in] config Transmission specific configuration
* @return
* - ESP_OK: Transmit data successfully
* - ESP_ERR_INVALID_ARG: Transmit data failed because of invalid argument
* - ESP_ERR_INVALID_STATE: Transmit data failed because channel is not enabled
* - ESP_ERR_NOT_SUPPORTED: Transmit data failed because some feature is not supported by hardware, e.g. unsupported loop count
* - ESP_FAIL: Transmit data failed because of other error
*/
esp_err_t rmt_transmit(rmt_channel_handle_t tx_channel, rmt_encoder_handle_t encoder, const void *payload, size_t payload_bytes, const rmt_transmit_config_t *config);
/**
* @brief Wait for all pending TX transactions done
*
* @note This function will block forever if the pending transaction can't be finished within a limited time (e.g. an infinite loop transaction).
* See also `rmt_disable()` for how to terminate a working channel.
*
* @param[in] tx_channel RMT TX channel that created by `rmt_new_tx_channel()`
* @param[in] timeout_ms Wait timeout, in ms. Specially, -1 means to wait forever.
* @return
* - ESP_OK: Flush transactions successfully
* - ESP_ERR_INVALID_ARG: Flush transactions failed because of invalid argument
* - ESP_ERR_TIMEOUT: Flush transactions failed because of timeout
* - ESP_FAIL: Flush transactions failed because of other error
*/
esp_err_t rmt_tx_wait_all_done(rmt_channel_handle_t tx_channel, int timeout_ms);
/**
* @brief Set event callbacks for RMT TX channel
*
* @note User can deregister a previously registered callback by calling this function and setting the callback member in the `cbs` structure to NULL.
* @note When CONFIG_RMT_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
* The variables used in the function should be in the SRAM as well. The `user_data` should also reside in SRAM.
*
* @param[in] tx_channel RMT generic channel that created by `rmt_new_tx_channel()`
* @param[in] cbs Group of callback functions
* @param[in] user_data User data, which will be passed to callback functions directly
* @return
* - ESP_OK: Set event callbacks successfully
* - ESP_ERR_INVALID_ARG: Set event callbacks failed because of invalid argument
* - ESP_FAIL: Set event callbacks failed because of other error
*/
esp_err_t rmt_tx_register_event_callbacks(rmt_channel_handle_t tx_channel, const rmt_tx_event_callbacks_t *cbs, void *user_data);
/**
* @brief Create a synchronization manager for multiple TX channels, so that the managed channel can start transmitting at the same time
*
* @note All the channels to be managed should be enabled by `rmt_enable()` before put them into sync manager.
*
* @param[in] config Synchronization manager configuration
* @param[out] ret_synchro Returned synchronization manager handle
* @return
* - ESP_OK: Create sync manager successfully
* - ESP_ERR_INVALID_ARG: Create sync manager failed because of invalid argument
* - ESP_ERR_NOT_SUPPORTED: Create sync manager failed because it is not supported by hardware
* - ESP_ERR_INVALID_STATE: Create sync manager failed because not all channels are enabled
* - ESP_ERR_NO_MEM: Create sync manager failed because out of memory
* - ESP_ERR_NOT_FOUND: Create sync manager failed because all sync controllers are used up and no more free one
* - ESP_FAIL: Create sync manager failed because of other error
*/
esp_err_t rmt_new_sync_manager(const rmt_sync_manager_config_t *config, rmt_sync_manager_handle_t *ret_synchro);
/**
* @brief Delete synchronization manager
*
* @param[in] synchro Synchronization manager handle returned from `rmt_new_sync_manager()`
* @return
* - ESP_OK: Delete the synchronization manager successfully
* - ESP_ERR_INVALID_ARG: Delete the synchronization manager failed because of invalid argument
* - ESP_FAIL: Delete the synchronization manager failed because of other error
*/
esp_err_t rmt_del_sync_manager(rmt_sync_manager_handle_t synchro);
/**
* @brief Reset synchronization manager
*
* @param[in] synchro Synchronization manager handle returned from `rmt_new_sync_manager()`
* @return
* - ESP_OK: Reset the synchronization manager successfully
* - ESP_ERR_INVALID_ARG: Reset the synchronization manager failed because of invalid argument
* - ESP_FAIL: Reset the synchronization manager failed because of other error
*/
esp_err_t rmt_sync_reset(rmt_sync_manager_handle_t synchro);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "hal/rmt_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Type of RMT channel handle
*/
typedef struct rmt_channel_t *rmt_channel_handle_t;
/**
* @brief Type of RMT synchronization manager handle
*/
typedef struct rmt_sync_manager_t *rmt_sync_manager_handle_t;
/**
* @brief Type of RMT encoder handle
*/
typedef struct rmt_encoder_t *rmt_encoder_handle_t;
/**
* @brief Type of RMT TX done event data
*/
typedef struct {
size_t num_symbols; /*!< The number of transmitted RMT symbols, including one EOF symbol, which is appended by the driver to mark the end of a transmission.
For a loop transmission, this value only counts for one round. */
} rmt_tx_done_event_data_t;
/**
* @brief Prototype of RMT event callback
* @param[in] tx_chan RMT channel handle, created from `rmt_new_tx_channel()`
* @param[in] edata Point to RMT event data. The lifecycle of this pointer memory is inside this function,
* user should copy it into static memory if used outside this funcion.
* @param[in] user_ctx User registered context, passed from `rmt_tx_register_event_callbacks()`
*
* @return Whether a high priority task has been waken up by this callback function
*/
typedef bool (*rmt_tx_done_callback_t)(rmt_channel_handle_t tx_chan, const rmt_tx_done_event_data_t *edata, void *user_ctx);
/**
* @brief Type of RMT RX done event data
*/
typedef struct {
rmt_symbol_word_t *received_symbols; /*!< Point to the received RMT symbols */
size_t num_symbols; /*!< The number of received RMT symbols */
} rmt_rx_done_event_data_t;
/**
* @brief Prototype of RMT event callback
*
* @param[in] rx_chan RMT channel handle, created from `rmt_new_rx_channel()`
* @param[in] edata Point to RMT event data. The lifecycle of this pointer memory is inside this function,
* user should copy it into static memory if used outside this funcion.
* @param[in] user_ctx User registered context, passed from `rmt_rx_register_event_callbacks()`
* @return Whether a high priority task has been waken up by this function
*/
typedef bool (*rmt_rx_done_callback_t)(rmt_channel_handle_t rx_chan, const rmt_rx_done_event_data_t *edata, void *user_ctx);
#ifdef __cplusplus
}
#endif