Skip to content

Commit

Permalink
testing ir tx
Browse files Browse the repository at this point in the history
  • Loading branch information
htotoo committed Dec 10, 2024
1 parent 279917f commit ceaa44a
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Source/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,6 @@
"cinttypes": "cpp",
"typeinfo": "cpp"
},
"idf.portWin": "COM14",
"idf.portWin": "COM5",
"idf.flashType": "UART"
}
2 changes: 1 addition & 1 deletion Source/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

idf_component_register(SRCS "ppshellcomm.cpp" "wifim.cpp" "led.cpp" "configuration.cpp" "sensordb.c" "orientation.c" "environment.c" "ppi2c/pp_handler.cpp" "ppi2c/i2c_slave_driver.c" "drivers/i2cdev.c" "drivers/hmc5883l.c" "drivers/lsm303.c" "drivers/mpu925x.c" "drivers/sht3x.c" "drivers/bh1750.c" "drivers/bmp280.c" "drivers/adxl345.c" "nmea_parser.c" "main.cpp"
idf_component_register(SRCS "tir.cpp" "ppshellcomm.cpp" "wifim.cpp" "led.cpp" "configuration.cpp" "sensordb.c" "orientation.c" "environment.c" "ppi2c/pp_handler.cpp" "ppi2c/i2c_slave_driver.c" "drivers/i2cdev.c" "drivers/hmc5883l.c" "drivers/lsm303.c" "drivers/mpu925x.c" "drivers/sht3x.c" "drivers/bh1750.c" "drivers/bmp280.c" "drivers/adxl345.c" "nmea_parser.c" "main.cpp"
"sgp4/brent.cpp"
"sgp4/sgp4coord.cpp"
"sgp4/sgp4ext.cpp"
Expand Down
16 changes: 15 additions & 1 deletion Source/main/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,26 @@ menu "ESP32PP"
default 10
help
I2C SLAVE SCL PIN on ESP

config I2C_SLAVE_SDA_IO
int "I2C SLAVE SDA PIN on ESP"
range 1 255
default 11
help
I2C SLAVE SDA PIN on ESP


config IR_RX_PIN
int "IR RX PIN"
range 1 255
default 12
help
IR RX PIN on ESP
config IR_TX_PIN
int "IR TX PIN"
range 1 255
default 13
help
IR TX PIN on ESP


endmenu
7 changes: 7 additions & 0 deletions Source/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
#include "orientation.h"
#include "environment.h"

#include "tir.h"

#include "ppi2c/pp_handler.hpp"

#define PPCMD_SATTRACK_DATA 0xa000
Expand All @@ -61,6 +63,8 @@ uint8_t time_method = 0; // 0 = no valid, 1 = gps, 2 = ntp

Sgp4 sat;

TIR tir;

typedef enum TimerEntry {
TimerEntry_SENSORGET,
TimerEntry_REPORTPPGPS,
Expand Down Expand Up @@ -442,6 +446,8 @@ void app_main(void) {
LedFeedback::init(RGB_LED_PIN);
LedFeedback::rgb_set(255, 255, 255);

tir.init((gpio_num_t)CONFIG_IR_TX_PIN, (gpio_num_t)CONFIG_IR_RX_PIN);

init_orientation(); // it loads orientation data too
init_environment();

Expand Down Expand Up @@ -537,6 +543,7 @@ void app_main(void) {
}
// GET ALL SENSOR DATA
if (time_millis - last_millis[TimerEntry_SENSORGET] > timer_millis[TimerEntry_SENSORGET]) {
tir.send(NEC, 0xa, 0xC1AAFC03); // send a test ir signal
// GPS IS AUTO
ESP_ERROR_CHECK(temperature_sensor_get_celsius(temp_sensor, &temperatureEsp)); // TEMPINT
heading = get_heading_degrees(); // ORIENTATION
Expand Down
223 changes: 223 additions & 0 deletions Source/main/tir.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
#include "tir.h"

QueueHandle_t TIR::sendQueue;
gpio_num_t TIR::tx_pin;

const ir_protocol_t TIR::proto[PROTO_COUNT] = {
[UNK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, "UNK", 32},
[NEC] = {9000, 4500, 560, 1690, 560, 560, 560, 0, 38000, "NEC", 32},
[SONY] = {2400, 600, 1200, 600, 600, 600, 0, 0, 40000, "SONY", 32},
[SAM] = {4500, 4500, 560, 1690, 560, 560, 560, 0, 38000, "SAM", 32},
[RC5] = {0, 0, 889, 889, 889, 889, 0, 0, 38000, "RC5", 32},
};

TIR::TIR() {
}

TIR::~TIR() {
}

void TIR::init(gpio_num_t tx, gpio_num_t rx) {
tx_pin = tx;
// init rx
if (rx != 0) {
// todo start rx thread, and sync with tx
}

if (tx_pin != 0) {
sendQueue = xQueueCreate(5, sizeof(ir_data_t));
xTaskCreate(processSendTask, "processSendTask", 4096, NULL, 5, NULL);
}
}

void TIR::send(irproto protocol, uint32_t addr, uint32_t data_) {
ir_data_t data;
data.protocol = protocol;
data.addr = addr;
data.data = data_;
data.repeat = 1;
send(data);
}

void TIR::send(ir_data_t data) {
xQueueSend(sendQueue, &data, portMAX_DELAY); // todo maybe handle error, not needed, since shouldn't add >5
}

void TIR::create_symbol(rmt_symbol_word_t& item, uint16_t high, uint16_t low, bool bit) {
item.level0 = !bit;
item.duration0 = high;
item.level1 = bit;
item.duration1 = low;
}

size_t TIR::rmt_encode_ir(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_encoder_t* ir_encoder = __containerof(encoder, rmt_ir_encoder_t, base);

rmt_encode_state_t fstate = RMT_ENCODING_RESET;

size_t encoded_symbols = 0;
rmt_encoder_handle_t copy_encoder = ir_encoder->copy_encoder;

ir_data_t* send_data = (ir_data_t*)primary_data;

ir_protocol_t protocol = proto[send_data->protocol];

if (ir_encoder->state == 0) {
if (protocol.header_high > 0) {
rmt_symbol_word_t header_symbol;
create_symbol(header_symbol, protocol.header_high, protocol.header_low, 0);
encoded_symbols += copy_encoder->encode(copy_encoder, channel, &header_symbol, sizeof(rmt_symbol_word_t), &fstate);
} else {
fstate = RMT_ENCODING_COMPLETE;
}

if (fstate & RMT_ENCODING_COMPLETE) {
ir_encoder->state = 1;
ir_encoder->bit_index = 0;
}
if (fstate & RMT_ENCODING_MEM_FULL) {
fstate = RMT_ENCODING_MEM_FULL;
*ret_state = fstate;
return encoded_symbols;
}
}

if (ir_encoder->state == 1) {
uint8_t rcspecial = 0;
if (send_data->protocol == RC5) {
rcspecial = 1;
}

rmt_symbol_word_t one_symbol;
create_symbol(one_symbol, protocol.one_high, protocol.one_low, rcspecial);

rmt_symbol_word_t zero_symbol;
create_symbol(zero_symbol, protocol.zero_high, protocol.zero_low, 0);

for (uint8_t i = ir_encoder->bit_index; i < protocol.bits; i++) {
if ((send_data->data >> i) & 1) {
encoded_symbols += copy_encoder->encode(copy_encoder, channel, &one_symbol, sizeof(rmt_symbol_word_t), &fstate);
} else {
encoded_symbols += copy_encoder->encode(copy_encoder, channel, &zero_symbol, sizeof(rmt_symbol_word_t), &fstate);
}
if (fstate & RMT_ENCODING_MEM_FULL) {
fstate = RMT_ENCODING_MEM_FULL;
ir_encoder->bit_index = i + 1;
*ret_state = fstate;
return encoded_symbols;
}
}
ir_encoder->state = 2;
}

if (ir_encoder->state == 2) {
if (protocol.footer_high > 0) {
rmt_symbol_word_t end_symbol;
create_symbol(end_symbol, protocol.footer_high, protocol.footer_low, 0);
encoded_symbols += copy_encoder->encode(copy_encoder, channel, &end_symbol, sizeof(rmt_symbol_word_t), &fstate);
} else {
fstate = (rmt_encode_state_t)((int)fstate | RMT_ENCODING_COMPLETE);
}
if (fstate & RMT_ENCODING_COMPLETE) {
ir_encoder->state = 0;
*ret_state = RMT_ENCODING_COMPLETE;
}
}

return encoded_symbols;
}

esp_err_t rmt_del_ir_encoder(rmt_encoder_t* encoder) {
rmt_ir_encoder_t* ir_encoder = __containerof(encoder, rmt_ir_encoder_t, base);
rmt_del_encoder(ir_encoder->copy_encoder);
free(ir_encoder);
return ESP_OK;
}

esp_err_t rmt_ir_encoder_reset(rmt_encoder_t* encoder) {
rmt_ir_encoder_t* ir_encoder = __containerof(encoder, rmt_ir_encoder_t, base);
rmt_encoder_reset(ir_encoder->copy_encoder);
ir_encoder->state = 0;
ir_encoder->bit_index = 0;
return ESP_OK;
}

void TIR::processSendTask(void* pvParameters) {
ir_data_t receivedData;
while (1) {
if (xQueueReceive(sendQueue, &receivedData, portMAX_DELAY) == pdTRUE) {
// wait for rx to finish. todo
rmt_channel_handle_t tx_channel = NULL;

rmt_tx_channel_config_t txconf = {
.gpio_num = static_cast<gpio_num_t>(tx_pin),
.clk_src = RMT_CLK_SRC_DEFAULT,
.resolution_hz = 1000000, // 1MHz resolution, 1 tick = 1us
.mem_block_symbols = 64,
.trans_queue_depth = 4,
.intr_priority = 0,

.flags = {
.invert_out = 0, // do not invert output signal
.with_dma = 0,
.io_loop_back = 0,
.io_od_mode = 0,
} // do not need DMA backend
};
if (rmt_new_tx_channel(&txconf, &tx_channel) != ESP_OK) {
continue;
}

// todo overwrite with protocol data
float duty = 0.50;
uint8_t rptgap = 100;
if (receivedData.protocol == SONY) {
rptgap = 24;
duty = 0.40;
}

rmt_carrier_config_t carrier_cfg = {
.frequency_hz = proto[receivedData.protocol].frequency,
.duty_cycle = duty,

.flags = {
.polarity_active_low = 0,
.always_on = 0}};

rmt_apply_carrier(tx_channel, &carrier_cfg);
rmt_ir_encoder_t* ir_encoder = (rmt_ir_encoder_t*)calloc(1, sizeof(rmt_ir_encoder_t));
ir_encoder->base.encode = rmt_encode_ir;
ir_encoder->base.del = rmt_del_ir_encoder;
ir_encoder->base.reset = rmt_ir_encoder_reset;

rmt_copy_encoder_config_t copy_encoder_config = {};
rmt_new_copy_encoder(&copy_encoder_config, &ir_encoder->copy_encoder);

rmt_encoder_handle_t encoder_handle = &ir_encoder->base;

rmt_enable(tx_channel);

rmt_transmit_config_t tx_config = {
.loop_count = 0,
.flags = {
.eot_level = 0,
.queue_nonblocking = 0,
}};

uint8_t burst = 1; // not really needed

for (uint8_t j = 0; j < receivedData.repeat; j++) {
for (uint8_t i = 0; i < burst; i++) {
rmt_transmit(tx_channel, encoder_handle, &receivedData, sizeof(ir_data_t), &tx_config);
rmt_tx_wait_all_done(tx_channel, portMAX_DELAY);
vTaskDelay(rptgap / portTICK_PERIOD_MS);
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}

rmt_disable(tx_channel);
rmt_del_channel(tx_channel);
rmt_del_encoder(encoder_handle);
}
}
}
71 changes: 71 additions & 0 deletions Source/main/tir.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef __TIR_H
#define __TIR_H

#include <stdint.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "driver/rmt_rx.h"
#include "driver/rmt_tx.h"
#include "driver/rmt_encoder.h"

enum irproto {
UNK,
NEC,
SONY,
SAM,
RC5,
PROTO_COUNT
};

typedef struct ir_data {
irproto protocol;
uint32_t addr;
uint32_t data;
uint8_t repeat;
uint8_t bits;
} ir_data_t;

typedef struct
{
uint16_t header_high;
uint16_t header_low;
uint16_t one_high;
uint16_t one_low;
uint16_t zero_high;
uint16_t zero_low;
uint16_t footer_high;
uint8_t footer_low;
uint16_t frequency;
const char* name;
uint8_t bits;
} ir_protocol_t;

typedef struct
{
rmt_encoder_t base;
rmt_encoder_t* copy_encoder;
uint8_t bit_index;
int state;
} rmt_ir_encoder_t;

class TIR {
public:
TIR();
~TIR();
void init(gpio_num_t tx, gpio_num_t rx); // initializes ir rx,tx

void send(irproto protocol, uint32_t addr, uint32_t data); // add data to a send queut, that is parsed from a thread that manages sending. queue max size is 5
void send(ir_data_t data); // add data to a send queut, that is parsed from a thread that manages sending. queue max size is 5

private:
static void create_symbol(rmt_symbol_word_t& item, uint16_t high, uint16_t low, bool bit);
static size_t rmt_encode_ir(rmt_encoder_t* encoder, rmt_channel_handle_t channel, const void* primary_data, size_t data_size, rmt_encode_state_t* ret_state);
static void processSendTask(void* pvParameters);
static const ir_protocol_t proto[PROTO_COUNT];
static QueueHandle_t sendQueue;
static gpio_num_t tx_pin;
};

#endif
2 changes: 2 additions & 0 deletions Source/sdkconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2179,6 +2179,8 @@ CONFIG_IC2SCLPIN=4
CONFIG_IC2SDAPIN=5
CONFIG_I2C_SLAVE_SCL_IO=10
CONFIG_I2C_SLAVE_SDA_IO=11
CONFIG_IR_RX_PIN=12
CONFIG_IR_TX_PIN=13
# end of ESP32PP

#
Expand Down

0 comments on commit ceaa44a

Please sign in to comment.