mirror of
https://github.com/BotChain-Robots/firmware.git
synced 2026-07-08 09:37:21 +02:00
decrease freq resolution for rmt to hopefully make it more reliable
This commit is contained in:
@@ -29,6 +29,9 @@ RMTManager::RMTManager(uint8_t num_channels = MAX_CHANNELS){
|
||||
|
||||
esp_err_t RMTManager::init_tx_channel(){
|
||||
esp_err_t res_tx = ESP_FAIL;
|
||||
memory_to_free = xQueueCreate(15, sizeof(uint8_t*));
|
||||
|
||||
xTaskCreate(RMTManager::freeMemory, "RIPFreeMem", 4096, static_cast<void*>(memory_to_free), 5, NULL);
|
||||
|
||||
for (uint8_t i = 0; i < num_channels; i++){
|
||||
//setup encoder config
|
||||
@@ -98,10 +101,11 @@ esp_err_t RMTManager::init_tx_channel(){
|
||||
|
||||
channels[i].tx_done_semaphore = xSemaphoreCreateBinary(); //create a binary sem
|
||||
|
||||
TxCallbackContext* tx_callback_ctx = new TxCallbackContext {
|
||||
channels[i].tx_context = {
|
||||
.tx_done_sem = channels[i].tx_done_semaphore,
|
||||
.transmit_queue = channels[i].tx_queue,
|
||||
.tx_context = &channels[i].encoder_context
|
||||
.tx_context = &channels[i].encoder_context,
|
||||
.free_mem_queue = memory_to_free
|
||||
};
|
||||
|
||||
if (channels[i].tx_done_semaphore == NULL){
|
||||
@@ -110,7 +114,7 @@ esp_err_t RMTManager::init_tx_channel(){
|
||||
}
|
||||
|
||||
// res_tx = rmt_tx_register_event_callbacks(channels[i].tx_rmt_handle, &tx_cbs, channels[i].tx_done_semaphore);
|
||||
res_tx = rmt_tx_register_event_callbacks(channels[i].tx_rmt_handle, &tx_cbs, static_cast<void*>(tx_callback_ctx));
|
||||
res_tx = rmt_tx_register_event_callbacks(channels[i].tx_rmt_handle, &tx_cbs, static_cast<void*>(&channels[i].tx_context));
|
||||
|
||||
if (res_tx != ESP_OK) {
|
||||
// printf("Failed to register TX callback\n");
|
||||
@@ -143,14 +147,15 @@ bool RMTManager::rmt_tx_done_callback(rmt_channel_handle_t channel, const rmt_tx
|
||||
SemaphoreHandle_t sem = args->tx_done_sem;
|
||||
QueueHandle_t queue = args->transmit_queue;
|
||||
rmt_encoder_context_t* encoder_context = args->tx_context;
|
||||
|
||||
|
||||
QueueHandle_t free_queue = args->free_mem_queue;
|
||||
|
||||
TxBuffer buf = {};
|
||||
BaseType_t xTaskWokenByReceive = pdFALSE;
|
||||
xQueueReceiveFromISR(queue, static_cast<TxBuffer*>(&buf), &xTaskWokenByReceive); //remove from the queue
|
||||
|
||||
if (buf.data != nullptr){
|
||||
vPortFree((void*)buf.data);
|
||||
xQueueSendFromISR(free_queue, &buf.data, &xTaskWokenByReceive);
|
||||
}
|
||||
|
||||
if (encoder_context != nullptr){
|
||||
@@ -186,10 +191,10 @@ bool RMTManager::rmt_rx_done_callback(rmt_channel_handle_t channel, const rmt_rx
|
||||
QueueHandle_t receive_queue = (QueueHandle_t)user_data;
|
||||
// send the received RMT symbols to the parser task
|
||||
BaseType_t res = xQueueSendFromISR(receive_queue, edata, &high_task_wakeup);
|
||||
if (res != pdTRUE){
|
||||
// printf("RX Callback: Failed to enqueue received data\n");
|
||||
ESP_LOGE(DEBUG_TAG, "RX Callback: Failed to enqueue received data");
|
||||
}
|
||||
// if (res != pdTRUE){
|
||||
// // printf("RX Callback: Failed to enqueue received data\n");
|
||||
// // ESP_LOGE(DEBUG_TAG, "RX Callback: Failed to enqueue received data");
|
||||
// }
|
||||
// return whether any task is woken up
|
||||
return high_task_wakeup == pdTRUE;
|
||||
}
|
||||
@@ -230,7 +235,7 @@ esp_err_t RMTManager::init_rx_channel(){
|
||||
.on_recv_done = RMTManager::rmt_rx_done_callback
|
||||
};
|
||||
rmt_rx_register_event_callbacks(channels[i].rx_rmt_handle, &cbs, channels[i].rx_queue);
|
||||
|
||||
|
||||
res_rx = rmt_enable(channels[i].rx_rmt_handle);
|
||||
|
||||
if (res_rx != ESP_OK) {
|
||||
@@ -274,6 +279,21 @@ esp_err_t RMTManager::init(){
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
[[noreturn]] void RMTManager::freeMemory(void* args){
|
||||
QueueHandle_t queue = (QueueHandle_t)(args);
|
||||
|
||||
uint8_t* dummy;
|
||||
|
||||
while (true){
|
||||
if (xQueueReceive(queue, &dummy, pdMS_TO_TICKS(10)) == pdTRUE){
|
||||
if (dummy != nullptr){
|
||||
vPortFree((void*)dummy);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This is a callback function called by RMT when transmitting. This function will encode the user data `data` with rising and falling edges based on the bit.a64l
|
||||
* The symbols are defined in `RMTManager.h`, where a bit 1 is transmitted as a `RMT_SYMBOL_ONE` and a bit 0 is transmitted as a `RMT_SYMBOL_ZERO`
|
||||
@@ -300,59 +320,10 @@ size_t RMTManager::encoder_callback(const void* data, size_t data_size, size_t s
|
||||
uint8_t byte = bytes[ctx->byte_index]; //get the byte from the data
|
||||
uint8_t bit = (byte >> (7 - ctx->bit_index)) & 0x01; //get the current bit, as determined from the bit index (MSB first)
|
||||
|
||||
#ifndef NRZ_INVERTED
|
||||
//Manchester (Ethernet Standard) Encoding
|
||||
symbols[symbols_used++] = bit ? RMT_SYMBOL_ONE : RMT_SYMBOL_ZERO; //if the bit is a 1, transmit a 1 symbol; otherwise, transmit 0 symbol
|
||||
ctx->num_symbols++;
|
||||
#else
|
||||
//NRZ-I encoding. Must change the voltage level whenever a bit 1 is detected
|
||||
if (ctx->byte_index == 0 && ctx->bit_index == 0){
|
||||
//MSB of the first byte - send a rising edge 1 to allow any succeeding 0s to be detected by the receiver
|
||||
symbols[symbols_used++] = RMT_SYMBOL_ONE_RISING;
|
||||
ctx->current_level = !ctx->current_level; //current level is high
|
||||
ctx->num_symbols++;
|
||||
}
|
||||
//Manchester (Ethernet Standard) Encoding
|
||||
symbols[symbols_used++] = bit ? RMT_SYMBOL_ONE : RMT_SYMBOL_ZERO; //if the bit is a 1, transmit a 1 symbol; otherwise, transmit 0 symbol
|
||||
ctx->num_symbols++;
|
||||
|
||||
if (ctx->zero_count == CONSEC_ZERO_THRESHOLD){
|
||||
ctx->current_level = !ctx->current_level;
|
||||
symbols[symbols_used++] = ctx->current_level ? RMT_SYMBOL_ONE_RISING : RMT_SYMBOL_ONE_FALLING;
|
||||
ctx->num_symbols++;
|
||||
ctx->zero_count = 0;
|
||||
|
||||
// Don't advance to next bit – reprocess the current bit
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bit == 1){
|
||||
ctx->current_level = !ctx->current_level; //invert current level
|
||||
symbols[symbols_used++] = ctx->current_level ? RMT_SYMBOL_ONE_RISING : RMT_SYMBOL_ONE_FALLING; //if current level is 0 (low), it must be a falling edge. otherwise, it is a rising edge
|
||||
ctx->num_symbols++;
|
||||
ctx->zero_count = 0;
|
||||
} else {
|
||||
//bit 0s, maintain current level
|
||||
if (ctx->current_level){
|
||||
//check if the previous symbol was RMT_SYMBOL_ZERO_HIGH. if it is, simply add another RMT_DURATION_MAX on duration1 (this is a slight optimization to send less symbols)
|
||||
if (symbols[symbols_used-1].level0 == 1 && symbols[symbols_used-1].level1 == 1){
|
||||
symbols[symbols_used-1].duration1 += RMT_DURATION_MAX;
|
||||
} else {
|
||||
//previous symbol was not RMT_SYMBOL_ZERO_HIGH
|
||||
symbols[symbols_used++] = RMT_SYMBOL_ZERO_HIGH;
|
||||
ctx->num_symbols++;
|
||||
}
|
||||
} else {
|
||||
if (symbols[symbols_used-1].level0 == 0 && symbols[symbols_used-1].level1 == 0){
|
||||
symbols[symbols_used-1].duration1 += RMT_DURATION_MAX;
|
||||
} else {
|
||||
symbols[symbols_used++] = ctx->current_level ? RMT_SYMBOL_ZERO_HIGH : RMT_SYMBOL_ZERO_LOW;
|
||||
ctx->num_symbols++;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->zero_count++;
|
||||
|
||||
}
|
||||
|
||||
#endif //NRZ_INVERTED
|
||||
ctx->bit_index++;
|
||||
if (ctx->bit_index >= 8) {
|
||||
//reached the end of the byte; go to the next byte
|
||||
@@ -370,9 +341,6 @@ void RMTManager::reset_encoder_context(rmt_encoder_context_t* ctx){
|
||||
ctx->bit_index = 0;
|
||||
ctx->byte_index = 0;
|
||||
ctx->num_symbols = 0;
|
||||
#ifdef NRZ_INVERTED
|
||||
ctx->current_level = false;
|
||||
#endif //NRZ_INVERTED
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -396,7 +364,12 @@ esp_err_t RMTManager::send(uint8_t* data, size_t size, rmt_transmit_config_t* co
|
||||
|
||||
if (this->channels[channel_num].tx_rmt_handle == nullptr) {
|
||||
// printf("send() error: tx_chan is NULL\n");
|
||||
ESP_LOGE(DEBUG_TAG, "send() error: tx_chan is NULL");
|
||||
ESP_LOGE(DEBUG_TAG, "send() error: tx_rmt_handle is NULL");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (this->channels[channel_num].tx_queue == nullptr) {
|
||||
// printf("send() error: tx_chan is NULL\n");
|
||||
ESP_LOGE(DEBUG_TAG, "send() error: tx_queue is NULL");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (this->channels[channel_num].encoder == nullptr) {
|
||||
@@ -426,8 +399,8 @@ esp_err_t RMTManager::send(uint8_t* data, size_t size, rmt_transmit_config_t* co
|
||||
}
|
||||
|
||||
memcpy((void*)(new_data_to_send_buf.data), data, size);
|
||||
|
||||
if (xQueueSendToBack(channels[channel_num].tx_queue, (void*)&new_data_to_send_buf, (TickType_t) 10) != pdPASS){ //note this may not work very well since im not checking the return value; this function can fail if the queue is full
|
||||
|
||||
if (xQueueSendToBack(channels[channel_num].tx_queue, (void*)&new_data_to_send_buf, (TickType_t) 10) != pdPASS){
|
||||
vPortFree((void*)new_data_to_send_buf.data);
|
||||
ESP_LOGE(DEBUG_TAG, "Failed to queue data");
|
||||
return ESP_FAIL;
|
||||
@@ -463,126 +436,39 @@ int RMTManager::decode_symbols(rmt_symbol_word_t* symbols, size_t num, rmt_symbo
|
||||
size_t i = 0;
|
||||
bool curr_high_low = true; //flag to maintain where we are (either high or low)
|
||||
|
||||
#ifdef NRZ_INVERTED
|
||||
uint32_t num_0_symbols_duration = 0, num_0_symbols = 0;
|
||||
uint8_t consecutive_zeros = 0;
|
||||
#endif //NRZ_INVERTED
|
||||
while (output_index < output_num && i < num){
|
||||
// printf("duration0 %d level0 %d duration1 %d level1 %d\n", symbols[i].duration0, symbols[i].level0, symbols[i].duration1, symbols[i].level1); //dummy print receive
|
||||
#ifndef NRZ_INVERTED
|
||||
//manchester encoding
|
||||
/*there are two cases in the beginning:
|
||||
1. if duration0 = 20, then we are in between two symbols (low to high and high to low).
|
||||
in this case, we need to insert a low in the beginning and "split" the current symbol into 2
|
||||
2. if duration0 = 10, then the first symbol should be high to low
|
||||
*/
|
||||
if (symbols[i].duration0 != RMT_DURATION_SYMBOL){
|
||||
if (i != 0){
|
||||
if (curr_high_low){
|
||||
decoded[output_index++] = RMT_SYMBOL_ONE;
|
||||
} else {
|
||||
decoded[output_index++] = RMT_SYMBOL_ZERO;
|
||||
}
|
||||
curr_high_low = !curr_high_low;
|
||||
//manchester encoding
|
||||
/*there are two cases in the beginning:
|
||||
1. if duration0 = 20, then we are in between two symbols (low to high and high to low).
|
||||
in this case, we need to insert a low in the beginning and "split" the current symbol into 2
|
||||
2. if duration0 = 10, then the first symbol should be high to low
|
||||
*/
|
||||
if (symbols[i].duration0 != RMT_DURATION_SYMBOL){
|
||||
if (i != 0){
|
||||
if (curr_high_low){
|
||||
decoded[output_index++] = RMT_SYMBOL_ONE;
|
||||
} else {
|
||||
//need to insert a 0 before received symbols
|
||||
decoded[output_index++] = RMT_SYMBOL_ZERO;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (curr_high_low){
|
||||
decoded[output_index++] = RMT_SYMBOL_ONE;
|
||||
curr_high_low = !curr_high_low;
|
||||
} else {
|
||||
//need to insert a 0 before received symbols
|
||||
decoded[output_index++] = RMT_SYMBOL_ZERO;
|
||||
}
|
||||
|
||||
//if duration1 = 20, then we are starting low
|
||||
if (symbols[i].duration1 != RMT_DURATION_SYMBOL){
|
||||
curr_high_low = !curr_high_low;
|
||||
}
|
||||
#else
|
||||
//nrz-i encoding - bit stuffing doesn't work
|
||||
//there is always a rising edge (period of RMT_DURATION_SYMBOL on high as the first half isn't captured)
|
||||
// if (i == 0){
|
||||
// curr_high_low = true;
|
||||
// if (symbols[i].duration0 == RMT_DURATION_MAX){
|
||||
// //next symbol is a 1 - can continue (first RMT_DURATION is from the first symbol (init rising edge). second RMT_DURATION is second symbol)
|
||||
// i++;
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
//need to "split"
|
||||
if (symbols[i].duration0 % (RMT_DURATION_SYMBOL * 2) != 0){
|
||||
num_0_symbols_duration = symbols[i].duration0 - RMT_DURATION_SYMBOL; //last waveform has duration0 with some duration that's only a multiple of RMT_DURATION_SYMBOL
|
||||
}else {
|
||||
num_0_symbols_duration = symbols[i].duration0 - RMT_DURATION_SYMBOL * 2; //one from the rising edge, one from the falling edge
|
||||
}
|
||||
|
||||
|
||||
num_0_symbols = num_0_symbols_duration / RMT_DURATION_MAX; //should be the number of 0 symbols
|
||||
for (int j = 0; j < num_0_symbols && output_index < output_num; j++){
|
||||
decoded[output_index++] = curr_high_low ? RMT_SYMBOL_ZERO_HIGH : RMT_SYMBOL_ZERO_LOW;
|
||||
consecutive_zeros++;
|
||||
}
|
||||
|
||||
curr_high_low = !curr_high_low;
|
||||
if (output_index >= output_num){
|
||||
break;
|
||||
}
|
||||
|
||||
if (!curr_high_low){
|
||||
decoded[output_index++] = RMT_SYMBOL_ONE_FALLING;
|
||||
} else {
|
||||
decoded[output_index++] = RMT_SYMBOL_ONE_RISING;
|
||||
}
|
||||
|
||||
// if (consecutive_zeros == MAX_ZER){
|
||||
// consecutive_zeros = 0;
|
||||
// } else {
|
||||
// if (!curr_high_low) {
|
||||
// decoded[output_index++] = RMT_SYMBOL_ONE_FALLING;
|
||||
// } else {
|
||||
// decoded[output_index++] = RMT_SYMBOL_ONE_RISING;
|
||||
// }
|
||||
// consecutive_zeros = 0; // reset zero count after a real 1 bit
|
||||
// }
|
||||
|
||||
if (symbols[i].duration1 == 0){
|
||||
break; //last waveform has duration1 = 0
|
||||
}
|
||||
|
||||
num_0_symbols_duration = symbols[i].duration1 - RMT_DURATION_SYMBOL * 2; //one from the falling edge, one from the rising edge
|
||||
num_0_symbols = num_0_symbols_duration / RMT_DURATION_MAX; //should be the number of 0 symbols
|
||||
|
||||
for (int j = 0; j < num_0_symbols && output_index < output_num; j++){
|
||||
decoded[output_index++] = curr_high_low ? RMT_SYMBOL_ZERO_HIGH : RMT_SYMBOL_ZERO_LOW;
|
||||
}
|
||||
|
||||
curr_high_low = !curr_high_low;
|
||||
if (output_index >= output_num){
|
||||
break;
|
||||
}
|
||||
if (!curr_high_low){
|
||||
decoded[output_index++] = RMT_SYMBOL_ONE_FALLING;
|
||||
} else {
|
||||
decoded[output_index++] = RMT_SYMBOL_ONE_RISING;
|
||||
}
|
||||
|
||||
// if (consecutive_zeros == 5){
|
||||
// consecutive_zeros = 0;
|
||||
// } else {
|
||||
// if (!curr_high_low) {
|
||||
// decoded[output_index++] = RMT_SYMBOL_ONE_FALLING;
|
||||
// } else {
|
||||
// decoded[output_index++] = RMT_SYMBOL_ONE_RISING;
|
||||
// }
|
||||
// consecutive_zeros = 0; // reset zero count after a real 1 bit
|
||||
// }
|
||||
|
||||
#endif //NRZ_INVERTED
|
||||
|
||||
}
|
||||
|
||||
if (curr_high_low){
|
||||
decoded[output_index++] = RMT_SYMBOL_ONE;
|
||||
} else {
|
||||
decoded[output_index++] = RMT_SYMBOL_ZERO;
|
||||
}
|
||||
|
||||
//if duration1 = 20, then we are starting low
|
||||
if (symbols[i].duration1 != RMT_DURATION_SYMBOL){
|
||||
curr_high_low = !curr_high_low;
|
||||
}
|
||||
i++;
|
||||
|
||||
}
|
||||
@@ -609,28 +495,14 @@ int RMTManager::convert_symbols_to_char(rmt_symbol_word_t* symbols, size_t num,
|
||||
int i = 0;
|
||||
|
||||
while (i < num && output_index < output_num){
|
||||
#ifndef NRZ_INVERTED
|
||||
if (symbols[i].level0 == 0 && symbols[i].level1 == 1){
|
||||
//zero
|
||||
byte = byte << 1;
|
||||
}else if (symbols[i].level0 == 1 && symbols[i].level1 == 0) {
|
||||
byte = (byte << 1) + 1;
|
||||
} else {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#else
|
||||
//nrz-i
|
||||
|
||||
if (symbols[i].level0 != symbols[i].level1){
|
||||
//bit 1
|
||||
byte = (byte << 1) + 1;
|
||||
} else if (symbols[i].level0 == symbols[i].level1){
|
||||
//bit 0
|
||||
byte = byte << 1;
|
||||
} else {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
#endif //NRZ_INVERTED
|
||||
if (symbols[i].level0 == 0 && symbols[i].level1 == 1){
|
||||
//zero
|
||||
byte = byte << 1;
|
||||
}else if (symbols[i].level0 == 1 && symbols[i].level1 == 0) {
|
||||
byte = (byte << 1) + 1;
|
||||
} else {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
bit_count++;
|
||||
if (bit_count == 8){
|
||||
@@ -717,15 +589,20 @@ esp_err_t RMTManager::receive(uint8_t* recv_buf, size_t size, size_t* output_siz
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// printf("\n\nparsed symbols:\n");
|
||||
// for (int i = 0; i < num; i++){
|
||||
// printf("duration0 %d level0 %d duration1 %d level1 %d\n", decoded_recv_symbols[i].duration0, decoded_recv_symbols[i].level0, decoded_recv_symbols[i].duration1, decoded_recv_symbols[i].level1);
|
||||
// }
|
||||
|
||||
*output_size = this->convert_symbols_to_char(channels[channel_num].decoded_recv_symbols, num, recv_buf, size);
|
||||
if (*output_size < 0){
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
//UNCOMMENT HERE TO GET RAW BITS TO USE IN `components/dataLink/test_scripts/parse_bit_frame.py`
|
||||
// printf("\n\nparsed characters:\n");
|
||||
// for (int i = 0; i < *output_size; i++) {
|
||||
// for (int bit = 7; bit >= 0; bit--) {
|
||||
// printf("%d", (recv_buf[i] >> bit) & 1);
|
||||
// }
|
||||
// printf(" ");
|
||||
// }
|
||||
// printf("\nDone\n");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -33,12 +33,21 @@ typedef struct {
|
||||
size_t byte_index; //which byte is currently being encoded when transmitting
|
||||
uint8_t bit_index; //which bit in the `byte_index` is currently being encoded (into high/low waveforms)
|
||||
size_t num_symbols; //temp
|
||||
#ifdef NRZ_INVERTED
|
||||
bool current_level;
|
||||
uint8_t zero_count;
|
||||
#endif //NRZ_INVERTED
|
||||
} rmt_encoder_context_t;
|
||||
|
||||
//will need to keep the data alive until it has been transmitted (not working or being used atm)
|
||||
struct TxCallbackContext{
|
||||
SemaphoreHandle_t tx_done_sem;
|
||||
QueueHandle_t transmit_queue;
|
||||
rmt_encoder_context_t* tx_context;
|
||||
QueueHandle_t free_mem_queue;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t* data;
|
||||
size_t length;
|
||||
} TxBuffer;
|
||||
|
||||
typedef struct _rmt_channel{
|
||||
//TX
|
||||
uint8_t tx_gpio;
|
||||
@@ -47,6 +56,7 @@ typedef struct _rmt_channel{
|
||||
QueueHandle_t tx_queue;
|
||||
rmt_encoder_handle_t encoder; //encoder config
|
||||
rmt_encoder_context_t encoder_context;
|
||||
TxCallbackContext tx_context;
|
||||
|
||||
//RX
|
||||
uint8_t rx_gpio;
|
||||
@@ -85,6 +95,8 @@ class RMTManager{
|
||||
esp_err_t init_rx_channel();
|
||||
int decode_symbols(rmt_symbol_word_t* symbols, size_t num, rmt_symbol_word_t* decoded, size_t output_num);
|
||||
int convert_symbols_to_char(rmt_symbol_word_t* symbols, size_t num, uint8_t* string, size_t output_num);
|
||||
|
||||
[[noreturn]] static void freeMemory(void* args);
|
||||
|
||||
rmt_channel channels[MAX_CHANNELS] = {0};
|
||||
//=====================TX=====================
|
||||
@@ -102,7 +114,7 @@ class RMTManager{
|
||||
//will be used to temporarily hold the bits that are being wait to be sent -- not working
|
||||
// QueueHandle_t transmit_queue = NULL;
|
||||
|
||||
// TxCallbackContext tx_context;
|
||||
QueueHandle_t memory_to_free;
|
||||
|
||||
//=====================RX=====================
|
||||
rmt_channel_handle_t rx_chan;
|
||||
@@ -124,19 +136,6 @@ class RMTManager{
|
||||
// bool ready_to_receive = false;
|
||||
};
|
||||
|
||||
//will need to keep the data alive until it has been transmitted (not working or being used atm)
|
||||
|
||||
struct TxCallbackContext{
|
||||
SemaphoreHandle_t tx_done_sem;
|
||||
QueueHandle_t transmit_queue;
|
||||
rmt_encoder_context_t* tx_context;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const uint8_t* data;
|
||||
size_t length;
|
||||
} TxBuffer;
|
||||
|
||||
typedef struct _gpio_channel_pair {
|
||||
gpio_num_t tx_pin;
|
||||
gpio_num_t rx_pin;
|
||||
|
||||
@@ -2,43 +2,11 @@
|
||||
|
||||
#include "driver/rmt_tx.h"
|
||||
|
||||
// #ifdef MANCHESTER_40
|
||||
// #define RMT_RESOLUTION_HZ 40 * 1000 * 1000 // 40MHz resolution
|
||||
// #define RMT_DURATION_SYMBOL 10 //0.25 us bit duration
|
||||
// #elif NRZ_INVERTED
|
||||
// #ifdef NRZ_INVERTED_40_HZ
|
||||
// #define RMT_RESOLUTION_HZ 40 * 1000 * 1000 // 40MHz resolution
|
||||
// #else
|
||||
// #define RMT_RESOLUTION_HZ 20 * 1000 * 1000 // 20MHz resolution
|
||||
// #endif //NRZ_INVERTED_40_HZ
|
||||
// #ifdef NRZ_INVERTED_10
|
||||
// #define RMT_DURATION_SYMBOL 10 //0.5us bit duration
|
||||
// #elif NRZ_INVERTED_20
|
||||
// #define RMT_DURATION_SYMBOL 5 //0.25 us bit duration
|
||||
// #elif NRZ_INVERTED_2
|
||||
// #define RMT_DURATION_SYMBOL 2 //0.1 us bit duration
|
||||
// #else
|
||||
// #define RMT_DURATION_SYMBOL 20 //1us bit duration
|
||||
// #endif //NRZ_INVERTED_10
|
||||
// #else
|
||||
// #define RMT_RESOLUTION_HZ 1 * 1000 * 1000 // 1MHz resolution
|
||||
// #define RMT_DURATION_SYMBOL 10
|
||||
// #endif //MANCHESTER_40
|
||||
|
||||
// #define NRZ_INVERTED //using NRZ_I
|
||||
#define RMT_RESOLUTION_HZ 40 * 1000 * 1000 // 40MHz resolution
|
||||
#define RMT_DURATION_SYMBOL 12 //0.6us
|
||||
|
||||
|
||||
// #define RMT_DURATION_SYMBOL ((RMT_RESOLUTION_HZ * 3) / 1000000) // duration time for a symbol - this is 3us
|
||||
#define RMT_RESOLUTION_HZ 3 * 1000 * 1000 // 3MHz resolution
|
||||
#define RMT_DURATION_SYMBOL 1 //0.667us
|
||||
|
||||
#define RMT_DURATION_MAX (2 * RMT_DURATION_SYMBOL)
|
||||
|
||||
// #define RMT_TX_GPIO GPIO_NUM_1 //RMT will use GPIO pin 1 to transmit (on one channel)
|
||||
|
||||
// #define RMT_RX_GPIO GPIO_NUM_12 // RMT will use GPIO pin 12 to receive (on one channel)
|
||||
|
||||
#ifndef NRZ_INVERTED
|
||||
//MANCHESTER ENCODING (ETHERNET STANDARD)
|
||||
|
||||
/**
|
||||
@@ -62,60 +30,6 @@ static const rmt_symbol_word_t RMT_SYMBOL_ZERO = {
|
||||
.duration1 = RMT_DURATION_SYMBOL,
|
||||
.level1 = 1,
|
||||
};
|
||||
#else
|
||||
|
||||
//Non-Return-to-Zero Inverted (NRZ-I)
|
||||
|
||||
#define CONSEC_ZERO_THRESHOLD 3 //max number of consecutive zeros before adding a bit 1
|
||||
|
||||
// Logic 1 inverts the current voltage state
|
||||
|
||||
/**
|
||||
* @brief This struct represents a 1 symbol being transmitted over RMT. This will create a falling edge (low for `RMT_DURATION_SYMBOL` and high for `RMT_DURATION_SYMBOL`)
|
||||
*
|
||||
*/
|
||||
static const rmt_symbol_word_t RMT_SYMBOL_ONE_FALLING = {
|
||||
.duration0 = RMT_DURATION_SYMBOL,
|
||||
.level0 = 1,
|
||||
.duration1 = RMT_DURATION_SYMBOL,
|
||||
.level1 = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This struct represents a 1 symbol being transmitted over RMT. This will create a rising edge (low for `RMT_DURATION_SYMBOL` and high for `RMT_DURATION_SYMBOL`)
|
||||
*
|
||||
*/
|
||||
static const rmt_symbol_word_t RMT_SYMBOL_ONE_RISING = {
|
||||
.duration0 = RMT_DURATION_SYMBOL,
|
||||
.level0 = 0,
|
||||
.duration1 = RMT_DURATION_SYMBOL,
|
||||
.level1 = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This struct will represent a bit 0. In NRZ-I, this represents a no change in the voltage
|
||||
*
|
||||
*/
|
||||
static const rmt_symbol_word_t RMT_SYMBOL_ZERO_HIGH = {
|
||||
.duration0 = RMT_DURATION_SYMBOL,
|
||||
.level0 = 1,
|
||||
.duration1 = RMT_DURATION_SYMBOL,
|
||||
.level1 = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This struct will represent a bit 0. In NRZ-I, this represents a no change in the voltage
|
||||
*
|
||||
*/
|
||||
static const rmt_symbol_word_t RMT_SYMBOL_ZERO_LOW = {
|
||||
.duration0 = RMT_DURATION_SYMBOL,
|
||||
.level0 = 0,
|
||||
.duration1 = RMT_DURATION_SYMBOL,
|
||||
.level1 = 0,
|
||||
};
|
||||
|
||||
|
||||
#endif //NRZ_INVERTED
|
||||
|
||||
//not used at the moment
|
||||
|
||||
|
||||
Reference in New Issue
Block a user