Skip to content
Draft
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
3 changes: 2 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
48 changes: 48 additions & 0 deletions src/sdcard/sdcard.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
*/
Comment on lines +147 to +150
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;
}
16 changes: 16 additions & 0 deletions src/sdcard/sdcard.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Comment on lines +109 to +113
response_t SDCARD_standalone_check(void);

#endif // _SDCARD_H
14 changes: 14 additions & 0 deletions src/states.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions src/states.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ extern "C" {
typedef enum {
STATE_STANDBY,
STATE_RUNCOMMAND,
STATE_STANDALONE,
NUM_STATES
} state_t;

Expand Down
Loading