Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions firmware/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ endif()
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(cloudburst)

# Include nanopb for protobuf support
list(APPEND CMAKE_MODULE_PATH ${ZEPHYR_BASE}/modules/nanopb)
include(nanopb)

# Generate protobuf sources from falcon-protos
set(FALCON_PROTOS_DIR ${CMAKE_CURRENT_LIST_DIR}/../../modules/falcon-protos)
zephyr_nanopb_sources(app ${FALCON_PROTOS_DIR}/HelloWorldPacket.proto)

target_sources(app PRIVATE
src/main.c
src/data.c
Expand All @@ -41,6 +49,7 @@ target_sources(app PRIVATE
src/state_machine/states/main_descent.c
src/state_machine/states/landed.c
src/pyro/pyro_thread.c
src/radio/radio_thread.c
)

target_include_directories(app PRIVATE
Expand Down
9 changes: 9 additions & 0 deletions firmware/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,12 @@ CONFIG_THREAD_MONITOR=y
CONFIG_THREAD_NAME=y
CONFIG_THREAD_STACK_INFO=n
CONFIG_STACK_SENTINEL=y

# Enable nanopb for protobuf support
CONFIG_NANOPB=y

# Enable CRC for packet integrity checking
CONFIG_CRC=y

# Enable COBS for packet framing
CONFIG_COBS=y
2 changes: 2 additions & 0 deletions firmware/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "logger_thread.h"
#include "state_machine/state_machine.h"
#include "pyro/pyro_thread.h"
#include "radio/radio_thread.h"
#include "data.h"

LOG_MODULE_REGISTER(falcon_main, LOG_LEVEL_INF);
Expand All @@ -22,6 +23,7 @@ int main(void)
start_baro_thread();
start_pyro_thread();
start_state_machine_thread();
start_radio_thread();

return 0;
}
98 changes: 98 additions & 0 deletions firmware/src/radio/radio_thread.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/crc.h>
#include <zephyr/data/cobs.h>
#include <zephyr/net_buf.h>
#include <pb_encode.h>
#include <HelloWorldPacket.pb.h>

LOG_MODULE_REGISTER(radio_thread, LOG_LEVEL_INF);

#define RADIO_THREAD_STACK_SIZE 2048
#define RADIO_THREAD_PRIORITY 5
#define RADIO_THREAD_PERIOD_MS 1000

#define MAX_COBS_SIZE 256 /* max size of COBS encoded data, defined by GNSS/RADIO SPI spec */
#define MAX_FRAME_SIZE ((MAX_COBS_SIZE - 2) * 254 / 255) /* 253 */
#define MAX_PAYLOAD_SIZE (MAX_FRAME_SIZE - sizeof(uint16_t)) /* 251 */

NET_BUF_POOL_DEFINE(cobs_src_pool, 1, MAX_FRAME_SIZE, 0, NULL);
NET_BUF_POOL_DEFINE(cobs_dst_pool, 1, MAX_COBS_SIZE, 0, NULL);

K_THREAD_STACK_DEFINE(radio_stack, RADIO_THREAD_STACK_SIZE);
static struct k_thread radio_thread;

BUILD_ASSERT(MAX_FRAME_SIZE + MAX_FRAME_SIZE / 254 + 2 <= MAX_COBS_SIZE,
"MAX_FRAME_SIZE too large for MAX_COBS_SIZE");

static void radio_thread_fn(void *p1, void *p2, void *p3)
{
uint32_t counter = 0;

while (1) {
HelloWorldPacket message = HelloWorldPacket_init_zero;
Comment thread
JonnoGG marked this conversation as resolved.
uint8_t buffer[MAX_PAYLOAD_SIZE];

message.counter = counter;
strncpy(message.message, "hello world", sizeof(message.message) - 1);

pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
bool status = pb_encode(&stream, HelloWorldPacket_fields, &message);
size_t message_length = stream.bytes_written;

if (!status) {
LOG_ERR("Failed to encode HelloWorldPacket: %s",
PB_GET_ERROR(&stream));
counter++;
k_sleep(K_MSEC(RADIO_THREAD_PERIOD_MS));
continue;
}

/* CRC16-CCITT over protobuf payload */
uint16_t crc = crc16_ccitt(0x0000, buffer, message_length);

/* Pack protobuf data + CRC into net_buf for COBS encoding */
struct net_buf *src_buf = net_buf_alloc(&cobs_src_pool, K_NO_WAIT);
struct net_buf *dst_buf = net_buf_alloc(&cobs_dst_pool, K_NO_WAIT);

if (!src_buf || !dst_buf) {
LOG_ERR("Failed to allocate net_buf for COBS encoding");
if (src_buf) {
net_buf_unref(src_buf);
}
if (dst_buf) {
net_buf_unref(dst_buf);
}
counter++;
k_sleep(K_MSEC(RADIO_THREAD_PERIOD_MS));
continue;
}

net_buf_add_mem(src_buf, buffer, message_length);
net_buf_add_le16(src_buf, crc);

/* COBS encode with trailing 0x00 delimiter */
int ret = cobs_encode(src_buf, dst_buf, COBS_FLAG_TRAILING_DELIMITER);

if (ret == 0) {
LOG_INF("Encoded packet: counter=%u, pb=%zu, cobs=%u bytes",
counter, message_length, dst_buf->len);
LOG_HEXDUMP_DBG(dst_buf->data, dst_buf->len,
"COBS encoded packet");
} else {
LOG_ERR("COBS encoding failed: %d", ret);
}

net_buf_unref(src_buf);
net_buf_unref(dst_buf);

counter++;
k_sleep(K_MSEC(RADIO_THREAD_PERIOD_MS));
}
}

void start_radio_thread(void)
{
k_thread_create(&radio_thread, radio_stack, K_THREAD_STACK_SIZEOF(radio_stack),
radio_thread_fn, NULL, NULL, NULL, RADIO_THREAD_PRIORITY, 0, K_NO_WAIT);
}
6 changes: 6 additions & 0 deletions firmware/src/radio/radio_thread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef RADIO_THREAD_H
#define RADIO_THREAD_H

void start_radio_thread(void);

#endif
6 changes: 6 additions & 0 deletions west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ manifest:
remotes:
- name: zephyrproject-rtos
url-base: https://github.com/zephyrproject-rtos
- name: ubc-rocket
url-base: https://github.com/UBC-Rocket

projects:
- name: zephyr
remote: zephyrproject-rtos
revision: v4.3.0
import: true
- name: falcon-protos
remote: ubc-rocket
revision: main
path: modules/falcon-protos

self:
path: app
Loading