diff --git a/src/main.c b/src/main.c index 3f63b14..c90c970 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 d52c3ea..f9aaa19 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,49 @@ 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 (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) { + if (!SD_SPI_IsMediaPresent()) { + return FAILED; + } + + static FATFS drive; + if (f_mount(&drive, SDCARD_DRIVE, 1) != FR_OK) { + s_mounted = false; + return FAILED; + } + s_mounted = true; + + 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 37f9df3..fbf2a0f 100644 --- a/src/sdcard/sdcard.h +++ b/src/sdcard/sdcard.h @@ -97,4 +97,20 @@ 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. + * + * @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 fd93812..c73b881 100644 --- a/src/states.c +++ b/src/states.c @@ -36,9 +36,23 @@ 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; + } + + WATCHDOG_TimerClear(); + 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 547cfac..12dcffc 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;