Skip to content

Commit

Permalink
Custom hardware component integration (#19)
Browse files Browse the repository at this point in the history
* Added withCustomDisplay

* Bumped version
  • Loading branch information
amirna2 authored Dec 9, 2024
1 parent 92953b6 commit 666fd3d
Show file tree
Hide file tree
Showing 13 changed files with 423 additions and 56 deletions.
2 changes: 1 addition & 1 deletion include/RadioMeshVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define VERSION_PATCH 7
#define VERSION_PATCH 8
#define VERSION_EXTRA 0

#define RM_VERSION ((((VERSION_MAJOR) << 26) | \
Expand Down
4 changes: 2 additions & 2 deletions library.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "RadioMesh",
"keywords": "mesh-network, long-range, low-power, radio, protocol, toolkit, wireless, networking, iot, esp32, arduino",
"description": "A library for building low-power, long-range IoT mesh networks using embedded radio devices.",
"description": "A library for building wide area mesh networks of embedded devices using long range radios.",

"authors":
{
Expand All @@ -10,7 +10,7 @@
"url": "https://github.com/amirna2/RadioMesh",
"maintainer": true
},
"version": "0.0.7",
"version": "0.0.8",
"repository":
{
"type": "git",
Expand Down
26 changes: 19 additions & 7 deletions src/common/inc/Errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,12 @@
#define RM_E_DISPLAY_SETUP (-201)

/**
* @brief The display failed to display.
* @brief The display operation failed to complete.
*/
#define RM_E_DISPLAY_FAILURE (-202)

/**
* @brief The display is not setup.
* @brief The display is not setup. Call setup() first.
*/
#define RM_E_DISPLAY_NOT_SETUP (-203)

Expand All @@ -145,18 +145,30 @@
*/
#define RM_E_DISPLAY_INVALID_FONT (-204)

/**
* @brief The display failed to draw string.
*/
#define RM_E_DISPLAY_DRAW_STRING (-205)

/**
* @brief The display parameters are invalid.
* @brief The display failed to draw number.
*/
#define RM_E_DISPLAY_DRAW_NUMBER (-206)

*/
#define RM_E_INVALID_DISPLAY_PARAMS (-205)
/**
* @brief The display coordinates are invalid/out of bounds.
*/
#define RM_E_DISPLAY_INVALID_COORDS (-207)

/**
* @brief The display rotation is invalid.
*/
#define RM_E_DISPLAY_INVALID_ROTATION (-208)

/**
* @brief The display failed to draw string.
* @brief The display brightness is invalid.
*/
#define RM_E_DISPLAY_DRAW_STRING (-206)
#define RM_E_DISPLAY_INVALID_BRIGHTNESS (-209)

/**
* @brief SSID in not available.
Expand Down
24 changes: 13 additions & 11 deletions src/framework/builder/inc/DeviceBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,6 @@ class DeviceBuilder
*/
DeviceBuilder &withTxPacketCallback(PacketSentCallback callback);

/**
* @brief Add AesCrypto to the device with the given key and IV
* @param key The key for the AesCrypto
* @param iv The IV for the AesCrypto
* @return A reference to the updated builder
*/
DeviceBuilder &withAesCrypto(const std::vector<byte>& key, const std::vector<byte>& iv);

/**
* @brief Add an OLED display to the device with the given parameters
* @param params The parameters for the OLED display
Expand Down Expand Up @@ -102,6 +94,13 @@ class DeviceBuilder
*/
DeviceBuilder& withSecureMessaging(const SecurityParams &params);

/**
* @brief Add a custom display to the device
* @param display The custom display to add
* @return A reference to the updated builder
*/
DeviceBuilder& withCustomDisplay(IDisplay *display);

/**
* @brief Build the device
* @param name The name of the device
Expand All @@ -128,14 +127,17 @@ class DeviceBuilder
// Device parameters
LoraRadioParams radioParams;
SecurityParams securityParams;
bool relayEnabled = false;
PacketReceivedCallback rxCallback = nullptr;
PacketSentCallback txCallback = nullptr;
OledDisplayParams oledDisplayParams;
WifiParams wifiParams = WifiParams();
WifiAccessPointParams wifiAPParams = WifiAccessPointParams();
ByteStorageParams storageParams;

bool relayEnabled = false;
PacketReceivedCallback rxCallback = nullptr;
PacketSentCallback txCallback = nullptr;
IDisplay* customDisplay = nullptr;
bool useCustomDisplay = false;

void destroyDevice(IDevice *device) {
if (device != nullptr) {
delete device;
Expand Down
33 changes: 27 additions & 6 deletions src/framework/builder/src/DeviceBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,20 @@ DeviceBuilder &DeviceBuilder::withOledDisplay(const OledDisplayParams &params)
loginfo_ln("Setting OLED display params");
blueprint.hasDisplay = true;
oledDisplayParams = params;
useCustomDisplay = true;

return *this;
}

DeviceBuilder &DeviceBuilder::withCustomDisplay(IDisplay* display)
{
blueprint.hasDisplay = true;
useCustomDisplay = true;
customDisplay = display;
return *this;
}


DeviceBuilder &DeviceBuilder::withWifi(const WifiParams &params)
{
loginfo_ln("Setting WiFi params");
Expand Down Expand Up @@ -175,13 +186,23 @@ IDevice *DeviceBuilder::build(const std::string name, std::array<byte, RM_ID_LEN
}

if (blueprint.hasDisplay) {
build_error = device->initializeOledDisplay(oledDisplayParams);
if (build_error != RM_E_NONE) {
logerr_ln("ERROR: Failed to create display [%d]", build_error);
destroyDevice(device);
return nullptr;
if (useCustomDisplay) {
if (customDisplay == nullptr) {
logerr_ln("ERROR: Custom display cannot be null.");
destroyDevice(device);
return nullptr;
}
device->setCustomDisplay(customDisplay);
logdbg_ln("Custom display initialized.");
} else {
build_error = device->initializeOledDisplay(oledDisplayParams);
if (build_error != RM_E_NONE) {
logerr_ln("ERROR: Failed to create display [%d]", build_error);
destroyDevice(device);
return nullptr;
}
logdbg_ln("OLED display initialized.");
}
logdbg_ln("Display initialized.");
}

if (blueprint.hasWifi) {
Expand Down
13 changes: 11 additions & 2 deletions src/framework/device/inc/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class RadioMeshDevice : public IDevice
wifiAccessPoint = nullptr;
#endif
#ifndef RM_NO_DISPLAY
display = nullptr;
oledDisplay = nullptr;
#endif
}

Expand Down Expand Up @@ -116,6 +116,14 @@ class RadioMeshDevice : public IDevice
*/
int initializeOledDisplay(OledDisplayParams displayParams);

/**
* @brief Set the custom display
*
* @param display IDisplay object to set
* @return RM_E_NONE if the display was successfully set, an error code otherwise.
*/
int setCustomDisplay(IDisplay *display);

/**
* @brief Initialize the crypto component
*
Expand Down Expand Up @@ -167,7 +175,8 @@ class RadioMeshDevice : public IDevice
EEPROMStorage* eepromStorage = nullptr;

#ifndef RM_NO_DISPLAY
OledDisplay* display = nullptr;
OledDisplay* oledDisplay = nullptr;
IDisplay* customDisplay = nullptr;
#endif

#ifndef RM_NO_WIFI
Expand Down
24 changes: 19 additions & 5 deletions src/framework/device/src/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,28 +67,42 @@ IDisplay *RadioMeshDevice::getDisplay()
return nullptr;
}
#else

int RadioMeshDevice::setCustomDisplay(IDisplay *display)
{
if (display == nullptr) {
logerr_ln("Custom display cannot be null");
return RM_E_INVALID_PARAM;
}
this->customDisplay = display; // Use the provided custom display
return RM_E_NONE;
}

int RadioMeshDevice::initializeOledDisplay(OledDisplayParams displayParams)
{
int rc = RM_E_NONE;

display = OledDisplay::getInstance();
oledDisplay = OledDisplay::getInstance();

if (display == nullptr) {
if (oledDisplay == nullptr) {
logerr_ln("Failed to create display");
return RM_E_UNKNOWN;
}

rc = display->setParams(displayParams);
rc = oledDisplay->setParams(displayParams);
if (rc != RM_E_NONE) {
logerr_ln("Failed to set display params");
display = nullptr;
oledDisplay = nullptr;
}
return rc;
}

IDisplay *RadioMeshDevice::getDisplay()
{
return display;
if (customDisplay != nullptr) {
return customDisplay;
}
return oledDisplay;
}
#endif // RM_NO_DISPLAY

Expand Down
53 changes: 35 additions & 18 deletions src/framework/interfaces/IDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,31 @@

/**
* @class IDisplay
* @brief This class is an interface for a display.
* @brief Interface for display implementations in the RadioMesh framework
*
* It provides the structure for setting up the display component of a device.
* Use this interface to create specialized display components such as OLED, E-Ink, etc.
* This interface defines the contract for display implementations.
* Custom display implementations must use the standard RM_E_* error codes
* to maintain consistent error handling throughout the system.
*/
class IDisplay
{
public:
virtual ~IDisplay() {}

/**
* @brief Setup the display with the currently stored parameters.
*
* @returns RM_E_NONE if the display was successfully setup, an error code otherwise.
*/
/**
* @brief Initialize the display hardware
*
* Must be called after device configuration but before any display operations.
* Performs actual hardware initialization.
*
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int setup() = 0;

/**
* @brief Set the display into standby mode.
* @param save If true, the display will be put into power save mode. If false, the display will be woken up.
* @returns RM_E_NONE if the display was successfully put into standby mode, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int powerSave(bool save) = 0;

Expand All @@ -37,7 +41,7 @@ class IDisplay
* @param y The y coordinate of the string.
* @param clearScreen If true, the screen will be cleared before drawing the string.
* @param text The text to draw.
* @returns RM_E_NONE if the string was successfully drawn, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int drawString(uint8_t x, uint8_t y, const std::string text) = 0;

Expand All @@ -47,7 +51,7 @@ class IDisplay
* @param y The y coordinate of the string.
* @param clearScreen If true, the screen will be cleared before drawing the string.
* @param text The text to draw.
* @returns RM_E_NONE if the string was successfully drawn, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int drawString(uint8_t x, uint8_t y, const char* text) = 0;

Expand All @@ -56,32 +60,32 @@ class IDisplay
* @param x The x coordinate of the number.
* @param y The y coordinate of the number.
* @param number The number to draw.
* @returns RM_E_NONE if the number was successfully drawn, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int drawNumber(uint8_t x, uint8_t y, int number) = 0;
/**
* @brief Set the cursor position of the display.
* @param x The x coordinate of the cursor.
* @param y The y coordinate of the cursor.
* @returns RM_E_NONE if the cursor was successfully set, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int setCursor(uint8_t x, uint8_t y) = 0;

/**
* @brief Print a string to the display at the current cursor position.
* @param text The text to print.
* @returns RM_E_NONE if the text was successfully printed, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int print(const std::string text) = 0;

/**
* @brief Clear the display buffer.
* @returns RM_E_NONE if the display buffer was successfully cleared, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int clear() = 0;
/**
* @brief Send the display buffer to the display.
* @returns RM_E_NONE if the display buffer was successfully sent, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int flush() = 0;

Expand All @@ -99,14 +103,27 @@ class IDisplay

/**
* @brief Show the splash screen on the display.
* @returns RM_E_NONE if the splash screen was successfully shown, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int showSplashScreen() = 0;

/**
* @brief Set the font of the display.
* @param fontId The ID of the font to set (e.g RM_FONT_MEDIUM)
* @returns RM_E_NONE if the font was successfully set, an error code otherwise.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int setFont(uint8_t fontId) = 0;

/**
* @brief Set the parameters of the display.
* @param params The parameters to set.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int setBrightness(uint8_t level) = 0;
/**
* @brief Set the rotation of the display.
* @param rotation The rotation to set.
* @return RM_E_NONE Success. A RadioMesh error (RM_E_*) code on failure.
*/
virtual int setRotation(uint8_t rotation) = 0;
};
Loading

0 comments on commit 666fd3d

Please sign in to comment.