Skip to content

Commit 9c19a68

Browse files
committed
mmc card: store current mmc card state is backup ram
So we can track power offs with unmounted card.
1 parent 0aa85ab commit 9c19a68

2 files changed

Lines changed: 92 additions & 15 deletions

File tree

firmware/hw_layer/mmc_card.cpp

Lines changed: 91 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "hellen_meta.h"
4141

4242
#include "rtc_helper.h"
43+
#include "backup_ram.h"
4344

4445
#if EFI_STORAGE_SD == TRUE
4546
#include "storage_sd.h"
@@ -59,7 +60,7 @@ extern int errorHandlerCheckReportFiles();
5960
extern void errorHandlerDeleteReports();
6061

6162
// see also SD_MODE
62-
typedef enum {
63+
typedef enum : uint8_t {
6364
SD_STATUS_INIT = 0,
6465
SD_STATUS_MOUNTED,
6566
SD_STATUS_MOUNT_FAILED,
@@ -86,7 +87,10 @@ static const char *sdStatusNames[] =
8687
};
8788

8889
static const char *sdStatusName(SD_STATUS status) {
89-
return sdStatusNames[status];
90+
if ((uint8_t)status < efi::size(sdStatusNames)) {
91+
return sdStatusNames[status];
92+
}
93+
return "INVALID";
9094
}
9195

9296
static const char *sdModeNames[] =
@@ -99,7 +103,10 @@ static const char *sdModeNames[] =
99103
};
100104

101105
static const char *sdModeName(SD_MODE mode) {
102-
return sdModeNames[mode];
106+
if ((uint8_t)mode < efi::size(sdModeNames)) {
107+
return sdModeNames[mode];
108+
}
109+
return "INVALID";
103110
}
104111

