Skip to content

Commit f40eb6e

Browse files
committed
terrain + blackbox at the same time
1 parent 8c73398 commit f40eb6e

8 files changed

Lines changed: 166 additions & 15 deletions

File tree

src/main/blackbox/blackbox.c

Lines changed: 68 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565

6666
#include "io/beeper.h"
6767
#include "io/gps.h"
68+
#include "io/asyncfatfs/asyncfatfs.h"
69+
6870

6971
#include "navigation/navigation.h"
7072

@@ -198,6 +200,54 @@ typedef struct blackboxDeltaFieldDefinition_s {
198200
uint8_t condition; // Decide whether this field should appear in the log
199201
} blackboxDeltaFieldDefinition_t;
200202

203+
static bool canUseBlackboxWithCurrentConfiguration(void)
204+
{
205+
return feature(FEATURE_BLACKBOX);
206+
}
207+
208+
#ifdef USE_TERRAIN
209+
//state machine to get access to other device, it's designed only for one other device, in this case for terrain
210+
//if you would like to have more devices, some queue must be implemented
211+
static struct blackboxSDCardAccessStatus_s {
212+
bool blackboxAccessToSDGrantedToOtherDevice;
213+
bool requestToSdCardAccessState;
214+
215+
} blackboxSDCardAccessStatus = {
216+
.blackboxAccessToSDGrantedToOtherDevice = false,
217+
.requestToSdCardAccessState = false
218+
};
219+
220+
221+
/**
222+
* request access from terrain subsystem
223+
* @return
224+
*/
225+
bool requestToSdCardAccess(void)
226+
{
227+
if(blackboxConfig()->device != BLACKBOX_DEVICE_SDCARD || !canUseBlackboxWithCurrentConfiguration()){
228+
return true;
229+
}
230+
231+
if(blackboxSDCardAccessStatus.blackboxAccessToSDGrantedToOtherDevice){
232+
return true;
233+
}
234+
235+
blackboxSDCardAccessStatus.requestToSdCardAccessState = true;
236+
return false;
237+
}
238+
239+
/**
240+
* release access from terrain subsystem
241+
* @return
242+
*/
243+
void releaseSdCardAccess(void)
244+
{
245+
blackboxSDCardAccessStatus.blackboxAccessToSDGrantedToOtherDevice = false;
246+
blackboxSDCardAccessStatus.requestToSdCardAccessState = false;
247+
}
248+
#endif
249+
250+
201251
/**
202252
* Description of the blackbox fields we are writing in our main intra (I) and inter (P) frames. This description is
203253
* written into the flight log header so the log can be properly interpreted (but these definitions don't actually cause
@@ -2178,6 +2228,24 @@ static void blackboxLogIteration(timeUs_t currentTimeUs)
21782228
*/
21792229
void blackboxUpdate(timeUs_t currentTimeUs)
21802230
{
2231+
#ifdef USE_TERRAIN
2232+
if(blackboxConfig()->device == BLACKBOX_DEVICE_SDCARD){
2233+
//access to SD card is given to other device
2234+
if(blackboxSDCardAccessStatus.blackboxAccessToSDGrantedToOtherDevice){
2235+
return;
2236+
}
2237+
2238+
//incooming request to get access to SD card
2239+
if(blackboxSDCardAccessStatus.requestToSdCardAccessState && (blackboxState == BLACKBOX_STATE_RUNNING || blackboxState == BLACKBOX_STATE_STOPPED)){
2240+
//we have to be sure that all writes are already processed and SD card is in idle
2241+
if(afatfs_isIdle()){
2242+
blackboxSDCardAccessStatus.requestToSdCardAccessState = false;
2243+
blackboxSDCardAccessStatus.blackboxAccessToSDGrantedToOtherDevice = true;
2244+
}
2245+
}
2246+
}
2247+
#endif
2248+
21812249
if (blackboxState >= BLACKBOX_FIRST_HEADER_SENDING_STATE && blackboxState <= BLACKBOX_LAST_HEADER_SENDING_STATE) {
21822250
blackboxReplenishHeaderBudget();
21832251
}
@@ -2308,15 +2376,6 @@ void blackboxUpdate(timeUs_t currentTimeUs)
23082376
}
23092377
}
23102378

