commit fb1da1b76175f81664585ef1252c30d95d77484b Author: Simon Oberzier Date: Fri Feb 20 20:44:13 2026 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..71d9086 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build +cmake-build-debug +.idea +.DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8a069e1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 4.1) + +# Set target board +set(YAHAL_BOARD "rp2350-launchpad") +set(YAHAL_USE_NANO_SPECS 0) + +# Locate the YAHAL library folder +include(YAHAL_import.cmake) + +project(MCRLController) + +set(CMAKE_CXX_STANDARD 20) + +add_executable(MCRLController main.cpp + lib/sd_reader.h + lib/rtlf.cpp) + +# Add YAHAL to target +yahal_add_me(MCRLController) +yahal_add_library(MCRLController FatFs) + +yahal_add_custom_targets(MCRLController) +yahal_add_extra_outputs(MCRLController) diff --git a/YAHAL_import.cmake b/YAHAL_import.cmake new file mode 100644 index 0000000..5c4f6e4 --- /dev/null +++ b/YAHAL_import.cmake @@ -0,0 +1,30 @@ +# This script tries to locate the YAHAL root +# folder and reads the YAHAL_init.cmake file. + +# Check if we can get the path from a environment variable +if (DEFINED ENV{YAHAL_DIR} AND (NOT YAHAL_DIR)) + set(YAHAL_DIR $ENV{YAHAL_DIR}) + message("Using YAHAL_DIR from environment ('${YAHAL_DIR}')") +endif() + +# Check if we need to locate the YAHAL root directory +if (NOT YAHAL_DIR) + message("Trying to find YAHAL ...") + find_path(YAHAL_DIR .yahal_version . .. ../.. ../../.. ../../../..) +endif () + +# Try to resolve a relative path +get_filename_component(YAHAL_DIR "${YAHAL_DIR}" REALPATH BASE_DIR "${CMAKE_CURRENT_LIST_DIR}") +if (NOT EXISTS ${YAHAL_DIR}) + message(FATAL_ERROR "Directory '${YAHAL_DIR}' not found") +endif () + +# Check if YAHAL_DIR points to the correct folder. +set(YAHAL_INIT_CMAKE_FILE ${YAHAL_DIR}/cmake/YAHAL_init.cmake) +if (NOT EXISTS ${YAHAL_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${YAHAL_DIR}' does not appear to be a YAHAL root folder") +endif () + +# Finally include the init-script +include(${YAHAL_INIT_CMAKE_FILE}) + diff --git a/lib/rtlf.cpp b/lib/rtlf.cpp new file mode 100644 index 0000000..0109a2d --- /dev/null +++ b/lib/rtlf.cpp @@ -0,0 +1,48 @@ +#include "rtlf.h" + +#include "cassert" + +static int write_header_block(FILE* file, __uint32_t car_id, const char* track_name) { + RTLF_Header_Fixed header; + const size_t track_len = strlen(track_name); + + memcpy(header.magic_number, RTLF_MAGIC_NUMBER, 4); + header.version = RTLF_VERSION; + header.car_id = car_id; + header.track_name_len = static_cast<__uint32_t>(track_len); + + assert(fwrite(&header, sizeof(RTLF_Header_Fixed), 1, file) == 1); + assert(fwrite(track_name, 1, track_len, file) == track_len); + + return 0; +} + +RTLF_Context* rtlf_open_write(const char* filename, __uint32_t car_id, const char* track_name) { + FILE* file = fopen(filename, "wb"); + + assert(file != nullptr); + + write_header_block(file, car_id, track_name); + auto* ctx = static_cast(malloc(sizeof(RTLF_Context))); + if (!ctx) { + fclose(file); + return nullptr; + } + + ctx->file = file; + ctx->track_name = strdup(track_name); + return ctx; +} + +int rtlf_write_record(RTLF_Context* ctx, const RTLF_Data_Record* record) { + if (!ctx || !ctx->file) return -1; + if (fwrite(record, RTLF_RECORD_SIZE, 1, ctx->file) != 1) return -1; + return 0; +} + +void rtlf_close(RTLF_Context* ctx) { + if (!ctx) return; + if (ctx->file) fclose(ctx->file); + if (ctx->track_name) free(ctx->track_name); + free(ctx); +} \ No newline at end of file diff --git a/lib/rtlf.h b/lib/rtlf.h new file mode 100644 index 0000000..5b8bae6 --- /dev/null +++ b/lib/rtlf.h @@ -0,0 +1,53 @@ +#ifndef MCRLCONTROLLER_RTLF_H +#define MCRLCONTROLLER_RTLF_H + + +#include +#include +#include + +#define RTLF_MAGIC_NUMBER "RTLF" +#define RTLF_VERSION 1 +#define RTLF_RECORD_SIZE 80 // 10 x float64 = 80 bytes + +#pragma pack(push, 1) + +// Fixed part of the Header Block (16 bytes) +typedef struct { + char magic_number[4]; // 0-4: 'RTLF' + __uint32_t version; // 4-8: File format version (Must be 1) + __uint32_t car_id; // 8-12: Unique numerical ID + __uint32_t track_name_len;// 12-16: Length of the Track Name string that follows +} RTLF_Header_Fixed; + +// Single Data Record (80 bytes) +typedef struct { + double timestamp; // 0-8: Time (seconds) + double gps_long; // 8-16: Position X (meters) + double gps_lat; // 16-24: Position Y (meters) + double facing_x; // 24-32: X-component of the car's orientation + double facing_y; // 32-40: Y-component of the car's orientation + double facing_z; // 40-48: Z-component of the car's orientation + double acceleration_x; // 48-56: Acceleration X (m/s^2) + double acceleration_y; // 56-64: Acceleration Y (m/s^2) + double acceleration_z; // 64-72: Acceleration Z (m/s^2) + double speed; // 72-80: Speed (m/s) +} RTLF_Data_Record; + +#pragma pack(pop) + +typedef struct { + FILE* file; + RTLF_Header_Fixed header; + char* track_name; + long data_start_offset; +} RTLF_Context; + +RTLF_Context* rtlf_open_write(const char* filename, __uint32_t car_id, const char* track_name); + +int rtlf_write_record(RTLF_Context* ctx, const RTLF_Data_Record* record); + +void rtlf_close(RTLF_Context* ctx); + + +#endif //MCRLCONTROLLER_RTLF_H \ No newline at end of file diff --git a/lib/sd_reader.h b/lib/sd_reader.h new file mode 100644 index 0000000..9852472 --- /dev/null +++ b/lib/sd_reader.h @@ -0,0 +1,33 @@ +#ifndef MCRLCONTROLLER_SD_READER_H +#define MCRLCONTROLLER_SD_READER_H + +#include "ff.h" +#include "gpio_rp2350.h" +#include "posix_io.h" +#include "sd_spi_drv.h" +#include "spi_rp2350.h" +#include "cassert" + +#define MISO_PIN 4 +#define MOSI_PIN 3 +#define SCLK_PIN 6 +#define CS_PIN 5 + +class SD_Reader { + gpio_rp2350 cs; + spi_rp2350 spi; + sd_spi_drv sd; + FatFs fs; +public: + SD_Reader() : cs(CS_PIN), spi(MISO_PIN, MOSI_PIN, SCLK_PIN, cs), sd(spi), fs(sd) { + posix_io::inst.register_fileio(fs); + assert(fs.mount() == FatFs::FR_OK); + } + ~SD_Reader() { + const FatFs::FRESULT erg = fs.umount(); + assert(erg == FatFs::FR_OK); + } +}; + + +#endif //MCRLCONTROLLER_SD_READER_H \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..f1f288e --- /dev/null +++ b/main.cpp @@ -0,0 +1,62 @@ +#define ever (;;) + +#include + +#include "posix_io.h" +#include "uart_rp2350.h" +#include "lib/rtlf.h" +#include "lib/sd_reader.h" + +[[noreturn]] +int main() { + uart_rp2350 uart; + + posix_io::inst.register_stdin(uart); + posix_io::inst.register_stdout(uart); + posix_io::inst.register_stderr(uart); + + printf("Mount SD-Card\n"); + + SD_Reader reader; + + printf("Creating file\n"); + + RTLF_Context* rtlf_ctx = rtlf_open_write("test.rtl", 2, "Nürburgring"); + + printf("Writing to file\n"); + + RTLF_Data_Record data_record_1 = { + .timestamp = 1672531200, + .gps_long = -122.4194, + .gps_lat = 37.7749, + .facing_x = 0.866, + .facing_y = 0.5, + .facing_z = 0.0, + .acceleration_x = 1.2, + .acceleration_y = 0.0, + .acceleration_z = -9.81, + .speed = 15.5 + }; + + RTLF_Data_Record data_record_2 = { + .timestamp = 1672983570, + .gps_long = -122.4594, + .gps_lat = 37.7449, + .facing_x = 0.746, + .facing_y = 0.44, + .facing_z = 0.0, + .acceleration_x = 1.3, + .acceleration_y = 0.0, + .acceleration_z = -9.81, + .speed = 15.9 + }; + + rtlf_write_record(rtlf_ctx, &data_record_1); + rtlf_write_record(rtlf_ctx, &data_record_2); + + printf("Close connection\n"); + + rtlf_close(rtlf_ctx); + + printf("Done\n"); +}