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();
5960extern 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
8889static 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
9296static const char *sdModeNames[] =
@@ -99,7 +103,10 @@ static const char *sdModeNames[] =
99103};
100104
101105static 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
105112static bool sdLoggerReady = false ;
@@ -153,6 +160,70 @@ static MMCConfig mmccfg = {
153160 */
154161static 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+
156227static 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 ) {
0 commit comments