1 // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 #ifndef _DRIVER_RMT_CTRL_H_
16 #define _DRIVER_RMT_CTRL_H_
18 #include "soc/rmt_reg.h"
19 #include "soc/dport_reg.h"
20 #include "soc/rmt_struct.h"
21 #include "freertos/FreeRTOS.h"
22 #include "freertos/semphr.h"
23 #include "freertos/xtensa_api.h"
24 #include "freertos/ringbuf.h"
25 #include "driver/gpio.h"
26 #include "driver/periph_ctrl.h"
32 #define RMT_MEM_BLOCK_BYTE_NUM (256)
33 #define RMT_MEM_ITEM_NUM (RMT_MEM_BLOCK_BYTE_NUM/4)
36 RMT_CHANNEL_0=0, /*!< RMT Channel0 */
37 RMT_CHANNEL_1, /*!< RMT Channel1 */
38 RMT_CHANNEL_2, /*!< RMT Channel2 */
39 RMT_CHANNEL_3, /*!< RMT Channel3 */
40 RMT_CHANNEL_4, /*!< RMT Channel4 */
41 RMT_CHANNEL_5, /*!< RMT Channel5 */
42 RMT_CHANNEL_6, /*!< RMT Channel6 */
43 RMT_CHANNEL_7, /*!< RMT Channel7 */
48 RMT_MEM_OWNER_TX = 0, /*!< RMT RX mode, RMT transmitter owns the memory block*/
49 RMT_MEM_OWNER_RX = 1, /*!< RMT RX mode, RMT receiver owns the memory block*/
54 RMT_BASECLK_REF = 0, /*!< RMT source clock system reference tick, 1MHz by default(Not supported in this version) */
55 RMT_BASECLK_APB, /*!< RMT source clock is APB CLK, 80Mhz by default */
60 RMT_DATA_MODE_FIFO = 0, /*<! RMT memory access in FIFO mode */
61 RMT_DATA_MODE_MEM = 1, /*<! RMT memory access in memory mode */
66 RMT_MODE_TX=0, /*!< RMT TX mode */
67 RMT_MODE_RX, /*!< RMT RX mode */
72 RMT_IDLE_LEVEL_LOW=0, /*!< RMT TX idle level: low Level */
73 RMT_IDLE_LEVEL_HIGH, /*!< RMT TX idle level: high Level */
78 RMT_CARRIER_LEVEL_LOW=0, /*!< RMT carrier wave is modulated for low Level output */
79 RMT_CARRIER_LEVEL_HIGH, /*!< RMT carrier wave is modulated for high Level output */
81 } rmt_carrier_level_t;
84 * @brief Data struct of RMT TX configure parameters
87 bool loop_en; /*!< RMT loop output mode*/
88 uint32_t carrier_freq_hz; /*!< RMT carrier frequency */
89 uint8_t carrier_duty_percent; /*!< RMT carrier duty (%) */
90 rmt_carrier_level_t carrier_level; /*!< RMT carrier level */
91 bool carrier_en; /*!< RMT carrier enable */
92 rmt_idle_level_t idle_level; /*!< RMT idle level */
93 bool idle_output_en; /*!< RMT idle level output enable*/
97 * @brief Data struct of RMT RX configure parameters
100 bool filter_en; /*!< RMT receiver filer enable*/
101 uint8_t filter_ticks_thresh; /*!< RMT filter tick number */
102 uint16_t idle_threshold; /*!< RMT RX idle threshold */
106 * @brief Data struct of RMT configure parameters
109 rmt_mode_t rmt_mode; /*!< RMT mode: transmitter or receiver */
110 rmt_channel_t channel; /*!< RMT channel */
111 uint8_t clk_div; /*!< RMT channel counter divider */
112 gpio_num_t gpio_num; /*!< RMT GPIO number */
113 uint8_t mem_block_num; /*!< RMT memory block number */
115 rmt_tx_config_t tx_config; /*!< RMT TX parameter */
116 rmt_rx_config_t rx_config; /*!< RMT RX parameter */
120 typedef intr_handle_t rmt_isr_handle_t;
123 * @brief Set RMT clock divider, channel clock is divided from source clock.
125 * @param channel RMT channel (0-7)
127 * @param div_cnt RMT counter clock divider
130 * - ESP_ERR_INVALID_ARG Parameter error
133 esp_err_t rmt_set_clk_div(rmt_channel_t channel, uint8_t div_cnt);
136 * @brief Get RMT clock divider, channel clock is divided from source clock.
138 * @param channel RMT channel (0-7)
140 * @param div_cnt pointer to accept RMT counter divider
143 * - ESP_ERR_INVALID_ARG Parameter error
146 esp_err_t rmt_get_clk_div(rmt_channel_t channel, uint8_t* div_cnt);
149 * @brief Set RMT RX idle threshold value
151 * In receive mode, when no edge is detected on the input signal
152 * for longer than idle_thres channel clock cycles,
153 * the receive process is finished.
155 * @param channel RMT channel (0-7)
157 * @param thresh RMT RX idle threshold
160 * - ESP_ERR_INVALID_ARG Parameter error
163 esp_err_t rmt_set_rx_idle_thresh(rmt_channel_t channel, uint16_t thresh);
166 * @brief Get RMT idle threshold value.
168 * In receive mode, when no edge is detected on the input signal
169 * for longer than idle_thres channel clock cycles,
170 * the receive process is finished.
172 * @param channel RMT channel (0-7)
174 * @param thresh pointer to accept RMT RX idle threshold value
177 * - ESP_ERR_INVALID_ARG Parameter error
180 esp_err_t rmt_get_rx_idle_thresh(rmt_channel_t channel, uint16_t *thresh);
183 * @brief Set RMT memory block number for RMT channel
185 * This function is used to configure the amount of memory blocks allocated to channel n
186 * The 8 channels share a 512x32-bit RAM block which can be read and written
187 * by the processor cores over the APB bus, as well as read by the transmitters
188 * and written by the receivers.
189 * The RAM address range for channel n is start_addr_CHn to end_addr_CHn, which are defined by:
190 * Memory block start address is RMT_CHANNEL_MEM(n) (in soc/rmt_reg.h),
191 * that is, start_addr_chn = RMT base address + 0x800 + 64 ∗ 4 ∗ n, and
192 * end_addr_chn = RMT base address + 0x800 + 64 ∗ 4 ∗ n + 64 ∗ 4 ∗ RMT_MEM_SIZE_CHn mod 512 ∗ 4
194 * If memory block number of one channel is set to a value greater than 1, this channel will occupy the memory
195 * block of the next channel.
196 * Channel0 can use at most 8 blocks of memory, accordingly channel7 can only use one memory block.
198 * @param channel RMT channel (0-7)
200 * @param rmt_mem_num RMT RX memory block number, one block has 64 * 32 bits.
203 * - ESP_ERR_INVALID_ARG Parameter error
206 esp_err_t rmt_set_mem_block_num(rmt_channel_t channel, uint8_t rmt_mem_num);
209 * @brief Get RMT memory block number
211 * @param channel RMT channel (0-7)
213 * @param rmt_mem_num Pointer to accept RMT RX memory block number
216 * - ESP_ERR_INVALID_ARG Parameter error
219 esp_err_t rmt_get_mem_block_num(rmt_channel_t channel, uint8_t* rmt_mem_num);
222 * @brief Configure RMT carrier for TX signal.
224 * Set different values for carrier_high and carrier_low to set different frequency of carrier.
225 * The unit of carrier_high/low is the source clock tick, not the divided channel counter clock.
227 * @param channel RMT channel (0-7)
229 * @param carrier_en Whether to enable output carrier.
231 * @param high_level High level duration of carrier
233 * @param low_level Low level duration of carrier.
235 * @param carrier_level Configure the way carrier wave is modulated for channel0-7.
237 * 1'b1:transmit on low output level
239 * 1'b0:transmit on high output level
242 * - ESP_ERR_INVALID_ARG Parameter error
245 esp_err_t rmt_set_tx_carrier(rmt_channel_t channel, bool carrier_en, uint16_t high_level, uint16_t low_level, rmt_carrier_level_t carrier_level);
248 * @brief Set RMT memory in low power mode.
250 * Reduce power consumed by memory. 1:memory is in low power state.
252 * @param channel RMT channel (0-7)
254 * @param pd_en RMT memory low power enable.
257 * - ESP_ERR_INVALID_ARG Parameter error
260 esp_err_t rmt_set_mem_pd(rmt_channel_t channel, bool pd_en);
263 * @brief Get RMT memory low power mode.
265 * @param channel RMT channel (0-7)
267 * @param pd_en Pointer to accept RMT memory low power mode.
270 * - ESP_ERR_INVALID_ARG Parameter error
273 esp_err_t rmt_get_mem_pd(rmt_channel_t channel, bool* pd_en);
276 * @brief Set RMT start sending data from memory.
278 * @param channel RMT channel (0-7)
280 * @param tx_idx_rst Set true to reset memory index for TX.
281 * Otherwise, transmitter will continue sending from the last index in memory.
284 * - ESP_ERR_INVALID_ARG Parameter error
287 esp_err_t rmt_tx_start(rmt_channel_t channel, bool tx_idx_rst);
290 * @brief Set RMT stop sending.
292 * @param channel RMT channel (0-7)
295 * - ESP_ERR_INVALID_ARG Parameter error
298 esp_err_t rmt_tx_stop(rmt_channel_t channel);
301 * @brief Set RMT start receiving data.
303 * @param channel RMT channel (0-7)
305 * @param rx_idx_rst Set true to reset memory index for receiver.
306 * Otherwise, receiver will continue receiving data to the last index in memory.
309 * - ESP_ERR_INVALID_ARG Parameter error
312 esp_err_t rmt_rx_start(rmt_channel_t channel, bool rx_idx_rst);
315 * @brief Set RMT stop receiving data.
317 * @param channel RMT channel (0-7)
320 * - ESP_ERR_INVALID_ARG Parameter error
323 esp_err_t rmt_rx_stop(rmt_channel_t channel);
326 * @brief Reset RMT TX/RX memory index.
328 * @param channel RMT channel (0-7)
331 * - ESP_ERR_INVALID_ARG Parameter error
334 esp_err_t rmt_memory_rw_rst(rmt_channel_t channel);
337 * @brief Set RMT memory owner.
339 * @param channel RMT channel (0-7)
341 * @param owner To set when the transmitter or receiver can process the memory of channel.
344 * - ESP_ERR_INVALID_ARG Parameter error
347 esp_err_t rmt_set_memory_owner(rmt_channel_t channel, rmt_mem_owner_t owner);
350 * @brief Get RMT memory owner.
352 * @param channel RMT channel (0-7)
354 * @param owner Pointer to get memory owner.
357 * - ESP_ERR_INVALID_ARG Parameter error
360 esp_err_t rmt_get_memory_owner(rmt_channel_t channel, rmt_mem_owner_t* owner);
363 * @brief Set RMT tx loop mode.
365 * @param channel RMT channel (0-7)
367 * @param loop_en To enable RMT transmitter loop sending mode.
369 * If set true, transmitter will continue sending from the first data
370 * to the last data in channel0-7 again and again.
373 * - ESP_ERR_INVALID_ARG Parameter error
376 esp_err_t rmt_set_tx_loop_mode(rmt_channel_t channel, bool loop_en);
379 * @brief Get RMT tx loop mode.
381 * @param channel RMT channel (0-7)
383 * @param loop_en Pointer to accept RMT transmitter loop sending mode.
386 * - ESP_ERR_INVALID_ARG Parameter error
389 esp_err_t rmt_get_tx_loop_mode(rmt_channel_t channel, bool* loop_en);
392 * @brief Set RMT RX filter.
394 * In receive mode, channel0-7 will ignore input pulse when the pulse width is smaller than threshold.
395 * Counted in source clock, not divided counter clock.
397 * @param channel RMT channel (0-7)
399 * @param rx_filter_en To enable RMT receiver filter.
401 * @param thresh Threshold of pulse width for receiver.
404 * - ESP_ERR_INVALID_ARG Parameter error
407 esp_err_t rmt_set_rx_filter(rmt_channel_t channel, bool rx_filter_en, uint8_t thresh);
410 * @brief Set RMT source clock
412 * RMT module has two source clock:
413 * 1. APB clock which is 80Mhz
414 * 2. REF tick clock, which would be 1Mhz( not supported in this version).
416 * @param channel RMT channel (0-7)
418 * @param base_clk To choose source clock for RMT module.
421 * - ESP_ERR_INVALID_ARG Parameter error
424 esp_err_t rmt_set_source_clk(rmt_channel_t channel, rmt_source_clk_t base_clk);
427 * @brief Get RMT source clock
429 * RMT module has two source clock:
430 * 1. APB clock which is 80Mhz
431 * 2. REF tick clock, which would be 1Mhz( not supported in this version).
433 * @param channel RMT channel (0-7)
435 * @param src_clk Pointer to accept source clock for RMT module.
438 * - ESP_ERR_INVALID_ARG Parameter error
441 esp_err_t rmt_get_source_clk(rmt_channel_t channel, rmt_source_clk_t* src_clk);
444 * @brief Set RMT idle output level for transmitter
446 * @param channel RMT channel (0-7)
448 * @param idle_out_en To enable idle level output.
450 * @param level To set the output signal's level for channel0-7 in idle state.
453 * - ESP_ERR_INVALID_ARG Parameter error
456 esp_err_t rmt_set_idle_level(rmt_channel_t channel, bool idle_out_en, rmt_idle_level_t level);
459 * @brief Get RMT status
461 * @param channel RMT channel (0-7)
463 * @param status Pointer to accept channel status.
466 * - ESP_ERR_INVALID_ARG Parameter error
469 esp_err_t rmt_get_status(rmt_channel_t channel, uint32_t* status);
472 * @brief Set mask value to RMT interrupt enable register.
474 * @param mask Bit mask to set to the register
477 void rmt_set_intr_enable_mask(uint32_t mask);
480 * @brief Clear mask value to RMT interrupt enable register.
482 * @param mask Bit mask to clear the register
485 void rmt_clr_intr_enable_mask(uint32_t mask);
488 * @brief Set RMT RX interrupt enable
490 * @param channel RMT channel (0 - 7)
492 * @param en enable or disable RX interrupt.
495 * - ESP_ERR_INVALID_ARG Parameter error
498 esp_err_t rmt_set_rx_intr_en(rmt_channel_t channel, bool en);
501 * @brief Set RMT RX error interrupt enable
503 * @param channel RMT channel (0 - 7)
505 * @param en enable or disable RX err interrupt.
508 * - ESP_ERR_INVALID_ARG Parameter error
511 esp_err_t rmt_set_err_intr_en(rmt_channel_t channel, bool en);
514 * @brief Set RMT TX interrupt enable
516 * @param channel RMT channel (0 - 7)
518 * @param en enable or disable TX interrupt.
521 * - ESP_ERR_INVALID_ARG Parameter error
524 esp_err_t rmt_set_tx_intr_en(rmt_channel_t channel, bool en);
527 * @brief Set RMT TX threshold event interrupt enable
529 * Causes an interrupt when a threshold number of items have been transmitted.
531 * @param channel RMT channel (0 - 7)
533 * @param en enable or disable TX event interrupt.
535 * @param evt_thresh RMT event interrupt threshold value
538 * - ESP_ERR_INVALID_ARG Parameter error
541 esp_err_t rmt_set_tx_thr_intr_en(rmt_channel_t channel, bool en, uint16_t evt_thresh);
544 * @brief Set RMT pins
546 * @param channel RMT channel (0 - 7)
548 * @param mode TX or RX mode for RMT
550 * @param gpio_num GPIO number to transmit or receive the signal.
553 * - ESP_ERR_INVALID_ARG Parameter error
556 esp_err_t rmt_set_pin(rmt_channel_t channel, rmt_mode_t mode, gpio_num_t gpio_num);
559 * @brief Configure RMT parameters
561 * @param rmt_param RMT parameter structor
564 * - ESP_ERR_INVALID_ARG Parameter error
567 esp_err_t rmt_config(rmt_config_t* rmt_param);
570 * @brief register RMT interrupt handler, the handler is an ISR.
572 * The handler will be attached to the same CPU core that this function is running on.
573 * @note If you already called rmt_driver_install to use system RMT driver,
574 * please do not register ISR handler again.
576 * @param fn Interrupt handler function.
577 * @param arg Parameter for handler function
578 * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
579 * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
580 * @param handle If non-zero, a handle to later clean up the ISR gets stored here.
584 * - ESP_ERR_INVALID_ARG Function pointer error.
585 * - ESP_FAIL System driver installed, can not register ISR handler for RMT
587 esp_err_t rmt_isr_register(void (* fn)(void* ), void * arg, int intr_alloc_flags, rmt_isr_handle_t *handle);
590 * @brief Deregister previously registered RMT interrupt handler
592 * @param handle Handle obtained from rmt_isr_register
596 * - ESP_ERR_INVALID_ARG Handle invalid
598 esp_err_t rmt_isr_deregister(rmt_isr_handle_t handle);
601 * @brief Fill memory data of channel with given RMT items.
603 * @param channel RMT channel (0 - 7)
605 * @param item Pointer of items.
607 * @param item_num RMT sending items number.
609 * @param mem_offset Index offset of memory.
612 * - ESP_ERR_INVALID_ARG Parameter error
615 esp_err_t rmt_fill_tx_items(rmt_channel_t channel, rmt_item32_t* item, uint16_t item_num, uint16_t mem_offset);
618 * @brief Initialize RMT driver
620 * @param channel RMT channel (0 - 7)
622 * @param rx_buf_size Size of RMT RX ringbuffer. Can be 0 if the RX ringbuffer is not used.
624 * @param intr_alloc_flags Flags for the RMT driver interrupt handler. Pass 0 for default flags. See esp_intr_alloc.h for details.
627 * - ESP_ERR_INVALID_STATE Driver is already installed, call rmt_driver_uninstall first.
628 * - ESP_ERR_NO_MEM Memory allocation failure
629 * - ESP_ERR_INVALID_ARG Parameter error
632 esp_err_t rmt_driver_install(rmt_channel_t channel, size_t rx_buf_size, int intr_alloc_flags);
635 * @brief Uninstall RMT driver.
637 * @param channel RMT channel (0 - 7)
640 * - ESP_ERR_INVALID_ARG Parameter error
643 esp_err_t rmt_driver_uninstall(rmt_channel_t channel);
646 * @brief RMT send waveform from rmt_item array.
648 * This API allows user to send waveform with any length.
650 * @param channel RMT channel (0 - 7)
652 * @param rmt_item head point of RMT items array.
654 * @param item_num RMT data item number.
656 * @param wait_tx_done If set 1, it will block the task and wait for sending done.
658 * If set 0, it will not wait and return immediately.
661 * This function will not copy data, instead, it will point to the original items,
662 * and send the waveform items.
663 * If wait_tx_done is set to true, this function will block and will not return until
664 * all items have been sent out.
665 * If wait_tx_done is set to false, this function will return immediately, and the driver
666 * interrupt will continue sending the items. We must make sure the item data will not be
667 * damaged when the driver is still sending items in driver interrupt.
670 * - ESP_ERR_INVALID_ARG Parameter error
673 esp_err_t rmt_write_items(rmt_channel_t channel, rmt_item32_t* rmt_item, int item_num, bool wait_tx_done);
676 * @brief Wait RMT TX finished.
678 * @param channel RMT channel (0 - 7)
681 * - ESP_ERR_INVALID_ARG Parameter error
684 esp_err_t rmt_wait_tx_done(rmt_channel_t channel);
687 * @brief Get ringbuffer from UART.
689 * Users can get the RMT RX ringbuffer handler, and process the RX data.
691 * @param channel RMT channel (0 - 7)
693 * @param buf_handler Pointer to buffer handler to accept RX ringbuffer handler.
696 * - ESP_ERR_INVALID_ARG Parameter error
699 esp_err_t rmt_get_ringbuf_handler(rmt_channel_t channel, RingbufHandle_t* buf_handler);
701 /***************************EXAMPLE**********************************
704 * You can also refer to example/09_rmt_nec_tx_rx to have more information about how to use RMT module.
706 * ----------------EXAMPLE OF RMT SETTING ---------------------
709 * //enable RMT module, or you can not set any register of it.
710 * //this will be done in rmt_config API.
711 * periph_module_enable(PERIPH_RMT_MODULE);
715 * //2. set RMT transmitter
718 * rmt_config_t rmt_tx;
719 * rmt_tx.channel = 0;
720 * rmt_tx.gpio_num = 16;
721 * rmt_tx.mem_block_num = 1;
722 * rmt_tx.clk_div = 100;
723 * rmt_tx.tx_config.loop_en = false;
724 * rmt_tx.tx_config.carrier_duty_percent = 50;
725 * rmt_tx.tx_config.carrier_freq_hz = 38000;
726 * rmt_tx.tx_config.carrier_level = 1;
727 * rmt_tx.tx_config.carrier_en = RMT_TX_CARRIER_EN;
728 * rmt_tx.tx_config.idle_level = 0;
729 * rmt_tx.tx_config.idle_output_en = true;
730 * rmt_tx.rmt_mode = 0;
731 * rmt_config(&rmt_tx);
733 * //install system RMT driver, disable rx ringbuffer for transmitter.
734 * rmt_driver_install(rmt_tx.channel, 0, 0);
739 * //3. set RMT receiver
742 * rmt_config_t rmt_rx;
743 * rmt_rx.channel = 1;
744 * rmt_rx.gpio_num = 19;
745 * rmt_rx.clk_div = 100;
746 * rmt_rx.mem_block_num = 1;
747 * rmt_rx.rmt_mode = RMT_MODE_RX;
748 * rmt_rx.rx_config.filter_en = true;
749 * rmt_rx.rx_config.filter_ticks_thresh = 100;
750 * rmt_rx.rx_config.idle_threshold = 0xffff;
751 * rmt_config(&rmt_rx);
753 * //install system RMT driver.
754 * rmt_driver_install(rmt_rx.channel, 1000, 0);
757 * ----------------EXAMPLE OF RMT INTERRUPT ------------------
760 * rmt_isr_register(rmt_isr, NULL, 0); //hook the ISR handler for RMT interrupt
763 * 0. If you have called rmt_driver_install, you don't need to set ISR handler any more.
765 * ----------------EXAMPLE OF INTERRUPT HANDLER ---------------
767 * #include "esp_attr.h"
768 * void IRAM_ATTR rmt_isr_handler(void* arg)
770 * //read RMT interrupt status.
771 * uint32_t intr_st = RMT.int_st.val;
773 * //you will find which channels have triggered fade_end interrupt here,
774 * //then, you can post some event to RTOS queue to process the event.
775 * //later we will add a queue in the driver code.
777 * //clear RMT interrupt status.
778 * RMT.int_clr.val = intr_st;
782 *--------------------------END OF EXAMPLE --------------------------
793 #endif /* _DRIVER_RMT_CTRL_H_ */