From 7910c788961441558d7776a38ba7630686a2bd21 Mon Sep 17 00:00:00 2001
From: Jochen Vothknecht <jochen3120@gmail.com>
Date: Mon, 4 Apr 2022 10:49:59 +0200
Subject: [PATCH] =?UTF-8?q?Trying=20another=20approach=E2=80=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../{CyanBus.cpp => CyanBusBREAK.cpp}         |   2 +-
 .../{CyanBus.hpp => CyanBusBREAK.hpp}         |   2 +-
 CLC-qthing/SiliconTorch/CyanBusTOUT.cpp       | 204 ++++++++++++++++++
 CLC-qthing/SiliconTorch/CyanBusTOUT.hpp       |  62 ++++++
 CLC-qthing/device_main.cpp                    |   4 +-
 5 files changed, 270 insertions(+), 4 deletions(-)
 rename CLC-qthing/SiliconTorch/{CyanBus.cpp => CyanBusBREAK.cpp} (99%)
 rename CLC-qthing/SiliconTorch/{CyanBus.hpp => CyanBusBREAK.hpp} (97%)
 create mode 100644 CLC-qthing/SiliconTorch/CyanBusTOUT.cpp
 create mode 100644 CLC-qthing/SiliconTorch/CyanBusTOUT.hpp

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 0985a70..0775ab8 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 b10cc65..6392ef0 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 0000000..53adce2
--- /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 0000000..aabcfb9
--- /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 082d198..5b5a073 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: ???
 
-- 
GitLab