chore: SDIO conversion to HAL (#3182)
This commit is contained in:
@@ -30,7 +30,9 @@ set(BOARD_LIB_SRC
|
||||
)
|
||||
|
||||
add_library(minimal_board_lib OBJECT EXCLUDE_FROM_ALL ${MINIMAL_BOARD_LIB_SRC})
|
||||
|
||||
add_library(board_lib OBJECT EXCLUDE_FROM_ALL ${BOARD_LIB_SRC})
|
||||
add_dependencies(board_lib minimal_board_lib)
|
||||
|
||||
set(FIRMWARE_SRC ${FIRMWARE_SRC}
|
||||
$<TARGET_OBJECTS:minimal_board_lib>
|
||||
|
||||
@@ -1259,6 +1259,10 @@ void printAudioVars()
|
||||
|
||||
#include "hal/switch_driver.h"
|
||||
|
||||
#if defined(DISK_CACHE)
|
||||
#include "disk_cache.h"
|
||||
#endif
|
||||
|
||||
int cliDisplay(const char ** argv)
|
||||
{
|
||||
long long int address = 0;
|
||||
|
||||
@@ -19,22 +19,48 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "disk_cache.h"
|
||||
#include "sdcard.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "opentx.h"
|
||||
|
||||
#if defined(SIMU) && !defined(SIMU_DISKIO)
|
||||
#define __disk_read(...) (RES_OK)
|
||||
#define __disk_write(...) (RES_OK)
|
||||
#endif
|
||||
|
||||
#if 0 // set to 1 to enable traces
|
||||
#if 0 // set to 1 to enable traces
|
||||
#include "debug.h"
|
||||
#define TRACE_DISK_CACHE(...) TRACE(__VA_ARGS__)
|
||||
#else
|
||||
#define TRACE_DISK_CACHE(...)
|
||||
#endif
|
||||
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
#error "Variable sector size is not supported"
|
||||
#endif
|
||||
|
||||
#define BLOCK_SIZE FF_MAX_SS
|
||||
#define DISK_CACHE_BLOCK_SIZE (DISK_CACHE_BLOCK_SECTORS * BLOCK_SIZE)
|
||||
|
||||
DiskCache diskCache;
|
||||
|
||||
class DiskCacheBlock
|
||||
{
|
||||
public:
|
||||
DiskCacheBlock();
|
||||
bool read(BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT fill(BYTE drv, BYTE* buff, DWORD sector, UINT count);
|
||||
void free(DWORD sector, UINT count);
|
||||
void free();
|
||||
bool empty() const;
|
||||
|
||||
private:
|
||||
uint8_t data[DISK_CACHE_BLOCK_SIZE];
|
||||
DWORD startSector;
|
||||
DWORD endSector;
|
||||
};
|
||||
|
||||
DiskCacheBlock::DiskCacheBlock():
|
||||
startSector(0),
|
||||
endSector(0)
|
||||
@@ -97,7 +123,7 @@ void DiskCache::clear()
|
||||
stats.noHits = 0;
|
||||
stats.noMisses = 0;
|
||||
stats.noWrites = 0;
|
||||
for (int n=0; n<DISK_CACHE_BLOCKS_NUM; ++n) {
|
||||
for (int n = 0; n < DISK_CACHE_BLOCKS_NUM; ++n) {
|
||||
blocks[n].free();
|
||||
}
|
||||
}
|
||||
@@ -117,12 +143,12 @@ DRESULT DiskCache::read(BYTE drv, BYTE * buff, DWORD sector, UINT count)
|
||||
}
|
||||
|
||||
// if block + cache block size is beyond the end of the disk, then read it directly without using cache
|
||||
if (sector+DISK_CACHE_BLOCK_SECTORS >= sdGetNoSectors()) {
|
||||
if (sector + DISK_CACHE_BLOCK_SECTORS >= sdGetNoSectors()) {
|
||||
TRACE_DISK_CACHE("\t\t cache would be beyond end of disk %u (%u)", (uint32_t)sector, sdGetNoSectors());
|
||||
return __disk_read(drv, buff, sector, count);
|
||||
}
|
||||
|
||||
for (int n=0; n<DISK_CACHE_BLOCKS_NUM; ++n) {
|
||||
for (int n = 0; n < DISK_CACHE_BLOCKS_NUM; ++n) {
|
||||
if (blocks[n].read(buff, sector, count)) {
|
||||
++stats.noHits;
|
||||
return RES_OK;
|
||||
@@ -132,7 +158,7 @@ DRESULT DiskCache::read(BYTE drv, BYTE * buff, DWORD sector, UINT count)
|
||||
++stats.noMisses;
|
||||
|
||||
// find free block
|
||||
for (int n=0; n<DISK_CACHE_BLOCKS_NUM; ++n) {
|
||||
for (int n = 0; n < DISK_CACHE_BLOCKS_NUM; ++n) {
|
||||
if (blocks[n].empty()) {
|
||||
TRACE_DISK_CACHE("\t\t using free block");
|
||||
return blocks[n].fill(drv, buff, sector, count);
|
||||
@@ -151,7 +177,7 @@ DRESULT DiskCache::read(BYTE drv, BYTE * buff, DWORD sector, UINT count)
|
||||
DRESULT DiskCache::write(BYTE drv, const BYTE* buff, DWORD sector, UINT count)
|
||||
{
|
||||
++stats.noWrites;
|
||||
for(int n=0; n < DISK_CACHE_BLOCKS_NUM; ++n) {
|
||||
for(int n = 0; n < DISK_CACHE_BLOCKS_NUM; ++n) {
|
||||
blocks[n].free(sector, count);
|
||||
}
|
||||
return __disk_write(drv, buff, sector, count);
|
||||
|
||||
+7
-20
@@ -22,30 +22,12 @@
|
||||
#ifndef _DISK_CACHE_H_
|
||||
#define _DISK_CACHE_H_
|
||||
|
||||
#include "diskio.h"
|
||||
#include "FatFs/diskio.h"
|
||||
|
||||
// tunable parameters
|
||||
#define DISK_CACHE_BLOCKS_NUM 32 // no cache blocks
|
||||
#define DISK_CACHE_BLOCK_SECTORS 16 // no sectors
|
||||
|
||||
#define DISK_CACHE_BLOCK_SIZE (DISK_CACHE_BLOCK_SECTORS * BLOCK_SIZE)
|
||||
|
||||
class DiskCacheBlock
|
||||
{
|
||||
public:
|
||||
DiskCacheBlock();
|
||||
bool read(BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT fill(BYTE drv, BYTE* buff, DWORD sector, UINT count);
|
||||
void free(DWORD sector, UINT count);
|
||||
void free();
|
||||
bool empty() const;
|
||||
|
||||
private:
|
||||
uint8_t data[DISK_CACHE_BLOCK_SIZE];
|
||||
DWORD startSector;
|
||||
DWORD endSector;
|
||||
};
|
||||
|
||||
struct DiskCacheStats
|
||||
{
|
||||
uint32_t noHits;
|
||||
@@ -53,15 +35,20 @@ struct DiskCacheStats
|
||||
uint32_t noWrites;
|
||||
};
|
||||
|
||||
class DiskCacheBlock;
|
||||
|
||||
class DiskCache
|
||||
{
|
||||
public:
|
||||
DiskCache();
|
||||
|
||||
void clear();
|
||||
|
||||
DRESULT read(BYTE drv, BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT write(BYTE drv, const BYTE* buff, DWORD sector, UINT count);
|
||||
|
||||
const DiskCacheStats & getStats() const;
|
||||
int getHitRate() const;
|
||||
void clear();
|
||||
|
||||
private:
|
||||
DiskCacheStats stats;
|
||||
|
||||
@@ -56,7 +56,7 @@ const char * writeScreenshot()
|
||||
UINT written;
|
||||
char filename[42]; // /SCREENSHOTS/screen-2013-01-01-123540.bmp
|
||||
|
||||
if (IS_SDCARD_FULL()) {
|
||||
if (sdIsFull()) {
|
||||
POPUP_WARNING(STR_SDCARD_FULL_EXT);
|
||||
return STR_SDCARD_FULL_EXT;
|
||||
}
|
||||
|
||||
+1
-1
@@ -280,7 +280,7 @@ void logsWrite()
|
||||
{
|
||||
#endif
|
||||
|
||||
bool sdCardFull = IS_SDCARD_FULL();
|
||||
bool sdCardFull = sdIsFull();
|
||||
|
||||
// check if file needs to be opened
|
||||
if (!g_oLogFile.obj.fs) {
|
||||
|
||||
@@ -197,7 +197,7 @@ void per10ms()
|
||||
if (mixWarning & 4) if(((g_tmr10ms&0xFF)==128) || ((g_tmr10ms&0xFF)==136) || ((g_tmr10ms&0xFF)==144)) AUDIO_MIX_WARNING(3);
|
||||
#endif
|
||||
|
||||
#if defined(SDCARD)
|
||||
#if defined(SDCARD) && defined(PCBTARANIS)
|
||||
sdPoll10ms();
|
||||
#endif
|
||||
|
||||
@@ -645,8 +645,9 @@ static void checkRTCBattery()
|
||||
}
|
||||
|
||||
void checkSDfreeStorage() {
|
||||
if(IS_SDCARD_FULL())
|
||||
if(sdIsFull()) {
|
||||
ALERT(STR_SD_CARD, STR_SDCARD_FULL, AU_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PCBFRSKY) || defined(PCBFLYSKY)
|
||||
|
||||
@@ -246,9 +246,6 @@ enum RotaryEncoderMode {
|
||||
#define CASE_JACK_DETECT(x)
|
||||
#endif
|
||||
|
||||
#if defined(DISK_CACHE)
|
||||
#include "disk_cache.h"
|
||||
#endif
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
@@ -1052,10 +1049,6 @@ inline bool IS_TXBATT_WARNING()
|
||||
return g_vbat100mV <= g_eeGeneral.vBatWarn;
|
||||
}
|
||||
|
||||
inline bool IS_SDCARD_FULL() {
|
||||
return sdGetFreeSectors() < ((50 *1024*1024) / BLOCK_SIZE); // 50MB safety margin
|
||||
}
|
||||
|
||||
enum TelemetryViews {
|
||||
TELEMETRY_CUSTOM_SCREEN_1,
|
||||
TELEMETRY_CUSTOM_SCREEN_2,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "opentx.h"
|
||||
#include "diskio.h"
|
||||
|
||||
@@ -30,6 +31,12 @@
|
||||
#include "libopenui/src/libopenui_file.h"
|
||||
#endif
|
||||
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
#error "Variable sector size is not supported"
|
||||
#endif
|
||||
|
||||
#define BLOCK_SIZE FF_MAX_SS
|
||||
|
||||
#define SDCARD_MIN_FREE_SPACE_MB 50 // Maintain a 50MB free space buffer to prevent crashes
|
||||
|
||||
const char * sdCheckAndCreateDirectory(const char * path)
|
||||
@@ -451,6 +458,13 @@ uint32_t sdGetFreeSectors()
|
||||
return nofree * fat->csize;
|
||||
}
|
||||
|
||||
uint32_t sdGetFreeKB()
|
||||
{
|
||||
return sdGetFreeSectors() * (1024 / BLOCK_SIZE);
|
||||
}
|
||||
|
||||
bool sdIsFull() { return sdGetFreeKB() < SDCARD_MIN_FREE_SPACE_MB * 1024; }
|
||||
|
||||
#else // #if !defined(SIMU) || defined(SIMU_DISKIO)
|
||||
|
||||
uint32_t sdGetNoSectors()
|
||||
@@ -468,4 +482,130 @@ uint32_t sdGetFreeSectors()
|
||||
return ((SDCARD_MIN_FREE_SPACE_MB*1024*1024)/BLOCK_SIZE)+1; // SIMU SD card is always above threshold
|
||||
}
|
||||
|
||||
uint32_t sdGetFreeKB() { return SDCARD_MIN_FREE_SPACE_MB * 1024 + 1; }
|
||||
bool sdIsFull() { return false; }
|
||||
|
||||
#endif // #if !defined(SIMU) || defined(SIMU_DISKIO)
|
||||
|
||||
|
||||
static bool _g_FATFS_init = false;
|
||||
static FATFS g_FATFS_Obj __DMA; // this is in uninitialised section !!!
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
FIL g_telemetryFile = {};
|
||||
#endif
|
||||
|
||||
#if defined(LOG_BLUETOOTH)
|
||||
FIL g_bluetoothFile = {};
|
||||
#endif
|
||||
|
||||
#include "audio.h"
|
||||
#include "sdcard.h"
|
||||
#include "disk_cache.h"
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Lock / unlock functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static RTOS_MUTEX_HANDLE ioMutex;
|
||||
uint32_t ioMutexReq = 0, ioMutexRel = 0;
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t * mutex)
|
||||
{
|
||||
*mutex = ioMutex;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ff_req_grant (FF_SYNC_t mutex)
|
||||
{
|
||||
ioMutexReq += 1;
|
||||
RTOS_LOCK_MUTEX(mutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ff_rel_grant (FF_SYNC_t mutex)
|
||||
{
|
||||
ioMutexRel += 1;
|
||||
RTOS_UNLOCK_MUTEX(mutex);
|
||||
}
|
||||
|
||||
int ff_del_syncobj (FF_SYNC_t mutex)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sdInit()
|
||||
{
|
||||
TRACE("sdInit");
|
||||
RTOS_CREATE_MUTEX(ioMutex);
|
||||
sdMount();
|
||||
}
|
||||
|
||||
void sdMount()
|
||||
{
|
||||
TRACE("sdMount");
|
||||
|
||||
#if defined(DISK_CACHE)
|
||||
diskCache.clear();
|
||||
#endif
|
||||
|
||||
if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
|
||||
// call sdGetFreeSectors() now because f_getfree() takes a long time first time it's called
|
||||
_g_FATFS_init = true;
|
||||
sdGetFreeSectors();
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
f_open(&g_telemetryFile, LOGS_PATH "/telemetry.log", FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (f_size(&g_telemetryFile) > 0) {
|
||||
f_lseek(&g_telemetryFile, f_size(&g_telemetryFile)); // append
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LOG_BLUETOOTH)
|
||||
f_open(&g_bluetoothFile, LOGS_PATH "/bluetooth.log", FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (f_size(&g_bluetoothFile) > 0) {
|
||||
f_lseek(&g_bluetoothFile, f_size(&g_bluetoothFile)); // append
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
TRACE("f_mount() failed");
|
||||
}
|
||||
}
|
||||
|
||||
void sdDone()
|
||||
{
|
||||
TRACE("sdDone");
|
||||
|
||||
if (sdMounted()) {
|
||||
audioQueue.stopSD();
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
f_close(&g_telemetryFile);
|
||||
#endif
|
||||
|
||||
#if defined(LOG_BLUETOOTH)
|
||||
f_close(&g_bluetoothFile);
|
||||
#endif
|
||||
|
||||
f_mount(nullptr, "", 0); // unmount SD
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t sdMounted()
|
||||
{
|
||||
return _g_FATFS_init && (g_FATFS_Obj.fs_type != 0);
|
||||
}
|
||||
|
||||
|
||||
uint32_t sdIsHC()
|
||||
{
|
||||
// defined in diskio
|
||||
#define CT_BLOCK 0x08
|
||||
extern uint32_t SD_GetCardType();
|
||||
|
||||
return SD_GetCardType() & CT_BLOCK;
|
||||
}
|
||||
|
||||
uint32_t sdGetSpeed()
|
||||
{
|
||||
return 330000;
|
||||
}
|
||||
|
||||
+23
-1
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "ff.h"
|
||||
|
||||
extern FATFS g_FATFS_Obj;
|
||||
extern FIL g_oLogFile;
|
||||
|
||||
#include "translations.h"
|
||||
@@ -124,9 +123,32 @@ void logsInit();
|
||||
void logsClose();
|
||||
void logsWrite();
|
||||
|
||||
void sdInit();
|
||||
void sdMount();
|
||||
void sdDone();
|
||||
uint32_t sdMounted();
|
||||
|
||||
uint32_t sdGetNoSectors();
|
||||
uint32_t sdGetSize();
|
||||
uint32_t sdGetFreeSectors();
|
||||
uint32_t sdGetFreeKB();
|
||||
bool sdIsFull();
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
void sdPoll10ms();
|
||||
#endif
|
||||
|
||||
#if !defined(SIMU) || defined(SIMU_DISKIO)
|
||||
uint32_t sdIsHC();
|
||||
uint32_t sdGetSpeed();
|
||||
#define SD_IS_HC() (sdIsHC())
|
||||
#define SD_GET_SPEED() (sdGetSpeed())
|
||||
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
|
||||
#else
|
||||
#define SD_IS_HC() (0)
|
||||
#define SD_GET_SPEED() (0)
|
||||
#endif
|
||||
|
||||
const char * sdCheckAndCreateDirectory(const char * path);
|
||||
|
||||
#if !defined(BOOT)
|
||||
|
||||
@@ -308,7 +308,6 @@ set(SRC
|
||||
set(FIRMWARE_TARGET_SRC
|
||||
${FIRMWARE_TARGET_SRC}
|
||||
# keys_driver.cpp
|
||||
diskio.cpp
|
||||
# telemetry_driver.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ set(BOOTLOADER_SRC
|
||||
../../../../../${FATFS_DIR}/ffunicode.c
|
||||
../../../../../targets/${TARGET_DIR}/${LCD_DRIVER}
|
||||
../../../../../targets/${TARGET_DIR}/backlight_driver.cpp
|
||||
../../../../../targets/${TARGET_DIR}/diskio.cpp
|
||||
../../../../../targets/${TARGET_DIR}/board.cpp
|
||||
../../../../../targets/${TARGET_DIR}/bootloader/boot_menu.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/hal_keys.inc
|
||||
@@ -42,6 +41,7 @@ set(BOOTLOADER_SRC
|
||||
../stm32_serial_driver.cpp
|
||||
../stm32_usart_driver.cpp
|
||||
../stm32_gpio_driver.cpp
|
||||
../stm32_dma.cpp
|
||||
init.c
|
||||
boot.cpp
|
||||
bin_files.cpp
|
||||
@@ -77,7 +77,8 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14)
|
||||
../../../../../fonts/lvgl/lv_font_roboto_bl_16.c
|
||||
../../../../../thirdparty/libopenui/src/bitmapbuffer.cpp
|
||||
../../../../../thirdparty/libopenui/thirdparty/lz4/lz4.c
|
||||
../../../../../targets/common/arm/stm32/sdio_sd.c
|
||||
../../../../../targets/common/arm/stm32/sdio_sd.cpp
|
||||
../../../../../targets/common/arm/stm32/diskio_sdio.cpp
|
||||
../../../../../targets/common/arm/stm32/rtc_driver.cpp
|
||||
../../../../../targets/${TARGET_DIR}/sdram_driver.c
|
||||
../../../../../targets/${TARGET_DIR}/haptic_driver.cpp
|
||||
@@ -119,6 +120,7 @@ else()
|
||||
../../../../../gui/common/stdlcd/fonts.cpp
|
||||
../../../../../gui/common/stdlcd/utf8.cpp
|
||||
../../../../../targets/${TARGET_DIR}/eeprom_driver.cpp
|
||||
../../../../../targets/${TARGET_DIR}/diskio.cpp
|
||||
)
|
||||
remove_definitions(-DDEBUG)
|
||||
endif()
|
||||
|
||||
@@ -38,6 +38,14 @@ BinFileInfo binFiles[MAX_BIN_FILES];
|
||||
uint8_t Block_buffer[BLOCK_LEN];
|
||||
UINT BlockCount;
|
||||
|
||||
void sdInit(void)
|
||||
{
|
||||
static FATFS fatFS __DMA;
|
||||
|
||||
if (f_mount(&fatFS, "", 1) == FR_OK) {
|
||||
f_chdir("/");
|
||||
}
|
||||
}
|
||||
|
||||
FRESULT openBinDir(MemoryType mt)
|
||||
{
|
||||
|
||||
@@ -94,9 +94,12 @@ uint32_t eepromWritten = 0;
|
||||
FlashCheckRes valid;
|
||||
MemoryType memoryType;
|
||||
uint32_t unlocked = 0;
|
||||
uint32_t timer10MsCount;
|
||||
|
||||
|
||||
void interrupt10ms()
|
||||
{
|
||||
timer10MsCount++;
|
||||
tenms |= 1u; // 10 mS has passed
|
||||
g_tmr10ms++;
|
||||
|
||||
@@ -116,6 +119,7 @@ void interrupt10ms()
|
||||
|
||||
void init10msTimer()
|
||||
{
|
||||
timer10MsCount = 0;
|
||||
INTERRUPT_xMS_TIMER->ARR = 9999; // 10mS in uS
|
||||
INTERRUPT_xMS_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1; // 1uS
|
||||
INTERRUPT_xMS_TIMER->CCER = 0;
|
||||
@@ -126,6 +130,11 @@ void init10msTimer()
|
||||
NVIC_EnableIRQ(INTERRUPT_xMS_IRQn);
|
||||
}
|
||||
|
||||
extern "C" uint32_t HAL_GetTick(void)
|
||||
{
|
||||
return timer10MsCount*10;
|
||||
}
|
||||
|
||||
#if !defined(SIMU)
|
||||
extern "C" void INTERRUPT_xMS_IRQHandler()
|
||||
{
|
||||
@@ -188,8 +197,6 @@ int menuFlashFile(uint32_t index, event_t event)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint32_t PowerUpDelay;
|
||||
|
||||
void flashWriteBlock()
|
||||
{
|
||||
uint32_t blockOffset = 0;
|
||||
@@ -571,12 +578,16 @@ int bootloaderMain()
|
||||
|
||||
lcdRefresh();
|
||||
|
||||
#if defined(SDCARD) && defined(PCBTARANIS)
|
||||
static uint32_t PowerUpDelay = 0;
|
||||
|
||||
if (PowerUpDelay < 20) { // 200 mS
|
||||
PowerUpDelay += 1;
|
||||
}
|
||||
else {
|
||||
sdPoll10ms();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (state != ST_FLASHING && state != ST_USB) {
|
||||
|
||||
+114
-169
@@ -25,45 +25,24 @@
|
||||
/* disk I/O modules and attach it to FatFs module with common interface. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include "diskio.h"
|
||||
#include "debug.h"
|
||||
#include "targets/common/arm/stm32/sdio_sd.h"
|
||||
#include "stm32_hal.h"
|
||||
#include "sdio_sd.h"
|
||||
|
||||
#include "FatFs/diskio.h"
|
||||
|
||||
#include <string.h>
|
||||
#include "debug.h"
|
||||
|
||||
// TODO share this with Horus (and perhaps other STM32)
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Lock / unlock functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#if !defined(BOOT)
|
||||
static RTOS_MUTEX_HANDLE ioMutex;
|
||||
uint32_t ioMutexReq = 0, ioMutexRel = 0;
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t *mutex)
|
||||
{
|
||||
*mutex = ioMutex;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ff_req_grant (FF_SYNC_t mutex)
|
||||
{
|
||||
ioMutexReq += 1;
|
||||
RTOS_LOCK_MUTEX(mutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ff_rel_grant (FF_SYNC_t mutex)
|
||||
{
|
||||
ioMutexRel += 1;
|
||||
RTOS_UNLOCK_MUTEX(mutex);
|
||||
}
|
||||
|
||||
int ff_del_syncobj (FF_SYNC_t mutex)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
#error "Variable sector size is not supported"
|
||||
#endif
|
||||
|
||||
#define BLOCK_SIZE FF_MAX_SS
|
||||
#define SD_TIMEOUT 300 /* 300ms */
|
||||
|
||||
// Disk status
|
||||
extern volatile uint32_t WriteStatus;
|
||||
extern volatile uint32_t ReadStatus;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
@@ -89,11 +68,11 @@ DSTATUS disk_initialize (
|
||||
}
|
||||
|
||||
TRACE("SD card info:");
|
||||
TRACE("sectors: %u", (uint32_t)(SDCardInfo.CardCapacity / 512));
|
||||
TRACE("type: %u", (uint32_t)(SDCardInfo.CardType));
|
||||
TRACE("EraseGrSize: %u", (uint32_t)(SDCardInfo.SD_csd.EraseGrSize));
|
||||
TRACE("EraseGrMul: %u", (uint32_t)(SDCardInfo.SD_csd.EraseGrMul));
|
||||
TRACE("ManufacturerID: %u", (uint32_t)(SDCardInfo.SD_cid.ManufacturerID));
|
||||
TRACE("type: %u", (uint32_t)(SD_GetCardType()));
|
||||
TRACE("class: %u", (uint32_t)(SD_GetCardClass()));
|
||||
TRACE("sectors: %u", (uint32_t)(SD_GetSectorCount()));
|
||||
TRACE("sector size: %u", (uint32_t)(SD_GetSectorSize()));
|
||||
TRACE("block size: %u", (uint32_t)(SD_GetBlockSize()));
|
||||
|
||||
return(stat);
|
||||
}
|
||||
@@ -124,39 +103,52 @@ uint32_t sdReadRetries = 0;
|
||||
/* Read Sector(s) */
|
||||
|
||||
|
||||
// Please note:
|
||||
// this functions assumes that buff is properly aligned
|
||||
// and in the right RAM segment for DMA
|
||||
//
|
||||
DRESULT disk_read_dma(BYTE drv, BYTE * buff, DWORD sector, UINT count)
|
||||
{
|
||||
// this functions assumes that buff is properly aligned and in the right RAM segment for DMA
|
||||
DRESULT res;
|
||||
SD_Error Status;
|
||||
SDTransferState State;
|
||||
for (int retry=0; retry<3; retry++) {
|
||||
res = RES_OK;
|
||||
if (count == 1) {
|
||||
Status = SD_ReadBlock(buff, sector, BLOCK_SIZE); // 4GB Compliant
|
||||
DRESULT res = RES_ERROR;
|
||||
|
||||
for (int retry = 0; retry < 3; retry++) {
|
||||
|
||||
ReadStatus = 0;
|
||||
SD_Error Status = SD_ReadBlocks(buff, sector, BLOCK_SIZE, count);
|
||||
if (Status != SD_OK) {
|
||||
TRACE("SD ReadBlocks=%d, s:%u c: %u", Status, sector, (uint32_t)count);
|
||||
++sdReadRetries;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
Status = SD_ReadMultiBlocks(buff, sector, BLOCK_SIZE, count); // 4GB Compliant
|
||||
|
||||
// Wait that the reading process is completed or a timeout occurs
|
||||
uint32_t timeout = HAL_GetTick();
|
||||
while((ReadStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT));
|
||||
|
||||
if (ReadStatus == 0) {
|
||||
TRACE("SD read timeout, s:%u c:%u", sector, (uint32_t)count);
|
||||
++sdReadRetries;
|
||||
continue;
|
||||
}
|
||||
if (Status == SD_OK) {
|
||||
Status = SD_WaitReadOperation(200*count); // Check if the Transfer is finished
|
||||
while ((State = SD_GetStatus()) == SD_TRANSFER_BUSY); // BUSY, OK (DONE), ERROR (FAIL)
|
||||
if (State == SD_TRANSFER_ERROR) {
|
||||
TRACE("State=SD_TRANSFER_ERROR, c: %u", sector, (uint32_t)count);
|
||||
res = RES_ERROR;
|
||||
}
|
||||
else if (Status != SD_OK) {
|
||||
TRACE("Status(WaitRead)=%d, s:%u c: %u", Status, sector, (uint32_t)count);
|
||||
res = RES_ERROR;
|
||||
|
||||
ReadStatus = 0;
|
||||
timeout = HAL_GetTick();
|
||||
|
||||
while((HAL_GetTick() - timeout) < SD_TIMEOUT) {
|
||||
if (SD_GetStatus() == SD_TRANSFER_OK) {
|
||||
res = RES_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRACE("Status(ReadBlock)=%d, s:%u c: %u", Status, sector, (uint32_t)count);
|
||||
res = RES_ERROR;
|
||||
|
||||
if (res == RES_OK) {
|
||||
// exit retry loop
|
||||
break;
|
||||
}
|
||||
if (res == RES_OK) break;
|
||||
sdReadRetries += 1;
|
||||
|
||||
TRACE("SD getstatus timeout, s:%u c:%u", sector, (uint32_t)count);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -174,6 +166,10 @@ DRESULT __disk_read(BYTE drv, BYTE * buff, DWORD sector, UINT count)
|
||||
return RES_NOTRDY;
|
||||
}
|
||||
|
||||
if (SD_CheckStatusWithTimeout(SD_TIMEOUT) < 0) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
DRESULT res = RES_OK;
|
||||
if (count == 0) return res;
|
||||
|
||||
@@ -199,6 +195,7 @@ DRESULT __disk_read(BYTE drv, BYTE * buff, DWORD sector, UINT count)
|
||||
buff += BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -213,13 +210,16 @@ DRESULT __disk_write(
|
||||
UINT count /* Number of sectors to write (1..255) */
|
||||
)
|
||||
{
|
||||
SD_Error Status;
|
||||
DRESULT res = RES_OK;
|
||||
|
||||
// TRACE("disk_write %d %p %10d %d", drv, buff, sector, count);
|
||||
|
||||
if (SD_Detect() != SD_PRESENT)
|
||||
return(RES_NOTRDY);
|
||||
return RES_NOTRDY;
|
||||
|
||||
if (SD_CheckStatusWithTimeout(SD_TIMEOUT) < 0) {
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
if ((DWORD)buff < 0x20000000 || ((DWORD)buff & 3)) {
|
||||
//TRACE("disk_write bad alignment (%p)", buff);
|
||||
@@ -236,30 +236,37 @@ DRESULT __disk_write(
|
||||
return(res);
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
Status = SD_WriteBlock((uint8_t *)buff, sector, BLOCK_SIZE); // 4GB Compliant
|
||||
}
|
||||
else {
|
||||
Status = SD_WriteMultiBlocks((uint8_t *)buff, sector, BLOCK_SIZE, count); // 4GB Compliant
|
||||
SD_Error Status = SD_WriteBlocks((uint8_t *)buff, sector, BLOCK_SIZE, count);
|
||||
if (Status != SD_OK) {
|
||||
TRACE("SD WriteBlocks=%d, s:%u c: %u", Status, sector, (uint32_t)count);
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
if (Status == SD_OK) {
|
||||
SDTransferState State;
|
||||
// Wait that the reading process is completed or a timeout occurs
|
||||
uint32_t timeout = HAL_GetTick();
|
||||
while((WriteStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT));
|
||||
|
||||
Status = SD_WaitWriteOperation(500*count); // Check if the Transfer is finished
|
||||
if (WriteStatus == 0) {
|
||||
TRACE("SD write timeout, s:%u c:%u", sector, (uint32_t)count);
|
||||
return RES_ERROR;
|
||||
}
|
||||
|
||||
while((State = SD_GetStatus()) == SD_TRANSFER_BUSY); // BUSY, OK (DONE), ERROR (FAIL)
|
||||
WriteStatus = 0;
|
||||
res = RES_ERROR;
|
||||
timeout = HAL_GetTick();
|
||||
|
||||
if ((State == SD_TRANSFER_ERROR) || (Status != SD_OK)) {
|
||||
TRACE("__disk_write() err, st:%d,%d, s:%u c: %u", Status, State, sector, (uint32_t)count);
|
||||
res = RES_ERROR;
|
||||
while((HAL_GetTick() - timeout) < SD_TIMEOUT) {
|
||||
if (SD_GetStatus() == SD_TRANSFER_OK) {
|
||||
res = RES_OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (res != RES_OK) {
|
||||
TRACE("SD getstatus timeout, s:%u c: %u", sector, (uint32_t)count);
|
||||
res = RES_ERROR;
|
||||
}
|
||||
|
||||
// TRACE("result=%d", res);
|
||||
return res;
|
||||
}
|
||||
#endif /* _READONLY */
|
||||
@@ -274,6 +281,7 @@ DRESULT disk_ioctl (
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
uint32_t tmp;
|
||||
|
||||
if (drv) return RES_PARERR;
|
||||
|
||||
@@ -281,24 +289,44 @@ DRESULT disk_ioctl (
|
||||
|
||||
switch (ctrl) {
|
||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
|
||||
// use 512 for sector size, SDCardInfo.CardBlockSize is not sector size and can be 1024 for 2G SD cards!!!!
|
||||
*(DWORD*)buff = SDCardInfo.CardCapacity / BLOCK_SIZE;
|
||||
tmp = SD_GetSectorCount();
|
||||
|
||||
if(tmp == 0) {
|
||||
res = RES_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
*(DWORD*)buff = tmp;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
|
||||
*(WORD*)buff = BLOCK_SIZE; // force sector size. SDCardInfo.CardBlockSize is not sector size and can be 1024 for 2G SD cards!!!!
|
||||
tmp = SD_GetSectorSize();
|
||||
|
||||
if(tmp == 0) {
|
||||
res = RES_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
*(WORD*)buff = tmp;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
|
||||
// TODO verify that this is the correct value
|
||||
*(DWORD*)buff = (uint32_t)SDCardInfo.SD_csd.EraseGrSize * (uint32_t)SDCardInfo.SD_csd.EraseGrMul;
|
||||
tmp = SD_GetBlockSize() / BLOCK_SIZE;
|
||||
|
||||
if(tmp == 0) {
|
||||
res = RES_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
*(DWORD*)buff = tmp;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case CTRL_SYNC:
|
||||
while (SD_GetStatus() == SD_TRANSFER_BUSY); /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
/* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
while (SD_GetStatus() == SD_TRANSFER_BUSY);
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
@@ -310,86 +338,3 @@ DRESULT disk_ioctl (
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO everything here should not be in the driver layer ...
|
||||
|
||||
bool _g_FATFS_init = false;
|
||||
FATFS g_FATFS_Obj __DMA; // initialized in boardInit()
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
FIL g_telemetryFile = {};
|
||||
#endif
|
||||
|
||||
#if defined(BOOT)
|
||||
void sdInit(void)
|
||||
{
|
||||
if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
|
||||
f_chdir("/");
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#include "audio.h"
|
||||
#include "sdcard.h"
|
||||
#include "disk_cache.h"
|
||||
|
||||
void sdInit()
|
||||
{
|
||||
TRACE("sdInit");
|
||||
RTOS_CREATE_MUTEX(ioMutex);
|
||||
sdMount();
|
||||
}
|
||||
|
||||
void sdMount()
|
||||
{
|
||||
TRACE("sdMount");
|
||||
|
||||
#if defined(DISK_CACHE)
|
||||
diskCache.clear();
|
||||
#endif
|
||||
|
||||
if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
|
||||
// call sdGetFreeSectors() now because f_getfree() takes a long time first time it's called
|
||||
_g_FATFS_init = true;
|
||||
sdGetFreeSectors();
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
f_open(&g_telemetryFile, LOGS_PATH "/telemetry.log", FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (f_size(&g_telemetryFile) > 0) {
|
||||
f_lseek(&g_telemetryFile, f_size(&g_telemetryFile)); // append
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
TRACE("f_mount() failed");
|
||||
}
|
||||
}
|
||||
|
||||
void sdDone()
|
||||
{
|
||||
TRACE("sdDone");
|
||||
|
||||
if (sdMounted()) {
|
||||
audioQueue.stopSD();
|
||||
#if defined(LOG_TELEMETRY)
|
||||
f_close(&g_telemetryFile);
|
||||
#endif
|
||||
f_mount(NULL, "", 0); // unmount SD
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t sdMounted()
|
||||
{
|
||||
return _g_FATFS_init && g_FATFS_Obj.fs_type != 0;
|
||||
}
|
||||
|
||||
uint32_t sdIsHC()
|
||||
{
|
||||
return true; // TODO (CardType & CT_BLOCK);
|
||||
}
|
||||
|
||||
uint32_t sdGetSpeed()
|
||||
{
|
||||
return 330000;
|
||||
}
|
||||
@@ -15,6 +15,7 @@ if(NOT NATIVE_BUILD)
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_ll_usart.c
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_ll_rcc.c
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_ll_exti.c
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_ll_sdmmc.c
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_ll_adc.c
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_ll_spi.c
|
||||
# HAL drivers
|
||||
@@ -25,6 +26,8 @@ if(NOT NATIVE_BUILD)
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_hal_rtc.c
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_hal_i2c.c
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_hal_i2c_ex.c
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_hal_sd.c
|
||||
${STM32CUBE_DIR}/Src/stm32f4xx_hal_dma.c
|
||||
)
|
||||
|
||||
target_compile_options(stm32cube_ll PRIVATE -DUSE_FULL_LL_DRIVER)
|
||||
@@ -64,7 +67,6 @@ if(CPU_TYPE_FULL STREQUAL STM32F429xI)
|
||||
${STM32_STDPERIPH_DIR}/src/stm32f4xx_ltdc.c
|
||||
${STM32_STDPERIPH_DIR}/src/stm32f4xx_dma.c
|
||||
${STM32_STDPERIPH_DIR}/src/stm32f4xx_dma2d.c
|
||||
${STM32_STDPERIPH_DIR}/src/stm32f4xx_sdio.c
|
||||
)
|
||||
elseif (CPU_TYPE_FULL STREQUAL STM32F413xG)
|
||||
set(STM32_STDPERIPH_SRC ${STM32_STDPERIPH_SRC}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* 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 "sdio_sd.h"
|
||||
#include "stm32_dma.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_hal.h"
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#include "delays_driver.h"
|
||||
#include "debug.h"
|
||||
|
||||
/* Configure PC.08, PC.09, PC.10, PC.11 pins: D0, D1, D2, D3 pins */
|
||||
#if !defined(SD_SDIO_DATA_GPIO) && !defined(SD_SDIO_DATA_GPIO_PINS)
|
||||
#define SD_SDIO_DATA_GPIO GPIOC
|
||||
#define SD_SDIO_DATA_GPIO_PINS \
|
||||
(LL_GPIO_PIN_8 | LL_GPIO_PIN_9 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11)
|
||||
#endif
|
||||
|
||||
/* Configure PD.02 CMD line */
|
||||
#if !defined(SD_SDIO_CMD_GPIO) && !defined(SD_SDIO_CMD_GPIO_PIN)
|
||||
#define SD_SDIO_CMD_GPIO GPIOD
|
||||
#define SD_SDIO_CMD_GPIO_PIN LL_GPIO_PIN_2
|
||||
#endif
|
||||
|
||||
#if !defined(SD_SDIO_CLK_GPIO) && !defined(SD_SDIO_CLK_GPIO_PIN)
|
||||
#define SD_SDIO_CLK_GPIO GPIOC
|
||||
#define SD_SDIO_CLK_GPIO_PIN LL_GPIO_PIN_12
|
||||
#endif
|
||||
|
||||
static SD_HandleTypeDef sdio;
|
||||
static DMA_HandleTypeDef sdioTxDma;
|
||||
|
||||
// Disk status
|
||||
volatile uint32_t WriteStatus = 0;
|
||||
volatile uint32_t ReadStatus = 0;
|
||||
|
||||
static void SD_LowLevel_Init(void)
|
||||
{
|
||||
/* Enable the SDIO APB2 Clock */
|
||||
__HAL_RCC_SDIO_CLK_ENABLE();
|
||||
|
||||
LL_GPIO_InitTypeDef GPIO_InitStructure;
|
||||
LL_GPIO_StructInit(&GPIO_InitStructure);
|
||||
|
||||
stm32_gpio_enable_clock(SD_SDIO_DATA_GPIO);
|
||||
stm32_gpio_enable_clock(SD_SDIO_CMD_GPIO);
|
||||
stm32_gpio_enable_clock(SD_SDIO_CLK_GPIO);
|
||||
|
||||
GPIO_InitStructure.Pin = SD_SDIO_DATA_GPIO_PINS;
|
||||
GPIO_InitStructure.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Mode = LL_GPIO_MODE_ALTERNATE;
|
||||
GPIO_InitStructure.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
GPIO_InitStructure.Pull = LL_GPIO_PULL_UP;
|
||||
GPIO_InitStructure.Alternate = LL_GPIO_AF_12; // SDIO
|
||||
LL_GPIO_Init(SD_SDIO_DATA_GPIO, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Pin = SD_SDIO_CMD_GPIO_PIN;
|
||||
LL_GPIO_Init(SD_SDIO_CMD_GPIO, &GPIO_InitStructure);
|
||||
|
||||
/* Configure PC.12 pin: CLK pin */
|
||||
GPIO_InitStructure.Pin = SD_SDIO_CLK_GPIO_PIN;
|
||||
GPIO_InitStructure.Pull = LL_GPIO_PULL_NO;
|
||||
LL_GPIO_Init(SD_SDIO_CLK_GPIO, &GPIO_InitStructure);
|
||||
|
||||
// SDIO Interrupt ENABLE
|
||||
NVIC_SetPriority(SDIO_IRQn, 0);
|
||||
NVIC_EnableIRQ(SDIO_IRQn);
|
||||
|
||||
// Init SDIO DMA instance
|
||||
sdioTxDma.Instance = SD_SDIO_DMA_STREAM;
|
||||
sdioTxDma.Init.Channel = SD_SDIO_DMA_CHANNEL;
|
||||
sdioTxDma.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||
sdioTxDma.Init.MemInc = DMA_MINC_ENABLE;
|
||||
sdioTxDma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
|
||||
sdioTxDma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
||||
sdioTxDma.Init.Mode = DMA_PFCTRL;
|
||||
sdioTxDma.Init.Priority = DMA_PRIORITY_VERY_HIGH;
|
||||
sdioTxDma.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
||||
sdioTxDma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||
sdioTxDma.Init.MemBurst = DMA_MBURST_INC4;
|
||||
sdioTxDma.Init.PeriphBurst = DMA_PBURST_INC4;
|
||||
|
||||
stm32_dma_enable_clock(SD_SDIO_DMA);
|
||||
HAL_DMA_Init(&sdioTxDma);
|
||||
|
||||
__HAL_LINKDMA(&sdio, hdmatx, sdioTxDma);
|
||||
__HAL_LINKDMA(&sdio, hdmarx, sdioTxDma);
|
||||
|
||||
// DMA2 STREAMx Interrupt ENABLE
|
||||
NVIC_SetPriority(SD_SDIO_DMA_IRQn, 0);
|
||||
NVIC_EnableIRQ(SD_SDIO_DMA_IRQn);
|
||||
}
|
||||
|
||||
SD_Error SD_Init(void)
|
||||
{
|
||||
static bool _sdio_init = false;
|
||||
|
||||
if(_sdio_init) return SD_OK;
|
||||
_sdio_init = true;
|
||||
|
||||
__IO SD_Error errorstatus = SD_OK;
|
||||
|
||||
/* SDIO Peripheral Low Level Init */
|
||||
SD_LowLevel_Init();
|
||||
|
||||
/*!< Configure the SDIO peripheral */
|
||||
/*!< SDIO_CK = SDIOCLK / (SDIO_TRANSFER_CLK_DIV + 2) */
|
||||
/*!< on STM32F4xx devices, SDIOCLK is fixed to 48MHz */
|
||||
sdio.Instance = SDIO;
|
||||
sdio.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
|
||||
sdio.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
|
||||
sdio.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
|
||||
sdio.Init.BusWide = SDIO_BUS_WIDE_1B;
|
||||
sdio.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
|
||||
sdio.Init.ClockDiv = SD_SDIO_TRANSFER_CLK_DIV;
|
||||
HAL_SD_DeInit(&sdio);
|
||||
|
||||
HAL_StatusTypeDef halStatus = HAL_SD_Init(&sdio);
|
||||
if (halStatus != HAL_OK) {
|
||||
TRACE("SD_PowerON() status=%d", halStatus);
|
||||
/*!< CMD Response TimeOut (wait for CMDSENT flag) */
|
||||
return SD_ERROR;
|
||||
}
|
||||
|
||||
HAL_SD_CardInfoTypeDef cardInfo;
|
||||
HAL_StatusTypeDef es = HAL_SD_GetCardInfo(&sdio, &cardInfo);
|
||||
if(es != HAL_OK)
|
||||
return SD_ERROR;
|
||||
|
||||
HAL_SD_ConfigWideBusOperation(&sdio, SDIO_BUS_WIDE_4B);
|
||||
|
||||
return errorstatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the cuurent sd card data transfer status.
|
||||
* @param None
|
||||
* @retval SDTransferState: Data Transfer state.
|
||||
* This value can be:
|
||||
* - SD_TRANSFER_OK: No data transfer is acting
|
||||
* - SD_TRANSFER_BUSY: Data transfer is acting
|
||||
*/
|
||||
SDTransferState SD_GetStatus(void)
|
||||
{
|
||||
HAL_SD_CardStateTypeDef cardstate = HAL_SD_GetCardState(&sdio);
|
||||
|
||||
if (cardstate == HAL_SD_CARD_TRANSFER) {
|
||||
return SD_TRANSFER_OK;
|
||||
}
|
||||
else if (cardstate == HAL_SD_CARD_ERROR) {
|
||||
return SD_TRANSFER_ERROR;
|
||||
}
|
||||
|
||||
return SD_TRANSFER_BUSY;
|
||||
}
|
||||
|
||||
int SD_CheckStatusWithTimeout(uint32_t timeout)
|
||||
{
|
||||
uint32_t timer = HAL_GetTick();
|
||||
/* block until SDIO IP is ready again or a timeout occur */
|
||||
while(HAL_GetTick() - timer < timeout) {
|
||||
auto state = SD_GetStatus();
|
||||
if (state != SD_TRANSFER_BUSY) {
|
||||
return state == SD_TRANSFER_OK ? 0 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Detect if SD card is correctly plugged in the memory slot.
|
||||
* @param None
|
||||
* @retval Return if SD is detected or not
|
||||
*/
|
||||
uint8_t SD_Detect(void)
|
||||
{
|
||||
__IO uint8_t status = SD_PRESENT;
|
||||
|
||||
/*!< Check GPIO to detect SD */
|
||||
if ((LL_GPIO_ReadInputPort(SD_PRESENT_GPIO) & SD_PRESENT_LL_GPIO_PIN) != 0) {
|
||||
status = SD_NOT_PRESENT;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns information about specific card.
|
||||
* @param cardinfo: pointer to a SD_CardInfo structure that contains all SD card
|
||||
* information.
|
||||
* @retval SD_Error: SD Card Error code.
|
||||
*/
|
||||
SD_Error SD_GetCardInfo(HAL_SD_CardInfoTypeDef *cardinfo)
|
||||
{
|
||||
if(HAL_SD_GetCardInfo(&sdio, cardinfo) != HAL_OK)
|
||||
return SD_ERROR;
|
||||
|
||||
return SD_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allows to read blocks from a specified address in a card. The Data
|
||||
* transfer can be managed by DMA mode or Polling mode.
|
||||
* @note This operation should be followed by two functions to check if the
|
||||
* DMA Controller and SD Card status.
|
||||
* - SD_ReadWaitOperation(): this function insure that the DMA
|
||||
* controller has finished all data transfer.
|
||||
* - SD_GetStatus(): to check that the SD Card has finished the
|
||||
* data transfer and it is ready for data.
|
||||
* @param readbuff: pointer to the buffer that will contain the received data.
|
||||
* @param ReadAddr: Address from where data are to be read.
|
||||
* @param BlockSize: the SD card Data block size. The Block size should be 512.
|
||||
* @param NumberOfBlocks: number of blocks to be read.
|
||||
* @retval SD_Error: SD Card Error code.
|
||||
*/
|
||||
SD_Error SD_ReadBlocks(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
|
||||
{
|
||||
HAL_StatusTypeDef res = HAL_SD_ReadBlocks_DMA(&sdio, readbuff, ReadAddr, NumberOfBlocks);
|
||||
if(res == HAL_OK)
|
||||
return SD_OK;
|
||||
|
||||
return SD_ERROR;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @brief This function waits until the SDIO DMA data transfer is finished.
|
||||
// * This function should be called after SDIO_ReadMultiBlocks() function
|
||||
// * to insure that all data sent by the card are already transferred by
|
||||
// * the DMA controller.
|
||||
// * @param None.
|
||||
// * @retval SD_Error: SD Card Error code.
|
||||
// */
|
||||
// SD_Error SD_WaitReadOperation(uint32_t timeout)
|
||||
// {
|
||||
// volatile HAL_SD_CardStateTypeDef state = HAL_SD_GetCardState(&sdio);
|
||||
// if(state == HAL_SD_CARD_READY || state == HAL_SD_CARD_TRANSFER)
|
||||
// return SD_OK;
|
||||
// timeout = 100;
|
||||
|
||||
// while((HAL_SD_GetCardState(&sdio) == HAL_SD_CARD_SENDING) && (timeout > 0)) {
|
||||
// delay_ms(1);
|
||||
// timeout--;
|
||||
// }
|
||||
|
||||
// state = HAL_SD_GetCardState(&sdio);
|
||||
// if(timeout > 0 && state == HAL_SD_CARD_TRANSFER)
|
||||
// return SD_OK;
|
||||
|
||||
// return SD_ERROR;
|
||||
// }
|
||||
|
||||
/**
|
||||
* @brief Allows to write blocks starting from a specified address in a card.
|
||||
* The Data transfer can be managed by DMA mode only.
|
||||
* @note This operation should be followed by two functions to check if the
|
||||
* DMA Controller and SD Card status.
|
||||
* - SD_ReadWaitOperation(): this function insure that the DMA
|
||||
* controller has finished all data transfer.
|
||||
* - SD_GetStatus(): to check that the SD Card has finished the
|
||||
* data transfer and it is ready for data.
|
||||
* @param WriteAddr: Address from where data are to be read.
|
||||
* @param writebuff: pointer to the buffer that contain the data to be transferred.
|
||||
* @param BlockSize: the SD card Data block size. The Block size should be 512.
|
||||
* @param NumberOfBlocks: number of blocks to be written.
|
||||
* @retval SD_Error: SD Card Error code.
|
||||
*/
|
||||
SD_Error SD_WriteBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
|
||||
{
|
||||
HAL_StatusTypeDef res = HAL_SD_WriteBlocks_DMA(&sdio, writebuff, WriteAddr, NumberOfBlocks);
|
||||
if(res == HAL_OK)
|
||||
return SD_OK;
|
||||
return SD_ERROR;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @brief This function waits until the SDIO DMA data transfer is finished.
|
||||
// * This function should be called after SDIO_WriteBlock() and
|
||||
// * SDIO_WriteMultiBlocks() function to insure that all data sent by the
|
||||
// * card are already transferred by the DMA controller.
|
||||
// * @param None.
|
||||
// * @retval SD_Error: SD Card Error code.
|
||||
// */
|
||||
// OPTIMIZE("O0") SD_Error SD_WaitWriteOperation(uint32_t timeout)
|
||||
// {
|
||||
// HAL_SD_CardStateTypeDef state = HAL_SD_GetCardState(&sdio);
|
||||
// if(state == HAL_SD_CARD_READY || state == HAL_SD_CARD_TRANSFER)
|
||||
// return SD_OK;
|
||||
|
||||
// timeout = 1000;
|
||||
|
||||
// state = HAL_SD_GetCardState(&sdio);
|
||||
// while((state == HAL_SD_CARD_RECEIVING || state == HAL_SD_CARD_PROGRAMMING) && (timeout > 0)) {
|
||||
// delay_ms(1);
|
||||
// timeout--;
|
||||
// state = HAL_SD_GetCardState(&sdio);
|
||||
// }
|
||||
|
||||
// state = HAL_SD_GetCardState(&sdio);
|
||||
// if(timeout > 0 && state == HAL_SD_CARD_TRANSFER)
|
||||
// return SD_OK;
|
||||
|
||||
// return SD_ERROR;
|
||||
// }
|
||||
|
||||
uint32_t SD_GetSectorCount()
|
||||
{
|
||||
HAL_SD_CardInfoTypeDef cardInfo;
|
||||
|
||||
if(SD_GetCardInfo(&cardInfo) != SD_OK)
|
||||
return 0;
|
||||
|
||||
return cardInfo.LogBlockNbr;
|
||||
}
|
||||
|
||||
uint32_t SD_GetSectorSize()
|
||||
{
|
||||
HAL_SD_CardInfoTypeDef cardInfo;
|
||||
|
||||
if(SD_GetCardInfo(&cardInfo) != SD_OK)
|
||||
return 0;
|
||||
|
||||
return cardInfo.LogBlockSize;
|
||||
}
|
||||
|
||||
uint32_t SD_GetBlockSize()
|
||||
{
|
||||
HAL_SD_CardInfoTypeDef cardInfo;
|
||||
|
||||
if(SD_GetCardInfo(&cardInfo) != SD_OK)
|
||||
return 0;
|
||||
|
||||
return cardInfo.LogBlockSize;
|
||||
}
|
||||
|
||||
uint32_t SD_GetCardType()
|
||||
{
|
||||
HAL_SD_CardInfoTypeDef cardInfo;
|
||||
|
||||
if(SD_GetCardInfo(&cardInfo) != SD_OK)
|
||||
return 0;
|
||||
|
||||
return cardInfo.CardType;
|
||||
}
|
||||
|
||||
uint32_t SD_GetCardVersion()
|
||||
{
|
||||
HAL_SD_CardInfoTypeDef cardInfo;
|
||||
|
||||
if(SD_GetCardInfo(&cardInfo) != SD_OK)
|
||||
return 0;
|
||||
|
||||
return cardInfo.CardVersion;
|
||||
}
|
||||
|
||||
uint32_t SD_GetCardClass()
|
||||
{
|
||||
HAL_SD_CardInfoTypeDef cardInfo;
|
||||
|
||||
if(SD_GetCardInfo(&cardInfo) != SD_OK)
|
||||
return 0;
|
||||
|
||||
return cardInfo.Class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tx Transfer completed callbacks
|
||||
* @param hsd: SD handle
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
extern "C" void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
|
||||
{
|
||||
UNUSED(hsd);
|
||||
WriteStatus = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rx Transfer completed callbacks
|
||||
* @param hsd: SD handle
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
extern "C" void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
|
||||
{
|
||||
UNUSED(hsd);
|
||||
ReadStatus = 1;
|
||||
}
|
||||
|
||||
extern "C" void SDIO_IRQHandler(void)
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_SDIO);
|
||||
HAL_SD_IRQHandler(&sdio);
|
||||
}
|
||||
extern "C" void SD_SDIO_DMA_IRQHANDLER(void)
|
||||
{
|
||||
DEBUG_INTERRUPT(INT_SDIO_DMA);
|
||||
HAL_DMA_IRQHandler(&sdioTxDma);
|
||||
}
|
||||
@@ -23,62 +23,11 @@
|
||||
#ifndef _SDIO_SD_H_
|
||||
#define _SDIO_SD_H_
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <stdint.h>
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
typedef enum
|
||||
{
|
||||
/**
|
||||
* @brief SDIO specific error defines
|
||||
*/
|
||||
SD_CMD_CRC_FAIL = (1), /*!< Command response received (but CRC check failed) */
|
||||
SD_DATA_CRC_FAIL = (2), /*!< Data bock sent/received (CRC check Failed) */
|
||||
SD_CMD_RSP_TIMEOUT = (3), /*!< Command response timeout */
|
||||
SD_DATA_TIMEOUT = (4), /*!< Data time out */
|
||||
SD_TX_UNDERRUN = (5), /*!< Transmit FIFO under-run */
|
||||
SD_RX_OVERRUN = (6), /*!< Receive FIFO over-run */
|
||||
SD_START_BIT_ERR = (7), /*!< Start bit not detected on all data signals in widE bus mode */
|
||||
SD_CMD_OUT_OF_RANGE = (8), /*!< CMD's argument was out of range.*/
|
||||
SD_ADDR_MISALIGNED = (9), /*!< Misaligned address */
|
||||
SD_BLOCK_LEN_ERR = (10), /*!< Transferred block length is not allowed for the card or the number of transferred bytes does not match the block length */
|
||||
SD_ERASE_SEQ_ERR = (11), /*!< An error in the sequence of erase command occurs.*/
|
||||
SD_BAD_ERASE_PARAM = (12), /*!< An Invalid selection for erase groups */
|
||||
SD_WRITE_PROT_VIOLATION = (13), /*!< Attempt to program a write protect block */
|
||||
SD_LOCK_UNLOCK_FAILED = (14), /*!< Sequence or password error has been detected in unlock command or if there was an attempt to access a locked card */
|
||||
SD_COM_CRC_FAILED = (15), /*!< CRC check of the previous command failed */
|
||||
SD_ILLEGAL_CMD = (16), /*!< Command is not legal for the card state */
|
||||
SD_CARD_ECC_FAILED = (17), /*!< Card internal ECC was applied but failed to correct the data */
|
||||
SD_CC_ERROR = (18), /*!< Internal card controller error */
|
||||
SD_GENERAL_UNKNOWN_ERROR = (19), /*!< General or Unknown error */
|
||||
SD_STREAM_READ_UNDERRUN = (20), /*!< The card could not sustain data transfer in stream read operation. */
|
||||
SD_STREAM_WRITE_OVERRUN = (21), /*!< The card could not sustain data programming in stream mode */
|
||||
SD_CID_CSD_OVERWRITE = (22), /*!< CID/CSD overwrite error */
|
||||
SD_WP_ERASE_SKIP = (23), /*!< only partial address space was erased */
|
||||
SD_CARD_ECC_DISABLED = (24), /*!< Command has been executed without using internal ECC */
|
||||
SD_ERASE_RESET = (25), /*!< Erase sequence was cleared before executing because an out of erase sequence command was received */
|
||||
SD_AKE_SEQ_ERROR = (26), /*!< Error in sequence of authentication. */
|
||||
SD_INVALID_VOLTRANGE = (27),
|
||||
SD_ADDR_OUT_OF_RANGE = (28),
|
||||
SD_SWITCH_ERROR = (29),
|
||||
SD_SDIO_DISABLED = (30),
|
||||
SD_SDIO_FUNCTION_BUSY = (31),
|
||||
SD_SDIO_FUNCTION_FAILED = (32),
|
||||
SD_SDIO_UNKNOWN_FUNCTION = (33),
|
||||
|
||||
/**
|
||||
* @brief Standard error defines
|
||||
*/
|
||||
SD_INTERNAL_ERROR,
|
||||
SD_NOT_CONFIGURED,
|
||||
SD_REQUEST_PENDING,
|
||||
SD_REQUEST_NOT_APPLICABLE,
|
||||
SD_INVALID_PARAMETER,
|
||||
SD_UNSUPPORTED_FEATURE,
|
||||
SD_UNSUPPORTED_HW,
|
||||
SD_ERROR,
|
||||
SD_OK = 0
|
||||
} SD_Error;
|
||||
@@ -93,106 +42,29 @@ typedef enum
|
||||
SD_TRANSFER_ERROR
|
||||
} SDTransferState;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Card Specific Data: CSD Register
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IO uint8_t CSDStruct; /*!< CSD structure */
|
||||
__IO uint8_t SysSpecVersion; /*!< System specification version */
|
||||
__IO uint8_t Reserved1; /*!< Reserved */
|
||||
__IO uint8_t TAAC; /*!< Data read access-time 1 */
|
||||
__IO uint8_t NSAC; /*!< Data read access-time 2 in CLK cycles */
|
||||
__IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */
|
||||
__IO uint16_t CardComdClasses; /*!< Card command classes */
|
||||
__IO uint8_t RdBlockLen; /*!< Max. read data block length */
|
||||
__IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */
|
||||
__IO uint8_t WrBlockMisalign; /*!< Write block misalignment */
|
||||
__IO uint8_t RdBlockMisalign; /*!< Read block misalignment */
|
||||
__IO uint8_t DSRImpl; /*!< DSR implemented */
|
||||
__IO uint8_t Reserved2; /*!< Reserved */
|
||||
__IO uint32_t DeviceSize; /*!< Device Size */
|
||||
__IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */
|
||||
__IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */
|
||||
__IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */
|
||||
__IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */
|
||||
__IO uint8_t DeviceSizeMul; /*!< Device size multiplier */
|
||||
__IO uint8_t EraseGrSize; /*!< Erase group size */
|
||||
__IO uint8_t EraseGrMul; /*!< Erase group size multiplier */
|
||||
__IO uint8_t WrProtectGrSize; /*!< Write protect group size */
|
||||
__IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */
|
||||
__IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */
|
||||
__IO uint8_t WrSpeedFact; /*!< Write speed factor */
|
||||
__IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */
|
||||
__IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */
|
||||
__IO uint8_t Reserved3; /*!< Reserded */
|
||||
__IO uint8_t ContentProtectAppli; /*!< Content protection application */
|
||||
__IO uint8_t FileFormatGrouop; /*!< File format group */
|
||||
__IO uint8_t CopyFlag; /*!< Copy flag (OTP) */
|
||||
__IO uint8_t PermWrProtect; /*!< Permanent write protection */
|
||||
__IO uint8_t TempWrProtect; /*!< Temporary write protection */
|
||||
__IO uint8_t FileFormat; /*!< File Format */
|
||||
__IO uint8_t ECC; /*!< ECC code */
|
||||
__IO uint8_t CSD_CRC; /*!< CSD CRC */
|
||||
__IO uint8_t Reserved4; /*!< always 1*/
|
||||
} SD_CSD;
|
||||
|
||||
/**
|
||||
* @brief Card Identification Data: CID Register
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IO uint8_t ManufacturerID; /*!< ManufacturerID */
|
||||
__IO uint16_t OEM_AppliID; /*!< OEM/Application ID */
|
||||
__IO uint32_t ProdName1; /*!< Product Name part1 */
|
||||
__IO uint8_t ProdName2; /*!< Product Name part2*/
|
||||
__IO uint8_t ProdRev; /*!< Product Revision */
|
||||
__IO uint32_t ProdSN; /*!< Product Serial Number */
|
||||
__IO uint8_t Reserved1; /*!< Reserved1 */
|
||||
__IO uint16_t ManufactDate; /*!< Manufacturing Date */
|
||||
__IO uint8_t CID_CRC; /*!< CID CRC */
|
||||
__IO uint8_t Reserved2; /*!< always 1 */
|
||||
} SD_CID;
|
||||
|
||||
/**
|
||||
* @brief SD Card information
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
SD_CSD SD_csd;
|
||||
SD_CID SD_cid;
|
||||
uint64_t CardCapacity; /*!< Card Capacity */
|
||||
uint32_t CardBlockSize; /*!< Card Block Size */
|
||||
uint16_t RCA;
|
||||
uint8_t CardType;
|
||||
} SD_CardInfo;
|
||||
|
||||
/**
|
||||
* @brief SD detection on its memory slot
|
||||
*/
|
||||
#define SD_PRESENT ((uint8_t)0x01)
|
||||
#define SD_NOT_PRESENT ((uint8_t)0x00)
|
||||
|
||||
// void SD_DeInit(void);
|
||||
SD_Error SD_Init(void);
|
||||
SDTransferState SD_GetStatus(void);
|
||||
int SD_CheckStatusWithTimeout(uint32_t timeout);
|
||||
uint8_t SD_Detect(void);
|
||||
SD_Error SD_PowerOFF(void);
|
||||
SD_Error SD_ReadBlock(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize);
|
||||
SD_Error SD_ReadMultiBlocks(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
|
||||
SD_Error SD_WriteBlock(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize);
|
||||
SD_Error SD_WriteMultiBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
|
||||
SD_Error SD_ReadBlocks(uint8_t *readbuff, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
|
||||
SD_Error SD_WriteBlocks(uint8_t *writebuff, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks);
|
||||
SDTransferState SD_GetTransferState(void);
|
||||
SD_Error SD_WaitReadOperation(uint32_t timeout);
|
||||
SD_Error SD_WaitWriteOperation(uint32_t timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
extern SD_CardInfo SDCardInfo;
|
||||
uint32_t SD_GetSectorCount();
|
||||
uint32_t SD_GetSectorSize();
|
||||
uint32_t SD_GetBlockSize();
|
||||
uint32_t SD_GetCardType();
|
||||
uint32_t SD_GetCardVersion();
|
||||
uint32_t SD_GetCardClass();
|
||||
|
||||
#endif // _SDIO_SD_H_
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
// #define HAL_RNG_MODULE_ENABLED
|
||||
#define HAL_RTC_MODULE_ENABLED
|
||||
// #define HAL_SAI_MODULE_ENABLED
|
||||
// #define HAL_SD_MODULE_ENABLED
|
||||
#define HAL_SD_MODULE_ENABLED
|
||||
// #define HAL_SPI_MODULE_ENABLED
|
||||
// #define HAL_TIM_MODULE_ENABLED
|
||||
// #define HAL_UART_MODULE_ENABLED
|
||||
|
||||
@@ -28,6 +28,13 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
#error "Variable sector size is not supported"
|
||||
#endif
|
||||
|
||||
#define BLOCK_SIZE FF_MAX_SS
|
||||
|
||||
#if !defined(BOOT)
|
||||
#include "timers_driver.h"
|
||||
#define WATCHDOG_SUSPEND(x) watchdogSuspend(x)
|
||||
|
||||
@@ -273,7 +273,8 @@ set(FIRMWARE_SRC
|
||||
targets/common/arm/stm32/heartbeat_driver.cpp
|
||||
targets/common/arm/stm32/trainer_driver.cpp
|
||||
targets/common/arm/stm32/ads79xx.cpp
|
||||
targets/common/arm/stm32/sdio_sd.c
|
||||
targets/common/arm/stm32/sdio_sd.cpp
|
||||
targets/common/arm/stm32/diskio_sdio.cpp
|
||||
)
|
||||
|
||||
if(BOOTLOADER)
|
||||
|
||||
@@ -261,4 +261,3 @@ bool isBacklightEnabled()
|
||||
if (globalData.unexpectedShutdown) return true;
|
||||
return boardBacklightOn;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,27 +92,10 @@ enum {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// SD driver
|
||||
#define BLOCK_SIZE 512 /* Block Size in Bytes */
|
||||
#if !defined(SIMU) || defined(SIMU_DISKIO)
|
||||
uint32_t sdIsHC();
|
||||
uint32_t sdGetSpeed();
|
||||
#define SD_IS_HC() (sdIsHC())
|
||||
#define SD_GET_SPEED() (sdGetSpeed())
|
||||
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
|
||||
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
|
||||
void sdInit();
|
||||
void sdMount();
|
||||
void sdDone();
|
||||
#define sdPoll10ms()
|
||||
uint32_t sdMounted();
|
||||
#if defined(SIMU)
|
||||
#define SD_CARD_PRESENT() true
|
||||
#else
|
||||
#define SD_IS_HC() (0)
|
||||
#define SD_GET_SPEED() (0)
|
||||
#define sdInit()
|
||||
#define sdMount()
|
||||
#define sdDone()
|
||||
#define SD_CARD_PRESENT() true
|
||||
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
|
||||
#endif
|
||||
|
||||
// Flash Write driver
|
||||
|
||||
@@ -1,408 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2007 */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* This is a stub disk I/O module that acts as front end of the existing */
|
||||
/* disk I/O modules and attach it to FatFs module with common interface. */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
||||
#include "diskio.h"
|
||||
#include "debug.h"
|
||||
#include "targets/common/arm/stm32/sdio_sd.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Lock / unlock functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#if !defined(BOOT)
|
||||
static RTOS_MUTEX_HANDLE ioMutex;
|
||||
uint32_t ioMutexReq = 0, ioMutexRel = 0;
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t * mutex)
|
||||
{
|
||||
*mutex = ioMutex;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ff_req_grant (FF_SYNC_t mutex)
|
||||
{
|
||||
ioMutexReq += 1;
|
||||
RTOS_LOCK_MUTEX(mutex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ff_rel_grant (FF_SYNC_t mutex)
|
||||
{
|
||||
ioMutexRel += 1;
|
||||
RTOS_UNLOCK_MUTEX(mutex);
|
||||
}
|
||||
|
||||
int ff_del_syncobj (FF_SYNC_t mutex)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Inidialize a Drive */
|
||||
|
||||
DSTATUS disk_initialize (
|
||||
BYTE drv /* Physical drive nmuber (0..) */
|
||||
)
|
||||
{
|
||||
DSTATUS stat = 0;
|
||||
|
||||
/* Supports only single drive */
|
||||
if (drv)
|
||||
{
|
||||
stat |= STA_NOINIT;
|
||||
}
|
||||
|
||||
/*-------------------------- SD Init ----------------------------- */
|
||||
SD_Error res = SD_Init();
|
||||
if (res != SD_OK)
|
||||
{
|
||||
TRACE("SD_Init() failed: %d", res);
|
||||
stat |= STA_NOINIT;
|
||||
}
|
||||
|
||||
TRACE("SD card info:");
|
||||
TRACE("sectors: %u", (uint32_t)(SDCardInfo.CardCapacity / 512));
|
||||
TRACE("type: %u", (uint32_t)(SDCardInfo.CardType));
|
||||
TRACE("EraseGrSize: %u", (uint32_t)(SDCardInfo.SD_csd.EraseGrSize));
|
||||
TRACE("EraseGrMul: %u", (uint32_t)(SDCardInfo.SD_csd.EraseGrMul));
|
||||
TRACE("ManufacturerID: %u", (uint32_t)(SDCardInfo.SD_cid.ManufacturerID));
|
||||
|
||||
return(stat);
|
||||
}
|
||||
|
||||
DWORD scratch[BLOCK_SIZE / 4] __DMA;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Return Disk Status */
|
||||
|
||||
DSTATUS disk_status (
|
||||
BYTE drv /* Physical drive nmuber (0..) */
|
||||
)
|
||||
{
|
||||
DSTATUS stat = 0;
|
||||
|
||||
if (SD_Detect() != SD_PRESENT)
|
||||
stat |= STA_NODISK;
|
||||
|
||||
// STA_NOTINIT - Subsystem not initailized
|
||||
// STA_PROTECTED - Write protected, MMC/SD switch if available
|
||||
|
||||
return(stat);
|
||||
}
|
||||
|
||||
uint32_t sdReadRetries = 0;
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read Sector(s) */
|
||||
|
||||
|
||||
DRESULT disk_read_dma(BYTE drv, BYTE * buff, DWORD sector, UINT count)
|
||||
{
|
||||
// this functions assumes that buff is properly aligned and in the right RAM segment for DMA
|
||||
DRESULT res;
|
||||
SD_Error Status;
|
||||
SDTransferState State;
|
||||
for (int retry=0; retry<3; retry++) {
|
||||
res = RES_OK;
|
||||
if (count == 1) {
|
||||
Status = SD_ReadBlock(buff, sector, BLOCK_SIZE); // 4GB Compliant
|
||||
}
|
||||
else {
|
||||
Status = SD_ReadMultiBlocks(buff, sector, BLOCK_SIZE, count); // 4GB Compliant
|
||||
}
|
||||
if (Status == SD_OK) {
|
||||
Status = SD_WaitReadOperation(200*count); // Check if the Transfer is finished
|
||||
while ((State = SD_GetStatus()) == SD_TRANSFER_BUSY); // BUSY, OK (DONE), ERROR (FAIL)
|
||||
if (State == SD_TRANSFER_ERROR) {
|
||||
TRACE("State=SD_TRANSFER_ERROR, c: %u", sector, (uint32_t)count);
|
||||
res = RES_ERROR;
|
||||
}
|
||||
else if (Status != SD_OK) {
|
||||
TRACE("Status(WaitRead)=%d, s:%u c: %u", Status, sector, (uint32_t)count);
|
||||
res = RES_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRACE("Status(ReadBlock)=%d, s:%u c: %u", Status, sector, (uint32_t)count);
|
||||
res = RES_ERROR;
|
||||
}
|
||||
if (res == RES_OK) break;
|
||||
sdReadRetries += 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
DRESULT __disk_read(BYTE drv, BYTE * buff, DWORD sector, UINT count)
|
||||
{
|
||||
// If unaligned, do the single block reads with a scratch buffer.
|
||||
// If aligned and single sector, do a single block read.
|
||||
// If aligned and multiple sectors, try multi block read.
|
||||
// If multi block read fails, try single block reads without
|
||||
// an intermediate buffer (move trough the provided buffer)
|
||||
|
||||
// TRACE("disk_read %d %p %10d %d", drv, buff, sector, count);
|
||||
if (SD_Detect() != SD_PRESENT) {
|
||||
TRACE("SD_Detect() != SD_PRESENT");
|
||||
return RES_NOTRDY;
|
||||
}
|
||||
|
||||
DRESULT res = RES_OK;
|
||||
if (count == 0) return res;
|
||||
|
||||
if ((DWORD)buff < 0x20000000 || ((DWORD)buff & 3)) {
|
||||
// buffer is not aligned, use scratch buffer that is aligned
|
||||
TRACE("disk_read bad alignment (%p)", buff);
|
||||
while (count--) {
|
||||
res = disk_read_dma(drv, (BYTE *)scratch, sector++, 1);
|
||||
if (res != RES_OK) break;
|
||||
memcpy(buff, scratch, BLOCK_SIZE);
|
||||
buff += BLOCK_SIZE;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
res = disk_read_dma(drv, buff, sector, count);
|
||||
if (res != RES_OK && count > 1) {
|
||||
// multi-read failed, try reading same sectors, one by one
|
||||
TRACE("disk_read() multi-block failed, trying single block reads...");
|
||||
while (count--) {
|
||||
res = disk_read_dma(drv, buff, sector++, 1);
|
||||
if (res != RES_OK) break;
|
||||
buff += BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write Sector(s) */
|
||||
|
||||
#if _READONLY == 0
|
||||
DRESULT __disk_write(
|
||||
BYTE drv, /* Physical drive nmuber (0..) */
|
||||
const BYTE *buff, /* Data to be written */
|
||||
DWORD sector, /* Sector address (LBA) */
|
||||
UINT count /* Number of sectors to write (1..255) */
|
||||
)
|
||||
{
|
||||
SD_Error Status;
|
||||
DRESULT res = RES_OK;
|
||||
|
||||
// TRACE("disk_write %d %p %10d %d", drv, buff, sector, count);
|
||||
|
||||
if (SD_Detect() != SD_PRESENT)
|
||||
return(RES_NOTRDY);
|
||||
|
||||
if ((DWORD)buff < 0x20000000 || ((DWORD)buff & 3)) {
|
||||
//TRACE("disk_write bad alignment (%p)", buff);
|
||||
while(count--) {
|
||||
memcpy(scratch, buff, BLOCK_SIZE);
|
||||
|
||||
res = __disk_write(drv, (BYTE *)scratch, sector++, 1);
|
||||
|
||||
if (res != RES_OK)
|
||||
break;
|
||||
|
||||
buff += BLOCK_SIZE;
|
||||
}
|
||||
return(res);
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
Status = SD_WriteBlock((uint8_t *)buff, sector, BLOCK_SIZE); // 4GB Compliant
|
||||
}
|
||||
else {
|
||||
Status = SD_WriteMultiBlocks((uint8_t *)buff, sector, BLOCK_SIZE, count); // 4GB Compliant
|
||||
}
|
||||
|
||||
if (Status == SD_OK) {
|
||||
SDTransferState State;
|
||||
|
||||
Status = SD_WaitWriteOperation(500*count); // Check if the Transfer is finished
|
||||
|
||||
while((State = SD_GetStatus()) == SD_TRANSFER_BUSY); // BUSY, OK (DONE), ERROR (FAIL)
|
||||
|
||||
if ((State == SD_TRANSFER_ERROR) || (Status != SD_OK)) {
|
||||
TRACE("__disk_write() err, st:%d,%d, s:%u c: %u", Status, State, sector, (uint32_t)count);
|
||||
res = RES_ERROR;
|
||||
}
|
||||
}
|
||||
else {
|
||||
res = RES_ERROR;
|
||||
}
|
||||
|
||||
// TRACE("result=%d", res);
|
||||
return res;
|
||||
}
|
||||
#endif /* _READONLY */
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Functions */
|
||||
|
||||
DRESULT disk_ioctl (
|
||||
BYTE drv, /* Physical drive nmuber (0..) */
|
||||
BYTE ctrl, /* Control code */
|
||||
void *buff /* Buffer to send/receive control data */
|
||||
)
|
||||
{
|
||||
DRESULT res;
|
||||
|
||||
if (drv) return RES_PARERR;
|
||||
|
||||
res = RES_ERROR;
|
||||
|
||||
switch (ctrl) {
|
||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
|
||||
// use 512 for sector size, SDCardInfo.CardBlockSize is not sector size and can be 1024 for 2G SD cards!!!!
|
||||
*(DWORD*)buff = SDCardInfo.CardCapacity / BLOCK_SIZE;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */
|
||||
*(WORD*)buff = BLOCK_SIZE; // force sector size. SDCardInfo.CardBlockSize is not sector size and can be 1024 for 2G SD cards!!!!
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
|
||||
// TODO verify that this is the correct value
|
||||
*(DWORD*)buff = (uint32_t)SDCardInfo.SD_csd.EraseGrSize * (uint32_t)SDCardInfo.SD_csd.EraseGrMul;
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
case CTRL_SYNC:
|
||||
while (SD_GetStatus() == SD_TRANSFER_BUSY); /* Complete pending write process (needed at _FS_READONLY == 0) */
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
default:
|
||||
res = RES_OK;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO everything here should not be in the driver layer ...
|
||||
|
||||
bool _g_FATFS_init = false;
|
||||
FATFS g_FATFS_Obj __DMA; // this is in uninitialised section !!!
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
FIL g_telemetryFile = {};
|
||||
#endif
|
||||
|
||||
#if defined(LOG_BLUETOOTH)
|
||||
FIL g_bluetoothFile = {};
|
||||
#endif
|
||||
|
||||
#if defined(BOOT)
|
||||
void sdInit(void)
|
||||
{
|
||||
if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
|
||||
f_chdir("/");
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
#include "audio.h"
|
||||
#include "sdcard.h"
|
||||
#include "disk_cache.h"
|
||||
|
||||
void sdInit()
|
||||
{
|
||||
TRACE("sdInit");
|
||||
RTOS_CREATE_MUTEX(ioMutex);
|
||||
sdMount();
|
||||
}
|
||||
|
||||
void sdMount()
|
||||
{
|
||||
TRACE("sdMount");
|
||||
|
||||
diskCache.clear();
|
||||
|
||||
if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
|
||||
// call sdGetFreeSectors() now because f_getfree() takes a long time first time it's called
|
||||
_g_FATFS_init = true;
|
||||
sdGetFreeSectors();
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
f_open(&g_telemetryFile, LOGS_PATH "/telemetry.log", FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (f_size(&g_telemetryFile) > 0) {
|
||||
f_lseek(&g_telemetryFile, f_size(&g_telemetryFile)); // append
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LOG_BLUETOOTH)
|
||||
f_open(&g_bluetoothFile, LOGS_PATH "/bluetooth.log", FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (f_size(&g_bluetoothFile) > 0) {
|
||||
f_lseek(&g_bluetoothFile, f_size(&g_bluetoothFile)); // append
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
TRACE("f_mount() failed");
|
||||
}
|
||||
}
|
||||
|
||||
void sdDone()
|
||||
{
|
||||
TRACE("sdDone");
|
||||
|
||||
if (sdMounted()) {
|
||||
audioQueue.stopSD();
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
f_close(&g_telemetryFile);
|
||||
#endif
|
||||
|
||||
#if defined(LOG_BLUETOOTH)
|
||||
f_close(&g_bluetoothFile);
|
||||
#endif
|
||||
|
||||
f_mount(nullptr, "", 0); // unmount SD
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t sdMounted()
|
||||
{
|
||||
return _g_FATFS_init && (g_FATFS_Obj.fs_type != 0);
|
||||
}
|
||||
|
||||
uint32_t sdIsHC()
|
||||
{
|
||||
return true; // TODO (CardType & CT_BLOCK);
|
||||
}
|
||||
|
||||
uint32_t sdGetSpeed()
|
||||
{
|
||||
return 330000;
|
||||
}
|
||||
@@ -620,16 +620,12 @@
|
||||
#define SD_RCC_APB1Periph 0
|
||||
#define SD_PRESENT_GPIO GPIOC
|
||||
#define SD_PRESENT_GPIO_PIN GPIO_Pin_5 // PC.05
|
||||
#define SD_PRESENT_LL_GPIO_PIN LL_GPIO_PIN_5 // PC.05
|
||||
#define SD_SDIO_DMA DMA2
|
||||
#define SD_SDIO_DMA_STREAM DMA2_Stream3
|
||||
#define SD_SDIO_DMA_CHANNEL DMA_Channel_4
|
||||
#define SD_SDIO_DMA_FLAG_FEIF DMA_FLAG_FEIF3
|
||||
#define SD_SDIO_DMA_FLAG_DMEIF DMA_FLAG_DMEIF3
|
||||
#define SD_SDIO_DMA_FLAG_TEIF DMA_FLAG_TEIF3
|
||||
#define SD_SDIO_DMA_FLAG_HTIF DMA_FLAG_HTIF3
|
||||
#define SD_SDIO_DMA_FLAG_TCIF DMA_FLAG_TCIF3
|
||||
#define SD_SDIO_DMA_CHANNEL LL_DMA_CHANNEL_4
|
||||
#define SD_SDIO_DMA_IRQn DMA2_Stream3_IRQn
|
||||
#define SD_SDIO_DMA_IRQHANDLER DMA2_Stream3_IRQHandler
|
||||
#define SD_SDIO_FIFO_ADDRESS ((uint32_t)0x40012C80)
|
||||
#define SD_SDIO_CLK_DIV(fq) ((48000000 / (fq)) - 2)
|
||||
#define SD_SDIO_INIT_CLK_DIV SD_SDIO_CLK_DIV(400000)
|
||||
#define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000)
|
||||
|
||||
@@ -147,7 +147,8 @@ set(FIRMWARE_SRC
|
||||
targets/common/arm/stm32/stm32_usart_driver.cpp
|
||||
targets/common/arm/stm32/trainer_driver.cpp
|
||||
targets/common/arm/stm32/pwr_driver.cpp
|
||||
targets/common/arm/stm32/sdio_sd.c
|
||||
targets/common/arm/stm32/sdio_sd.cpp
|
||||
targets/common/arm/stm32/diskio_sdio.cpp
|
||||
)
|
||||
|
||||
# Make malloc() thread-safe
|
||||
|
||||
@@ -273,9 +273,6 @@ void boardInit()
|
||||
keysInit();
|
||||
switchInit();
|
||||
audioInit();
|
||||
// we need to initialize g_FATFS_Obj here, because it is in .ram section (because of DMA access)
|
||||
// and this section is un-initialized
|
||||
memset(&g_FATFS_Obj, 0, sizeof(g_FATFS_Obj));
|
||||
monitorInit();
|
||||
adcInit(&_adc_driver);
|
||||
hapticInit();
|
||||
|
||||
@@ -53,27 +53,10 @@ void boardOff();
|
||||
#define LEN_CPU_UID (3*8+2)
|
||||
void getCPUUniqueID(char * s);
|
||||
|
||||
// SD driver
|
||||
#define BLOCK_SIZE 512 /* Block Size in Bytes */
|
||||
#if !defined(SIMU) || defined(SIMU_DISKIO)
|
||||
uint32_t sdIsHC();
|
||||
uint32_t sdGetSpeed();
|
||||
#define SD_IS_HC() (sdIsHC())
|
||||
#define SD_GET_SPEED() (sdGetSpeed())
|
||||
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
|
||||
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
|
||||
void sdInit();
|
||||
void sdMount();
|
||||
void sdDone();
|
||||
#define sdPoll10ms()
|
||||
uint32_t sdMounted();
|
||||
#if defined(SIMU)
|
||||
#define SD_CARD_PRESENT() true
|
||||
#else
|
||||
#define SD_IS_HC() (0)
|
||||
#define SD_GET_SPEED() (0)
|
||||
#define sdInit()
|
||||
#define sdMount()
|
||||
#define sdDone()
|
||||
#define SD_CARD_PRESENT() true
|
||||
#define SD_CARD_PRESENT() (~SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN)
|
||||
#endif
|
||||
|
||||
// Flash Write driver
|
||||
|
||||
@@ -296,16 +296,12 @@
|
||||
#define SD_RCC_APB1Periph 0
|
||||
#define SD_PRESENT_GPIO GPIOH
|
||||
#define SD_PRESENT_GPIO_PIN GPIO_Pin_10 // PH.10
|
||||
#define SD_PRESENT_LL_GPIO_PIN LL_GPIO_PIN_10 // PH.10
|
||||
#define SD_SDIO_DMA DMA2
|
||||
#define SD_SDIO_DMA_STREAM DMA2_Stream3
|
||||
#define SD_SDIO_DMA_CHANNEL DMA_Channel_4
|
||||
#define SD_SDIO_DMA_FLAG_FEIF DMA_FLAG_FEIF3
|
||||
#define SD_SDIO_DMA_FLAG_DMEIF DMA_FLAG_DMEIF3
|
||||
#define SD_SDIO_DMA_FLAG_TEIF DMA_FLAG_TEIF3
|
||||
#define SD_SDIO_DMA_FLAG_HTIF DMA_FLAG_HTIF3
|
||||
#define SD_SDIO_DMA_FLAG_TCIF DMA_FLAG_TCIF3
|
||||
#define SD_SDIO_DMA_CHANNEL LL_DMA_CHANNEL_4
|
||||
#define SD_SDIO_DMA_IRQn DMA2_Stream3_IRQn
|
||||
#define SD_SDIO_DMA_IRQHANDLER DMA2_Stream3_IRQHandler
|
||||
#define SD_SDIO_FIFO_ADDRESS ((uint32_t)0x40012C80)
|
||||
#define SD_SDIO_CLK_DIV(fq) ((48000000 / (fq)) - 2)
|
||||
#define SD_SDIO_INIT_CLK_DIV SD_SDIO_CLK_DIV(400000)
|
||||
#define SD_SDIO_TRANSFER_CLK_DIV SD_SDIO_CLK_DIV(24000000)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#define SIMPGMSPC_USE_QT 0
|
||||
|
||||
#if defined(SIMU_AUDIO)
|
||||
@@ -65,8 +66,6 @@ extern const etx_hal_adc_driver_t simu_adc_driver;
|
||||
|
||||
void lcdCopy(void * dest, void * src);
|
||||
|
||||
FATFS g_FATFS_Obj;
|
||||
|
||||
uint64_t simuTimerMicros(void)
|
||||
{
|
||||
#if SIMPGMSPC_USE_QT
|
||||
@@ -588,6 +587,12 @@ void rtcSetTime(const struct gtm * t)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
void sdPoll10ms() {}
|
||||
#endif
|
||||
|
||||
uint32_t SD_GetCardType() { return 0; }
|
||||
|
||||
#if defined(USB_SERIAL)
|
||||
const etx_serial_port_t UsbSerialPort = { "USB-VCP", nullptr, nullptr };
|
||||
#endif
|
||||
|
||||
@@ -80,17 +80,6 @@ void simuMain();
|
||||
#define SIMU_USE_SDCARD
|
||||
#endif
|
||||
|
||||
#if defined(SIMU_DISKIO)
|
||||
uint32_t sdMounted();
|
||||
#define sdPoll10ms()
|
||||
void sdInit(void);
|
||||
void sdDone(void);
|
||||
#else
|
||||
#define sdPoll10ms()
|
||||
uint32_t sdMounted(void);
|
||||
#define sdMounted() (true)
|
||||
#endif
|
||||
|
||||
#if defined(SIMU_USE_SDCARD)
|
||||
void simuFatfsSetPaths(const char * sdPath, const char * settingsPath);
|
||||
#else
|
||||
|
||||
@@ -559,6 +559,7 @@ set(FIRMWARE_TARGET_SRC
|
||||
volume_i2c.cpp
|
||||
eeprom_driver.cpp
|
||||
backlight_driver.cpp
|
||||
diskio.cpp
|
||||
)
|
||||
|
||||
if(PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR PCBREV STREQUAL COMMANDO8)
|
||||
|
||||
@@ -65,37 +65,13 @@ enum {
|
||||
};
|
||||
|
||||
// SD driver
|
||||
#define BLOCK_SIZE 512 /* Block Size in Bytes */
|
||||
#if !defined(SIMU) || defined(SIMU_DISKIO)
|
||||
uint32_t sdIsHC();
|
||||
uint32_t sdGetSpeed();
|
||||
#define SD_IS_HC() (sdIsHC())
|
||||
#define SD_GET_SPEED() (sdGetSpeed())
|
||||
#define SD_GET_FREE_BLOCKNR() (sdGetFreeSectors())
|
||||
#else
|
||||
#define SD_IS_HC() (0)
|
||||
#define SD_GET_SPEED() (0)
|
||||
#endif
|
||||
#define __disk_read disk_read
|
||||
#define __disk_write disk_write
|
||||
#if defined(SIMU)
|
||||
#if !defined(SIMU_DISKIO)
|
||||
#define sdInit()
|
||||
#define sdDone()
|
||||
#endif
|
||||
#define sdMount()
|
||||
#define SD_CARD_PRESENT() true
|
||||
|
||||
#if defined(SIMU) || !defined(SD_PRESENT_GPIO)
|
||||
#define SD_CARD_PRESENT() true
|
||||
#else
|
||||
void sdInit();
|
||||
void sdMount();
|
||||
void sdDone();
|
||||
void sdPoll10ms();
|
||||
uint32_t sdMounted();
|
||||
#if defined(SD_PRESENT_GPIO)
|
||||
#define SD_CARD_PRESENT() ((SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN) == 0)
|
||||
#else
|
||||
#define SD_CARD_PRESENT() (true)
|
||||
#endif
|
||||
#define SD_CARD_PRESENT() ((SD_PRESENT_GPIO->IDR & SD_PRESENT_GPIO_PIN) == 0)
|
||||
#endif
|
||||
|
||||
// Flash Write driver
|
||||
|
||||
@@ -63,45 +63,17 @@
|
||||
#define CT_SDC (CT_SD1|CT_SD2)
|
||||
#define CT_BLOCK 0x08
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Lock / unlock functions */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#if !defined(BOOT)
|
||||
static RTOS_MUTEX_HANDLE ioMutex;
|
||||
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t *mutex)
|
||||
{
|
||||
*mutex = ioMutex;
|
||||
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
|
||||
|
||||
static const DWORD socket_state_mask_cp = (1 << 0);
|
||||
static const DWORD socket_state_mask_wp = (1 << 1);
|
||||
|
||||
static volatile
|
||||
DSTATUS Stat = STA_NOINIT; /* Disk status */
|
||||
/* Disk status */
|
||||
static volatile DSTATUS Stat = STA_NOINIT;
|
||||
|
||||
static volatile
|
||||
DWORD Timer1, Timer2; /* 100Hz decrement timers */
|
||||
/* 100Hz decrement timers */
|
||||
static volatile DWORD Timer1, Timer2;
|
||||
|
||||
BYTE CardType; /* Card type flags */
|
||||
/* Card type flags */
|
||||
BYTE CardType;
|
||||
|
||||
enum speed_setting { INTERFACE_SLOW, INTERFACE_FAST };
|
||||
|
||||
@@ -955,85 +927,7 @@ void sdPoll10ms()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO everything here should not be in the driver layer ...
|
||||
|
||||
bool _g_FATFS_init = false;
|
||||
FATFS g_FATFS_Obj __DMA; // this is in uninitialised section !!!
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
FIL g_telemetryFile = {};
|
||||
#endif
|
||||
|
||||
#if defined(LOG_BLUETOOTH)
|
||||
FIL g_bluetoothFile = {};
|
||||
#endif
|
||||
|
||||
#if defined(BOOT)
|
||||
void sdInit(void)
|
||||
uint32_t SD_GetCardType()
|
||||
{
|
||||
if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
|
||||
f_chdir("/");
|
||||
}
|
||||
}
|
||||
#else
|
||||
// TODO shouldn't be there!
|
||||
void sdInit(void)
|
||||
{
|
||||
TRACE("sdInit");
|
||||
RTOS_CREATE_MUTEX(ioMutex);
|
||||
sdMount();
|
||||
}
|
||||
|
||||
void sdMount()
|
||||
{
|
||||
TRACE("sdMount");
|
||||
if (f_mount(&g_FATFS_Obj, "", 1) == FR_OK) {
|
||||
// call sdGetFreeSectors() now because f_getfree() takes a long time first time it's called
|
||||
_g_FATFS_init = true;
|
||||
sdGetFreeSectors();
|
||||
|
||||
#if defined(LOG_TELEMETRY)
|
||||
f_open(&g_telemetryFile, LOGS_PATH "/telemetry.log", FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (f_size(&g_telemetryFile) > 0) {
|
||||
f_lseek(&g_telemetryFile, f_size(&g_telemetryFile)); // append
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LOG_BLUETOOTH)
|
||||
f_open(&g_bluetoothFile, LOGS_PATH "/bluetooth.log", FA_OPEN_ALWAYS | FA_WRITE);
|
||||
if (f_size(&g_bluetoothFile) > 0) {
|
||||
f_lseek(&g_bluetoothFile, f_size(&g_bluetoothFile)); // append
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void sdDone()
|
||||
{
|
||||
if (sdMounted()) {
|
||||
audioQueue.stopSD();
|
||||
#if defined(LOG_TELEMETRY)
|
||||
f_close(&g_telemetryFile);
|
||||
#endif
|
||||
#if defined(LOG_BLUETOOTH)
|
||||
f_close(&g_bluetoothFile);
|
||||
#endif
|
||||
f_mount(nullptr, "", 0); // unmount SD
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t sdMounted()
|
||||
{
|
||||
return _g_FATFS_init && (g_FATFS_Obj.fs_type != 0);
|
||||
}
|
||||
|
||||
uint32_t sdIsHC()
|
||||
{
|
||||
return (CardType & CT_BLOCK);
|
||||
}
|
||||
|
||||
uint32_t sdGetSpeed()
|
||||
{
|
||||
return 330000;
|
||||
return CardType;
|
||||
}
|
||||
|
||||
Vendored
-1
@@ -35,7 +35,6 @@ DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||
|
||||
#if defined(DISK_CACHE)
|
||||
// #include "FatFs/diskio.h"
|
||||
DRESULT __disk_read(BYTE drv, BYTE * buff, DWORD sector, UINT count);
|
||||
DRESULT __disk_write(BYTE drv, const BYTE * buff, DWORD sector, UINT count);
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user