diff --git a/.github/workflows/build-examples.yml b/.github/workflows/build-examples.yml index bce2d99..24cd8f4 100644 --- a/.github/workflows/build-examples.yml +++ b/.github/workflows/build-examples.yml @@ -15,6 +15,7 @@ jobs: example: - blinky - message-queues + - binary - shell overlay: - i2c.overlay diff --git a/examples/README.md b/examples/README.md index 3e1d9c9..c3a3629 100644 --- a/examples/README.md +++ b/examples/README.md @@ -6,3 +6,4 @@ These examples demonstrate how to use the Notecard with Zephyr. Examples include - [blinky](./blinky/README.md) - Toggle an LED and sends a Note to the Notecard with the status of the LED. A modification of Zephyr's Blinky example. - [message queues](./message-queues/README.md) - Demonstrates how to use the Zephyr's Message Queue API to send and receive messages across threads while handling real-time events and offloading the data to Notecard for cloud upload. +- [binary](./binary/README.md) - Demonstrates how to send and receive binary data to and from the Notecard (and to and from Notehub). diff --git a/examples/binary/CMakeLists.txt b/examples/binary/CMakeLists.txt new file mode 100644 index 0000000..e3f0134 --- /dev/null +++ b/examples/binary/CMakeLists.txt @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Blues Inc. +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.13.1) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project(app LANGUAGES C) + +target_sources(app PRIVATE src/main.c) diff --git a/examples/binary/README.md b/examples/binary/README.md new file mode 100644 index 0000000..5cd23d4 --- /dev/null +++ b/examples/binary/README.md @@ -0,0 +1,13 @@ +# binary + +This example demonstrates how to use the Notecard with Zephyr. It shows how to send and receive binary data to and from the Notecard (and to and from Notehub). + +```bash +# Build for I2C +west build examples/binary -b swan_r5 -DDTC_OVERLAY_FILE=../overlays/i2c.overlay +west flash + +# Build for UART +west build examples/binary -b swan_r5 -DDTC_OVERLAY_FILE=../overlays/uart.overlay +west flash +``` diff --git a/examples/binary/prj.conf b/examples/binary/prj.conf new file mode 100644 index 0000000..17b6169 --- /dev/null +++ b/examples/binary/prj.conf @@ -0,0 +1,11 @@ +# Logging +CONFIG_LOG=y + +# Notecard libraries +CONFIG_NEWLIB_LIBC=y # Required by `note-c` +CONFIG_BLUES_NOTECARD=y +# Optional: Enable Notecard logging +CONFIG_BLUES_NOTECARD_LOGGING=y + +# Configure Heap Memory Pool +CONFIG_HEAP_MEM_POOL_SIZE=1024 \ No newline at end of file diff --git a/examples/binary/src/main.c b/examples/binary/src/main.c new file mode 100644 index 0000000..4fd220d --- /dev/null +++ b/examples/binary/src/main.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2025 Blues Inc. + * + * MIT License. Use of this source code is governed by licenses granted + * by the copyright holder including that found in the LICENSE file. + */ + +#include +#include +#include +#include + +// Include Notecard note-c library +#include + +#ifndef PRODUCT_UID +#define PRODUCT_UID "" +#pragma message "PRODUCT_UID is not defined in this example. Please ensure your Notecard has a product identifier set before running this example or define it in code here. More details at https://bit.ly/product-uid" +#endif + +#define SLEEP_TIME_MS 30000 +#define MAX_ITERATIONS 5 + +LOG_MODULE_REGISTER(main); + +int main(void) +{ + LOG_INF("Initializing binary send/receive example..."); + + // Initialize note-c hooks + NoteSetUserAgent((char *)"note-zephyr"); + + // Configure the Notecard + J *req = NoteNewRequest("hub.set"); + if (req) { + JAddStringToObject(req, "product", PRODUCT_UID); + JAddStringToObject(req, "mode", "continuous"); + if (!NoteRequest(req)) { + LOG_ERR("Failed to configure Notecard."); + return -1; + } + } else { + LOG_ERR("Failed to allocate memory for hub.set request."); + return -1; + } + + // Reset the binary store + NoteBinaryStoreReset(); + + uint8_t event_counter = 0; + while (1) { + if (++event_counter > MAX_ITERATIONS) { + LOG_INF("Demo complete. Program stopping to conserve data."); + return 0; + } + + // Example data to transmit + char data[] = "https://youtu.be/0epWToAOlFY?t=21"; + uint32_t data_len = strlen(data); + const uint32_t notecard_binary_area_offset = 0; + + // Transmit data to Notecard storage + NoteBinaryStoreTransmit((uint8_t *)data, data_len, sizeof(data), notecard_binary_area_offset); + LOG_INF("Transmitted %d bytes", data_len); + + // Receive data length from Notecard storage + uint32_t rx_data_len = 0; + NoteBinaryStoreDecodedLength(&rx_data_len); + + // Allocate receive buffer + uint32_t rx_buffer_len = NoteBinaryCodecMaxEncodedLength(rx_data_len); + uint8_t *rx_buffer = k_malloc(rx_buffer_len); + if (!rx_buffer) { + LOG_ERR("Failed to allocate receive buffer"); + return -1; + } + + // Receive the actual data from Notecard storage + NoteBinaryStoreReceive(rx_buffer, rx_buffer_len, 0, rx_data_len); + LOG_INF("Received %d bytes: %.*s", rx_data_len, rx_data_len, rx_buffer); + + k_free(rx_buffer); + + // Send binary data to Notehub + req = NoteNewRequest("note.add"); + if (req) { + JAddStringToObject(req, "file", "cobs.qo"); + JAddBoolToObject(req, "binary", true); + JAddBoolToObject(req, "live", true); + if (!NoteRequest(req)) { + LOG_ERR("Failed to send binary note to Notehub"); + NoteBinaryStoreReset(); + } else { + LOG_INF("Binary note sent to Notehub"); + } + } else { + LOG_ERR("Failed to allocate memory for note.add request"); + NoteBinaryStoreReset(); + } + + k_msleep(SLEEP_TIME_MS); + } + + return 0; +}