Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(SDHC,MiscDrivers): Update AppSwitcher example to use new features with External Flash instead of SDHC #571

Merged
merged 22 commits into from
Jun 14, 2023

Conversation

MertCanBoz1
Copy link
Contributor

I changed the AppSwitcher (in "refdes" repository) example to work from the external flash instead of the SD Card. To be able to build the new code, some functions should be changed from here too.

/* Definitions of physical drive number for each drive */
#define DEV_SD 0 /* Example: Map MMC/SD card to physical drive 1 */
#define SPI_SPEED 10000000

#ifdef NATIVE_SDHC

#define MX25_EXP_ID 0x00c2953a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we move this to mx25.h.

Then, move the validation of the expected ID inside of mscmem_ID, and return a generic boolean.

As a result the check

if (mscmem_ID() == MX25_EXP_ID) {
    status = 0;
}
else{
    init_done = 0;
    status = STA_NOINIT | STA_NODISK;
}

becomes

if (!mscmem_ID()) {
    status = STA_NOINIT | STA_NODISK;
}

DSTATUS status = 0;


if (mscmem_ID() == MX25_EXP_ID) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again here, see comment above

@@ -31,23 +33,44 @@ static unsigned int init_done = 0;

/*local vaiables*/
static uint8_t rtc_en;

uint8_t flash = 0;
Copy link
Contributor

@Jake-Carter Jake-Carter May 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a little bit confused about using the global flash variable vs #ifdef FLASH in the preprocessor.

Consider the following function:

DSTATUS disk_status (
    BYTE pdrv       /* Physical drive nmuber to identify the drive */
)
{
	if(!flash){
    	DSTATUS status = 0;

    	if (!MXC_SDHC_Card_Inserted()) {
			init_done = 0;
			status = STA_NOINIT | STA_NODISK;
    	}

    	return status;
	}
#ifdef FLASH
	else{
		    DSTATUS status = 0;


    if (mscmem_ID() == MX25_EXP_ID) {
    	status = 0;
    }
    else{
    	init_done = 0;
    	status = STA_NOINIT | STA_NODISK;
    }

    return status;
	}
#endif
	return 0;
}

Why is the global runtime variable necessary? I don't see any calls to disk_flash in this driver code. Given the compiler definition and the suggestion above we can reduce this function to:

