1 /* 2 * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #pragma once 8 9 #include <stdint.h> 10 #include "soc/soc_caps.h" 11 #include "soc/clk_tree_defs.h" 12 #include "driver/gpio.h" 13 14 #ifdef __cplusplus 15 extern "C" { 16 #endif 17 18 19 #define RMT_CHANNEL_FLAGS_AWARE_DFS (1 << 0) /*!< Channel can work during APB clock scaling */ 20 #define RMT_CHANNEL_FLAGS_INVERT_SIG (1 << 1) /*!< Invert RMT signal */ 21 22 /** 23 * @brief Define memory space of each RMT channel (in words = 4 bytes) 24 */ 25 #define RMT_MEM_ITEM_NUM SOC_RMT_MEM_WORDS_PER_CHANNEL 26 27 /** 28 * @brief Definition of RMT item 29 */ 30 typedef struct { 31 union { 32 struct { 33 uint32_t duration0 : 15; /*!< Duration of level0 */ 34 uint32_t level0 : 1; /*!< Level of the first part */ 35 uint32_t duration1 : 15; /*!< Duration of level1 */ 36 uint32_t level1 : 1; /*!< Level of the second part */ 37 }; 38 uint32_t val; /*!< Equivalent unsigned value for the RMT item */ 39 }; 40 } rmt_item32_t; 41 42 43 #if SOC_RMT_SUPPORTED 44 /** 45 * @brief RMT hardware memory layout 46 */ 47 typedef struct { 48 struct { 49 volatile rmt_item32_t data32[SOC_RMT_MEM_WORDS_PER_CHANNEL]; 50 } chan[SOC_RMT_CHANNELS_PER_GROUP]; 51 } rmt_mem_t; 52 #endif // SOC_RMT_SUPPORTED 53 54 /** 55 * @brief RMT channel ID 56 */ 57 typedef enum { 58 RMT_CHANNEL_0, /*!< RMT channel number 0 */ 59 RMT_CHANNEL_1, /*!< RMT channel number 1 */ 60 RMT_CHANNEL_2, /*!< RMT channel number 2 */ 61 RMT_CHANNEL_3, /*!< RMT channel number 3 */ 62 #if SOC_RMT_CHANNELS_PER_GROUP > 4 63 RMT_CHANNEL_4, /*!< RMT channel number 4 */ 64 RMT_CHANNEL_5, /*!< RMT channel number 5 */ 65 RMT_CHANNEL_6, /*!< RMT channel number 6 */ 66 RMT_CHANNEL_7, /*!< RMT channel number 7 */ 67 #endif 68 RMT_CHANNEL_MAX /*!< Number of RMT channels */ 69 } rmt_channel_t; 70 71 /** 72 * @brief RMT Internal Memory Owner 73 */ 74 typedef enum { 75 RMT_MEM_OWNER_TX, /*!< RMT RX mode, RMT transmitter owns the memory block*/ 76 RMT_MEM_OWNER_RX, /*!< RMT RX mode, RMT receiver owns the memory block*/ 77 RMT_MEM_OWNER_MAX, 78 } rmt_mem_owner_t; 79 80 /** 81 * @brief Clock Source of RMT Channel 82 */ 83 #if SOC_RMT_SUPPORTED 84 typedef soc_periph_rmt_clk_src_legacy_t rmt_source_clk_t; 85 #else 86 typedef int rmt_source_clk_t; 87 #endif // SOC_RMT_SUPPORTED 88 89 /** 90 * @brief RMT Data Mode 91 * 92 * @note We highly recommended to use MEM mode not FIFO mode since there will be some gotcha in FIFO mode. 93 */ 94 typedef enum { 95 RMT_DATA_MODE_FIFO, /*<! RMT memory access in FIFO mode */ 96 RMT_DATA_MODE_MEM, /*<! RMT memory access in memory mode */ 97 RMT_DATA_MODE_MAX, 98 } rmt_data_mode_t; 99 100 /** 101 * @brief RMT Channel Working Mode (TX or RX) 102 */ 103 typedef enum { 104 RMT_MODE_TX, /*!< RMT TX mode */ 105 RMT_MODE_RX, /*!< RMT RX mode */ 106 RMT_MODE_MAX 107 } rmt_mode_t; 108 109 /** 110 * @brief RMT Idle Level 111 * 112 */ 113 typedef enum { 114 RMT_IDLE_LEVEL_LOW, /*!< RMT TX idle level: low Level */ 115 RMT_IDLE_LEVEL_HIGH, /*!< RMT TX idle level: high Level */ 116 RMT_IDLE_LEVEL_MAX, 117 } rmt_idle_level_t; 118 119 /** 120 * @brief RMT Carrier Level 121 */ 122 typedef enum { 123 RMT_CARRIER_LEVEL_LOW, /*!< RMT carrier wave is modulated for low Level output */ 124 RMT_CARRIER_LEVEL_HIGH, /*!< RMT carrier wave is modulated for high Level output */ 125 RMT_CARRIER_LEVEL_MAX 126 } rmt_carrier_level_t; 127 128 /** 129 * @brief RMT Channel Status 130 */ 131 typedef enum { 132 RMT_CHANNEL_UNINIT, /*!< RMT channel uninitialized */ 133 RMT_CHANNEL_IDLE, /*!< RMT channel status idle */ 134 RMT_CHANNEL_BUSY, /*!< RMT channel status busy */ 135 } rmt_channel_status_t; 136 137 /** 138 * @brief Data struct of RMT channel status 139 */ 140 typedef struct { 141 rmt_channel_status_t status[RMT_CHANNEL_MAX]; /*!< Store the current status of each channel */ 142 } rmt_channel_status_result_t; 143 144 /** 145 * @brief Data struct of RMT TX configure parameters 146 */ 147 typedef struct { 148 uint32_t carrier_freq_hz; /*!< RMT carrier frequency */ 149 rmt_carrier_level_t carrier_level; /*!< Level of the RMT output, when the carrier is applied */ 150 rmt_idle_level_t idle_level; /*!< RMT idle level */ 151 uint8_t carrier_duty_percent; /*!< RMT carrier duty (%) */ 152 uint32_t loop_count; /*!< Maximum loop count, only take effect for chips that is capable of `SOC_RMT_SUPPORT_TX_LOOP_COUNT` */ 153 bool carrier_en; /*!< RMT carrier enable */ 154 bool loop_en; /*!< Enable sending RMT items in a loop */ 155 bool idle_output_en; /*!< RMT idle level output enable */ 156 } rmt_tx_config_t; 157 158 /** 159 * @brief Data struct of RMT RX configure parameters 160 */ 161 typedef struct { 162 uint16_t idle_threshold; /*!< RMT RX idle threshold */ 163 uint8_t filter_ticks_thresh; /*!< RMT filter tick number */ 164 bool filter_en; /*!< RMT receiver filter enable */ 165 #if SOC_RMT_SUPPORT_RX_DEMODULATION 166 bool rm_carrier; /*!< RMT receiver remove carrier enable */ 167 uint32_t carrier_freq_hz; /*!< RMT carrier frequency */ 168 uint8_t carrier_duty_percent; /*!< RMT carrier duty (%) */ 169 rmt_carrier_level_t carrier_level; /*!< The level to remove the carrier */ 170 #endif 171 } rmt_rx_config_t; 172 173 /** 174 * @brief Data struct of RMT configure parameters 175 */ 176 typedef struct { 177 rmt_mode_t rmt_mode; /*!< RMT mode: transmitter or receiver */ 178 rmt_channel_t channel; /*!< RMT channel */ 179 gpio_num_t gpio_num; /*!< RMT GPIO number */ 180 uint8_t clk_div; /*!< RMT channel counter divider */ 181 uint8_t mem_block_num; /*!< RMT memory block number */ 182 uint32_t flags; /*!< RMT channel extra configurations, OR'd with RMT_CHANNEL_FLAGS_[*] */ 183 union { 184 rmt_tx_config_t tx_config; /*!< RMT TX parameter */ 185 rmt_rx_config_t rx_config; /*!< RMT RX parameter */ 186 }; 187 } rmt_config_t; 188 189 #if CONFIG_IDF_TARGET_ESP32H2 190 #define RMT_DEFAULT_CLK_DIV 32 191 #else 192 #define RMT_DEFAULT_CLK_DIV 80 193 #endif 194 195 /** 196 * @brief Default configuration for Tx channel 197 * 198 */ 199 #define RMT_DEFAULT_CONFIG_TX(gpio, channel_id) \ 200 { \ 201 .rmt_mode = RMT_MODE_TX, \ 202 .channel = channel_id, \ 203 .gpio_num = gpio, \ 204 .clk_div = RMT_DEFAULT_CLK_DIV, \ 205 .mem_block_num = 1, \ 206 .flags = 0, \ 207 .tx_config = { \ 208 .carrier_freq_hz = 38000, \ 209 .carrier_level = RMT_CARRIER_LEVEL_HIGH, \ 210 .idle_level = RMT_IDLE_LEVEL_LOW, \ 211 .carrier_duty_percent = 33, \ 212 .loop_count = 0, \ 213 .carrier_en = false, \ 214 .loop_en = false, \ 215 .idle_output_en = true, \ 216 } \ 217 } 218 219 /** 220 * @brief Default configuration for RX channel 221 * 222 */ 223 #define RMT_DEFAULT_CONFIG_RX(gpio, channel_id) \ 224 { \ 225 .rmt_mode = RMT_MODE_RX, \ 226 .channel = channel_id, \ 227 .gpio_num = gpio, \ 228 .clk_div = RMT_DEFAULT_CLK_DIV, \ 229 .mem_block_num = 1, \ 230 .flags = 0, \ 231 .rx_config = { \ 232 .idle_threshold = 12000, \ 233 .filter_ticks_thresh = 100, \ 234 .filter_en = true, \ 235 } \ 236 } 237 238 /** 239 * @brief RMT interrupt handle 240 */ 241 typedef intr_handle_t rmt_isr_handle_t; 242 243 /** 244 * @brief Type of RMT Tx End callback function 245 */ 246 typedef void (*rmt_tx_end_fn_t)(rmt_channel_t channel, void *arg); 247 248 /** 249 * @brief Structure encapsulating a RMT TX end callback 250 */ 251 typedef struct { 252 rmt_tx_end_fn_t function; /*!< Function which is called on RMT TX end */ 253 void *arg; /*!< Optional argument passed to function */ 254 } rmt_tx_end_callback_t; 255 256 /** 257 * @brief User callback function to convert uint8_t type data to rmt format(rmt_item32_t). 258 * 259 * This function may be called from an ISR, so, the code should be short and efficient. 260 * 261 * @param src Pointer to the buffer storing the raw data that needs to be converted to rmt format. 262 * @param[out] dest Pointer to the buffer storing the rmt format data. 263 * @param src_size The raw data size. 264 * @param wanted_num The number of rmt format data that wanted to get. 265 * @param[out] translated_size The size of the raw data that has been converted to rmt format, 266 * it should return 0 if no data is converted in user callback. 267 * @param[out] item_num The number of the rmt format data that actually converted to, 268 * it can be less than wanted_num if there is not enough raw data, but cannot exceed wanted_num. 269 * it should return 0 if no data was converted. 270 * 271 * @note 272 * In fact, item_num should be a multiple of translated_size, e.g. : 273 * When we convert each byte of uint8_t type data to rmt format data, 274 * the relation between item_num and translated_size should be `item_num = translated_size*8`. 275 */ 276 typedef void (*sample_to_rmt_t)(const void *src, rmt_item32_t *dest, size_t src_size, size_t wanted_num, size_t *translated_size, size_t *item_num); 277 278 #ifdef __cplusplus 279 } 280 #endif 281