Skip to content

Commit

Permalink
feat(SDHC,MiscDrivers): Update AppSwitcher example to use new feature…
Browse files Browse the repository at this point in the history
…s with External Flash instead of SDHC (#571)

* SDHC Library Changes to Enable New Features of the AppSwitcher Example (from refdes repository)

* SDHC and ExtMemory Updates to Enable New Features of AppSwitcher

* Delete ar_args.txt

* Minor Changes on diskio.c

* ff13.c Minor Changes

* clang-format bot reformatting.

* Updated copyright in sdhc.mk.

* Revert "clang-format bot reformatting."

This reverts commit db7e4ec.

* clang-format bot reformatting.

* Triggering workflows.

* Removed SDHC from linter check.

* Fixed linter errors.

* Fixed linter errors.

* AFE: Updated SVD file names to include Revision.

* style(Examples,MiscDrivers): Update capitalization for EXT_FLASH_READ_DUMMY

* Fix Linter filter

* Revert "style(Examples,MiscDrivers): Update capitalization for EXT_FLASH_READ_DUMMY"

This reverts commit 675d646.

---------

Co-authored-by: Jake Carter <jake.carter@analog.com>
Co-authored-by: sihyung-maxim <sihyung-maxim@users.noreply.github.com>
Co-authored-by: Sihyung Woo <75494566+sihyung-maxim@users.noreply.github.com>
Co-authored-by: Sihyung Woo <sihyung.woo@analog.com>
  • Loading branch information
5 people authored Jun 14, 2023
1 parent 98a31d2 commit ebf73d5
Show file tree
Hide file tree
Showing 13 changed files with 1,248 additions and 97 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# Skip autogenerated register files and internal use board files
FILTER_REGEX_EXCLUDE: (.*\/Libraries\/((CMSIS\/Device\/Maxim\/[^\/]*\/Include)|(PeriphDrivers\/Source\/[^\/]*))\/[^\/]*_regs\.h)|(.*\/Libraries\/Boards\/[^\/]*\/(BCB|Emulator|Simulation|ROM)[^\/]*\/.*)|(.*\/Examples\/[^\/]*\/Display\/lvgl-8\.0\.2\/.*)|(.*\/Examples\/[^\/]*\/Demo\/lv_conf.h)|(.*\/Libraries\/CMSIS\/5.9.0\/.*)|(.*\/Libraries\/CMSIS\/Include\/.*)|(.*\/Libraries\/Cordio\/.*)|(.*\/Examples\/[^\/]*\/CNN\/.*)|(.*\/Libraries\/lwIP.*)
FILTER_REGEX_EXCLUDE: (.*\/Libraries\/((CMSIS\/Device\/Maxim\/[^\/]*\/Include)|(PeriphDrivers\/Source\/[^\/]*))\/[^\/]*_regs\.h)|(.*\/Libraries\/Boards\/[^\/]*\/(BCB|Emulator|Simulation|ROM)[^\/]*\/.*)|(.*\/Examples\/[^\/]*\/Display\/lvgl-8\.0\.2\/.*)|(.*\/Examples\/[^\/]*\/Demo\/lv_conf.h)|(.*\/Libraries\/CMSIS\/5.9.0\/.*)|(.*\/Libraries\/CMSIS\/Include\/.*)|(.*\/Libraries\/Cordio\/.*)|(.*\/Libraries\/SDHC\/.*)|(.*\/Libraries\/lwIP\/.*)|(.*\/Examples\/[^\/]*\/CNN\/.*)

# Explicity turn off all linters except CPP
# SuperLinter Documentation says all we need to do is turn on the ones we want
Expand Down
4 changes: 2 additions & 2 deletions Libraries/Boards/MAX32665/MAXREFDES178/board.mk
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ endif
SRCS += board.c
SRCS += stdio.c
SRCS += led.c
SRCS += mx25.c
SRCS += mx25_64MB.c
SRCS += pb.c

PROJ_CFLAGS+=-DEXT_FLASH_MX25
PROJ_CFLAGS+=-DEXT_FLASH_MX25_64MB

MISC_DRIVERS_DIR=$(LIBS_DIR)/MiscDrivers

Expand Down
17 changes: 17 additions & 0 deletions Libraries/MiscDrivers/ExtMemory/Ext_Flash.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,23 @@ extern "C" {
#define EXT_FLASH_CMD_DREAD 0xBB /**< Dual SPI Read */
#define EXT_FLASH_CMD_QREAD 0xEB /**< Quad SPI Read */

#elif defined(EXT_FLASH_MX25_64MB)

#define EXT_FLASH_NAME "MX25_64MB"

#define EXT_FLASH_Read_DUMMY \
8 /**< Dummy byte sent on a standard read command per the MX25 datasheet. */
#define EXT_FLASH_DREAD_DUMMY \
4 /**< Dummy data sent on a fast-read (Dual) read command per the MX25 datasheet. */
#define EXT_FLASH_QREAD_DUMMY \
10 /**< Dummy data sent on a fast-read (Quad) read command per the MX25 datasheet. */

#define EXT_FLASH_EXP_ID 0x00c2953a

#define EXT_FLASH_CMD_READ 0x0B /**< Read */
#define EXT_FLASH_CMD_DREAD 0xBB /**< Dual SPI Read */
#define EXT_FLASH_CMD_QREAD 0xEB /**< Quad SPI Read */

#endif

/**
Expand Down
340 changes: 340 additions & 0 deletions Libraries/MiscDrivers/ExtMemory/mscmem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,340 @@
/******************************************************************************
* Copyright (C) 2023 Maxim Integrated Products, Inc., All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of Maxim Integrated
* Products, Inc. shall not be used except as stated in the Maxim Integrated
* Products, Inc. Branding Policy.
*
* The mere transfer of this software does not imply any licenses
* of trade secrets, proprietary technology, copyrights, patents,
* trademarks, maskwork rights, or any other form of intellectual
* property whatsoever. Maxim Integrated Products, Inc. retains all
* ownership rights.
*
******************************************************************************/

/**
* @file mscmem.h
* @brief Memory routines used by the USB Mass Storage Class example.
* See the msc_mem_t structure in msc.h for function details.
* @details Functions are provided for using the internal RAM of the
* device or the external SPI flash memory. Use the SPIXF_DISK
* and RAM_DISK defines to select the desired memory at compile
* time.
*/

#include "mscmem.h"
#include <string.h>
#include <stdio.h>
#include "Ext_Flash.h"
#include "spixf.h"

/***** Definitions *****/

#define SPIXF_DISK 1
#define RAM_DISK 0

#define LBA_SIZE 512 /* Size of "logical blocks" in bytes */
#define LBA_SIZE_SHIFT 9 /* The shift value used to convert between addresses and block numbers */

/***** Global Data *****/

/***** File Scope Variables *****/

static int initialized = 0;
static int running = 0;

#if SPIXF_DISK

#undef EXT_FLASH_BAUD
#define EXT_FLASH_BAUD 5000000 /* SPI clock rate to communicate with the external flash */

#define MXC_SPIXF_WIDTH Ext_Flash_DataLine_Quad /*Number of data lines*/

#define LBA_PER_SECTOR (EXT_FLASH_SECTOR_SIZE >> LBA_SIZE_SHIFT)
#define INVALID_SECTOR \
EXT_FLASH_NUM_SECTORS /* Use a sector number past the end of memory to indicate invalid */

/***** File Scope Variables *****/
static uint32_t sectorNum = INVALID_SECTOR;
static uint8_t sector[EXT_FLASH_SECTOR_SIZE];
static int sectorDirty = 0;

/***** Function Prototypes *****/
static uint32_t getSectorNum(uint32_t lba);
static uint32_t getSectorAddr(uint32_t lba);
static uint32_t getSector(uint32_t num);

/******************************************************************************/
static uint32_t getSectorNum(uint32_t lba)
{
/* Absolute_address = lba * LBA_SIZE */
/* Sector_num = Absolute_address / EXT_FLASH_SECTOR_SIZE */
/* Sector_num = lba * 512 / 4096 */
return lba >> (EXT_FLASH_SECTOR_SIZE_SHIFT - LBA_SIZE_SHIFT);
}

/******************************************************************************/
static uint32_t getSectorAddr(uint32_t lba)
{
/* eight 512 byte blocks in each sector */
return (lba & (LBA_PER_SECTOR - 1)) << LBA_SIZE_SHIFT;
}

/******************************************************************************/
static uint32_t getSector(uint32_t num)
{
/* New sector requested? */
if (sectorNum != num) {
/* Is the current sector real? */
if (sectorNum != INVALID_SECTOR) {
/* Was it written to after it was read from memory? */
if (sectorDirty) {
/* Erase the old data. */
Ext_Flash_Erase(sectorNum << EXT_FLASH_SECTOR_SIZE_SHIFT, Ext_Flash_Erase_4K);
/* Write the new */
Ext_Flash_Program_Page(sectorNum << EXT_FLASH_SECTOR_SIZE_SHIFT, sector,
EXT_FLASH_SECTOR_SIZE, MXC_SPIXF_WIDTH);
/* Mark data as clean */
sectorDirty = 0;
}
}

/* Requesting a new valid sector? */
if (num != INVALID_SECTOR) {
Ext_Flash_Read(num << EXT_FLASH_SECTOR_SIZE_SHIFT, sector, EXT_FLASH_SECTOR_SIZE,
MXC_SPIXF_WIDTH);
sectorDirty = 0;
sectorNum = num;
}
}

return 0;
}

/******************************************************************************/
int mscmem_Init()
{
if (!initialized) {
MXC_SPIXF_SetSPIFrequency(EXT_FLASH_BAUD);
Ext_Flash_Init();
Ext_Flash_Reset();

if (MXC_SPIXF_WIDTH == Ext_Flash_DataLine_Quad) {
Ext_Flash_Quad(1);
} else {
Ext_Flash_Quad(0);
}

initialized = 1;
}

return 0;
}

/******************************************************************************/
uint32_t mscmem_Size(void)
{
/* Get number of 512 byte chunks the external flash contains. */
return (EXT_FLASH_SECTOR_SIZE >> LBA_SIZE_SHIFT) * EXT_FLASH_NUM_SECTORS;
}

/******************************************************************************/
int mscmem_Read(uint32_t lba, uint8_t *buffer)
{
uint32_t addr;

/* Convert to external flash sector number. */
uint32_t sNum = getSectorNum(lba);

if (getSector(sNum)) {
/* Failed to write/read from external flash */
return 1;
}

/* Get the offset into the current sector */
addr = getSectorAddr(lba);

memcpy(buffer, sector + addr, LBA_SIZE);

return 0;
}

/******************************************************************************/
int mscmem_Write(uint32_t lba, uint8_t *buffer)
{
uint32_t addr;

/* Convert to external flash sector number. */
uint32_t sNum = getSectorNum(lba);

if (getSector(sNum)) {
/* Failed to write/read from external flash */
return 1;
}

/* Get the offset into the current sector */
addr = getSectorAddr(lba);

memcpy(sector + addr, buffer, LBA_SIZE);
sectorDirty = 1;

return 0;
}

/******************************************************************************/
int mscmem_Start()
{
/* Turn on the external flash if it is not already. */
if (!initialized) {
mscmem_Init();
}

/* Check if the initialization succeeded. If it has, start running. */
if (initialized) {
running = 1;
}

/* Start should return fail (non-zero) if the memory cannot be initialized. */
return !initialized;
}

/******************************************************************************/
int mscmem_Stop()
{
/* TODO - could shut down XIPF interface here. */

/* Flush the currently cached sector if necessary. */
if (getSector(INVALID_SECTOR)) {
return 1;
}

running = 0;
return 0;
}

/******************************************************************************/
int mscmem_Ready()
{
return running;
}
int mscmem_write_dirty_sector()
{
if (sectorDirty) {
/* Erase the old data. */
Ext_Flash_Erase(sectorNum << EXT_FLASH_SECTOR_SIZE_SHIFT, Ext_Flash_Erase_4K);
/* Write the new */
Ext_Flash_Program_Page(sectorNum << EXT_FLASH_SECTOR_SIZE_SHIFT, sector,
EXT_FLASH_SECTOR_SIZE, MXC_SPIXF_WIDTH_4);
/* Mark data as clean */
sectorDirty = 0;
}
return 0;
}
uint32_t mscmem_ID()
{
if (Ext_Flash_ID() == EXT_FLASH_EXP_ID) {
return 1;
} else {
return 0;
}
}
#elif RAM_DISK

#define NUM_PAGES 0x100
static uint8_t mem[NUM_PAGES][LBA_SIZE];

/******************************************************************************/
int mscmem_Init()
{
if (!initialized) {
initialized = 1;
#if (ERASE_MEMORY_ON_INIT)
memset(mem, 0, sizeof(mem));
#endif
}

return 0;
}

/******************************************************************************/
uint32_t mscmem_Size(void)
{
return NUM_PAGES;
}

/******************************************************************************/
int mscmem_Read(uint32_t lba, uint8_t *buffer)
{
if (lba >= NUM_PAGES) {
return 1;
}

memcpy(buffer, mem[lba], LBA_SIZE);
return 0;
}

/******************************************************************************/
int mscmem_Write(uint32_t lba, uint8_t *buffer)
{
if (lba >= NUM_PAGES) {
return 1;
}

memcpy(mem[lba], buffer, LBA_SIZE);
return 0;
}

/******************************************************************************/
int mscmem_Start()
{
/* Not much to do for this implementation. The RAM is always ready. */
if (!initialized) {
mscmem_Init();
}

/* Check if the RAM has been initialized. If it has, start running. */
if (initialized) {
running = 1;
}

/* Start should return fail (non-zero) if the memory cannot be initialized. */
return !initialized;
}

/******************************************************************************/
int mscmem_Stop()
{
/* Nothing to do for this implementation. All data is written as it is */
/* received so there are no pending writes that need to be flushed. */
running = 0;
return 0;
}

/******************************************************************************/
int mscmem_Ready()
{
return running;
}

#else
#error "You must assign either RAM_DISK or SPIXF_DISK to 1."
#endif
Loading

0 comments on commit ebf73d5

Please sign in to comment.