refactor: SD card SPI HAL (#3957)
* refactor: SD card SPI driver * Removed SPI and DMA StdPeriph drivers * Allow for disabling SPI DMA support * Disable SPI sdcard CRC support * Fix 2MHz timer on NV14 * Shared VS1053b driver * Fix: SPI2 uses PCLK1 * feat: new generic diskio API * More generic SD_CARD_PRESENT() * Fixes * Flush incoming block on token mismatch * Scratch buffer test * Incredible hack to re-sync sd card * fix: SDIO driver
This commit is contained in:
@@ -8,3 +8,24 @@ set(SRC ${SRC}
|
||||
hal/adc_driver.cpp
|
||||
hal/key_driver.cpp
|
||||
)
|
||||
|
||||
include_directories(${FATFS_DIR} ${FATFS_DIR}/option)
|
||||
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hal/key_driver.cpp
|
||||
)
|
||||
|
||||
if (NOT NATIVE_BUILD)
|
||||
set(SRC ${SRC}
|
||||
hal/storage.cpp
|
||||
hal/fatfs_diskio.cpp
|
||||
${FATFS_DIR}/ff.c
|
||||
${FATFS_DIR}/ffunicode.c
|
||||
)
|
||||
set(BOOTLOADER_SRC ${BOOTLOADER_SRC}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hal/storage.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/hal/fatfs_diskio.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${FATFS_DIR}/ff.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/${FATFS_DIR}/ffunicode.c
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "fatfs_diskio.h"
|
||||
#include "FatFs/diskio.h"
|
||||
|
||||
#if FF_FS_REENTRANT != 0
|
||||
#include "rtos.h"
|
||||
#endif
|
||||
|
||||
struct fatfs_drive_t {
|
||||
const diskio_driver_t* drv;
|
||||
uint8_t lun;
|
||||
bool initialized;
|
||||
#if FF_FS_REENTRANT != 0
|
||||
RTOS_MUTEX_HANDLE mutex;
|
||||
#endif
|
||||
};
|
||||
|
||||
static fatfs_drive_t _fatfs_drives[FF_VOLUMES];
|
||||
static uint8_t _fatfs_n_drives = 0;
|
||||
|
||||
int fatfsRegisterDriver(const diskio_driver_t* drv, uint8_t lun)
|
||||
{
|
||||
if (_fatfs_n_drives >= FF_VOLUMES) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t vol = _fatfs_n_drives++;
|
||||
auto& drive = _fatfs_drives[vol];
|
||||
drive.drv = drv;
|
||||
drive.lun = lun;
|
||||
drive.initialized = false;
|
||||
|
||||
#if FF_FS_REENTRANT != 0
|
||||
// init IO mutex only once
|
||||
RTOS_CREATE_MUTEX(drive.mutex);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const diskio_driver_t* fatfsGetDriver(uint8_t pdrv)
|
||||
{
|
||||
if (pdrv >= _fatfs_n_drives) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return _fatfs_drives[pdrv].drv;
|
||||
}
|
||||
|
||||
uint8_t fatfsGetLun(uint8_t pdrv)
|
||||
{
|
||||
if (pdrv >= _fatfs_n_drives) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _fatfs_drives[pdrv].lun;
|
||||
}
|
||||
|
||||
#if FF_FS_REENTRANT != 0
|
||||
|
||||
int ff_cre_syncobj(BYTE vol, FF_SYNC_t* mutex)
|
||||
{
|
||||
*mutex = _fatfs_drives[vol].mutex;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ff_req_grant(FF_SYNC_t mutex)
|
||||
{
|
||||
RTOS_LOCK_MUTEX(mutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ff_rel_grant(FF_SYNC_t mutex) { RTOS_UNLOCK_MUTEX(mutex); }
|
||||
|
||||
int ff_del_syncobj(FF_SYNC_t mutex) { return 1; }
|
||||
|
||||
#endif
|
||||
|
||||
DSTATUS disk_initialize(BYTE pdrv)
|
||||
{
|
||||
if (pdrv >= _fatfs_n_drives) {
|
||||
return STA_NODISK;
|
||||
}
|
||||
|
||||
DSTATUS stat = RES_OK;
|
||||
auto drive = &_fatfs_drives[pdrv];
|
||||
if (!drive->initialized) {
|
||||
stat = drive->drv->initialize(drive->lun);
|
||||
if (stat == RES_OK) {
|
||||
drive->initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
return stat;
|
||||
}
|
||||
|
||||
DSTATUS disk_status(BYTE pdrv)
|
||||
{
|
||||
auto drv = _fatfs_drives[pdrv].drv;
|
||||
uint8_t lun = _fatfs_drives[pdrv].lun;
|
||||
return drv->status(lun);
|
||||
}
|
||||
|
||||
DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count)
|
||||
{
|
||||
auto drv = _fatfs_drives[pdrv].drv;
|
||||
uint8_t lun = _fatfs_drives[pdrv].lun;
|
||||
return drv->read(lun, buff, sector, count);
|
||||
}
|
||||
|
||||
DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count)
|
||||
{
|
||||
auto drv = _fatfs_drives[pdrv].drv;
|
||||
uint8_t lun = _fatfs_drives[pdrv].lun;
|
||||
return drv->write(lun, buff, sector, count);
|
||||
}
|
||||
|
||||
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void* buff)
|
||||
{
|
||||
auto drv = _fatfs_drives[pdrv].drv;
|
||||
uint8_t lun = _fatfs_drives[pdrv].lun;
|
||||
return drv->ioctl(lun, cmd, buff);
|
||||
}
|
||||
|
||||
#if FF_FS_NORTC == 0
|
||||
|
||||
#include "rtc.h"
|
||||
|
||||
DWORD get_fattime(void)
|
||||
{
|
||||
struct gtm t;
|
||||
|
||||
gettime(&t);
|
||||
|
||||
/* Pack date and time into a DWORD variable */
|
||||
return ((DWORD)(t.tm_year - 80) << 25)
|
||||
| ((uint32_t)(t.tm_mon+1) << 21)
|
||||
| ((uint32_t)t.tm_mday << 16)
|
||||
| ((uint32_t)t.tm_hour << 11)
|
||||
| ((uint32_t)t.tm_min << 5)
|
||||
| ((uint32_t)t.tm_sec >> 1);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "FatFs/diskio.h"
|
||||
#include <stdint.h>
|
||||
|
||||
struct diskio_driver_t
|
||||
{
|
||||
DSTATUS (*initialize)(BYTE pdrv);
|
||||
|
||||
DSTATUS (*status)(BYTE pdrv);
|
||||
|
||||
DRESULT (*read)(BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
||||
|
||||
DRESULT (*write)(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
|
||||
DRESULT (*ioctl)(BYTE pdrv, BYTE cmd, void* buff);
|
||||
};
|
||||
|
||||
// returns 1 if successful, 0 otherwise
|
||||
int fatfsRegisterDriver(const diskio_driver_t* drv, uint8_t lun);
|
||||
|
||||
// returns a pyhsical disk driver or NULL
|
||||
const diskio_driver_t* fatfsGetDriver(uint8_t pdrv);
|
||||
|
||||
// returns a physical LUN or 0
|
||||
uint8_t fatfsGetLun(uint8_t pdrv);
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/storage.h"
|
||||
#include "hal.h"
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
#if defined(STORAGE_USE_SDIO)
|
||||
#include "diskio_sdio.h"
|
||||
#define _STORAGE_DRIVER sdio_diskio_driver
|
||||
#elif defined(STORAGE_USE_SDCARD_SPI)
|
||||
#include "diskio_spi.h"
|
||||
#define _STORAGE_DRIVER sdcard_spi_driver
|
||||
#else
|
||||
#error "No supported storage driver configured"
|
||||
#endif
|
||||
|
||||
#if defined(DISK_CACHE)
|
||||
#include "disk_cache.h"
|
||||
const diskio_driver_t disk_cache_shim = {
|
||||
.initialize = _STORAGE_DRIVER.initialize,
|
||||
.status = _STORAGE_DRIVER.status,
|
||||
.read = disk_cache_read,
|
||||
.write = disk_cache_write,
|
||||
.ioctl = _STORAGE_DRIVER.ioctl,
|
||||
};
|
||||
#endif
|
||||
|
||||
void storageInit()
|
||||
{
|
||||
if (fatfsGetDriver(0) != nullptr)
|
||||
return;
|
||||
|
||||
const diskio_driver_t* drv = &_STORAGE_DRIVER;
|
||||
|
||||
#if defined(DISK_CACHE)
|
||||
diskCache.initialize(drv);
|
||||
drv = &disk_cache_shim;
|
||||
#endif
|
||||
|
||||
if (!fatfsRegisterDriver(drv, 0)) {
|
||||
TRACE("fatfsRegisterDriver: [FAILED]");
|
||||
}
|
||||
}
|
||||
|
||||
void storagePreMountHook()
|
||||
{
|
||||
#if defined(DISK_CACHE)
|
||||
diskCache.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool storageIsPresent()
|
||||
{
|
||||
return (_STORAGE_DRIVER.status(0) & STA_NODISK) == 0;
|
||||
}
|
||||
|
||||
const diskio_driver_t* storageGetDefaultDriver()
|
||||
{
|
||||
return &_STORAGE_DRIVER;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Called when the storage is initialized
|
||||
//
|
||||
// Note: can be used to attach the pyhsical volume driver
|
||||
// to the generic FatFs driver
|
||||
void storageInit();
|
||||
|
||||
// Called before the storage is mounted
|
||||
void storagePreMountHook();
|
||||
|
||||
bool storageIsPresent();
|
||||
|
||||
#define SD_CARD_PRESENT() storageIsPresent()
|
||||
|
||||
struct diskio_driver_t;
|
||||
|
||||
// returns the default storage's IO driver
|
||||
const diskio_driver_t* storageGetDefaultDriver();
|
||||
Reference in New Issue
Block a user