feature(ir_tx): use wdev timer

This commit is contained in:
xiongyu
2019-10-23 17:47:35 +08:00
parent 7b78b9772b
commit 350971d8bb
3 changed files with 51 additions and 7 deletions
components/esp8266
driver
include/driver
examples/peripherals/ir_tx/main

@ -29,6 +29,17 @@
static const char *TAG = "ir tx";
#define WDEVTSF0_TIME_LO 0x3ff21004
#define WDEVTSF0_TIME_HI 0x3ff21008
#define WDEVTSFSW0_LO 0x3ff21018
#define WDEVTSFSW0_HI 0x3ff2101C
#define WDEVTSF0_TIMER_LO 0x3ff2109c
#define WDEVTSF0_TIMER_HI 0x3ff210a0
#define WDEVTSF0TIMER_ENA 0x3ff21098
#define WDEV_TSF0TIMER_ENA BIT(31)
int wDev_MacTimSetFunc(void (*handle)(void));
#define IR_TX_CHECK(a, str, ret_val) \
if (!(a)) { \
ESP_LOGE(TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
@ -61,6 +72,7 @@ typedef struct {
SemaphoreHandle_t done_sem;
SemaphoreHandle_t send_mux;
ir_tx_trans_t trans;
ir_tx_timer_t timer;
} ir_tx_obj_t;
ir_tx_obj_t *ir_tx_obj = NULL;
@ -103,7 +115,17 @@ static void inline ir_tx_gen_carrier()
static void inline ir_tx_timer_alarm(uint32_t val)
{
hw_timer_alarm_us(val - IR_TX_ERROR_US, false);
if (ir_tx_obj->timer == IR_TX_WDEV_TIMER) {
REG_WRITE(WDEVTSFSW0_LO, 0);
REG_WRITE(WDEVTSFSW0_HI, 0);
REG_WRITE(WDEVTSFSW0_LO, 0);
REG_WRITE(WDEVTSF0_TIMER_LO, 0);
REG_WRITE(WDEVTSF0_TIMER_HI, 0);
REG_WRITE(WDEVTSF0_TIMER_LO, val - IR_TX_WDEV_TIMER_ERROR_US);
REG_WRITE(WDEVTSF0TIMER_ENA, WDEV_TSF0TIMER_ENA);
} else {
hw_timer_alarm_us(val - IR_TX_HW_TIMER_ERROR_US, false);
}
}
void IRAM_ATTR ir_tx_handler()
@ -115,7 +137,9 @@ void IRAM_ATTR ir_tx_handler()
static uint8_t ir_bit_state = TX_BIT_CARRIER;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (ir_tx_obj->timer == IR_TX_WDEV_TIMER) {
REG_WRITE(WDEVTSF0TIMER_ENA, REG_READ(WDEVTSF0TIMER_ENA) & (~WDEV_TSF0TIMER_ENA));
}
switch (ir_tx_state) {
case IR_TX_IDLE: {
ir_tx_gen_carrier();
@ -351,7 +375,12 @@ esp_err_t ir_tx_deinit()
ir_tx_obj->send_mux = NULL;
}
if (ir_tx_obj->timer == IR_TX_WDEV_TIMER) {
REG_WRITE(WDEVTSF0TIMER_ENA, REG_READ(WDEVTSF0TIMER_ENA) & (~WDEV_TSF0TIMER_ENA));
wDev_MacTimSetFunc(NULL);
} else {
hw_timer_deinit();
}
i2s_driver_uninstall(I2S_NUM_0);
@ -370,6 +399,7 @@ esp_err_t ir_tx_init(ir_tx_config_t *config)
IR_TX_CHECK(ir_tx_obj, "ir tx object malloc error", ESP_ERR_NO_MEM);
ir_tx_obj->io_num = config->io_num;
ir_tx_obj->freq = config->freq;
ir_tx_obj->timer = config->timer;
ir_tx_obj->done_sem = xSemaphoreCreateBinary();
ir_tx_obj->send_mux = xSemaphoreCreateMutex();
@ -413,8 +443,12 @@ esp_err_t ir_tx_init(ir_tx_config_t *config)
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM_0, &pin_config);
if (ir_tx_obj->timer == IR_TX_WDEV_TIMER) {
wDev_MacTimSetFunc(ir_tx_handler);
} else {
hw_timer_init(ir_tx_handler, NULL);
hw_timer_disarm();
}
ir_tx_clear_carrier();
return ESP_OK;

@ -32,7 +32,13 @@ extern "C" {
#define IR_TX_NEC_REP_LOW_US 2250
#define IR_TX_NEC_REP_STOP_US 562
#define IR_TX_NEC_REP_CYCLE 108000
#define IR_TX_ERROR_US 40 // Timing in advance to reduce errors
#define IR_TX_WDEV_TIMER_ERROR_US 5 // Timing in advance to reduce errors
#define IR_TX_HW_TIMER_ERROR_US 40 // Timing in advance to reduce errors
typedef enum {
IR_TX_WDEV_TIMER,
IR_TX_HW_TIMER,
} ir_tx_timer_t;
/**
* @brief ir tx initialization parameter structure type definition
@ -40,6 +46,7 @@ extern "C" {
typedef struct {
uint32_t io_num; // 2 or 14, 2: I2SO_WS 14: I2SI_WS
uint32_t freq;
ir_tx_timer_t timer; // WDEV timer will be more accurate, but PWM will not work
} ir_tx_config_t;
/**
@ -83,6 +90,8 @@ esp_err_t ir_tx_deinit();
/**
* @brief Initialize the ir tx
*
* @note WDEV timer will be more accurate, but PWM will not work.
*
* @param config Pointer to deliver initialize configuration parameter
*
* @return

@ -22,7 +22,8 @@ void ir_tx_task(void *arg)
{
ir_tx_config_t ir_tx_config = {
.io_num = IR_TX_IO_NUM,
.freq = 38000
.freq = 38000,
.timer = IR_TX_WDEV_TIMER // WDEV timer will be more accurate, but PWM will not work
};
ir_tx_init(&ir_tx_config);