Skip to content

Commit

Permalink
chore: SDIO conversion to HAL
Browse files Browse the repository at this point in the history
  • Loading branch information
gagarinlg authored and raphaelcoeffic committed Aug 13, 2023
1 parent 3342d21 commit 7394ba6
Show file tree
Hide file tree
Showing 35 changed files with 833 additions and 3,013 deletions.
4 changes: 4 additions & 0 deletions radio/src/cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
40 changes: 33 additions & 7 deletions radio/src/disk_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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();
}
}
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand Down
27 changes: 7 additions & 20 deletions radio/src/disk_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,46 +22,33 @@
#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;
uint32_t noMisses;
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;
Expand Down
2 changes: 1 addition & 1 deletion radio/src/gui/screenshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion radio/src/logs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
5 changes: 3 additions & 2 deletions radio/src/opentx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down
7 changes: 0 additions & 7 deletions radio/src/opentx.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,6 @@ enum RotaryEncoderMode {
#define CASE_JACK_DETECT(x)
#endif

#if defined(DISK_CACHE)
#include "disk_cache.h"
#endif

#include "debug.h"

Expand Down Expand Up @@ -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,
Expand Down
140 changes: 140 additions & 0 deletions radio/src/sdcard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <stdio.h>
#include <stdint.h>

#include "opentx.h"
#include "diskio.h"

Expand All @@ -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)
Expand Down Expand Up @@ -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()
Expand All @@ -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;
}
Loading

0 comments on commit 7394ba6

Please sign in to comment.