In the following code, how do I dynamically modify the duration0 parameter already configured in the object nec_encoder->bytes_encoder of the rmt_encoder_handle_t structure?
Code: Select all
[Codebox=c file=Untitled.c]
typedef struct
{
rmt_encoder_t base; // the base "class", declares the standard encoder interface
rmt_encoder_t *bytes_encoder; // use the bytes_encoder to encode the address and command data
int state;
} rmt_ir_nec_encoder_t;
static size_t rmt_encode_ir_nec(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state)
{
rmt_ir_nec_encoder_t *nec_encoder = __containerof(encoder, rmt_ir_nec_encoder_t, base);
rmt_encode_state_t session_state = RMT_ENCODING_RESET;
rmt_encode_state_t state = RMT_ENCODING_RESET;
size_t encoded_symbols = 0;
ir_nec_scan_code_t *scan_code = (ir_nec_scan_code_t *)primary_data;
uint32_t flag[6] = {0x80000001, 0x80000001, 0x80000001, 0x80000001, 0x80000001, 0x80000001};
rmt_encoder_handle_t bytes_encoder = nec_encoder->bytes_encoder;
[color=#FF0040]//?????
//How can I dynamically modify the duration0 parameter of this structure 'bytes_encoder_config' after calling rmt_new_bytes_encoder.
//?????[/color]
switch (nec_encoder->state)
{
case 0:
encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, &flag[0], sizeof(uint32_t), &session_state);
if (session_state & RMT_ENCODING_COMPLETE)
{
nec_encoder->state = 1; // we can only switch to next state when current encoder finished
}
if (session_state & RMT_ENCODING_MEM_FULL)
{
state |= RMT_ENCODING_MEM_FULL;
goto out; // yield if there's no free space to put other encoding artifacts
}
// fall-through
case 1:
encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, &flag[1], sizeof(uint32_t), &session_state);
if (session_state & RMT_ENCODING_COMPLETE)
{
nec_encoder->state = 2; // we can only switch to next state when current encoder finished
}
if (session_state & RMT_ENCODING_MEM_FULL)
{
state |= RMT_ENCODING_MEM_FULL;
goto out; // yield if there's no free space to put other encoding artifacts
}
// fall-through
case 2:
encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, &flag[2], sizeof(uint32_t), &session_state);
if (session_state & RMT_ENCODING_COMPLETE)
{
nec_encoder->state = 3; // we can only switch to next state when current encoder finished
}
if (session_state & RMT_ENCODING_MEM_FULL)
{
state |= RMT_ENCODING_MEM_FULL;
goto out; // yield if there's no free space to put other encoding artifacts
}
// fall-through
case 3:
encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, &flag[3], sizeof(uint32_t), &session_state);
if (session_state & RMT_ENCODING_COMPLETE)
{
nec_encoder->state = 4; // we can only switch to next state when current encoder finished
}
if (session_state & RMT_ENCODING_MEM_FULL)
{
state |= RMT_ENCODING_MEM_FULL;
goto out; // yield if there's no free space to put other encoding artifacts
}
// fall-through
case 4:
encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, &flag[4], sizeof(uint32_t), &session_state);
if (session_state & RMT_ENCODING_COMPLETE)
{
nec_encoder->state = 5; // we can only switch to next state when current encoder finished
}
if (session_state & RMT_ENCODING_MEM_FULL)
{
state |= RMT_ENCODING_MEM_FULL;
goto out; // yield if there's no free space to put other encoding artifacts
}
// fall through
case 5:
encoded_symbols += bytes_encoder->encode(bytes_encoder, channel, &flag[5], sizeof(uint32_t), &session_state);
if (session_state & RMT_ENCODING_COMPLETE)
{
nec_encoder->state = RMT_ENCODING_RESET; // back to the initial encoding session
state |= RMT_ENCODING_COMPLETE;
}
if (session_state & RMT_ENCODING_MEM_FULL)
{
state |= RMT_ENCODING_MEM_FULL;
goto out; // yield if there's no free space to put other encoding artifacts
}
// fall through
default:
break;
}
out:
*ret_state = state;
return encoded_symbols;
}
static esp_err_t rmt_del_ir_nec_encoder(rmt_encoder_t *encoder)
{
rmt_ir_nec_encoder_t *nec_encoder = __containerof(encoder, rmt_ir_nec_encoder_t, base);
rmt_del_encoder(nec_encoder->bytes_encoder);
free(nec_encoder);
return ESP_OK;
}
static esp_err_t rmt_ir_nec_encoder_reset(rmt_encoder_t *encoder)
{
rmt_ir_nec_encoder_t *nec_encoder = __containerof(encoder, rmt_ir_nec_encoder_t, base);
rmt_encoder_reset(nec_encoder->bytes_encoder);
nec_encoder->state = RMT_ENCODING_RESET;
return ESP_OK;
}
esp_err_t rmt_new_ir_nec_encoder(const ir_nec_encoder_config_t *config, rmt_encoder_handle_t *ret_encoder)
{
esp_err_t ret = ESP_OK;
rmt_ir_nec_encoder_t *nec_encoder = NULL;
ESP_GOTO_ON_FALSE(config && ret_encoder, ESP_ERR_INVALID_ARG, err, TAG, "invalid argument");
nec_encoder = calloc(1, sizeof(rmt_ir_nec_encoder_t));
ESP_GOTO_ON_FALSE(nec_encoder, ESP_ERR_NO_MEM, err, TAG, "no mem for ir nec encoder");
nec_encoder->base.encode = rmt_encode_ir_nec;
nec_encoder->base.del = rmt_del_ir_nec_encoder;
nec_encoder->base.reset = rmt_ir_nec_encoder_reset;
rmt_bytes_encoder_config_t bytes_encoder_config = {
.bit0 = {
.level0 = 0,
.duration0 = config->speed * config->resolution / 1000000, //
.level1 = 0,
.duration1 = config->speed * config->resolution / 1000000, //
},
.bit1 = {
.level0 = 1,
.duration0 = config->speed * config->resolution / 1000000, //
.level1 = 1,
.duration1 = config->speed * config->resolution / 1000000, //
},
.flags.msb_first = 0, //
};
rmt_new_bytes_encoder(&bytes_encoder_config, &nec_encoder->bytes_encoder);
*ret_encoder = &nec_encoder->base;
return ESP_OK;
err:
if (nec_encoder)
{
if (nec_encoder->bytes_encoder)
{
rmt_del_encoder(nec_encoder->bytes_encoder);
}
free(nec_encoder);
}
return ret;
}
[/Codebox]
I tried to make a call to rmt_new_bytes_encoder in the rmt_encode_ir_nec function to achieve the effect I need. But there is a call to heap_caps_calloc in the rmt_new_bytes_encoder function, does this have a performance impact?
Code: Select all
static size_t rmt_encode_ir_nec(rmt_encoder_t *encoder, rmt_channel_handle_t channel, const void *primary_data, size_t data_size, rmt_encode_state_t *ret_state)
{
rmt_ir_nec_encoder_t *nec_encoder = __containerof(encoder, rmt_ir_nec_encoder_t, base);
rmt_encode_state_t session_state = RMT_ENCODING_RESET;
rmt_encode_state_t state = RMT_ENCODING_RESET;
size_t encoded_symbols = 0;
ir_nec_scan_code_t *scan_code = (ir_nec_scan_code_t *)primary_data;
uint32_t flag[6] = {0x80000001, 0x80000001, 0x80000001, 0x80000001, 0x80000001, 0x80000001};
rmt_encoder_handle_t bytes_encoder ;
rmt_bytes_encoder_config_t bytes_encoder_config = {
.bit0 = {
.level0 = 0,
.duration0 = scan_code.command* scan_code.resolution / 1000000, // T0H=560us
.level1 = 0,
.duration1 = scan_code.command* scan_code.resolution/ 1000000, // T0L=560us
},
.bit1 = {
.level0 = 1,
.duration0 = scan_code.command* scan_code.resolution / 1000000, // T1H=560us
.level1 = 1,
.duration1 = scan_code.command* scan_code.resolution / 1000000, // T1L=1690us
},
.flags.msb_first = 0, // 从低bit位开始产生波形
};
rmt_new_bytes_encoder(&bytes_encoder_config, &bytes_encoder);
switch (nec_encoder->state)
{
case 0:
//..........
}
out:
*ret_state = state;
return encoded_symbols;
}