Compare commits

...

23 commits

Author SHA1 Message Date
brentru
0663d1d1bf Putback existing Doxyfile 2025-08-22 11:41:17 -04:00
brentru
3f9d05410e doxy2 2025-08-22 11:29:06 -04:00
brentru
82476b8659 Clang format 2025-08-22 11:13:20 -04:00
brentru
1b9b634465 bump ver 2025-08-21 11:08:49 -04:00
brentru
49cf9cc4bf Detect SSD1680 automatically 2025-08-21 10:37:18 -04:00
brentru
05db09227b Implement publishing back to IO, T5 driver for pre-2025 2025-08-20 15:42:27 -04:00
brentru
b5e53344d8 Doxygen across new sections 2025-08-20 13:21:00 -04:00
brentru
0242373096 Speed up writeMessage 2025-08-20 10:48:20 -04:00
brentru
cfb893d7ba debugging failed to subscribe err 2025-08-19 16:46:22 -04:00
brentru
e8fbd8786c Checkin Display Write handler code 2025-08-19 15:40:46 -04:00
brentru
12d23548e2 Route DisplayWrite throughout MVC 2025-08-19 12:15:55 -04:00
brentru
ca75bf0f18 Match 711bf14..000802e 2025-08-18 14:46:33 -04:00
brentru
2743edc637 last bit of optimization to allow a factory map within hardware.cpp and switch to a default type to allow general api access rather than specific driver access. similar to v2 2025-08-18 14:35:13 -04:00
brentru
cf617c5ae9 Refactor out hardware file 2025-08-18 14:04:44 -04:00
brentru
ab55789f25 Implement HandleDisplayRemove 2025-08-15 14:25:20 -04:00
brentru
37904f3282 Almost full circle display add 2025-08-15 14:17:25 -04:00
brentru
fc41a7de82 Add beginEPD full implementation with safety concerns and a better init flow 2025-08-15 13:41:36 -04:00
brentru
c308694233 Routing epd begin thru 2025-08-15 12:32:32 -04:00
brentru
14ef634f1f Update for Protobuf 23abc52..c83b680 2025-08-15 12:08:41 -04:00
brentru
967650e580 Add display component, start handleAdd 2025-08-15 12:05:31 -04:00
brentru
71cb68d10c Add deserializer hooks 2025-08-14 16:39:21 -04:00
brentru
209abea1eb Track WipperSnapper_Protobuf add-display-v1 commit 2025-08-14 16:34:56 -04:00
brentru
b784f3ffe3 Initial Commit - Hooks for MQTT topics and decoders 2025-08-14 14:14:47 -04:00
37 changed files with 1450 additions and 27 deletions

4
.gitignore vendored
View file

@ -52,4 +52,6 @@ data/
# Misc. Data
tests/
venv/
venv/
Doxyfile

13
.vscode/settings.json vendored
View file

@ -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",

View file

@ -2451,4 +2451,4 @@ GENERATE_LEGEND = YES
# plantuml temporary files.
# The default value is: YES.
DOT_CLEANUP = YES
DOT_CLEANUP = YES

View file

@ -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

View file

@ -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,6 +100,7 @@ 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
@ -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

View file