2311-
static bool canUseBlackboxWithCurrentConfiguration(void)
2312-
{
2313-
return feature(FEATURE_BLACKBOX)
2314-
#ifdef USE_TERRAIN
2315-
&& terrainConfig()->terrainEnabled == false && blackboxConfig()->device == BLACKBOX_DEVICE_SDCARD
2316-
#endif
2317-
;
2318-
}
2319-
23202379
BlackboxState getBlackboxState(void)
23212380
{
23222381
return blackboxState;

src/main/blackbox/blackbox.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,6 @@ void blackboxIncludeFlagSet(uint32_t mask);
7575
void blackboxIncludeFlagClear(uint32_t mask);
7676
bool blackboxIncludeFlag(uint32_t mask);
7777
BlackboxState getBlackboxState(void);
78+
79+
bool requestToSdCardAccess(void);
80+
void releaseSdCardAccess(void);

src/main/blackbox/blackbox_io.c

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,16 @@ static bool blackboxSDCardBeginLog(void)
435435
if (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_READY) {
436436
blackboxSDCard.state = BLACKBOX_SDCARD_WAITING;
437437

438-
afatfs_mkdir("logs", blackboxLogDirCreated);
438+
if(afatfs_isCurrentDirRoot()){
439+
//we are in root of SD card, we have to create or move to log directory
440+
afatfs_mkdir("logs", blackboxLogDirCreated);
441+
}
442+
else
443+
{
444+
//we are already in log directory
445+
blackboxSDCard.logDirectory = NULL;
446+
blackboxSDCard.state = BLACKBOX_SDCARD_READY_TO_CREATE_LOG;
447+
}
439448
}
440449
break;
441450

@@ -444,6 +453,12 @@ static bool blackboxSDCardBeginLog(void)
444453
break;
445454

446455
case BLACKBOX_SDCARD_ENUMERATE_FILES:
456+
457+
if (blackboxSDCard.logDirectory == NULL) {
458+
blackboxSDCard.state = BLACKBOX_SDCARD_READY_TO_CREATE_LOG;
459+
break;
460+
}
461+
447462
while (afatfs_findNext(blackboxSDCard.logDirectory, &blackboxSDCard.logDirectoryFinder, &directoryEntry) == AFATFS_OPERATION_SUCCESS) {
448463
if (directoryEntry && !fat_isDirectoryEntryTerminator(directoryEntry)) {
449464
// If this is a log file, parse the log number from the filename
@@ -469,6 +484,12 @@ static bool blackboxSDCardBeginLog(void)
469484
break;
470485

471486
case BLACKBOX_SDCARD_CHANGE_INTO_LOG_DIRECTORY:
487+
//if logDirectory is NULL, it would mean change directory to ROOT, we don't want to do that
488+
if (blackboxSDCard.logDirectory == NULL) {
489+
blackboxSDCard.state = BLACKBOX_SDCARD_READY_TO_CREATE_LOG;
490+
break;
491+
}
492+
472493
// Change into the log directory:
473494
if (afatfs_chdir(blackboxSDCard.logDirectory)) {
474495
// We no longer need our open handle on the log directory
@@ -535,7 +556,7 @@ bool blackboxDeviceEndLog(bool retainLog)
535556
) {
536557
// Don't bother waiting the for the close to complete, it's queued now and will complete eventually
537558
blackboxSDCard.logFile = NULL;
538-
blackboxSDCard.state = BLACKBOX_SDCARD_READY_TO_CREATE_LOG;
559+
blackboxSDCard.state = BLACKBOX_SDCARD_INITIAL;
539560
return true;
540561
}
541562
return false;

src/main/io/asyncfatfs/asyncfatfs.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,50 @@ static void afatfs_fileOperationContinue(afatfsFile_t *file);
495495
static uint8_t* afatfs_fileLockCursorSectorForWrite(afatfsFilePtr_t file);
496496
static uint8_t* afatfs_fileRetainCursorSectorForRead(afatfsFilePtr_t file);
497497

498+
bool afatfs_isIdle(void)
499+
{
500+
// 1. Check if any sector is being actively flushed or read at the hardware level
501+
if (afatfs.cacheFlushInProgress) {
502+
return false;
503+
}
504+
505+
// 2. Check all cache descriptors for active I/O states (waiting for SD card)
506+
for (int i = 0; i < AFATFS_NUM_CACHE_SECTORS; i++) {
507+
if (afatfs.cacheDescriptor[i].state == AFATFS_CACHE_STATE_READING ||
508+
afatfs.cacheDescriptor[i].state == AFATFS_CACHE_STATE_WRITING) {
509+
return false;
510+
}
511+
}
512+
513+
// 3. Check if current directory state machine is performing an async task (like chdir or findNext)
514+
if (afatfs.currentDirectory.operation.operation != AFATFS_FILE_OPERATION_NONE) {
515+
return false;
516+
}
517+
518+
#ifdef AFATFS_USE_FREEFILE
519+
// 4. Check freeFile state (ignore LOCKED as it's a static permission marker, not an operation)
520+
if (afatfs.freeFile.operation.operation != AFATFS_FILE_OPERATION_NONE &&
521+
afatfs.freeFile.operation.operation != AFATFS_FILE_OPERATION_LOCKED) {
522+
return false;
523+
}
524+
#endif
525+
526+
// 5. Check all potentially open file handles for pending background operations
527+
for (int i = 0; i < AFATFS_MAX_OPEN_FILES; i++) {
528+
if (afatfs.openFiles[i].type != AFATFS_FILE_TYPE_NONE &&
529+
afatfs.openFiles[i].operation.operation != AFATFS_FILE_OPERATION_NONE) {
530+
return false;
531+
}
532+
}
533+
534+
// 6. During initialization, we are never "idle" in the operational sense
535+
if (afatfs.filesystemState == AFATFS_FILESYSTEM_STATE_INITIALIZATION) {
536+
return false;
537+
}
538+
539+
return true;
540+
}
541+
498542
static uint32_t roundUpTo(uint32_t value, uint32_t rounding)
499543
{
500544
uint32_t remainder = value % rounding;
@@ -3622,6 +3666,11 @@ afatfsError_e afatfs_getLastError(void)
36223666
return afatfs.lastError;
36233667
}
36243668

3669+
bool afatfs_isCurrentDirRoot(void)
3670+
{
3671+
return afatfs.currentDirectory.directoryEntryPos.sectorNumberPhysical == 0;
3672+
}
3673+
36253674
void afatfs_init(void)
36263675
{
36273676
#ifdef STM32H7

src/main/io/asyncfatfs/asyncfatfs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,6 @@ bool afatfs_isFull(void);
9595

9696
afatfsFilesystemState_e afatfs_getFilesystemState(void);
9797
afatfsError_e afatfs_getLastError(void);
98+
99+
bool afatfs_isIdle(void);
100+
bool afatfs_isCurrentDirRoot(void);

src/main/terrain/terrain.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,8 @@ void terrainUpdateTask(timeUs_t currentTimeUs)
170170
}
171171

172172
/////////////////////////////////////////////////////////////////////////////////////////////////////
173-
//try to find home altitude to safe offset
174-
//save reference only once when gps origin is valid and different than last saved
175-
if(terrainHomePos.homeAltitudeFound == false && posControl.gpsOrigin.valid && (posControl.gpsOrigin.lat != terrainHomePos.homeLocation.lat || posControl.gpsOrigin.lon != terrainHomePos.homeLocation.lon)){
173+
//try to find home altitude to home offset
174+
if(terrainHomePos.homeAltitudeFound == false && posControl.gpsOrigin.valid && (posControl.gpsOrigin.lat != terrainHomePos.homeLocation.lat || posControl.gpsOrigin.lon != terrainHomePos.homeLocation.lon)) {
176175

177176
gpsLocation_t homeLoc = {
178177
.lat = posControl.gpsOrigin.lat,
@@ -214,7 +213,7 @@ int32_t terrainGetLastDistanceCm(void)
214213
terrainSystemStatus.isStarted = true;
215214
}
216215

217-
return terrainHeight.lastUpdate + 500 < millis() ? TERRAIN_STATUS_NO_DATA : terrainHeight.terrainAGL;
216+
return terrainHeight.lastUpdate + 200 < millis() ? TERRAIN_STATUS_NO_DATA : terrainHeight.terrainAGL;
218217
}
219218

220219
#endif

src/main/terrain/terrain.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "navigation/navigation.h"
3131

3232
#define TERRAIN_TASK_RATE_HZ 50
33+
#define TERRAIN_TASK_ 200
3334

3435
#define TERRAIN_STATUS_FAILURE (-1)
3536
#define TERRAIN_STATUS_WRONG_BLOC_SIZE (-2)

src/main/terrain/terrain_io.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "drivers/time.h"
3434
#include "terrain_utils.h"
3535
#include "drivers/sdcard/sdcard.h"
36+
#include "blackbox/blackbox.h"
3637

3738
#include "io/asyncfatfs/asyncfatfs.h"
3839

@@ -47,6 +48,7 @@ static void hardFailure(void)
4748
terrainIoState.status = TERRAIN_IO_FAILURE;
4849
terrainIoState.gridBlock = NULL;
4950
//LOG_DEBUG(SYSTEM, "TERRAIN RELEASE FAILURE");
51+
releaseSdCardAccess();
5052
}
5153

5254
/**
@@ -62,6 +64,7 @@ static void resetStateMachine(void)
6264
terrainIoState.openFileStartTimeMs = 0;
6365

6466
//LOG_DEBUG(SYSTEM, "TERRAIN RELEASE RESET STATE");
67+
releaseSdCardAccess();
6568
}
6669

6770
/**
@@ -182,6 +185,13 @@ void loadGridToCacheTask(void)
182185
return;
183186
}
184187

188+
///////////////////////////////////////////////////////////////////
189+
//request access from blackbox
190+
if(requestToSdCardAccess() == false){
191+
return;
192+
}
193+
////////////////////////////////////////////////////////////////
194+
185195
//check if we had too many errors opening of this file
186196
terrainIoFileOpenStatus_t* fileOpenStatus = getFileOpenStatusIndex(gridBlock->latDegrees, gridBlock->lonDegrees);
187197
if(fileOpenStatus->errorOpenCount >= 3){
@@ -200,6 +210,12 @@ void loadGridToCacheTask(void)
200210
///////////////////////////////////////////////////////////////////
201211
/////// CHANGE DIR /////////////////////////////////////////////
202212
if(terrainIoState.status == TERRAIN_IO_CHANGE_DIR){
213+
//already in the root directory, no need to change the directory
214+
if(afatfs_isCurrentDirRoot()){
215+
terrainIoState.status = TERRAIN_IO_OPEN_FILE;
216+
return;
217+
}
218+
203219
//LOG_DEBUG(SYSTEM, "TERRAIN CHANGING DIR");
204220
//change dir to ROOT (null)
205221
if(!afatfs_chdir(NULL)){

0 commit comments

Comments
 (0)