diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..bdffccd
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 LaCocoRoco
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9ed5819
--- /dev/null
+++ b/README.md
@@ -0,0 +1,446 @@
+# DataVisualizer
+This library is intended to simplify the use from Microchip Data Visualizer via the Atmel Data Protocol.
+The Atmel Data Protocol is a content independent protocol intended for transferring data from a target MCU to a host PC.
+The connection can be established via a Serial Port or the Data Gateway Interface (EDBG-based Debugger).
+
+## Quick Guide
+1. Download Michrochip Data Visualizer. `Link`
+2. Download Arduino Data Visualizer Library.
+3. Open Arduino, select default example, compile and upload project.
+4. Open Data Visualizer, select Serial Port Panel and press Connect.
+
+## Known Issues
+- No Y-Values displayed in Graph Visualization
+> In the left Top Corner select Configuration.
+> At the bottom in Configuration Window switch Theme (Dark/Light).
+- Not all possible Graph Settings are available
+> The Graph Module is bad supported.
+> This is related to the Atmel Data Protocol.
+- After connect there is a ADP Control Panel but nothing else
+> This sometimes happens at a Baudrate of 9600. Just push Disconnect & Connect again.
+
+## Roadmap
+- [x] Add Gateway Uart
+- [x] Add Gateway Twi
+- [x] Add Gateway Spi
+- [x] Add Gateway Callabck
+- [x] Add Module Info
+- [x] Add Module Terminal
+- [x] Add Module Graph
+- [x] Add Module Graph Axis
+- [x] Add Module Graph Axis Channel
+- [x] Add Module Graph Axis Cursor
+- [x] Add Module Dashboard
+- [x] Add Module Dashboard Label
+- [x] Add Module Dashboard Button
+- [x] Add Module Dashboard Numeric Input
+- [x] Add Module Dashboard Signal
+- [x] Add Module Dashboard Radio Group
+- [x] Add Module Dashboard Graph
+- [ ] Add Module Dashboard Table
+- [ ] Add Module Dashboard Check Box
+- [ ] Add Module Dashboard Slider
+- [ ] Add Module Dashboard Progress Bar
+- [ ] Add Module Dashboard Segment Display
+- [ ] Add Module Dashboard Pie Chart
+- [ ] Add Module Dashboard Surface Grid
+- [ ] Add Module Dashboard Rectangle
+
+## Reference
+- `Data Visualizer User's Guid (HTML)`
+- `Data Visualizer User's Guid (PDF)`
+- `Microchip Data Visualizer`
+
+
+## Usage
+- [Gateway](#gateway)
+- [Common](#common)
+- [Info](#info)
+- [Terminal](#terminal)
+- [Graph](#graph)
+- [Dashboard](#dashboard)
+- [Literal](#literal)
+
+### Gateway
+- #### Universal Asynchronous Receiver Transmitter (Serial)
+```cpp
+// Setup Uart Default (GATEWAY_SERIAL)
+Visualizer.begin(GATEWAY_UART);
+
+// Setup Uart Customized
+Serial.begin(DEFAULT_UART_BAUDRATE);
+Visualizer.begin(&Serial);
+```
+
+- #### Two Wire Interface
+```cpp
+// Setup Twi Default
+Visualizer.begin(GATEWAY_TWI);
+
+// Setup Twi Customized
+Wire.begin();
+Visualizer.begin(&Wire, DEFAULT_TWI_ADDRESS);
+```
+
+- #### Serial Peripheral Interface
+```cpp
+// Setup Spi Default
+Visualizer.begin(GATEWAY_SPI);
+
+// Setup Spi Customized
+SPISettings settings(DEFAULT_SPI_FREQUENCY, MSBFIRST, SPI_MODE0);
+SPI.begin();
+Visualizer.begin(&SPI, settings, SS);
+```
+
+- #### External Interface
+```cpp
+// Setup External
+Visualizer.begin(GATEWAY_EXTERN);
+Visualizer.onTransmit(&transmit);
+Visualizer.onReceive(&receive);
+Visualizer.onTransceive(&transceive);
+
+// External Transmit
+void transmit(uint8_t* txBuffer, uint16_t length);
+
+// External Receive
+uint16_t receive(uint8_t* rxBuffer, uint16_t length);
+
+// External Transceive
+uint16_t transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length);
+
+```
+
+### Common
+```cpp
+// Element Setup Handler Configuration None
+if(Visualizer.setup(CONFIGURATION_NONE)) {
+ // initialize elements
+}
+
+// Element Setup Handler Configuration Autostart
+if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ // initialize elements
+}
+
+// Data Visualizer Handshake Request
+ if(Visualizer.request()) {
+ // handshake accepted
+ }
+
+// Data Visualizer Reset
+Visualizer.reset();
+
+// Request Data From Data Visualizer
+Visualizer.refresh();
+```
+
+### Info
+```cpp
+// Add Atmel Data Protocol Environment Information
+Visualizer.addInfo("My Visualizer", "My Environment");
+```
+
+### Terminal
+```cpp
+// Add Terminal
+Terminal terminal = Visualizer.addTerminal("My Terminal");
+
+// Read Single Byte From Terminal
+while(terminal.available()) {
+ char c = terminal.read();
+}
+
+// Read All Bytes From Terminal
+while(terminal.available()) {
+ char text[terminal.available()];
+ terminal.read(text);
+}
+
+// Print Data In Terminal Console
+terminal.print("My Text");
+
+// Print Data In Terminal Console Carriage Return
+terminal.println("My Text");
+```
+
+### Graph
+```cpp
+// Add Graph
+Graph graph = Visualizer.addGraph("My Graph");
+
+// Add Axis
+GraphAxis graphAxis = graph.addAxis("My Axis");
+
+// Add Channel
+GraphAxisChannel graphAxisChannel = graphAxis.addChannel("My Channel");
+
+// Add Cursor
+GraphAxisCursor graphAxisCursor = graphAxis.addCursor("My Cursor");
+
+// Send Data To Channel
+graphAxisChannel.write(number);
+
+// Cursor Data Changed
+GraphAxisCursor.feed();
+
+// Read Data From Cursor
+GraphAxisCursor.read();
+```
+
+### Dashboard
+```cpp
+// Add Dashboard
+Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+```
+- #### Label
+```cpp
+// Config Label
+ConfigDashboardLabel configDashboardLabel = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 100,
+ .height = 25,
+ .fontSize = 20,
+ .attribute = BOLD_ON_ITALIC_OFF,
+ .aligmentHorisontal = HORISONTAL_ALIGNMENT_CENTER,
+ .aligmentVertical = VERTICAL_ALIGNMENT_CENTER,
+ .backgroundColor = COLOR_WHITE,
+ .backgroundAlpha = 0,
+ .forgroundColor = COLOR_BLACK,
+ .forgroundAlpha = 255
+};
+
+// Add Label
+dashboard.addLabel("MyLabel", configDashboardLabel);
+```
+- #### Button
+```cpp
+// Config Button
+ConfigDashboardButton configDashboardButton = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 150,
+ .height = 50,
+ .fontSize = 20
+};
+
+// Add Button
+DashboardButton dashboardButton = dashboard.addButton("MyButton", configDashboardButton);
+
+// Add Toggle Button
+DashboardButton dashboardButton = dashboard.addButton("MyOn", "MyOff", configDashboardButton);
+
+// Button Pressed
+dashboardButton.pressed();
+
+// Button Toggled State
+dashboardButton.toggled();
+```
+- #### Numeric Input
+```cpp
+// Config Numeric Input
+ConfigDashboardNumericInput configDashboardNumericInput = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 150,
+ .height = 50,
+ .fontSize = 20
+};
+
+// Add Numeric Input
+DashboardNumericInput dashboardNumericInput = dashboard.addNumericInput(configDashboardNumericInput);
+
+// Numeric Input New Data
+dashboardNumericInput.feed();
+
+// Read Numeric Data
+dashboardNumericInput.read();
+```
+- #### Signal
+```cpp
+// Config Signal
+ConfigDashboardSignal configDashboardSignal = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 50,
+ .height = 50,
+ .onColor = COLOR_RED,
+ .onAlpha = 255,
+ .offColor = COLOR_GREEN,
+ .offAlpha = 255
+};
+
+// Add Signal
+DashboardSignal dashboardSignal = dashboard.addSignal(configDashboardSignal);
+
+// Set Signal On
+dashboardSignal.on();
+
+// Set Signal Off
+dashboardSignal.off();
+```
+- #### Radio Group
+```cpp
+// Config Radio Group
+ConfigDashboardRadioGroup configDashboardRadioGroup = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 15,
+ .height = 150,
+ .sizeItems = 10,
+ .numberItems = 6,
+ .orientation = HORIZONTAL
+};
+
+// Add Signal
+DashboardRadioGroup dashboardRadioGroup = dashboard.addRadioGroup(configDashboardRadioGroup);
+
+// Radio Group New Data
+dashboardRadioGroup.feed();
+
+// Read Radio Group Data
+dashboardRadioGroup.selected();
+```
+- #### Graph
+```cpp
+// Config Graph
+ConfigDashboardGraph configDashboardGraph = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 400,
+ .height = 200,
+ .titleColor = COLOR_WHITE,
+ .backgroundColor = COLOR_BLACK,
+ .graphBackgroundColor = COLOR_BLACK,
+ .plotCount = 1,
+ .xMinimum = 0,
+ .xMaximum = 10,
+ .yMinimum = -1000,
+ .yMaximum = +1000,
+ .mouseInteraction = true,
+ .fitToRight = false,
+ .autoscale = false,
+ .scrollByTime = true,
+ .showPlot = true,
+ .showPoints = false
+};
+
+// Add Graph
+DashboardGraph dashboardGraph = dashboard.addGraph("My Graph", configDashboardGraph);
+
+// Add Channel
+DashboardGraphChannel dashboardGraphChannel = dashboardGraph.addChannel("My Channel A");
+
+// Read Radio Group Data
+dashboardGraphChannel.write(number);
+```
+- #### Predefined Configuration
+```cpp
+/* Data Visualizer has the possibility to predefine a Dashboard.
+ * 1. Start Data Visualizer.
+ * 2. On the top left corner press "Configuration".
+ * 3. In Modules select "Visualization" and then "Custom Dashboard".
+ * 4. In the "Dashboard Panel" on the bottom left press "Edit".
+ * 5. In the "Dashboard Panel" on the right side expand "Elements".
+ * 6. Create your own Dashboard.
+ * 7. In the "Dashboard Panel" on the bottom press "Save".
+ * 8. The configuration per element will be saved as byte arrays.
+ * 9. Use the configuration file in combination with the Visualizer.
+ **/
+
+// Dashboard Configuration Example Button
+byte configDashboardButton[] = {
+ 0, // Dashboard ID
+ 0, // Element ID
+ DB_TYPE_BUTTON, // Element Type
+ 0, // Z-Index (GUI stack order)
+ 50, 0, // X-coordinate
+ 50, 0, // Y-coordinate
+ 150, 0, // Width
+ 50, 0, // Height
+ 20, // Font Size
+ 'M', 'y', 'B', 'u', 't', 't', 'o', 'n', '\0', // Text
+ 0,
+};
+
+// Add Button Via Configuration
+DashboardButton dashboardButton = dashboard.addButton(configDashboardButton);
+```
+
+### Literal
+```cpp
+CONFIGURATION_NONE
+CONFIGURATION_AUTOSTART
+
+GATEWAY_EXTERNAL
+GATEWAY_TWI
+GATEWAY_SPI
+GATEWAY_UART
+GATEWAY_SERIAL
+
+BAUDRATE_9600
+BAUDRATE_19200
+BAUDRATE_38400
+BAUDRATE_57600
+BAUDRATE_115200
+BAUDRATE_230400
+BAUDRATE_500000
+BAUDRATE_1000000
+BAUDRATE_2000000
+
+COLOR_WHITE
+COLOR_BLACK
+COLOR_SILVER
+COLOR_GRAY
+COLOR_MAROON
+COLOR_RED
+COLOR_PURPLE
+COLOR_FUCHSIA
+COLOR_GREEN
+COLOR_LIME
+COLOR_OLIVE
+COLOR_YELLOW
+COLOR_NAVY
+COLOR_BLUE
+COLOR_TEAL
+COLOR_AQUA
+COLOR_ORANGE
+
+BOLD_OFF_ITALIC_OFF
+BOLD_ON_ITALIC_OFF
+BOLD_OFF_ITALIC_ON
+BOLD_ON_ITALIC_ON
+
+HORISONTAL_ALIGNMENT_LEFT
+HORISONTAL_ALIGNMENT_CENTER
+HORISONTAL_ALIGNMENT_RIGHT
+
+VERTICAL_ALIGNMENT_TOP
+VERTICAL_ALIGNMENT_CENTER
+VERTICAL_ALIGNMENT_BOTTOM
+
+HORIZONTAL
+VERTICAL
+
+DB_TYPE_LABEL
+DB_TYPE_BUTTON
+DB_TYPE_TEXT
+DB_TYPE_SIGNAL
+DB_TYPE_RADIOGROUP
+
+DEFAULT_UART_BAUDRATE
+DEFAULT_UART_TIMEOUT
+DEFAULT_TWI_ADDRESS
+DEFAULT_TWI_FREQUENCY
+DEFAULT_TWI_TIMEOUT
+DEFAULT_SPI_FREQUENCY
+DEFAULT_VIEW
+```
\ No newline at end of file
diff --git a/examples/defaultExample/defaultExample.ino b/examples/defaultExample/defaultExample.ino
new file mode 100644
index 0000000..cd1b7ab
--- /dev/null
+++ b/examples/defaultExample/defaultExample.ino
@@ -0,0 +1,54 @@
+#include
+
+Terminal terminal;
+GraphAxisChannel graphAxisChannel;
+GraphAxisCursor cursor;
+int valueChannel, valueCursor;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ /****************************************************************/
+ /* WARNING: Initializing elements blocks process. */
+ /****************************************************************/
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ /* add atmel data protocol environment info */
+ Visualizer.addInfo("My Visualizer", "My Environment");
+ /* add terminal */
+ terminal = Visualizer.addTerminal("My Terminal");
+ /* add graph, axis, channel & cursor */
+ Graph graph = Visualizer.addGraph("My Graph");
+ GraphAxis axis = graph.addAxis("My Axis");
+ graphAxisChannel = axis.addChannel("My Channel");
+ cursor = axis.addCursor("My Cursor");
+ }
+
+ /* only read data if necessary */
+ while(terminal.available()) {
+ /* read text from terminal */
+ char text[terminal.available()];
+ terminal.read(text);
+ /* convert text into integer */
+ String string = String(text);
+ valueChannel = string.toInt();
+ /* write text to terminal console */
+ string = "Terminal Input: " + string;
+ terminal.println(string.c_str());
+
+ }
+
+ /* only write data if value changed */
+ if(cursor.read() != valueCursor) {
+ /* read value from cursor */
+ valueCursor = cursor.read();
+ /* write cursor value to terminal */
+ String string = String(valueCursor);
+ string = "Cursor Input: " + string;
+ terminal.println(string.c_str());
+ }
+
+ /* write terminal value to channel */
+ graphAxisChannel.write(valueChannel);
+}
\ No newline at end of file
diff --git a/examples/defaultExamplePredefinedDashboard/defaultExamplePredefinedDashboard.ino b/examples/defaultExamplePredefinedDashboard/defaultExamplePredefinedDashboard.ino
new file mode 100644
index 0000000..2a89142
--- /dev/null
+++ b/examples/defaultExamplePredefinedDashboard/defaultExamplePredefinedDashboard.ino
@@ -0,0 +1,135 @@
+#include
+
+/* Data Visualizer has the possibility to predefine a Dashboard.
+ * 1. Start Data Visualizer.
+ * 2. On the top left corner press "Configuration".
+ * 3. In Modules select "Visualization" and then "Custom Dashboard".
+ * 4. In the "Dashboard Panel" on the bottom left press "Edit".
+ * 5. In the "Dashboard Panel" on the right side expand "Elements".
+ * 6. Create your own Dashboard.
+ * 7. In the "Dashboard Panel" on the bottom press "Save".
+ * 8. The configuration per element will be saved as byte arrays.
+ * 9. Use the configuration file in combination with the Visualizer.
+ **/
+
+DashboardNumericInput dashboardNumericInput;
+DashboardButton dashboardButton;
+DashboardGraphChannel dashboardGraphChannel;
+int value;
+
+void setup() {
+ value = 0;
+
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ /****************************************************************/
+ /* WARNING: Initializing elements blocks process. */
+ /****************************************************************/
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+
+ byte configDashboardLabelTop[] = {
+ 0, // Dashboard ID
+ 0, // Element ID
+ DB_TYPE_LABEL, // Element Type
+ 0, // Z-Index (GUI stack order)
+ 50, 0, // X-coordinate
+ 50, 0, // Y-coordinate
+ 250, 0, // Width
+ 30, 0, // Height
+ 20, // Font Size
+ 1,
+ 0, // Horizontal Alignment
+ 0, // Vertical Alignment
+ 0, 255, 255, 255, // Background Color
+ 255, 0, 0, 0, // Foreground Color
+ 'M', 'y', ' ', 'P', 'r', 'e', 'd', 'e', 'f', 'i', 'n', 'e', 'd', ' ', 'D', 'a', 's', 'h', 'b', 'o', 'a', 'r', 'd', '\0', // Text
+ };
+ dashboard.addLabel(configDashboardLabelTop);
+
+ byte configDashboardGraph[] = {
+ 0, // Dashboard ID
+ 1, // Element ID
+ DB_TYPE_GRAPH, // Element Type
+ 0, // Z-Index (GUI stack order)
+ 50, 0, // X-coordinate
+ 80, 0, // Y-coordinate
+ 104, 1, // Width
+ 250, 0, // Height
+ 255, 255, 255, // Title color
+ 0, 0, 0, // Background color
+ 20, 20, 20, // Graph background color
+ 'M', 'y', ' ', 'G', 'r', 'a', 'p', 'h', '\0', // Title
+ 1, // Number of plots
+ 0, 0, 0, 0, // X Minimum
+ 0, 0, 32, 65, // X Maximum
+ 0, 0, 122, 196, // Y Minimum
+ 0, 0, 122, 68, // Y Maximum
+ 1,
+ 1,
+ };
+ DashboardGraph dashboardGraph = dashboard.addGraph(configDashboardGraph);
+ dashboardGraphChannel = dashboardGraph.addChannel("My Channel");
+
+ byte configDashboardNumericInput[] = {
+ 0, // Dashboard ID
+ 2, // Element ID
+ DB_TYPE_TEXT, // Element Type
+ 1, // Z-Index (GUI stack order)
+ 210, 0, // X-coordinate
+ 134, 1, // Y-coordinate
+ 60, 0, // Width
+ 20, 0, // Height
+ 24, 252, 255, 255, // Minimum
+ 232, 3, 0, 0, // Maximum
+ 0, 0, 0, 0, // Value
+ };
+ dashboardNumericInput = dashboard.addNumericInput(configDashboardNumericInput);
+
+ byte configDashboardLabelValue[] = {
+ 0, // Dashboard ID
+ 3, // Element ID
+ DB_TYPE_LABEL, // Element Type
+ 0, // Z-Index (GUI stack order)
+ 50, 0, // X-coordinate
+ 134, 1, // Y-coordinate
+ 160, 0, // Width
+ 20, 0, // Height
+ 15, // Font Size
+ 0,
+ 0, // Horizontal Alignment
+ 1, // Vertical Alignment
+ 0, 255, 255, 255, // Background Color
+ 255, 0, 0, 0, // Foreground Color
+ 'O', 'v', 'e', 'r', 'r', 'i', 'd', 'e', ' ', 'G', 'r', 'a', 'p', 'h', ' ', 'V', 'a', 'l', 'u', 'e', ':', '\0', // Text
+ };
+ dashboard.addLabel(configDashboardLabelValue);
+
+ byte configDashboardButton[] = {
+ 0, // Dashboard ID
+ 4, // Element ID
+ DB_TYPE_BUTTON, // Element Type
+ 0, // Z-Index (GUI stack order)
+ 44, 1, // X-coordinate
+ 134, 1, // Y-coordinate
+ 110, 0, // Width
+ 20, 0, // Height
+ 12, // Font Size
+ 'R', 'e', 's', 'e', 't', ' ', 'G', 'r', 'a', 'p', 'h', ' ', 'V', 'a', 'l', 'u', 'e', '\0', // Text
+ 0,
+ };
+ dashboardButton = dashboard.addButton(configDashboardButton);
+ }
+
+ if(dashboardNumericInput.feed()) {
+ value = dashboardNumericInput.read();
+ }
+
+ if(dashboardButton.pressed()) {
+ value = 0;
+ }
+
+ dashboardGraphChannel.write(value);
+}
\ No newline at end of file
diff --git a/examples/gatewaySetupExternal/gatewaySetupExternal.ino b/examples/gatewaySetupExternal/gatewaySetupExternal.ino
new file mode 100644
index 0000000..e71bfee
--- /dev/null
+++ b/examples/gatewaySetupExternal/gatewaySetupExternal.ino
@@ -0,0 +1,24 @@
+#include
+
+void transmit(uint8_t* txBuffer, uint16_t length) {
+
+}
+
+uint16_t receive(uint8_t* rxBuffer, uint16_t length) {
+
+}
+
+uint16_t transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length) {
+
+}
+
+void setup() {
+ Visualizer.begin(GATEWAY_EXTERN);
+ Visualizer.onTransmit(&transmit);
+ Visualizer.onReceive(&receive);
+ Visualizer.onTransceive(&transceive);
+}
+
+void loop() {
+
+}
\ No newline at end of file
diff --git a/examples/gatewaySetupSpi/gatewaySetupSpi.ino b/examples/gatewaySetupSpi/gatewaySetupSpi.ino
new file mode 100644
index 0000000..7aac78d
--- /dev/null
+++ b/examples/gatewaySetupSpi/gatewaySetupSpi.ino
@@ -0,0 +1,9 @@
+#include
+
+void setup() {
+ Visualizer.begin(GATEWAY_SPI);
+}
+
+void loop() {
+
+}
diff --git a/examples/gatewaySetupSpiCustomized/gatewaySetupSpiCustomized.ino b/examples/gatewaySetupSpiCustomized/gatewaySetupSpiCustomized.ino
new file mode 100644
index 0000000..c515ea0
--- /dev/null
+++ b/examples/gatewaySetupSpiCustomized/gatewaySetupSpiCustomized.ino
@@ -0,0 +1,13 @@
+#include
+
+void setup() {
+ SPISettings settings(DEFAULT_SPI_FREQUENCY, MSBFIRST, SPI_MODE0);
+
+ SPI.begin();
+
+ Visualizer.begin(&SPI, settings, SS);
+}
+
+void loop() {
+
+}
diff --git a/examples/gatewaySetupTwi/gatewaySetupTwi.ino b/examples/gatewaySetupTwi/gatewaySetupTwi.ino
new file mode 100644
index 0000000..2c146fc
--- /dev/null
+++ b/examples/gatewaySetupTwi/gatewaySetupTwi.ino
@@ -0,0 +1,9 @@
+#include
+
+void setup() {
+ Visualizer.begin(GATEWAY_TWI);
+}
+
+void loop() {
+
+}
\ No newline at end of file
diff --git a/examples/gatewaySetupTwiCustomized/gatewaySetupTwiCustomized.ino b/examples/gatewaySetupTwiCustomized/gatewaySetupTwiCustomized.ino
new file mode 100644
index 0000000..0526fde
--- /dev/null
+++ b/examples/gatewaySetupTwiCustomized/gatewaySetupTwiCustomized.ino
@@ -0,0 +1,11 @@
+#include
+
+void setup() {
+ Wire.begin();
+
+ Visualizer.begin(&Wire, DEFAULT_TWI_ADDRESS);
+}
+
+void loop() {
+
+}
\ No newline at end of file
diff --git a/examples/gatewaySetupUart/gatewaySetupUart.ino b/examples/gatewaySetupUart/gatewaySetupUart.ino
new file mode 100644
index 0000000..c1ed49c
--- /dev/null
+++ b/examples/gatewaySetupUart/gatewaySetupUart.ino
@@ -0,0 +1,9 @@
+#include
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+
+}
diff --git a/examples/gatewaySetupUartCustomized/gatewaySetupUartCustomized.ino b/examples/gatewaySetupUartCustomized/gatewaySetupUartCustomized.ino
new file mode 100644
index 0000000..04c17aa
--- /dev/null
+++ b/examples/gatewaySetupUartCustomized/gatewaySetupUartCustomized.ino
@@ -0,0 +1,11 @@
+#include
+
+void setup() {
+ Serial.begin(DEFAULT_UART_BAUDRATE);
+
+ Visualizer.begin(&Serial);
+}
+
+void loop() {
+
+}
diff --git a/examples/moduleDashboard/moduleDashboard.ino b/examples/moduleDashboard/moduleDashboard.ino
new file mode 100644
index 0000000..42b93a3
--- /dev/null
+++ b/examples/moduleDashboard/moduleDashboard.ino
@@ -0,0 +1,14 @@
+#include
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ /****************************************************************/
+ /* WARNING: Initializing elements blocks process. */
+ /****************************************************************/
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+ }
+}
\ No newline at end of file
diff --git a/examples/moduleDashboardButton/moduleDashboardButton.ino b/examples/moduleDashboardButton/moduleDashboardButton.ino
new file mode 100644
index 0000000..d0af7a6
--- /dev/null
+++ b/examples/moduleDashboardButton/moduleDashboardButton.ino
@@ -0,0 +1,30 @@
+#include
+
+Terminal terminal;
+DashboardButton dashboardButton;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+ terminal = Visualizer.addTerminal("My Terminal");
+
+ ConfigDashboardButton configDashboardButton = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 150,
+ .height = 50,
+ .fontSize = 20
+ };
+
+ dashboardButton = dashboard.addButton("My Button", configDashboardButton);
+ }
+
+ if(dashboardButton.pressed()) {
+ terminal.println("My Button Pressed");
+ }
+}
\ No newline at end of file
diff --git a/examples/moduleDashboardButtonToggled/moduleDashboardButtonToggled.ino b/examples/moduleDashboardButtonToggled/moduleDashboardButtonToggled.ino
new file mode 100644
index 0000000..386945e
--- /dev/null
+++ b/examples/moduleDashboardButtonToggled/moduleDashboardButtonToggled.ino
@@ -0,0 +1,34 @@
+#include
+
+Terminal terminal;
+DashboardButton dashboardButton;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+ terminal = Visualizer.addTerminal("My Terminal");
+
+ ConfigDashboardButton configDashboardButton = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 150,
+ .height = 50,
+ .fontSize = 20
+ };
+
+ dashboardButton = dashboard.addButton("MyOn", "MyOff", configDashboardButton);
+ }
+
+ if(dashboardButton.pressed()) {
+ if(dashboardButton.toggled()) {
+ terminal.println("My Button Toggled On");
+ } else {
+ terminal.println("My Button Toggled Off");
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/moduleDashboardGraph/moduleDashboardGraph.ino b/examples/moduleDashboardGraph/moduleDashboardGraph.ino
new file mode 100644
index 0000000..68f0706
--- /dev/null
+++ b/examples/moduleDashboardGraph/moduleDashboardGraph.ino
@@ -0,0 +1,41 @@
+#include
+
+DashboardGraphChannel dashboardGraphChannel;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+
+ ConfigDashboardGraph configDashboardGraph = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 400,
+ .height = 200,
+ .titleColor = COLOR_WHITE,
+ .backgroundColor = COLOR_BLACK,
+ .graphColor = COLOR_BLACK,
+ .plotCount = 1,
+ .xMinimum = 0,
+ .xMaximum = 10,
+ .yMinimum = -1000,
+ .yMaximum = +1000,
+ .mouseInteraction = true,
+ .fitToRight = false,
+ .autoscale = false,
+ .scrollByTime = true,
+ .showPlot = true,
+ .showPoints = false
+ };
+
+ DashboardGraph dashboardGraph = dashboard.addGraph("My Graph", configDashboardGraph);
+
+ dashboardGraphChannel = dashboardGraph.addChannel("My Channel");
+ }
+
+ dashboardGraphChannel.write(500);
+}
\ No newline at end of file
diff --git a/examples/moduleDashboardLabel/moduleDashboardLabel.ino b/examples/moduleDashboardLabel/moduleDashboardLabel.ino
new file mode 100644
index 0000000..af1fbbc
--- /dev/null
+++ b/examples/moduleDashboardLabel/moduleDashboardLabel.ino
@@ -0,0 +1,31 @@
+#include
+
+Terminal terminal;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+
+ ConfigDashboardLabel configDashboardLabel = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 100,
+ .height = 25,
+ .fontSize = 20,
+ .attribute = BOLD_ON_ITALIC_OFF,
+ .aligmentHorisontal = HORISONTAL_ALIGNMENT_CENTER,
+ .aligmentVertical = VERTICAL_ALIGNMENT_CENTER,
+ .backgroundColor = COLOR_WHITE,
+ .backgroundAlpha = 0,
+ .forgroundColor = COLOR_BLACK,
+ .forgroundAlpha = 255
+ };
+
+ dashboard.addLabel("MyLabel", configDashboardLabel);
+ }
+}
\ No newline at end of file
diff --git a/examples/moduleDashboardNumericInput/moduleDashboardNumericInput.ino b/examples/moduleDashboardNumericInput/moduleDashboardNumericInput.ino
new file mode 100644
index 0000000..78f40a0
--- /dev/null
+++ b/examples/moduleDashboardNumericInput/moduleDashboardNumericInput.ino
@@ -0,0 +1,33 @@
+#include
+
+Terminal terminal;
+DashboardNumericInput dashboardNumericInput;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+ terminal = Visualizer.addTerminal("My Terminal");
+
+ ConfigDashboardNumericInput configDashboardNumericInput = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 100,
+ .height = 20,
+ .minimum = -100,
+ .maximum = +100,
+ .value = 0
+ };
+
+ dashboardNumericInput = dashboard.addNumericInput(configDashboardNumericInput);
+ }
+
+ if(dashboardNumericInput.feed()) {
+ terminal.print("Numeric Input Value: ");
+ terminal.println(dashboardNumericInput.read());
+ }
+}
\ No newline at end of file
diff --git a/examples/moduleDashboardRadioGroup/moduleDashboardRadioGroup.ino b/examples/moduleDashboardRadioGroup/moduleDashboardRadioGroup.ino
new file mode 100644
index 0000000..1caf12b
--- /dev/null
+++ b/examples/moduleDashboardRadioGroup/moduleDashboardRadioGroup.ino
@@ -0,0 +1,32 @@
+#include
+
+Terminal terminal;
+DashboardRadioGroup dashboardRadioGroup;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+ terminal = Visualizer.addTerminal("My Terminal");
+
+ ConfigDashboardRadioGroup configDashboardRadioGroup = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 15,
+ .height = 150,
+ .sizeItems = 10,
+ .numberItems = 6,
+ .orientation = VERTICAL
+ };
+
+ dashboardRadioGroup = dashboard.addRadioGroup(configDashboardRadioGroup);
+ }
+
+ if(dashboardRadioGroup.feed()) {
+ terminal.println(dashboardRadioGroup.selected());
+ }
+}
\ No newline at end of file
diff --git a/examples/moduleDashboardSignal/moduleDashboardSignal.ino b/examples/moduleDashboardSignal/moduleDashboardSignal.ino
new file mode 100644
index 0000000..6779ef6
--- /dev/null
+++ b/examples/moduleDashboardSignal/moduleDashboardSignal.ino
@@ -0,0 +1,42 @@
+#include
+
+DashboardSignal dashboardSignal;
+
+long tick;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ /****************************************************************/
+ /* WARNING: Initializing elements blocks process. */
+ /****************************************************************/
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Dashboard dashboard = Visualizer.addDashboard("My Dashboard");
+
+ ConfigDashboardSignal configDashboardSignal = {
+ .zIndex = 0,
+ .x = 50,
+ .y = 50,
+ .width = 50,
+ .height = 50,
+ .onColor = COLOR_RED,
+ .onAlpha = 255,
+ .offColor = COLOR_GREEN,
+ .offAlpha = 255
+ };
+
+ dashboardSignal = dashboard.addSignal(configDashboardSignal);
+ }
+
+ tick++;
+
+ if(tick > 2000) tick = 0;
+
+ if(tick < 1000) {
+ dashboardSignal.on();
+ } else {
+ dashboardSignal.off();
+ }
+}
\ No newline at end of file
diff --git a/examples/moduleGraph/moduleGraph.ino b/examples/moduleGraph/moduleGraph.ino
new file mode 100644
index 0000000..a9a77e4
--- /dev/null
+++ b/examples/moduleGraph/moduleGraph.ino
@@ -0,0 +1,23 @@
+#include
+
+GraphAxisChannel graphAxisChannel;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ /****************************************************************/
+ /* WARNING: Initializing elements blocks process. */
+ /****************************************************************/
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Graph graph = Visualizer.addGraph("My Graph");
+ GraphAxis graphAxis = graph.addAxis("My Axis");
+ graphAxisChannel = graphAxis.addChannel("My Channel");
+ }
+
+ /****************************************************************/
+ /* Write data to channel. */
+ /****************************************************************/
+ graphAxisChannel.write(10000);
+}
\ No newline at end of file
diff --git a/examples/moduleInfo/moduleInfo.ino b/examples/moduleInfo/moduleInfo.ino
new file mode 100644
index 0000000..5e6ac2f
--- /dev/null
+++ b/examples/moduleInfo/moduleInfo.ino
@@ -0,0 +1,14 @@
+#include
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ /****************************************************************/
+ /* WARNING: Initializing elements blocks process. */
+ /****************************************************************/
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ Visualizer.addInfo("My Visualizer", "My Environment");
+ }
+}
\ No newline at end of file
diff --git a/examples/moduleTerminal/moduleTerminal.ino b/examples/moduleTerminal/moduleTerminal.ino
new file mode 100644
index 0000000..abed77d
--- /dev/null
+++ b/examples/moduleTerminal/moduleTerminal.ino
@@ -0,0 +1,24 @@
+#include
+
+Terminal terminal;
+
+void setup() {
+ Visualizer.begin(GATEWAY_SERIAL);
+}
+
+void loop() {
+ /****************************************************************/
+ /* WARNING: Initializing elements blocks process. */
+ /****************************************************************/
+ if(Visualizer.setup(CONFIGURATION_AUTOSTART)) {
+ terminal = Visualizer.addTerminal("My Terminal");
+ }
+
+ /****************************************************************/
+ /* Read data from terminal and write to terminal console */
+ /****************************************************************/
+ while(terminal.available()) {
+ char c = terminal.read();
+ terminal.println(c);
+ }
+}
\ No newline at end of file
diff --git a/extras/DataVisualizer.pdf b/extras/DataVisualizer.pdf
new file mode 100644
index 0000000..568b542
Binary files /dev/null and b/extras/DataVisualizer.pdf differ
diff --git a/keywords.txt b/keywords.txt
new file mode 100644
index 0000000..99b6791
--- /dev/null
+++ b/keywords.txt
@@ -0,0 +1,196 @@
+######################################
+# Main KEYWORD1 #
+######################################
+Visualizer KEYWORD1
+
+######################################
+# Classes KEYWORD1 #
+######################################
+Terminal KEYWORD1
+Graph KEYWORD1
+GraphAxis KEYWORD1
+GraphAxisChannel KEYWORD1
+GraphAxisCursor KEYWORD1
+Dashboard KEYWORD1
+DashboardLabel KEYWORD1
+DashboardButton KEYWORD1
+DashboardNumericInput KEYWORD1
+DashboardSignal KEYWORD1
+DashboardRadioGroup KEYWORD1
+DashboardGraph KEYWORD1
+DashboardGraphChannel KEYWORD1
+
+######################################
+# Configuration KEYWORD1 #
+######################################
+ConfigDashboardLabel KEYWORD1
+ConfigDashboardButton KEYWORD1
+ConfigDashboardNumericInput KEYWORD1
+ConfigDashboardSignal KEYWORD1
+ConfigDashboardRadioGroup KEYWORD1
+ConfigDashboardGraph KEYWORD1
+
+######################################
+# Interface KEYWORD2 #
+######################################
+transmit KEYWORD2
+receive KEYWORD2
+transceive KEYWORD2
+onTransmit KEYWORD2
+onReceive KEYWORD2
+onTransceive KEYWORD2
+
+######################################
+# Visualizer KEYWORD2 #
+######################################
+request KEYWORD2
+reset KEYWORD2
+refresh KEYWORD2
+addInfo KEYWORD2
+addTerminal KEYWORD2
+addGraph KEYWORD2
+addDashboard KEYWORD2
+
+######################################
+# Terminal KEYWORD2 #
+######################################
+available KEYWORD2
+read KEYWORD2
+print KEYWORD2
+println KEYWORD2
+
+######################################
+# Graph KEYWORD2 #
+######################################
+addAxis KEYWORD2
+
+######################################
+# GraphAxis KEYWORD2 #
+######################################
+addChannel KEYWORD2
+addCursor KEYWORD2
+
+######################################
+# GraphAxisChannel KEYWORD2 #
+######################################
+write KEYWORD2
+
+######################################
+# GraphAxisCursor KEYWORD2 #
+######################################
+read KEYWORD2
+feed KEYWORD2
+
+######################################
+# Dashboard KEYWORD2 #
+######################################
+addButton KEYWORD2
+addNumericInput KEYWORD2
+addLabel KEYWORD2
+addSignal KEYWORD2
+addRadioGroup KEYWORD2
+addGraph
+
+######################################
+# DashboardButton KEYWORD2 #
+######################################
+pressed KEYWORD2
+toggled KEYWORD2
+
+######################################
+# DashboardNumericalInput KEYWORD2 #
+######################################
+read KEYWORD2
+feed KEYWORD2
+
+######################################
+# DashboardSignal KEYWORD2 #
+######################################
+on KEYWORD2
+off KEYWORD2
+
+######################################
+# DashboardRadioGroup KEYWORD2 #
+######################################
+selected KEYWORD2
+feed KEYWORD2
+
+######################################
+# DashboardGraph KEYWORD2 #
+######################################
+addChannel KEYWORD2
+
+######################################
+# DashboardGraphChannel KEYWORD2 #
+######################################
+write KEYWORD2
+
+######################################
+# General LITERAL1 #
+######################################
+CONFIGURATION_NONE LITERAL1
+CONFIGURATION_AUTOSTART LITERAL1
+
+GATEWAY_EXTERNAL LITERAL1
+GATEWAY_TWI LITERAL1
+GATEWAY_SPI LITERAL1
+GATEWAY_UART LITERAL1
+GATEWAY_SERIAL LITERAL1
+
+BAUDRATE_9600 LITERAL1
+BAUDRATE_19200 LITERAL1
+BAUDRATE_38400 LITERAL1
+BAUDRATE_57600 LITERAL1
+BAUDRATE_115200 LITERAL1
+BAUDRATE_230400 LITERAL1
+BAUDRATE_500000 LITERAL1
+BAUDRATE_1000000 LITERAL1
+BAUDRATE_2000000 LITERAL1
+
+COLOR_WHITE LITERAL1
+COLOR_BLACK LITERAL1
+COLOR_SILVER LITERAL1
+COLOR_GRAY LITERAL1
+COLOR_MAROON LITERAL1
+COLOR_RED LITERAL1
+COLOR_PURPLE LITERAL1
+COLOR_FUCHSIA LITERAL1
+COLOR_GREEN LITERAL1
+COLOR_LIME LITERAL1
+COLOR_OLIVE LITERAL1
+COLOR_YELLOW LITERAL1
+COLOR_NAVY LITERAL1
+COLOR_BLUE LITERAL1
+COLOR_TEAL LITERAL1
+COLOR_AQUA LITERAL1
+COLOR_ORANGE LITERAL1
+
+BOLD_OFF_ITALIC_OFF LITERAL1
+BOLD_ON_ITALIC_OFF LITERAL1
+BOLD_OFF_ITALIC_ON LITERAL1
+BOLD_ON_ITALIC_ON LITERAL1
+
+HORISONTAL_ALIGNMENT_LEFT LITERAL1
+HORISONTAL_ALIGNMENT_CENTER LITERAL1
+HORISONTAL_ALIGNMENT_RIGHT LITERAL1
+
+VERTICAL_ALIGNMENT_TOP LITERAL1
+VERTICAL_ALIGNMENT_CENTER LITERAL1
+VERTICAL_ALIGNMENT_BOTTOM LITERAL1
+
+HORIZONTAL LITERAL1
+VERTICAL LITERAL1
+
+DB_TYPE_LABEL LITERAL1
+DB_TYPE_BUTTON LITERAL1
+DB_TYPE_TEXT LITERAL1
+DB_TYPE_SIGNAL LITERAL1
+DB_TYPE_RADIOGROUP LITERAL1
+
+DEFAULT_UART_BAUDRATE LITERAL1
+DEFAULT_UART_TIMEOUT LITERAL1
+DEFAULT_TWI_ADDRESS LITERAL1
+DEFAULT_TWI_FREQUENCY LITERAL1
+DEFAULT_TWI_TIMEOUT LITERAL1
+DEFAULT_SPI_FREQUENCY LITERAL1
+DEFAULT_VIEW LITERAL1
\ No newline at end of file
diff --git a/library.properties b/library.properties
new file mode 100644
index 0000000..14dbcdb
--- /dev/null
+++ b/library.properties
@@ -0,0 +1,9 @@
+name=DataVisualizer
+version=1.0.0
+author=Deiring Andreas
+maintainer=Deiring Andreas
+sentence=This library is intended to simplify the use from Microchip Data Visualizer via the Atmel Data Protocol.
+paragraph=The Atmel Data Protocol is a content independent protocol intended for transferring data from a target MCU to a host PC. The connection can be established via a Serial Port or the Data Gateway Interface (EDBG-based Debugger).
+category=Communication
+url=https://github.com/LaCocoRoco/DataVisualizer
+architectures=*
\ No newline at end of file
diff --git a/src/AtmelDataGateway.h b/src/AtmelDataGateway.h
new file mode 100644
index 0000000..71d49c4
--- /dev/null
+++ b/src/AtmelDataGateway.h
@@ -0,0 +1,26 @@
+#ifndef ATMEL_DATA_GATEWAY_H
+#define ATMEL_DATA_GATEWAY_H
+
+#ifdef __has_include
+
+#if __has_include()
+#define GATEWAY_INCLUDED_TWI
+#endif
+
+#if __has_include()
+#define GATEWAY_INCLUDED_UART
+#endif
+
+#if __has_include()
+#define GATEWAY_INCLUDED_SPI
+#endif
+
+#else
+
+#define GATEWAY_INCLUDED_UART
+#define GATEWAY_INCLUDED_TWI
+#define GATEWAY_INCLUDED_SPI
+
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/AtmelDataGatewaySpi.cpp b/src/AtmelDataGatewaySpi.cpp
new file mode 100644
index 0000000..02c1a49
--- /dev/null
+++ b/src/AtmelDataGatewaySpi.cpp
@@ -0,0 +1,44 @@
+#include "AtmelDataGatewaySpi.h"
+
+#ifdef GATEWAY_INCLUDED_SPI
+
+void AtmelDataGatewaySpi::begin(void) {
+ SPISettings settings(DEFAULT_SPI_FREQUENCY, MSBFIRST, SPI_MODE0);
+ SPI.begin();
+ this->begin(&SPI, settings, SS);
+}
+
+void AtmelDataGatewaySpi::begin(SPIClass* spi, SPISettings settings, uint8_t ss) {
+ pinMode(ss, OUTPUT);
+ this->spi = spi;
+ this->ss = ss;
+ this->settings = settings;
+}
+
+void AtmelDataGatewaySpi::transmit(uint8_t* txBuffer, uint16_t length) {
+ digitalWrite(this->ss, LOW);
+ this->spi->beginTransaction(this->settings);
+ for(uint8_t i = 0; i < length; i++) this->spi->transfer(txBuffer[i]);
+ this->spi->endTransaction();
+ digitalWrite(this->ss, HIGH);
+}
+
+uint16_t AtmelDataGatewaySpi::receive(uint8_t* rxBuffer, uint16_t length) {
+ digitalWrite(this->ss, LOW);
+ this->spi->beginTransaction(this->settings);
+ for(uint8_t i = 0; i < length; i++) rxBuffer[i] = this->spi->transfer(DEFAULT_TOKEN);
+ this->spi->endTransaction();
+ digitalWrite(this->ss, HIGH);
+ return length;
+}
+
+uint16_t AtmelDataGatewaySpi::transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length) {
+ digitalWrite(this->ss, LOW);
+ this->spi->beginTransaction(this->settings);
+ for(uint8_t i = 0; i < length; i++) rxBuffer[i] = this->spi->transfer(txBuffer[i]);
+ this->spi->endTransaction();
+ digitalWrite(this->ss, HIGH);
+ return length;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/AtmelDataGatewaySpi.h b/src/AtmelDataGatewaySpi.h
new file mode 100644
index 0000000..d4f2d1b
--- /dev/null
+++ b/src/AtmelDataGatewaySpi.h
@@ -0,0 +1,33 @@
+#ifndef ATMEL_DATA_GATEWAY_INCLUDED_SPI_H
+#define ATMEL_DATA_GATEWAY_INCLUDED_SPI_H
+
+#include "AtmelDataGateway.h"
+
+#ifdef GATEWAY_INCLUDED_SPI
+
+#include "AtmelDataProtocol.h"
+
+#include
+#include
+
+#define DEFAULT_TWI_TIMEOUT 0
+#define DEFAULT_SPI_FREQUENCY 4000000
+#define DEFAULT_TOKEN ADP_TOKEN
+
+class AtmelDataGatewaySpi {
+ private:
+ SPIClass* spi;
+ SPISettings settings;
+ uint8_t ss;
+
+ public:
+ void begin(void);
+ void begin(SPIClass* spi, SPISettings settings, uint8_t ss);
+ void transmit(uint8_t* txBuffer, uint16_t length);
+ uint16_t receive(uint8_t* rxBuffer, uint16_t length);
+ uint16_t transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length);
+};
+
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/AtmelDataGatewayTwi.cpp b/src/AtmelDataGatewayTwi.cpp
new file mode 100644
index 0000000..4e37a58
--- /dev/null
+++ b/src/AtmelDataGatewayTwi.cpp
@@ -0,0 +1,36 @@
+#include "AtmelDataGatewayTwi.h"
+
+#ifdef GATEWAY_INCLUDED_TWI
+
+void AtmelDataGatewayTwi::begin(void) {
+ Wire.begin();
+ this->begin(&Wire, DEFAULT_TWI_ADDRESS);
+}
+
+void AtmelDataGatewayTwi::begin(TwoWire* twi, uint8_t address) {
+ this->address = address;
+ this->twi = twi;
+ this->twi->setTimeout(DEFAULT_TWI_TIMEOUT);
+}
+
+void AtmelDataGatewayTwi::transmit(uint8_t* txBuffer, uint16_t length) {
+ this->twi->beginTransmission(this->address);
+ this->twi->write(txBuffer, length);
+ this->twi->endTransmission();
+}
+
+uint16_t AtmelDataGatewayTwi::receive(uint8_t* rxBuffer, uint16_t length) {
+ this->twi->requestFrom(this->address, length);
+ uint16_t rxLength = this->twi->available();
+ if(!rxLength) return 0;
+ rxLength = rxLength > length ? length : rxLength;
+ this->twi->readBytes(rxBuffer, rxLength);
+ return rxLength;
+}
+
+uint16_t AtmelDataGatewayTwi::transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length) {
+ this->transmit(txBuffer, length);
+ return this->receive(rxBuffer, length);
+}
+
+#endif
\ No newline at end of file
diff --git a/src/AtmelDataGatewayTwi.h b/src/AtmelDataGatewayTwi.h
new file mode 100644
index 0000000..adbdf80
--- /dev/null
+++ b/src/AtmelDataGatewayTwi.h
@@ -0,0 +1,32 @@
+#ifndef ATMEL_DATA_GATEWAY_INCLUDED_TWI_H
+#define ATMEL_DATA_GATEWAY_INCLUDED_TWI_H
+
+#include "AtmelDataGateway.h"
+
+#ifdef GATEWAY_INCLUDED_TWI
+
+#include "AtmelDataProtocol.h"
+
+#include
+#include
+
+#define DEFAULT_TWI_TIMEOUT 0
+#define DEFAULT_TWI_ADDRESS 40
+#define DEFAULT_TWI_FREQUENCY 100000
+
+class AtmelDataGatewayTwi {
+ private:
+ TwoWire* twi;
+ uint8_t address;
+
+ public:
+ void begin(void);
+ void begin(TwoWire* twi, uint8_t address);
+ void transmit(uint8_t* txBuffer, uint16_t length);
+ uint16_t receive(uint8_t* rxBuffer, uint16_t length);
+ uint16_t transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length);
+};
+
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/AtmelDataGatewayUart.cpp b/src/AtmelDataGatewayUart.cpp
new file mode 100644
index 0000000..9fc63f3
--- /dev/null
+++ b/src/AtmelDataGatewayUart.cpp
@@ -0,0 +1,32 @@
+#include "AtmelDataGatewayUart.h"
+
+#ifdef GATEWAY_INCLUDED_UART
+
+void AtmelDataGatewayUart::begin(void) {
+ Serial.begin(DEFAULT_UART_BAUDRATE);
+ this->begin(&Serial);
+}
+
+void AtmelDataGatewayUart::begin(Stream* uart) {
+ this->uart = uart;
+ this->uart->setTimeout(DEFAULT_UART_TIMEOUT);
+}
+
+void AtmelDataGatewayUart::transmit(uint8_t* txBuffer, uint16_t length) {
+ this->uart->write(txBuffer, length);
+}
+
+uint16_t AtmelDataGatewayUart::receive(uint8_t* rxBuffer, uint16_t length) {
+ uint16_t rxLength = this->uart->available();
+ if(!rxLength) return 0;
+ rxLength = rxLength > length ? length : rxLength;
+ this->uart->readBytes(rxBuffer, rxLength);
+ return rxLength;
+}
+
+uint16_t AtmelDataGatewayUart::transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length) {
+ this->transmit(txBuffer, length);
+ return this->receive(rxBuffer, length);
+}
+
+#endif
\ No newline at end of file
diff --git a/src/AtmelDataGatewayUart.h b/src/AtmelDataGatewayUart.h
new file mode 100644
index 0000000..ceeb9cd
--- /dev/null
+++ b/src/AtmelDataGatewayUart.h
@@ -0,0 +1,40 @@
+#ifndef ATMEL_DATA_GATEWAY_INCLUDED_UART_H
+#define ATMEL_DATA_GATEWAY_INCLUDED_UART_H
+
+#include "AtmelDataGateway.h"
+
+#ifdef GATEWAY_INCLUDED_UART
+
+#include "AtmelDataProtocol.h"
+
+#include
+#include
+
+#define BAUDRATE_9600 9600
+#define BAUDRATE_19200 19200
+#define BAUDRATE_38400 38400
+#define BAUDRATE_57600 57600
+#define BAUDRATE_115200 115200
+#define BAUDRATE_230400 230400
+#define BAUDRATE_500000 500000
+#define BAUDRATE_1000000 1000000
+#define BAUDRATE_2000000 2000000
+
+#define DEFAULT_UART_BAUDRATE BAUDRATE_230400
+#define DEFAULT_UART_TIMEOUT 0
+
+class AtmelDataGatewayUart {
+ private:
+ Stream *uart;
+
+ public:
+ void begin(void);
+ void begin(Stream* uart);
+ void transmit(uint8_t* txBuffer, uint16_t length);
+ uint16_t receive(uint8_t* rxBuffer, uint16_t length);
+ uint16_t transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length);
+};
+
+#endif
+
+#endif
\ No newline at end of file
diff --git a/src/AtmelDataProtocol.cpp b/src/AtmelDataProtocol.cpp
new file mode 100644
index 0000000..c4ee968
--- /dev/null
+++ b/src/AtmelDataProtocol.cpp
@@ -0,0 +1,1274 @@
+#include "AtmelDataProtocol.h"
+
+AtmelDataProtocol::AtmelDataProtocol(void) {
+ this->lastReceivedMessageId = ADP_TOKEN;
+ this->packetReceived = false;
+ this->prevData = 0;
+}
+
+void AtmelDataProtocol::addAtmelDataGateway(AtmelDataGateway* gateway) {
+ this->gateway = gateway;
+}
+
+void AtmelDataProtocol::setColor(uint8_t *structMember, RgbColor color) {
+ structMember[0] = color.red;
+ structMember[1] = color.green;
+ structMember[2] = color.blue;
+}
+
+void AtmelDataProtocol::configureStreamGetDefaults(MsgConfigStream *const config) {
+ config->streamId = 0;
+ config->type = STREAM_UINT_8;
+ config->mode = STREAM_OUT;
+ config->state = STREAM_ON;
+}
+
+void AtmelDataProtocol::configureGraphGetDefaults(MsgConfigGraph *const config) {
+ config->graphId = 0;
+ config->xMin = 0;
+ config->xMax = 0;
+ config->xScaleNumerator = 0;
+ config->xScaleDenominator = 0;
+ /* Bug: Auto scaling results in bouncing y scale */
+ config->scaleMode = GRAPH_SCALE_OFF;
+ /* Bug: Scroll by time not working */
+ config->scrollMode = GRAPH_SCROLL_SCROLL;
+ setColor(config->backgroundColor, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::addAxisToGraphGetDefaults(MsgConfigAxis *const config) {
+ config->axisId = 0;
+ config->graphId = 0;
+ config->yMin = 0;
+ config->yMax = 0;
+ config->xScaleNumerator = 0;
+ config->xScaleDenominator = 0;
+ config->mode = 0;
+ setColor(config->color, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::addStreamToAxisGetDefaults(MsgAddStreamToAxis *const config) {
+ config->graphId = 0;
+ config->axisId = 0;
+ config->streamId = 0;
+ config->sampleRateNumerator = 0;
+ config->sampleRateDenominator = 0;
+ config->yScaleNumerator = 0;
+ config->yScaleDenominator = 0;
+ config->yOffset = 0;
+ config->transparency = 0;
+ config->mode = AXIS_LINE_bm;
+ config->lineThickness = 1;
+ setColor(config->lineColor, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::addCursorToGraphGetDefaults(MsgAddCursorToGraph *const config) {
+ config->streamId = 0;
+ config->graphId = 0;
+ config->axisId = 0;
+ config->thickness = 1;
+ config->initialValue = 0;
+ config->minimumValue = 0;
+ config->maximumValue = 0;
+ config->scaleNumerator = 0;
+ config->scaleDenominator = 0;
+ config->scaleOffset = 0;
+ config->lineStyle = 0;
+ setColor(config->color, COLOR_WHITE);
+}
+
+void AtmelDataProtocol::addGpioToGraphGetDefaults(MsgConfigGpioToGraph *const config) {
+ config->graphId = 0;
+ config->gpioNumber = 0;
+ config->groupId = 0;
+ config->transparency = 0;
+ config->mode = 0;
+ config->lineThickness = 1;
+ config->lineStyle = 0;
+ setColor(config->lineColorHighState, COLOR_WHITE);
+ setColor(config->lineColorLowState, COLOR_WHITE);
+}
+
+void AtmelDataProtocol::configureTerminalGetDefaults(MsgConfigTerminal *const config) {
+ config->terminalId = 0;
+ config->width = 80;
+ config->height = 25;
+ setColor(config->backgroundColor, COLOR_WHITE);
+ setColor(config->foregroundColor, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::addStreamToTerminalGetDefaults(MsgConfigAddStreamToTerminal *const config) {
+ config->terminalId = 0;
+ config->streamId = 0;
+ config->mode = 0;
+ setColor(config->textColor, COLOR_BLACK);
+ setColor(config->tagTextColor, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::configureDashboardGetDefaults(MsgConfigDahsboard *const config) {
+ config->dashboardId = 0;
+ config->height = 100;
+ setColor(config->color, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::configureDashboardElementGetDefaults(MsgConfigDashboardElementCommon *const config) {
+ config->dashboardId = 0;
+ config->elementId = 0;
+ config->zIndex = 0;
+ config->x = 0;
+ config->y = 0;
+ config->width = 0;
+ config->height = 0;
+}
+
+void AtmelDataProtocol::configureDashboardLabelGetDefaults(MsgConfigDashboardElementLabel *const config) {
+ configureDashboardElementGetDefaults((MsgConfigDashboardElementCommon *)config);
+ config->elementType = ELEMENT_TYPE_LABEL;
+ config->fontSize = 10;
+ config->attribute = 0;
+ config->horisontalAlignment = HORISONTAL_ALIGNMENT_LEFT;
+ config->verticalAlignment = VERTICAL_ALIGNMENT_CENTER;
+ config->backgroundTransparency = 0;
+ config->foregroundTransparency = 0;
+ setColor(config->backgroundColor, COLOR_BLACK);
+ setColor(config->foregroundColor, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::configureDashboardButtonGetDefaults(MsgConfigDashboardElementButton *const config) {
+ configureDashboardElementGetDefaults((MsgConfigDashboardElementCommon *)config);
+ config->elementType = ELEMENT_TYPE_BUTTON;
+ config->fontSize = 10;
+ config->toggle = 0;
+}
+
+void AtmelDataProtocol::configureDashboardTextGetDefaults(MsgConfigDashboardElementText *const config) {
+ configureDashboardElementGetDefaults((MsgConfigDashboardElementCommon *)config);
+ config->elementType = ELEMENT_TYPE_TEXT;
+ memset(config->minimum, 0, 4);
+ memset(config->maximum, 0, 4);
+ memset(config->value, 0, 4);
+}
+
+void AtmelDataProtocol::configureDashboardSliderGetDefaults(MsgConfigDashboardElementSlider *const config) {
+ configureDashboardElementGetDefaults((MsgConfigDashboardElementCommon *)config);
+ config->elementType = ELEMENT_TYPE_SLIDER;
+ config->minimumValue = 0;
+ config->maximumValue = 100;
+ config->initialValue = 0;
+}
+
+void AtmelDataProtocol::configureDashboardSignalGetDefaults(MsgConfigDashboardElementSignal *const config) {
+ configureDashboardElementGetDefaults((MsgConfigDashboardElementCommon *)config);
+ config->elementType = ELEMENT_TYPE_SIGNAL;
+ config->onTransparency = 0;
+ config->offTransparency = 0;
+ setColor(config->onColor, COLOR_WHITE);
+ setColor(config->offColor, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::configureDashboardPrograssGetDefaults(MsgConfigDashboardElementProgress *const config) {
+ configureDashboardElementGetDefaults((MsgConfigDashboardElementCommon *)config);
+ config->elemntType = ELEMENT_TYPE_PROGRESS;
+ config->minimumValue = 0;
+ config->maximumValue = 100;
+ config->initialValue = 0;
+ setColor(config->color, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::configureDashboardSegmentGetDefaults(MsgConfigDashboardElementSegment *const config) {
+ configureDashboardElementGetDefaults((MsgConfigDashboardElementCommon *)config);
+ config->elementType = ELEMENT_TYPE_SEGMENT;
+ config->segmentCount = 1;
+ config->base = 10;
+ config->transparency = 0;
+ setColor(config->color, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::configureDashboardGraphGetDefaults(MsgConfigDashboardElementGraph *const config) {
+ configureDashboardElementGetDefaults((MsgConfigDashboardElementCommon *)config);
+ config->elementType = ELEMENT_TYPE_GRAPH;
+ config->plotCount = 1;
+ config->xMin = 0;
+ config->xMax = 10;
+ config->yMin = 0;
+ config->yMax = 5;
+ config->mode.bit.autoscale = 0;
+ config->mode.bit.fitGraph = 1;
+ config->mode.bit.mouse = 0;
+ config->mode.bit.scrollByTime = 0;
+ config->mode.bit.showPlot = 0;
+ config->mode.bit.showPoints = 0;
+ setColor(config->titleColor, COLOR_WHITE);
+ setColor(config->backgroundColor, COLOR_BLACK);
+ setColor(config->graphBackgroundColor, COLOR_BLACK);
+}
+
+void AtmelDataProtocol::configureDashboardRadioGetDefaults(MsgConfigDashboardElementRadio *const config) {
+ configureDashboardElementGetDefaults((MsgConfigDashboardElementCommon *)config);
+ config->elementType = ELEMENT_TYPE_RADIO;
+ config->fontSize = 10;
+ config->numberItems = 1;
+ config->orientation = HORIZONTAL;
+}
+
+uint16_t AtmelDataProtocol::addSendByte(uint8_t *buffer, uint8_t index, uint8_t *data, uint16_t length) {
+ for(uint16_t i = 0; i < length; i++) {
+ if(*(data + i) == ADP_TOKEN) {
+ *(buffer + index) = ADP_TOKEN;
+ index++;
+ }
+ *(buffer + index) = *(data + i);
+ index++;
+ }
+
+ return index;
+}
+
+bool AtmelDataProtocol::addReceiveByte(uint8_t data) {
+ static uint8_t messageId;
+
+ if((rxState == RX_STATE_GOT_SYMBOL) && (data != ADP_TOKEN)) {
+ /* Abort packet reception, new packet incoming */
+ rxState = RX_STATE_WAIT_LENGTH_LSB;
+ }
+
+ switch(rxState) {
+ case RX_STATE_IDLE:
+ packetReceived = false;
+ lastReceivedMessageId = 0xFF;
+ /* We are waiting for a new packet. */
+ if(data != ADP_TOKEN) {
+ return false;
+ }
+ /* Got start symbol, wait for message ID */
+ rxState = RX_STATE_WAIT_MSG_ID;
+ return false;
+
+ case RX_STATE_WAIT_MSG_ID:
+ if(data == ADP_TOKEN) {
+ /* Restart. Don't change state. Wait for new message ID */
+ return false;
+ }
+ messageId = data;
+ rxState = RX_STATE_WAIT_LENGTH_LSB;
+ return false;
+
+ case RX_STATE_WAIT_LENGTH_LSB:
+ if(data == ADP_TOKEN) {
+ if(prevData != ADP_TOKEN) {
+ prevData = ADP_TOKEN;
+ return false;
+ }
+ }
+ lengthReceived = data;
+ rxState = RX_STATE_WAIT_LENGTH_MSB;
+ prevData = 0;
+ return false;
+
+ case RX_STATE_WAIT_LENGTH_MSB:
+ if(data == ADP_TOKEN) {
+ if(prevData != ADP_TOKEN) {
+ prevData = ADP_TOKEN;
+ return false;
+ }
+ }
+ lengthReceived += (uint16_t)data << 8;
+ prevData = 0;
+ /* Got valid length, do we expect data? */
+ if(lengthReceived == 0) {
+ /* No data here, wait for next packet */
+ rxState = RX_STATE_IDLE;
+ packetReceived = true;
+ lastReceivedMessageId = messageId;
+ return false;
+ }
+
+ /* Wait for packet data */
+ bytesReceived = 0;
+ rxState = RX_STATE_GET_DATA;
+ return false;
+
+ case RX_STATE_GET_DATA:
+ case RX_STATE_GOT_SYMBOL:
+ if((data == ADP_TOKEN) && (rxState == RX_STATE_GET_DATA)) {
+ rxState = RX_STATE_GOT_SYMBOL;
+ return false;
+ }
+ /* Add new data to rx buffer */
+ bytesReceived++;
+ /* Are we done yet? */
+
+ if(bytesReceived >= lengthReceived || lengthReceived > MSG_RES_DATA_MAX_LEN) {
+ /* Yes we are! */
+ packetReceived = true;
+ rxState = RX_STATE_IDLE;
+ lastReceivedMessageId = messageId;
+ return true;
+ }
+ /* Not done yet.. keep on receiving */
+ rxState = RX_STATE_GET_DATA;
+ return true;
+ }
+ return false;
+}
+
+bool AtmelDataProtocol::isReceived(void) {
+ if(bytesReceived == 0) {
+ return false;
+ }
+ return packetReceived;
+}
+
+uint8_t AtmelDataProtocol::packetReceiveGetId(void) {
+ return lastReceivedMessageId;
+}
+
+bool AtmelDataProtocol::protocolAddByte(uint8_t rxId, uint8_t *rxBuffer, uint16_t rxLength, uint8_t *rxPacket, uint16_t rxPacketLength) {
+ uint8_t i;
+
+ for(i = 0; i < rxLength; i++) {
+ if(addReceiveByte(*(rxBuffer + i)) == true) {
+ /* This is a data byte */
+ rxPacketBuffer[bytesReceived - 1] = *(rxBuffer + i);
+ }
+
+ if(isReceived() && (packetReceiveGetId() == rxId)) {
+ memcpy(rxPacket, rxPacketBuffer, rxPacketLength);
+ memset(rxPacketBuffer, 0, MSG_RES_DATA_PACKET_MAX_LEN);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool AtmelDataProtocol::checkForResponse(uint8_t rxId, uint8_t *rxPacket, uint16_t rxPacketLength) {
+ uint16_t txLength = rxPacketLength + ADP_LENGTH_PACKET_HEADER;
+ uint8_t retry = ADP_CHECK_FOR_RESPONSE_RETRYS;
+
+ uint8_t rxBuffer[txLength];
+ memset(rxBuffer, 0, txLength);
+
+ rxState = RX_STATE_IDLE;
+ packetReceived = false;
+ memset(rxPacketBuffer, 0, MSG_RES_DATA_PACKET_MAX_LEN);
+
+ while(!isReceived() & (retry-- > 0)) {
+ uint16_t rxLength = this->gateway->receive(rxBuffer, txLength);
+ if(protocolAddByte(rxId, rxBuffer, rxLength, rxPacket, rxPacketLength)) return true;
+ }
+
+ return false;
+}
+
+void AtmelDataProtocol::waitForResponse(uint8_t rxId, uint8_t *rxPacket, uint16_t rxPacketLength) {
+ uint16_t txLength = rxPacketLength + ADP_LENGTH_PACKET_HEADER;
+
+ uint8_t rxBuffer[txLength];
+ memset(rxBuffer, 0, txLength);
+
+ rxState = RX_STATE_IDLE;
+ packetReceived = false;
+ memset(rxPacketBuffer, 0, MSG_RES_DATA_PACKET_MAX_LEN);
+
+ while(!isReceived()) {
+ uint16_t rxLength = this->gateway->receive(rxBuffer, txLength);
+ protocolAddByte(rxId, rxBuffer, rxLength, rxPacket, rxPacketLength);
+ }
+}
+
+bool AtmelDataProtocol::requestHandshake(uint8_t protocolVersion, uint8_t options, uint8_t *rxPacket) {
+ uint16_t txLength = MSQ_REQ_HANDSHAKE_LEN + ADP_LENGTH_PACKET_HEADER;
+ uint8_t key[8] = ADP_HANDSHAKE_KEY;
+
+ MsgFormat msgFormat;
+ MsgRequestHandshake msgRequestHandshake;
+
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_REQ_HANDSHAKE;
+ msgFormat.dataLength = MSQ_REQ_HANDSHAKE_LEN;
+
+ msgRequestHandshake.protocolVersion = ADP_VERSION;
+ msgRequestHandshake.options = HANDSHAKE_OPTIONS_GPIO;
+
+ memcpy(&msgRequestHandshake.key, key, 8);
+ memcpy((uint8_t *)&msgFormat.data, &msgRequestHandshake, sizeof(msgRequestHandshake));
+
+ /* Send the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_RES_HANDSHAKE;
+ uint16_t rxPacketLength = 1;
+
+ return checkForResponse(rxId, rxPacket, rxPacketLength);
+}
+
+HandshakeStatus AtmelDataProtocol::waitForHandshake(void) {
+ uint8_t handshake_status;
+
+ /* Keep sending handshake until we get something back */
+ while(!requestHandshake(ADP_VERSION, 0, &handshake_status));
+
+ /* Return status */
+ return ((HandshakeStatus)handshake_status);
+}
+
+StatusCode AtmelDataProtocol::requestStatus(void) {
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_REQ_STATUS;
+ msgFormat.dataLength = MSG_REQ_STATUS_LEN;
+
+ uint16_t tx_length = MSG_REQ_STATUS_LEN + ADP_LENGTH_PACKET_HEADER;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, tx_length);
+
+ uint8_t rxId = MSG_RES_STATUS;
+ uint16_t rxPacket;
+ uint16_t rxPacketLength = 2;
+
+ /* Wait for response from PC */
+ waitForResponse(rxId, (uint8_t *)&rxPacket, rxPacketLength);
+
+ return ((StatusCode)rxPacket);
+}
+
+uint16_t AtmelDataProtocol::verifyDataLength(uint16_t length) {
+ return length <= ADP_MAX_PROTOCOL_LEN ? length : ADP_MAX_PROTOCOL_LEN;
+}
+
+bool AtmelDataProtocol::configureInfo(const char *title, const char *description) {
+ /* Add null-termination to length */
+ uint16_t titleLength = strlen(title) + 1;
+ uint16_t descriptionLength = strlen(description) + 1;
+
+ /* Make sure the strings are not too long */
+ uint16_t dataLength = verifyDataLength(MSG_CONF_INFO_LEN + titleLength + descriptionLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_INFO;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)title, titleLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)description, descriptionLength);
+
+ uint16_t tx_length = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, tx_length);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::configureStream(MsgConfigStream *const config, const char *label) {
+ /* Add null-termination to length */
+ uint16_t labelLength = strlen(label) + 1;
+
+ /* Make sure the strings are not too long */
+ uint16_t dataLength = verifyDataLength(MSG_CONF_STREAM_LEN + labelLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_STREAM;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->streamId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->type, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->mode, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->state, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)label, labelLength);
+
+ uint16_t tx_length = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, tx_length);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::toggleStream(MsgToggleStream *const config) {
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_TOGGLE_STREAM;
+ msgFormat.dataLength = MSG_CONF_TOGGLE_STREAM_LEN;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->streamId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->state, 1);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+
+bool AtmelDataProtocol::configureGraph(MsgConfigGraph *const config, const char *graphLabel, const char *xLabel) {
+ /* Add 0-termination to label string length */
+ uint16_t graphLabelLength = strlen(graphLabel) + 1;
+ uint16_t xLabelLength = strlen(xLabel) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(MSG_CONF_GRAPH_LEN + graphLabelLength + xLabelLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_GRAPH;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->graphId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)graphLabel, graphLabelLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->xMin, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->xMax, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)xLabel, xLabelLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->xScaleNumerator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->xScaleDenominator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->scaleMode, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->backgroundColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->scrollMode, 1);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::configureTerminal(MsgConfigTerminal *const config, const char *label) {
+ /* Add 0-termination to label string length */
+ uint16_t labelLength = strlen(label) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(MSG_CONF_TERMINAL_LEN + labelLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_TERMINAL;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->terminalId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)label, labelLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->width, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->height, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->backgroundColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->foregroundColor, 3);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addStreamToTerminal(MsgConfigAddStreamToTerminal *const config, const char *tagText) {
+ /* Add 0-termination to label string length */
+ uint16_t tagTextLength = strlen(tagText) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(MSG_CONF_ADD_TO_TERMINAL_LEN + tagTextLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_ADD_TO_TERMINAL;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->terminalId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->streamId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->mode, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->textColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)tagText, tagTextLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->tagTextColor, 3);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addAxisToGraph(MsgConfigAxis *const config, const char *label) {
+ /* Add 0-termination to label string length */
+ uint16_t labelLength = strlen(label) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(MSG_CONF_AXIS_LEN + labelLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_AXIS;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->axisId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->graphId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)label, labelLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->yMin, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->yMax, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->xScaleNumerator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->xScaleDenominator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->mode, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->color, 3);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addStreamToAxis(MsgAddStreamToAxis *const config) {
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_ADD_STREAM_TO_AXIS;
+ msgFormat.dataLength = MSG_CONF_ADD_STREAM_TO_AXIS_LEN;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->axisId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->graphId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->streamId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->sampleRateNumerator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->sampleRateDenominator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->yScaleNumerator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->yScaleDenominator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->yOffset, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->transparency, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->mode, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->lineThickness, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->lineColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)ADP_BUG_FIX, 1);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addCursorToGraph(MsgAddCursorToGraph *const config, const char *label) {
+ /* Add 0-termination to label string length */
+ uint16_t labelLength = strlen(label) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(MSG_CONF_CURSOR_TO_GRAPH_LEN + labelLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_CURSOR_TO_GRAPH;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->streamId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->axisId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->graphId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)label, labelLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->thickness, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->color, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->initialValue, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->minimumValue, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->maximumValue, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->scaleNumerator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->scaleDenominator, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->scaleOffset, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->lineStyle, 1);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addGpioToGraph(MsgConfigGpioToGraph *const config, const char *tagHighState, const char *tagLowState) {
+ /* Add 0-termination to label string length */
+ uint16_t tagHighStateLength = strlen(tagHighState) + 1;
+ uint16_t tagLowStateLength = strlen(tagLowState) + 1;
+ uint16_t labelLength = tagHighStateLength + tagLowStateLength;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(MSG_CONF_GPIO_TO_GRAPH_LEN + labelLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_GPIO_TO_GRAPH;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->graphId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->gpioNumber, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->graphId, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)tagHighState, tagHighStateLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)tagLowState, tagLowStateLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->transparency, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->mode, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->lineThickness, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->lineColorHighState, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->lineColorLowState, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->lineStyle, 1);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addDashboard(MsgConfigDahsboard *const config, const char *label) {
+ /* Add 0-termination to label string length */
+ uint16_t labelLength = strlen(label) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(MSG_CONF_DASHBOARD_LEN + labelLength);
+
+ MsgFormat msgFormat;
+
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->dashboardId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)label, labelLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->color, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->height, 2);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+uint16_t AtmelDataProtocol::addSendByteDashboard(uint8_t *addBuffer, uint16_t index, MsgConfigDashboardElementCommon *const config) {
+ index = addSendByte(addBuffer, index, (uint8_t *)&config->dashboardId, 2);
+ index = addSendByte(addBuffer, index, (uint8_t *)&config->elementId, 2);
+ index = addSendByte(addBuffer, index, (uint8_t *)&config->zIndex, 1);
+ index = addSendByte(addBuffer, index, (uint8_t *)&config->x, 2);
+ index = addSendByte(addBuffer, index, (uint8_t *)&config->y, 2);
+ index = addSendByte(addBuffer, index, (uint8_t *)&config->width, 2);
+ index = addSendByte(addBuffer, index, (uint8_t *)&config->height, 2);
+ index = addSendByte(addBuffer, index, (uint8_t *)&config->elementType, 1);
+
+ return index;
+}
+
+bool AtmelDataProtocol::addLabelToDashboard(MsgConfigDashboardElementLabel *const config, const char *label) {
+ /* Add 0-termination to label string length */
+ uint16_t labelLength = strlen(label) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(ELEMENT_TYPE_LABEL_LEN + labelLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->fontSize, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->attribute, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->horisontalAlignment, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->verticalAlignment, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->backgroundTransparency, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->backgroundColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->foregroundTransparency, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->foregroundColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)label, labelLength);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addButtonToDashboard(MsgConfigDashboardElementButton *const config, const char *label) {
+ /* Add 0-termination to label string length */
+ uint16_t labelLength = strlen(label) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(ELEMENT_TYPE_BUTTON_LEN + labelLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->fontSize, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)label, labelLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->toggle, 1);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Send the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addSliderToDashboard(MsgConfigDashboardElementSlider *const config) {
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = ELEMENT_TYPE_SLIDER_LEN;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->minimumValue, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->maximumValue, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->initialValue, 4);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addProgressToDashboard(MsgConfigDashboardElementProgress *const config) {
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = ELEMENT_TYPE_PROGRESS_LEN;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->minimumValue, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->maximumValue, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->initialValue, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->color, 3);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Send the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addSignalToDashboard(MsgConfigDashboardElementSignal *const config) {
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = ELEMENT_TYPE_SIGNAL_LEN;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->onTransparency, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->onColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->offTransparency, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->offColor, 3);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addSegmentToDashboard(MsgConfigDashboardElementSegment *const config) {
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = ELEMENT_TYPE_SEGMENT_LEN;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->segmentCount, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->base, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->transparency, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->color, 3);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addGraphToDashboard(MsgConfigDashboardElementGraph *const config, const char *title) {
+ /* Add 0-termination to label string length */
+ uint16_t titleLength = strlen(title) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(ELEMENT_TYPE_GRAPH_LEN + titleLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->titleColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->backgroundColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->graphBackgroundColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)title, titleLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->plotCount, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->xMin, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->xMax, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->yMin, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->yMax, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->mode, 2);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addTextToDashboard(MsgConfigDashboardElementText *const config) {
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = ELEMENT_TYPE_TEXT_LEN;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->minimum, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->maximum, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->value, 4);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)ADP_BUG_FIX, 1);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addRadioToDashboard(MsgConfigDashboardElementRadio *const config, const char *text) {
+ /* Add 0-termination to label string length */
+ uint16_t textLength = strlen(text) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(ELEMENT_TYPE_RADIO_LEN + textLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->fontSize, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->numberItems, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->orientation, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)text, textLength);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addPieToDashboard(MsgConfigDashboardElementPie *const config, const char *title) {
+ /* Add 0-termination to label string length */
+ uint16_t titleLength = strlen(title) + 1;
+
+ /* Make sure label isn't too big */
+ uint16_t dataLength = verifyDataLength(ELEMENT_TYPE_PIE_LEN + titleLength);
+
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_DASHBOARD_ELEMENT;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t index = 0;
+
+ index = addSendByteDashboard((uint8_t *)&msgFormat.data, index, (MsgConfigDashboardElementCommon *)config);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->backgroundColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->titleColor, 3);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)title, titleLength);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->numberSlices, 1);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::addStreamToElement(MsgConfigAddStreamToElement *const config) {
+ MsgFormat msgFormat;
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_CONF_ADD_STREAM_TO_ELEMENT;
+ msgFormat.dataLength = MSG_CONF_ADD_STREAM_TO_ELEMENT_LEN;
+
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->dashboardId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->elementId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&config->streamId, 2);
+
+ uint16_t txLength = ADP_LENGTH_PACKET_HEADER + index;
+
+ /* Transmit the protocol packet data */
+ this->gateway->transmit((uint8_t *)&msgFormat, txLength);
+
+ uint8_t rxId = MSG_CONF_ACK;
+ uint8_t rxPacket;
+ uint16_t rxPacketLength = 1;
+
+ /* Wait for response and return status */
+ waitForResponse(rxId, &rxPacket, rxPacketLength);
+
+ return (rxPacket == ACK_OK);
+}
+
+bool AtmelDataProtocol::transceiveStream(MsgDataStream *const streamData, uint8_t *rxPacket) {
+ MsgFormat msgFormat;
+
+ uint16_t dataLength = 1;
+ uint16_t index = 0;
+
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&streamData->numberOfStreams, 1);
+
+ for(uint8_t stream_num = 0; stream_num < streamData->numberOfStreams; stream_num++) {
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&streamData->stream[stream_num].streamId, 2);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, (uint8_t *)&streamData->stream[stream_num].dataSize, 1);
+ index = addSendByte((uint8_t *)&msgFormat.data, index, streamData->stream[stream_num].data, streamData->stream[stream_num].dataSize);
+ /* 2 bytes stream.stream_id and 1 byte stream.data_size */
+ dataLength += 2 + 1 + streamData->stream[stream_num].dataSize;
+ }
+
+ msgFormat.protocolToken = ADP_TOKEN;
+ msgFormat.protocolMsgId = MSG_DATA_STREAM;
+ msgFormat.dataLength = dataLength;
+
+ uint16_t txrxLength = ADP_LENGTH_PACKET_HEADER + index;
+ uint16_t rxPacketLength = MSG_RES_DATA_PACKET_MAX_LEN;
+ uint8_t rxId = MSG_RES_DATA;
+
+ uint8_t rxBuffer[txrxLength];
+ memset(rxBuffer, 0, txrxLength);
+
+ /* Transmit and receive protocol packet data */
+ uint16_t rxLength = this->gateway->transceive((uint8_t *)&msgFormat, rxBuffer, txrxLength);
+
+ return protocolAddByte(rxId, rxBuffer, rxLength, rxPacket, rxPacketLength);
+}
+
+bool AtmelDataProtocol::transceiveSingleStream(uint16_t streamId, uint8_t *data, uint8_t dataSize, uint8_t *rxPacket) {
+ MsgDataStream msgDataStream;
+
+ msgDataStream.numberOfStreams = 1;
+ msgDataStream.stream[0].streamId = streamId;
+ msgDataStream.stream[0].dataSize = dataSize;
+ msgDataStream.stream[0].data = data;
+
+ uint8_t status = transceiveStream(&msgDataStream, rxPacket);
+
+ return status;
+}
+
+bool AtmelDataProtocol::receivePacketData(uint8_t *rxPacket) {
+ uint16_t rxPacketLength = MSG_RES_DATA_PACKET_MAX_LEN;
+ uint8_t txrxLength = MSG_RES_DATA_REQUEST;
+ uint8_t rxId = MSG_RES_DATA;
+
+ uint8_t rxBuffer[txrxLength];
+ memset(rxBuffer, 0, txrxLength);
+
+ /* Transmit and receive protocol packet data */
+ uint16_t rxLength = this->gateway->receive(rxBuffer, txrxLength);
+
+ return protocolAddByte(rxId, rxBuffer, rxLength, rxPacket, rxPacketLength);
+}
\ No newline at end of file
diff --git a/src/AtmelDataProtocol.h b/src/AtmelDataProtocol.h
new file mode 100644
index 0000000..19bbdb4
--- /dev/null
+++ b/src/AtmelDataProtocol.h
@@ -0,0 +1,771 @@
+#ifndef ATMEL_DATA_PROTOCOL_H
+#define ATMEL_DATA_PROTOCOL_H
+
+#include
+#include
+#include
+
+/** Bug Fix for last message byte ADP Token */
+#define ADP_BUG_FIX 0x00
+
+/** Version of ADP implemented here */
+#define ADP_VERSION 1
+
+/** Start token for ADP data */
+#define ADP_TOKEN 0xFF
+
+/** Maximum number of streams from PC to target */
+#define ADP_MAX_INCOMMING_STREAMS 5
+
+/** Maximum number of streams from target to PC */
+#define ADP_MAX_OUTGOING_STREAMS 5
+
+/** Key used to identify proper handshake message */
+#define ADP_HANDSHAKE_KEY {0x58, 0x99, 0xAB, 0xC9, 0x0F, 0xE2, 0xF7, 0xAA}
+
+/** Maximum retry for handshake request */
+#define ADP_CHECK_FOR_RESPONSE_RETRYS 50
+
+/** Length of ADP packet header: Token, Message ID, Data Length */
+#define ADP_LENGTH_PACKET_HEADER 4
+
+/** Maximum number of bytes in data part of ADP packet out */
+#define ADP_MAX_PROTOCOL_LEN 250
+
+/** Max length of labels */
+#define ADP_CONF_MAX_LABEL 20
+
+/** ADP RGB color definitions. Other RGB values can be used as well */
+#define COLOR_WHITE (RgbColor) {0xFF, 0xFF, 0xFF}
+#define COLOR_BLACK (RgbColor) {0x00, 0x00, 0x00}
+#define COLOR_SILVER (RgbColor) {0xC0, 0xC0, 0xC0}
+#define COLOR_GRAY (RgbColor) {0x80, 0x80, 0x80}
+#define COLOR_MAROON (RgbColor) {0x80, 0x00, 0x00}
+#define COLOR_RED (RgbColor) {0xFF, 0x00, 0x00}
+#define COLOR_PURPLE (RgbColor) {0x80, 0x00, 0x80}
+#define COLOR_FUCHSIA (RgbColor) {0xFF, 0x00, 0xFF}
+#define COLOR_GREEN (RgbColor) {0x00, 0x80, 0x00}
+#define COLOR_LIME (RgbColor) {0x00, 0xFF, 0x00}
+#define COLOR_OLIVE (RgbColor) {0x80, 0x80, 0x00}
+#define COLOR_YELLOW (RgbColor) {0xFF, 0xFF, 0x00}
+#define COLOR_NAVY (RgbColor) {0x00, 0x00, 0x80}
+#define COLOR_BLUE (RgbColor) {0x00, 0x00, 0xFF}
+#define COLOR_TEAL (RgbColor) {0x00, 0x80, 0x80}
+#define COLOR_AQUA (RgbColor) {0x00, 0xFF, 0xFF}
+#define COLOR_ORANGE (RgbColor) {0xFF, 0xA5, 0x00}
+
+#define ACK_NOT_OK 0
+#define ACK_OK 1
+
+#define AXIS_LINE_bm 0x01
+#define AXIS_POINTS_bm 0x02
+
+#define MSG_DATA_STREAM 0x40
+
+#define MSG_REQ_HANDSHAKE 0x00
+#define MSQ_REQ_HANDSHAKE_LEN 10
+
+#define MSG_REQ_STATUS 0x02
+#define MSG_REQ_STATUS_LEN 0
+
+#define MSG_RES_HANDSHAKE 0x10
+#define MSG_RES_STATUS 0x12
+#define MSG_RES_DATA 0x14
+#define MSG_RES_DATA_REQUEST 10
+#define MSG_RES_DATA_PACKET_MAX_LEN 250
+#define MSG_RES_DATA_MAX_LEN MSG_RES_DATA_PACKET_MAX_LEN - 3
+
+#define MSG_CONF_ACK 0x30
+
+#define MSG_CONF_INFO 0x28
+#define MSG_CONF_INFO_LEN 0
+
+#define MSG_CONF_STREAM 0x20
+#define MSG_CONF_STREAM_LEN 5
+
+#define MSG_CONF_TOGGLE_STREAM 0x21
+#define MSG_CONF_TOGGLE_STREAM_LEN 3
+
+#define MSG_CONF_GRAPH 0x22
+#define MSG_CONF_GRAPH_LEN 23
+
+#define MSG_CONF_AXIS 0x29
+#define MSG_CONF_AXIS_LEN 24
+
+#define MSG_CONF_ADD_STREAM_TO_AXIS 0x23
+#define MSG_CONF_ADD_STREAM_TO_AXIS_LEN 32
+
+#define MSG_CONF_CURSOR_TO_GRAPH 0x24
+#define MSG_CONF_CURSOR_TO_GRAPH_LEN 35
+
+#define MSG_CONF_GPIO_TO_GRAPH 0x25
+#define MSG_CONF_GPIO_TO_GRAPH_LEN 15
+
+#define MSG_CONF_TERMINAL 0x26
+#define MSG_CONF_TERMINAL_LEN 10
+
+#define MSG_CONF_ADD_TO_TERMINAL 0x27
+#define MSG_CONF_ADD_TO_TERMINAL_LEN 11
+
+#define MSG_CONF_DASHBOARD 0x2A
+#define MSG_CONF_DASHBOARD_LEN 7
+
+#define MSG_CONF_DASHBOARD_ELEMENT 0x2B
+#define MSG_CONF_DASHBOARD_COMMON_LEN 14
+
+#define MSG_CONF_ADD_STREAM_TO_ELEMENT 0x2C
+#define MSG_CONF_ADD_STREAM_TO_ELEMENT_LEN 6
+
+#define ELEMENT_TYPE_LABEL_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 12)
+#define ELEMENT_TYPE_BUTTON_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 2)
+#define ELEMENT_TYPE_SLIDER_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 12)
+#define ELEMENT_TYPE_SIGNAL_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 8)
+#define ELEMENT_TYPE_PROGRESS_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 15)
+#define ELEMENT_TYPE_TEXT_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 12)
+#define ELEMENT_TYPE_RADIO_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 3)
+#define ELEMENT_TYPE_PIE_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 7)
+#define ELEMENT_TYPE_SEGMENT_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 6)
+#define ELEMENT_TYPE_GRAPH_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 28)
+
+/** States in receive state machine */
+enum RxState {
+ /** We are idle, waiting for a new packet */
+ RX_STATE_IDLE,
+ /** Start symbol received, waiting for Message ID */
+ RX_STATE_WAIT_MSG_ID,
+ /** Message ID received, waiting for data length */
+ RX_STATE_WAIT_LENGTH_LSB,
+ /** Message ID received, waiting for data length */
+ RX_STATE_WAIT_LENGTH_MSB,
+ /** Length received; we are receiving packet data */
+ RX_STATE_GET_DATA,
+ /** Start symbol received */
+ RX_STATE_GOT_SYMBOL,
+};
+
+enum HandshakeOptions {
+ /* Use GPIO */
+ HANDSHAKE_OPTIONS_GPIO,
+ /* Lock configuration */
+ HANDSHAKE_OPTIONS_LOCK,
+};
+
+enum HandshakeStatus {
+ /* Handshake accepted */
+ HANDSHAKE_ACCEPTED,
+ /* Handshake rejected. Invalid protocol version */
+ HANDSHAKE_REJECTED_PROTOCOL,
+ /* Handshake rejected. Other reason */
+ HANDSHAKE_REJECTED_OTHER,
+};
+
+enum StatusCode {
+ /* Invalid packet received */
+ STATUS_INVALID_PACKET,
+ /* Invalid configuration data received */
+ STATUS_INVALID_CONFIGURATION,
+ /* Data ready to be transmitted to target */
+ STATUS_DATA_READY,
+ /* Invalid stream request (req_data) */
+ STATUS_INVALID_REQUEST,
+ /* No data available on stream (req_data) */
+ STATUS_NO_DATA,
+ /* Request target software reset */
+ STATUS_RESET,
+};
+
+enum StreamType {
+ STREAM_EVENT,
+ STREAM_STRING,
+ STREAM_UINT_8,
+ STREAM_INT_8,
+ STREAM_UINT_16,
+ STREAM_INT_16,
+ STREAM_UINT_32,
+ STREAM_INT_32,
+ STREAM_XY_8,
+ STREAM_XY_16,
+ STREAM_XY_32,
+ STREAM_BOOL,
+ STREAM_FLOAT,
+};
+
+enum StreamState {
+ STREAM_OFF,
+ STREAM_ON,
+};
+
+enum StreaMode {
+ /* Incoming (normal) */
+ STREAM_IN,
+ /* Incoming (single value) */
+ STREAM_IN_SINGLE,
+ /* Outgoing */
+ STREAM_OUT,
+};
+
+enum GraphScaleMode {
+ GRAPH_SCALE_OFF,
+ GRAPH_SCALE_AUTO
+};
+
+enum GraphScrollMode {
+ /* No scrolling */
+ GRAPH_SCROLL_OFF,
+ /* Stepping */
+ GRAPH_SCROLL_STEP,
+ /* Scroll */
+ GRAPH_SCROLL_SCROLL,
+ /* Circular/sweep */
+ GRAPH_SCROLL_CIRCULAR
+};
+
+enum DashboardElementType {
+ ELEMENT_TYPE_LABEL,
+ ELEMENT_TYPE_BUTTON,
+ ELEMENT_TYPE_SLIDER,
+ ELEMENT_TYPE_PROGRESS,
+ ELEMENT_TYPE_SIGNAL,
+ ELEMENT_TYPE_SEGMENT,
+ ELEMENT_TYPE_GRAPH,
+ ELEMENT_TYPE_TEXT,
+ ELEMENT_TYPE_RADIO,
+ ELEMENT_TYPE_PIE,
+};
+
+enum LabelAttribute {
+ BOLD_OFF_ITALIC_OFF,
+ BOLD_ON_ITALIC_OFF,
+ BOLD_OFF_ITALIC_ON,
+ BOLD_ON_ITALIC_ON,
+};
+
+enum LabelAligmentHorisontal {
+ HORISONTAL_ALIGNMENT_LEFT,
+ HORISONTAL_ALIGNMENT_CENTER,
+ HORISONTAL_ALIGNMENT_RIGHT,
+};
+
+enum LabelAligmentVertical {
+ VERTICAL_ALIGNMENT_TOP,
+ VERTICAL_ALIGNMENT_CENTER,
+ VERTICAL_ALIGNMENT_BOTTOM,
+};
+
+enum RadioOrientation {
+ HORIZONTAL,
+ VERTICAL,
+};
+
+struct RgbColor {
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
+};
+
+struct MsgFormat {
+ /* Start token for ADP data */
+ uint8_t protocolToken;
+ /* Describes what data is sent */
+ uint8_t protocolMsgId;
+ /* Length of data packet */
+ uint16_t dataLength;
+ /* Data packet for the message */
+ uint8_t data[ADP_MAX_PROTOCOL_LEN];
+};
+
+struct MsgRequestHandshake {
+ /* Version of protocol on target */
+ uint8_t protocolVersion;
+ /* Is GPIO in use in this app?
+ * Can user change configuration on PC side?
+ */
+ uint8_t options;
+ /* Token used to verify ADP protocol */
+ uint8_t key[8];
+};
+
+struct MsgResponseHandshake {
+ enum HandshakeStatus status;
+};
+
+struct MsgResponseStatus {
+ enum StatusCode status;
+};
+
+struct MsgPacketData {
+ uint16_t streamId;
+ uint8_t bytesSent;
+ uint8_t data[MSG_RES_DATA_MAX_LEN];
+};
+
+struct MsgConfigStream {
+ /* ID of stream */
+ uint16_t streamId;
+ /* Stream type */
+ enum StreamType type;
+ /* Stream mode/direction */
+ enum StreaMode mode;
+ /* Stream state */
+ enum StreamState state;
+};
+
+struct MsgToggleStream {
+ uint16_t streamId;
+ enum StreamState state;
+};
+
+struct MsgConfigGraph {
+ /* ID of new graph */
+ uint8_t graphId;
+ /* Range Xmin value */
+ uint32_t xMin;
+ /* Range Xmax value */
+ uint32_t xMax;
+ /* Xscale numerator */
+ uint32_t xScaleNumerator;
+ /* X range scale value. Set to 0 to enable auto range */
+ uint32_t xScaleDenominator;
+ /* Vertical scaling */
+ enum GraphScaleMode scaleMode;
+ /* RGB background color */
+ uint8_t backgroundColor[3];
+ /* Horizontal scrolling */
+ enum GraphScrollMode scrollMode;
+};
+
+struct MsgConfigAxis {
+ /* ID of new axis */
+ uint16_t axisId;
+ /* ID of graph */
+ uint16_t graphId;
+ /* Range Ymin value */
+ int32_t yMin;
+ /* Range Ymax value */
+ int32_t yMax;
+ /* X range scale value. Set to 0 to enable auto range */
+ uint32_t xScaleNumerator;
+ /* X range scale value. Set to 0 to enable auto range */
+ uint32_t xScaleDenominator;
+ /* Mode */
+ uint8_t mode; // TODO
+ /* RGB color */
+ uint8_t color[3];
+};
+
+struct MsgAddStreamToAxis {
+ /* ID of graph */
+ uint16_t graphId;
+ /* ID of new axis */
+ uint16_t axisId;
+ /* ID of stream */
+ uint16_t streamId;
+ /* Sample rate of stream, set to 0 if NA */
+ uint32_t sampleRateNumerator;
+ /* Sample rate of stream, set to 0 if NA */
+ uint32_t sampleRateDenominator;
+ /* Range Ymin value */
+ uint32_t yScaleNumerator;
+ /* Range Ymax value */
+ uint32_t yScaleDenominator;
+ /* Offset of values */
+ uint32_t yOffset;
+ /* Adjust the transparency */
+ uint8_t transparency;
+ /* For graphs: bit 0 = line on/off
+ * bit 1 = points on/off
+ * For text: bit 0 = flag
+ * bit 1 = text
+ */
+ uint8_t mode; // TODO
+ /* Thickness of line */
+ uint8_t lineThickness;
+ /* RGB color of line */
+ uint8_t lineColor[3];
+};
+
+struct MsgAddCursorToGraph {
+ /* ID of streama */
+ uint16_t streamId;
+ /* ID of graph */
+ uint16_t graphId;
+ /* ID of axis */
+ uint16_t axisId;
+ /* Thickness of line */
+ uint8_t thickness;
+ /* RGB color of cursor */
+ uint8_t color[3];
+ /* Starting point of cursor */
+ uint32_t initialValue;
+ /* Minimum allowed value */
+ uint32_t minimumValue;
+ /* Maximum */
+ uint32_t maximumValue;
+ /* Numerator of scaling value */
+ uint32_t scaleNumerator;
+ /* Denominator of scaling value */
+ uint32_t scaleDenominator;
+ /* Offset of value */
+ uint32_t scaleOffset;
+ /* The style of line: Solid, dashed, dotted.. */
+ uint8_t lineStyle; // TODO
+};
+
+struct MsgConfigGpioToGraph {
+ /* ID of graph */
+ uint16_t graphId;
+ /* GPIO number to add to graph. Bit 0: GPIO0. bit 1: GPIO1 etc. */
+ uint8_t gpioNumber;
+ /* Used to group graphs and cursors to the same scale */
+ uint8_t groupId;
+ /* Adjust the transparency */
+ uint8_t transparency;
+ /* Mode */
+ uint16_t mode; // TODO
+ /* Thickness of line */
+ uint8_t lineThickness;
+ /* RGB color of line when GPIO pin is high */
+ uint8_t lineColorHighState[3];
+ /* RGB color of line when GPIO pin is low */
+ uint8_t lineColorLowState[3];
+ /* The style of line */
+ uint8_t lineStyle;
+};
+
+struct MsgConfigTerminal {
+ /* ID of terminal */
+ uint16_t terminalId;
+ /* Number of characters wide */
+ uint8_t width;
+ /* Number of characters high */
+ uint8_t height;
+ /* RGB background color */
+ uint8_t backgroundColor[3];
+ /* RGB background color */
+ uint8_t foregroundColor[3];
+};
+
+struct MsgConfigAddStreamToTerminal {
+ /* ID of Terminal */
+ uint16_t terminalId;
+ /* ID of stream */
+ uint16_t streamId;
+ /* 0bx x x N T S F F
+ * N = implicit newline in incoming text
+ * T = enable tag
+ * S = timestamped
+ * F = format (Hex, decimal, binary, ascii)
+ */
+ uint8_t mode; // TODO
+ /* RGB color of the text stream received */
+ uint8_t textColor[3];
+ /* RGB color of the tag text */
+ uint8_t tagTextColor[3];
+};
+
+struct MsgConfigDahsboard {
+ uint16_t dashboardId;
+ uint8_t color[3];
+ uint16_t height;
+};
+
+struct MsgConfigDashboardElementCommon {
+ /* Dashboard ID */
+ uint16_t dashboardId;
+ /* Unique ID of element */
+ uint16_t elementId;
+ /* Order index */
+ uint8_t zIndex;
+ /* X-coordinate of element location. 0 is leftmost position on dashboard */
+ uint16_t x;
+ /* Y-coordinate of element location. 0 is topmost position on dashboard */
+ uint16_t y;
+ /* Width of element */
+ uint16_t width;
+ /* Height of element */
+ uint16_t height;
+ /* See each element type below */
+ DashboardElementType elementType;
+};
+
+struct MsgConfigDashboardElementLabel {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elementType;
+ uint8_t fontSize;
+ uint8_t attribute;
+ LabelAligmentHorisontal horisontalAlignment;
+ LabelAligmentVertical verticalAlignment;
+ uint8_t backgroundTransparency;
+ uint8_t backgroundColor[3];
+ uint8_t foregroundTransparency;
+ uint8_t foregroundColor[3];
+};
+
+struct MsgConfigDashboardElementButton {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elementType;
+ uint8_t fontSize;
+ uint8_t toggle;
+};
+
+struct MsgConfigDashboardElementSlider {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elementType;
+ uint32_t minimumValue;
+ uint32_t maximumValue;
+ uint32_t initialValue;
+};
+
+struct MsgConfigDashboardElementSignal {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elementType;
+ uint8_t onTransparency;
+ uint8_t onColor[3];
+ uint8_t offTransparency;
+ uint8_t offColor[3];
+};
+
+struct MsgConfigDashboardElementProgress {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elemntType;
+ uint32_t minimumValue;
+ uint32_t maximumValue;
+ uint32_t initialValue;
+ uint8_t color[3];
+};
+
+struct MsgConfigDashboardElementSegment {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elementType;
+ /* Values: 1 ~ 20 */
+ uint8_t segmentCount;
+ /* Values: 2 ~ 16*/
+ uint8_t base;
+ uint8_t transparency;
+ uint8_t color[3];
+};
+
+typedef union {
+ struct {
+ uint8_t mouse : 1;
+ uint8_t fitGraph : 1;
+ uint8_t autoscale : 1;
+ uint8_t scrollByTime : 1;
+ uint8_t : 4;
+ uint8_t showPlot : 1;
+ uint8_t showPoints : 1;
+ uint8_t : 6;
+ } bit;
+ uint16_t reg;
+} modeType;
+
+struct MsgConfigDashboardElementGraph {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elementType;
+ uint8_t titleColor[3];
+ uint8_t backgroundColor[3];
+ uint8_t graphBackgroundColor[3];
+ uint8_t plotCount;
+ float xMin;
+ float xMax;
+ float yMin;
+ float yMax;
+ modeType mode;
+};
+
+struct MsgConfigDashboardElementText {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elementType;
+ uint8_t minimum[4];
+ uint8_t maximum[4];
+ uint8_t value[4];
+};
+
+struct MsgConfigDashboardElementRadio {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elementType;
+ uint8_t fontSize;
+ uint8_t numberItems;
+ RadioOrientation orientation;
+};
+
+struct MsgConfigDashboardElementPie {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ DashboardElementType elementType;
+ uint8_t backgroundColor[3];
+ uint8_t titleColor[3];
+ uint8_t numberSlices;
+};
+
+struct MsgConfigAddStreamToElement {
+ uint16_t dashboardId;
+ uint16_t elementId;
+ uint16_t streamId;
+};
+
+struct MsgDataStreamData {
+ uint16_t streamId;
+ uint8_t dataSize;
+ uint8_t* data;
+};
+
+struct MsgDataStream {
+ uint8_t numberOfStreams;
+ MsgDataStreamData stream[ADP_MAX_OUTGOING_STREAMS];
+};
+
+struct AtmelDataGateway {
+ virtual void transmit(uint8_t* txBuffer, uint16_t length);
+ virtual uint16_t receive(uint8_t* rxBuffer, uint16_t length);
+ virtual uint16_t transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length);
+};
+
+class AtmelDataProtocol {
+ private:
+ bool packetReceived;
+ uint8_t prevData;
+ uint8_t lastReceivedMessageId;
+ uint8_t rxPacketBuffer[MSG_RES_DATA_PACKET_MAX_LEN];
+ uint16_t bytesReceived;
+ uint16_t lengthReceived;
+ RxState rxState;
+ AtmelDataGateway* gateway;
+
+ bool addReceiveByte(uint8_t data);
+ bool isReceived(void);
+ bool protocolAddByte(uint8_t rxId, uint8_t *rxBuffer, uint16_t rxLength, uint8_t *rxPacket, uint16_t rxPacketLength);
+ bool checkForResponse(uint8_t rxId, uint8_t *rxPacket, uint16_t rxPacketLength);
+ void waitForResponse(uint8_t rxId, uint8_t *rxPacket, uint16_t rxPacketLength);
+ uint8_t packetReceiveGetId(void);
+ uint16_t addSendByteDashboard(uint8_t *addBuffer, uint16_t index, struct MsgConfigDashboardElementCommon *const config);
+ uint16_t verifyDataLength(uint16_t length);
+
+ public:
+ AtmelDataProtocol(void);
+
+ HandshakeStatus waitForHandshake(void);
+ StatusCode requestStatus(void);
+ void addAtmelDataGateway(AtmelDataGateway* adg);
+ void setColor(uint8_t *structMember, RgbColor color);
+ bool requestHandshake(uint8_t protocolVersion, uint8_t options, uint8_t *protocolBuffer);
+ bool receivePacketData(uint8_t *receiveBuffer);
+ bool configureInfo(const char *title, const char *description);
+ void configureStreamGetDefaults(MsgConfigStream *const config);
+ bool configureStream(MsgConfigStream *const config, const char *label);
+ bool toggleStream(MsgToggleStream *const config);
+ void configureGraphGetDefaults(MsgConfigGraph *const config);
+ bool configureGraph(MsgConfigGraph *const config, const char *graphLabel, const char *xLabel);
+ void addAxisToGraphGetDefaults(MsgConfigAxis *const config);
+ bool addAxisToGraph(MsgConfigAxis *const config, const char *label);
+ void addStreamToAxisGetDefaults(MsgAddStreamToAxis *const config);
+ bool addStreamToAxis(MsgAddStreamToAxis *const config);
+ void addCursorToGraphGetDefaults(MsgAddCursorToGraph *const config);
+ bool addCursorToGraph(MsgAddCursorToGraph *const config, const char *label);
+ void addGpioToGraphGetDefaults(MsgConfigGpioToGraph *const config);
+ bool addGpioToGraph(MsgConfigGpioToGraph *const config, const char *tagHighState, const char *tagLowState);
+ void configureTerminalGetDefaults(MsgConfigTerminal *const config);
+ bool configureTerminal(MsgConfigTerminal *const config, const char *label);
+ void addStreamToTerminalGetDefaults(MsgConfigAddStreamToTerminal *const config);
+ bool addStreamToTerminal(MsgConfigAddStreamToTerminal *const config, const char *tagText);
+ void configureDashboardGetDefaults(MsgConfigDahsboard *const config);
+ bool addDashboard(MsgConfigDahsboard *const config, const char *label);
+
+ void configureDashboardElementGetDefaults(MsgConfigDashboardElementCommon *const config);
+
+ void configureDashboardLabelGetDefaults(MsgConfigDashboardElementLabel *const config);
+ bool addLabelToDashboard(MsgConfigDashboardElementLabel *const config, const char *label);
+
+ void configureDashboardButtonGetDefaults(MsgConfigDashboardElementButton *const config);
+ bool addButtonToDashboard(MsgConfigDashboardElementButton *const config, const char *label);
+
+ void configureDashboardSliderGetDefaults(MsgConfigDashboardElementSlider *const config);
+ bool addSliderToDashboard(MsgConfigDashboardElementSlider *const config);
+
+ void configureDashboardSignalGetDefaults(MsgConfigDashboardElementSignal *const config);
+ bool addSignalToDashboard(MsgConfigDashboardElementSignal *const config);
+
+ void configureDashboardPrograssGetDefaults(MsgConfigDashboardElementProgress *const config);
+ bool addProgressToDashboard(MsgConfigDashboardElementProgress *const config);
+
+ void configureDashboardSegmentGetDefaults(MsgConfigDashboardElementSegment *const config);
+ bool addSegmentToDashboard(MsgConfigDashboardElementSegment *const config);
+
+ void configureDashboardGraphGetDefaults(MsgConfigDashboardElementGraph *const config);
+ bool addGraphToDashboard(MsgConfigDashboardElementGraph *const config, const char *title);
+
+ void configureDashboardRadioGetDefaults(MsgConfigDashboardElementRadio *const config);
+ bool addRadioToDashboard(MsgConfigDashboardElementRadio *const config, const char *text);
+
+ void configureDashboardPieGetDefaults(MsgConfigDashboardElementPie *const config);
+ bool addPieToDashboard(MsgConfigDashboardElementPie *const config, const char *title);
+
+ void configureDashboardTextGetDefaults(MsgConfigDashboardElementText *const config);
+ bool addTextToDashboard(MsgConfigDashboardElementText *const config);
+
+ bool addStreamToElement(MsgConfigAddStreamToElement *const config);
+ bool transceiveStream(MsgDataStream *const streamData, uint8_t *receiveBuffer);
+ bool transceiveSingleStream(uint16_t streamId, uint8_t *data, uint8_t dataSize, uint8_t *receiveBuffer);
+ uint16_t addSendByte(uint8_t *buffer, uint8_t index, uint8_t *data, uint16_t length);
+};
+
+#endif /* ATMEL_DATA_GATEWAY_PROTOCOL_H */
diff --git a/src/DataVisualizer.cpp b/src/DataVisualizer.cpp
new file mode 100644
index 0000000..f7776f7
--- /dev/null
+++ b/src/DataVisualizer.cpp
@@ -0,0 +1,366 @@
+#include "DataVisualizer.h"
+
+/*********************************************************/
+/* Internal */
+/*********************************************************/
+
+void DataVisualizer::read(uint8_t* rxBuffer) {
+ MsgPacketData* adp = (MsgPacketData*)rxBuffer;
+
+ /* discard incorrect atmel data protocol packet */
+ if(adp->bytesSent == 0) return;
+
+ for(uint16_t i = 0; i < buffer.length; i++) {
+ DataPacket* packet = this->buffer.cache[i].packet;
+
+ if(adp->streamId == packet->id) {
+
+ switch(packet->length) {
+ case LENGTH_N_BYTE: {
+ packet->sent = adp->bytesSent;
+ memcpy(packet->data, adp->data, LENGTH_N_BYTE);
+ break;
+ }
+
+ case LENGTH_4_BYTE: {
+ packet->sent = LENGTH_4_BYTE;
+ uint8_t index = adp->bytesSent - LENGTH_4_BYTE;
+ memcpy(packet->data, &adp->data[index], LENGTH_4_BYTE);
+ break;
+ }
+
+ case LENGTH_1_BYTE: {
+ packet->sent = LENGTH_1_BYTE;
+ packet->data[0] = adp->data[0];
+ break;
+ }
+ }
+ }
+ }
+}
+
+void DataVisualizer::write(uint16_t id, uint8_t* data, uint8_t length) {
+ uint8_t rxData[MSG_RES_DATA_PACKET_MAX_LEN];
+ memset(rxData, 0, MSG_RES_DATA_PACKET_MAX_LEN);
+
+ if(this->protocol.transceiveSingleStream(id, data, length, rxData)) {
+ this->read(rxData);
+ };
+}
+
+bool DataVisualizer::init(void) {
+ if(this->handshake) {
+ if(!this->initialized) {
+ this->initialized = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+void DataVisualizer::defaults(void) {
+ this->index = 0;
+ this->handshake = false;
+ this->initialized = false;
+ this->gateway = GATEWAY_NONE;
+}
+
+void DataVisualizer::release(void) {
+ for(uint16_t i = 0; i < this->buffer.length; i++) {
+ free(this->buffer.cache[i].packet);
+ }
+ free(this->buffer.cache);
+}
+
+DataPacket* DataVisualizer::pack(uint16_t id, DataLength length) {
+ this->buffer.length++;
+
+ uint16_t setLength = this->buffer.length;
+ DataCache* cache = (DataCache*) malloc(sizeof(DataCache) * setLength);
+ memset(cache, 0 , sizeof(DataCache) * setLength);
+
+ uint16_t copyLength = this->buffer.length - 1;
+ memcpy(cache, this->buffer.cache, sizeof(DataCache) * copyLength);
+
+ free(this->buffer.cache);
+ this->buffer.cache = cache;
+
+ uint16_t packetIndex = this->buffer.length - 1;
+ this->buffer.cache[packetIndex].packet = new DataPacket;
+
+ DataPacket* packet = this->buffer.cache[packetIndex].packet;
+ packet->id = id;
+ packet->sent = 0;
+ packet->length = length;
+ packet->data = new uint8_t[length];
+ memset(packet->data, 0, length);
+
+ return packet;
+}
+
+/*********************************************************/
+/* Common */
+/*********************************************************/
+
+DataVisualizer::DataVisualizer(void) {
+ this->protocol.addAtmelDataGateway(this);
+ this->defaults();
+}
+
+bool DataVisualizer::setup(Configuration config) {
+ switch(config) {
+ case CONFIGURATION_NONE:
+ return this->init();
+
+ case CONFIGURATION_AUTOSTART:
+ this->request();
+ this->refresh();
+ return this->init();
+ }
+
+ return 0;
+}
+
+bool DataVisualizer::request(void) {
+ if(!this->handshake) {
+ uint8_t handshakeStatus;
+ if(this->protocol.requestHandshake(ADP_VERSION, 0, &handshakeStatus)) {
+ if(handshakeStatus == HANDSHAKE_ACCEPTED) {
+ this->handshake = true;
+ }
+ }
+ }
+ return this->handshake;
+}
+
+void DataVisualizer::refresh(void) {
+ if(this->handshake) {
+ uint8_t rxData[MSG_RES_DATA_PACKET_MAX_LEN];
+ memset(rxData, 0, MSG_RES_DATA_PACKET_MAX_LEN);
+
+ if(this->protocol.receivePacketData(rxData)) {
+ this->read(rxData);
+ }
+ }
+}
+
+void DataVisualizer::reset(void) {
+ this->defaults();
+ this->release();
+}
+
+/*********************************************************/
+/* Elements */
+/*********************************************************/
+
+void DataVisualizer::addInfo(const char *title, const char *description) {
+ if(!this->handshake) return;
+
+ this->protocol.configureInfo(title, description);
+}
+
+DataVisualizerTerminal DataVisualizer::addTerminal(const char *title) {
+ return this->addTerminal(title, COLOR_WHITE, COLOR_BLACK);
+}
+
+DataVisualizerTerminal DataVisualizer::addTerminal(const char *title, RgbColor bgColor, RgbColor fgColor) {
+ DataVisualizerTerminal terminal;
+
+ if(!this->handshake) return terminal;
+
+ uint16_t terminalId = this->index++;
+ uint16_t terminalStreamIdIn = this->index++;
+ uint16_t terminalStreamIdOut = this->index++;
+
+ terminal.visualizer = this;
+ terminal.id = terminalStreamIdOut;
+ terminal.packet = this->pack(terminalStreamIdIn, LENGTH_N_BYTE);
+
+ MsgConfigTerminal msgConfigTerminal;
+ this->protocol.configureTerminalGetDefaults(&msgConfigTerminal);
+ msgConfigTerminal.terminalId = terminalId;
+ this->protocol.setColor(msgConfigTerminal.backgroundColor, bgColor);
+ this->protocol.setColor(msgConfigTerminal.foregroundColor, fgColor);
+ this->protocol.configureTerminal(&msgConfigTerminal, title);
+
+ MsgConfigStream msgConfigStream;
+ this->protocol.configureStreamGetDefaults(&msgConfigStream);
+ msgConfigStream.streamId = terminalStreamIdIn;
+ msgConfigStream.type = STREAM_STRING;
+ msgConfigStream.mode = STREAM_IN;
+ msgConfigStream.state = STREAM_ON;
+ this->protocol.configureStream(&msgConfigStream, "TerminalStreamIn");
+
+ MsgConfigAddStreamToTerminal msgConfigTerminalStream;
+ this->protocol.addStreamToTerminalGetDefaults(&msgConfigTerminalStream);
+ msgConfigTerminalStream.terminalId = terminalId;
+ msgConfigTerminalStream.streamId = terminalStreamIdIn;
+ this->protocol.addStreamToTerminal(&msgConfigTerminalStream, "AddTerminalStreamIn");
+
+ this->protocol.configureStreamGetDefaults(&msgConfigStream);
+ msgConfigStream.streamId = terminalStreamIdOut;
+ msgConfigStream.type = STREAM_STRING;
+ msgConfigStream.mode = STREAM_OUT;
+ msgConfigStream.state = STREAM_ON;
+ this->protocol.configureStream(&msgConfigStream, "TerminalStreamOut");
+
+ this->protocol.addStreamToTerminalGetDefaults(&msgConfigTerminalStream);
+ msgConfigTerminalStream.terminalId = terminalId;
+ msgConfigTerminalStream.streamId = terminalStreamIdOut;
+ this->protocol.addStreamToTerminal(&msgConfigTerminalStream, "AddTerminalStreamOut");
+
+ return terminal;
+}
+
+DataVisualizerGraph DataVisualizer::addGraph(const char* title) {
+ return this->addGraph(title, COLOR_BLACK);
+}
+
+DataVisualizerGraph DataVisualizer::addGraph(const char* title, RgbColor bgColor) {
+ DataVisualizerGraph graph;
+
+ if(!this->handshake) return graph;
+
+ uint16_t graphId = this->index++;
+ graph.visualizer = this;
+ graph.id = graphId;
+
+ MsgConfigGraph msgConfigGraph;
+ this->protocol.configureGraphGetDefaults(&msgConfigGraph);
+ msgConfigGraph.graphId = graphId;
+ this->protocol.setColor(msgConfigGraph.backgroundColor, bgColor);
+ this->protocol.configureGraph(&msgConfigGraph, title, "graph");
+
+ return graph;
+}
+
+DataVisualizerDashboard DataVisualizer::addDashboard(const char* title) {
+ return this->addDashboard(title, COLOR_WHITE, 500);
+}
+
+DataVisualizerDashboard DataVisualizer::addDashboard(const char* title, RgbColor color, uint16_t height) {
+ DataVisualizerDashboard dashboard;
+
+ if(!this->handshake) return dashboard;
+
+ uint16_t dashboardId = this->index++;
+ dashboard.visualizer = this;
+ dashboard.id = dashboardId;
+
+ MsgConfigDahsboard msgConfigDashboard;
+ this->protocol.configureDashboardGetDefaults(&msgConfigDashboard);
+ msgConfigDashboard.dashboardId = dashboardId;
+ msgConfigDashboard.height = height;
+ this->protocol.setColor(msgConfigDashboard.color, color);
+ this->protocol.addDashboard(&msgConfigDashboard, title);
+
+ return dashboard;
+}
+
+/*********************************************************/
+/* Gateway */
+/*********************************************************/
+
+void DataVisualizer::onTransmit(void (*f)(uint8_t*, uint16_t)) {
+ this->transmitCallback = f;
+}
+
+void DataVisualizer::onReceive(uint16_t (*f)(uint8_t*, uint16_t)) {
+ this->receiveCallback = f;
+}
+
+void DataVisualizer::onTransceive(uint16_t (*f)(uint8_t*, uint8_t*, uint16_t)) {
+ this->transceiveCallback = f;
+}
+
+void DataVisualizer::transmit(uint8_t* txBuffer, uint16_t length) {
+ if(this->gateway == GATEWAY_EXTERN)
+ this->transmitCallback(txBuffer, length);
+#ifdef GATEWAY_INCLUDED_UART
+ if(this->gateway == GATEWAY_UART)
+ this->gatewayUart.transmit(txBuffer, length);
+#endif
+#ifdef GATEWAY_INCLUDED_TWI
+ if(this->gateway == GATEWAY_TWI)
+ this->gatewayTwi.transmit(txBuffer, length);
+#endif
+#ifdef GATEWAY_INCLUDED_SPI
+ if(this->gateway == GATEWAY_SPI)
+ this->gatewaySpi.transmit(txBuffer, length);
+#endif
+}
+
+uint16_t DataVisualizer::receive(uint8_t* rxBuffer, uint16_t length) {
+ if(this->gateway == GATEWAY_EXTERN)
+ return this->receiveCallback(rxBuffer, length);
+#ifdef GATEWAY_INCLUDED_UART
+ if(this->gateway == GATEWAY_UART)
+ return this->gatewayUart.receive(rxBuffer, length);
+#endif
+#ifdef GATEWAY_INCLUDED_TWI
+ if(this->gateway == GATEWAY_TWI)
+ return this->gatewayTwi.receive(rxBuffer, length);
+#endif
+#ifdef GATEWAY_INCLUDED_SPI
+ if(this->gateway == GATEWAY_SPI)
+ return this->gatewaySpi.receive(rxBuffer, length);
+#endif
+ return 0;
+}
+
+uint16_t DataVisualizer::transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length) {
+ if(this->gateway == GATEWAY_EXTERN)
+ return this->transceiveCallback(txBuffer, rxBuffer, length);
+#ifdef GATEWAY_INCLUDED_UART
+ if(this->gateway == GATEWAY_UART)
+ return this->gatewayUart.transceive(txBuffer, rxBuffer, length);
+#endif
+#ifdef GATEWAY_INCLUDED_TWI
+ if(this->gateway == GATEWAY_TWI)
+ return this->gatewayTwi.transceive(txBuffer, rxBuffer, length);
+#endif
+#ifdef GATEWAY_INCLUDED_SPI
+ if(this->gateway == GATEWAY_SPI)
+ return this->gatewaySpi.transceive(txBuffer, rxBuffer, length);
+#endif
+ return 0;
+}
+
+void DataVisualizer::begin(DataGateway com) {
+ this->gateway = com;
+#ifdef GATEWAY_INCLUDED_UART
+ if(com == GATEWAY_UART)
+ this->gatewayUart.begin();
+#endif
+#ifdef GATEWAY_INCLUDED_TWI
+ if(com == GATEWAY_TWI)
+ this->gatewayTwi.begin();
+#endif
+#ifdef GATEWAY_INCLUDED_SPI
+ if(com == GATEWAY_SPI)
+ this->gatewaySpi.begin();
+#endif
+}
+
+#ifdef GATEWAY_INCLUDED_UART
+void DataVisualizer::begin(Stream* uart) {
+ this->gateway = GATEWAY_UART;
+ this->gatewayUart.begin(uart);
+}
+#endif
+
+#ifdef GATEWAY_INCLUDED_TWI
+void DataVisualizer::begin(TwoWire* twi, uint8_t address) {
+ this->gateway = GATEWAY_TWI;
+ this->gatewayTwi.begin(twi, address);
+}
+#endif
+
+#ifdef GATEWAY_INCLUDED_SPI
+void DataVisualizer::begin(SPIClass* spi, SPISettings settings, uint8_t ss) {
+ this->gateway = GATEWAY_SPI;
+ this->gatewaySpi.begin(spi, settings, ss);
+}
+#endif
+
+DataVisualizer Visualizer = DataVisualizer();
\ No newline at end of file
diff --git a/src/DataVisualizer.h b/src/DataVisualizer.h
new file mode 100644
index 0000000..79e8c68
--- /dev/null
+++ b/src/DataVisualizer.h
@@ -0,0 +1,181 @@
+#ifndef DATA_VISUALIZER_H
+#define DATA_VISUALIZER_H
+
+#include
+#include
+#include
+#include
+
+#include "AtmelDataProtocol.h"
+#include "AtmelDataGatewayUart.h"
+#include "AtmelDataGatewaySpi.h"
+#include "AtmelDataGatewayTwi.h"
+#include "DataVisualizerTerminal.h"
+#include "DataVisualizerGraph.h"
+#include "DataVisualizerGraphAxis.h"
+#include "DataVisualizerGraphAxisCursor.h"
+#include "DataVisualizerGraphAxisChannel.h"
+#include "DataVisualizerDashboard.h"
+#include "DataVisualizerDashboardButton.h"
+#include "DataVisualizerDashboardNumericInput.h"
+#include "DataVisualizerDashboardLabel.h"
+#include "DataVisualizerDashboardSignal.h"
+#include "DataVisualizerDashboardRadioGroup.h"
+#include "DataVisualizerDashboardGraph.h"
+#include "DataVisualizerDashboardGraphChannel.h"
+
+enum Configuration {
+ CONFIGURATION_NONE,
+ CONFIGURATION_AUTOSTART
+};
+
+enum DataGateway {
+ GATEWAY_NONE,
+ GATEWAY_EXTERN,
+ GATEWAY_TWI,
+ GATEWAY_SPI,
+ GATEWAY_UART,
+ GATEWAY_SERIAL = GATEWAY_UART
+};
+
+enum DataLength {
+ LENGTH_1_BYTE = 1,
+ LENGTH_4_BYTE = 4,
+ LENGTH_N_BYTE = MSG_RES_DATA_MAX_LEN
+};
+
+struct DataPacket {
+ uint16_t id;
+ uint16_t sent;
+ uint8_t* data;
+ DataLength length;
+};
+
+struct DataCache {
+ DataPacket* packet;
+};
+
+struct DataBuffer {
+ uint16_t length;
+ DataCache* cache;
+};
+
+class DataVisualizerGraph;
+class DataVisualizerTerminal;
+class DataVisualizerDashboard;
+class DataVisualizer : AtmelDataGateway {
+ friend class DataVisualizerTerminal;
+ friend class DataVisualizerGraph;
+ friend class DataVisualizerGraphAxis;
+ friend class DataVisualizerGraphAxisChannel;
+ friend class DataVisualizerGraphAxisCursor;
+ friend class DataVisualizerDashboard;
+ friend class DataVisualizerDashboardButton;
+ friend class DataVisualizerDashboardNumericInput;
+ friend class DataVisualizerDashboardSignal;
+ friend class DataVisualizerDashboardRadioGroup;
+ friend class DataVisualizerDashboardGraph;
+ friend class DataVisualizerDashboardGraphChannel;
+
+ private:
+ bool handshake;
+ bool initialized;
+ uint16_t index;
+ DataBuffer buffer;
+ AtmelDataProtocol protocol;
+
+ /*********************************************************/
+ /* Internal */
+ /*********************************************************/
+ bool init(void);
+ void defaults(void);
+ void release(void);
+ void read(uint8_t* rxBuffer);
+ void write(uint16_t id, uint8_t* data, uint8_t length);
+ DataPacket* pack(uint16_t id, DataLength length);
+
+ public:
+ DataVisualizer(void);
+
+ /*********************************************************/
+ /* Common */
+ /*********************************************************/
+ bool setup(Configuration config);
+ bool request(void);
+ void refresh(void);
+ void reset(void);
+
+ /*********************************************************/
+ /* Elements */
+ /*********************************************************/
+ void addInfo(const char* title, const char* description);
+ DataVisualizerTerminal addTerminal(const char* title);
+ DataVisualizerTerminal addTerminal(const char* title, RgbColor bgColor, RgbColor fgColor);
+ DataVisualizerGraph addGraph(const char* title);
+ DataVisualizerGraph addGraph(const char* title, RgbColor bgColor);
+ DataVisualizerDashboard addDashboard(const char* title);
+ DataVisualizerDashboard addDashboard(const char* title, RgbColor color, uint16_t height);
+
+ /*********************************************************/
+ /* Gateway */
+ /*********************************************************/
+ private:
+ DataGateway gateway;
+
+ virtual void transmit(uint8_t* txBuffer, uint16_t length);
+ virtual uint16_t receive(uint8_t* rxBuffer, uint16_t length);
+ virtual uint16_t transceive(uint8_t* txBuffer, uint8_t* rxBuffer, uint16_t length);
+
+ public:
+ void begin(DataGateway com);
+
+ /*********************************************************/
+ /* Gateway External */
+ /*********************************************************/
+ private:
+ void (*transmitCallback)(uint8_t*, uint16_t) = NULL;
+ uint16_t (*receiveCallback)(uint8_t*, uint16_t) = NULL;
+ uint16_t (*transceiveCallback)(uint8_t*, uint8_t*, uint16_t) = NULL;
+
+ public:
+ void onTransmit(void (*)(uint8_t*, uint16_t));
+ void onReceive(uint16_t (*)(uint8_t*, uint16_t));
+ void onTransceive(uint16_t (*)(uint8_t*, uint8_t*, uint16_t));
+
+#ifdef GATEWAY_INCLUDED_UART
+ /*********************************************************/
+ /* Gateway Universal Asynchronous Receiver Transmitter */
+ /*********************************************************/
+ private:
+ AtmelDataGatewayUart gatewayUart;
+
+ public:
+ void begin(Stream* uart);
+#endif
+
+#ifdef GATEWAY_INCLUDED_TWI
+ /*********************************************************/
+ /* Gateway Two Wire Interface */
+ /*********************************************************/
+ private:
+ AtmelDataGatewayTwi gatewayTwi;
+
+ public:
+ void begin(TwoWire* twi, uint8_t address);
+#endif
+
+#ifdef GATEWAY_INCLUDED_SPI
+ /*********************************************************/
+ /* Gateway Serial Peripheral Interface */
+ /*********************************************************/
+ private:
+ AtmelDataGatewaySpi gatewaySpi;
+
+ public:
+ void begin(SPIClass* spi, SPISettings settings, uint8_t ss);
+#endif
+};
+
+extern DataVisualizer Visualizer;
+
+#endif /* DATA_VISUALIZER_H */
\ No newline at end of file
diff --git a/src/DataVisualizerDashboard.cpp b/src/DataVisualizerDashboard.cpp
new file mode 100644
index 0000000..96086d0
--- /dev/null
+++ b/src/DataVisualizerDashboard.cpp
@@ -0,0 +1,427 @@
+#include "DataVisualizerDashboard.h"
+
+DataVisualizerDashboard::DataVisualizerDashboard(void) {
+ this->id = 0;
+ this->visualizer = 0;
+}
+
+DataVisualizerDashboardLabel DataVisualizerDashboard::addLabel(const uint8_t* config) {
+ DataVisualizerDashboardLabel dashboardLabel;
+
+ if(config[POSITION_TYPE] != DB_TYPE_LABEL) return dashboardLabel;
+
+ uint8_t length = strlen((const char*)(config + POSITION_LABEL_TEXT)) + 1;
+ char text[length];
+ memcpy(&text, config + POSITION_LABEL_TEXT, length);
+
+ ConfigDashboardLabel configDashboardLabel;
+ memcpy(&configDashboardLabel.zIndex, config + POSITION_Z_INDEX, sizeof(configDashboardLabel.zIndex));
+ memcpy(&configDashboardLabel.x, config + POSITION_X, sizeof(configDashboardLabel.x));
+ memcpy(&configDashboardLabel.y, config + POSITION_Y, sizeof(configDashboardLabel.y));
+ memcpy(&configDashboardLabel.width, config + POSITION_WIDTH, sizeof(configDashboardLabel.width));
+ memcpy(&configDashboardLabel.height, config + POSITION_HEIGHT, sizeof(configDashboardLabel.height));
+ memcpy(&configDashboardLabel.fontSize, config + POSITION_LABEL_FONT, sizeof(configDashboardLabel.fontSize));
+ memcpy(&configDashboardLabel.backgroundAlpha, config + POSITION_LABEL_ALPHA_BACKGROUND, sizeof(configDashboardLabel.backgroundAlpha));
+ memcpy(&configDashboardLabel.forgroundAlpha, config + POSITION_LABEL_ALPHA_FOREGROUND, sizeof(configDashboardLabel.forgroundAlpha));
+ memcpy(&configDashboardLabel.attribute, config + POSITION_LABEL_ATTRIBUTE, sizeof(configDashboardLabel.attribute));
+ memcpy(&configDashboardLabel.aligmentHorisontal, config + POSITION_LABEL_HOR_ALIG, sizeof(configDashboardLabel.aligmentHorisontal));
+ memcpy(&configDashboardLabel.aligmentVertical, config + POSITION_LABEL_VER_ALIG, sizeof(configDashboardLabel.aligmentVertical));
+ memcpy(&configDashboardLabel.backgroundColor, config + POSITION_LABEL_COLOR_BACKGROUND, sizeof(configDashboardLabel.backgroundColor));
+ memcpy(&configDashboardLabel.forgroundColor, config + POSITION_LABEL_COLOR_FOREGROUND, sizeof(configDashboardLabel.forgroundColor));
+
+ this->addLabel(text, configDashboardLabel);
+}
+
+DataVisualizerDashboardLabel DataVisualizerDashboard::addLabel(const char* text, ConfigDashboardLabel config) {
+ DataVisualizerDashboardLabel dashboardLabel;
+
+ if(!this->visualizer) return dashboardLabel;
+ if(!this->visualizer->handshake) return dashboardLabel;
+
+ uint16_t elementId = this->visualizer->index++;
+
+ dashboardLabel.visualizer = this->visualizer;
+ dashboardLabel.id = elementId;
+
+ MsgConfigDashboardElementLabel msgConfigDashboardElementLabel;
+ this->visualizer->protocol.configureDashboardLabelGetDefaults(&msgConfigDashboardElementLabel);
+ msgConfigDashboardElementLabel.elementType = ELEMENT_TYPE_LABEL;
+ msgConfigDashboardElementLabel.dashboardId = this->id;
+ msgConfigDashboardElementLabel.elementId = elementId;
+ msgConfigDashboardElementLabel.zIndex = config.zIndex;
+ msgConfigDashboardElementLabel.x = config.x;
+ msgConfigDashboardElementLabel.y = config.y;
+ msgConfigDashboardElementLabel.width = config.width;
+ msgConfigDashboardElementLabel.height = config.height;
+ msgConfigDashboardElementLabel.fontSize = config.fontSize;
+ msgConfigDashboardElementLabel.attribute = config.attribute;
+ msgConfigDashboardElementLabel.horisontalAlignment = config.aligmentHorisontal;
+ msgConfigDashboardElementLabel.verticalAlignment = config.aligmentVertical;
+ msgConfigDashboardElementLabel.backgroundTransparency = config.backgroundAlpha;
+ msgConfigDashboardElementLabel.foregroundTransparency = config.forgroundAlpha;
+ this->visualizer->protocol.setColor(msgConfigDashboardElementLabel.backgroundColor, config.backgroundColor);
+ this->visualizer->protocol.setColor(msgConfigDashboardElementLabel.foregroundColor, config.forgroundColor);
+ this->visualizer->protocol.addLabelToDashboard(&msgConfigDashboardElementLabel, text);
+
+ return dashboardLabel;
+}
+
+DataVisualizerDashboardNumericInput DataVisualizerDashboard::addNumericInput(const uint8_t* config) {
+ DataVisualizerDashboardNumericInput dashboardNumericInput;
+
+ if(config[POSITION_TYPE] != DB_TYPE_TEXT) return dashboardNumericInput;
+
+ ConfigDashboardNumericInput configDashboardNumericInput;
+ memcpy(&configDashboardNumericInput.zIndex, config + POSITION_Z_INDEX, sizeof(configDashboardNumericInput.zIndex));
+ memcpy(&configDashboardNumericInput.x, config + POSITION_X, sizeof(configDashboardNumericInput.x));
+ memcpy(&configDashboardNumericInput.y, config + POSITION_Y, sizeof(configDashboardNumericInput.y));
+ memcpy(&configDashboardNumericInput.width, config + POSITION_WIDTH, sizeof(configDashboardNumericInput.width));
+ memcpy(&configDashboardNumericInput.height, config + POSITION_HEIGHT, sizeof(configDashboardNumericInput.height));
+ memcpy(&configDashboardNumericInput.minimum, config + POSITION_TEXT_MINIMUM, sizeof(configDashboardNumericInput.minimum));
+ memcpy(&configDashboardNumericInput.maximum, config + POSITION_TEXT_MAXIMUM, sizeof(configDashboardNumericInput.maximum));
+ memcpy(&configDashboardNumericInput.value, config + POSITION_TEXT_VALUE, sizeof(configDashboardNumericInput.value));
+
+ return this->addNumericInput(configDashboardNumericInput);
+}
+
+DataVisualizerDashboardNumericInput DataVisualizerDashboard::addNumericInput(ConfigDashboardNumericInput config) {
+ DataVisualizerDashboardNumericInput dashboardNumericInput;
+
+ if(!this->visualizer) return dashboardNumericInput;
+ if(!this->visualizer->handshake) return dashboardNumericInput;
+
+ uint16_t elementId = this->visualizer->index++;
+ uint16_t streamId = this->visualizer->index++;
+
+ dashboardNumericInput.visualizer = this->visualizer;
+ dashboardNumericInput.id = elementId;
+ dashboardNumericInput.packet = this->visualizer->pack(streamId, LENGTH_4_BYTE);
+ memcpy(dashboardNumericInput.packet->data, &config.value, LENGTH_4_BYTE);
+
+ MsgConfigDashboardElementText msgConfigDashboardElementText;
+ this->visualizer->protocol.configureDashboardTextGetDefaults(&msgConfigDashboardElementText);
+ msgConfigDashboardElementText.elementType = ELEMENT_TYPE_TEXT;
+ msgConfigDashboardElementText.dashboardId = this->id;
+ msgConfigDashboardElementText.elementId = elementId;
+ msgConfigDashboardElementText.zIndex = config.zIndex;
+ msgConfigDashboardElementText.x = config.x;
+ msgConfigDashboardElementText.y = config.y;
+ msgConfigDashboardElementText.width = config.width;
+ msgConfigDashboardElementText.height = config.height;
+ memcpy(msgConfigDashboardElementText.minimum, &config.minimum, LENGTH_4_BYTE);
+ memcpy(msgConfigDashboardElementText.maximum, &config.maximum, LENGTH_4_BYTE);
+ memcpy(msgConfigDashboardElementText.value, &config.value, LENGTH_4_BYTE);
+ this->visualizer->protocol.addTextToDashboard(&msgConfigDashboardElementText);
+
+ MsgConfigStream msgConfigStream;
+ msgConfigStream.streamId = streamId;
+ msgConfigStream.type = STREAM_INT_32;
+ msgConfigStream.mode = STREAM_IN;
+ msgConfigStream.state = STREAM_ON;
+ this->visualizer->protocol.configureStream(&msgConfigStream, "NumericInput");
+
+ MsgConfigAddStreamToElement msgConfigAddStreamToElement;
+ msgConfigAddStreamToElement.dashboardId = this->id;
+ msgConfigAddStreamToElement.elementId = elementId;
+ msgConfigAddStreamToElement.streamId = streamId;
+ this->visualizer->protocol.addStreamToElement(&msgConfigAddStreamToElement);
+
+ return dashboardNumericInput;
+}
+
+DataVisualizerDashboardButton DataVisualizerDashboard::addButton(const char* text, ConfigDashboardButton config) {
+ return this->addButton(text, config, VARIANT_TOGGLED_OFF);
+}
+
+DataVisualizerDashboardButton DataVisualizerDashboard::addButton(const char* textOn, const char* textOff, ConfigDashboardButton config) {
+
+ uint8_t length = strlen(textOn) + strlen(textOff) + 2;
+
+ const char delimiter[] = "/";
+ char text[length];
+
+ strcat(text, textOn);
+ strcat(text, delimiter);
+ strcat(text, textOff);
+
+ return this->addButton(text, config, VARIANT_TOGGLED_ON);
+}
+
+DataVisualizerDashboardButton DataVisualizerDashboard::addButton(const uint8_t* config) {
+ DataVisualizerDashboardButton dashboardButton;
+
+ if(config[POSITION_TYPE] != DB_TYPE_BUTTON) return dashboardButton;
+
+ uint8_t length = strlen((const char*)(config + POSITION_BUTTON_TEXT)) + 1;
+ char text[length];
+ memcpy(&text, config + POSITION_BUTTON_TEXT, length);
+
+ ConfigDashboardButton configDashboardButton;
+ memcpy(&configDashboardButton.zIndex, config + POSITION_Z_INDEX, sizeof(configDashboardButton.zIndex));
+ memcpy(&configDashboardButton.x, config + POSITION_X, sizeof(configDashboardButton.x));
+ memcpy(&configDashboardButton.y, config + POSITION_Y, sizeof(configDashboardButton.y));
+ memcpy(&configDashboardButton.width, config + POSITION_WIDTH, sizeof(configDashboardButton.width));
+ memcpy(&configDashboardButton.height, config + POSITION_HEIGHT, sizeof(configDashboardButton.height));
+ memcpy(&configDashboardButton.fontSize, config + POSITION_BUTTON_FONT_SIZE, sizeof(configDashboardButton.fontSize));
+
+ uint8_t toggle = config[POSITION_BUTTON_TEXT + length];
+
+ return this->addButton(text, configDashboardButton, toggle);
+}
+
+DataVisualizerDashboardButton DataVisualizerDashboard::addButton(const char* text, ConfigDashboardButton config, uint8_t toggle) {
+ DataVisualizerDashboardButton dashboardButton;
+
+ if(!this->visualizer) return dashboardButton;
+ if(!this->visualizer->handshake) return dashboardButton;
+
+ uint16_t elementId = this->visualizer->index++;
+ uint16_t streamId = this->visualizer->index++;
+
+ dashboardButton.visualizer = this->visualizer;
+ dashboardButton.id = elementId;
+ dashboardButton.packet = this->visualizer->pack(streamId, LENGTH_1_BYTE);
+
+ MsgConfigDashboardElementButton msgConfigDashboardElementButton;
+ this->visualizer->protocol.configureDashboardButtonGetDefaults(&msgConfigDashboardElementButton);
+ msgConfigDashboardElementButton.elementType = ELEMENT_TYPE_BUTTON;
+ msgConfigDashboardElementButton.dashboardId = this->id;
+ msgConfigDashboardElementButton.elementId = elementId;
+ msgConfigDashboardElementButton.zIndex = config.zIndex;
+ msgConfigDashboardElementButton.x = config.x;
+ msgConfigDashboardElementButton.y = config.y;
+ msgConfigDashboardElementButton.width = config.width;
+ msgConfigDashboardElementButton.height = config.height;
+ msgConfigDashboardElementButton.fontSize = config.fontSize;
+ msgConfigDashboardElementButton.toggle = toggle;
+ this->visualizer->protocol.addButtonToDashboard(&msgConfigDashboardElementButton, text);
+
+ MsgConfigStream msgConfigStream;
+ msgConfigStream.streamId = streamId;
+ msgConfigStream.type = STREAM_UINT_8;
+ msgConfigStream.mode = STREAM_IN;
+ msgConfigStream.state = STREAM_ON;
+ this->visualizer->protocol.configureStream(&msgConfigStream, "Button");
+
+ MsgConfigAddStreamToElement msgConfigAddStreamToElement;
+ msgConfigAddStreamToElement.dashboardId = this->id;
+ msgConfigAddStreamToElement.elementId = elementId;
+ msgConfigAddStreamToElement.streamId = streamId;
+ this->visualizer->protocol.addStreamToElement(&msgConfigAddStreamToElement);
+
+ return dashboardButton;
+}
+
+DataVisualizerDashboardSignal DataVisualizerDashboard::addSignal(const uint8_t* config) {
+ DataVisualizerDashboardSignal dashboardSignal;
+
+ if(config[POSITION_TYPE] != DB_TYPE_SIGNAL) return dashboardSignal;
+
+ ConfigDashboardSignal configDashboardSignal;
+ memcpy(&configDashboardSignal.zIndex, config + POSITION_Z_INDEX, sizeof(configDashboardSignal.zIndex));
+ memcpy(&configDashboardSignal.x, config + POSITION_X, sizeof(configDashboardSignal.x));
+ memcpy(&configDashboardSignal.y, config + POSITION_Y, sizeof(configDashboardSignal.y));
+ memcpy(&configDashboardSignal.width, config + POSITION_WIDTH, sizeof(configDashboardSignal.width));
+ memcpy(&configDashboardSignal.height, config + POSITION_HEIGHT, sizeof(configDashboardSignal.height));
+ memcpy(&configDashboardSignal.onAlpha, config + POSITION_SIGNAL_ALPHA_ON, sizeof(configDashboardSignal.onAlpha));
+ memcpy(&configDashboardSignal.offAlpha, config + POSITION_SIGNAL_ALPHA_OFF, sizeof(configDashboardSignal.offAlpha));
+ memcpy(&configDashboardSignal.onColor, config + POSITION_SIGNAL_COLOR_ON, sizeof(configDashboardSignal.onColor));
+ memcpy(&configDashboardSignal.offColor, config + POSITION_SIGNAL_COLOR_OFF, sizeof(configDashboardSignal.offColor));
+
+ return this->addSignal(configDashboardSignal);
+}
+
+DataVisualizerDashboardSignal DataVisualizerDashboard::addSignal(ConfigDashboardSignal config) {
+ DataVisualizerDashboardSignal dashboardSignal;
+
+ if(!this->visualizer) return dashboardSignal;
+ if(!this->visualizer->handshake) return dashboardSignal;
+
+ uint16_t elementId = this->visualizer->index++;
+ uint16_t streamId = this->visualizer->index++;
+
+ dashboardSignal.visualizer = this->visualizer;
+ dashboardSignal.id = streamId;
+
+ MsgConfigDashboardElementSignal msgConfigCashboardElementSignal;
+ this->visualizer->protocol.configureDashboardSignalGetDefaults(&msgConfigCashboardElementSignal);
+ msgConfigCashboardElementSignal.elementType = ELEMENT_TYPE_SIGNAL;
+ msgConfigCashboardElementSignal.dashboardId = this->id;
+ msgConfigCashboardElementSignal.elementId = elementId;
+ msgConfigCashboardElementSignal.zIndex = config.zIndex;
+ msgConfigCashboardElementSignal.x = config.x;
+ msgConfigCashboardElementSignal.y = config.y;
+ msgConfigCashboardElementSignal.width = config.width;
+ msgConfigCashboardElementSignal.height = config.height;
+ msgConfigCashboardElementSignal.onTransparency = config.onAlpha;
+ msgConfigCashboardElementSignal.offTransparency = config.offAlpha;
+ this->visualizer->protocol.setColor(msgConfigCashboardElementSignal.onColor, config.onColor);
+ this->visualizer->protocol.setColor(msgConfigCashboardElementSignal.offColor, config.offColor);
+ this->visualizer->protocol.addSignalToDashboard(&msgConfigCashboardElementSignal);
+
+ MsgConfigStream msgConfigStream;
+ msgConfigStream.streamId = streamId;
+ msgConfigStream.type = STREAM_UINT_8;
+ msgConfigStream.mode = STREAM_OUT;
+ msgConfigStream.state = STREAM_ON;
+ this->visualizer->protocol.configureStream(&msgConfigStream, "Signal");
+
+ MsgConfigAddStreamToElement msgConfigAddStreamToElement;
+ msgConfigAddStreamToElement.dashboardId = this->id;
+ msgConfigAddStreamToElement.elementId = elementId;
+ msgConfigAddStreamToElement.streamId = streamId;
+ this->visualizer->protocol.addStreamToElement(&msgConfigAddStreamToElement);
+
+ return dashboardSignal;
+}
+
+DataVisualizerDashboardRadioGroup DataVisualizerDashboard::addRadioGroup(const uint8_t* config) {
+ DataVisualizerDashboardRadioGroup dashboardRadioGroup;
+
+ if(config[POSITION_TYPE] != DB_TYPE_RADIOGROUP) return dashboardRadioGroup;
+
+ uint8_t length = strlen((const char*)(config + POSITION_RADIOGROUP_TEXT)) + 1;
+ char text[length];
+ memcpy(&text, config + POSITION_RADIOGROUP_TEXT, length);
+
+ ConfigDashboardRadioGroup configDashboardRadioGroup;
+ memcpy(&configDashboardRadioGroup.zIndex, config + POSITION_Z_INDEX, sizeof(configDashboardRadioGroup.zIndex));
+ memcpy(&configDashboardRadioGroup.x, config + POSITION_X, sizeof(configDashboardRadioGroup.x));
+ memcpy(&configDashboardRadioGroup.y, config + POSITION_Y, sizeof(configDashboardRadioGroup.y));
+ memcpy(&configDashboardRadioGroup.width, config + POSITION_WIDTH, sizeof(configDashboardRadioGroup.width));
+ memcpy(&configDashboardRadioGroup.height, config + POSITION_HEIGHT, sizeof(configDashboardRadioGroup.height));
+ memcpy(&configDashboardRadioGroup.sizeItems, config + POSITION_RADIOGROUP_SIZE_ITEMS, sizeof(configDashboardRadioGroup.sizeItems));
+ memcpy(&configDashboardRadioGroup.numberItems, config + POSITION_RADIOGROUP_NUMBER_ITEMS, sizeof(configDashboardRadioGroup.numberItems));
+ memcpy(&configDashboardRadioGroup.orientation, config + POSITION_RADIOGROUP_ORIENTATION, sizeof(configDashboardRadioGroup.orientation));
+
+ return this->addRadioGroup(text, configDashboardRadioGroup);
+}
+
+DataVisualizerDashboardRadioGroup DataVisualizerDashboard::addRadioGroup(ConfigDashboardRadioGroup config) {
+ config.numberItems = config.numberItems > RADIOGROUP_MAX ? RADIOGROUP_MAX : config.numberItems;
+
+ char text[config.numberItems];
+ for(uint8_t i = 0; i < config.numberItems; i++) text[i] = '/';
+
+ return this->addRadioGroup(text, config);
+}
+
+DataVisualizerDashboardRadioGroup DataVisualizerDashboard::addRadioGroup(const char* text, ConfigDashboardRadioGroup config) {
+ DataVisualizerDashboardRadioGroup dashboardRadioGroup;
+
+ if(!this->visualizer) return dashboardRadioGroup;
+ if(!this->visualizer->handshake) return dashboardRadioGroup;
+
+ uint16_t elementId = this->visualizer->index++;
+ uint16_t streamId = this->visualizer->index++;
+
+ dashboardRadioGroup.visualizer = this->visualizer;
+ dashboardRadioGroup.id = elementId;
+ dashboardRadioGroup.packet = this->visualizer->pack(streamId, LENGTH_1_BYTE);
+
+ MsgConfigDashboardElementRadio msgConfigDashboardElementRadio;
+ this->visualizer->protocol.configureDashboardRadioGetDefaults(&msgConfigDashboardElementRadio);
+ msgConfigDashboardElementRadio.elementType = ELEMENT_TYPE_RADIO;
+ msgConfigDashboardElementRadio.dashboardId = this->id;
+ msgConfigDashboardElementRadio.elementId = elementId;
+ msgConfigDashboardElementRadio.zIndex = config.zIndex;
+ msgConfigDashboardElementRadio.x = config.x;
+ msgConfigDashboardElementRadio.y = config.y;
+ msgConfigDashboardElementRadio.width = config.width;
+ msgConfigDashboardElementRadio.height = config.height;
+ msgConfigDashboardElementRadio.fontSize = config.sizeItems;
+ msgConfigDashboardElementRadio.orientation = config.orientation;
+ msgConfigDashboardElementRadio.numberItems = config.numberItems;
+ this->visualizer->protocol.addRadioToDashboard(&msgConfigDashboardElementRadio, text);
+
+ MsgConfigStream msgConfigStream;
+ msgConfigStream.streamId = streamId;
+ msgConfigStream.type = STREAM_UINT_8;
+ msgConfigStream.mode = STREAM_IN;
+ msgConfigStream.state = STREAM_ON;
+ this->visualizer->protocol.configureStream(&msgConfigStream, "RadioGroup");
+
+ MsgConfigAddStreamToElement msgConfigAddStreamToElement;
+ msgConfigAddStreamToElement.dashboardId = this->id;
+ msgConfigAddStreamToElement.elementId = elementId;
+ msgConfigAddStreamToElement.streamId = streamId;
+ this->visualizer->protocol.addStreamToElement(&msgConfigAddStreamToElement);
+
+ return dashboardRadioGroup;
+}
+
+DataVisualizerDashboardGraph DataVisualizerDashboard::addGraph(uint8_t* config) {
+ DataVisualizerDashboardGraph dashboardGraph;
+
+ if(config[POSITION_TYPE] != DB_TYPE_GRAPH) return dashboardGraph;
+
+ uint8_t length = strlen((const char*)(config + POSITION_GRAPH_TEXT)) + 1;
+ char text[length];
+ memcpy(&text, config + POSITION_GRAPH_TEXT, length);
+
+ ConfigDashboardGraph configDashboardGraph;
+ memcpy(&configDashboardGraph.zIndex, config + POSITION_Z_INDEX, sizeof(configDashboardGraph.zIndex));
+ memcpy(&configDashboardGraph.x, config + POSITION_X, sizeof(configDashboardGraph.x));
+ memcpy(&configDashboardGraph.y, config + POSITION_Y, sizeof(configDashboardGraph.y));
+ memcpy(&configDashboardGraph.width, config + POSITION_WIDTH, sizeof(configDashboardGraph.width));
+ memcpy(&configDashboardGraph.height, config + POSITION_HEIGHT, sizeof(configDashboardGraph.height));
+ memcpy(&configDashboardGraph.plotCount, config + POSITION_GRAPH_PLOT_COUNT + length, sizeof(configDashboardGraph.plotCount));
+ memcpy(&configDashboardGraph.xMinimum, config + POSITION_GRAPH_X_MINIMUM + length, sizeof(configDashboardGraph.xMinimum));
+ memcpy(&configDashboardGraph.xMaximum, config + POSITION_GRAPH_X_MAXIMUM + length, sizeof(configDashboardGraph.xMaximum));
+ memcpy(&configDashboardGraph.yMinimum, config + POSITION_GRAPH_Y_MINIMUM + length, sizeof(configDashboardGraph.yMinimum));
+ memcpy(&configDashboardGraph.yMaximum, config + POSITION_GRAPH_Y_MAXIMUM + length, sizeof(configDashboardGraph.yMaximum));
+ memcpy(&configDashboardGraph.titleColor, config + POSITION_GRAPH_COLOR_TITLE, sizeof(configDashboardGraph.titleColor));
+ memcpy(&configDashboardGraph.backgroundColor, config + POSITION_GRAPH_COLOR_BACKGROUND, sizeof(configDashboardGraph.backgroundColor));
+ memcpy(&configDashboardGraph.graphColor, config + POSITION_GRAPH_COLOR_GRAPH, sizeof(configDashboardGraph.graphColor));
+
+ configDashboardGraph.mouseInteraction = config[POSITION_GRAPH_MODE_LB + length] & 0x01;
+ configDashboardGraph.fitToRight = config[POSITION_GRAPH_MODE_LB + length] & 0x02;
+ configDashboardGraph.autoscale = config[POSITION_GRAPH_MODE_LB + length] & 0x04;
+ configDashboardGraph.scrollByTime = config[POSITION_GRAPH_MODE_LB + length] & 0x08;
+ configDashboardGraph.showPlot = config[POSITION_GRAPH_MODE_HB + length] & 0x01;
+ configDashboardGraph.showPoints = config[POSITION_GRAPH_MODE_HB + length] & 0x02;
+
+ return this->addGraph(text, configDashboardGraph);
+}
+
+DataVisualizerDashboardGraph DataVisualizerDashboard::addGraph(const char* text, ConfigDashboardGraph config) {
+ DataVisualizerDashboardGraph dashboardGraph;
+
+ if(!this->visualizer) return dashboardGraph;
+ if(!this->visualizer->handshake) return dashboardGraph;
+
+ uint16_t elementId = this->visualizer->index++;
+
+ dashboardGraph.visualizer = this->visualizer;
+ dashboardGraph.dashboard = this;
+ dashboardGraph.id = elementId;
+ dashboardGraph.plotCount = config.plotCount;
+
+ MsgConfigDashboardElementGraph msgConfigDashboardElementGraph;
+ this->visualizer->protocol.configureDashboardGraphGetDefaults(&msgConfigDashboardElementGraph);
+ msgConfigDashboardElementGraph.elementType = ELEMENT_TYPE_GRAPH;
+ msgConfigDashboardElementGraph.dashboardId = this->id;
+ msgConfigDashboardElementGraph.elementId = elementId;
+ msgConfigDashboardElementGraph.zIndex = config.zIndex;
+ msgConfigDashboardElementGraph.x = config.x;
+ msgConfigDashboardElementGraph.y = config.y;
+ msgConfigDashboardElementGraph.width = config.width;
+ msgConfigDashboardElementGraph.height = config.height;
+ msgConfigDashboardElementGraph.plotCount = config.plotCount;
+ msgConfigDashboardElementGraph.xMin = config.xMinimum;
+ msgConfigDashboardElementGraph.xMax = config.xMaximum;
+ msgConfigDashboardElementGraph.yMin = config.yMinimum;
+ msgConfigDashboardElementGraph.yMax = config.yMaximum;
+ msgConfigDashboardElementGraph.mode.bit.fitGraph = config.fitToRight;
+ msgConfigDashboardElementGraph.mode.bit.mouse = config.mouseInteraction;
+ msgConfigDashboardElementGraph.mode.bit.autoscale = config.autoscale;
+ msgConfigDashboardElementGraph.mode.bit.scrollByTime = config.scrollByTime;
+ msgConfigDashboardElementGraph.mode.bit.showPlot = config.showPlot;
+ msgConfigDashboardElementGraph.mode.bit.showPoints = config.showPoints;
+ this->visualizer->protocol.setColor(msgConfigDashboardElementGraph.titleColor, config.titleColor);
+ this->visualizer->protocol.setColor(msgConfigDashboardElementGraph.backgroundColor, config.backgroundColor);
+ this->visualizer->protocol.setColor(msgConfigDashboardElementGraph.graphBackgroundColor, config.graphColor);
+ this->visualizer->protocol.addGraphToDashboard(&msgConfigDashboardElementGraph, text);
+
+ return dashboardGraph;
+}
\ No newline at end of file
diff --git a/src/DataVisualizerDashboard.h b/src/DataVisualizerDashboard.h
new file mode 100644
index 0000000..fef9c3f
--- /dev/null
+++ b/src/DataVisualizerDashboard.h
@@ -0,0 +1,191 @@
+#ifndef DATA_VISUALIZER_DASHBOARD_H
+#define DATA_VISUALIZER_DASHBOARD_H
+
+#include "DataVisualizer.h"
+
+#define POSITION_TYPE 2
+#define POSITION_Z_INDEX 3
+#define POSITION_X 4
+#define POSITION_Y 6
+#define POSITION_WIDTH 8
+#define POSITION_HEIGHT 10
+
+#define POSITION_BUTTON_FONT_SIZE 12
+#define POSITION_BUTTON_TEXT 13
+
+#define POSITION_TEXT_MINIMUM 12
+#define POSITION_TEXT_MAXIMUM 16
+#define POSITION_TEXT_VALUE 20
+
+#define POSITION_LABEL_FONT 12
+#define POSITION_LABEL_ATTRIBUTE 13
+#define POSITION_LABEL_HOR_ALIG 14
+#define POSITION_LABEL_VER_ALIG 15
+#define POSITION_LABEL_ALPHA_BACKGROUND 16
+#define POSITION_LABEL_COLOR_BACKGROUND 17
+#define POSITION_LABEL_ALPHA_FOREGROUND 20
+#define POSITION_LABEL_COLOR_FOREGROUND 21
+#define POSITION_LABEL_TEXT 24
+
+#define POSITION_SIGNAL_ALPHA_ON 12
+#define POSITION_SIGNAL_COLOR_ON 13
+#define POSITION_SIGNAL_ALPHA_OFF 16
+#define POSITION_SIGNAL_COLOR_OFF 17
+
+#define POSITION_RADIOGROUP_SIZE_ITEMS 12
+#define POSITION_RADIOGROUP_NUMBER_ITEMS 13
+#define POSITION_RADIOGROUP_ORIENTATION 14
+#define POSITION_RADIOGROUP_TEXT 15
+
+#define POSITION_GRAPH_COLOR_TITLE 12
+#define POSITION_GRAPH_COLOR_BACKGROUND 15
+#define POSITION_GRAPH_COLOR_GRAPH 18
+#define POSITION_GRAPH_TEXT 21
+#define POSITION_GRAPH_PLOT_COUNT 21
+#define POSITION_GRAPH_X_MINIMUM 22
+#define POSITION_GRAPH_X_MAXIMUM 26
+#define POSITION_GRAPH_Y_MINIMUM 30
+#define POSITION_GRAPH_Y_MAXIMUM 34
+#define POSITION_GRAPH_MODE_LB 38
+#define POSITION_GRAPH_MODE_HB 39
+
+#define RADIOGROUP_MAX 10
+
+enum DashboardType {
+ DB_TYPE_NONE,
+ DB_TYPE_LABEL,
+ DB_TYPE_BUTTON,
+ DB_TYPE_TEXT,
+ DB_TYPE_SIGNAL,
+ DB_TYPE_RADIOGROUP,
+ DB_TYPE_GRAPH
+};
+
+enum ButtonVariant {
+ VARIANT_TOGGLED_OFF,
+ VARIANT_TOGGLED_ON
+};
+
+struct ConfigDashboardLabel {
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ uint8_t fontSize;
+ LabelAttribute attribute;
+ LabelAligmentHorisontal aligmentHorisontal;
+ LabelAligmentVertical aligmentVertical;
+ RgbColor backgroundColor;
+ uint8_t backgroundAlpha;
+ RgbColor forgroundColor;
+ uint8_t forgroundAlpha;
+};
+
+struct ConfigDashboardNumericInput {
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ uint32_t minimum;
+ uint32_t maximum;
+ uint32_t value;
+};
+
+struct ConfigDashboardButton {
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ uint8_t fontSize;
+};
+
+struct ConfigDashboardSignal {
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ RgbColor onColor;
+ uint8_t onAlpha;
+ RgbColor offColor;
+ uint8_t offAlpha;
+};
+
+struct ConfigDashboardRadioGroup {
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ uint8_t sizeItems;
+ uint8_t numberItems;
+ RadioOrientation orientation;
+};
+
+struct ConfigDashboardGraph {
+ uint8_t zIndex;
+ uint16_t x;
+ uint16_t y;
+ uint16_t width;
+ uint16_t height;
+ RgbColor titleColor;
+ RgbColor backgroundColor;
+ RgbColor graphColor;
+ uint8_t plotCount;
+ float xMinimum;
+ float xMaximum;
+ float yMinimum;
+ float yMaximum;
+ bool mouseInteraction;
+ bool fitToRight;
+ bool autoscale;
+ bool scrollByTime;
+ bool showPlot;
+ bool showPoints;
+};
+
+class DataVisualizer;
+class DataVisualizerDashboardLabel;
+class DataVisualizerDashboardButton;
+class DataVisualizerDashboardNumericInput;
+class DataVisualizerDashboardSignal;
+class DataVisualizerDashboardRadioGroup;
+class DataVisualizerDashboardGraph;
+class DataVisualizerDashboard {
+ friend class DataVisualizer;
+ friend class DataVisualizerDashboardGraph;
+
+ private:
+ uint16_t id;
+ DataVisualizer* visualizer;
+ DataVisualizerDashboardButton addButton(const char* text, ConfigDashboardButton config, uint8_t toggle);
+ DataVisualizerDashboardRadioGroup addRadioGroup(const char* text, ConfigDashboardRadioGroup config);
+
+ public:
+ DataVisualizerDashboard(void);
+ DataVisualizerDashboardLabel addLabel(const uint8_t* config);
+ DataVisualizerDashboardLabel addLabel(const char* text, ConfigDashboardLabel config);
+
+ DataVisualizerDashboardNumericInput addNumericInput(const uint8_t* config);
+ DataVisualizerDashboardNumericInput addNumericInput(ConfigDashboardNumericInput config);
+
+ DataVisualizerDashboardButton addButton(const uint8_t* config);
+ DataVisualizerDashboardButton addButton(const char* text, ConfigDashboardButton config);
+ DataVisualizerDashboardButton addButton(const char* textOn, const char* textOff, ConfigDashboardButton config);
+
+ DataVisualizerDashboardSignal addSignal(const uint8_t* config);
+ DataVisualizerDashboardSignal addSignal(ConfigDashboardSignal config);
+
+ DataVisualizerDashboardRadioGroup addRadioGroup(const uint8_t* config);
+ DataVisualizerDashboardRadioGroup addRadioGroup(ConfigDashboardRadioGroup config);
+
+ DataVisualizerDashboardGraph addGraph(uint8_t* config);
+ DataVisualizerDashboardGraph addGraph(const char* text, ConfigDashboardGraph config);
+};
+
+typedef DataVisualizerDashboard Dashboard;
+
+#endif /* DATA_VISUALIZER_DASHBOARD_H */
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardButton.cpp b/src/DataVisualizerDashboardButton.cpp
new file mode 100644
index 0000000..33d201e
--- /dev/null
+++ b/src/DataVisualizerDashboardButton.cpp
@@ -0,0 +1,31 @@
+#include "DataVisualizerDashboardButton.h"
+
+DataVisualizerDashboardButton::DataVisualizerDashboardButton(void) {
+ this->id = 0;
+ this->toggle = 0;
+ this->visualizer = 0;
+ this->packet = 0;
+}
+
+bool DataVisualizerDashboardButton::pressed(void) {
+ if(!this->visualizer) return 0;
+ if(!this->visualizer->handshake) return 0;
+
+ if(this->packet->sent) {
+ if(this->packet->data[0]) {
+ this->toggle = true;
+ } else {
+ this->toggle = false;
+ }
+ this->packet->data[0] = 0;
+ this->packet->sent = 0;
+ return true;
+ }
+
+ return false;
+}
+
+bool DataVisualizerDashboardButton::toggled(void) {
+ this->pressed();
+ return this->toggle;
+}
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardButton.h b/src/DataVisualizerDashboardButton.h
new file mode 100644
index 0000000..5f67f1f
--- /dev/null
+++ b/src/DataVisualizerDashboardButton.h
@@ -0,0 +1,25 @@
+#ifndef DATA_VISUALIZER_DASHBOARD_BUTTON_H
+#define DATA_VISUALIZER_DASHBOARD_BUTTON_H
+
+#include "DataVisualizer.h"
+
+struct DataPacket;
+class DataVisualizer;
+class DataVisualizerDashboardButton {
+ friend class DataVisualizerDashboard;
+
+ private:
+ bool toggle;
+ uint16_t id;
+ DataPacket* packet;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerDashboardButton(void);
+ bool pressed(void);
+ bool toggled(void);
+};
+
+typedef DataVisualizerDashboardButton DashboardButton;
+
+#endif /* DATA_VISUALIZER_DASHBOARD_BUTTON_H */
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardGraph.cpp b/src/DataVisualizerDashboardGraph.cpp
new file mode 100644
index 0000000..12a123e
--- /dev/null
+++ b/src/DataVisualizerDashboardGraph.cpp
@@ -0,0 +1,36 @@
+#include "DataVisualizerDashboardGraph.h"
+
+DataVisualizerDashboardGraph::DataVisualizerDashboardGraph(void) {
+ this->id = 0;
+ this->visualizer = 0;
+}
+
+DataVisualizerDashboardGraphChannel DataVisualizerDashboardGraph::addChannel(const char* text) {
+ DataVisualizerDashboardGraphChannel dashboardGraphChannel;
+
+ if(!this->visualizer) return dashboardGraphChannel;
+ if(!this->visualizer->handshake) return dashboardGraphChannel;
+ if(this->plotCount == 0) return dashboardGraphChannel;
+
+ this->plotCount--;
+
+ uint16_t streamId = this->visualizer->index++;
+
+ dashboardGraphChannel.visualizer = this->visualizer;
+ dashboardGraphChannel.id = streamId;
+
+ MsgConfigStream msgConfigStream;
+ msgConfigStream.streamId = streamId;
+ msgConfigStream.type = STREAM_INT_32;
+ msgConfigStream.mode = STREAM_OUT;
+ msgConfigStream.state = STREAM_ON;
+ this->visualizer->protocol.configureStream(&msgConfigStream, text);
+
+ MsgConfigAddStreamToElement msgConfigAddStreamToElement;
+ msgConfigAddStreamToElement.dashboardId = this->dashboard->id;
+ msgConfigAddStreamToElement.elementId = this->id;
+ msgConfigAddStreamToElement.streamId = streamId;
+ this->visualizer->protocol.addStreamToElement(&msgConfigAddStreamToElement);
+
+ return dashboardGraphChannel;
+}
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardGraph.h b/src/DataVisualizerDashboardGraph.h
new file mode 100644
index 0000000..ef28656
--- /dev/null
+++ b/src/DataVisualizerDashboardGraph.h
@@ -0,0 +1,25 @@
+#ifndef DATA_VISUALIZER_DASHBOARD_GRAPH_H
+#define DATA_VISUALIZER_DASHBOARD_GRAPH_H
+
+#include "DataVisualizer.h"
+
+class DataVisualizer;
+class DataVisualizerDashboard;
+class DataVisualizerDashboardGraphChannel;
+class DataVisualizerDashboardGraph {
+ friend class DataVisualizerDashboard;
+
+ private:
+ uint16_t id;
+ uint8_t plotCount;
+ DataVisualizer* visualizer;
+ DataVisualizerDashboard *dashboard;
+
+ public:
+ DataVisualizerDashboardGraph(void);
+ DataVisualizerDashboardGraphChannel addChannel(const char* text);
+};
+
+typedef DataVisualizerDashboardGraph DashboardGraph;
+
+#endif /* DATA_VISUALIZER_DASHBOARD_GRAPH_H */
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardGraphChannel.cpp b/src/DataVisualizerDashboardGraphChannel.cpp
new file mode 100644
index 0000000..0946bb6
--- /dev/null
+++ b/src/DataVisualizerDashboardGraphChannel.cpp
@@ -0,0 +1,13 @@
+#include "DataVisualizerDashboardGraphChannel.h"
+
+DataVisualizerDashboardGraphChannel::DataVisualizerDashboardGraphChannel(void) {
+ this->id = 0;
+ this->visualizer = 0;
+}
+
+void DataVisualizerDashboardGraphChannel::write(int32_t value) {
+ if(!this->visualizer) return;
+ if(!this->visualizer->handshake) return;
+
+ this->visualizer->write(this->id, (uint8_t*) &value, sizeof(int32_t));
+}
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardGraphChannel.h b/src/DataVisualizerDashboardGraphChannel.h
new file mode 100644
index 0000000..ddae0da
--- /dev/null
+++ b/src/DataVisualizerDashboardGraphChannel.h
@@ -0,0 +1,21 @@
+#ifndef DATA_VISUALIZER_DASHBOARD_GRAPH_CHANNEL_H
+#define DATA_VISUALIZER_DASHBOARD_GRAPH_CHANNEL_H
+
+#include "DataVisualizer.h"
+
+class DataVisualizer;
+class DataVisualizerDashboardGraphChannel {
+ friend class DataVisualizerDashboardGraph;
+
+ private:
+ uint16_t id;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerDashboardGraphChannel(void);
+ void write(int32_t value);
+};
+
+typedef DataVisualizerDashboardGraphChannel DashboardGraphChannel;
+
+#endif /* DATA_VISUALIZER_DASHBOARD_GRAPH_CHANNEL_H */
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardLabel.cpp b/src/DataVisualizerDashboardLabel.cpp
new file mode 100644
index 0000000..7295c0f
--- /dev/null
+++ b/src/DataVisualizerDashboardLabel.cpp
@@ -0,0 +1,6 @@
+#include "DataVisualizerDashboardLabel.h"
+
+DataVisualizerDashboardLabel::DataVisualizerDashboardLabel(void) {
+ this->id = 0;
+ this->visualizer = 0;
+}
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardLabel.h b/src/DataVisualizerDashboardLabel.h
new file mode 100644
index 0000000..2a54d57
--- /dev/null
+++ b/src/DataVisualizerDashboardLabel.h
@@ -0,0 +1,20 @@
+#ifndef DATA_VISUALIZER_DASHBOARD_LABEL_H
+#define DATA_VISUALIZER_DASHBOARD_LABEL_H
+
+#include "DataVisualizer.h"
+
+class DataVisualizer;
+class DataVisualizerDashboardLabel {
+ friend class DataVisualizerDashboard;
+
+ private:
+ uint16_t id;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerDashboardLabel(void);
+};
+
+typedef DataVisualizerDashboardLabel DashboardLabel;
+
+#endif /* DATA_VISUALIZER_DASHBOARD_LABEL_H */
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardNumericInput.cpp b/src/DataVisualizerDashboardNumericInput.cpp
new file mode 100644
index 0000000..828ca89
--- /dev/null
+++ b/src/DataVisualizerDashboardNumericInput.cpp
@@ -0,0 +1,29 @@
+#include "DataVisualizerDashboardNumericInput.h"
+
+DataVisualizerDashboardNumericInput::DataVisualizerDashboardNumericInput(void) {
+ this->id = 0;
+ this->visualizer = 0;
+ this->packet = 0;
+}
+
+int32_t DataVisualizerDashboardNumericInput::read(void) {
+ if(!this->visualizer) return 0;
+ if(!this->visualizer->handshake) return 0;
+
+ int32_t value;
+ memcpy(&value, this->packet->data, LENGTH_4_BYTE);
+ return value;
+}
+
+bool DataVisualizerDashboardNumericInput::feed(void) {
+ if(!this->visualizer) return 0;
+ if(!this->visualizer->handshake) return 0;
+
+ if(this->packet->sent) {
+ this->packet->sent = 0;
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/DataVisualizerDashboardNumericInput.h b/src/DataVisualizerDashboardNumericInput.h
new file mode 100644
index 0000000..3328983
--- /dev/null
+++ b/src/DataVisualizerDashboardNumericInput.h
@@ -0,0 +1,24 @@
+#ifndef DATA_VISUALIZER_DASHBOARD_NUMERIC_INPUT_H
+#define DATA_VISUALIZER_DASHBOARD_NUMERIC_INPUT_H
+
+#include "DataVisualizer.h"
+
+struct DataPacket;
+class DataVisualizer;
+class DataVisualizerDashboardNumericInput {
+ friend class DataVisualizerDashboard;
+
+ private:
+ uint16_t id;
+ DataPacket* packet;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerDashboardNumericInput(void);
+ int32_t read(void);
+ bool feed(void);
+};
+
+typedef DataVisualizerDashboardNumericInput DashboardNumericInput;
+
+#endif /* DATA_VISUALIZER_DASHBOARD_NUMERIC_INPUT_H */
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardRadioGroup.cpp b/src/DataVisualizerDashboardRadioGroup.cpp
new file mode 100644
index 0000000..4816443
--- /dev/null
+++ b/src/DataVisualizerDashboardRadioGroup.cpp
@@ -0,0 +1,27 @@
+#include "DataVisualizerDashboardRadioGroup.h"
+
+DataVisualizerDashboardRadioGroup::DataVisualizerDashboardRadioGroup(void) {
+ this->id = 0;
+ this->visualizer = 0;
+ this->packet = 0;
+}
+
+uint8_t DataVisualizerDashboardRadioGroup::selected(void) {
+ if(!this->visualizer) return 0;
+ if(!this->visualizer->handshake) return 0;
+
+ return this->packet->data[0];
+}
+
+bool DataVisualizerDashboardRadioGroup::feed(void) {
+ if(!this->visualizer) return 0;
+ if(!this->visualizer->handshake) return 0;
+
+ if(this->packet->sent) {
+ this->packet->sent = 0;
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/DataVisualizerDashboardRadioGroup.h b/src/DataVisualizerDashboardRadioGroup.h
new file mode 100644
index 0000000..dd00289
--- /dev/null
+++ b/src/DataVisualizerDashboardRadioGroup.h
@@ -0,0 +1,23 @@
+#ifndef DATA_VISUALIZER_DASHBOARD_RADIO_GROUP_H
+#define DATA_VISUALIZER_DASHBOARD_RADIO_GROUP_H
+
+#include "DataVisualizer.h"
+
+class DataVisualizer;
+class DataVisualizerDashboardRadioGroup {
+ friend class DataVisualizerDashboard;
+
+ private:
+ uint16_t id;
+ DataPacket* packet;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerDashboardRadioGroup(void);
+ uint8_t selected(void);
+ bool feed(void);
+};
+
+typedef DataVisualizerDashboardRadioGroup DashboardRadioGroup;
+
+#endif /* DATA_VISUALIZER_DASHBOARD_RADIO_GROUP_H */
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardSignal.cpp b/src/DataVisualizerDashboardSignal.cpp
new file mode 100644
index 0000000..c4d5fc3
--- /dev/null
+++ b/src/DataVisualizerDashboardSignal.cpp
@@ -0,0 +1,26 @@
+#include "DataVisualizerDashboardSignal.h"
+
+DataVisualizerDashboardSignal::DataVisualizerDashboardSignal(void) {
+ this->id = 0;
+ this->visualizer = 0;
+}
+
+void DataVisualizerDashboardSignal::on(void) {
+ if(!this->visualizer) return;
+ if(!this->visualizer->handshake) return;
+
+ uint8_t value = 1;
+ this->visualizer->write(this->id, (uint8_t*) &value, 1);
+
+ /* this->visualizer->write(this->id, (uint8_t*) true, 1);*/
+}
+
+void DataVisualizerDashboardSignal::off(void) {
+ if(!this->visualizer) return;
+ if(!this->visualizer->handshake) return;
+
+ uint8_t value = 0;
+ this->visualizer->write(this->id, (uint8_t*) &value, 1);
+
+ /* this->visualizer->write(this->id, (uint8_t*) false, 1);*/
+}
\ No newline at end of file
diff --git a/src/DataVisualizerDashboardSignal.h b/src/DataVisualizerDashboardSignal.h
new file mode 100644
index 0000000..eddaa44
--- /dev/null
+++ b/src/DataVisualizerDashboardSignal.h
@@ -0,0 +1,24 @@
+#ifndef DATAV_ISUALIZER_DASHBOARD_SIGNAL_H
+#define DATAV_ISUALIZER_DASHBOARD_SIGNAL_H
+
+#include "DataVisualizer.h"
+
+class DataVisualizer;
+class DataVisualizerDashboardSignal {
+ friend class DataVisualizerDashboard;
+
+ private:
+ uint16_t id;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerDashboardSignal(void);
+ void on(void);
+ void off(void);
+};
+
+typedef DataVisualizerDashboardSignal DashboardSignal;
+
+
+
+#endif /* DATAV_ISUALIZER_DASHBOARD_SIGNAL_H */
\ No newline at end of file
diff --git a/src/DataVisualizerGraph.cpp b/src/DataVisualizerGraph.cpp
new file mode 100644
index 0000000..ad21923
--- /dev/null
+++ b/src/DataVisualizerGraph.cpp
@@ -0,0 +1,39 @@
+#include "DataVisualizerGraph.h"
+
+DataVisualizerGraph::DataVisualizerGraph(void) {
+ this->id = 0;
+ this->visualizer = 0;
+}
+
+DataVisualizerGraphAxis DataVisualizerGraph::addAxis(const char *title) {
+ return this->addAxis(title, COLOR_RED, DEFAULT_GRAPH_MIN, DEFAULT_GRAPH_MAX);
+}
+
+DataVisualizerGraphAxis DataVisualizerGraph::addAxis(const char *title, RgbColor color) {
+ return this->addAxis(title, color, DEFAULT_GRAPH_MIN, DEFAULT_GRAPH_MAX);
+}
+
+DataVisualizerGraphAxis DataVisualizerGraph::addAxis(const char *title, RgbColor color, int32_t yMin, int32_t yMax) {
+ DataVisualizerGraphAxis axis;
+
+ if(!this->visualizer) return axis;
+ if(!this->visualizer->handshake) return axis;
+
+ uint16_t axisId = this->visualizer->index++;
+ axis.visualizer = this->visualizer;
+ axis.graph = this;
+ axis.id = axisId;
+
+ MsgConfigAxis msgConfigAxis;
+ this->visualizer->protocol.addAxisToGraphGetDefaults(&msgConfigAxis);
+ msgConfigAxis.graphId = this->id;
+ msgConfigAxis.axisId = axisId;
+ msgConfigAxis.yMin = yMin;
+ msgConfigAxis.yMax = yMax;
+ msgConfigAxis.xScaleNumerator = 1;
+ msgConfigAxis.xScaleDenominator = 1;
+ this->visualizer->protocol.setColor(msgConfigAxis.color, color);
+ this->visualizer->protocol.addAxisToGraph(&msgConfigAxis, title);
+
+ return axis;
+}
\ No newline at end of file
diff --git a/src/DataVisualizerGraph.h b/src/DataVisualizerGraph.h
new file mode 100644
index 0000000..966ea0f
--- /dev/null
+++ b/src/DataVisualizerGraph.h
@@ -0,0 +1,28 @@
+#ifndef DATA_VISUALIZER_GRAPH_H
+#define DATA_VISUALIZER_GRAPH_H
+
+#include "DataVisualizer.h"
+
+#define DEFAULT_GRAPH_MIN -32767
+#define DEFAULT_GRAPH_MAX +32767
+
+class DataVisualizer;
+class DataVisualizerGraphAxis;
+class DataVisualizerGraph {
+ friend class DataVisualizer;
+ friend class DataVisualizerGraphAxis;
+
+ private:
+ uint16_t id;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerGraph(void);
+ DataVisualizerGraphAxis addAxis(const char *title);
+ DataVisualizerGraphAxis addAxis(const char *title, RgbColor color);
+ DataVisualizerGraphAxis addAxis(const char *title, RgbColor color, int32_t yMin, int32_t yMax);
+};
+
+typedef DataVisualizerGraph Graph;
+
+#endif /* DATA_VISUALIZER_GRAPH_H */
\ No newline at end of file
diff --git a/src/DataVisualizerGraphAxis.cpp b/src/DataVisualizerGraphAxis.cpp
new file mode 100644
index 0000000..1e2143c
--- /dev/null
+++ b/src/DataVisualizerGraphAxis.cpp
@@ -0,0 +1,76 @@
+#include "DataVisualizerGraphAxis.h"
+
+DataVisualizerGraphAxis::DataVisualizerGraphAxis(void) {
+ this->id = 0;
+ this->visualizer = 0;
+ this->graph = 0;
+}
+
+DataVisualizerGraphAxisChannel DataVisualizerGraphAxis::addChannel(const char *label) {
+ return this->addChannel(label, COLOR_RED);
+}
+
+DataVisualizerGraphAxisChannel DataVisualizerGraphAxis::addChannel(const char *label, RgbColor color) {
+ DataVisualizerGraphAxisChannel channel;
+
+ if(!this->visualizer) return channel;
+ if(!this->visualizer->handshake) return channel;
+
+ uint16_t streamId = this->visualizer->index++;
+ channel.visualizer = this->visualizer;
+ channel.id = streamId;
+
+ MsgConfigStream msgConfigStream;
+ this->visualizer->protocol.configureStreamGetDefaults(&msgConfigStream);
+ msgConfigStream.streamId = streamId;
+ msgConfigStream.type = STREAM_INT_32;
+ msgConfigStream.mode = STREAM_OUT;
+ msgConfigStream.state = STREAM_ON;
+ this->visualizer->protocol.configureStream(&msgConfigStream, label);
+
+ MsgAddStreamToAxis msgAddStreamToAxis;
+ this->visualizer->protocol.addStreamToAxisGetDefaults(&msgAddStreamToAxis);
+ msgAddStreamToAxis.graphId = this->graph->id;
+ msgAddStreamToAxis.axisId = this->id;
+ msgAddStreamToAxis.streamId = streamId;
+ this->visualizer->protocol.setColor(msgAddStreamToAxis.lineColor, color);
+ this->visualizer->protocol.addStreamToAxis(&msgAddStreamToAxis);
+
+ return channel;
+}
+
+DataVisualizerGraphAxisCursor DataVisualizerGraphAxis::addCursor(const char *label) {
+ return this->addCursor(label, COLOR_GREEN);
+}
+
+DataVisualizerGraphAxisCursor DataVisualizerGraphAxis::addCursor(const char *label, RgbColor color) {
+ DataVisualizerGraphAxisCursor cursor;
+
+ if(!this->visualizer) return cursor;
+ if(!this->visualizer->handshake) return cursor;
+
+ uint16_t streamId = this->visualizer->index++;
+ cursor.visualizer = this->visualizer;
+ cursor.id = streamId;
+ cursor.packet = this->visualizer->pack(streamId, LENGTH_4_BYTE);
+
+ MsgConfigStream msgConfigStream;
+ this->visualizer->protocol.configureStreamGetDefaults(&msgConfigStream);
+ msgConfigStream.streamId = streamId;
+ msgConfigStream.type = STREAM_INT_32;
+ msgConfigStream.mode = STREAM_IN;
+ msgConfigStream.state = STREAM_ON;
+ this->visualizer->protocol.configureStream(&msgConfigStream, label);
+
+ MsgAddCursorToGraph msgAddCursorToGraph;
+ this->visualizer->protocol.addCursorToGraphGetDefaults(&msgAddCursorToGraph);
+ msgAddCursorToGraph.streamId = streamId;
+ msgAddCursorToGraph.graphId = this->graph->id;
+ msgAddCursorToGraph.axisId = this->id;
+ msgAddCursorToGraph.scaleNumerator = 1;
+ msgAddCursorToGraph.scaleDenominator = 1;
+ this->visualizer->protocol.setColor(msgAddCursorToGraph.color, color);
+ this->visualizer->protocol.addCursorToGraph(&msgAddCursorToGraph, label);
+
+ return cursor;
+}
\ No newline at end of file
diff --git a/src/DataVisualizerGraphAxis.h b/src/DataVisualizerGraphAxis.h
new file mode 100644
index 0000000..6549f00
--- /dev/null
+++ b/src/DataVisualizerGraphAxis.h
@@ -0,0 +1,29 @@
+#ifndef DATA_VISUALIZER_GRAPH_AXIS_H
+#define DATA_VISUALIZER_GRAPH_AXIS_H
+
+#include "DataVisualizer.h"
+
+class DataVisualizer;
+class DataVisualizerGraph;
+class DataVisualizerGraphAxisChannel;
+class DataVisualizerGraphAxisCursor;
+class DataVisualizerGraphAxis {
+ friend class DataVisualizer;
+ friend class DataVisualizerGraph;
+
+ private:
+ uint16_t id;
+ DataVisualizer* visualizer;
+ DataVisualizerGraph* graph;
+
+ public:
+ DataVisualizerGraphAxis(void);
+ DataVisualizerGraphAxisChannel addChannel(const char *label);
+ DataVisualizerGraphAxisChannel addChannel(const char *label, RgbColor color);
+ DataVisualizerGraphAxisCursor addCursor(const char *label);
+ DataVisualizerGraphAxisCursor addCursor(const char *label, RgbColor color);
+};
+
+typedef DataVisualizerGraphAxis GraphAxis;
+
+#endif /* DATA_VISUALIZER_GRAPH_AXIS_H */
\ No newline at end of file
diff --git a/src/DataVisualizerGraphAxisChannel.cpp b/src/DataVisualizerGraphAxisChannel.cpp
new file mode 100644
index 0000000..1da2a32
--- /dev/null
+++ b/src/DataVisualizerGraphAxisChannel.cpp
@@ -0,0 +1,13 @@
+#include "DataVisualizerGraphAxisChannel.h"
+
+DataVisualizerGraphAxisChannel::DataVisualizerGraphAxisChannel(void) {
+ this->id = 0;
+ this->visualizer = 0;
+}
+
+void DataVisualizerGraphAxisChannel::write(int32_t value) {
+ if(!this->visualizer) return;
+ if(!this->visualizer->handshake) return;
+
+ this->visualizer->write(this->id, (uint8_t*) &value, sizeof(int32_t));
+}
\ No newline at end of file
diff --git a/src/DataVisualizerGraphAxisChannel.h b/src/DataVisualizerGraphAxisChannel.h
new file mode 100644
index 0000000..7b3cc26
--- /dev/null
+++ b/src/DataVisualizerGraphAxisChannel.h
@@ -0,0 +1,22 @@
+#ifndef DATA_VISUALIZER_GRAPH_AXIS_CHANNEL_H
+#define DATA_VISUALIZER_GRAPH_AXIS_CHANNEL_H
+
+#include "DataVisualizer.h"
+
+class DataVisualizer;
+class DataVisualizerGraphAxisChannel {
+ friend class DataVisualizer;
+ friend class DataVisualizerGraphAxis;
+
+ private:
+ uint16_t id;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerGraphAxisChannel(void);
+ void write(int32_t value);
+};
+
+typedef DataVisualizerGraphAxisChannel GraphAxisChannel;
+
+#endif /* DATA_VISUALIZER_GRAPH_AXIS_CHANNEL_H */
\ No newline at end of file
diff --git a/src/DataVisualizerGraphAxisCursor.cpp b/src/DataVisualizerGraphAxisCursor.cpp
new file mode 100644
index 0000000..324dd59
--- /dev/null
+++ b/src/DataVisualizerGraphAxisCursor.cpp
@@ -0,0 +1,29 @@
+#include "DataVisualizerGraphAxisCursor.h"
+
+DataVisualizerGraphAxisCursor::DataVisualizerGraphAxisCursor(void) {
+ this->id = 0;
+ this->visualizer = 0;
+ this->packet = 0;
+}
+
+int32_t DataVisualizerGraphAxisCursor::read(void) {
+ if(!this->visualizer) return 0;
+ if(!this->visualizer->handshake) return 0;
+
+ int32_t value;
+ memcpy(&value, this->packet->data, LENGTH_4_BYTE);
+ return value;
+}
+
+bool DataVisualizerGraphAxisCursor::feed(void) {
+ if(!this->visualizer) return 0;
+ if(!this->visualizer->handshake) return 0;
+
+ if(this->packet->sent) {
+ this->packet->sent = 0;
+
+ return true;
+ }
+
+ return false;
+}
\ No newline at end of file
diff --git a/src/DataVisualizerGraphAxisCursor.h b/src/DataVisualizerGraphAxisCursor.h
new file mode 100644
index 0000000..d09fcde
--- /dev/null
+++ b/src/DataVisualizerGraphAxisCursor.h
@@ -0,0 +1,25 @@
+#ifndef DATA_VISUALIZER_GRAPH_AXIS_CURSOR_H
+#define DATA_VISUALIZER_GRAPH_AXIS_CURSOR_H
+
+#include "DataVisualizer.h"
+
+struct DataPacket;
+class DataVisualizer;
+class DataVisualizerGraphAxisCursor {
+ friend class DataVisualizer;
+ friend class DataVisualizerGraphAxis;
+
+ private:
+ uint16_t id;
+ DataPacket* packet;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerGraphAxisCursor(void);
+ int32_t read(void);
+ bool feed(void);
+};
+
+typedef DataVisualizerGraphAxisCursor GraphAxisCursor;
+
+#endif /* DATA_VISUALIZER_GRAPH_AXIS_CURSOR_H */
\ No newline at end of file
diff --git a/src/DataVisualizerTerminal.cpp b/src/DataVisualizerTerminal.cpp
new file mode 100644
index 0000000..e3c7bcc
--- /dev/null
+++ b/src/DataVisualizerTerminal.cpp
@@ -0,0 +1,93 @@
+#include "DataVisualizerTerminal.h"
+
+DataVisualizerTerminal::DataVisualizerTerminal(void) {
+ this->id = 0;
+ this->scan = 0;
+ this->visualizer = 0;
+ this->packet = 0;
+}
+
+uint16_t DataVisualizerTerminal::available(void) {
+ if(!this->visualizer) return 0;
+ if(!this->visualizer->handshake) return 0;
+
+ return this->packet->sent;
+}
+
+char DataVisualizerTerminal::read(void) {
+ if(!this->visualizer) return 0;
+ if(!this->visualizer->handshake) return 0;
+
+ if(this->packet->sent) {
+ char value = packet->data[this->scan++];
+
+ if(this->scan == this->packet->sent) {
+ memset(this->packet->data, 0, this->packet->length);
+ this->scan = 0;
+ this->packet->sent = 0;
+ }
+
+ return value;
+ }
+
+ return 0;
+}
+
+void DataVisualizerTerminal::read(char* buffer) {
+ if(!this->visualizer) return;
+ if(!this->visualizer->handshake) return;
+
+ if(this->packet->sent) {
+ memcpy(buffer, this->packet->data, this->packet->sent);
+ memset(this->packet->data, 0, this->packet->length);
+ this->scan = 0;
+ this->packet->sent = 0;
+ }
+}
+
+void DataVisualizerTerminal::print(char c) {
+ this->print(&c);
+}
+
+void DataVisualizerTerminal::print(int n) {
+ this->print((long) n);
+}
+
+void DataVisualizerTerminal::print(long n) {
+ char c[ITOA_MAX_LENGTH];
+ itoa(n, c, ITOA_DEC);
+ this->print(c);
+}
+
+void DataVisualizerTerminal::print(const char* c) {
+ if(!this->visualizer) return;
+ if(!this->visualizer->handshake) return;
+
+ this->visualizer->write(this->id, (uint8_t*) c, strlen(c));
+}
+
+void DataVisualizerTerminal::println(char c) {
+ this->println(&c);
+}
+
+void DataVisualizerTerminal::println(int n) {
+ this->println((long) n);
+}
+
+void DataVisualizerTerminal::println(long n) {
+ char c[ITOA_MAX_LENGTH];
+ itoa(n, c, ITOA_DEC);
+ this->println(c);
+}
+
+void DataVisualizerTerminal::println(const char *c) {
+ if(!this->visualizer) return;
+ if(!this->visualizer->handshake) return;
+
+ uint16_t length = strlen(c) + 1;
+ char data[length];
+ strncpy(data, c, length - 1);
+ data[length - 1] = '\n';
+
+ this->visualizer->write(this->id, (uint8_t*) data, length);
+}
\ No newline at end of file
diff --git a/src/DataVisualizerTerminal.h b/src/DataVisualizerTerminal.h
new file mode 100644
index 0000000..f768b0b
--- /dev/null
+++ b/src/DataVisualizerTerminal.h
@@ -0,0 +1,37 @@
+#ifndef DATA_VISUALIZER_TERMINAL_H
+#define DATA_VISUALIZER_TERMINAL_H
+
+#include "DataVisualizer.h"
+
+#define ITOA_MAX_LENGTH 30
+#define ITOA_DEC 10
+
+struct DataPacket;
+class DataVisualizer;
+class DataVisualizerTerminal {
+ friend class DataVisualizer;
+
+ private:
+ uint16_t id;
+ uint16_t scan;
+ DataPacket* packet;
+ DataVisualizer* visualizer;
+
+ public:
+ DataVisualizerTerminal(void);
+ uint16_t available(void);
+ void print(int n);
+ void print(long n);
+ void print(char c);
+ void print(const char *c);
+ void println(int n);
+ void println(long n);
+ void println(char c);
+ void println(const char *c);
+ char read(void);
+ void read(char* buffer);
+};
+
+typedef DataVisualizerTerminal Terminal;
+
+#endif /* DATA_VISUALIZER_TERMINAL_H */
\ No newline at end of file