diff --git a/CLC-qthing/SiliconTorch/CyanBus.cpp b/CLC-qthing/SiliconTorch/CyanBusBREAK.cpp similarity index 99% rename from CLC-qthing/SiliconTorch/CyanBus.cpp rename to CLC-qthing/SiliconTorch/CyanBusBREAK.cpp index 0985a7059ee3ff3dd114e641ddcf84d9ba0c6d48..0775ab8b3c4b39f46e3e29f76605f733cdcaefc5 100644 --- a/CLC-qthing/SiliconTorch/CyanBus.cpp +++ b/CLC-qthing/SiliconTorch/CyanBusBREAK.cpp @@ -36,7 +36,7 @@ namespace SiliconTorch { // // } - namespace CyanBus { + namespace CyanBusBREAK { // CyanBus envelope header const uint8_t* const HEADER = (const uint8_t*)"fxCyan"; diff --git a/CLC-qthing/SiliconTorch/CyanBus.hpp b/CLC-qthing/SiliconTorch/CyanBusBREAK.hpp similarity index 97% rename from CLC-qthing/SiliconTorch/CyanBus.hpp rename to CLC-qthing/SiliconTorch/CyanBusBREAK.hpp index b10cc652f535d1437d596c5f57a9cdbc4f29a12d..6392ef0db0c5ed5c17d9a956c776e0bbb6b9fad2 100644 --- a/CLC-qthing/SiliconTorch/CyanBus.hpp +++ b/CLC-qthing/SiliconTorch/CyanBusBREAK.hpp @@ -15,7 +15,7 @@ namespace SiliconTorch { - namespace CyanBus { + namespace CyanBusBREAK { // CyanBus payload MTU // This leads to ~54 P/s @ 2 MBaud at 100% load diff --git a/CLC-qthing/SiliconTorch/CyanBusTOUT.cpp b/CLC-qthing/SiliconTorch/CyanBusTOUT.cpp new file mode 100644 index 0000000000000000000000000000000000000000..53adce2b6cecce3527558232cedcba2271b2c161 --- /dev/null +++ b/CLC-qthing/SiliconTorch/CyanBusTOUT.cpp @@ -0,0 +1,204 @@ +#include "CyanBus.hpp" + +// C++ system level +#include <cstring> // memset +#include <cstdlib> // TODO: is this for memcpy? +#include <cinttypes> +#include <functional> + +// ESP32 specific +#include "esp_log.h" +#include "driver/gpio.h" +#include "driver/uart.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" + +// project specific +#include "LambdaTask.hpp" + +// qthing stuff +// #include "" + + + +static const char* TAG = "CyanBus"; + +#include "esp_err.h" +namespace SiliconTorch { + +// namespace Impl { +// +// typedef struct { +// bool crcOK; +// uint16_t length; +// uint8_t payload[CyanBus::MTU]; +// } CyanData; +// +// } + + namespace CyanBusTOUT { + + // CyanBus envelope header + const uint8_t* const HEADER = (const uint8_t*)"fxCyan"; + + + CyanBus::CyanBus(uint8_t tx, uint8_t rx, uint8_t de, uint8_t re, uint32_t baudRate, uint8_t uartChannel) : tx(tx), rx(rx), de(de), re(re), uartChannel(uartChannel) { + + + uint64_t bitMask = 0; + + bitMask |= 1 << tx; + bitMask |= 1 << de; + bitMask |= 1 << re; + + gpio_config_t gpio = { + .pin_bit_mask = bitMask, + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + + // configure outputs + gpio_config(&gpio); + txrxEN(false); + + gpio.pin_bit_mask = 1 << rx; + gpio.mode = GPIO_MODE_INPUT; + + // configure inputs + gpio_config(&gpio); + + + uart_config_t uartConfig = { + .baud_rate = (int)baudRate, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .rx_flow_ctrl_thresh = 0, + .use_ref_tick = false, + // .source_clk = UART_SCLK_APB, + }; + + + uart_port_t _ch = (uart_port_t)uartChannel; + + ESP_ERROR_CHECK(uart_param_config(_ch, &uartConfig)); + ESP_ERROR_CHECK(uart_set_pin(_ch, tx, rx, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); + //uart_intr_config(_ch); + + ESP_ERROR_CHECK(uart_driver_install(_ch, MTU, 0, 0, NULL, 0)); + + ESP_ERROR_CHECK(uart_set_mode(_ch, UART_MODE_UART)); + uart_set_rx_timeout(_ch, 0); // TODO: timeout…?? + + + // TOOD: receive only ATM! + txEN(false); + rxEN(true); + + + readerTaskHandle = new Util::LambdaTask([&](){ readerTask(); }); + + // packetQ = xQueueCreate(3, sizeof(Impl::CyanData)); + packetQ = xQueueCreate(3, 4096); + packetTaskHandle = new Util::LambdaTask([&](){ packetTask(); }); + } + + void CyanBus::readerTask() { + + uart_port_t _ch = (uart_port_t)uartChannel; + + uint32_t bufLEN = MTU; + uint8_t* buffer = new uint8_t[bufLEN]; // our packet buffer + uint8_t* bufPTR = buffer; // points inside our buffer; used for envelope parsing… + // uint16_t payloadLEN = 0; + + std::memset(buffer, 0x00, bufLEN); + + + /* enum FSM { SearchHeader, ReadLength, ReadPayload, CheckCRC }; + FSM fsm = SearchHeader; + + uint8_t headerLength = std::strlen(HEADER); + uint32_t headerByteNum = 0; */ + + auto Q2 = packetQ; + + while (true) { + + uint32_t packetLEN = bufPTR - buffer; + + // what happens when we try to read 0 bytes??? + auto bytes = uart_read_bytes(_ch, bufPTR, MTU - packetLEN, 5); // 5 = ms Tout; TODO: make configurable and smaller + + if (bytes > 0) { + + bufPTR += bytes; + + } else { + + ESP_LOGI(TAG, "Received Tout Ⱐafter reading %d bytes", bufPTR - buffer); + xQueueSendToBack(Q2, buffer, portMAX_DELAY); + bufPTR = buffer; + + } + } + + delete buffer; + } + + void CyanBus::packetTask() { + ESP_LOGW(TAG, "TODO: implement callback task!"); + + uint8_t* buffer = new uint8_t[MTU]; + + auto Q = packetQ; + while (true) { + + if (xQueueReceive(Q, buffer, (TickType_t)portMAX_DELAY)) { + + // TODO: handle packet! + + char strbuf[17]; + strbuf[16] = 0x00; + + std::memcpy(strbuf, buffer, 16); + + ESP_LOGI(TAG, "PACKET DEBUG: Starts with [ %s ]", strbuf); + + // TODO: really handle packet! + } + } + } + + void CyanBus::setBaudRate(uint32_t baudRate) { + uart_set_baudrate((uart_port_t)uartChannel, baudRate); + } + + uint32_t CyanBus::getBaudRate() { + uint32_t baudRate = 0; + uart_get_baudrate((uart_port_t)uartChannel, &baudRate); + return baudRate; + } + + + void CyanBus::txEN(bool state) { + gpio_set_level((gpio_num_t)de, state); + } + + void CyanBus::rxEN(bool state) { + gpio_set_level((gpio_num_t)re, state ^ 1); + } + + void CyanBus::txrxEN(bool state) { + txEN(state); + rxEN(state); + } + + } +} + + + diff --git a/CLC-qthing/SiliconTorch/CyanBusTOUT.hpp b/CLC-qthing/SiliconTorch/CyanBusTOUT.hpp new file mode 100644 index 0000000000000000000000000000000000000000..aabcfb9bed97e43526bdc1bece04c4ebe35813a0 --- /dev/null +++ b/CLC-qthing/SiliconTorch/CyanBusTOUT.hpp @@ -0,0 +1,62 @@ +#pragma once + +// C++ system level +#include <string> +#include <cinttypes> +#include <functional> + +// ESP32 specific +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" + +// project specific +#include "LambdaTask.hpp" + + +namespace SiliconTorch { + + namespace CyanBusTOUT { + + // CyanBus payload MTU + // This leads to ~54 P/s @ 2 MBaud at 100% load + constexpr uint32_t MTU = 4096; + + // CyanBus envelope header + extern const uint8_t* const HEADER; + + + class CyanBus { + public: + CyanBus(uint8_t tx, uint8_t rx, uint8_t de, uint8_t re, uint32_t baudRate = 115200, uint8_t uartChannel = 1); + + uint32_t getBaudRate(); + void setBaudRate(uint32_t baudRate); + + private: + + QueueHandle_t packetQ; + + uint8_t uartChannel; + uint8_t tx, rx, de, re; + + void txEN(bool state); + void rxEN(bool state); + void txrxEN(bool state); + + + // Receive only ATM! (make public after sound implementation…) + void write(std::string& data); + void write(const uint8_t* data, uint32_t length); + + + + + void readerTask(); + void packetTask(); + + Util::LambdaTask* readerTaskHandle = NULL; + Util::LambdaTask* packetTaskHandle = NULL; + + }; + } +} diff --git a/CLC-qthing/device_main.cpp b/CLC-qthing/device_main.cpp index 082d19840c1151692c85f49f0bec431274e65ef0..5b5a073a1659a6d77b52969636e86a16140553c3 100644 --- a/CLC-qthing/device_main.cpp +++ b/CLC-qthing/device_main.cpp @@ -9,7 +9,7 @@ #include "CyanLight.hpp" -#include "SiliconTorch/CyanBus.hpp" +#include "SiliconTorch/CyanBusTOUT.hpp" qthing::Config cfg; @@ -22,7 +22,7 @@ void device_main() { qthing::power_managment_max_power(); - SiliconTorch::CyanBus::CyanBus cyanBus(13, 14, 12, 15); // Pinout of CyanStripe + SiliconTorch::CyanBusTOUT::CyanBus cyanBus(13, 14, 12, 15); // Pinout of CyanStripe // TODO: ???