rewrite SD initialization (#2346)

* rewrite SD init

* static

* return a pointer instead
This commit is contained in:
Matthew Kennedy 2021-02-13 18:26:11 -08:00 committed by GitHub
parent d94dd050c7
commit 6ab7e151f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 63 additions and 66 deletions

View File

@ -355,53 +355,67 @@ static const scsi_inquiry_response_t scsi_inquiry_response = {
#endif /* HAL_USE_USB_MSD */
/*
* MMC card mount.
* Attempts to initialize the MMC card.
* Returns a BaseBlockDevice* corresponding to the SD card if successful, otherwise nullptr.
*/
static void MMCmount(void) {
// printMmcPinout();
if (isSdCardAlive()) {
scheduleMsg(&logger, "Error: Already mounted. \"umountsd\" first");
return;
}
if ((MMCD1.state == BLK_STOP) || (MMCD1.state == BLK_ACTIVE)) {
// looks like we would only get here after manual unmount with mmcStop? Do we really need to ever mmcStop?
// not sure if this code is needed
// start to initialize MMC/SD
mmcStart(&MMCD1, &mmccfg); // Configures and activates the MMC peripheral.
static BaseBlockDevice* initializeMmcBlockDevice() {
if (!CONFIG(isSdCardEnabled)) {
return nullptr;
}
#if HAL_USE_USB_MSD
msdObjectInit(&USBMSD1);
#endif
// Configures and activates the MMC peripheral.
mmcSpiDevice = CONFIG(sdCardSpiDevice);
efiAssert(OBD_PCM_Processor_Fault, mmcSpiDevice != SPI_NONE, "SD card enabled, but no SPI device configured!", nullptr);
// todo: reuse initSpiCs method?
hs_spicfg.ssport = ls_spicfg.ssport = getHwPort("mmc", CONFIG(sdCardCsPin));
hs_spicfg.sspad = ls_spicfg.sspad = getHwPin("mmc", CONFIG(sdCardCsPin));
mmccfg.spip = getSpiDevice(mmcSpiDevice);
// We think we have everything for the card, let's try to mount it!
mmcObjectInit(&MMCD1);
mmcStart(&MMCD1, &mmccfg);
// Performs the initialization procedure on the inserted card.
LOCK_SD_SPI;
LOCK_SD_SPI;
sdStatus = SD_STATE_CONNECTING;
if (mmcConnect(&MMCD1) != HAL_SUCCESS) {
#if HAL_USE_USB_MSD
// mount a null device to USB
msdMountNullDevice(&USBMSD1, &USBD2, blkbuf, &scsi_inquiry_response);
#endif
sdStatus = SD_STATE_NOT_CONNECTED;
warning(CUSTOM_OBD_MMC_ERROR, "Can't connect or mount MMC/SD");
UNLOCK_SD_SPI;
return;
return nullptr;
}
#if HAL_USE_USB_MSD
BaseBlockDevice *bbdp = (BaseBlockDevice*)&MMCD1;
msdStart(&USBMSD1, usb_driver, bbdp, blkbuf, &scsi_inquiry_response, NULL);
#endif
UNLOCK_SD_SPI;
return (BaseBlockDevice*)&MMCD1;
}
// Initialize and mount the SD card.
// Returns true if the filesystem was successfully mounted for writing.
static bool mountMmc() {
auto cardBlockDevice = initializeMmcBlockDevice();
#if HAL_USE_USB_MSD
sdStatus = SD_STATE_MOUNTED;
return;
msdObjectInit(&USBMSD1);
if (cardBlockDevice) {
// Mount the real card to USB
msdStart(&USBMSD1, usb_driver, cardBlockDevice, blkbuf, &scsi_inquiry_response, NULL);
} else {
// Mount a "no media" device to USB
msdMountNullDevice(&USBMSD1, usb_driver, blkbuf, &scsi_inquiry_response);
}
// TODO: local mount and log if USB not connected
return false;
#endif
// if no card, don't try to mount FS
if (!cardBlockDevice) {
return false;
}
// if Ok - mount FS now
memset(&MMC_FS, 0, sizeof(FATFS));
if (f_mount(&MMC_FS, "/", 1) == FR_OK) {
@ -410,12 +424,16 @@ static void MMCmount(void) {
createLogFile();
fileCreatedCounter++;
scheduleMsg(&logger, "MMC/SD mounted!");
return true;
} else {
sdStatus = SD_STATE_MOUNT_FAILED;
return false;
}
}
class SdLogBufferWriter final : public BufferedWriter<512> {
struct SdLogBufferWriter final : public BufferedWriter<512> {
bool failed = false;
size_t writeInternal(const char* buffer, size_t count) override {
size_t bytesWritten;
@ -426,7 +444,12 @@ class SdLogBufferWriter final : public BufferedWriter<512> {
if (bytesWritten != count) {
printError("write error or disk full", err); // error or disk full
// Close file and unmount volume
mmcUnMount();
UNLOCK_SD_SPI;
failed = true;
return 0;
} else {
writeCounter++;
totalWritesCounter++;
@ -465,20 +488,11 @@ static THD_FUNCTION(MMCmonThread, arg) {
tsOutputChannels.debugIntField4 = fileCreatedCounter;
}
// this returns TRUE if SD module is there, even without an SD card?
if (blkIsInserted(&MMCD1)) {
writeLogLine(logBuffer);
if (!isSdCardAlive()) {
MMCmount();
}
} else {
sdStatus = SD_STATE_NOT_INSERTED;
}
if (isSdCardAlive()) {
writeLogLine(logBuffer);
} else {
chThdSleepMilliseconds(100);
// Something went wrong (already handled), so cancel further writes
if (logBuffer.failed) {
return;
}
auto period = CONFIG(sdCardPeriodMs);
@ -494,32 +508,15 @@ bool isSdCardAlive(void) {
void initMmcCard(void) {
logName[0] = 0;
addConsoleAction("sdinfo", sdStatistics);
if (!CONFIG(isSdCardEnabled)) {
if (!mountMmc()) {
// no card present, don't start thread
return;
}
mmcSpiDevice = CONFIG(sdCardSpiDevice);
efiAssertVoid(OBD_PCM_Processor_Fault, mmcSpiDevice != SPI_NONE, "SD card enabled, but no SPI device configured!");
// todo: reuse initSpiCs method?
hs_spicfg.ssport = ls_spicfg.ssport = getHwPort("mmc", CONFIG(sdCardCsPin));
hs_spicfg.sspad = ls_spicfg.sspad = getHwPin("mmc", CONFIG(sdCardCsPin));
mmccfg.spip = getSpiDevice(mmcSpiDevice);
/**
* FYI: SPI does not work with CCM memory, be sure to have main() stack in RAM, not in CCMRAM
*/
// start to initialize MMC/SD
mmcObjectInit(&MMCD1); // Initializes an instance.
mmcStart(&MMCD1, &mmccfg);
chThdCreateStatic(mmcThreadStack, sizeof(mmcThreadStack), LOWPRIO, (tfunc_t)(void*) MMCmonThread, NULL);
addConsoleAction("mountsd", MMCmount);
addConsoleAction("umountsd", mmcUnMount);
addConsoleAction("sdinfo", sdStatistics);
addConsoleActionS("ls", listDirectory);
addConsoleActionS("del", removeFile);
addConsoleAction("incfilename", incLogFileName);