rmt_tx.c 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045
  1. /*
  2. * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/cdefs.h>
  9. #include <sys/param.h>
  10. #include "sdkconfig.h"
  11. #if CONFIG_RMT_ENABLE_DEBUG_LOG
  12. // The local log level must be defined before including esp_log.h
  13. // Set the maximum log level for this source file
  14. #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
  15. #endif
  16. #include "esp_log.h"
  17. #include "esp_check.h"
  18. #include "esp_rom_gpio.h"
  19. #include "soc/rmt_periph.h"
  20. #include "soc/rtc.h"
  21. #include "hal/rmt_ll.h"
  22. #include "hal/gpio_hal.h"
  23. #include "driver/gpio.h"
  24. #include "driver/rmt_tx.h"
  25. #include "rmt_private.h"
  26. #include "esp_memory_utils.h"
  27. static const char *TAG = "rmt";
  28. struct rmt_sync_manager_t {
  29. rmt_group_t *group; // which group the synchro belongs to
  30. uint32_t channel_mask; // Mask of channels that are managed
  31. size_t array_size; // Size of the `tx_channel_array`
  32. rmt_channel_handle_t tx_channel_array[]; // Array of TX channels that are managed
  33. };
  34. static esp_err_t rmt_del_tx_channel(rmt_channel_handle_t channel);
  35. static esp_err_t rmt_tx_modulate_carrier(rmt_channel_handle_t channel, const rmt_carrier_config_t *config);
  36. static esp_err_t rmt_tx_enable(rmt_channel_handle_t channel);
  37. static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel);
  38. static void rmt_tx_default_isr(void *args);
  39. #if SOC_RMT_SUPPORT_DMA
  40. static bool rmt_dma_tx_eof_cb(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data);
  41. static esp_err_t rmt_tx_init_dma_link(rmt_tx_channel_t *tx_channel, const rmt_tx_channel_config_t *config)
  42. {
  43. rmt_symbol_word_t *dma_mem_base = heap_caps_calloc(1, sizeof(rmt_symbol_word_t) * config->mem_block_symbols, RMT_MEM_ALLOC_CAPS | MALLOC_CAP_DMA);
  44. ESP_RETURN_ON_FALSE(dma_mem_base, ESP_ERR_NO_MEM, TAG, "no mem for tx DMA buffer");
  45. tx_channel->base.dma_mem_base = dma_mem_base;
  46. for (int i = 0; i < RMT_DMA_NODES_PING_PONG; i++) {
  47. // each descriptor shares half of the DMA buffer
  48. tx_channel->dma_nodes[i].buffer = dma_mem_base + tx_channel->ping_pong_symbols * i;
  49. tx_channel->dma_nodes[i].dw0.size = tx_channel->ping_pong_symbols * sizeof(rmt_symbol_word_t);
  50. // the ownership will be switched to DMA in `rmt_tx_do_transaction()`
  51. tx_channel->dma_nodes[i].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_CPU;
  52. // each node can generate the DMA eof interrupt, and the driver will do a ping-pong trick in the eof callback
  53. tx_channel->dma_nodes[i].dw0.suc_eof = 1;
  54. }
  55. gdma_channel_alloc_config_t dma_chan_config = {
  56. .direction = GDMA_CHANNEL_DIRECTION_TX,
  57. };
  58. ESP_RETURN_ON_ERROR(gdma_new_channel(&dma_chan_config, &tx_channel->base.dma_chan), TAG, "allocate TX DMA channel failed");
  59. gdma_strategy_config_t gdma_strategy_conf = {
  60. .auto_update_desc = true,
  61. .owner_check = true,
  62. };
  63. gdma_apply_strategy(tx_channel->base.dma_chan, &gdma_strategy_conf);
  64. gdma_tx_event_callbacks_t cbs = {
  65. .on_trans_eof = rmt_dma_tx_eof_cb,
  66. };
  67. gdma_register_tx_event_callbacks(tx_channel->base.dma_chan, &cbs, tx_channel);
  68. return ESP_OK;
  69. }
  70. #endif // SOC_RMT_SUPPORT_DMA
  71. static esp_err_t rmt_tx_register_to_group(rmt_tx_channel_t *tx_channel, const rmt_tx_channel_config_t *config)
  72. {
  73. size_t mem_block_num = 0;
  74. // start to search for a free channel
  75. // a channel can take up its neighbour's memory block, so the neighbour channel won't work, we should skip these "invaded" ones
  76. int channel_scan_start = RMT_TX_CHANNEL_OFFSET_IN_GROUP;
  77. int channel_scan_end = RMT_TX_CHANNEL_OFFSET_IN_GROUP + SOC_RMT_TX_CANDIDATES_PER_GROUP;
  78. if (config->flags.with_dma) {
  79. // for DMA mode, the memory block number is always 1; for non-DMA mode, memory block number is configured by user
  80. mem_block_num = 1;
  81. // Only the last channel has the DMA capability
  82. channel_scan_start = RMT_TX_CHANNEL_OFFSET_IN_GROUP + SOC_RMT_TX_CANDIDATES_PER_GROUP - 1;
  83. tx_channel->ping_pong_symbols = config->mem_block_symbols / 2;
  84. } else {
  85. // one channel can occupy multiple memory blocks
  86. mem_block_num = config->mem_block_symbols / SOC_RMT_MEM_WORDS_PER_CHANNEL;
  87. if (mem_block_num * SOC_RMT_MEM_WORDS_PER_CHANNEL < config->mem_block_symbols) {
  88. mem_block_num++;
  89. }
  90. tx_channel->ping_pong_symbols = mem_block_num * SOC_RMT_MEM_WORDS_PER_CHANNEL / 2;
  91. }
  92. tx_channel->base.mem_block_num = mem_block_num;
  93. // search free channel and then register to the group
  94. // memory blocks used by one channel must be continuous
  95. uint32_t channel_mask = (1 << mem_block_num) - 1;
  96. rmt_group_t *group = NULL;
  97. int channel_id = -1;
  98. for (int i = 0; i < SOC_RMT_GROUPS; i++) {
  99. group = rmt_acquire_group_handle(i);
  100. ESP_RETURN_ON_FALSE(group, ESP_ERR_NO_MEM, TAG, "no mem for group (%d)", i);
  101. portENTER_CRITICAL(&group->spinlock);
  102. for (int j = channel_scan_start; j < channel_scan_end; j++) {
  103. if (!(group->occupy_mask & (channel_mask << j))) {
  104. group->occupy_mask |= (channel_mask << j);
  105. // the channel ID should index from 0
  106. channel_id = j - RMT_TX_CHANNEL_OFFSET_IN_GROUP;
  107. group->tx_channels[channel_id] = tx_channel;
  108. break;
  109. }
  110. }
  111. portEXIT_CRITICAL(&group->spinlock);
  112. if (channel_id < 0) {
  113. // didn't find a capable channel in the group, don't forget to release the group handle
  114. rmt_release_group_handle(group);
  115. group = NULL;
  116. } else {
  117. tx_channel->base.channel_id = channel_id;
  118. tx_channel->base.channel_mask = channel_mask;
  119. tx_channel->base.group = group;
  120. break;
  121. }
  122. }
  123. ESP_RETURN_ON_FALSE(channel_id >= 0, ESP_ERR_NOT_FOUND, TAG, "no free tx channels");
  124. return ESP_OK;
  125. }
  126. static void rmt_tx_unregister_from_group(rmt_channel_t *channel, rmt_group_t *group)
  127. {
  128. portENTER_CRITICAL(&group->spinlock);
  129. group->tx_channels[channel->channel_id] = NULL;
  130. group->occupy_mask &= ~(channel->channel_mask << (channel->channel_id + RMT_TX_CHANNEL_OFFSET_IN_GROUP));
  131. portEXIT_CRITICAL(&group->spinlock);
  132. // channel has a reference on group, release it now
  133. rmt_release_group_handle(group);
  134. }
  135. static esp_err_t rmt_tx_create_trans_queue(rmt_tx_channel_t *tx_channel, const rmt_tx_channel_config_t *config)
  136. {
  137. tx_channel->queue_size = config->trans_queue_depth;
  138. // the queue only saves transaction description pointers
  139. tx_channel->queues_storage = heap_caps_calloc(config->trans_queue_depth * RMT_TX_QUEUE_MAX, sizeof(rmt_tx_trans_desc_t *), RMT_MEM_ALLOC_CAPS);
  140. ESP_RETURN_ON_FALSE(tx_channel->queues_storage, ESP_ERR_NO_MEM, TAG, "no mem for queue storage");
  141. rmt_tx_trans_desc_t **pp_trans_desc = (rmt_tx_trans_desc_t **)tx_channel->queues_storage;
  142. for (int i = 0; i < RMT_TX_QUEUE_MAX; i++) {
  143. tx_channel->trans_queues[i] = xQueueCreateStatic(config->trans_queue_depth, sizeof(rmt_tx_trans_desc_t *),
  144. (uint8_t *)pp_trans_desc, &tx_channel->trans_queue_structs[i]);
  145. pp_trans_desc += config->trans_queue_depth;
  146. // sanity check
  147. assert(tx_channel->trans_queues[i]);
  148. }
  149. // initialize the ready queue
  150. rmt_tx_trans_desc_t *p_trans_desc = NULL;
  151. for (int i = 0; i < config->trans_queue_depth; i++) {
  152. p_trans_desc = &tx_channel->trans_desc_pool[i];
  153. ESP_RETURN_ON_FALSE(xQueueSend(tx_channel->trans_queues[RMT_TX_QUEUE_READY], &p_trans_desc, 0) == pdTRUE,
  154. ESP_ERR_INVALID_STATE, TAG, "ready queue full");
  155. }
  156. return ESP_OK;
  157. }
  158. static esp_err_t rmt_tx_destory(rmt_tx_channel_t *tx_channel)
  159. {
  160. if (tx_channel->base.intr) {
  161. ESP_RETURN_ON_ERROR(esp_intr_free(tx_channel->base.intr), TAG, "delete interrupt service failed");
  162. }
  163. if (tx_channel->base.pm_lock) {
  164. ESP_RETURN_ON_ERROR(esp_pm_lock_delete(tx_channel->base.pm_lock), TAG, "delete pm_lock failed");
  165. }
  166. #if SOC_RMT_SUPPORT_DMA
  167. if (tx_channel->base.dma_chan) {
  168. ESP_RETURN_ON_ERROR(gdma_del_channel(tx_channel->base.dma_chan), TAG, "delete dma channel failed");
  169. }
  170. #endif // SOC_RMT_SUPPORT_DMA
  171. for (int i = 0; i < RMT_TX_QUEUE_MAX; i++) {
  172. if (tx_channel->trans_queues[i]) {
  173. vQueueDelete(tx_channel->trans_queues[i]);
  174. }
  175. }
  176. if (tx_channel->queues_storage) {
  177. free(tx_channel->queues_storage);
  178. }
  179. if (tx_channel->base.dma_mem_base) {
  180. free(tx_channel->base.dma_mem_base);
  181. }
  182. if (tx_channel->base.group) {
  183. // de-register channel from RMT group
  184. rmt_tx_unregister_from_group(&tx_channel->base, tx_channel->base.group);
  185. }
  186. free(tx_channel);
  187. return ESP_OK;
  188. }
  189. esp_err_t rmt_new_tx_channel(const rmt_tx_channel_config_t *config, rmt_channel_handle_t *ret_chan)
  190. {
  191. #if CONFIG_RMT_ENABLE_DEBUG_LOG
  192. esp_log_level_set(TAG, ESP_LOG_DEBUG);
  193. #endif
  194. esp_err_t ret = ESP_OK;
  195. rmt_tx_channel_t *tx_channel = NULL;
  196. ESP_GOTO_ON_FALSE(config && ret_chan && config->resolution_hz && config->trans_queue_depth, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
  197. ESP_GOTO_ON_FALSE(GPIO_IS_VALID_GPIO(config->gpio_num), ESP_ERR_INVALID_ARG, err, TAG, "invalid GPIO number");
  198. ESP_GOTO_ON_FALSE((config->mem_block_symbols & 0x01) == 0 && config->mem_block_symbols >= SOC_RMT_MEM_WORDS_PER_CHANNEL,
  199. ESP_ERR_INVALID_ARG, err, TAG, "mem_block_symbols must be even and at least %d", SOC_RMT_MEM_WORDS_PER_CHANNEL);
  200. #if SOC_RMT_SUPPORT_DMA
  201. // we only support 2 nodes ping-pong, if the configured memory block size needs more than two DMA descriptors, should treat it as invalid
  202. ESP_GOTO_ON_FALSE(config->mem_block_symbols <= RMT_DMA_DESC_BUF_MAX_SIZE * RMT_DMA_NODES_PING_PONG, ESP_ERR_INVALID_ARG, err, TAG,
  203. "mem_block_symbols can't exceed %d", RMT_DMA_DESC_BUF_MAX_SIZE * RMT_DMA_NODES_PING_PONG);
  204. #else
  205. ESP_GOTO_ON_FALSE(config->flags.with_dma == 0, ESP_ERR_NOT_SUPPORTED, err, TAG, "DMA not supported");
  206. #endif
  207. // malloc channel memory
  208. uint32_t mem_caps = RMT_MEM_ALLOC_CAPS;
  209. if (config->flags.with_dma) {
  210. // DMA descriptors must be placed in internal SRAM
  211. mem_caps |= MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA;
  212. }
  213. tx_channel = heap_caps_calloc(1, sizeof(rmt_tx_channel_t) + sizeof(rmt_tx_trans_desc_t) * config->trans_queue_depth, mem_caps);
  214. ESP_GOTO_ON_FALSE(tx_channel, ESP_ERR_NO_MEM, err, TAG, "no mem for tx channel");
  215. // create transaction queues
  216. ESP_GOTO_ON_ERROR(rmt_tx_create_trans_queue(tx_channel, config), err, TAG, "install trans queues failed");
  217. // register the channel to group
  218. ESP_GOTO_ON_ERROR(rmt_tx_register_to_group(tx_channel, config), err, TAG, "register channel failed");
  219. rmt_group_t *group = tx_channel->base.group;
  220. rmt_hal_context_t *hal = &group->hal;
  221. int channel_id = tx_channel->base.channel_id;
  222. int group_id = group->group_id;
  223. // select the clock source
  224. ESP_GOTO_ON_ERROR(rmt_select_periph_clock(&tx_channel->base, config->clk_src), err, TAG, "set group clock failed");
  225. // reset channel, make sure the TX engine is not working, and events are cleared
  226. portENTER_CRITICAL(&group->spinlock);
  227. rmt_hal_tx_channel_reset(&group->hal, channel_id);
  228. portEXIT_CRITICAL(&group->spinlock);
  229. // install interrupt service
  230. // interrupt is mandatory to run basic RMT transactions, so it's not lazy installed in `rmt_tx_register_event_callbacks()`
  231. int isr_flags = RMT_INTR_ALLOC_FLAG;
  232. ret = esp_intr_alloc_intrstatus(rmt_periph_signals.groups[group_id].irq, isr_flags,
  233. (uint32_t)rmt_ll_get_interrupt_status_reg(hal->regs),
  234. RMT_LL_EVENT_TX_MASK(channel_id), rmt_tx_default_isr, tx_channel, &tx_channel->base.intr);
  235. ESP_GOTO_ON_ERROR(ret, err, TAG, "install tx interrupt failed");
  236. // install DMA service
  237. #if SOC_RMT_SUPPORT_DMA
  238. if (config->flags.with_dma) {
  239. ESP_GOTO_ON_ERROR(rmt_tx_init_dma_link(tx_channel, config), err, TAG, "install tx DMA failed");
  240. }
  241. #endif
  242. // set channel clock resolution
  243. uint32_t real_div = group->resolution_hz / config->resolution_hz;
  244. rmt_ll_tx_set_channel_clock_div(hal->regs, channel_id, real_div);
  245. // resolution lost due to division, calculate the real resolution
  246. tx_channel->base.resolution_hz = group->resolution_hz / real_div;
  247. if (tx_channel->base.resolution_hz != config->resolution_hz) {
  248. ESP_LOGW(TAG, "channel resolution loss, real=%"PRIu32, tx_channel->base.resolution_hz);
  249. }
  250. rmt_ll_tx_set_mem_blocks(hal->regs, channel_id, tx_channel->base.mem_block_num);
  251. // set limit threshold, after transmit ping_pong_symbols size, an interrupt event would be generated
  252. rmt_ll_tx_set_limit(hal->regs, channel_id, tx_channel->ping_pong_symbols);
  253. // disable carrier modulation by default, can reenable by `rmt_apply_carrier()`
  254. rmt_ll_tx_enable_carrier_modulation(hal->regs, channel_id, false);
  255. // idle level is determined by register value
  256. rmt_ll_tx_fix_idle_level(hal->regs, channel_id, 0, true);
  257. // always enable tx wrap, both DMA mode and ping-pong mode rely this feature
  258. rmt_ll_tx_enable_wrap(hal->regs, channel_id, true);
  259. // GPIO Matrix/MUX configuration
  260. tx_channel->base.gpio_num = config->gpio_num;
  261. gpio_config_t gpio_conf = {
  262. .intr_type = GPIO_INTR_DISABLE,
  263. // also enable the input path is `io_loop_back` is on, this is useful for bi-directional buses
  264. .mode = (config->flags.io_od_mode ? GPIO_MODE_OUTPUT_OD : GPIO_MODE_OUTPUT) | (config->flags.io_loop_back ? GPIO_MODE_INPUT : 0),
  265. .pull_down_en = false,
  266. .pull_up_en = true,
  267. .pin_bit_mask = 1ULL << config->gpio_num,
  268. };
  269. ESP_GOTO_ON_ERROR(gpio_config(&gpio_conf), err, TAG, "config GPIO failed");
  270. esp_rom_gpio_connect_out_signal(config->gpio_num,
  271. rmt_periph_signals.groups[group_id].channels[channel_id + RMT_TX_CHANNEL_OFFSET_IN_GROUP].tx_sig,
  272. config->flags.invert_out, false);
  273. gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[config->gpio_num], PIN_FUNC_GPIO);
  274. tx_channel->base.direction = RMT_CHANNEL_DIRECTION_TX;
  275. tx_channel->base.fsm = RMT_FSM_INIT;
  276. tx_channel->base.hw_mem_base = &RMTMEM.channels[channel_id + RMT_TX_CHANNEL_OFFSET_IN_GROUP].symbols[0];
  277. tx_channel->base.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
  278. // polymorphic methods
  279. tx_channel->base.del = rmt_del_tx_channel;
  280. tx_channel->base.set_carrier_action = rmt_tx_modulate_carrier;
  281. tx_channel->base.enable = rmt_tx_enable;
  282. tx_channel->base.disable = rmt_tx_disable;
  283. // return general channel handle
  284. *ret_chan = &tx_channel->base;
  285. ESP_LOGD(TAG, "new tx channel(%d,%d) at %p, gpio=%d, res=%"PRIu32"Hz, hw_mem_base=%p, dma_mem_base=%p, ping_pong_size=%zu, queue_depth=%zu",
  286. group_id, channel_id, tx_channel, config->gpio_num, tx_channel->base.resolution_hz,
  287. tx_channel->base.hw_mem_base, tx_channel->base.dma_mem_base, tx_channel->ping_pong_symbols, tx_channel->queue_size);
  288. return ESP_OK;
  289. err:
  290. if (tx_channel) {
  291. rmt_tx_destory(tx_channel);
  292. }
  293. return ret;
  294. }
  295. static esp_err_t rmt_del_tx_channel(rmt_channel_handle_t channel)
  296. {
  297. rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base);
  298. rmt_group_t *group = channel->group;
  299. int group_id = group->group_id;
  300. int channel_id = channel->channel_id;
  301. ESP_LOGD(TAG, "del tx channel(%d,%d)", group_id, channel_id);
  302. // recycle memory resource
  303. ESP_RETURN_ON_ERROR(rmt_tx_destory(tx_chan), TAG, "destory tx channel failed");
  304. return ESP_OK;
  305. }
  306. esp_err_t rmt_new_sync_manager(const rmt_sync_manager_config_t *config, rmt_sync_manager_handle_t *ret_synchro)
  307. {
  308. #if !SOC_RMT_SUPPORT_TX_SYNCHRO
  309. ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "sync manager not supported");
  310. #else
  311. esp_err_t ret = ESP_OK;
  312. rmt_sync_manager_t *synchro = NULL;
  313. ESP_GOTO_ON_FALSE(config && ret_synchro && config->tx_channel_array && config->array_size, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
  314. synchro = heap_caps_calloc(1, sizeof(rmt_sync_manager_t) + sizeof(rmt_channel_handle_t) * config->array_size, RMT_MEM_ALLOC_CAPS);
  315. ESP_GOTO_ON_FALSE(synchro, ESP_ERR_NO_MEM, err, TAG, "no mem for sync manager");
  316. for (size_t i = 0; i < config->array_size; i++) {
  317. synchro->tx_channel_array[i] = config->tx_channel_array[i];
  318. }
  319. synchro->array_size = config->array_size;
  320. int group_id = config->tx_channel_array[0]->group->group_id;
  321. // acquire group handle, increase reference count
  322. rmt_group_t *group = rmt_acquire_group_handle(group_id);
  323. // sanity check
  324. assert(group);
  325. synchro->group = group;
  326. // calculate the mask of the channels to be managed
  327. uint32_t channel_mask = 0;
  328. rmt_channel_handle_t channel = NULL;
  329. for (size_t i = 0; i < config->array_size; i++) {
  330. channel = config->tx_channel_array[i];
  331. ESP_GOTO_ON_FALSE(channel->direction == RMT_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, err, TAG, "sync manager supports TX channel only");
  332. ESP_GOTO_ON_FALSE(channel->group == group, ESP_ERR_INVALID_ARG, err, TAG, "channels to be managed should locate in the same group");
  333. ESP_GOTO_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, err, TAG, "channel should be started before creating sync manager");
  334. channel_mask |= 1 << channel->channel_id;
  335. }
  336. synchro->channel_mask = channel_mask;
  337. // search and register sync manager to group
  338. bool new_synchro = false;
  339. portENTER_CRITICAL(&group->spinlock);
  340. if (group->sync_manager == NULL) {
  341. group->sync_manager = synchro;
  342. new_synchro = true;
  343. }
  344. portEXIT_CRITICAL(&group->spinlock);
  345. ESP_GOTO_ON_FALSE(new_synchro, ESP_ERR_NOT_FOUND, err, TAG, "no free sync manager in the group");
  346. // enable sync manager
  347. portENTER_CRITICAL(&group->spinlock);
  348. rmt_ll_tx_enable_sync(group->hal.regs, true);
  349. rmt_ll_tx_sync_group_add_channels(group->hal.regs, channel_mask);
  350. rmt_ll_tx_reset_channels_clock_div(group->hal.regs, channel_mask);
  351. // ensure the reading cursor of each channel is pulled back to the starting line
  352. for (size_t i = 0; i < config->array_size; i++) {
  353. rmt_ll_tx_reset_pointer(group->hal.regs, config->tx_channel_array[i]->channel_id);
  354. }
  355. portEXIT_CRITICAL(&group->spinlock);
  356. *ret_synchro = synchro;
  357. ESP_LOGD(TAG, "new sync manager at %p, with channel mask:%02"PRIx32, synchro, synchro->channel_mask);
  358. return ESP_OK;
  359. err:
  360. if (synchro) {
  361. if (synchro->group) {
  362. rmt_release_group_handle(synchro->group);
  363. }
  364. free(synchro);
  365. }
  366. return ret;
  367. #endif // !SOC_RMT_SUPPORT_TX_SYNCHRO
  368. }
  369. esp_err_t rmt_sync_reset(rmt_sync_manager_handle_t synchro)
  370. {
  371. #if !SOC_RMT_SUPPORT_TX_SYNCHRO
  372. ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "sync manager not supported");
  373. #else
  374. ESP_RETURN_ON_FALSE(synchro, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
  375. rmt_group_t *group = synchro->group;
  376. portENTER_CRITICAL(&group->spinlock);
  377. rmt_ll_tx_reset_channels_clock_div(group->hal.regs, synchro->channel_mask);
  378. for (size_t i = 0; i < synchro->array_size; i++) {
  379. rmt_ll_tx_reset_pointer(group->hal.regs, synchro->tx_channel_array[i]->channel_id);
  380. }
  381. portEXIT_CRITICAL(&group->spinlock);
  382. return ESP_OK;
  383. #endif // !SOC_RMT_SUPPORT_TX_SYNCHRO
  384. }
  385. esp_err_t rmt_del_sync_manager(rmt_sync_manager_handle_t synchro)
  386. {
  387. #if !SOC_RMT_SUPPORT_TX_SYNCHRO
  388. ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "sync manager not supported");
  389. #else
  390. ESP_RETURN_ON_FALSE(synchro, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
  391. rmt_group_t *group = synchro->group;
  392. int group_id = group->group_id;
  393. portENTER_CRITICAL(&group->spinlock);
  394. group->sync_manager = NULL;
  395. // disable sync manager
  396. rmt_ll_tx_enable_sync(group->hal.regs, false);
  397. rmt_ll_tx_sync_group_remove_channels(group->hal.regs, synchro->channel_mask);
  398. portEXIT_CRITICAL(&group->spinlock);
  399. free(synchro);
  400. ESP_LOGD(TAG, "del sync manager in group(%d)", group_id);
  401. rmt_release_group_handle(group);
  402. return ESP_OK;
  403. #endif // !SOC_RMT_SUPPORT_TX_SYNCHRO
  404. }
  405. esp_err_t rmt_tx_register_event_callbacks(rmt_channel_handle_t channel, const rmt_tx_event_callbacks_t *cbs, void *user_data)
  406. {
  407. ESP_RETURN_ON_FALSE(channel && cbs, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
  408. ESP_RETURN_ON_FALSE(channel->direction == RMT_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, TAG, "invalid channel direction");
  409. rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base);
  410. #if CONFIG_RMT_ISR_IRAM_SAFE
  411. if (cbs->on_trans_done) {
  412. ESP_RETURN_ON_FALSE(esp_ptr_in_iram(cbs->on_trans_done), ESP_ERR_INVALID_ARG, TAG, "on_trans_done callback not in IRAM");
  413. }
  414. if (user_data) {
  415. ESP_RETURN_ON_FALSE(esp_ptr_internal(user_data), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM");
  416. }
  417. #endif
  418. tx_chan->on_trans_done = cbs->on_trans_done;
  419. tx_chan->user_data = user_data;
  420. return ESP_OK;
  421. }
  422. esp_err_t rmt_transmit(rmt_channel_handle_t channel, rmt_encoder_t *encoder, const void *payload, size_t payload_bytes, const rmt_transmit_config_t *config)
  423. {
  424. ESP_RETURN_ON_FALSE(channel && encoder && payload && payload_bytes && config, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
  425. ESP_RETURN_ON_FALSE(channel->direction == RMT_CHANNEL_DIRECTION_TX, ESP_ERR_INVALID_ARG, TAG, "invalid channel direction");
  426. ESP_RETURN_ON_FALSE(channel->fsm == RMT_FSM_ENABLE, ESP_ERR_INVALID_STATE, TAG, "channel not in enable state");
  427. #if !SOC_RMT_SUPPORT_TX_LOOP_COUNT
  428. ESP_RETURN_ON_FALSE(config->loop_count <= 0, ESP_ERR_NOT_SUPPORTED, TAG, "loop count is not supported");
  429. #endif // !SOC_RMT_SUPPORT_TX_LOOP_COUNT
  430. rmt_group_t *group = channel->group;
  431. rmt_hal_context_t *hal = &group->hal;
  432. int channel_id = channel->channel_id;
  433. rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base);
  434. rmt_tx_trans_desc_t *t = NULL;
  435. // acquire one transaction description from ready_queue or done_queue
  436. if (tx_chan->num_trans_inflight < tx_chan->queue_size) {
  437. ESP_RETURN_ON_FALSE(xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, portMAX_DELAY) == pdTRUE,
  438. ESP_FAIL, TAG, "no transaction in the ready queue");
  439. } else {
  440. ESP_RETURN_ON_FALSE(xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, portMAX_DELAY) == pdTRUE,
  441. ESP_FAIL, TAG, "recycle transaction from done queue failed");
  442. tx_chan->num_trans_inflight--;
  443. }
  444. // sanity check
  445. assert(t);
  446. // fill in the transaction descriptor
  447. memset(t, 0, sizeof(rmt_tx_trans_desc_t));
  448. t->encoder = encoder;
  449. t->payload = payload;
  450. t->payload_bytes = payload_bytes;
  451. t->loop_count = config->loop_count;
  452. t->remain_loop_count = t->loop_count;
  453. t->flags.eot_level = config->flags.eot_level;
  454. // send the transaction descriptor to queue
  455. if (xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &t, portMAX_DELAY) == pdTRUE) {
  456. tx_chan->num_trans_inflight++;
  457. } else {
  458. // put the trans descriptor back to ready_queue
  459. ESP_RETURN_ON_FALSE(xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, 0) == pdTRUE,
  460. ESP_ERR_INVALID_STATE, TAG, "ready queue full");
  461. }
  462. // we don't know which "transmission complete" event will be triggered, but must be one of them: trans_done, loop_done
  463. // when we run at here, the interrupt status bit for tx_done or loop_end should already up (ensured by `rmt_tx_enable()`)
  464. // that's why we can go into ISR as soon as we enable the interrupt bit
  465. // in the ISR, we will fetch the transactions from trans_queue and start it
  466. portENTER_CRITICAL(&group->spinlock);
  467. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id) | RMT_LL_EVENT_TX_LOOP_END(channel_id), true);
  468. portEXIT_CRITICAL(&group->spinlock);
  469. return ESP_OK;
  470. }
  471. esp_err_t rmt_tx_wait_all_done(rmt_channel_handle_t channel, int timeout_ms)
  472. {
  473. ESP_RETURN_ON_FALSE(channel, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
  474. rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base);
  475. TickType_t wait_ticks = timeout_ms < 0 ? portMAX_DELAY : pdMS_TO_TICKS(timeout_ms);
  476. // recycle all transaction that are on the fly
  477. rmt_tx_trans_desc_t *t = NULL;
  478. size_t num_trans_inflight = tx_chan->num_trans_inflight;
  479. for (size_t i = 0; i < num_trans_inflight; i++) {
  480. ESP_RETURN_ON_FALSE(xQueueReceive(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &t, wait_ticks) == pdTRUE,
  481. ESP_ERR_TIMEOUT, TAG, "flush timeout");
  482. ESP_RETURN_ON_FALSE(xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_READY], &t, 0) == pdTRUE,
  483. ESP_ERR_INVALID_STATE, TAG, "ready queue full");
  484. tx_chan->num_trans_inflight--;
  485. }
  486. return ESP_OK;
  487. }
  488. static void IRAM_ATTR rmt_tx_mark_eof(rmt_tx_channel_t *tx_chan)
  489. {
  490. rmt_channel_t *channel = &tx_chan->base;
  491. rmt_group_t *group = channel->group;
  492. int channel_id = channel->channel_id;
  493. rmt_symbol_word_t *mem_to = channel->dma_chan ? channel->dma_mem_base : channel->hw_mem_base;
  494. rmt_tx_trans_desc_t *cur_trans = tx_chan->cur_trans;
  495. dma_descriptor_t *desc = NULL;
  496. // a RMT word whose duration is zero means a "stop" pattern
  497. mem_to[tx_chan->mem_off++] = (rmt_symbol_word_t) {
  498. .duration0 = 0,
  499. .level0 = cur_trans->flags.eot_level,
  500. .duration1 = 0,
  501. .level1 = cur_trans->flags.eot_level,
  502. };
  503. size_t off = 0;
  504. if (channel->dma_chan) {
  505. if (tx_chan->mem_off <= tx_chan->ping_pong_symbols) {
  506. desc = &tx_chan->dma_nodes[0];
  507. off = tx_chan->mem_off;
  508. } else {
  509. desc = &tx_chan->dma_nodes[1];
  510. off = tx_chan->mem_off - tx_chan->ping_pong_symbols;
  511. }
  512. desc->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA;
  513. desc->dw0.length = off * sizeof(rmt_symbol_word_t);
  514. // break down the DMA descriptor link
  515. desc->next = NULL;
  516. } else {
  517. portENTER_CRITICAL_ISR(&group->spinlock);
  518. // This is the end of a sequence of encoding sessions, disable the threshold interrupt as no more data will be put into RMT memory block
  519. rmt_ll_enable_interrupt(group->hal.regs, RMT_LL_EVENT_TX_THRES(channel_id), false);
  520. portEXIT_CRITICAL_ISR(&group->spinlock);
  521. }
  522. }
  523. static size_t IRAM_ATTR rmt_encode_check_result(rmt_tx_channel_t *tx_chan, rmt_tx_trans_desc_t *t)
  524. {
  525. rmt_encode_state_t encode_state = 0;
  526. rmt_encoder_handle_t encoder = t->encoder;
  527. size_t encoded_symbols = encoder->encode(encoder, &tx_chan->base, t->payload, t->payload_bytes, &encode_state);
  528. if (encode_state & RMT_ENCODING_COMPLETE) {
  529. t->flags.encoding_done = true;
  530. // inserting EOF symbol if there's extra space
  531. if (!(encode_state & RMT_ENCODING_MEM_FULL)) {
  532. rmt_tx_mark_eof(tx_chan);
  533. encoded_symbols += 1;
  534. }
  535. }
  536. // for loop transaction, the memory block should accommodate all encoded RMT symbols
  537. if (t->loop_count != 0) {
  538. if (unlikely(encoded_symbols > tx_chan->base.mem_block_num * SOC_RMT_MEM_WORDS_PER_CHANNEL)) {
  539. ESP_DRAM_LOGE(TAG, "encoding artifacts can't exceed hw memory block for loop transmission");
  540. }
  541. }
  542. return encoded_symbols;
  543. }
  544. static void IRAM_ATTR rmt_tx_do_transaction(rmt_tx_channel_t *tx_chan, rmt_tx_trans_desc_t *t)
  545. {
  546. rmt_channel_t *channel = &tx_chan->base;
  547. rmt_group_t *group = channel->group;
  548. rmt_hal_context_t *hal = &group->hal;
  549. int channel_id = channel->channel_id;
  550. #if SOC_RMT_SUPPORT_DMA
  551. if (channel->dma_chan) {
  552. gdma_reset(channel->dma_chan);
  553. // chain the descritpros into a ring, and will break it in `rmt_encode_eof()`
  554. for (int i = 0; i < RMT_DMA_NODES_PING_PONG; i++) {
  555. tx_chan->dma_nodes[i].next = &tx_chan->dma_nodes[i + 1];
  556. tx_chan->dma_nodes[i].dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_CPU;
  557. }
  558. tx_chan->dma_nodes[1].next = &tx_chan->dma_nodes[0];
  559. }
  560. #endif // SOC_RMT_SUPPORT_DMA
  561. // set transaction specific parameters
  562. portENTER_CRITICAL_ISR(&channel->spinlock);
  563. rmt_ll_tx_reset_pointer(hal->regs, channel_id); // reset pointer for new transaction
  564. rmt_ll_tx_enable_loop(hal->regs, channel_id, t->loop_count != 0);
  565. #if SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP
  566. rmt_ll_tx_enable_loop_autostop(hal->regs, channel_id, true);
  567. #endif // SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP
  568. #if SOC_RMT_SUPPORT_TX_LOOP_COUNT
  569. rmt_ll_tx_reset_loop_count(hal->regs, channel_id);
  570. rmt_ll_tx_enable_loop_count(hal->regs, channel_id, t->loop_count > 0);
  571. // transfer loops in batches
  572. if (t->remain_loop_count > 0) {
  573. uint32_t this_loop_count = MIN(t->remain_loop_count, RMT_LL_MAX_LOOP_COUNT_PER_BATCH);
  574. rmt_ll_tx_set_loop_count(hal->regs, channel_id, this_loop_count);
  575. t->remain_loop_count -= this_loop_count;
  576. }
  577. #endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT
  578. portEXIT_CRITICAL_ISR(&channel->spinlock);
  579. // enable/disable specific interrupts
  580. portENTER_CRITICAL_ISR(&group->spinlock);
  581. #if SOC_RMT_SUPPORT_TX_LOOP_COUNT
  582. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), t->loop_count > 0);
  583. #endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT
  584. // in DMA mode, DMA eof event plays the similar functionality to this threshold interrupt, so only enable it for non-DMA mode
  585. if (!channel->dma_chan) {
  586. // don't enable threshold interrupt with loop mode on
  587. // threshold interrupt will be disabled in `rmt_encode_eof()`
  588. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_THRES(channel_id), t->loop_count == 0);
  589. // Threshold interrupt will be generated by accident, clear it before starting new transmission
  590. rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_THRES(channel_id));
  591. }
  592. // don't generate trans done event for loop transmission
  593. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), t->loop_count == 0);
  594. portEXIT_CRITICAL_ISR(&group->spinlock);
  595. // at the beginning of a new transaction, encoding memory offset should start from zero.
  596. // It will increase in the encode function e.g. `rmt_encode_copy()`
  597. tx_chan->mem_off = 0;
  598. // use the full memory block for the beginning encoding session
  599. tx_chan->mem_end = tx_chan->ping_pong_symbols * 2;
  600. // perform the encoding session, return the number of encoded symbols
  601. t->transmitted_symbol_num = rmt_encode_check_result(tx_chan, t);
  602. // we're going to perform ping-pong operation, so the next encoding end position is the middle
  603. tx_chan->mem_end = tx_chan->ping_pong_symbols;
  604. #if SOC_RMT_SUPPORT_DMA
  605. if (channel->dma_chan) {
  606. gdma_start(channel->dma_chan, (intptr_t)tx_chan->dma_nodes);
  607. // delay a while, wait for DMA data going to RMT memory block
  608. esp_rom_delay_us(1);
  609. }
  610. #endif
  611. // turn on the TX machine
  612. portENTER_CRITICAL_ISR(&channel->spinlock);
  613. rmt_ll_tx_fix_idle_level(hal->regs, channel_id, t->flags.eot_level, true);
  614. rmt_ll_tx_start(hal->regs, channel_id);
  615. portEXIT_CRITICAL_ISR(&channel->spinlock);
  616. }
  617. static esp_err_t rmt_tx_enable(rmt_channel_handle_t channel)
  618. {
  619. rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base);
  620. rmt_group_t *group = channel->group;
  621. rmt_hal_context_t *hal = &group->hal;
  622. int channel_id = channel->channel_id;
  623. // acquire power manager lock
  624. if (channel->pm_lock) {
  625. ESP_RETURN_ON_ERROR(esp_pm_lock_acquire(channel->pm_lock), TAG, "acquire pm_lock failed");
  626. }
  627. portENTER_CRITICAL(&channel->spinlock);
  628. rmt_ll_tx_reset_pointer(hal->regs, channel_id);
  629. rmt_ll_tx_enable_loop(hal->regs, channel_id, false);
  630. #if SOC_RMT_SUPPORT_TX_LOOP_COUNT
  631. rmt_ll_tx_reset_loop_count(hal->regs, channel_id);
  632. rmt_ll_tx_enable_loop_count(hal->regs, channel_id, false);
  633. #endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT
  634. // trigger a quick trans done event by sending a EOF symbol, no signal should appear on the GPIO
  635. tx_chan->cur_trans = NULL;
  636. channel->hw_mem_base[0].val = 0;
  637. rmt_ll_tx_start(hal->regs, channel_id);
  638. portEXIT_CRITICAL(&channel->spinlock);
  639. // wait the RMT interrupt line goes active, we won't go into the ISR handler until we enable the `RMT_LL_EVENT_TX_DONE` interrupt
  640. while (!(rmt_ll_tx_get_interrupt_status_raw(hal->regs, channel_id) & RMT_LL_EVENT_TX_DONE(channel_id))) {}
  641. #if SOC_RMT_SUPPORT_DMA
  642. if (channel->dma_chan) {
  643. // enable the DMA access mode
  644. portENTER_CRITICAL(&channel->spinlock);
  645. rmt_ll_tx_enable_dma(hal->regs, channel_id, true);
  646. portEXIT_CRITICAL(&channel->spinlock);
  647. gdma_connect(channel->dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_RMT, 0));
  648. }
  649. #endif // SOC_RMT_SUPPORT_DMA
  650. channel->fsm = RMT_FSM_ENABLE;
  651. // enable channel interrupt, dispatch transactions in ISR (in case there're transaction descriptors in the queue, then we should start them)
  652. portENTER_CRITICAL(&group->spinlock);
  653. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), true);
  654. portEXIT_CRITICAL(&group->spinlock);
  655. return ESP_OK;
  656. }
  657. static esp_err_t rmt_tx_disable(rmt_channel_handle_t channel)
  658. {
  659. rmt_tx_channel_t *tx_chan = __containerof(channel, rmt_tx_channel_t, base);
  660. rmt_group_t *group = channel->group;
  661. rmt_hal_context_t *hal = &group->hal;
  662. int channel_id = channel->channel_id;
  663. portENTER_CRITICAL(&channel->spinlock);
  664. rmt_ll_tx_enable_loop(hal->regs, channel->channel_id, false);
  665. #if SOC_RMT_SUPPORT_TX_ASYNC_STOP
  666. rmt_ll_tx_stop(hal->regs, channel->channel_id);
  667. #endif
  668. portEXIT_CRITICAL(&channel->spinlock);
  669. portENTER_CRITICAL(&group->spinlock);
  670. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id), false);
  671. #if !SOC_RMT_SUPPORT_TX_ASYNC_STOP
  672. // we do a trick to stop the undergoing transmission
  673. // stop interrupt, insert EOF marker to the RMT memory, polling the trans_done event
  674. channel->hw_mem_base[0].val = 0;
  675. while (!(rmt_ll_tx_get_interrupt_status_raw(hal->regs, channel_id) & RMT_LL_EVENT_TX_DONE(channel_id))) {}
  676. #endif
  677. rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_MASK(channel_id));
  678. portEXIT_CRITICAL(&group->spinlock);
  679. #if SOC_RMT_SUPPORT_DMA
  680. if (channel->dma_chan) {
  681. gdma_stop(channel->dma_chan);
  682. gdma_disconnect(channel->dma_chan);
  683. // disable DMA access mode
  684. portENTER_CRITICAL(&channel->spinlock);
  685. rmt_ll_tx_enable_dma(hal->regs, channel_id, false);
  686. portEXIT_CRITICAL(&channel->spinlock);
  687. }
  688. #endif
  689. // recycle the interrupted transaction
  690. if (tx_chan->cur_trans) {
  691. xQueueSend(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &tx_chan->cur_trans, portMAX_DELAY);
  692. // reset corresponding encoder
  693. rmt_encoder_reset(tx_chan->cur_trans->encoder);
  694. }
  695. tx_chan->cur_trans = NULL;
  696. // release power manager lock
  697. if (channel->pm_lock) {
  698. ESP_RETURN_ON_ERROR(esp_pm_lock_release(channel->pm_lock), TAG, "release pm_lock failed");
  699. }
  700. channel->fsm = RMT_FSM_INIT;
  701. return ESP_OK;
  702. }
  703. static esp_err_t rmt_tx_modulate_carrier(rmt_channel_handle_t channel, const rmt_carrier_config_t *config)
  704. {
  705. rmt_group_t *group = channel->group;
  706. rmt_hal_context_t *hal = &group->hal;
  707. int group_id = group->group_id;
  708. int channel_id = channel->channel_id;
  709. uint32_t real_frequency = 0;
  710. if (config && config->frequency_hz) {
  711. // carrier module works base on group clock
  712. uint32_t total_ticks = group->resolution_hz / config->frequency_hz; // Note this division operation will lose precision
  713. uint32_t high_ticks = total_ticks * config->duty_cycle;
  714. uint32_t low_ticks = total_ticks - high_ticks;
  715. portENTER_CRITICAL(&channel->spinlock);
  716. rmt_ll_tx_set_carrier_level(hal->regs, channel_id, !config->flags.polarity_active_low);
  717. rmt_ll_tx_set_carrier_high_low_ticks(hal->regs, channel_id, high_ticks, low_ticks);
  718. #if SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY
  719. rmt_ll_tx_enable_carrier_always_on(hal->regs, channel_id, config->flags.always_on);
  720. #endif
  721. portEXIT_CRITICAL(&channel->spinlock);
  722. // save real carrier frequency
  723. real_frequency = group->resolution_hz / total_ticks;
  724. }
  725. // enable/disable carrier modulation
  726. portENTER_CRITICAL(&channel->spinlock);
  727. rmt_ll_tx_enable_carrier_modulation(hal->regs, channel_id, real_frequency > 0);
  728. portEXIT_CRITICAL(&channel->spinlock);
  729. if (real_frequency > 0) {
  730. ESP_LOGD(TAG, "enable carrier modulation for channel(%d,%d), freq=%"PRIu32"Hz", group_id, channel_id, real_frequency);
  731. } else {
  732. ESP_LOGD(TAG, "disable carrier modulation for channel(%d,%d)", group_id, channel_id);
  733. }
  734. return ESP_OK;
  735. }
  736. static bool IRAM_ATTR rmt_isr_handle_tx_threshold(rmt_tx_channel_t *tx_chan)
  737. {
  738. rmt_channel_t *channel = &tx_chan->base;
  739. rmt_group_t *group = channel->group;
  740. rmt_hal_context_t *hal = &group->hal;
  741. uint32_t channel_id = channel->channel_id;
  742. // continue pingpong transmission
  743. rmt_tx_trans_desc_t *t = tx_chan->cur_trans;
  744. size_t encoded_symbols = t->transmitted_symbol_num;
  745. // encoding finished, only need to send the EOF symbol
  746. if (t->flags.encoding_done) {
  747. rmt_tx_mark_eof(tx_chan);
  748. encoded_symbols += 1;
  749. } else {
  750. encoded_symbols += rmt_encode_check_result(tx_chan, t);
  751. }
  752. t->transmitted_symbol_num = encoded_symbols;
  753. tx_chan->mem_end = tx_chan->ping_pong_symbols * 3 - tx_chan->mem_end; // mem_end equals to either ping_pong_symbols or ping_pong_symbols*2
  754. rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_THRES(channel_id));
  755. return false;
  756. }
  757. static bool IRAM_ATTR rmt_isr_handle_tx_done(rmt_tx_channel_t *tx_chan)
  758. {
  759. rmt_channel_t *channel = &tx_chan->base;
  760. rmt_group_t *group = channel->group;
  761. rmt_hal_context_t *hal = &group->hal;
  762. uint32_t channel_id = channel->channel_id;
  763. BaseType_t awoken = pdFALSE;
  764. rmt_tx_trans_desc_t *trans_desc = NULL;
  765. bool need_yield = false;
  766. portENTER_CRITICAL_ISR(&group->spinlock);
  767. // disable interrupt temporarily, re-enable it when there is transaction unhandled in the queue
  768. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), false);
  769. portEXIT_CRITICAL_ISR(&group->spinlock);
  770. trans_desc = tx_chan->cur_trans;
  771. // process finished transaction
  772. if (trans_desc) {
  773. // don't care of the tx done event for any undergoing loop transaction
  774. // mostly it's triggered when a loop transmission is undergoing and user calls `rmt_transmit()` where tx done interrupt is generated by accident
  775. if (trans_desc->loop_count != 0) {
  776. rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id));
  777. return need_yield;
  778. }
  779. if (tx_chan->on_trans_done) {
  780. rmt_tx_done_event_data_t edata = {
  781. .num_symbols = trans_desc->transmitted_symbol_num,
  782. };
  783. if (tx_chan->on_trans_done(channel, &edata, tx_chan->user_data)) {
  784. need_yield = true;
  785. }
  786. }
  787. // move transaction to done_queue
  788. xQueueSendFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &trans_desc, &awoken);
  789. if (awoken == pdTRUE) {
  790. need_yield = true;
  791. }
  792. }
  793. // fetch new transaction description from trans_queue
  794. if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) {
  795. // sanity check
  796. assert(trans_desc);
  797. // update current transaction
  798. tx_chan->cur_trans = trans_desc;
  799. portENTER_CRITICAL_ISR(&group->spinlock);
  800. // only clear the trans done status when we're sure there still remains transaction to handle
  801. rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id));
  802. // enable interrupt again, because the new transaction can trigger another trans done event
  803. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), trans_desc->loop_count == 0);
  804. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), trans_desc->loop_count > 0);
  805. portEXIT_CRITICAL_ISR(&group->spinlock);
  806. // begin a new transaction
  807. rmt_tx_do_transaction(tx_chan, trans_desc);
  808. } else { // No transactions left in the queue
  809. // don't clear interrupt status, so when next time user push new transaction to the queue and call esp_intr_enable,
  810. // we can go to this ISR handler again
  811. tx_chan->cur_trans = NULL;
  812. }
  813. if (awoken == pdTRUE) {
  814. need_yield = true;
  815. }
  816. return need_yield;
  817. }
  818. #if SOC_RMT_SUPPORT_TX_LOOP_COUNT
  819. static bool IRAM_ATTR rmt_isr_handle_tx_loop_end(rmt_tx_channel_t *tx_chan)
  820. {
  821. rmt_channel_t *channel = &tx_chan->base;
  822. rmt_group_t *group = channel->group;
  823. rmt_hal_context_t *hal = &group->hal;
  824. uint32_t channel_id = channel->channel_id;
  825. BaseType_t awoken = pdFALSE;
  826. rmt_tx_trans_desc_t *trans_desc = NULL;
  827. bool need_yield = false;
  828. trans_desc = tx_chan->cur_trans;
  829. if (trans_desc) {
  830. #if !SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP
  831. portENTER_CRITICAL_ISR(&channel->spinlock);
  832. // This is a workaround for chips that don't support auto stop
  833. // Although we stop the transaction immediately in ISR handler, it's still possible that some rmt symbols have sneaked out
  834. rmt_ll_tx_stop(hal->regs, channel_id);
  835. portEXIT_CRITICAL_ISR(&channel->spinlock);
  836. #endif // SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP
  837. // continue unfinished loop transaction
  838. if (trans_desc->remain_loop_count) {
  839. uint32_t this_loop_count = MIN(trans_desc->remain_loop_count, RMT_LL_MAX_LOOP_COUNT_PER_BATCH);
  840. trans_desc->remain_loop_count -= this_loop_count;
  841. rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id));
  842. portENTER_CRITICAL_ISR(&channel->spinlock);
  843. rmt_ll_tx_set_loop_count(hal->regs, channel_id, this_loop_count);
  844. rmt_ll_tx_reset_pointer(hal->regs, channel_id);
  845. // continue the loop transmission, don't need to fill the RMT symbols again, just restart the engine
  846. rmt_ll_tx_start(hal->regs, channel_id);
  847. portEXIT_CRITICAL_ISR(&channel->spinlock);
  848. return need_yield;
  849. } else {
  850. if (tx_chan->on_trans_done) {
  851. rmt_tx_done_event_data_t edata = {
  852. .num_symbols = trans_desc->transmitted_symbol_num,
  853. };
  854. if (tx_chan->on_trans_done(channel, &edata, tx_chan->user_data)) {
  855. need_yield = true;
  856. }
  857. }
  858. // move transaction to done_queue
  859. xQueueSendFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_COMPLETE], &trans_desc, &awoken);
  860. if (awoken == pdTRUE) {
  861. need_yield = true;
  862. }
  863. }
  864. }
  865. // trans_done and loop_done should be considered as one "transmission complete"
  866. // but sometimes the trans done event might also be triggered together with loop done event, by accident, so clear it first
  867. rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id));
  868. portENTER_CRITICAL_ISR(&group->spinlock);
  869. // disable interrupt temporarily, re-enable it when there is transaction unhandled in the queue
  870. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), false);
  871. portEXIT_CRITICAL_ISR(&group->spinlock);
  872. // fetch new transaction description from trans_queue
  873. if (xQueueReceiveFromISR(tx_chan->trans_queues[RMT_TX_QUEUE_PROGRESS], &trans_desc, &awoken) == pdTRUE) {
  874. // sanity check
  875. assert(trans_desc);
  876. tx_chan->cur_trans = trans_desc;
  877. // clear the loop end status when we're sure there still remains transaction to handle
  878. rmt_ll_clear_interrupt_status(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id));
  879. portENTER_CRITICAL_ISR(&group->spinlock);
  880. // enable interrupt again, because the new transaction can trigger new trans done event
  881. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_DONE(channel_id), trans_desc->loop_count == 0);
  882. rmt_ll_enable_interrupt(hal->regs, RMT_LL_EVENT_TX_LOOP_END(channel_id), trans_desc->loop_count > 0);
  883. portEXIT_CRITICAL_ISR(&group->spinlock);
  884. // begin a new transaction
  885. rmt_tx_do_transaction(tx_chan, trans_desc);
  886. } else { // No transactions left in the queue
  887. // don't clear interrupt status, so when next time user push new transaction to the queue and call esp_intr_enable,
  888. // we can go into ISR handler again
  889. tx_chan->cur_trans = NULL;
  890. }
  891. if (awoken == pdTRUE) {
  892. need_yield = true;
  893. }
  894. return need_yield;
  895. }
  896. #endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT
  897. static void IRAM_ATTR rmt_tx_default_isr(void *args)
  898. {
  899. rmt_tx_channel_t *tx_chan = (rmt_tx_channel_t *)args;
  900. rmt_channel_t *channel = &tx_chan->base;
  901. rmt_group_t *group = channel->group;
  902. rmt_hal_context_t *hal = &group->hal;
  903. uint32_t channel_id = channel->channel_id;
  904. bool need_yield = false;
  905. uint32_t status = rmt_ll_tx_get_interrupt_status(hal->regs, channel_id);
  906. // Tx threshold interrupt
  907. if (status & RMT_LL_EVENT_TX_THRES(channel_id)) {
  908. if (rmt_isr_handle_tx_threshold(tx_chan)) {
  909. need_yield = true;
  910. }
  911. }
  912. // Tx end interrupt
  913. if (status & RMT_LL_EVENT_TX_DONE(channel_id)) {
  914. if (rmt_isr_handle_tx_done(tx_chan)) {
  915. need_yield = true;
  916. }
  917. }
  918. #if SOC_RMT_SUPPORT_TX_LOOP_COUNT
  919. // Tx loop end interrupt
  920. if (status & RMT_LL_EVENT_TX_LOOP_END(channel_id)) {
  921. if (rmt_isr_handle_tx_loop_end(tx_chan)) {
  922. need_yield = true;
  923. }
  924. }
  925. #endif // SOC_RMT_SUPPORT_TX_LOOP_COUNT
  926. if (need_yield) {
  927. portYIELD_FROM_ISR();
  928. }
  929. }
  930. #if SOC_RMT_SUPPORT_DMA
  931. static bool IRAM_ATTR rmt_dma_tx_eof_cb(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
  932. {
  933. rmt_tx_channel_t *tx_chan = (rmt_tx_channel_t *)user_data;
  934. dma_descriptor_t *eof_desc = (dma_descriptor_t *)event_data->tx_eof_desc_addr;
  935. // if the DMA descriptor link is still a ring (i.e. hasn't broken down by `rmt_tx_mark_eof()`), then we treat it as a valid ping-pong event
  936. if (eof_desc->next && eof_desc->next->next) {
  937. // continue pingpong transmission
  938. rmt_tx_trans_desc_t *t = tx_chan->cur_trans;
  939. size_t encoded_symbols = t->transmitted_symbol_num;
  940. if (t->flags.encoding_done) {
  941. rmt_tx_mark_eof(tx_chan);
  942. encoded_symbols += 1;
  943. } else {
  944. encoded_symbols += rmt_encode_check_result(tx_chan, t);
  945. }
  946. t->transmitted_symbol_num = encoded_symbols;
  947. tx_chan->mem_end = tx_chan->ping_pong_symbols * 3 - tx_chan->mem_end; // mem_end equals to either ping_pong_symbols or ping_pong_symbols*2
  948. // tell DMA that we have a new descriptor attached
  949. gdma_append(dma_chan);
  950. }
  951. return false;
  952. }
  953. #endif // SOC_RMT_SUPPORT_DMA