mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
f6c90adb42
RMT write should be non-blocking to wait the correct time for sending the repeat frame
120 lines
4.2 KiB
C
120 lines
4.2 KiB
C
/* IR protocols example
|
|
|
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
|
|
|
Unless required by applicable law or agreed to in writing, this
|
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
CONDITIONS OF ANY KIND, either express or implied.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "sdkconfig.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "esp_log.h"
|
|
#include "driver/rmt.h"
|
|
#include "ir_tools.h"
|
|
|
|
static const char *TAG = "example";
|
|
|
|
static rmt_channel_t example_tx_channel = RMT_CHANNEL_0;
|
|
static rmt_channel_t example_rx_channel = RMT_CHANNEL_1;
|
|
|
|
/**
|
|
* @brief RMT Receive Task
|
|
*
|
|
*/
|
|
static void example_ir_rx_task(void *arg)
|
|
{
|
|
uint32_t addr = 0;
|
|
uint32_t cmd = 0;
|
|
uint32_t length = 0;
|
|
bool repeat = false;
|
|
RingbufHandle_t rb = NULL;
|
|
rmt_item32_t *items = NULL;
|
|
|
|
rmt_config_t rmt_rx_config = RMT_DEFAULT_CONFIG_RX(CONFIG_EXAMPLE_RMT_RX_GPIO, example_rx_channel);
|
|
rmt_config(&rmt_rx_config);
|
|
rmt_driver_install(example_rx_channel, 1000, 0);
|
|
ir_parser_config_t ir_parser_config = IR_PARSER_DEFAULT_CONFIG((ir_dev_t)example_rx_channel);
|
|
ir_parser_config.flags |= IR_TOOLS_FLAGS_PROTO_EXT; // Using extended IR protocols (both NEC and RC5 have extended version)
|
|
ir_parser_t *ir_parser = NULL;
|
|
#if CONFIG_EXAMPLE_IR_PROTOCOL_NEC
|
|
ir_parser = ir_parser_rmt_new_nec(&ir_parser_config);
|
|
#elif CONFIG_EXAMPLE_IR_PROTOCOL_RC5
|
|
ir_parser = ir_parser_rmt_new_rc5(&ir_parser_config);
|
|
#endif
|
|
|
|
//get RMT RX ringbuffer
|
|
rmt_get_ringbuf_handle(example_rx_channel, &rb);
|
|
// Start receive
|
|
rmt_rx_start(example_rx_channel, true);
|
|
while (rb) {
|
|
items = (rmt_item32_t *) xRingbufferReceive(rb, &length, 1000);
|
|
if (items) {
|
|
length /= 4; // one RMT = 4 Bytes
|
|
if (ir_parser->input(ir_parser, items, length) == ESP_OK) {
|
|
if (ir_parser->get_scan_code(ir_parser, &addr, &cmd, &repeat) == ESP_OK) {
|
|
ESP_LOGI(TAG, "Scan Code %s --- addr: 0x%04x cmd: 0x%04x", repeat ? "(repeat)" : "", addr, cmd);
|
|
}
|
|
}
|
|
//after parsing the data, return spaces to ringbuffer.
|
|
vRingbufferReturnItem(rb, (void *) items);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
ir_parser->del(ir_parser);
|
|
rmt_driver_uninstall(example_rx_channel);
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
/**
|
|
* @brief RMT Transmit Task
|
|
*
|
|
*/
|
|
static void example_ir_tx_task(void *arg)
|
|
{
|
|
uint32_t addr = 0x10;
|
|
uint32_t cmd = 0x20;
|
|
rmt_item32_t *items = NULL;
|
|
uint32_t length = 0;
|
|
ir_builder_t *ir_builder = NULL;
|
|
|
|
rmt_config_t rmt_tx_config = RMT_DEFAULT_CONFIG_TX(CONFIG_EXAMPLE_RMT_TX_GPIO, example_tx_channel);
|
|
rmt_tx_config.tx_config.carrier_en = true;
|
|
rmt_config(&rmt_tx_config);
|
|
rmt_driver_install(example_tx_channel, 0, 0);
|
|
ir_builder_config_t ir_builder_config = IR_BUILDER_DEFAULT_CONFIG((ir_dev_t)example_tx_channel);
|
|
ir_builder_config.flags |= IR_TOOLS_FLAGS_PROTO_EXT; // Using extended IR protocols (both NEC and RC5 have extended version)
|
|
#if CONFIG_EXAMPLE_IR_PROTOCOL_NEC
|
|
ir_builder = ir_builder_rmt_new_nec(&ir_builder_config);
|
|
#elif CONFIG_EXAMPLE_IR_PROTOCOL_RC5
|
|
ir_builder = ir_builder_rmt_new_rc5(&ir_builder_config);
|
|
#endif
|
|
while (1) {
|
|
vTaskDelay(pdMS_TO_TICKS(2000));
|
|
ESP_LOGI(TAG, "Send command 0x%x to address 0x%x", cmd, addr);
|
|
// Send new key code
|
|
ESP_ERROR_CHECK(ir_builder->build_frame(ir_builder, addr, cmd));
|
|
ESP_ERROR_CHECK(ir_builder->get_result(ir_builder, &items, &length));
|
|
//To send data according to the waveform items.
|
|
rmt_write_items(example_tx_channel, items, length, false);
|
|
// Send repeat code
|
|
vTaskDelay(pdMS_TO_TICKS(ir_builder->repeat_period_ms));
|
|
ESP_ERROR_CHECK(ir_builder->build_repeat_frame(ir_builder));
|
|
ESP_ERROR_CHECK(ir_builder->get_result(ir_builder, &items, &length));
|
|
rmt_write_items(example_tx_channel, items, length, false);
|
|
cmd++;
|
|
}
|
|
ir_builder->del(ir_builder);
|
|
rmt_driver_uninstall(example_tx_channel);
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void app_main(void)
|
|
{
|
|
xTaskCreate(example_ir_rx_task, "ir_rx_task", 2048, NULL, 10, NULL);
|
|
xTaskCreate(example_ir_tx_task, "ir_tx_task", 2048, NULL, 10, NULL);
|
|
}
|