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
13 changes: 10 additions & 3 deletions .github/workflows/Build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- main
- siglent
pull_request:
branches:
- main
Expand Down Expand Up @@ -199,14 +200,20 @@ jobs:


Embedded_Firmware:
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

- name: Install toolchain
run: |
sudo apt-get update
sudo apt install -y build-essential gcc-arm-none-eabi binutils-arm-none-eabi
sudo apt install -y build-essential binutils-arm-none-eabi

# Ubuntu 24.04 comes with version 10.3 of the ARM GCC toolchain. For some reason builds with that version result in buggy file reading/writing and unstable USB connections.
# Manually install older version of the toolchain which does not have the problem
wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2
tar -xvjf gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 -C /opt

sudo git clone https://github.com/raspberrypi/pico-sdk.git /opt/pico-sdk
sudo git -C /opt/pico-sdk checkout 2.1.1
sudo git -C /opt/pico-sdk submodule update --init
Expand All @@ -229,11 +236,11 @@ jobs:
- name: Build application
run: |
export PICO_SDK_PATH=/opt/pico-sdk
export PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update/bin:$PATH
cd Software/LibreCAL
mkdir build && cd build
cmake ..
make -j9
make -j9
shell: bash

- name: Upload
Expand Down
5 changes: 4 additions & 1 deletion Software/LibreCAL/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ add_definitions(
-DFW_MAJOR=0
-DFW_MINOR=2
-DFW_PATCH=4
#-DENABLE_UART
)