DSTATUS disk_status (
    BYTE pdrv       /* Physical drive nmuber to identify the drive */
)
{
    DSTATUS status = 0;
#ifndef FLASH
    init_done = MXC_SDHC_Card_Inserted();
#else
    init_done = mscmem_ID();
#endif
    if (!init_done) {
        status = STA_NOINIT | STA_NODISK;
    }
    return status;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The global external_flash variable is necessary because the new AppSwitcher code will check whether the user uses an SD Card or the external flash (if the SD Card is not inserted, then continue with the external flash). I added a preprocessor because if an application other than AppSwitcher calls the diskio.c, it is not necessary to compile all mscmem functions. The disk_flash() is called from the main.c of the new AppSwitcher, which also exists as a PR in another repository (refdes).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, thank you for clarifying. This situation is a multi-drive system:

image
(http://elm-chan.org/fsw/ff/doc/appnote.html#port)

The disk_initialize function is already designed to handle this with the pdrv argument. In the image above physical drive 2 is the SD card slot, and physical drive 0 is the external flash.

Following that scheme, the app switcher application code would first attempt to initialize drive 2 (SD). If it fails, then you attempt to initialize drive 0 (Ext Flash).

The diskio.c file in the avr example in ffsample.zip is a decent reference for a multi-drive implementation.

Notice how they are separating the driver layers based on a scheme they have defined for pdrv.

/*-----------------------------------------------------------------------*/
/* Low level disk I/O module glue functions         (C)ChaN, 2016        */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be        */
/* attached to the FatFs via a glue function rather than modifying it.   */
/* This is an example of glue functions to attach various exsisting      */
/* storage control modules to the FatFs module with a defined API.       */
/*-----------------------------------------------------------------------*/

#include "ff.h"			/* Obtains integer types for FatFs */
#include "diskio.h"		/* FatFs lower layer API */
#ifdef DRV_CFC
#include "cfc_avr.h"	/* Header file of existing CF control module */
#endif
#ifdef DRV_MMC
#include "mmc_avr.h"	/* Header file of existing SD control module */
#endif

// ...

/*-----------------------------------------------------------------------*/
/* Inidialize a Drive                                                    */
/*-----------------------------------------------------------------------*/

DSTATUS disk_initialize (
	BYTE pdrv				/* Physical drive nmuber to identify the drive */
)
{
	switch (pdrv) {
#ifdef DRV_CFC
	case DRV_CFC :
		return cf_disk_initialize();
#endif
#ifdef DRV_MMC
	case DRV_MMC :
		return mmc_disk_initialize();
#endif
	}
	return STA_NOINIT;
}

rtc_en = 0;
#if (FF_FS_NORTC == 0)
//Initialize RTC
if (MXC_RTC->cn & MXC_F_RTC_CN_WE) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting issue on this block, make sure lines 92 - 101 are indented correctly


status = RES_OK;

#if FF_MAX_SS == 4096
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am a little confused on the driver differences between FF_MAX_SS = 4096 and FF_MAX_SS = 512.

To improve the readability of the code I would suggest adding a comment explaining it, and you can also consolidate inside of the for loop:

for(index = 0; index < count; index++){
#if FF_MAX_SS == 4096
    // ...
#endif
#if FF_MAX_SS == 512
    // ...
#endif
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took the base code from the MAXREFDES104 project, and FF_MAX_SS = 4096 part was added to their code. I will remove all FF_MAX_SS = 4096 parts.



status = RES_OK;
#if FF_MAX_SS == 4096
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same FF_MAX_SS considerations here - please add a comment explaining why it's necessary and consider consolidating the switch statements if possible

@@ -40,7 +42,7 @@ DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
DWORD get_fattime(void);

void disk_flash(uint32_t isFlash);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diskio.h modification - adding this function to the API should only be done as an absolute last resort. Additionally, uint32_t is used which goes against the FatFS convention of using its built-in data types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure how I can come around to not changing the diskio.h for this code snippet. I will look into it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -171,6 +174,8 @@

#define FF_MIN_SS 512
#define FF_MAX_SS 512
//#define FF_MIN_SS 4096
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a comment explaining in what situation the sector size of 4096 would be used.

We should also consider whether we want to wrap this in some variable that we have more control over from the build system.

Ex:

#ifdef SOMEVARIABLE
#define FF_MIN_SS		512
#define FF_MAX_SS		512
#else
#define FF_MIN_SS		4096
#define FF_MAX_SS		4096
#endif


/**
* @file mscmem.h
* @brief Memory routines used by the USB Mass Storage Class example.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sanjayjaroli can you take a look at the application of these files towards the SDHC library? Are there any maintenance considerations?

@MertCanBoz1 since FatFS is not USB-specific I wonder if using the Libraries/MiscDrivers/ExtMemory is a better choice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be, but the external flash on the connectivity board of the MAXREFDES178 is different than the one used for EvKits. Some functions (specifically Ext_Flash_Erase.c ) need different handling than the ones at the mx25.c. The new AppSwitcher code calls mx25.c directly from the source file ( analogdevicesinc/MAX78xxx-RefDes#48 ).
Therefore, adding the mscmem.c to the Libraries/MiscDrivers/ExtMemory may cause some conflicts between them.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's what I mean - we should use mx25.c directly. Ext_Flash.h provides a struct to abstract the physical communication layer which should be enough to address connectivity issues I think.

https://github.com/Analog-Devices-MSDK/msdk/blob/9bf68cf780920cc3d9654418c5722543f2e69c89/Libraries/MiscDrivers/ExtMemory/Ext_Flash.h#L143

Maybe I missed something - Does the cube camera present itself as a mass storage device for USB? Is that what the mscmem files are used for?

@@ -67,7 +67,7 @@ export PROJ_LDFLAGS
export MXC_OPTIMIZE_CFLAGS
export BOARD_DIR
export USE_NATIVE_SDHC

export FLASH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest naming this variable EXTERNAL_FLASH

Copy link
Contributor

@Jake-Carter Jake-Carter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks for implementing the changes.

I have one last minor suggestion below, but otherwise I think it's ready. Nice work!

@@ -21,7 +24,7 @@
#define INIT_CARD_RETRIES 10

/* Prototypes for module-only functions */
static DRESULT ctrl_sync(void *buff);
static DRESULT ctrl_sync(void *buff,BYTE pdrv);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest applying the same change that you made to ctrl_sync (adding pdrv as an argument) to get_sector_count, get_block_size, and mmc_get_csd as well. Then you can move the implementations inside of these functions with the same method that you have applied elsewhere.

Since these are internal module functions we can modify them more freely as we see fit.

This would help keep the implementation of the disk_ioctl function clean, so you wouldn't need the nested switch statements.

}

DRESULT status;
switch(pdrv){
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above - pass this in as an argument to avoid nested switch statements

@sihyung-maxim
Copy link
Contributor

/clang-format-run

@sihyung-maxim
Copy link
Contributor

Not sure why the workflows aren't running...

@sihyung-maxim
Copy link
Contributor

/clang-format-run

@sihyung-maxim
Copy link
Contributor

The BTM-CI runner has not pulled the latest changes. Attempting to fix.

@sihyung-maxim sihyung-maxim changed the title SDHC Library Changes to Enable New Features of the AppSwitcher feat(SDHC,MiscDrivers): Update AppSwitcher example to use new features with External Flash instead of SDHC Jun 6, 2023
@sihyung-maxim sihyung-maxim merged commit ebf73d5 into analogdevicesinc:main Jun 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants