Compare commits
36 commits
main
...
add-spi-tf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5efe8cee93 | ||
|
|
1c265a1ba9 | ||
|
|
c8961599bf | ||
|
|
7be4cadfd0 | ||
|
|
437b0915ed | ||
|
|
098edaa9ba | ||
|
|
33e43d5680 | ||
|
|
6c1666efd4 | ||
|
|
5c42673c03 | ||
|
|
41598d93ee | ||
|
|
6d5f95132b | ||
|
|
bf68aed49c | ||
|
|
3636761d5c | ||
|
|
0663d1d1bf | ||
|
|
3f9d05410e | ||
|
|
82476b8659 | ||
|
|
1b9b634465 | ||
|
|
49cf9cc4bf | ||
|
|
05db09227b | ||
|
|
b5e53344d8 | ||
|
|
0242373096 | ||
|
|
cfb893d7ba | ||
|
|
e8fbd8786c | ||
|
|
12d23548e2 | ||
|
|
ca75bf0f18 | ||
|
|
2743edc637 | ||
|
|
cf617c5ae9 | ||
|
|
ab55789f25 | ||
|
|
37904f3282 | ||
|
|
fc41a7de82 | ||
|
|
c308694233 | ||
|
|
14ef634f1f | ||
|
|
967650e580 | ||
|
|
71cb68d10c | ||
|
|
209abea1eb | ||
|
|
b784f3ffe3 |
37 changed files with 1854 additions and 29 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -52,4 +52,6 @@ data/
|
|||
|
||||
# Misc. Data
|
||||
tests/
|
||||
venv/
|
||||
venv/
|
||||
|
||||
Doxyfile
|
||||
13
.vscode/settings.json
vendored
13
.vscode/settings.json
vendored
|
|
@ -1,7 +1,18 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"limits": "c",
|
||||
"type_traits": "c"
|
||||
"type_traits": "c",
|
||||
"array": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"string_view": "cpp",
|
||||
"format": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"span": "cpp"
|
||||
},
|
||||
"C_Cpp.dimInactiveRegions": true,
|
||||
"dotnet.defaultSolution": "disable",
|
||||
|
|
|
|||
2
Doxyfile
2
Doxyfile
|
|
@ -2451,4 +2451,4 @@ GENERATE_LEGEND = YES
|
|||
# plantuml temporary files.
|
||||
# The default value is: YES.
|
||||
|
||||
DOT_CLEANUP = YES
|
||||
DOT_CLEANUP = YES
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
name=Adafruit WipperSnapper
|
||||
version=1.0.0-beta.110
|
||||
version=1.0.0-beta.112
|
||||
author=Adafruit
|
||||
maintainer=Adafruit <adafruitio@adafruit.com>
|
||||
sentence=Arduino application for Adafruit.io WipperSnapper
|
||||
|
|
@ -7,4 +7,4 @@ paragraph=Arduino application for Adafruit.io WipperSnapper
|
|||
category=Communication
|
||||
url=https://github.com/adafruit/Adafruit_Wippersnapper_Arduino
|
||||
architectures=*
|
||||
depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 Library, Adafruit INA237 and INA238 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306
|
||||
depends=OmronD6T - Community Fork, SdFat - Adafruit Fork, Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit HDC302x, Adafruit INA219, Adafruit INA260 Library, Adafruit INA237 and INA238 Library, Adafruit LTR329 and LTR303, Adafruit LTR390 Library, Adafruit MCP3421, Adafruit NAU7802 Library, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit DS248x, Adafruit SCD30, Adafruit SGP30 Sensor, Adafruit SGP40 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, Sensirion I2C SEN66, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit MPRLS Library, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit VL53L1X, STM32duino VL53L4CD, STM32duino VL53L4CX, Adafruit_VL6180X, Adafruit PM25 AQI Sensor, Adafruit VCNL4020 Library, Adafruit VCNL4040, Adafruit VCNL4200 Library, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS2X, Adafruit LPS28, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit HTU21DF Library, Adafruit HTU31D Library, Adafruit PCT2075, hp_BH1750, ENS160 - Adafruit Fork, Adafruit BusIO, Adafruit Unified Sensor, Sensirion Core, Adafruit GFX Library, Adafruit LED Backpack Library, Adafruit LiquidCrystal, Adafruit SH110X, Adafruit SSD1306, Adafruit EPD, Adafruit ST7735 and ST7789 Library
|
||||
|
|
|
|||
|
|
@ -90,9 +90,9 @@ lib_deps =
|
|||
https://github.com/tyeth/omron-devhub_d6t-arduino.git
|
||||
https://github.com/pstolarz/OneWireNg.git
|
||||
; COMMENT OUT FOR RP2040/RP2350 BOARDS
|
||||
https://github.com/milesburton/Arduino-Temperature-Control-Library.git
|
||||
;https://github.com/milesburton/Arduino-Temperature-Control-Library.git
|
||||
; AND UNCOMMENT FOR RP2040/RP2350 BOARDS
|
||||
; https://github.com/pstolarz/Arduino-Temperature-Control-Library.git
|
||||
https://github.com/pstolarz/Arduino-Temperature-Control-Library.git
|
||||
https://github.com/Sensirion/arduino-sht.git
|
||||
https://github.com/Sensirion/arduino-i2c-scd4x.git
|
||||
https://github.com/Sensirion/arduino-i2c-sen5x.git
|
||||
|
|
@ -100,7 +100,8 @@ lib_deps =
|
|||
https://github.com/adafruit/WiFiNINA.git
|
||||
https://github.com/Starmbi/hp_BH1750.git
|
||||
https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
|
||||
|
||||
Adafruit EPD
|
||||
Adafruit ST7735 and ST7789 Library
|
||||
|
||||
|
||||
; Common build environment for ESP32 platform
|
||||
|
|
@ -211,7 +212,7 @@ extra_scripts = pre:rename_usb_config.py
|
|||
extends = common:esp32
|
||||
board = adafruit_feather_esp32s2_tft
|
||||
build_flags = -DARDUINO_ADAFRUIT_FEATHER_ESP32S2_TFT -DBOARD_HAS_PSRAM
|
||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
||||
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||
extra_scripts = pre:rename_usb_config.py
|
||||
|
||||
; Adafruit Feather ESP32-S2 Reverse TFT
|
||||
|
|
@ -265,7 +266,7 @@ extends = common:esp32
|
|||
board = adafruit_magtag29_esp32s2
|
||||
build_flags = -DARDUINO_MAGTAG29_ESP32S2 -DBOARD_HAS_PSRAM
|
||||
;set partition to tinyuf2-partitions-4MB.csv as of idf 5.1
|
||||
board_build.partitions = tinyuf2-partitions-4MB.csv
|
||||
board_build.partitions = tinyuf2-partitions-4MB-noota.csv
|
||||
extra_scripts = pre:rename_usb_config.py
|
||||
|
||||
; Adafruit Metro ESP32-S2
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ Wippersnapper::Wippersnapper() {
|
|||
|
||||
// DallasSemi (OneWire)
|
||||
WS._ds18x20Component = new ws_ds18x20();
|
||||
|
||||
// Display controller
|
||||
WS._displayController = new DisplayController();
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
|
@ -1655,6 +1658,124 @@ void cbSignalUARTReq(char *data, uint16_t len) {
|
|||
WS_DEBUG_PRINTLN("ERROR: Unable to decode UART Signal message");
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Deserializes a DisplayRequest message and sends it to the display
|
||||
component.
|
||||
@param stream
|
||||
Incoming data stream from buffer.
|
||||
@param field
|
||||
Protobuf message's tag type.
|
||||
@param arg
|
||||
Optional arguments from decoder calling function.
|
||||
@returns True if decoded successfully, False otherwise.
|
||||
*/
|
||||
bool cbDecodeDisplayMsg(pb_istream_t *stream, const pb_field_t *field,
|
||||
void **arg) {
|
||||
if (field->tag == wippersnapper_signal_v1_DisplayRequest_display_add_tag) {
|
||||
|
||||
// Decode message into a DisplayAddRequest
|
||||
wippersnapper_display_v1_DisplayAddOrReplace msgAddReq =
|
||||
wippersnapper_display_v1_DisplayAddOrReplace_init_zero;
|
||||
if (!ws_pb_decode(stream,
|
||||
wippersnapper_display_v1_DisplayAddOrReplace_fields,
|
||||
&msgAddReq)) {
|
||||
WS_DEBUG_PRINTLN("ERROR: Failure decoding DisplayAddOrReplace message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Attempt to add or replace a display component
|
||||
bool did_add =
|
||||
WS._displayController->Handle_Display_AddOrReplace(&msgAddReq);
|
||||
|
||||
// Create a DisplayResponse message
|
||||
wippersnapper_signal_v1_DisplayResponse msgResp =
|
||||
wippersnapper_signal_v1_DisplayResponse_init_zero;
|
||||
msgResp.which_payload =
|
||||
wippersnapper_signal_v1_DisplayResponse_display_added_tag;
|
||||
msgResp.payload.display_added.did_add = did_add;
|
||||
strncpy(msgResp.payload.display_added.name, msgAddReq.name,
|
||||
sizeof(msgResp.payload.display_added.name));
|
||||
|
||||
// Encode and publish response back to broker
|
||||
memset(WS._buffer_outgoing, 0, sizeof(WS._buffer_outgoing));
|
||||
pb_ostream_t ostream = pb_ostream_from_buffer(WS._buffer_outgoing,
|
||||
sizeof(WS._buffer_outgoing));
|
||||
if (!ws_pb_encode(&ostream, wippersnapper_signal_v1_DisplayResponse_fields,
|
||||
&msgResp)) {
|
||||
WS_DEBUG_PRINTLN("ERROR: Unable to encode display response message!");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t msgSz;
|
||||
pb_get_encoded_size(&msgSz, wippersnapper_signal_v1_DisplayResponse_fields,
|
||||
&msgResp);
|
||||
WS_DEBUG_PRINT("Publishing DisplayResponse Message...");
|
||||
if (!WS._mqtt->publish(WS._topic_signal_display_device, WS._buffer_outgoing,
|
||||
msgSz, 1)) {
|
||||
WS_DEBUG_PRINTLN("ERROR: Failed to DisplayResponse Response!");
|
||||
} else {
|
||||
WS_DEBUG_PRINTLN("Published!");
|
||||
}
|
||||
} else if (field->tag ==
|
||||
wippersnapper_signal_v1_DisplayRequest_display_write_tag) {
|
||||
// Decode message into a DisplayAddRequest
|
||||
wippersnapper_display_v1_DisplayWrite msgWrite =
|
||||
wippersnapper_display_v1_DisplayWrite_init_zero;
|
||||
if (!ws_pb_decode(stream, wippersnapper_display_v1_DisplayWrite_fields,
|
||||
&msgWrite)) {
|
||||
WS_DEBUG_PRINTLN("ERROR: Failure decoding DisplayWrite message!");
|
||||
return false;
|
||||
}
|
||||
// Attempt to write to a display
|
||||
WS._displayController->Handle_Display_Write(&msgWrite);
|
||||
} else if (field->tag ==
|
||||
wippersnapper_signal_v1_DisplayRequest_display_remove_tag) {
|
||||
// Decode message into a DisplayRemoveRequest
|
||||
wippersnapper_display_v1_DisplayRemove msgRemove =
|
||||
wippersnapper_display_v1_DisplayRemove_init_zero;
|
||||
if (!ws_pb_decode(stream, wippersnapper_display_v1_DisplayRemove_fields,
|
||||
&msgRemove)) {
|
||||
WS_DEBUG_PRINTLN("ERROR: Failure decoding DisplayRemove message!");
|
||||
return false;
|
||||
}
|
||||
// Attempt to remove a display
|
||||
WS._displayController->Handle_Display_Remove(&msgRemove);
|
||||
} else {
|
||||
WS_DEBUG_PRINTLN("ERROR: Display message type not found!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Called when the device receives a new message from the
|
||||
/display/ topic.
|
||||
@param data
|
||||
Incoming data from MQTT broker.
|
||||
@param len
|
||||
Length of incoming data.
|
||||
*/
|
||||
void cbDisplayMessage(char *data, uint16_t len) {
|
||||
WS_DEBUG_PRINTLN("* NEW MESSAGE [Topic: Display]: ");
|
||||
WS_DEBUG_PRINT(len);
|
||||
WS_DEBUG_PRINTLN(" bytes.");
|
||||
// zero-out current buffer
|
||||
memset(WS._buffer, 0, sizeof(WS._buffer));
|
||||
// copy mqtt data into buffer
|
||||
memcpy(WS._buffer, data, len);
|
||||
WS.bufSize = len;
|
||||
|
||||
// Set up the payload callback, which will set up the callbacks for
|
||||
// each oneof payload field once the field tag is known
|
||||
WS.msgSignalDisplay.cb_payload.funcs.decode = cbDecodeDisplayMsg;
|
||||
|
||||
// Decode pixel message from buffer
|
||||
pb_istream_t istream = pb_istream_from_buffer(WS._buffer, WS.bufSize);
|
||||
if (!ws_pb_decode(&istream, wippersnapper_signal_v1_DisplayRequest_fields,
|
||||
&WS.msgSignalDisplay))
|
||||
WS_DEBUG_PRINTLN("ERROR: Unable to decode display message");
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/*!
|
||||
@brief Handles MQTT messages on signal topic until timeout.
|
||||
|
|
@ -2344,6 +2465,63 @@ bool Wippersnapper::generateWSTopics() {
|
|||
WS_DEBUG_PRINTLN("FATAL ERROR: Failed to allocate memory for UART topic!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// /display topic //
|
||||
|
||||
// Pre-determine topic size
|
||||
topicLen = strlen(WS._config.aio_user) + strlen("/") + strlen(_device_uid) +
|
||||
strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + strlen("broker") +
|
||||
strlen(TOPIC_DISPLAY) + 1;
|
||||
|
||||
// Pre-allocate memory for topic
|
||||
#ifdef USE_PSRAM
|
||||
WS._topic_signal_display_brkr = (char *)ps_malloc(topicLen);
|
||||
#else
|
||||
WS._topic_signal_display_brkr = (char *)malloc(topicLen);
|
||||
#endif
|
||||
|
||||
// Generate the topic
|
||||
if (WS._topic_signal_display_brkr != NULL) {
|
||||
snprintf(WS._topic_signal_display_brkr, topicLen, "%s/wprsnpr/%s%sbroker%s",
|
||||
WS._config.aio_user, _device_uid, TOPIC_SIGNALS, TOPIC_DISPLAY);
|
||||
} else {
|
||||
WS_DEBUG_PRINTLN(
|
||||
"FATAL ERROR: Failed to allocate memory for DISPLAY topic!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Subscribe to signal's DISPLAY sub-topic and set callback
|
||||
_topic_signal_display_sub =
|
||||
new Adafruit_MQTT_Subscribe(WS._mqtt, WS._topic_signal_display_brkr, 1);
|
||||
WS_DEBUG_PRINTLN("Subscribing to DISPLAY topic: ");
|
||||
WS_DEBUG_PRINTLN(WS._topic_signal_display_brkr);
|
||||
WS._mqtt->subscribe(_topic_signal_display_sub);
|
||||
WS_DEBUG_PRINTLN("Subscribed to DISPLAY topic!");
|
||||
_topic_signal_display_sub->setCallback(cbDisplayMessage);
|
||||
|
||||
// Calculate length of the topic for device-to-broker DISPLAY topic
|
||||
topicLen = strlen(WS._config.aio_user) + strlen("/") + strlen(_device_uid) +
|
||||
strlen("/wprsnpr/") + strlen(TOPIC_SIGNALS) + strlen("device") +
|
||||
strlen(TOPIC_DISPLAY) + 1;
|
||||
|
||||
// Allocate memory for dynamic MQTT topic
|
||||
#ifdef USE_PSRAM
|
||||
WS._topic_signal_display_device = (char *)ps_malloc(topicLen);
|
||||
#else
|
||||
WS._topic_signal_display_device = (char *)malloc(topicLen);
|
||||
#endif
|
||||
|
||||
// Generate the topic if memory was allocated successfully
|
||||
if (WS._topic_signal_display_device != NULL) {
|
||||
snprintf(WS._topic_signal_display_device, topicLen,
|
||||
"%s/wprsnpr/%s%sdevice%s", WS._config.aio_user, _device_uid,
|
||||
TOPIC_SIGNALS, TOPIC_DISPLAY);
|
||||
} else {
|
||||
WS_DEBUG_PRINTLN(
|
||||
"FATAL ERROR: Failed to allocate memory for DISPLAY topic!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2837,6 +3015,11 @@ void Wippersnapper::connect() {
|
|||
WS._ui_helper->build_scr_monitor();
|
||||
#endif
|
||||
|
||||
// Initialize Digital IO class
|
||||
WS._digitalGPIO = new Wippersnapper_DigitalGPIO(20);
|
||||
// Initialize Analog IO class
|
||||
WS._analogIO = new Wippersnapper_AnalogIO(5, 3.3);
|
||||
|
||||
// Configure hardware
|
||||
while (!WS.pinCfgCompleted) {
|
||||
WS_DEBUG_PRINTLN(
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@
|
|||
#include "display/ws_display_ui_helper.h"
|
||||
#endif
|
||||
|
||||
#include "components/display/controller.h"
|
||||
#include "components/ds18x20/ws_ds18x20.h"
|
||||
#include "components/pixels/ws_pixels.h"
|
||||
#include "components/pwm/ws_pwm.h"
|
||||
|
|
@ -142,7 +143,7 @@
|
|||
#endif
|
||||
|
||||
#define WS_VERSION \
|
||||
"1.0.0-beta.110" ///< WipperSnapper app. version (semver-formatted)
|
||||
"1.0.0-beta.112" ///< WipperSnapper app. version (semver-formatted)
|
||||
|
||||
// Reserved Adafruit IO MQTT topics
|
||||
#define TOPIC_IO_THROTTLE "/throttle" ///< Adafruit IO Throttle MQTT Topic
|
||||
|
|
@ -153,6 +154,7 @@
|
|||
#define TOPIC_INFO "/info/" ///< Registration sub-topic
|
||||
#define TOPIC_SIGNALS "/signals/" ///< Signals sub-topic
|
||||
#define TOPIC_I2C "/i2c" ///< I2C sub-topic
|
||||
#define TOPIC_DISPLAY "/display" ///< Display sub-topic (EPD, OLED, TFT, etc.)
|
||||
#define MQTT_TOPIC_PIXELS_DEVICE \
|
||||
"/signals/device/pixel" ///< Pixels device->broker topic
|
||||
#define MQTT_TOPIC_PIXELS_BROKER \
|
||||
|
|
@ -245,6 +247,7 @@ class ws_pwm;
|
|||
class ws_ds18x20;
|
||||
class ws_pixels;
|
||||
class ws_uart;
|
||||
class DisplayController;
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
|
|
@ -368,6 +371,8 @@ public:
|
|||
ws_servo *_servoComponent; ///< Instance of servo class
|
||||
ws_ds18x20 *_ds18x20Component; ///< Instance of DS18x20 class
|
||||
ws_uart *_uartComponent; ///< Instance of UART class
|
||||
DisplayController
|
||||
*_displayController; ///< Instance of display controller class
|
||||
|
||||
// TODO: does this really need to be global?
|
||||
uint8_t _macAddr[6]; /*!< Unique network iface identifier */
|
||||
|
|
@ -404,6 +409,10 @@ public:
|
|||
char *_topic_signal_pixels_device = NULL; /*!< Topic carries pixel messages */
|
||||
char *_topic_signal_uart_brkr = NULL; /*!< Topic carries UART messages */
|
||||
char *_topic_signal_uart_device = NULL; /*!< Topic carries UART messages */
|
||||
char *_topic_signal_display_brkr =
|
||||
NULL; /*!< Topic carries messages from a device to a broker. */
|
||||
char *_topic_signal_display_device =
|
||||
NULL; /*!< Topic carries messages from a broker to a device. */
|
||||
|
||||
wippersnapper_signal_v1_CreateSignalRequest
|
||||
_incomingSignalMsg; /*!< Incoming signal message from broker */
|
||||
|
|
@ -430,6 +439,9 @@ public:
|
|||
wippersnapper_signal_v1_UARTRequest
|
||||
msgSignalUART; ///< UARTReq wrapper message
|
||||
|
||||
wippersnapper_signal_v1_DisplayRequest
|
||||
msgSignalDisplay; ///< DisplayRequest wrapper message
|
||||
|
||||
char *throttleMessage; /*!< Pointer to throttle message data. */
|
||||
int throttleTime; /*!< Total amount of time to throttle the device, in
|
||||
milliseconds. */
|
||||
|
|
@ -490,6 +502,8 @@ protected:
|
|||
*_topic_signal_pixels_sub; /*!< Subscribes to pixel device topic. */
|
||||
Adafruit_MQTT_Subscribe
|
||||
*_topic_signal_uart_sub; /*!< Subscribes to signal's UART topic. */
|
||||
Adafruit_MQTT_Subscribe *_topic_signal_display_sub; /*!< Subscription callback
|
||||
for display topic. */
|
||||
|
||||
Adafruit_MQTT_Subscribe
|
||||
*_err_sub; /*!< Subscription to Adafruit IO Error topic. */
|
||||
|
|
|
|||
126
src/components/display/controller.cpp
Normal file
126
src/components/display/controller.cpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/*!
|
||||
* @file src/components/display/controller.cpp
|
||||
*
|
||||
* Implementation for the display API controller.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Copyright (c) Brent Rubell 2025 for Adafruit Industries.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
#include "controller.h"
|
||||
|
||||
/*!
|
||||
@brief Constructs a new DisplayController object
|
||||
*/
|
||||
DisplayController::DisplayController() {}
|
||||
|
||||
/*!
|
||||
@brief Destructor
|
||||
*/
|
||||
DisplayController::~DisplayController() {
|
||||
// Clean up all display hardware instances
|
||||
for (DisplayHardware *hw_instance : _hw_instances) {
|
||||
delete hw_instance;
|
||||
}
|
||||
_hw_instances.clear();
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Handles a Display_AddOrReplace message.
|
||||
@param msgAdd
|
||||
Pointer to a DisplayAddOrReplace message structure.
|
||||
@return True if the display was added or replaced successfully, false
|
||||
otherwise.
|
||||
*/
|
||||
bool DisplayController::Handle_Display_AddOrReplace(
|
||||
wippersnapper_display_v1_DisplayAddOrReplace *msgAdd) {
|
||||
DisplayHardware *display = new DisplayHardware(msgAdd->name);
|
||||
WS_DEBUG_PRINT("[display] Adding or replacing display: ");
|
||||
WS_DEBUG_PRINTLN(msgAdd->name);
|
||||
|
||||
// Configure display type
|
||||
display->setType(msgAdd->type);
|
||||
|
||||
// Attempt to initialize display hardware instance
|
||||
bool did_begin = false;
|
||||
if (msgAdd->which_config ==
|
||||
wippersnapper_display_v1_DisplayAddOrReplace_config_epd_tag) {
|
||||
did_begin = display->beginEPD(&msgAdd->config.config_epd,
|
||||
&msgAdd->interface_type.spi_epd);
|
||||
} else if (msgAdd->which_config ==
|
||||
wippersnapper_display_v1_DisplayAddOrReplace_config_tft_tag) {
|
||||
did_begin = display->beginTft(&msgAdd->config.config_tft,
|
||||
&msgAdd->interface_type.spi_tft);
|
||||
} else {
|
||||
WS_DEBUG_PRINTLN("[display] Unsupported display configuration type!");
|
||||
delete display;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the display began successfully
|
||||
if (!did_begin) {
|
||||
WS_DEBUG_PRINTLN("[display] Failed to initialize display!");
|
||||
delete display; // Clean up if initialization failed
|
||||
return false;
|
||||
}
|
||||
|
||||
_hw_instances.push_back(display); // Store the display instance
|
||||
WS_DEBUG_PRINTLN("[display] Display added or replaced successfully!");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Handles a Display_Remove message.
|
||||
@param msgRemove
|
||||
Pointer to a DisplayRemove message structure.
|
||||
@return True if the display was removed successfully, false otherwise.
|
||||
*/
|
||||
bool DisplayController::Handle_Display_Remove(
|
||||
wippersnapper_display_v1_DisplayRemove *msgRemove) {
|
||||
// Find the display instance by name
|
||||
for (auto it = _hw_instances.begin(); it != _hw_instances.end(); ++it) {
|
||||
if (strcmp((*it)->getName(), msgRemove->name) == 0) {
|
||||
delete *it;
|
||||
_hw_instances.erase(it);
|
||||
WS_DEBUG_PRINTLN("[display] Display removed successfully!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
WS_DEBUG_PRINTLN("[display] Could not remove display, not found!");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Handles a Display_Write message.
|
||||
@param msgWrite
|
||||
Pointer to a DisplayWrite message structure.
|
||||
@return True if the display write was successful, false otherwise.
|
||||
*/
|
||||
bool DisplayController::Handle_Display_Write(
|
||||
wippersnapper_display_v1_DisplayWrite *msgWrite) {
|
||||
// Get the driver instance for the display
|
||||
DisplayHardware *display = nullptr;
|
||||
for (auto &hw_instance : _hw_instances) {
|
||||
if (strcmp(hw_instance->getName(), msgWrite->name) == 0) {
|
||||
display = hw_instance;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Early-out if driver instance not found
|
||||
if (!display) {
|
||||
WS_DEBUG_PRINTLN("[display] Failed to write, driver not found!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write the message to the display
|
||||
WS_DEBUG_PRINT("[display] Writing message to display: ");
|
||||
WS_DEBUG_PRINTLN(msgWrite->message);
|
||||
display->writeMessage(msgWrite->message);
|
||||
return true;
|
||||
}
|
||||
44
src/components/display/controller.h
Normal file
44
src/components/display/controller.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*!
|
||||
* @file src/components/display/controller.h
|
||||
*
|
||||
* Controller for the display API
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Copyright (c) Brent Rubell 2025 for Adafruit Industries.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
#ifndef WS_DISPLAY_CONTROLLER_H
|
||||
#define WS_DISPLAY_CONTROLLER_H
|
||||
#include "Wippersnapper.h"
|
||||
#include "hardware.h"
|
||||
|
||||
class Wippersnapper_V2; ///< Forward declaration
|
||||
class DisplayHardware; ///< Forward declaration
|
||||
|
||||
/**************************************************************************/
|
||||
/*!
|
||||
@brief Routes messages using the display.proto API to the
|
||||
appropriate hardware and model classes, controls and tracks
|
||||
the state of displays.
|
||||
*/
|
||||
/**************************************************************************/
|
||||
class DisplayController {
|
||||
public:
|
||||
DisplayController();
|
||||
~DisplayController();
|
||||
bool Handle_Display_AddOrReplace(
|
||||
wippersnapper_display_v1_DisplayAddOrReplace *msgAdd);
|
||||
bool Handle_Display_Remove(wippersnapper_display_v1_DisplayRemove *msgRemove);
|
||||
bool Handle_Display_Write(wippersnapper_display_v1_DisplayWrite *msgWrite);
|
||||
|
||||
private:
|
||||
std::vector<DisplayHardware *>
|
||||
_hw_instances; ///< Holds pointers to DisplayHardware instances
|
||||
};
|
||||
extern Wippersnapper Ws; ///< Global WS instance
|
||||
#endif
|
||||
142
src/components/display/drivers/dispDrvBase.h
Normal file
142
src/components/display/drivers/dispDrvBase.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/*!
|
||||
* @file src/components/display/drivers/dispDrvBase.h
|
||||
*
|
||||
* Abstract base class for display drivers.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Copyright (c) Brent Rubell 2025 for Adafruit Industries.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
#ifndef WS_DISP_DRV_BASE_H
|
||||
#define WS_DISP_DRV_BASE_H
|
||||
|
||||
#include "Adafruit_ThinkInk.h"
|
||||
#include "Wippersnapper.h"
|
||||
|
||||
/*!
|
||||
@brief Abstract base class for display drivers.
|
||||
This class provides a common interface for all display drivers,
|
||||
allowing them to be used interchangeably.
|
||||
*/
|
||||
class dispDrvBase {
|
||||
public:
|
||||
/*!
|
||||
@brief Constructor for the base display driver for E-Ink displays.
|
||||
@param dc
|
||||
Data/Command pin for the display.
|
||||
@param rst
|
||||
Reset pin for the display.
|
||||
@param cs
|
||||
Chip Select pin for the display.
|
||||
@param sram_cs
|
||||
Optional SRAM Chip Select pin for E-Ink displays that support it.
|
||||
@param busy
|
||||
Optional Busy pin for the display.
|
||||
*/
|
||||
dispDrvBase(int16_t dc, int16_t rst, int16_t cs, int16_t sram_cs = -1,
|
||||
int16_t busy = -1)
|
||||
: _pin_dc(dc), _pin_rst(rst), _pin_cs(cs), _pin_sram_cs(sram_cs),
|
||||
_pin_busy(busy) {}
|
||||
|
||||
/*!
|
||||
@brief Constructor for the base display driver for SPI TFT displays.
|
||||
@param cs
|
||||
Chip Select pin for the display.
|
||||
@param dc
|
||||
Data/Command pin for the display.
|
||||
@param mosi
|
||||
MOSI pin for the display.
|
||||
@param sck
|
||||
SCK pin for the display.
|
||||
@param rst
|
||||
Optional Reset pin for the display.
|
||||
@param miso
|
||||
Optional MISO pin for the display.
|
||||
*/
|
||||
dispDrvBase(int8_t cs, int8_t dc, int8_t mosi, int8_t sck, int8_t rst = -1,
|
||||
int8_t miso = -1)
|
||||
: _pin_cs(cs), _pin_dc(dc), _pin_mosi(mosi), _pin_sck(sck), _pin_rst(rst),
|
||||
_pin_miso(miso) {}
|
||||
|
||||
/*!
|
||||
@brief Destructor for the base display driver.
|
||||
This destructor is virtual to allow derived classes to clean up
|
||||
resources properly.
|
||||
*/
|
||||
virtual ~dispDrvBase() {}
|
||||
|
||||
/*!
|
||||
@brief Attempts to initialize a ThinkInk EPD driver.
|
||||
@param mode
|
||||
The ThinkInk mode to use for the display.
|
||||
@param reset
|
||||
Whether to reset the display before initialization.
|
||||
@return True if the display was initialized successfully, false otherwise.
|
||||
*/
|
||||
virtual bool begin(thinkinkmode_t mode, bool reset = true) { return false; }
|
||||
|
||||
/*!
|
||||
@brief Attempts to initialize a SPI TFT driver.
|
||||
@return True if the display was initialized successfully, false otherwise.
|
||||
*/
|
||||
virtual bool begin() { return false; }
|
||||
|
||||
/*!
|
||||
@brief Writes a message to the display.
|
||||
@param message
|
||||
The message to write to the display.
|
||||
@note MUST be implemented by derived classes.
|
||||
*/
|
||||
virtual void writeMessage(const char *message) = 0;
|
||||
|
||||
/*!
|
||||
@brief Sets the width of the display.
|
||||
@param w
|
||||
The width of the display in pixels.
|
||||
*/
|
||||
void setWidth(int16_t w) { _width = w; }
|
||||
|
||||
/*!
|
||||
@brief Sets the height of the display.
|
||||
@param h
|
||||
The height of the display in pixels.
|
||||
*/
|
||||
void setHeight(int16_t h) { _height = h; }
|
||||
|
||||
/*!
|
||||
@brief Sets the rotation of the display.
|
||||
@param r
|
||||
The rotation of the display (0-3).
|
||||
*/
|
||||
void setRotation(uint8_t r) { _rotation = r; }
|
||||
|
||||
/*!
|
||||
@brief Sets the text size for the display.
|
||||
@param s
|
||||
The text size to set.
|
||||
@note This method can be overridden by derived classes to provide
|
||||
specific functionality.
|
||||
*/
|
||||
virtual void setTextSize(uint8_t s) { _text_sz = s; }
|
||||
|
||||
protected:
|
||||
int16_t _pin_dc; ///< Data/Command pin
|
||||
int16_t _pin_rst; ///< Reset pin
|
||||
int16_t _pin_cs; ///< Chip Select pin
|
||||
int16_t _pin_busy; ///< Optional Busy pin
|
||||
int16_t _pin_sram_cs; ///< Optional EPD SRAM chip select pin
|
||||
uint16_t _pin_mosi; ///< Optional MOSI pin for SPI TFT displays
|
||||
uint16_t _pin_miso; ///< Optional MISO pin for SPI TFT displays
|
||||
uint16_t _pin_sck; ///< Optional SCK pin for SPI TFT displays
|
||||
uint8_t _text_sz = 1; ///< Text size for displaying a message
|
||||
int16_t _height; ///< Height of the display
|
||||
int16_t _width; ///< Width of the display
|
||||
uint8_t _rotation; ///< Rotation of the display
|
||||
};
|
||||
|
||||
#endif // WS_DISP_DRV_BASE_H
|
||||
154
src/components/display/drivers/dispDrvSt7789.h
Normal file
154
src/components/display/drivers/dispDrvSt7789.h
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
/*!
|
||||
* @file src/components/display/drivers/dispDrvSt7789.h
|
||||
*
|
||||
* Driver for ST7789-based TFT displays.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Copyright (c) Brent Rubell 2025 for Adafruit Industries.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
#ifndef WS_DISP_DRV_ST7789
|
||||
#define WS_DISP_DRV_ST7789
|
||||
|
||||
#include "dispDrvBase.h"
|
||||
#include <Adafruit_ST7789.h>
|
||||
|
||||
#define ST7789_TEXT_SZ_DEFAULT 2 ///< Default text size for ST7789 displays
|
||||
|
||||
/*!
|
||||
@brief Driver for ST7789-based TFT displays.
|
||||
*/
|
||||
class dispDrvSt7789 : public dispDrvBase {
|
||||
public:
|
||||
/*!
|
||||
@brief Constructor for the ST7789 display driver.
|
||||
@param cs
|
||||
Chip Select pin for the display.
|
||||
@param dc
|
||||
Data/Command pin for the display.
|
||||
@param mosi
|
||||
MOSI pin for the display.
|
||||
@param sck
|
||||
SCK pin for the display.
|
||||
@param rst
|
||||
Optional Reset pin for the display.
|
||||
@param miso
|
||||
Optional MISO pin for the display.
|
||||
*/
|
||||
dispDrvSt7789(int16_t cs, int16_t dc, int16_t mosi, int16_t sck,
|
||||
int16_t rst = -1, int16_t miso = -1)
|
||||
: dispDrvBase(cs, dc, mosi, sck, rst, miso), _display(nullptr) {}
|
||||
|
||||
~dispDrvSt7789() {
|
||||
if (_display) {
|
||||
delete _display;
|
||||
_display = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Attempts to initialize the ST7789 TFT driver.
|
||||
@return True if the display was initialized successfully, false otherwise.
|
||||
*/
|
||||
bool begin() override {
|
||||
|
||||
// Special configuration for Feather TFTs
|
||||
#if defined(TFT_BACKLITE)
|
||||
// turn on backlite
|
||||
pinMode(TFT_BACKLITE, OUTPUT);
|
||||
digitalWrite(TFT_BACKLITE, HIGH);
|
||||
|
||||
// turn on the TFT / I2C power supply
|
||||
pinMode(TFT_I2C_POWER, OUTPUT);
|
||||
digitalWrite(TFT_I2C_POWER, HIGH);
|
||||
delay(10);
|
||||
#endif
|
||||
|
||||
_display = new Adafruit_ST7789(_pin_cs, _pin_dc, _pin_rst);
|
||||
if (!_display)
|
||||
return false;
|
||||
|
||||
_display->init(_width, _height);
|
||||
_display->setRotation(_rotation);
|
||||
setTextSize(ST7789_TEXT_SZ_DEFAULT);
|
||||
_display->fillScreen(ST77XX_BLACK);
|
||||
_display->setTextColor(ST77XX_WHITE);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Sets the text size for the display.
|
||||
@param s
|
||||
The text size to set.
|
||||
@note This method overrides the base class method to provide specific
|
||||
functionality for the ST7789 driver.
|
||||
*/
|
||||
void setTextSize(uint8_t s) override {
|
||||
if (!_display)
|
||||
return;
|
||||
_text_sz = s;
|
||||
_display->setTextSize(s);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Writes a message to the display.
|
||||
@param message
|
||||
The message to write to the display.
|
||||
@note This method overrides the base class method to provide specific
|
||||
functionality for the ST7789 driver.
|
||||
*/
|
||||
virtual void writeMessage(const char *message) override {
|
||||
if (_display == nullptr)
|
||||
return;
|
||||
|
||||
// Start with a fresh display buffer
|
||||
_display->fillScreen(ST77XX_BLACK);
|
||||
int16_t y_idx = 0;
|
||||
_display->setCursor(0, y_idx);
|
||||
|
||||
// Calculate the line height based on the text size (NOTE: base height is
|
||||
// 8px)
|
||||
int16_t line_height = 8 * _text_sz;
|
||||
uint16_t c_idx = 0;
|
||||
size_t msg_size = strlen(message);
|
||||
for (size_t i = 0; i < msg_size && c_idx < msg_size; i++) {
|
||||
if (y_idx + line_height > _height)
|
||||
break;
|
||||
if (message[i] == '\\' && i + 1 < msg_size &&
|
||||
(message[i + 1] == 'n' || message[i + 1] == 'r')) {
|
||||
// Handle \r\n sequence as a single newline
|
||||
if (message[i + 1] == 'r' && i + 3 < msg_size &&
|
||||
message[i + 2] == '\\' && message[i + 3] == 'n') {
|
||||
// Skip to the next line
|
||||
if (y_idx + line_height > _height)
|
||||
break;
|
||||
y_idx += line_height;
|
||||
_display->setCursor(0, y_idx);
|
||||
i += 3;
|
||||
} else if (message[i + 1] == 'n') {
|
||||
// Skip to the next line
|
||||
if (y_idx + line_height > _height)
|
||||
break;
|
||||
y_idx += line_height;
|
||||
_display->setCursor(0, y_idx);
|
||||
i++;
|
||||
}
|
||||
} else if (message[i] == 0xC2 && message[i + 1] == 0xB0) {
|
||||
_display->write(char(248));
|
||||
i++;
|
||||
} else {
|
||||
_display->print(message[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Adafruit_ST7789 *_display;
|
||||
};
|
||||
|
||||
#endif // WS_DISP_DRV_ST7789
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/*!
|
||||
* @file src/components/display/drivers/dispDrvThinkInkGrayscale4Eaamfgn.h
|
||||
*
|
||||
* Driver for ThinkInk 2.9" Grayscale 4-level EAAMFGN display (present on the
|
||||
* 2025 version of the Adafruit MagTag)
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Copyright (c) Brent Rubell 2025 for Adafruit Industries.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
#ifndef WS_DRV_THINKINK_GRAYSCALE4_EAAMFGN_H
|
||||
#define WS_DRV_THINKINK_GRAYSCALE4_EAAMFGN_H
|
||||
|
||||
#include "dispDrvBase.h"
|
||||
|
||||
/*!
|
||||
@brief Driver for a ThinkInk 2.9" Grayscale 4-level EAAMFGN display.
|
||||
*/
|
||||
class drvDispThinkInkGrayscale4Eaamfgn : public dispDrvBase {
|
||||
public:
|
||||
/*!
|
||||
@brief Constructor for the ThinkInk Grayscale 4-level EAAMFGN display
|
||||
driver.
|
||||
@param dc
|
||||
Data/Command pin for the display.
|
||||
@param rst
|
||||
Reset pin for the display.
|
||||
@param cs
|
||||
Chip Select pin for the display.
|
||||
@param sram_cs
|
||||
Optional SRAM Chip Select pin for E-Ink displays that support it.
|
||||
@param busy
|
||||
Optional Busy pin for the display.
|
||||
*/
|
||||
drvDispThinkInkGrayscale4Eaamfgn(int16_t dc, int16_t rst, int16_t cs,
|
||||
int16_t sram_cs = -1, int16_t busy = -1)
|
||||
: dispDrvBase(dc, rst, cs, sram_cs, busy), _display(nullptr) {}
|
||||
|
||||
~drvDispThinkInkGrayscale4Eaamfgn() {
|
||||
if (_display) {
|
||||
delete _display;
|
||||
_display = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Attempts to initialize the ThinkInk Grayscale 4-level EAAMFGN
|
||||
display driver.
|
||||
@param mode
|
||||
The ThinkInk mode to use for the display.
|
||||
@param reset
|
||||
Whether to reset the display before initialization.
|
||||
@return True if the display was initialized successfully, false otherwise.
|
||||
*/
|
||||
bool begin(thinkinkmode_t mode, bool reset = true) override {
|
||||
_display = new ThinkInk_290_Grayscale4_EAAMFGN(_pin_dc, _pin_rst, _pin_cs,
|
||||
_pin_sram_cs, _pin_busy);
|
||||
if (!_display)
|
||||
return false; // Allocation failed
|
||||
|
||||
// Initialize the display
|
||||
_display->begin(mode);
|
||||
// Configure display settings
|
||||
_text_sz = 3;
|
||||
_display->setTextSize(_text_sz);
|
||||
_display->setTextColor(EPD_BLACK);
|
||||
_display->setTextWrap(false);
|
||||
_height = _display->height();
|
||||
_width = _display->width();
|
||||
// Clear the display buffer
|
||||
_display->clearBuffer();
|
||||
_display->display();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Writes a message to the display.
|
||||
@param message
|
||||
The message to write to the display.
|
||||
@note This method overrides the base class method to provide specific
|
||||
functionality for the Think Ink Grayscale 4 EAAMGFGN driver.
|
||||
*/
|
||||
virtual void writeMessage(const char *message) override {
|
||||
if (_display == nullptr)
|
||||
return;
|
||||
|
||||
// Start with a fresh display buffer
|
||||
_display->clearBuffer();
|
||||
int16_t y_idx = 0;
|
||||
_display->setCursor(0, y_idx);
|
||||
|
||||
// Calculate the line height based on the text size (NOTE: base height is
|
||||
// 8px)
|
||||
int16_t line_height = 8 * _text_sz;
|
||||
uint16_t c_idx = 0;
|
||||
size_t msg_size = strlen(message);
|
||||
for (size_t i = 0; i < msg_size && c_idx < msg_size; i++) {
|
||||
if (y_idx + line_height > _height)
|
||||
break;
|
||||
if (message[i] == '\\' && i + 1 < msg_size &&
|
||||
(message[i + 1] == 'n' || message[i + 1] == 'r')) {
|
||||
// Handle \r\n sequence as a single newline
|
||||
if (message[i + 1] == 'r' && i + 3 < msg_size &&
|
||||
message[i + 2] == '\\' && message[i + 3] == 'n') {
|
||||
// Skip to the next line
|
||||
if (y_idx + line_height > _height)
|
||||
break;
|
||||
y_idx += line_height;
|
||||
_display->setCursor(0, y_idx);
|
||||
i += 3;
|
||||
} else if (message[i + 1] == 'n') {
|
||||
// Skip to the next line
|
||||
if (y_idx + line_height > _height)
|
||||
break;
|
||||
y_idx += line_height;
|
||||
_display->setCursor(0, y_idx);
|
||||
i++;
|
||||
}
|
||||
} else if (message[i] == 0xC2 && message[i + 1] == 0xB0) {
|
||||
// Degree symbol
|
||||
_display->write(char(248));
|
||||
i++;
|
||||
} else {
|
||||
_display->print(message[i]);
|
||||
}
|
||||
}
|
||||
_display->display();
|
||||
}
|
||||
|
||||
private:
|
||||
ThinkInk_290_Grayscale4_EAAMFGN *_display;
|
||||
};
|
||||
|
||||
#endif // WS_DRV_THINKINK_GRAYSCALE4_EAAMFGN_H
|
||||
140
src/components/display/drivers/dispDrvThinkInkGrayscale4T5.h
Normal file
140
src/components/display/drivers/dispDrvThinkInkGrayscale4T5.h
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*!
|
||||
* @file src/components/display/drivers/dispDrvThinkInkGrayscale4T5.h
|
||||
*
|
||||
* Driver for ThinkInk 2.9" Grayscale 4-level T5 display (present on the
|
||||
* pre-2025 version of the Adafruit MagTag)
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Copyright (c) Brent Rubell 2025 for Adafruit Industries.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
#ifndef WS_DRV_THINKINK_GRAYSCALE4_T5_H
|
||||
#define WS_DRV_THINKINK_GRAYSCALE4_T5_H
|
||||
|
||||
#include "dispDrvBase.h"
|
||||
|
||||
/*!
|
||||
@brief Driver for a ThinkInk 2.9" Grayscale 4-level T5 display (pre-2025
|
||||
version of the Adafruit MagTag).
|
||||
*/
|
||||
class dispDrvThinkInkGrayscale4T5 : public dispDrvBase {
|
||||
public:
|
||||
/*!
|
||||
@brief Constructor for the ThinkInk Grayscale 4-level EAAMFGN display
|
||||
driver.
|
||||
@param dc
|
||||
Data/Command pin for the display.
|
||||
@param rst
|
||||
Reset pin for the display.
|
||||
@param cs
|
||||
Chip Select pin for the display.
|
||||
@param sram_cs
|
||||
Optional SRAM Chip Select pin for E-Ink displays that support it.
|
||||
@param busy
|
||||
Optional Busy pin for the display.
|
||||
*/
|
||||
dispDrvThinkInkGrayscale4T5(int16_t dc, int16_t rst, int16_t cs,
|
||||
int16_t sram_cs = -1, int16_t busy = -1)
|
||||
: dispDrvBase(dc, rst, cs, sram_cs, busy), _display(nullptr) {}
|
||||
|
||||
~dispDrvThinkInkGrayscale4T5() {
|
||||
if (_display) {
|
||||
delete _display;
|
||||
_display = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Attempts to initialize the ThinkInk Grayscale 4-level EAAMFGN
|
||||
display driver.
|
||||
@param mode
|
||||
The ThinkInk mode to use for the display.
|
||||
@param reset
|
||||
Whether to reset the display before initialization.
|
||||
@return True if the display was initialized successfully, false otherwise.
|
||||
*/
|
||||
bool begin(thinkinkmode_t mode, bool reset = true) override {
|
||||
_display = new ThinkInk_290_Grayscale4_T5(_pin_dc, _pin_rst, _pin_cs,
|
||||
_pin_sram_cs, _pin_busy);
|
||||
if (!_display)
|
||||
return false; // Allocation failed
|
||||
|
||||
// Initialize the display
|
||||
_display->begin(mode);
|
||||
// Configure display settings
|
||||
_text_sz = 3;
|
||||
_display->setTextSize(_text_sz);
|
||||
_display->setTextColor(EPD_BLACK);
|
||||
_display->setTextWrap(false);
|
||||
_height = _display->height();
|
||||
_width = _display->width();
|
||||
// Clear the display buffer
|
||||
_display->clearBuffer();
|
||||
_display->display();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Writes a message to the display.
|
||||
@param message
|
||||
The message to write to the display.
|
||||
@note This method overrides the base class method to provide specific
|
||||
functionality for the Think Ink Grayscale 4 EAAMGFGN driver.
|
||||
*/
|
||||
virtual void writeMessage(const char *message) override {
|
||||
if (_display == nullptr)
|
||||
return;
|
||||
|
||||
// Start with a fresh display buffer
|
||||
_display->clearBuffer();
|
||||
int16_t y_idx = 0;
|
||||
_display->setCursor(0, y_idx);
|
||||
|
||||
// Calculate the line height based on the text size (NOTE: base height is
|
||||
// 8px)
|
||||
int16_t line_height = 8 * _text_sz;
|
||||
uint16_t c_idx = 0;
|
||||
size_t msg_size = strlen(message);
|
||||
for (size_t i = 0; i < msg_size && c_idx < msg_size; i++) {
|
||||
if (y_idx + line_height > _height)
|
||||
break;
|
||||
if (message[i] == '\\' && i + 1 < msg_size &&
|
||||
(message[i + 1] == 'n' || message[i + 1] == 'r')) {
|
||||
// Handle \r\n sequence as a single newline
|
||||
if (message[i + 1] == 'r' && i + 3 < msg_size &&
|
||||
message[i + 2] == '\\' && message[i + 3] == 'n') {
|
||||
// Skip to the next line
|
||||
if (y_idx + line_height > _height)
|
||||
break;
|
||||
y_idx += line_height;
|
||||
_display->setCursor(0, y_idx);
|
||||
i += 3;
|
||||
} else if (message[i + 1] == 'n') {
|
||||
// Skip to the next line
|
||||
if (y_idx + line_height > _height)
|
||||
break;
|
||||
y_idx += line_height;
|
||||
_display->setCursor(0, y_idx);
|
||||
i++;
|
||||
}
|
||||
} else if (message[i] == 0xC2 && message[i + 1] == 0xB0) {
|
||||
_display->write(char(248));
|
||||
i++;
|
||||
} else {
|
||||
_display->print(message[i]);
|
||||
}
|
||||
}
|
||||
_display->display();
|
||||
}
|
||||
|
||||
private:
|
||||
ThinkInk_290_Grayscale4_T5 *_display;
|
||||
};
|
||||
|
||||
#endif // WS_DRV_THINKINK_GRAYSCALE4_T5_H
|
||||
418
src/components/display/hardware.cpp
Normal file
418
src/components/display/hardware.cpp
Normal file
|
|
@ -0,0 +1,418 @@
|
|||
/*!
|
||||
* @file src/components/display/hardware.cpp
|
||||
*
|
||||
* Implementation for the display hardware.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Copyright (c) Brent Rubell 2025 for Adafruit Industries.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
#include "controller.h"
|
||||
|
||||
/*!
|
||||
@brief Lambda function to create a dispDrvBase EPD instance.
|
||||
*/
|
||||
using FnCreateDispDrvEpd =
|
||||
std::function<dispDrvBase *(int16_t, int16_t, int16_t, int16_t, int16_t)>;
|
||||
|
||||
// Factory for creating a new display drivers
|
||||
// NOTE: When you add a new display driver, make sure to add it to the factory!
|
||||
static const std::map<std::string, FnCreateDispDrvEpd> FactoryDrvDispEpd = {
|
||||
{"thinkink-gs4-eaamfgn",
|
||||
[](int16_t dc, int16_t rst, int16_t cs, int16_t sram_cs,
|
||||
int16_t busy) -> dispDrvBase * {
|
||||
return new drvDispThinkInkGrayscale4Eaamfgn(dc, rst, cs, sram_cs, busy);
|
||||
}},
|
||||
{"thinkink-gs4-t5",
|
||||
[](int16_t dc, int16_t rst, int16_t cs, int16_t sram_cs,
|
||||
int16_t busy) -> dispDrvBase * {
|
||||
return new dispDrvThinkInkGrayscale4T5(dc, rst, cs, sram_cs, busy);
|
||||
}}};
|
||||
|
||||
/*!
|
||||
@brief Lambda function to create a dispDrvBase SPI TFT instance
|
||||
*/
|
||||
using FnCreateDispDrvTft = std::function<dispDrvBase *(
|
||||
int16_t, int16_t, int16_t, int16_t, int16_t, int16_t)>;
|
||||
|
||||
// Factory for creating a new SPI TFT display driver
|
||||
// NOTE: When you add a new SPI TFT display driver, make sure to add it to the
|
||||
// factory!
|
||||
static const std::map<std::string, FnCreateDispDrvTft> FactoryDrvDispTft = {
|
||||
{"st7735",
|
||||
[](int16_t cs, int16_t dc, int16_t mosi, int16_t sck, int16_t rst,
|
||||
int16_t miso) -> dispDrvBase * {
|
||||
return new dispDrvSt7789(cs, dc, mosi, sck, rst, miso);
|
||||
}},
|
||||
{"st7789",
|
||||
[](int16_t cs, int16_t dc, int16_t mosi, int16_t sck, int16_t rst,
|
||||
int16_t miso) -> dispDrvBase * {
|
||||
return new dispDrvSt7789(cs, dc, mosi, sck, rst, miso);
|
||||
}}};
|
||||
|
||||
/*!
|
||||
@brief Creates a new E-Ink display driver instance based on the driver
|
||||
name.
|
||||
@param driver_name
|
||||
The name of the display driver to create.
|
||||
@param dc
|
||||
Data/Command pin number.
|
||||
@param rst
|
||||
Reset pin number.
|
||||
@param cs
|
||||
Chip Select pin number.
|
||||
@param sram_cs
|
||||
Optional SRAM Chip Select pin number (default: -1).
|
||||
@param busy
|
||||
Optional Busy pin number (default: -1).
|
||||
@return Pointer to the created display driver instance, or nullptr if the
|
||||
driver name is not recognized.
|
||||
*/
|
||||
dispDrvBase *CreateDrvDispEpd(const char *driver_name, int16_t dc, int16_t rst,
|
||||
int16_t cs, int16_t sram_cs = -1,
|
||||
int16_t busy = -1) {
|
||||
auto it = FactoryDrvDispEpd.find(driver_name);
|
||||
if (it == FactoryDrvDispEpd.end())
|
||||
return nullptr;
|
||||
|
||||
return it->second(dc, rst, cs, sram_cs, busy);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Creates a new SPI TFT display driver instance based on the driver
|
||||
name.
|
||||
@param driver_name
|
||||
The name of the SPI TFT display driver to create.
|
||||
@param cs
|
||||
Chip Select pin number.
|
||||
@param dc
|
||||
Data/Command pin number.
|
||||
@param mosi
|
||||
MOSI pin number.
|
||||
@param sck
|
||||
SCK pin number.
|
||||
@param rst
|
||||
Optional Reset pin number (default: -1).
|
||||
@param miso
|
||||
Optional MISO pin number (default: -1).
|
||||
@return Pointer to the created display driver instance, or nullptr if the
|
||||
driver name is not recognized.
|
||||
*/
|
||||
dispDrvBase *CreateDrvDispTft(const char *driver_name, int16_t cs, int16_t dc,
|
||||
int16_t mosi, int16_t sck, int16_t rst = -1,
|
||||
int16_t miso = -1) {
|
||||
auto it = FactoryDrvDispTft.find(driver_name);
|
||||
if (it == FactoryDrvDispTft.end())
|
||||
return nullptr;
|
||||
|
||||
return it->second(cs, dc, mosi, sck, rst, miso);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Constructs a new DisplayHardware object
|
||||
@param name
|
||||
The name of the hardware instance.
|
||||
*/
|
||||
DisplayHardware::DisplayHardware(const char *name) {
|
||||
strncpy(_name, name, sizeof(_name) - 1);
|
||||
_name[sizeof(_name) - 1] = '\0';
|
||||
_type = wippersnapper_display_v1_DisplayType_DISPLAY_TYPE_UNSPECIFIED;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Destructor
|
||||
*/
|
||||
DisplayHardware::~DisplayHardware() {
|
||||
if (_drvDisp) {
|
||||
delete _drvDisp;
|
||||
_drvDisp = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Sets the hardware's display type.
|
||||
@param type
|
||||
The display type to set.
|
||||
*/
|
||||
void DisplayHardware::setType(wippersnapper_display_v1_DisplayType type) {
|
||||
_type = type;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Gets the hardware's display type.
|
||||
@return The current display type.
|
||||
*/
|
||||
wippersnapper_display_v1_DisplayType DisplayHardware::getType() {
|
||||
return _type;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Parses a pin string (e.g., "D5") and returns the corresponding pin
|
||||
number.
|
||||
@param pinStr
|
||||
The pin string to parse.
|
||||
@return The pin number, or -1 if the string is invalid.
|
||||
*/
|
||||
int16_t DisplayHardware::parsePin(const char *pinStr) {
|
||||
if (!pinStr || strlen(pinStr) < 2 || pinStr[0] != 'D') {
|
||||
return -1;
|
||||
}
|
||||
return atoi(pinStr + 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Configures the EPD display with the provided configuration.
|
||||
@param config
|
||||
Pointer to the EPD configuration structure.
|
||||
@param spi_config
|
||||
Pointer to the SPI configuration structure for EPD.
|
||||
@return True if configuration was successful, False otherwise.
|
||||
*/
|
||||
bool DisplayHardware::beginEPD(
|
||||
wippersnapper_display_v1_EPDConfig *config,
|
||||
wippersnapper_display_v1_EpdSpiConfig *spi_config) {
|
||||
// Validate pointers
|
||||
if (config == nullptr || spi_config == nullptr) {
|
||||
WS_DEBUG_PRINTLN("[display] EPD config or SPI config is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate mode is a correct EPD mode
|
||||
if (config->mode == wippersnapper_display_v1_EPDMode_EPD_MODE_UNSPECIFIED) {
|
||||
WS_DEBUG_PRINTLN("[display] Unsupported EPD mode!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we already have a display driver assigned to this hardware instance,
|
||||
// clean it up!
|
||||
if (_drvDisp) {
|
||||
delete _drvDisp;
|
||||
_drvDisp = nullptr;
|
||||
}
|
||||
|
||||
// Parse and assign pins
|
||||
int16_t srcs = -1, busy = -1;
|
||||
int16_t dc = parsePin(spi_config->pin_dc);
|
||||
int16_t rst = parsePin(spi_config->pin_rst);
|
||||
int16_t cs = parsePin(spi_config->pin_cs);
|
||||
|
||||
// Optionally parse SRAM CS and BUSY pins
|
||||
if (strlen(spi_config->pin_sram_cs) >= 2) {
|
||||
srcs = parsePin(spi_config->pin_sram_cs);
|
||||
}
|
||||
if (strlen(spi_config->pin_busy) >= 2) {
|
||||
busy = parsePin(spi_config->pin_busy);
|
||||
}
|
||||
|
||||
// Configure SPI bus
|
||||
if (spi_config->bus != 0) {
|
||||
WS_DEBUG_PRINTLN(
|
||||
"[display] ERROR: Non-default SPI buses are currently not supported!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// For "magtag" component name, attempt to autodetect the driver type
|
||||
if (strncmp(_name, "magtag", 6) == 0) {
|
||||
if (detect_ssd1680(cs, dc, rst)) {
|
||||
// Detected SSD1680, use EAAMFGN driver
|
||||
strncpy(_name, "thinkink-gs4-eaamfgn", sizeof(_name) - 1);
|
||||
_name[sizeof(_name) - 1] = '\0';
|
||||
} else {
|
||||
// Did not detect SSD1680, use IL0373 driver
|
||||
strncpy(_name, "thinkink-gs4-t5", sizeof(_name) - 1);
|
||||
_name[sizeof(_name) - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// Create display driver object using the factory function
|
||||
_drvDisp = CreateDrvDispEpd(_name, dc, rst, cs, srcs, busy);
|
||||
if (!_drvDisp) {
|
||||
WS_DEBUG_PRINTLN("[display] Failed to create display driver!");
|
||||
return false; // Failed to create display driver
|
||||
}
|
||||
|
||||
// Configure EPD mode
|
||||
thinkinkmode_t epd_mode = THINKINK_MONO;
|
||||
if (config->mode == wippersnapper_display_v1_EPDMode_EPD_MODE_GRAYSCALE4) {
|
||||
epd_mode = THINKINK_GRAYSCALE4;
|
||||
WS_DEBUG_PRINTLN("[display] EPD mode: GRAYSCALE4");
|
||||
}
|
||||
|
||||
if (!_drvDisp->begin(epd_mode)) {
|
||||
WS_DEBUG_PRINTLN("[display] Failed to begin display driver!");
|
||||
delete _drvDisp;
|
||||
_drvDisp = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Removes a suffix from the hardware instance name, if it exists.
|
||||
@param suffix
|
||||
The suffix to remove (e.g., "-lg", "-md", "-sm").
|
||||
*/
|
||||
void DisplayHardware::removeSuffix(const char *suffix) {
|
||||
char *suffix_pos = strstr(_name, suffix);
|
||||
if (suffix_pos) {
|
||||
*suffix_pos = '\0'; // Truncate string at suffix position
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Attempts to configure and initialize a TFT display
|
||||
@param config
|
||||
Pointer to the TFT configuration structure.
|
||||
@param spi_config
|
||||
Pointer to the SPI configuration structure for TFT.
|
||||
@return True if configuration was successful, False otherwise.
|
||||
*/
|
||||
bool DisplayHardware::beginTft(
|
||||
wippersnapper_display_v1_TftConfig *config,
|
||||
wippersnapper_display_v1_TftSpiConfig *spi_config) {
|
||||
// Validate pointers
|
||||
if (config == nullptr || spi_config == nullptr) {
|
||||
WS_DEBUG_PRINTLN("[display] EPD config or SPI config is null!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we already have a display driver assigned to this hardware instance,
|
||||
// clean it up!
|
||||
if (_drvDisp) {
|
||||
delete _drvDisp;
|
||||
_drvDisp = nullptr;
|
||||
}
|
||||
|
||||
int16_t rst = -1, miso = -1;
|
||||
int16_t cs = parsePin(spi_config->pin_cs);
|
||||
int16_t dc = parsePin(spi_config->pin_dc);
|
||||
int16_t mosi = parsePin(spi_config->pin_mosi);
|
||||
int16_t sck = parsePin(spi_config->pin_sck);
|
||||
|
||||
// Optionally parse SRAM CS and BUSY pins
|
||||
if (strlen(spi_config->pin_rst) >= 2) {
|
||||
rst = parsePin(spi_config->pin_rst);
|
||||
}
|
||||
if (strlen(spi_config->pin_miso) >= 2) {
|
||||
miso = parsePin(spi_config->pin_miso);
|
||||
}
|
||||
|
||||
// Configure text size based on suffix in driver name
|
||||
uint8_t text_sz; // Default text size
|
||||
if (strstr(_name, "-lg") != nullptr) {
|
||||
// Larger text size for displays with -lg suffix
|
||||
text_sz = 4;
|
||||
removeSuffix("-lg");
|
||||
} else if (strstr(_name, "-md") != nullptr) {
|
||||
// Larger text size for displays with -md suffix
|
||||
text_sz = 3;
|
||||
removeSuffix("-md");
|
||||
} else {
|
||||
text_sz = 1;
|
||||
}
|
||||
|
||||
// Create display driver object using the factory function
|
||||
_drvDisp = CreateDrvDispTft(_name, cs, dc, mosi, sck, rst, miso);
|
||||
if (!_drvDisp) {
|
||||
WS_DEBUG_PRINTLN("[display] Failed to create display driver!");
|
||||
return false;
|
||||
}
|
||||
|
||||
_drvDisp->setWidth(config->width);
|
||||
_drvDisp->setHeight(config->height);
|
||||
_drvDisp->setRotation(config->rotation);
|
||||
_drvDisp->begin();
|
||||
_drvDisp->setTextSize(text_sz);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Gets the name of the display hardware instance.
|
||||
@return The name of the display hardware instance.
|
||||
*/
|
||||
const char *DisplayHardware::getName() { return _name; }
|
||||
|
||||
/*!
|
||||
@brief Writes a message to the display.
|
||||
@param message
|
||||
The message to display.
|
||||
*/
|
||||
void DisplayHardware::writeMessage(const char *message) {
|
||||
if (!_drvDisp)
|
||||
return;
|
||||
_drvDisp->writeMessage(message);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Detects if an SSD1680 EPD is connected using bit-banged SPI.
|
||||
@param cs
|
||||
Chip Select pin number.
|
||||
@param dc
|
||||
Data/Command pin number.
|
||||
@param rst
|
||||
Reset pin number.
|
||||
@return True if an SSD1680 is detected, False otherwise (IL0373 or different
|
||||
EPD).
|
||||
*/
|
||||
bool DisplayHardware::detect_ssd1680(uint8_t cs, uint8_t dc, uint8_t rst) {
|
||||
// note: for a complete implementation reference, see
|
||||
// https://github.com/adafruit/circuitpython/commit/f4316cb2491c815b128acca47f1bb75519fe306e
|
||||
// Configure SPI pins to bit-bang
|
||||
pinMode(MOSI, OUTPUT);
|
||||
pinMode(SCK, OUTPUT);
|
||||
pinMode(cs, OUTPUT);
|
||||
pinMode(dc, OUTPUT);
|
||||
pinMode(rst, OUTPUT);
|
||||
|
||||
// Begin transaction by pulling cs and dc LOW
|
||||
digitalWrite(cs, LOW);
|
||||
digitalWrite(dc, LOW);
|
||||
digitalWrite(SCK, LOW);
|
||||
digitalWrite(rst, HIGH);
|
||||
|
||||
// Write to read register 0x71
|
||||
uint8_t cmd = 0x71;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
digitalWrite(MOSI, (cmd & (1 << (7 - i))) != 0);
|
||||
digitalWrite(SCK, HIGH);
|
||||
digitalWrite(SCK, LOW);
|
||||
}
|
||||
|
||||
// Set DC high to indicate data and switch MOSI to input with PUR in case
|
||||
// SSD1680 does not send data back
|
||||
digitalWrite(dc, HIGH);
|
||||
delayMicroseconds(1);
|
||||
pinMode(MOSI, INPUT_PULLUP);
|
||||
delayMicroseconds(1);
|
||||
|
||||
// Read response from register
|
||||
uint8_t status = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
status <<= 1;
|
||||
if (digitalRead(MOSI)) {
|
||||
status |= 1;
|
||||
}
|
||||
digitalWrite(SCK, HIGH);
|
||||
delayMicroseconds(1);
|
||||
digitalWrite(SCK, LOW);
|
||||
delayMicroseconds(1);
|
||||
}
|
||||
|
||||
// End transaction by pulling CS high
|
||||
digitalWrite(cs, HIGH);
|
||||
|
||||
// Put back MOSI pin as an output
|
||||
pinMode(MOSI, OUTPUT);
|
||||
|
||||
WS_DEBUG_PRINT("[display] Bitbang read 0x71: 0x");
|
||||
WS_DEBUG_PRINTLN(status, HEX);
|
||||
|
||||
return status == 0xFF;
|
||||
}
|
||||
62
src/components/display/hardware.h
Normal file
62
src/components/display/hardware.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*!
|
||||
* @file src/components/display/hardware.h
|
||||
*
|
||||
* Hardware interface for display components.
|
||||
*
|
||||
* Adafruit invests time and resources providing this open source code,
|
||||
* please support Adafruit and open-source hardware by purchasing
|
||||
* products from Adafruit!
|
||||
*
|
||||
* Copyright (c) Brent Rubell 2025 for Adafruit Industries.
|
||||
*
|
||||
* BSD license, all text here must be included in any redistribution.
|
||||
*
|
||||
*/
|
||||
#ifndef WS_DISPLAY_HARDWARE_H
|
||||
#define WS_DISPLAY_HARDWARE_H
|
||||
#include "Wippersnapper.h"
|
||||
#include "drivers/dispDrvBase.h"
|
||||
#include "drivers/dispDrvSt7789.h"
|
||||
#include "drivers/dispDrvThinkInkGrayscale4Eaamfgn.h"
|
||||
#include "drivers/dispDrvThinkInkGrayscale4T5.h"
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
/*!
|
||||
@brief Interface for interacting with display hardware (TFT, eInk,
|
||||
OLED, etc.)
|
||||
This class provides methods to initialize, write to, and
|
||||
manage the state of display hardware.
|
||||
*/
|
||||
class DisplayHardware {
|
||||
public:
|
||||
DisplayHardware(const char *name);
|
||||
~DisplayHardware();
|
||||
|
||||
//
|
||||
// API for configuring the display hardware //
|
||||
//
|
||||
const char *getName();
|
||||
void setType(wippersnapper_display_v1_DisplayType type);
|
||||
wippersnapper_display_v1_DisplayType getType();
|
||||
bool beginEPD(wippersnapper_display_v1_EPDConfig *config,
|
||||
wippersnapper_display_v1_EpdSpiConfig *spi_config);
|
||||
bool beginTft(wippersnapper_display_v1_TftConfig *config,
|
||||
wippersnapper_display_v1_TftSpiConfig *spi_config);
|
||||
|
||||
//
|
||||
// API for Adafruit_GFX that abstracts hardware functionality
|
||||
// NOTE: These methods are meant to be implemented within dispDrvBase and
|
||||
// exposed within dispDrv driver instances
|
||||
//
|
||||
void writeMessage(const char *message);
|
||||
|
||||
private:
|
||||
int16_t parsePin(const char *pinStr);
|
||||
void removeSuffix(const char *suffix);
|
||||
bool detect_ssd1680(uint8_t cs, uint8_t dc, uint8_t rst);
|
||||
char _name[64]; ///< Identifies the hardware instance
|
||||
wippersnapper_display_v1_DisplayType _type; ///< Display type
|
||||
dispDrvBase *_drvDisp = nullptr; ///< Base display driver
|
||||
};
|
||||
#endif // WS_DISPLAY_HARDWARE_H
|
||||
0
src/provisioning/sdcard/ws_sdcard.cpp
Normal file
0
src/provisioning/sdcard/ws_sdcard.cpp
Normal file
0
src/provisioning/sdcard/ws_sdcard.h
Normal file
0
src/provisioning/sdcard/ws_sdcard.h
Normal file
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/description/v1/description.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_DESCRIPTION_V1_WIPPERSNAPPER_DESCRIPTION_V1_DESCRIPTION_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_DESCRIPTION_V1_WIPPERSNAPPER_DESCRIPTION_V1_DESCRIPTION_PB_H_INCLUDED
|
||||
|
|
|
|||
41
src/wippersnapper/display/v1/display.pb.c
Normal file
41
src/wippersnapper/display/v1/display.pb.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/display/v1/display.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_EpdSpiConfig, wippersnapper_display_v1_EpdSpiConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_EPDConfig, wippersnapper_display_v1_EPDConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_EPDWriteOptions, wippersnapper_display_v1_EPDWriteOptions, AUTO)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_TftSpiConfig, wippersnapper_display_v1_TftSpiConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_TftConfig, wippersnapper_display_v1_TftConfig, AUTO)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_DisplayAddOrReplace, wippersnapper_display_v1_DisplayAddOrReplace, AUTO)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_DisplayRemove, wippersnapper_display_v1_DisplayRemove, AUTO)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_DisplayWrite, wippersnapper_display_v1_DisplayWrite, 2)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_DisplayAddedorReplaced, wippersnapper_display_v1_DisplayAddedorReplaced, AUTO)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_display_v1_DisplayRemoved, wippersnapper_display_v1_DisplayRemoved, AUTO)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
288
src/wippersnapper/display/v1/display.pb.h
Normal file
288
src/wippersnapper/display/v1/display.pb.h
Normal file
|
|
@ -0,0 +1,288 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_DISPLAY_V1_WIPPERSNAPPER_DISPLAY_V1_DISPLAY_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_DISPLAY_V1_WIPPERSNAPPER_DISPLAY_V1_DISPLAY_PB_H_INCLUDED
|
||||
#include <pb.h>
|
||||
#include "nanopb/nanopb.pb.h"
|
||||
#include "wippersnapper/i2c/v1/i2c.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
#endif
|
||||
|
||||
/* Enum definitions */
|
||||
typedef enum _wippersnapper_display_v1_DisplayType {
|
||||
wippersnapper_display_v1_DisplayType_DISPLAY_TYPE_UNSPECIFIED = 0,
|
||||
wippersnapper_display_v1_DisplayType_DISPLAY_TYPE_OLED = 1,
|
||||
wippersnapper_display_v1_DisplayType_DISPLAY_TYPE_EPD = 2,
|
||||
wippersnapper_display_v1_DisplayType_DISPLAY_TYPE_TFT = 3
|
||||
} wippersnapper_display_v1_DisplayType;
|
||||
|
||||
typedef enum _wippersnapper_display_v1_EPDMode {
|
||||
wippersnapper_display_v1_EPDMode_EPD_MODE_UNSPECIFIED = 0,
|
||||
wippersnapper_display_v1_EPDMode_EPD_MODE_GRAYSCALE4 = 1,
|
||||
wippersnapper_display_v1_EPDMode_EPD_MODE_MONO = 2
|
||||
} wippersnapper_display_v1_EPDMode;
|
||||
|
||||
/* Struct definitions */
|
||||
typedef struct _wippersnapper_display_v1_DisplayAddedorReplaced {
|
||||
char name[64];
|
||||
bool did_add;
|
||||
} wippersnapper_display_v1_DisplayAddedorReplaced;
|
||||
|
||||
typedef struct _wippersnapper_display_v1_DisplayRemove {
|
||||
char name[64];
|
||||
} wippersnapper_display_v1_DisplayRemove;
|
||||
|
||||
typedef struct _wippersnapper_display_v1_DisplayRemoved {
|
||||
char name[64];
|
||||
bool did_remove;
|
||||
} wippersnapper_display_v1_DisplayRemoved;
|
||||
|
||||
typedef struct _wippersnapper_display_v1_EPDConfig {
|
||||
wippersnapper_display_v1_EPDMode mode;
|
||||
} wippersnapper_display_v1_EPDConfig;
|
||||
|
||||
typedef struct _wippersnapper_display_v1_EPDWriteOptions {
|
||||
int32_t text_size;
|
||||
} wippersnapper_display_v1_EPDWriteOptions;
|
||||
|
||||
typedef struct _wippersnapper_display_v1_EpdSpiConfig {
|
||||
int32_t bus;
|
||||
char pin_dc[6];
|
||||
char pin_rst[6];
|
||||
char pin_cs[6];
|
||||
char pin_sram_cs[6];
|
||||
char pin_busy[6];
|
||||
} wippersnapper_display_v1_EpdSpiConfig;
|
||||
|
||||
typedef struct _wippersnapper_display_v1_TftConfig {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t rotation;
|
||||
} wippersnapper_display_v1_TftConfig;
|
||||
|
||||
typedef struct _wippersnapper_display_v1_TftSpiConfig {
|
||||
int32_t bus;
|
||||
char pin_cs[6];
|
||||
char pin_dc[6];
|
||||
char pin_mosi[6];
|
||||
char pin_sck[6];
|
||||
char pin_rst[6];
|
||||
char pin_miso[6];
|
||||
} wippersnapper_display_v1_TftSpiConfig;
|
||||
|
||||
typedef struct _wippersnapper_display_v1_DisplayAddOrReplace {
|
||||
wippersnapper_display_v1_DisplayType type;
|
||||
char name[64];
|
||||
pb_size_t which_interface_type;
|
||||
union {
|
||||
wippersnapper_display_v1_EpdSpiConfig spi_epd;
|
||||
wippersnapper_display_v1_TftSpiConfig spi_tft;
|
||||
} interface_type;
|
||||
pb_size_t which_config;
|
||||
union {
|
||||
wippersnapper_display_v1_EPDConfig config_epd;
|
||||
wippersnapper_display_v1_TftConfig config_tft;
|
||||
} config;
|
||||
} wippersnapper_display_v1_DisplayAddOrReplace;
|
||||
|
||||
typedef struct _wippersnapper_display_v1_DisplayWrite {
|
||||
char name[64];
|
||||
char message[1024];
|
||||
pb_size_t which_options;
|
||||
union {
|
||||
wippersnapper_display_v1_EPDWriteOptions epd_options;
|
||||
} options;
|
||||
} wippersnapper_display_v1_DisplayWrite;
|
||||
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _wippersnapper_display_v1_DisplayType_MIN wippersnapper_display_v1_DisplayType_DISPLAY_TYPE_UNSPECIFIED
|
||||
#define _wippersnapper_display_v1_DisplayType_MAX wippersnapper_display_v1_DisplayType_DISPLAY_TYPE_TFT
|
||||
#define _wippersnapper_display_v1_DisplayType_ARRAYSIZE ((wippersnapper_display_v1_DisplayType)(wippersnapper_display_v1_DisplayType_DISPLAY_TYPE_TFT+1))
|
||||
|
||||
#define _wippersnapper_display_v1_EPDMode_MIN wippersnapper_display_v1_EPDMode_EPD_MODE_UNSPECIFIED
|
||||
#define _wippersnapper_display_v1_EPDMode_MAX wippersnapper_display_v1_EPDMode_EPD_MODE_MONO
|
||||
#define _wippersnapper_display_v1_EPDMode_ARRAYSIZE ((wippersnapper_display_v1_EPDMode)(wippersnapper_display_v1_EPDMode_EPD_MODE_MONO+1))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_init_default {0, "", "", "", "", ""}
|
||||
#define wippersnapper_display_v1_EPDConfig_init_default {_wippersnapper_display_v1_EPDMode_MIN}
|
||||
#define wippersnapper_display_v1_EPDWriteOptions_init_default {0}
|
||||
#define wippersnapper_display_v1_TftSpiConfig_init_default {0, "", "", "", "", "", ""}
|
||||
#define wippersnapper_display_v1_TftConfig_init_default {0, 0, 0}
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_init_default {_wippersnapper_display_v1_DisplayType_MIN, "", 0, {wippersnapper_display_v1_EpdSpiConfig_init_default}, 0, {wippersnapper_display_v1_EPDConfig_init_default}}
|
||||
#define wippersnapper_display_v1_DisplayRemove_init_default {""}
|
||||
#define wippersnapper_display_v1_DisplayWrite_init_default {"", "", 0, {wippersnapper_display_v1_EPDWriteOptions_init_default}}
|
||||
#define wippersnapper_display_v1_DisplayAddedorReplaced_init_default {"", 0}
|
||||
#define wippersnapper_display_v1_DisplayRemoved_init_default {"", 0}
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_init_zero {0, "", "", "", "", ""}
|
||||
#define wippersnapper_display_v1_EPDConfig_init_zero {_wippersnapper_display_v1_EPDMode_MIN}
|
||||
#define wippersnapper_display_v1_EPDWriteOptions_init_zero {0}
|
||||
#define wippersnapper_display_v1_TftSpiConfig_init_zero {0, "", "", "", "", "", ""}
|
||||
#define wippersnapper_display_v1_TftConfig_init_zero {0, 0, 0}
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_init_zero {_wippersnapper_display_v1_DisplayType_MIN, "", 0, {wippersnapper_display_v1_EpdSpiConfig_init_zero}, 0, {wippersnapper_display_v1_EPDConfig_init_zero}}
|
||||
#define wippersnapper_display_v1_DisplayRemove_init_zero {""}
|
||||
#define wippersnapper_display_v1_DisplayWrite_init_zero {"", "", 0, {wippersnapper_display_v1_EPDWriteOptions_init_zero}}
|
||||
#define wippersnapper_display_v1_DisplayAddedorReplaced_init_zero {"", 0}
|
||||
#define wippersnapper_display_v1_DisplayRemoved_init_zero {"", 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define wippersnapper_display_v1_DisplayAddedorReplaced_name_tag 1
|
||||
#define wippersnapper_display_v1_DisplayAddedorReplaced_did_add_tag 2
|
||||
#define wippersnapper_display_v1_DisplayRemove_name_tag 1
|
||||
#define wippersnapper_display_v1_DisplayRemoved_name_tag 1
|
||||
#define wippersnapper_display_v1_DisplayRemoved_did_remove_tag 2
|
||||
#define wippersnapper_display_v1_EPDConfig_mode_tag 1
|
||||
#define wippersnapper_display_v1_EPDWriteOptions_text_size_tag 1
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_bus_tag 1
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_pin_dc_tag 2
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_pin_rst_tag 3
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_pin_cs_tag 4
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_pin_sram_cs_tag 5
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_pin_busy_tag 6
|
||||
#define wippersnapper_display_v1_TftConfig_width_tag 1
|
||||
#define wippersnapper_display_v1_TftConfig_height_tag 2
|
||||
#define wippersnapper_display_v1_TftConfig_rotation_tag 3
|
||||
#define wippersnapper_display_v1_TftSpiConfig_bus_tag 1
|
||||
#define wippersnapper_display_v1_TftSpiConfig_pin_cs_tag 2
|
||||
#define wippersnapper_display_v1_TftSpiConfig_pin_dc_tag 3
|
||||
#define wippersnapper_display_v1_TftSpiConfig_pin_mosi_tag 4
|
||||
#define wippersnapper_display_v1_TftSpiConfig_pin_sck_tag 5
|
||||
#define wippersnapper_display_v1_TftSpiConfig_pin_rst_tag 6
|
||||
#define wippersnapper_display_v1_TftSpiConfig_pin_miso_tag 7
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_type_tag 1
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_name_tag 2
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_spi_epd_tag 3
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_spi_tft_tag 4
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_config_epd_tag 5
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_config_tft_tag 6
|
||||
#define wippersnapper_display_v1_DisplayWrite_name_tag 1
|
||||
#define wippersnapper_display_v1_DisplayWrite_message_tag 2
|
||||
#define wippersnapper_display_v1_DisplayWrite_epd_options_tag 3
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, bus, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_dc, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_rst, 3) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_cs, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_sram_cs, 5) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_busy, 6)
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_DEFAULT NULL
|
||||
|
||||
#define wippersnapper_display_v1_EPDConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, mode, 1)
|
||||
#define wippersnapper_display_v1_EPDConfig_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_EPDConfig_DEFAULT NULL
|
||||
|
||||
#define wippersnapper_display_v1_EPDWriteOptions_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, text_size, 1)
|
||||
#define wippersnapper_display_v1_EPDWriteOptions_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_EPDWriteOptions_DEFAULT NULL
|
||||
|
||||
#define wippersnapper_display_v1_TftSpiConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, bus, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_cs, 2) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_dc, 3) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_mosi, 4) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_sck, 5) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_rst, 6) \
|
||||
X(a, STATIC, SINGULAR, STRING, pin_miso, 7)
|
||||
#define wippersnapper_display_v1_TftSpiConfig_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_TftSpiConfig_DEFAULT NULL
|
||||
|
||||
#define wippersnapper_display_v1_TftConfig_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, width, 1) \
|
||||
X(a, STATIC, SINGULAR, INT32, height, 2) \
|
||||
X(a, STATIC, SINGULAR, INT32, rotation, 3)
|
||||
#define wippersnapper_display_v1_TftConfig_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_TftConfig_DEFAULT NULL
|
||||
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, type, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, name, 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (interface_type,spi_epd,interface_type.spi_epd), 3) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (interface_type,spi_tft,interface_type.spi_tft), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (config,config_epd,config.config_epd), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (config,config_tft,config.config_tft), 6)
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_DEFAULT NULL
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_interface_type_spi_epd_MSGTYPE wippersnapper_display_v1_EpdSpiConfig
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_interface_type_spi_tft_MSGTYPE wippersnapper_display_v1_TftSpiConfig
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_config_config_epd_MSGTYPE wippersnapper_display_v1_EPDConfig
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_config_config_tft_MSGTYPE wippersnapper_display_v1_TftConfig
|
||||
|
||||
#define wippersnapper_display_v1_DisplayRemove_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, STRING, name, 1)
|
||||
#define wippersnapper_display_v1_DisplayRemove_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_DisplayRemove_DEFAULT NULL
|
||||
|
||||
#define wippersnapper_display_v1_DisplayWrite_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, STRING, name, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, message, 2) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (options,epd_options,options.epd_options), 3)
|
||||
#define wippersnapper_display_v1_DisplayWrite_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_DisplayWrite_DEFAULT NULL
|
||||
#define wippersnapper_display_v1_DisplayWrite_options_epd_options_MSGTYPE wippersnapper_display_v1_EPDWriteOptions
|
||||
|
||||
#define wippersnapper_display_v1_DisplayAddedorReplaced_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, STRING, name, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, did_add, 2)
|
||||
#define wippersnapper_display_v1_DisplayAddedorReplaced_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_DisplayAddedorReplaced_DEFAULT NULL
|
||||
|
||||
#define wippersnapper_display_v1_DisplayRemoved_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, STRING, name, 1) \
|
||||
X(a, STATIC, SINGULAR, BOOL, did_remove, 2)
|
||||
#define wippersnapper_display_v1_DisplayRemoved_CALLBACK NULL
|
||||
#define wippersnapper_display_v1_DisplayRemoved_DEFAULT NULL
|
||||
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_EpdSpiConfig_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_EPDConfig_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_EPDWriteOptions_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_TftSpiConfig_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_TftConfig_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_DisplayAddOrReplace_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_DisplayRemove_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_DisplayWrite_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_DisplayAddedorReplaced_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_display_v1_DisplayRemoved_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_fields &wippersnapper_display_v1_EpdSpiConfig_msg
|
||||
#define wippersnapper_display_v1_EPDConfig_fields &wippersnapper_display_v1_EPDConfig_msg
|
||||
#define wippersnapper_display_v1_EPDWriteOptions_fields &wippersnapper_display_v1_EPDWriteOptions_msg
|
||||
#define wippersnapper_display_v1_TftSpiConfig_fields &wippersnapper_display_v1_TftSpiConfig_msg
|
||||
#define wippersnapper_display_v1_TftConfig_fields &wippersnapper_display_v1_TftConfig_msg
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_fields &wippersnapper_display_v1_DisplayAddOrReplace_msg
|
||||
#define wippersnapper_display_v1_DisplayRemove_fields &wippersnapper_display_v1_DisplayRemove_msg
|
||||
#define wippersnapper_display_v1_DisplayWrite_fields &wippersnapper_display_v1_DisplayWrite_msg
|
||||
#define wippersnapper_display_v1_DisplayAddedorReplaced_fields &wippersnapper_display_v1_DisplayAddedorReplaced_msg
|
||||
#define wippersnapper_display_v1_DisplayRemoved_fields &wippersnapper_display_v1_DisplayRemoved_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define wippersnapper_display_v1_EpdSpiConfig_size 46
|
||||
#define wippersnapper_display_v1_EPDConfig_size 2
|
||||
#define wippersnapper_display_v1_EPDWriteOptions_size 11
|
||||
#define wippersnapper_display_v1_TftSpiConfig_size 53
|
||||
#define wippersnapper_display_v1_TftConfig_size 33
|
||||
#define wippersnapper_display_v1_DisplayAddOrReplace_size 157
|
||||
#define wippersnapper_display_v1_DisplayRemove_size 65
|
||||
#define wippersnapper_display_v1_DisplayWrite_size 1104
|
||||
#define wippersnapper_display_v1_DisplayAddedorReplaced_size 67
|
||||
#define wippersnapper_display_v1_DisplayRemoved_size 67
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/ds18x20/v1/ds18x20.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_DS18X20_V1_WIPPERSNAPPER_DS18X20_V1_DS18X20_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_DS18X20_V1_WIPPERSNAPPER_DS18X20_V1_DS18X20_PB_H_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/i2c/v1/i2c.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_I2C_V1_WIPPERSNAPPER_I2C_V1_I2C_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_I2C_V1_WIPPERSNAPPER_I2C_V1_I2C_PB_H_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/pin/v1/pin.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_PIN_V1_WIPPERSNAPPER_PIN_V1_PIN_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_PIN_V1_WIPPERSNAPPER_PIN_V1_PIN_PB_H_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/pixels/v1/pixels.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_PIXELS_V1_WIPPERSNAPPER_PIXELS_V1_PIXELS_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_PIXELS_V1_WIPPERSNAPPER_PIXELS_V1_PIXELS_PB_H_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/pwm/v1/pwm.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_PWM_V1_WIPPERSNAPPER_PWM_V1_PWM_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_PWM_V1_WIPPERSNAPPER_PWM_V1_PWM_PB_H_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/servo/v1/servo.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_SERVO_V1_WIPPERSNAPPER_SERVO_V1_SERVO_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_SERVO_V1_WIPPERSNAPPER_SERVO_V1_SERVO_PB_H_INCLUDED
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/signal/v1/signal.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
|
@ -48,4 +48,10 @@ PB_BIND(wippersnapper_signal_v1_PWMRequest, wippersnapper_signal_v1_PWMRequest,
|
|||
PB_BIND(wippersnapper_signal_v1_PWMResponse, wippersnapper_signal_v1_PWMResponse, AUTO)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_signal_v1_DisplayRequest, wippersnapper_signal_v1_DisplayRequest, 2)
|
||||
|
||||
|
||||
PB_BIND(wippersnapper_signal_v1_DisplayResponse, wippersnapper_signal_v1_DisplayResponse, AUTO)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_SIGNAL_V1_WIPPERSNAPPER_SIGNAL_V1_SIGNAL_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_SIGNAL_V1_WIPPERSNAPPER_SIGNAL_V1_SIGNAL_PB_H_INCLUDED
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
#include "wippersnapper/ds18x20/v1/ds18x20.pb.h"
|
||||
#include "wippersnapper/pixels/v1/pixels.pb.h"
|
||||
#include "wippersnapper/uart/v1/uart.pb.h"
|
||||
#include "wippersnapper/display/v1/display.pb.h"
|
||||
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
#error Regenerate this file with the current version of nanopb generator.
|
||||
|
|
@ -28,6 +29,25 @@ typedef struct _wippersnapper_signal_v1_CreateSignalRequest {
|
|||
} payload;
|
||||
} wippersnapper_signal_v1_CreateSignalRequest;
|
||||
|
||||
typedef struct _wippersnapper_signal_v1_DisplayRequest {
|
||||
pb_callback_t cb_payload;
|
||||
pb_size_t which_payload;
|
||||
union {
|
||||
wippersnapper_display_v1_DisplayAddOrReplace display_add;
|
||||
wippersnapper_display_v1_DisplayRemove display_remove;
|
||||
wippersnapper_display_v1_DisplayWrite display_write;
|
||||
} payload;
|
||||
} wippersnapper_signal_v1_DisplayRequest;
|
||||
|
||||
typedef struct _wippersnapper_signal_v1_DisplayResponse {
|
||||
pb_callback_t cb_payload;
|
||||
pb_size_t which_payload;
|
||||
union {
|
||||
wippersnapper_display_v1_DisplayAddedorReplaced display_added;
|
||||
wippersnapper_display_v1_DisplayRemoved display_removed;
|
||||
} payload;
|
||||
} wippersnapper_signal_v1_DisplayResponse;
|
||||
|
||||
typedef struct _wippersnapper_signal_v1_Ds18x20Request {
|
||||
pb_callback_t cb_payload;
|
||||
pb_size_t which_payload;
|
||||
|
|
@ -173,6 +193,8 @@ extern "C" {
|
|||
#define wippersnapper_signal_v1_SignalResponse_init_default {0, {0}}
|
||||
#define wippersnapper_signal_v1_PWMRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_pwm_v1_PWMAttachRequest_init_default}}
|
||||
#define wippersnapper_signal_v1_PWMResponse_init_default {{{NULL}, NULL}, 0, {wippersnapper_pwm_v1_PWMAttachResponse_init_default}}
|
||||
#define wippersnapper_signal_v1_DisplayRequest_init_default {{{NULL}, NULL}, 0, {wippersnapper_display_v1_DisplayAddOrReplace_init_default}}
|
||||
#define wippersnapper_signal_v1_DisplayResponse_init_default {{{NULL}, NULL}, 0, {wippersnapper_display_v1_DisplayAddedorReplaced_init_default}}
|
||||
#define wippersnapper_signal_v1_UARTRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_uart_v1_UARTDeviceAttachRequest_init_zero}}
|
||||
#define wippersnapper_signal_v1_UARTResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_uart_v1_UARTDeviceAttachResponse_init_zero}}
|
||||
#define wippersnapper_signal_v1_Ds18x20Request_init_zero {{{NULL}, NULL}, 0, {wippersnapper_ds18x20_v1_Ds18x20InitRequest_init_zero}}
|
||||
|
|
@ -187,11 +209,18 @@ extern "C" {
|
|||
#define wippersnapper_signal_v1_SignalResponse_init_zero {0, {0}}
|
||||
#define wippersnapper_signal_v1_PWMRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_pwm_v1_PWMAttachRequest_init_zero}}
|
||||
#define wippersnapper_signal_v1_PWMResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_pwm_v1_PWMAttachResponse_init_zero}}
|
||||
#define wippersnapper_signal_v1_DisplayRequest_init_zero {{{NULL}, NULL}, 0, {wippersnapper_display_v1_DisplayAddOrReplace_init_zero}}
|
||||
#define wippersnapper_signal_v1_DisplayResponse_init_zero {{{NULL}, NULL}, 0, {wippersnapper_display_v1_DisplayAddedorReplaced_init_zero}}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define wippersnapper_signal_v1_CreateSignalRequest_pin_configs_tag 6
|
||||
#define wippersnapper_signal_v1_CreateSignalRequest_pin_events_tag 7
|
||||
#define wippersnapper_signal_v1_CreateSignalRequest_pin_event_tag 15
|
||||
#define wippersnapper_signal_v1_DisplayRequest_display_add_tag 1
|
||||
#define wippersnapper_signal_v1_DisplayRequest_display_remove_tag 2
|
||||
#define wippersnapper_signal_v1_DisplayRequest_display_write_tag 3
|
||||
#define wippersnapper_signal_v1_DisplayResponse_display_added_tag 1
|
||||
#define wippersnapper_signal_v1_DisplayResponse_display_removed_tag 2
|
||||
#define wippersnapper_signal_v1_Ds18x20Request_req_ds18x20_init_tag 1
|
||||
#define wippersnapper_signal_v1_Ds18x20Request_req_ds18x20_deinit_tag 2
|
||||
#define wippersnapper_signal_v1_Ds18x20Response_resp_ds18x20_init_tag 1
|
||||
|
|
@ -360,6 +389,24 @@ X(a, STATIC, ONEOF, MSG_W_CB, (payload,attach_response,payload.attach_respo
|
|||
#define wippersnapper_signal_v1_PWMResponse_DEFAULT NULL
|
||||
#define wippersnapper_signal_v1_PWMResponse_payload_attach_response_MSGTYPE wippersnapper_pwm_v1_PWMAttachResponse
|
||||
|
||||
#define wippersnapper_signal_v1_DisplayRequest_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MSG_W_CB, (payload,display_add,payload.display_add), 1) \
|
||||
X(a, STATIC, ONEOF, MSG_W_CB, (payload,display_remove,payload.display_remove), 2) \
|
||||
X(a, STATIC, ONEOF, MSG_W_CB, (payload,display_write,payload.display_write), 3)
|
||||
#define wippersnapper_signal_v1_DisplayRequest_CALLBACK NULL
|
||||
#define wippersnapper_signal_v1_DisplayRequest_DEFAULT NULL
|
||||
#define wippersnapper_signal_v1_DisplayRequest_payload_display_add_MSGTYPE wippersnapper_display_v1_DisplayAddOrReplace
|
||||
#define wippersnapper_signal_v1_DisplayRequest_payload_display_remove_MSGTYPE wippersnapper_display_v1_DisplayRemove
|
||||
#define wippersnapper_signal_v1_DisplayRequest_payload_display_write_MSGTYPE wippersnapper_display_v1_DisplayWrite
|
||||
|
||||
#define wippersnapper_signal_v1_DisplayResponse_FIELDLIST(X, a) \
|
||||
X(a, STATIC, ONEOF, MSG_W_CB, (payload,display_added,payload.display_added), 1) \
|
||||
X(a, STATIC, ONEOF, MSG_W_CB, (payload,display_removed,payload.display_removed), 2)
|
||||
#define wippersnapper_signal_v1_DisplayResponse_CALLBACK NULL
|
||||
#define wippersnapper_signal_v1_DisplayResponse_DEFAULT NULL
|
||||
#define wippersnapper_signal_v1_DisplayResponse_payload_display_added_MSGTYPE wippersnapper_display_v1_DisplayAddedorReplaced
|
||||
#define wippersnapper_signal_v1_DisplayResponse_payload_display_removed_MSGTYPE wippersnapper_display_v1_DisplayRemoved
|
||||
|
||||
extern const pb_msgdesc_t wippersnapper_signal_v1_UARTRequest_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_signal_v1_UARTResponse_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_signal_v1_Ds18x20Request_msg;
|
||||
|
|
@ -374,6 +421,8 @@ extern const pb_msgdesc_t wippersnapper_signal_v1_CreateSignalRequest_msg;
|
|||
extern const pb_msgdesc_t wippersnapper_signal_v1_SignalResponse_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_signal_v1_PWMRequest_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_signal_v1_PWMResponse_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_signal_v1_DisplayRequest_msg;
|
||||
extern const pb_msgdesc_t wippersnapper_signal_v1_DisplayResponse_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define wippersnapper_signal_v1_UARTRequest_fields &wippersnapper_signal_v1_UARTRequest_msg
|
||||
|
|
@ -390,6 +439,8 @@ extern const pb_msgdesc_t wippersnapper_signal_v1_PWMResponse_msg;
|
|||
#define wippersnapper_signal_v1_SignalResponse_fields &wippersnapper_signal_v1_SignalResponse_msg
|
||||
#define wippersnapper_signal_v1_PWMRequest_fields &wippersnapper_signal_v1_PWMRequest_msg
|
||||
#define wippersnapper_signal_v1_PWMResponse_fields &wippersnapper_signal_v1_PWMResponse_msg
|
||||
#define wippersnapper_signal_v1_DisplayRequest_fields &wippersnapper_signal_v1_DisplayRequest_msg
|
||||
#define wippersnapper_signal_v1_DisplayResponse_fields &wippersnapper_signal_v1_DisplayResponse_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define wippersnapper_signal_v1_UARTRequest_size 58
|
||||
|
|
@ -412,6 +463,8 @@ union wippersnapper_signal_v1_CreateSignalRequest_payload_size_union {char f6[(6
|
|||
#define wippersnapper_signal_v1_SignalResponse_size 2
|
||||
#define wippersnapper_signal_v1_PWMRequest_size 82
|
||||
#define wippersnapper_signal_v1_PWMResponse_size 11
|
||||
#define wippersnapper_signal_v1_DisplayRequest_size 1107
|
||||
#define wippersnapper_signal_v1_DisplayResponse_size 69
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb constant definitions */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#include "wippersnapper/uart/v1/uart.pb.h"
|
||||
#if PB_PROTO_HEADER_VERSION != 40
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* Automatically generated nanopb header */
|
||||
/* Generated by nanopb-0.4.5-dev at Fri Jun 6 19:48:16 2025. */
|
||||
/* Generated by nanopb-0.4.5-dev at Mon Aug 25 15:39:12 2025. */
|
||||
|
||||
#ifndef PB_WIPPERSNAPPER_UART_V1_WIPPERSNAPPER_UART_V1_UART_PB_H_INCLUDED
|
||||
#define PB_WIPPERSNAPPER_UART_V1_WIPPERSNAPPER_UART_V1_UART_PB_H_INCLUDED
|
||||
|
|
|
|||
Loading…
Reference in a new issue