From 2179a874d171755a0bf2b5447d8572317f5e90bb Mon Sep 17 00:00:00 2001 From: Padmal Date: Mon, 6 Jul 2026 21:54:29 +0200 Subject: [PATCH 1/2] feat: state path to switch into standalone mode --- src/main.c | 3 ++- src/sdcard/sdcard.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ src/sdcard/sdcard.h | 11 ++++++++++ src/states.c | 13 ++++++++++++ src/states.h | 1 + 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 3f63b142..c90c970e 100644 --- a/src/main.c +++ b/src/main.c @@ -1,11 +1,12 @@ #include "registers/system/system.h" #include "states.h" +#include "sdcard/sdcard.h" int main(void) { SYSTEM_Initialize(); - state_t current_state = STATE_STANDBY; + state_t current_state = SDCARD_standalone_check() == SUCCESS ? STATE_STANDALONE : STATE_STANDBY; while (1) { current_state = STATES_RunState(current_state); diff --git a/src/sdcard/sdcard.c b/src/sdcard/sdcard.c index d52c3eac..9a2cd1f0 100644 --- a/src/sdcard/sdcard.c +++ b/src/sdcard/sdcard.c @@ -15,7 +15,9 @@ #define FILENAME_SIZE (SFN_MAX + SFN_SUFFIX_LEN + 1) #define BUF_MAX FF_MIN_SS #define SDCARD_DRIVE "0:" +#define CONFIG_FILENAME "PSLAB.CFG" +static bool s_mounted = false; static TCHAR s_sector_buf[BUF_MAX]; _Static_assert( sizeof(s_sector_buf) == 512, @@ -141,3 +143,51 @@ response_t SDCARD_get_file_info(void) return SUCCESS; } + +/** + * @brief Read the configuration file from the SD card. + * @return true if the config file was read successfully, false otherwise or if the config structure is invalid. + */ +static bool read_config_file(void) { + FIL file; + if (f_open(&file, CONFIG_FILENAME, FA_READ) != FR_OK) { + return false; + } + + TCHAR buf[6] = {0}; // Config file should have a magic header of 5 bytes + UINT bytes_read = 0; + if (f_read(&file, buf, sizeof buf - 1, &bytes_read) != FR_OK + || bytes_read != sizeof buf - 1) { + f_close(&file); + return false; + } + f_close(&file); + + return true; +} + +response_t SDCARD_standalone_check(void) { + if (!SD_SPI_IsMediaPresent()) { + return FAILED; + } + + FATFS drive; + if (f_mount(&drive, SDCARD_DRIVE, 1) != FR_OK) { + return FAILED; + } + s_mounted = true; + + if (!read_config_file()) { + SDCARD_standalone_unmount(); + return FAILED; + } + + return SUCCESS; +} + +void SDCARD_standalone_unmount(void) { + if (s_mounted) { + f_mount(0, SDCARD_DRIVE, 0); + s_mounted = false; + } +} \ No newline at end of file diff --git a/src/sdcard/sdcard.h b/src/sdcard/sdcard.h index 37f9df30..22194568 100644 --- a/src/sdcard/sdcard.h +++ b/src/sdcard/sdcard.h @@ -97,4 +97,15 @@ response_t SDCARD_read_file(void); */ response_t SDCARD_get_file_info(void); +/** + * @brief Check if SD-card is present and can be mounted. + * + * @details Checks if the SD-card can be mounted and if the configuration file is present and valid. + * If the configuration file is not present or invalid, or if the SD-card is not mounted, the function returns FAILED. + * The configuration file is expected to be named "PSLAB.CFG" and contain a magic header of 5 bytes with a null terminator. + * + * @return SUCCESS + */ +response_t SDCARD_standalone_check(void); + #endif // _SDCARD_H diff --git a/src/states.c b/src/states.c index fd93812c..c7248d56 100644 --- a/src/states.c +++ b/src/states.c @@ -36,9 +36,22 @@ state_t RunCommand(void) { return STATE_STANDBY; } +/** + * @brief Run in standalone mode until serial traffic is detected. + * @return STATE_STANDALONE or STATE_RUNCOMMAND if serial traffic is detected. + */ +state_t Standalone(void) { + if (UART_IsRxReady(U1SELECT)) { + return STATE_RUNCOMMAND; + } + + return STATE_STANDALONE; +} + state_func_t* const state_table[NUM_STATES] = { Standby, RunCommand, + Standalone, }; state_t STATES_RunState(state_t current_state) { diff --git a/src/states.h b/src/states.h index 547cfacf..12dcffc7 100644 --- a/src/states.h +++ b/src/states.h @@ -16,6 +16,7 @@ extern "C" { typedef enum { STATE_STANDBY, STATE_RUNCOMMAND, + STATE_STANDALONE, NUM_STATES } state_t; From 43579b9fa2de199100617b86d120efd22372ece9 Mon Sep 17 00:00:00 2001 From: Padmal Date: Mon, 6 Jul 2026 22:40:07 +0200 Subject: [PATCH 2/2] fix: copilot reviews --- src/sdcard/sdcard.c | 28 +++++++++++++--------------- src/sdcard/sdcard.h | 5 +++++ src/states.c | 5 +++-- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/sdcard/sdcard.c b/src/sdcard/sdcard.c index 9a2cd1f0..f9aaa194 100644 --- a/src/sdcard/sdcard.c +++ b/src/sdcard/sdcard.c @@ -163,7 +163,14 @@ static bool read_config_file(void) { } f_close(&file); - return true; + return (buf[0] == 'P' && buf[1] == 'S' && buf[2] == 'L' && buf[3] == 'A' && buf[4] == 'B'); +} + +void SDCARD_standalone_unmount(void) { + if (s_mounted) { + f_mount(0, SDCARD_DRIVE, 0); + s_mounted = false; + } } response_t SDCARD_standalone_check(void) { @@ -171,23 +178,14 @@ response_t SDCARD_standalone_check(void) { return FAILED; } - FATFS drive; + static FATFS drive; if (f_mount(&drive, SDCARD_DRIVE, 1) != FR_OK) { + s_mounted = false; return FAILED; } s_mounted = true; - if (!read_config_file()) { - SDCARD_standalone_unmount(); - return FAILED; - } - - return SUCCESS; -} - -void SDCARD_standalone_unmount(void) { - if (s_mounted) { - f_mount(0, SDCARD_DRIVE, 0); - s_mounted = false; - } + bool ok = read_config_file(); + SDCARD_standalone_unmount(); + return ok ? SUCCESS : FAILED; } \ No newline at end of file diff --git a/src/sdcard/sdcard.h b/src/sdcard/sdcard.h index 22194568..fbf2a0fb 100644 --- a/src/sdcard/sdcard.h +++ b/src/sdcard/sdcard.h @@ -97,6 +97,11 @@ response_t SDCARD_read_file(void); */ response_t SDCARD_get_file_info(void); +/** + * @brief Unmount SD-card after standalone configuration checks. + */ +void SDCARD_standalone_unmount(void); + /** * @brief Check if SD-card is present and can be mounted. * diff --git a/src/states.c b/src/states.c index c7248d56..c73b881b 100644 --- a/src/states.c +++ b/src/states.c @@ -43,8 +43,9 @@ state_t RunCommand(void) { state_t Standalone(void) { if (UART_IsRxReady(U1SELECT)) { return STATE_RUNCOMMAND; - } - + } + + WATCHDOG_TimerClear(); return STATE_STANDALONE; }