Forráskód Böngészése

Basic serial protocol framework, breaks serial input for now

Scott Bezek 4 éve
szülő
commit
81ef1e677f

+ 24 - 53
firmware/src/interface_task.cpp

@@ -1,5 +1,3 @@
-#include <AceButton.h>
-
 #if SK_LEDS
 #include <FastLED.h>
 #endif
@@ -15,8 +13,6 @@
 #include "interface_task.h"
 #include "util.h"
 
-using namespace ace_button;
-
 #define COUNT_OF(A) (sizeof(A) / sizeof(A[0]))
 
 #if SK_LEDS
@@ -127,7 +123,9 @@ InterfaceTask::InterfaceTask(const uint8_t task_core, MotorTask& motor_task, Dis
         Task("Interface", 2048, 1, task_core),
         stream_(),
         motor_task_(motor_task),
-        display_task_(display_task) {
+        display_task_(display_task),
+        plaintext_protocol_(stream_),
+        proto_protocol_(stream_) {
     #if SK_DISPLAY
         assert(display_task != nullptr);
     #endif
@@ -140,24 +138,6 @@ InterfaceTask::~InterfaceTask() {}
 
 void InterfaceTask::run() {
     stream_.begin();
-
-    #if PIN_BUTTON_NEXT >= 34
-        pinMode(PIN_BUTTON_NEXT, INPUT);
-    #else
-        pinMode(PIN_BUTTON_NEXT, INPUT_PULLUP);
-    #endif
-    AceButton button_next((uint8_t) PIN_BUTTON_NEXT);
-    button_next.getButtonConfig()->setIEventHandler(this);
-
-    #if PIN_BUTTON_PREV > -1
-        #if PIN_BUTTON_PREV >= 34
-            pinMode(PIN_BUTTON_PREV, INPUT);
-        #else
-            pinMode(PIN_BUTTON_PREV, INPUT_PULLUP);
-        #endif
-        AceButton button_prev((uint8_t) PIN_BUTTON_PREV);
-        button_prev.getButtonConfig()->setIEventHandler(this);
-    #endif
     
     #if SK_LEDS
         FastLED.addLeds<SK6812, PIN_LED_DATA, GRB>(leds, NUM_LEDS);
@@ -182,22 +162,30 @@ void InterfaceTask::run() {
 
     motor_task_.setConfig(configs[0]);
 
-    log("Interface starting.\nPress 'C' at any time to run calibration.");
+
+    // Start in legacy protocol mode
+    plaintext_protocol_.init();
+    SerialProtocol* current_protocol = &plaintext_protocol_;
+
+    ProtocolChangeCallback protocol_change_callback = [this, &current_protocol] (uint8_t protocol) {
+        switch (protocol) {
+            case SERIAL_PROTOCOL_LEGACY:
+                current_protocol = &plaintext_protocol_;
+                break;
+            case SERIAL_PROTOCOL_PROTO:
+                current_protocol = &proto_protocol_;
+                break;
+            default:
+                log("Unknown protocol requested");
+                break;
+        }
+    };
+
+    plaintext_protocol_.setProtocolChangeCallback(protocol_change_callback);
+    proto_protocol_.setProtocolChangeCallback(protocol_change_callback);
 
     // Interface loop:
     while (1) {
-        button_next.check();
-        #if PIN_BUTTON_PREV > -1
-            button_prev.check();
-        #endif
-        if (stream_.available()) {
-            int v = stream_.read();
-            if (v == ' ') {
-                changeConfig(true);
-            } else if (v == 'C') {
-                motor_task_.runCalibration();
-            }
-        }
         std::string* log_string;
         while (xQueueReceive(log_queue_, &log_string, 0) == pdTRUE) {
             stream_.println(log_string->c_str());
@@ -210,23 +198,6 @@ void InterfaceTask::run() {
     }
 }
 
-void InterfaceTask::handleEvent(AceButton* button, uint8_t event_type, uint8_t button_state) {
-    switch (event_type) {
-        case AceButton::kEventPressed:
-            if (button->getPin() == PIN_BUTTON_NEXT) {
-                changeConfig(true);
-            }
-            #if PIN_BUTTON_PREV > -1
-                if (button->getPin() == PIN_BUTTON_PREV) {
-                    changeConfig(false);
-                }
-            #endif
-            break;
-        case AceButton::kEventReleased:
-            break;
-    }
-}
-
 void InterfaceTask::log(const char* msg) {
     // Allocate a string for the duration it's in the queue; it is free'd by the queue consumer
     std::string* msg_str = new std::string(msg);

+ 5 - 2
firmware/src/interface_task.h

@@ -6,17 +6,18 @@
 #include "display_task.h"
 #include "logger.h"
 #include "motor_task.h"
+#include "serial/serial_protocol_plaintext.h"
+#include "serial/serial_protocol_protobuf.h"
 #include "serial/uart_stream.h"
 #include "task.h"
 
-class InterfaceTask : public Task<InterfaceTask>, public Logger, public ace_button::IEventHandler {
+class InterfaceTask : public Task<InterfaceTask>, public Logger {
     friend class Task<InterfaceTask>; // Allow base Task to invoke protected run()
 
     public:
         InterfaceTask(const uint8_t task_core, MotorTask& motor_task, DisplayTask* display_task);
         ~InterfaceTask();
 
-        void handleEvent(ace_button::AceButton* button, uint8_t event_type, uint8_t button_state) override;
         void log(const char* msg) override;
 
     protected:
@@ -31,6 +32,8 @@ class InterfaceTask : public Task<InterfaceTask>, public Logger, public ace_butt
         int current_config_ = 0;
 
         QueueHandle_t log_queue_;
+        SerialProtocolPlaintext plaintext_protocol_;
+        SerialProtocolProtobuf proto_protocol_;
 
         void changeConfig(bool next);
         void updateHardware();

+ 28 - 0
firmware/src/serial/serial_protocol.h

@@ -0,0 +1,28 @@
+#pragma once
+
+#include <functional>
+
+#include "../logger.h"
+#include "../proto_gen/smartknob.pb.h"
+
+#define SERIAL_PROTOCOL_LEGACY 0
+#define SERIAL_PROTOCOL_PROTO 1
+
+typedef std::function<void(uint8_t)> ProtocolChangeCallback;
+
+class SerialProtocol : public Logger {
+    public:
+        SerialProtocol() : Logger() {}
+        virtual ~SerialProtocol(){}
+
+        virtual void loop() = 0;
+
+        virtual void handleState(const PB_SmartKnobState& state) = 0;
+
+        virtual void setProtocolChangeCallback(ProtocolChangeCallback cb) {
+            protocol_change_callback_ = cb;
+        }
+    
+    protected:
+        ProtocolChangeCallback protocol_change_callback_;
+};

+ 34 - 0
firmware/src/serial/serial_protocol_plaintext.cpp

@@ -0,0 +1,34 @@
+#include "../proto_gen/smartknob.pb.h"
+
+#include "serial_protocol_plaintext.h"
+
+void SerialProtocolPlaintext::handleState(const PB_SmartKnobState& state) {
+    latest_state_ = state;
+}
+
+void SerialProtocolPlaintext::log(const char* msg) {
+    stream_.print("LOG: ");
+    stream_.println(msg);
+}
+
+void SerialProtocolPlaintext::loop() {
+    while (stream_.available() > 0) {
+        int b = stream_.read();
+        if (b == 0) {
+            if (protocol_change_callback_) {
+                protocol_change_callback_(SERIAL_PROTOCOL_PROTO);
+            }
+            break;
+        }
+        // TODO: implement calibration and mode change here
+        // if (v == ' ') {
+        //     changeConfig(true);
+        // } else if (v == 'C') {
+        //     motor_task_.runCalibration();
+        // }
+    }
+}
+
+void SerialProtocolPlaintext::init() {
+    stream_.println("SmartKnob starting!\n\nSerial mode: plaintext\nPress 'C' at any time to calibrate.\nPress <Space> to change haptic modes.");
+}

+ 21 - 0
firmware/src/serial/serial_protocol_plaintext.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include "../proto_gen/smartknob.pb.h"
+
+#include "serial_protocol.h"
+#include "uart_stream.h"
+
+class SerialProtocolPlaintext : public SerialProtocol {
+    public:
+        SerialProtocolPlaintext(Stream& stream) : SerialProtocol(), stream_(stream) {}
+        ~SerialProtocolPlaintext(){}
+        void log(const char* msg) override;
+        void loop() override;
+        void handleState(const PB_SmartKnobState& state) override;
+
+        void init();
+    
+    private:
+        Stream& stream_;
+        PB_SmartKnobState latest_state_ = {};
+};

+ 15 - 0
firmware/src/serial/serial_protocol_protobuf.cpp

@@ -0,0 +1,15 @@
+#include "../proto_gen/smartknob.pb.h"
+
+#include "serial_protocol_protobuf.h"
+
+void SerialProtocolProtobuf::handleState(const PB_SmartKnobState& state) {
+}
+
+void SerialProtocolProtobuf::log(const char* msg) {
+}
+
+void SerialProtocolProtobuf::loop() {
+}
+
+void SerialProtocolProtobuf::init() {
+}

+ 20 - 0
firmware/src/serial/serial_protocol_protobuf.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#include "../proto_gen/smartknob.pb.h"
+
+#include "serial_protocol.h"
+#include "uart_stream.h"
+
+class SerialProtocolProtobuf : public SerialProtocol {
+    public:
+        SerialProtocolProtobuf(Stream& stream) : SerialProtocol(), stream_(stream) {}
+        ~SerialProtocolProtobuf(){}
+        void log(const char* msg) override;
+        void loop() override;
+        void handleState(const PB_SmartKnobState& state) override;
+
+        void init();
+    
+    private:
+        Stream& stream_;
+};