add_executable(LibreCAL
Expand All @@ -48,10 +49,12 @@ add_executable(LibreCAL
src/USB/msc_disk.cpp
src/USB/usb_descriptors.c
src/USB/usb.c
src/USB/siglent_tmc.cpp
src/fatfs/ff.c
src/fatfs/ffsystem.c
src/fatfs/ffunicode.c
src/fatfs/flashdisk.cpp
src/Log.cpp
)

target_include_directories(LibreCAL PUBLIC
Expand All @@ -62,4 +65,4 @@ target_include_directories(LibreCAL PUBLIC
)

pico_add_extra_outputs(LibreCAL)
target_link_libraries(LibreCAL pico_stdlib pico_unique_id hardware_rtc hardware_spi hardware_pwm hardware_adc FreeRTOS tinyusb_device tinyusb_board)
target_link_libraries(LibreCAL pico_stdlib pico_unique_id hardware_rtc hardware_uart hardware_spi hardware_pwm hardware_adc FreeRTOS tinyusb_device tinyusb_board)
109 changes: 109 additions & 0 deletions Software/LibreCAL/src/Log.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include "Log.h"

#ifdef ENABLE_UART

#include <cstdarg>
#include <cstdio>
#include <cstring>

#include "hardware/uart.h"
#include "hardware/gpio.h"

#include "FreeRTOS.h"
#include "task.h"

extern "C" {

#define MAX_LINE_LENGTH 256

static char fifo[LOG_SENDBUF_LENGTH + MAX_LINE_LENGTH];
static uint16_t fifo_write, fifo_read;

#ifdef LOG_USE_MUTEX
#include "FreeRTOS.h"
#include "semphr.h"
static StaticSemaphore_t xMutex;
static SemaphoreHandle_t mutex;
#endif

#define INC_FIFO_POS(pos, inc) do { pos = (pos + inc) % LOG_SENDBUF_LENGTH; } while(0)

static uint16_t fifo_space() {
uint16_t used;
if(fifo_write >= fifo_read) {
used = fifo_write - fifo_read;
} else {
used = fifo_write - fifo_read + LOG_SENDBUF_LENGTH;
}
return LOG_SENDBUF_LENGTH - used - 1;
}

void on_uart_needs_data(void) {
if(fifo_read != fifo_write) {
uart_putc_raw(LOG_UART_ID, fifo[fifo_read]);
INC_FIFO_POS(fifo_read, 1);
} else {
// all done, disable interrupt
uart_set_irq_enables(LOG_UART_ID, false, false);
}
}

void Log_Init() {
fifo_write = 0;
fifo_read = 0;
#ifdef LOG_USE_MUTEXES
mutex = xSemaphoreCreateMutexStatic(&xMutex);
#endif

// initialize the UART
uart_init(LOG_UART_ID, 115200);
gpio_set_function(LOG_UART_PIN, UART_FUNCSEL_NUM(LOG_UART_ID, LOG_UART_PIN));

uart_set_hw_flow(LOG_UART_ID, false, false);
uart_set_fifo_enabled(LOG_UART_ID, false);

// Set up the TX interrupt
int UART_IRQ = LOG_UART_ID == uart0 ? UART0_IRQ : UART1_IRQ;
irq_set_exclusive_handler(UART_IRQ, on_uart_needs_data);
irq_set_enabled(UART_IRQ, true);

// we need to write something here, otherwise the handler is never called later?
uart_puts(LOG_UART_ID, "LibreCAL log start\r\n");
}


void _log_write(const char *module, const char *level, const char *fmt, ...) {
int written = 0;
va_list args;
va_start(args, fmt);
#ifdef LOG_USE_MUTEX
if (!STM::InInterrupt()) {
xSemaphoreTake(mutex, portMAX_DELAY);
}
#endif
written = snprintf(&fifo[fifo_write], MAX_LINE_LENGTH, "%05lu [%6.6s,%s]: ",
xTaskGetTickCount(), module, level);
written += vsnprintf(&fifo[fifo_write + written], MAX_LINE_LENGTH - written,
fmt, args);
written += snprintf(&fifo[fifo_write + written], MAX_LINE_LENGTH - written,
"\r\n");

// check if line still fits into ring buffer
if (written > fifo_space()) {
// unable to fit line, skip
return;
}

int16_t overflow = (fifo_write + written) - LOG_SENDBUF_LENGTH;
if (overflow > 0) {
// printf wrote over the end of the ring buffer -> wrap around
memmove(&fifo[0], &fifo[LOG_SENDBUF_LENGTH], overflow);
}
INC_FIFO_POS(fifo_write, written);
// enable interrupt
uart_set_irq_enables(LOG_UART_ID, false, true);
}
}

#endif

73 changes: 73 additions & 0 deletions Software/LibreCAL/src/Log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#ifndef ENABLE_UART
// Log output disabled
#define LOG_CRIT(fmt, ...)
#define LOG_ERR(fmt, ...)
#define LOG_WARN(fmt, ...)
#define LOG_INFO(fmt, ...)
#define LOG_DEBUG(fmt, ...)
#else

#define LOG_UART_ID uart1
#define LOG_UART_PIN 24

#define LOG_SENDBUF_LENGTH 1024

#define LOG_LEVEL_DEBUG 4
#define LOG_LEVEL_INFO 3
#define LOG_LEVEL_WARN 2
#define LOG_LEVEL_ERR 1
#define LOG_LEVEL_CRIT 0

#define LOG_LEVEL_DEFAULT LOG_LEVEL_ERR

#ifndef LOG_LEVEL
#define LOG_LEVEL LOG_LEVEL_DEFAULT
#endif

#ifndef LOG_MODULE
#define LOG_MODULE "Log"
#endif

#if LOG_LEVEL >= LOG_LEVEL_CRIT
#define LOG_CRIT(fmt, ...) _log_write(LOG_MODULE, "CRT", fmt, ## __VA_ARGS__)
#else
#define LOG_CRIT(fmt, ...)
#endif
#if LOG_LEVEL >= LOG_LEVEL_ERR
#define LOG_ERR(fmt, ...) _log_write(LOG_MODULE, "ERR", fmt, ## __VA_ARGS__)
#else
#define LOG_ERR(fmt, ...)
#endif
#if LOG_LEVEL >= LOG_LEVEL_WARN
#define LOG_WARN(fmt, ...) _log_write(LOG_MODULE, "WRN", fmt, ## __VA_ARGS__)
#else
#define LOG_WARN(fmt, ...)
#endif
#if LOG_LEVEL >= LOG_LEVEL_INFO
#define LOG_INFO(fmt, ...) _log_write(LOG_MODULE, "INF", fmt, ## __VA_ARGS__)
#else
#define LOG_INFO(fmt, ...)
#endif
#if LOG_LEVEL >= LOG_LEVEL_DEBUG
#define LOG_DEBUG(fmt, ...) _log_write(LOG_MODULE, "DBG", fmt, ## __VA_ARGS__)
#else
#define LOG_DEBUG(fmt, ...)
#endif

#include <stdint.h>

void Log_Init();
typedef void (*log_redirect_t)(const char *line, uint16_t length);
void _log_write(const char *module, const char *level, const char *fmt, ...);

#endif

#ifdef __cplusplus
}
#endif
Loading