@ -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,14 @@ void Wippersnapper::connect() {
WS._ui_helper->build_scr_monitor();
#endif
WS.pinCfgCompleted = true;
// Initialize Digital IO class
WS._digitalGPIO = new Wippersnapper_DigitalGPIO(20);
// Initialize Analog IO class
WS._analogIO = new Wippersnapper_AnalogIO(5, 3.3);
WS._boardStatus = WS_BOARD_DEF_OK;
// Configure hardware
while (!WS.pinCfgCompleted) {
WS_DEBUG_PRINTLN(

View file

@ -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. */

View file

@ -0,0 +1,121 @@
/*!
* @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_epd_config_tag) {
did_begin = display->beginEPD(&msgAdd->config.epd_config,
&msgAdd->interface_type.spi_epd);
} else {
WS_DEBUG_PRINTLN("[display] Unsupported display configuration type!");
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;
}

View 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

View file

@ -0,0 +1,82 @@
/*!
* @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 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);
/*!
@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;
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
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
};
#endif // WS_DISP_DRV_BASE_H

View file

@ -0,0 +1,139 @@
/*!
* @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) {
_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

View 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

View file

@ -0,0 +1,287 @@
/*!
* @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 instance
*/
using FnCreateDispDrv =
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, FnCreateDispDrv> FactoryDrvDisp = {
{"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 Creates a new 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 *CreateDrvDisp(const char *driver_name, int16_t dc, int16_t rst,
int16_t cs, int16_t sram_cs = -1,
int16_t busy = -1) {
auto it = FactoryDrvDisp.find(driver_name);
if (it == FactoryDrvDisp.end())
return nullptr;
return it->second(dc, rst, cs, sram_cs, busy);
}
/*!
@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 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 all SPI bus pins
// Check length
if (strlen(spi_config->pin_dc) < 2 || strlen(spi_config->pin_rst) < 2 ||
strlen(spi_config->pin_cs) < 2) {
WS_DEBUG_PRINTLN("[display] Invalid SPI pin len!");
return false;
}
// SPI pins must start with 'D'
if (spi_config->pin_dc[0] != 'D' || spi_config->pin_rst[0] != 'D' ||
spi_config->pin_cs[0] != 'D') {
WS_DEBUG_PRINTLN("[display] SPI pins must start with 'D'!");
return false;
}
// Parse and assign pins
int16_t srcs = -1, busy = -1;
int16_t dc = (int16_t)atoi(spi_config->pin_dc + 1);
int16_t rst = (int16_t)atoi(spi_config->pin_rst + 1);
int16_t cs = (int16_t)atoi(spi_config->pin_cs + 1);
// Optionally parse SRAM CS and BUSY pins
if (strlen(spi_config->pin_sram_cs) >= 2 &&
spi_config->pin_sram_cs[0] == 'D') {
srcs = (int16_t)atoi(spi_config->pin_sram_cs + 1);
}
if (strlen(spi_config->pin_busy) >= 2 && spi_config->pin_busy[0] == 'D') {
busy = (int16_t)atoi(spi_config->pin_busy + 1);
}
// 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 = CreateDrvDisp(_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; // Configuration successful
}
/*!
@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;
}

View file

@ -0,0 +1,57 @@
/*!
* @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/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);
//
// 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:
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

View file

@ -77,6 +77,7 @@ bool Wippersnapper::encodePubRegistrationReq() {
/****************************************************************************/
void Wippersnapper::pollRegistrationResp() {
// Blocking loop, WDT reset upon failure.
WS._boardStatus = WS_BOARD_DEF_OK;
while (WS._boardStatus != WS_BOARD_DEF_OK) {
WS_DEBUG_PRINT("Polling for registration message response...");
WS_DEBUG_PRINTLN(WS._boardStatus);

View file

View file

View 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 Wed Aug 20 17:46:06 2025. */
#include "wippersnapper/description/v1/description.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -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 Wed Aug 20 17:46:06 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

View file

@ -0,0 +1,36 @@
/* Automatically generated nanopb constant definitions */
/* Generated by nanopb-0.4.5-dev at Wed Aug 20 17:46:06 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_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)

View file

@ -0,0 +1,243 @@
/* Automatically generated nanopb header */
/* Generated by nanopb-0.4.5-dev at Wed Aug 20 17:46:06 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;
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;
typedef enum _wippersnapper_display_v1_EPDColors {
wippersnapper_display_v1_EPDColors_EPD_COLORS_UNSPECIFIED = 0,
wippersnapper_display_v1_EPDColors_EPD_COLORS_WHITE = 1,
wippersnapper_display_v1_EPDColors_EPD_COLORS_BLACK = 2,
wippersnapper_display_v1_EPDColors_EPD_COLORS_RED = 3,
wippersnapper_display_v1_EPDColors_EPD_COLORS_GRAY = 4,
wippersnapper_display_v1_EPDColors_EPD_COLORS_DARK = 5,
wippersnapper_display_v1_EPDColors_EPD_COLORS_LIGHT = 6,
wippersnapper_display_v1_EPDColors_EPD_COLORS_YELLOW = 7
} wippersnapper_display_v1_EPDColors;
/* 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_EPDColors color;
} 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_DisplayAddOrReplace {
wippersnapper_display_v1_DisplayType type;
char name[64];
pb_size_t which_interface_type;
union {
wippersnapper_display_v1_EpdSpiConfig spi_epd;
} interface_type;
pb_size_t which_config;
union {
wippersnapper_display_v1_EPDConfig epd_config;
} 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_EPD
#define _wippersnapper_display_v1_DisplayType_ARRAYSIZE ((wippersnapper_display_v1_DisplayType)(wippersnapper_display_v1_DisplayType_DISPLAY_TYPE_EPD+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))
#define _wippersnapper_display_v1_EPDColors_MIN wippersnapper_display_v1_EPDColors_EPD_COLORS_UNSPECIFIED
#define _wippersnapper_display_v1_EPDColors_MAX wippersnapper_display_v1_EPDColors_EPD_COLORS_YELLOW
#define _wippersnapper_display_v1_EPDColors_ARRAYSIZE ((wippersnapper_display_v1_EPDColors)(wippersnapper_display_v1_EPDColors_EPD_COLORS_YELLOW+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, _wippersnapper_display_v1_EPDColors_MIN}
#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, _wippersnapper_display_v1_EPDColors_MIN}
#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_EPDWriteOptions_color_tag 2
#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_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_epd_config_tag 4
#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) \
X(a, STATIC, SINGULAR, UENUM, color, 2)
#define wippersnapper_display_v1_EPDWriteOptions_CALLBACK NULL
#define wippersnapper_display_v1_EPDWriteOptions_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, (config,epd_config,config.epd_config), 4)
#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_config_epd_config_MSGTYPE wippersnapper_display_v1_EPDConfig
#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_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_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 13
#define wippersnapper_display_v1_DisplayAddOrReplace_size 119
#define wippersnapper_display_v1_DisplayRemove_size 65
#define wippersnapper_display_v1_DisplayWrite_size 1106
#define wippersnapper_display_v1_DisplayAddedorReplaced_size 67
#define wippersnapper_display_v1_DisplayRemoved_size 67
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View 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 Wed Aug 20 17:46:06 2025. */
#include "wippersnapper/ds18x20/v1/ds18x20.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -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 Wed Aug 20 17:46:06 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

View 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 Wed Aug 20 17:46:06 2025. */
#include "wippersnapper/i2c/v1/i2c.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -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 Wed Aug 20 17:46:06 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

View 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 Wed Aug 20 17:46:06 2025. */
#include "wippersnapper/pin/v1/pin.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -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 Wed Aug 20 17:46:06 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

View 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 Wed Aug 20 17:46:06 2025. */
#include "wippersnapper/pixels/v1/pixels.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -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 Wed Aug 20 17:46:06 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

View 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 Wed Aug 20 17:46:06 2025. */
#include "wippersnapper/pwm/v1/pwm.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -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 Wed Aug 20 17:46:06 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

View 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 Wed Aug 20 17:46:06 2025. */
#include "wippersnapper/servo/v1/servo.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -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 Wed Aug 20 17:46:06 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

View 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 Wed Aug 20 17:46:06 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)

View file

@ -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 Wed Aug 20 17:46:06 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 1109
#define wippersnapper_signal_v1_DisplayResponse_size 69
#ifdef __cplusplus
} /* extern "C" */

View 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 Wed Aug 20 17:46:06 2025. */
#include "wippersnapper/uart/v1/uart.pb.h"
#if PB_PROTO_HEADER_VERSION != 40

View file

@ -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 Wed Aug 20 17:46:06 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