rusEFI
The most advanced open source ECU
mmc_card.cpp
Go to the documentation of this file.
1 /**
2  * @file mmc_card.cpp
3  *
4  * @date Dec 28, 2013
5  * @author Kot_dnz
6  * @author Andrey Belomutskiy, (c) 2012-2020
7  *
8  * default pinouts in case of SPI2 connected to MMC: PB13 - SCK, PB14 - MISO, PB15 - MOSI, PD4 - CS, 3.3v
9  * default pinouts in case of SPI3 connected to MMC: PB3 - SCK, PB4 - MISO, PB5 - MOSI, PD4 - CS, 3.3v
10  *
11  *
12  * todo: extract some logic into a controller file
13  */
14 
15 #include "pch.h"
16 
17 #if EFI_FILE_LOGGING
18 
19 #include "buffered_writer.h"
20 #include "status_loop.h"
21 #include "binary_logging.h"
22 
23 static bool fs_ready = false;
24 
25 #if EFI_PROD_CODE
26 
28 static int fileCreatedCounter = 0;
29 static int writeCounter = 0;
30 static int totalWritesCounter = 0;
31 static int totalSyncCounter = 0;
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include "mmc_card.h"
36 #include "ff.h"
37 #include "mass_storage_init.h"
38 #include "hellen_meta.h"
39 
40 #include "rtc_helper.h"
41 
42 #define SD_STATE_INIT "init"
43 #define SD_STATE_MOUNTED "MOUNTED"
44 #define SD_STATE_MOUNT_FAILED "MOUNT_FAILED"
45 #define SD_STATE_OPEN_FAILED "OPEN_FAILED"
46 #define SD_STATE_SEEK_FAILED "SEEK_FAILED"
47 #define SD_STATE_NOT_INSERTED "NOT_INSERTED"
48 #define SD_STATE_CONNECTING "CONNECTING"
49 #define SD_STATE_MSD "MSD"
50 #define SD_STATE_NOT_CONNECTED "NOT_CONNECTED"
51 #define SD_STATE_MMC_FAILED "MMC_CONNECT_FAILED"
52 
53 // todo: shall we migrate to enum with enum2string for consistency? maybe not until we start reading sdStatus?
54 static const char *sdStatus = SD_STATE_INIT;
55 
56 // at about 20Hz we write about 2Kb per second, looks like we flush once every ~2 seconds
57 #define F_SYNC_FREQUENCY 10
58 
59 /**
60  * on't re-read SD card spi device after boot - it could change mid transaction (TS thread could preempt),
61  * which will cause disaster (usually multiple-unlock of the same mutex in UNLOCK_SD_SPI)
62  */
63 static spi_device_e mmcSpiDevice = SPI_NONE;
64 
65 #define LOG_INDEX_FILENAME "index.txt"
66 
67 #define RUSEFI_LOG_PREFIX "re_"
68 #define PREFIX_LEN 3
69 #define SHORT_TIME_LEN 13
70 
71 #define LS_RESPONSE "ls_result"
72 #define FILE_LIST_MAX_COUNT 20
73 
74 #if HAL_USE_MMC_SPI
75 /**
76  * MMC driver instance.
77  */
78 MMCDriver MMCD1;
79 
80 /* MMC/SD over SPI driver configuration.*/
81 static MMCConfig mmccfg = { NULL, &mmc_ls_spicfg, &mmc_hs_spicfg };
82 
83 #if MMC_USE_MUTUAL_EXCLUSION == TRUE
84 #define LOCK_SD_SPI()
85 #define UNLOCK_SD_SPI()
86 #else
87 #define LOCK_SD_SPI() lockSpi(mmcSpiDevice)
88 #define UNLOCK_SD_SPI() unlockSpi(mmcSpiDevice)
89 #endif
90 
91 #endif /* HAL_USE_MMC_SPI */
92 
93 /**
94  * fatfs MMC/SPI
95  */
96 static NO_CACHE FATFS MMC_FS;
97 
98 static int fatFsErrors = 0;
99 
100 static void mmcUnMount();
101 
102 static void setSdCardReady(bool value) {
103  fs_ready = value;
104 }
105 
106 // print FAT error function
107 static void printError(const char *str, FRESULT f_error) {
108  if (fatFsErrors++ > 16) {
109  // no reason to spam the console
110  return;
111  }
112 
113  efiPrintf("FATfs Error \"%s\" %d", str, f_error);
114 }
115 
116 static FIL FDLogFile NO_CACHE;
117 
118 // 10 because we want at least 4 character name
119 #define MIN_FILE_INDEX 10
120 static int logFileIndex = MIN_FILE_INDEX;
121 static char logName[_MAX_FILLER + 20];
122 
123 static void printMmcPinout() {
124  efiPrintf("MMC CS %s", hwPortname(engineConfiguration->sdCardCsPin));
125  // todo: we need to figure out the right SPI pinout, not just SPI2
126 // efiPrintf("MMC SCK %s:%d", portname(EFI_SPI2_SCK_PORT), EFI_SPI2_SCK_PIN);
127 // efiPrintf("MMC MISO %s:%d", portname(EFI_SPI2_MISO_PORT), EFI_SPI2_MISO_PIN);
128 // efiPrintf("MMC MOSI %s:%d", portname(EFI_SPI2_MOSI_PORT), EFI_SPI2_MOSI_PIN);
129 }
130 
131 static void sdStatistics() {
132  printMmcPinout();
133  efiPrintf("SD enabled=%s status=%s", boolToString(engineConfiguration->isSdCardEnabled),
134  sdStatus);
136  if (isSdCardAlive()) {
137  efiPrintf("filename=%s size=%d", logName, totalLoggedBytes);
138  }
139 }
140 
141 static void incLogFileName() {
142  memset(&FDLogFile, 0, sizeof(FIL)); // clear the memory
143  FRESULT err = f_open(&FDLogFile, LOG_INDEX_FILENAME, FA_READ); // This file has the index for next log file name
144 
145  char data[_MAX_FILLER];
146  UINT result = 0;
147  if (err != FR_OK && err != FR_EXIST) {
148  logFileIndex = MIN_FILE_INDEX;
149  efiPrintf("%s: not found or error: %d", LOG_INDEX_FILENAME, err);
150  } else {
151  f_read(&FDLogFile, (void*)data, sizeof(data), &result);
152 
153  efiPrintf("Got content [%s] size %d", data, result);
154  f_close(&FDLogFile);
155  if (result < 5) {
156  data[result] = 0;
157  logFileIndex = maxI(MIN_FILE_INDEX, atoi(data));
158  if (absI(logFileIndex) == ATOI_ERROR_CODE) {
159  logFileIndex = MIN_FILE_INDEX;
160  } else {
161  logFileIndex++; // next file would use next file name
162  }
163  } else {
164  logFileIndex = MIN_FILE_INDEX;
165  }
166  }
167 
168  err = f_open(&FDLogFile, LOG_INDEX_FILENAME, FA_OPEN_ALWAYS | FA_WRITE);
169  itoa10(data, logFileIndex);
170  f_write(&FDLogFile, (void*)data, strlen(data), &result);
171  f_close(&FDLogFile);
172  efiPrintf("Done %d", logFileIndex);
173 }
174 
175 static void prepareLogFileName() {
176  strcpy(logName, RUSEFI_LOG_PREFIX);
177  char *ptr;
178 
179 #if HAL_USE_USB_MSD
180  bool result = dateToStringShort(&logName[PREFIX_LEN]);
181 #else
182  // TS SD protocol supports only short 8 symbol file names :(
183  bool result = false;
184 #endif
185 
186  if (result) {
187  ptr = &logName[PREFIX_LEN + SHORT_TIME_LEN];
188  } else {
189  ptr = itoa10(&logName[PREFIX_LEN], logFileIndex);
190  }
191 
193  strcat(ptr, ".teeth");
194  } else {
195  strcat(ptr, DOT_MLG);
196  }
197 }
198 
199 /**
200  * @brief Create a new file with the specified name
201  *
202  * This function saves the name of the file in a global variable
203  * so that we can later append to that file
204  */
205 static void createLogFile() {
206  memset(&FDLogFile, 0, sizeof(FIL)); // clear the memory
208 
209  FRESULT err = f_open(&FDLogFile, logName, FA_OPEN_ALWAYS | FA_WRITE); // Create new file
210  if (err != FR_OK && err != FR_EXIST) {
211  sdStatus = SD_STATE_OPEN_FAILED;
212  warning(ObdCode::CUSTOM_ERR_SD_MOUNT_FAILED, "SD: mount failed");
213  printError("FS mount failed", err); // else - show error
214  return;
215  }
216 
217  err = f_lseek(&FDLogFile, f_size(&FDLogFile)); // Move to end of the file to append data
218  if (err) {
219  sdStatus = SD_STATE_SEEK_FAILED;
220  warning(ObdCode::CUSTOM_ERR_SD_SEEK_FAILED, "SD: seek failed");
221  printError("Seek error", err);
222  return;
223  }
224  f_sync(&FDLogFile);
225  setSdCardReady(true); // everything Ok
226 }
227 
228 static void removeFile(const char *pathx) {
229  if (!isSdCardAlive()) {
230  efiPrintf("Error: No File system is mounted");
231  return;
232  }
233 
234  f_unlink(pathx);
235 }
236 
237 int mystrncasecmp(const char *s1, const char *s2, size_t n) {
238  if (n != 0) {
239  const char *us1 = (const char *)s1;
240  const char *us2 = (const char *)s2;
241 
242  do {
243  if (mytolower(*us1) != mytolower(*us2))
244  return (mytolower(*us1) - mytolower(*us2));
245  if (*us1++ == '\0')
246  break;
247  us2++;
248  } while (--n != 0);
249  }
250  return (0);
251  }
252 
253 static void listDirectory(const char *path) {
254 
255  if (!isSdCardAlive()) {
256  efiPrintf("Error: No File system is mounted");
257  return;
258  }
259 
260  DIR dir;
261  FRESULT res = f_opendir(&dir, path);
262 
263  if (res != FR_OK) {
264  efiPrintf("Error opening directory %s", path);
265  return;
266  }
267 
268  efiPrintf(LS_RESPONSE);
269 
270  for (int count = 0;count < FILE_LIST_MAX_COUNT;) {
271  FILINFO fno;
272 
273  res = f_readdir(&dir, &fno);
274  if (res != FR_OK || fno.fname[0] == 0) {
275  break;
276  }
277  if (fno.fname[0] == '.') {
278  continue;
279  }
280  if ((fno.fattrib & AM_DIR) || mystrncasecmp(RUSEFI_LOG_PREFIX, fno.fname, sizeof(RUSEFI_LOG_PREFIX) - 1)) {
281  continue;
282  }
283  efiPrintf("logfile%lu:%s", fno.fsize, fno.fname);
284  count++;
285 
286 // efiPrintf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %-12s", (fno.fattrib & AM_DIR) ? 'D' : '-',
287 // (fno.fattrib & AM_RDO) ? 'R' : '-', (fno.fattrib & AM_HID) ? 'H' : '-',
288 // (fno.fattrib & AM_SYS) ? 'S' : '-', (fno.fattrib & AM_ARC) ? 'A' : '-', (fno.fdate >> 9) + 1980,
289 // (fno.fdate >> 5) & 15, fno.fdate & 31, (fno.ftime >> 11), (fno.ftime >> 5) & 63, fno.fsize,
290 // fno.fname);
291  }
292 }
293 
294 /*
295  * MMC card un-mount.
296  */
297 static void mmcUnMount() {
298  if (!isSdCardAlive()) {
299  efiPrintf("Error: No File system is mounted. \"mountsd\" first");
300  return;
301  }
302  f_close(&FDLogFile); // close file
303  f_sync(&FDLogFile); // sync ALL
304 
305 #if HAL_USE_MMC_SPI
306  blkDisconnect(&MMCD1); // Brings the driver in a state safe for card removal.
307  mmcStop(&MMCD1); // Disables the MMC peripheral.
308  UNLOCK_SD_SPI();
309 #endif
310 #ifdef EFI_SDC_DEVICE
311  blkDisconnect(&EFI_SDC_DEVICE);
312  sdcStop(&EFI_SDC_DEVICE);
313 #endif
314  f_mount(NULL, 0, 0); // FATFS: Unregister work area prior to discard it
315  memset(&FDLogFile, 0, sizeof(FIL)); // clear FDLogFile
316  setSdCardReady(false); // status = false
317  efiPrintf("MMC/SD card removed");
318 }
319 
320 #if HAL_USE_USB_MSD
321 
322 static chibios_rt::BinarySemaphore usbConnectedSemaphore(/* taken =*/ true);
323 
325  usbConnectedSemaphore.signalI();
326 }
327 
328 #endif /* HAL_USE_USB_MSD */
329 
330 #if HAL_USE_MMC_SPI
331 /*
332  * Attempts to initialize the MMC card.
333  * Returns a BaseBlockDevice* corresponding to the SD card if successful, otherwise nullptr.
334  */
335 static BaseBlockDevice* initializeMmcBlockDevice() {
336  // Don't try to mount SD card in case of fatal error - hardware may be in an unexpected state
337  if (hasFirmwareError()) {
338  return nullptr;
339  }
340 
342  engineConfiguration->sdCardSpiDevice == SPI_NONE ||
344  return nullptr;
345  }
346 
347  // Configures and activates the MMC peripheral.
349 
350  // todo: reuse initSpiCs method?
354 
355  // Invalid SPI device, abort.
356  if (!mmccfg.spip) {
357  return nullptr;
358  }
359 
360  // We think we have everything for the card, let's try to mount it!
361  mmcObjectInit(&MMCD1);
362  mmcStart(&MMCD1, &mmccfg);
363 
364  // Performs the initialization procedure on the inserted card.
365  LOCK_SD_SPI();
366  sdStatus = SD_STATE_CONNECTING;
367  if (blkConnect(&MMCD1) != HAL_SUCCESS) {
368  sdStatus = SD_STATE_MMC_FAILED;
369  UNLOCK_SD_SPI();
370  return nullptr;
371  }
372  // We intentionally never unlock in case of success, we take exclusive access of that spi device for SD use
373 
374  return reinterpret_cast<BaseBlockDevice*>(&MMCD1);
375 }
376 #endif /* HAL_USE_MMC_SPI */
377 
378 #ifndef RE_SDC_MODE
379 #define RE_SDC_MODE SDC_MODE_4BIT
380 #endif // RE_SDC_MODE
381 
382 // Some ECUs are wired for SDIO/SDMMC instead of SPI
383 #ifdef EFI_SDC_DEVICE
384 static const SDCConfig sdcConfig = {
385  RE_SDC_MODE
386 };
387 
388 static BaseBlockDevice* initializeMmcBlockDevice() {
390  return nullptr;
391  }
392 
393  sdcStart(&EFI_SDC_DEVICE, &sdcConfig);
394  sdStatus = SD_STATE_CONNECTING;
395  if (blkConnect(&EFI_SDC_DEVICE) != HAL_SUCCESS) {
396  sdStatus = SD_STATE_NOT_CONNECTED;
397  return nullptr;
398  }
399 
400  return reinterpret_cast<BaseBlockDevice*>(&EFI_SDC_DEVICE);
401 }
402 #endif /* EFI_SDC_DEVICE */
403 
404 // Initialize and mount the SD card.
405 // Returns true if the filesystem was successfully mounted for writing.
406 static bool mountMmc() {
407  auto cardBlockDevice = initializeMmcBlockDevice();
408 
409 #if EFI_TUNER_STUDIO
410  // If not null, card is present
411  engine->outputChannels.sd_present = cardBlockDevice != nullptr;
412 #endif
413 
414 #if HAL_USE_USB_MSD
415  // Wait for the USB stack to wake up, or a 15 second timeout, whichever occurs first
416  msg_t usbResult = usbConnectedSemaphore.wait(TIME_MS2I(15000));
417 
418  bool hasUsb = usbResult == MSG_OK;
419 
420  // If we have a device AND USB is connected, mount the card to USB, otherwise
421  // mount the null device and try to mount the filesystem ourselves
422  if (cardBlockDevice && hasUsb) {
423  // Mount the real card to USB
424  attachMsdSdCard(cardBlockDevice);
425 
426  sdStatus = SD_STATE_MSD;
427  // At this point we're done: don't try to write files ourselves
428  return false;
429  }
430 #endif
431 
432  // if no card, don't try to mount FS
433  if (!cardBlockDevice) {
434  return false;
435  }
436 
437  // We were able to connect the SD card, mount the filesystem
438  memset(&MMC_FS, 0, sizeof(FATFS));
439  if (f_mount(&MMC_FS, "/", 1) == FR_OK) {
440  sdStatus = SD_STATE_MOUNTED;
441  incLogFileName();
442  createLogFile();
444  efiPrintf("MMC/SD mounted!");
445  return true;
446  } else {
447  sdStatus = SD_STATE_MOUNT_FAILED;
448  return false;
449  }
450 }
451 
452 struct SdLogBufferWriter final : public BufferedWriter<512> {
453  bool failed = false;
454 
455  size_t writeInternal(const char* buffer, size_t count) override {
456  size_t bytesWritten;
457 
458  totalLoggedBytes += count;
459 
460  FRESULT err = f_write(&FDLogFile, buffer, count, &bytesWritten);
461 
462  if (bytesWritten != count) {
463  printError("write error or disk full", err);
464 
465  // Close file and unmount volume
466  mmcUnMount();
467  failed = true;
468  return 0;
469  } else {
470  writeCounter++;
472  if (writeCounter >= F_SYNC_FREQUENCY) {
473  /**
474  * Performance optimization: not f_sync after each line, f_sync is probably a heavy operation
475  * todo: one day someone should actually measure the relative cost of f_sync
476  */
477  f_sync(&FDLogFile);
479  writeCounter = 0;
480  }
481  }
482 
483  return bytesWritten;
484  }
485 };
486 
487 #else // not EFI_PROD_CODE (simulator)
488 
489 #include <fstream>
490 
491 bool mountMmc() {
492  // Stub so the loop thinks the MMC mounted OK
493  return true;
494 }
495 
496 class SdLogBufferWriter final : public BufferedWriter<512> {
497 public:
498  bool failed = false;
499 
500  SdLogBufferWriter()
501  : m_stream("rusefi_simulator_log.mlg", std::ios::binary | std::ios::trunc)
502  {
503  fs_ready = true;
504  }
505 
506  size_t writeInternal(const char* buffer, size_t count) override {
507  m_stream.write(buffer, count);
508  m_stream.flush();
509  return count;
510  }
511 
512 private:
513  std::ofstream m_stream;
514 };
515 
516 #endif // EFI_PROD_CODE
517 
518 static NO_CACHE SdLogBufferWriter logBuffer;
519 
520 // Log 'regular' ECU log to MLG file
521 static void mlgLogger();
522 
523 // Log binary trigger log
524 static void sdTriggerLogger();
525 
526 static THD_WORKING_AREA(mmcThreadStack, 3 * UTILITY_THREAD_STACK_SIZE); // MMC monitor thread
527 static THD_FUNCTION(MMCmonThread, arg) {
528  (void)arg;
529  chRegSetThreadName("MMC Card Logger");
530 
531 #if HW_HELLEN && EFI_PROD_CODE
532  // on mega-module we manage SD card power supply
533  while (!getHellenBoardEnabled()) {
534  // wait until board enables peripheral
535  chThdSleepMilliseconds(100);
536  if (getTimeNowS() > 4 && !isIgnVoltage()) {
537  // looks like vehicle is OFF and we are hooked to USB - turn on peripheral to get Mass Storage Device USB profile
538  efiPrintf(" *** turning board ON to power SD card ***");
539  hellenEnableEn();
540  break;
541  }
542  }
543  chThdSleepMilliseconds(300);
544 #endif
545 
546  if (!mountMmc()) {
547  // no card present (or mounted via USB), don't do internal logging
548  return;
549  }
550 
551  #if EFI_TUNER_STUDIO
553  #endif
554 
556  sdTriggerLogger();
557  } else {
558  mlgLogger();
559  }
560 }
561 
562 void mlgLogger() {
563  while (true) {
564  // if the SPI device got un-picked somehow, cancel SD card
565  // Don't do this check at all if using SDMMC interface instead of SPI
566 #if EFI_PROD_CODE && !defined(EFI_SDC_DEVICE)
567  if (engineConfiguration->sdCardSpiDevice == SPI_NONE) {
568  return;
569  }
570 #endif
571 
572 
574 
575  // Something went wrong (already handled), so cancel further writes
576  if (logBuffer.failed) {
577  return;
578  }
579 
581  if (freq > 250) {
582  freq = 250;
583  } else if (freq < 1) {
584  freq = 1;
585  }
586 
587  auto period = 1e6 / freq;
588  chThdSleepMicroseconds((int)period);
589  }
590 }
591 
592 static void sdTriggerLogger() {
593 #if EFI_TOOTH_LOGGER
595 
596  while (true) {
598 
599  // can return nullptr
600  if (buffer) {
601  logBuffer.write(reinterpret_cast<const char*>(buffer->buffer), buffer->nextIdx * sizeof(composite_logger_s));
602 
604  }
605  }
606 #endif /* EFI_TOOTH_LOGGER */
607 }
608 
609 bool isSdCardAlive(void) {
610  return fs_ready;
611 }
612 
613 // Pre-config load init
615 #if EFI_PROD_CODE
616  logName[0] = 0;
617 
618  addConsoleAction("sdinfo", sdStatistics);
621  addConsoleAction("incfilename", incLogFileName);
622 #endif // EFI_PROD_CODE
623 }
624 
625 void initMmcCard() {
626  chThdCreateStatic(mmcThreadStack, sizeof(mmcThreadStack), PRIO_MMC, (tfunc_t)(void*) MMCmonThread, NULL);
627 }
628 
629 #endif /* EFI_FILE_LOGGING */
SPIConfig mmc_hs_spicfg
Definition: at32_spi.cpp:256
SPIConfig mmc_ls_spicfg
Definition: at32_spi.cpp:265
void writeSdLogLine(Writer &bufferedWriter)
beuint32_t period
virtual size_t writeInternal(const char *buffer, size_t count)=0
TunerStudioOutputChannels outputChannels
Definition: engine.h:96
void addConsoleActionS(const char *token, VoidCharPtr callback)
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
ioportid_t getHwPort(const char *msg, brain_pin_e brainPin)
ioportmask_t getHwPin(const char *msg, brain_pin_e brainPin)
char * itoa10(char *p, int num)
Definition: efilib.cpp:119
const char * boolToString(bool value)
Definition: efilib.cpp:18
int mytolower(const char c)
Definition: efilib.cpp:150
efitimesec_t getTimeNowS()
Current system time in seconds (32 bits)
Definition: efitime.cpp:42
Engine * engine
bool warning(ObdCode code, const char *fmt,...)
SPIDriver * getSpiDevice(spi_device_e spiDevice)
Definition: hardware.cpp:144
void printSpiConfig(const char *msg, spi_device_e device)
Definition: hardware.cpp:251
void hellenEnableEn(const char *msg)
bool getHellenBoardEnabled()
bool isIgnVoltage()
void attachMsdSdCard(BaseBlockDevice *blkdev)
static THD_FUNCTION(MMCmonThread, arg)
Definition: mmc_card.cpp:527
static void sdStatistics()
Definition: mmc_card.cpp:131
void initEarlyMmcCard()
Definition: mmc_card.cpp:614
static spi_device_e mmcSpiDevice
Definition: mmc_card.cpp:63
static chibios_rt::BinarySemaphore usbConnectedSemaphore(true)
static const char * sdStatus
Definition: mmc_card.cpp:54
static int fileCreatedCounter
Definition: mmc_card.cpp:28
static void sdTriggerLogger()
Definition: mmc_card.cpp:592
static NO_CACHE SdLogBufferWriter logBuffer
Definition: mmc_card.cpp:518
MMCDriver MMCD1
Definition: mmc_card.cpp:78
static bool mountMmc()
Definition: mmc_card.cpp:406
static THD_WORKING_AREA(mmcThreadStack, 3 *UTILITY_THREAD_STACK_SIZE)
static void printError(const char *str, FRESULT f_error)
Definition: mmc_card.cpp:107
static const SDCConfig sdcConfig
Definition: mmc_card.cpp:384
void onUsbConnectedNotifyMmcI()
Definition: mmc_card.cpp:324
static int fatFsErrors
Definition: mmc_card.cpp:98
int mystrncasecmp(const char *s1, const char *s2, size_t n)
Definition: mmc_card.cpp:237
int totalLoggedBytes
Definition: mmc_card.cpp:27
static MMCConfig mmccfg
Definition: mmc_card.cpp:81
static void mlgLogger()
Definition: mmc_card.cpp:562
static int writeCounter
Definition: mmc_card.cpp:29
static void incLogFileName()
Definition: mmc_card.cpp:141
static void listDirectory(const char *path)
Definition: mmc_card.cpp:253
static char logName[_MAX_FILLER+20]
Definition: mmc_card.cpp:121
static void removeFile(const char *pathx)
Definition: mmc_card.cpp:228
static void prepareLogFileName()
Definition: mmc_card.cpp:175
static int logFileIndex
Definition: mmc_card.cpp:120
static int totalSyncCounter
Definition: mmc_card.cpp:31
static void setSdCardReady(bool value)
Definition: mmc_card.cpp:102
static void mmcUnMount()
Definition: mmc_card.cpp:297
static bool fs_ready
Definition: mmc_card.cpp:23
static int totalWritesCounter
Definition: mmc_card.cpp:30
static BaseBlockDevice * initializeMmcBlockDevice()
Definition: mmc_card.cpp:335
static FIL FDLogFile NO_CACHE
Definition: mmc_card.cpp:116
bool isSdCardAlive(void)
Definition: mmc_card.cpp:609
static void createLogFile()
Create a new file with the specified name.
Definition: mmc_card.cpp:205
static NO_CACHE FATFS MMC_FS
Definition: mmc_card.cpp:96
void initMmcCard()
Definition: mmc_card.cpp:625
static void printMmcPinout()
Definition: mmc_card.cpp:123
@ CUSTOM_ERR_SD_MOUNT_FAILED
@ CUSTOM_ERR_SD_SEEK_FAILED
engine_configuration_s * engineConfiguration
const char * hwPortname(brain_pin_e brainPin)
bool isBrainPinValid(brain_pin_e brainPin)
bool dateToStringShort(char *lcd_str)
Definition: rtc_helper.cpp:110
Real Time Clock helper.
spi_device_e
Definition: rusefi_enums.h:361
void EnableToothLogger()
CompositeBuffer * GetToothLoggerBufferBlocking()
void ReturnToothLoggerBuffer(CompositeBuffer *buffer)
composite_logger_s
Definition: tooth_logger.h:48
static BigBufferHandle buffer