105112
static bool sdLoggerReady = false;
@@ -153,6 +160,70 @@ static MMCConfig mmccfg = {
153160
*/
154161
static NO_CACHE FATFS MMC_FS;
155162

163+
union SdBackupState {
164+
struct {
165+
SD_MODE mode;
166+
SD_STATUS status;
167+
uint8_t unsafeUnmountCnt;
168+
uint8_t valid;
169+
} __attribute__((packed));
170+
uint32_t x;
171+
};
172+
173+
static_assert(sizeof(SdBackupState) == sizeof(uint32_t));
174+
175+
static void sdCardUpdateBackupState() {
176+
SdBackupState state;
177+
state.x = backupRamLoad(backup_ram_e::MccStatus);
178+
state.mode = sdMode;
179+
state.status = sdStatus;
180+
state.valid = 0x5A;
181+
backupRamSave(backup_ram_e::MccStatus, state.x);
182+
}
183+
184+
static void sdCardShowBackupState() {
185+
SdBackupState state;
186+
state.x = backupRamLoad(backup_ram_e::MccStatus);
187+
188+
efiPrintf("SD state at last power off %s / %s", sdModeName(state.mode), sdStatusName(state.status));
189+
efiPrintf("total unsafe power offs %d", state.unsafeUnmountCnt);
190+
}
191+
192+
static bool sdCardInitBackupState() {
193+
SdBackupState state;
194+
state.x = backupRamLoad(backup_ram_e::MccStatus);
195+
196+
bool valid = state.valid == 0x5A;
197+
if (valid) {
198+
if ((state.mode != SD_MODE_IDLE) && (state.mode != SD_MODE_UNMOUNT)) {
199+
if (state.unsafeUnmountCnt < 255) {
200+
state.unsafeUnmountCnt++;
201+
}
202+
}
203+
} else {
204+
state.mode = SD_MODE_IDLE;
205+
state.status = SD_STATUS_INIT;
206+
state.unsafeUnmountCnt = 0;
207+
state.valid = 0x5A;
208+
}
209+
210+
backupRamSave(backup_ram_e::MccStatus, state.x);
211+
212+
return valid;
213+
}
214+
215+
static void sdCardSetCurrentMode(SD_MODE mode) {
216+
sdMode = mode;
217+
218+
sdCardUpdateBackupState();
219+
}
220+
221+
static void sdSetCurrentStatus(SD_STATUS status) {
222+
sdStatus = status;
223+
224+
sdCardUpdateBackupState();
225+
}
226+
156227
static void sdLoggerSetReady(bool value) {
157228
#if EFI_TUNER_STUDIO
158229
engine->outputChannels.sd_logging_internal = value;
@@ -304,7 +375,7 @@ static int sdLoggerCreateFile(FIL *fd) {
304375
engine->outputChannels.sd_error = (uint8_t)err;
305376
#endif
306377
if (err != FR_OK) {
307-
sdStatus = SD_STATUS_OPEN_FAILED;
378+
sdSetCurrentStatus(SD_STATUS_OPEN_FAILED);
308379
warning(ObdCode::CUSTOM_ERR_SD_MOUNT_FAILED, "SD: file open failed");
309380
printFatFsError("log file create", err);
310381
return -1;
@@ -396,7 +467,7 @@ static BaseBlockDevice* initializeMmcBlockDevice() {
396467
// Performs the initialization procedure on the inserted card.
397468
LOCK_SD_SPI();
398469
if (blkConnect(&MMCD1) != HAL_SUCCESS) {
399-
sdStatus = SD_STATUS_MMC_FAILED;
470+
sdSetCurrentStatus(SD_STATUS_MMC_FAILED);
400471
UNLOCK_SD_SPI();
401472
return nullptr;
402473
}
@@ -726,7 +797,7 @@ static int sdModeSwitchToIdle(SD_MODE from)
726797
case SD_MODE_ECU:
727798
sdLoggerStop();
728799
unmountMmc();
729-
sdStatus = SD_STATUS_INIT;
800+
sdSetCurrentStatus(SD_STATUS_INIT);
730801
return 0;
731802
case SD_MODE_PC:
732803
deattachMsdSdCard();
@@ -799,23 +870,23 @@ static SD_MODE sdModeSwitcher(SD_MODE mode, SD_MODE target) {
799870
return target;
800871
case SD_MODE_ECU:
801872
if (mountMmc()) {
802-
sdStatus = SD_STATUS_MOUNTED;
873+
sdSetCurrentStatus(SD_STATUS_MOUNTED);
803874
sdLoggerStart();
804875
return SD_MODE_ECU;
805876
} else {
806-
sdStatus = SD_STATUS_MOUNT_FAILED;
877+
sdSetCurrentStatus(SD_STATUS_MOUNT_FAILED);
807878
// failed to mount SD card to ECU, go to idle
808879
return SD_MODE_IDLE;
809880
}
810881
case SD_MODE_PC:
811882
attachMsdSdCard(cardBlockDevice, resources.blkbuf, sizeof(resources.blkbuf));
812-
sdStatus = SD_STATUS_MSD;
883+
sdSetCurrentStatus(SD_STATUS_MSD);
813884
return SD_MODE_PC;
814885
case SD_MODE_FORMAT:
815886
if (sdFormat()) {
816887
// formated ok
817888
}
818-
sdStatus = SD_STATUS_INIT;
889+
sdSetCurrentStatus(SD_STATUS_INIT);
819890
return SD_MODE_IDLE;
820891
}
821892

@@ -890,10 +961,16 @@ static THD_FUNCTION(MMCmonThread, arg) {
890961
chThdSleepMilliseconds(100);
891962
}
892963

893-
sdStatus = SD_STATUS_CONNECTING;
964+
if (sdCardInitBackupState()) {
965+
sdCardShowBackupState();
966+
} else {
967+
efiPrintf("SD backup RAM state is not valid");
968+
}
969+
970+
sdSetCurrentStatus(SD_STATUS_CONNECTING);
894971
if (!initMmc()) {
895972
efiPrintf("Card is not preset/failed to init");
896-
sdStatus = SD_STATUS_NOT_INSERTED;
973+
sdSetCurrentStatus(SD_STATUS_NOT_INSERTED);
897974
// give up until next boot
898975
goto die;
899976
}
@@ -924,11 +1001,11 @@ static THD_FUNCTION(MMCmonThread, arg) {
9241001
efiPrintf("SD: failed to switch from %s to %s", sdModeName(sdMode), sdModeName(target));
9251002
// TODO: handle
9261003
chThdSleepMilliseconds(1000);
927-
sdMode = SD_MODE_IDLE;
1004+
sdCardSetCurrentMode(SD_MODE_IDLE);
9281005
} else {
9291006
efiPrintf("SD: switched from %s to %s", sdModeName(sdMode), sdModeName(target));
9301007
}
931-
sdMode = target;
1008+
sdCardSetCurrentMode(target);
9321009
}
9331010

9341011
if (sdModeExecuter(sdMode) == 0) {

firmware/hw_layer/mmc_card.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#define DOT_MLG ".mlg"
1515

1616
// see also SD_STATUS
17-
typedef enum {
17+
typedef enum : uint8_t {
1818
SD_MODE_IDLE = 0,
1919
SD_MODE_ECU,
2020
SD_MODE_PC,

0 commit comments

Comments
 (0)