Announcements

Help us improve the Power & Sensing Selection Guide. Share feedback

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
bluefish97
Level 2
Level 2
10 sign-ins 5 questions asked 5 replies posted

Hello,

I am trying to flash littlefs filesystem on the qspi external serial flash memory in XMC7100 V1.1. As I see library mtb-littlefs is not included in the XMC7100 kit but i have included the mtb-littlefs from PSoc6 Kit to my project and in makefile included target as XMC7100 (my board).

BOARD: XMC7100 EVK Lite v1.1

Memory: External QSPI flash memory

These are the errors when I try to builld the file:

 

 

 

Initializing build: mtb-example-psoc6-filesystem-littlefs-freertos Debug APP_KIT_XMC71_EVK_LITE_V1 GCC_ARM

Prebuild operations complete

Auto-discovery in progress...
Auto-discovery complete
Commencing build operations...

Tools Directory: C:/Users/Prasad/ModusToolbox/tools_3.2
"Using linker bsps/TARGET_APP_KIT_XMC71_EVK_LITE_V1/COMPONENT_/TOOLCHAIN_GCC_ARM/linker.ld"

Constructing build rules...
Build rules construction complete

==============================================================================
= Building application =
==============================================================================
Generating compilation database file...
-> ./build/compile_commands.json
Compilation database file generation complete
Building 223 file(s)
Compiling ../mtb_shared/mtb-littlefs/latest-v2.X/source/lfs_qspi_memslot.c -DCOMPONENT_APP_KIT_XMC71_EVK_LITE_V1 -DCOMPONENT_CAT1 -DCOMPONENT_CAT1C -DCOMPONENT_CAT1C4M -DCOMPONENT_CM7 -DCOMPONENT_CM7_0 -DCOMPONENT_Debug -DCOMPONENT_FREERTOS -DCOMPONENT_GCC_ARM -DCOMPONENT_MW_ABSTRACTION_RTOS -DCOMPONENT_MW_CAT1CM0P -DCOMPONENT_MW_CLIB_SUPPORT -DCOMPONENT_MW_CMSIS -DCOMPONENT_MW_CORE_LIB -DCOMPONENT_MW_CORE_MAKE -DCOMPONENT_MW_FREERTOS -DCOMPONENT_MW_MTB_HAL_CAT1 -DCOMPONENT_MW_MTB_LITTLEFS -DCOMPONENT_MW_MTB_PDL_CAT1 -DCOMPONENT_MW_RECIPE_MAKE_CAT1C -DCOMPONENT_MW_RETARGET_IO -DCOMPONENT_RTOS_AWARE -DCOMPONENT_SOFTFP -DCOMPONENT_XMC7x_CM0P_SLEEP -DCORE_NAME_CM7_0=1 -DCY_APPNAME_mtb_example_psoc6_filesystem_littlefs_freertos -DCY_RETARGET_IO_CONVERT_LF_TO_CRLF -DCY_SUPPORTS_DEVICE_VALIDATION -DCY_TARGET_BOARD=APP_KIT_XMC71_EVK_LITE_V1 -DCY_USING_HAL -DDEBUG -DLFS_THREADSAFE -DTARGET_APP_KIT_XMC71_EVK_LITE_V1 -DXMC7100D_F176K4160  -I. -Ibsps/TARGET_APP_KIT_XMC71_EVK_LITE_V1 -Ibsps -Ibsps/TARGET_APP_KIT_XMC71_EVK_LITE_V1/config/GeneratedSource -Ibsps/TARGET_APP_KIT_XMC71_EVK_LITE_V1/config -Ilibs/abstraction-rtos/include -Ilibs/abstraction-rtos -Ilibs/abstraction-rtos/include/COMPONENT_FREERTOS -Ilibs/cat1cm0p/COMPONENT_CAT1C -Ilibs/cat1cm0p -Ilibs/clib-support -Ilibs/clib-support/TOOLCHAIN_GCC_ARM -Ilibs/cmsis/Core/Include -Ilibs/cmsis/Core -Ilibs/cmsis -Ilibs/core-lib/include -Ilibs/core-lib -Ilibs/freertos/Source/include -Ilibs/freertos/Source -Ilibs/freertos -Ilibs/freertos/Source/portable/COMPONENT_CM7 -Ilibs/freertos/Source/portable -Ilibs/freertos/Source/portable/COMPONENT_CM7/TOOLCHAIN_GCC_ARM -Ilibs/mtb-hal-cat1/COMPONENT_CAT1C/include/pin_packages -Ilibs/mtb-hal-cat1/COMPONENT_CAT1C/include -Ilibs/mtb-hal-cat1/COMPONENT_CAT1C -Ilibs/mtb-hal-cat1 -Ilibs/mtb-hal-cat1/COMPONENT_CAT1C/include/triggers -Ilibs/mtb-hal-cat1/include -Ilibs/mtb-hal-cat1/include_pvt -Ilibs/mtb-hal-cat1/source -Ilibs/mtb-pdl-cat1/devices/COMPONENT_CAT1C/include -Ilibs/mtb-pdl-cat1/devices/COMPONENT_CAT1C -Ilibs/mtb-pdl-cat1/devices -Ilibs/mtb-pdl-cat1 -Ilibs/mtb-pdl-cat1/devices/COMPONENT_CAT1C/include/ip -Ilibs/mtb-pdl-cat1/drivers/include -Ilibs/mtb-pdl-cat1/drivers -Ilibs/mtb-pdl-cat1/drivers/third_party/ethernet/include -Ilibs/mtb-pdl-cat1/drivers/third_party/ethernet -Ilibs/mtb-pdl-cat1/drivers/third_party -Ilibs/retarget-io -I../mtb_shared/mtb-littlefs/latest-v2.X/bd -I../mtb_shared/mtb-littlefs/latest-v2.X -I../mtb_shared/mtb-littlefs/latest-v2.X/include 
../mtb_shared/mtb-littlefs/latest-v2.X/source/lfs_qspi_memslot.c:487:5: error: 'cy_stc_smif_mem_device_cfg_t' has no member named 'mergeTimeout'
  487 |     .mergeTimeout = CY_SMIF_MERGE_TIMEOUT_1_CYCLE
      |     ^
make[1]: *** [libs/core-make/make/core/build.mk:283: C:/Users/Prasad/mtw/Littlefs_Filesystem/Littlefs_Filesystem/build/APP_KIT_XMC71_EVK_LITE_V1/Debug/ext/mtb_shared/mtb-littlefs/latest-v2.X/source/lfs_qspi_memslot.o] Error 1
make: *** [libs/core-make/make/core/main.mk:385: secondstage_build] Error 2
"C:/Users/Prasad/ModusToolbox/tools_3.2/modus-shell/bin/make CY_MAKE_IDE=eclipse CY_IDE_TOOLS_DIR=C:/Users/Prasad/ModusToolbox/tools_3.2 CY_IDE_BT_TOOLS_DIR= -j8 --output-sync all" terminated with exit code 2. Build might be incomplete.

 

 

 

When I comment the line:

 

 

#if (CY_IP_MXSMIF_VERSION >= 2)
    /** Continuous transfer merge timeout.
     * After this period the memory device is deselected. A later transfer, even from a
     * continuous address, starts with the overhead phases (command, address, mode, dummy cycles).
     * This configuration parameter is available for CAT1B devices. */
    //.mergeTimeout = CY_SMIF_MERGE_TIMEOUT_1_CYCLE
#endif /* CY_IP_MXSMIF_VERSION */

 

 

 

I get failed to creat spi device block:

PrasadA_0-1713522059074.png

 

Could someone help me with ".mergeTimeout = CY_SMIF_MERGE_TIMEOUT_1_CYCLE" error?

When using the mtb-littlefs through the mtb-shared, how do I enable the cy_hal, freertos and thread in make file?
I tried to add the necessary comments on my application makefile but it is not enabling the corresponding if condition in the files in mtb-shared folder/mtb-littlefs!

best regard,
PrasadA

 

0 Likes
8 Replies
Maragani
Moderator
Moderator
Moderator
25 solutions authored 10 likes received 100 replies posted

Hi @bluefish97 
We have not ported littlefs file system into XMC7000 devices, kindly give us some time to port at our end and will help you on your issue. 
Thanks & Regards
Sateesh M

bluefish97
Level 2
Level 2
10 sign-ins 5 questions asked 5 replies posted

Hi Maragani, Thak you for looking into this.

Meanwhile could you please guide me how I can assign (spi or gpio) pins to another external serial flash nor memory(from ISSI having qspi and spi inputs)? I would like to implement the serial flash read/write program (using the qspi configurator for my flash memeory)

(I was not able to find the spi/qspi architecture for xmc7100 in the board expect p7 port with I believe is default attached to the boards external qspi)

0 Likes
Maragani
Moderator
Moderator
Moderator
25 solutions authored 10 likes received 100 replies posted

Hi @bluefish97 
I have replied to your thread which is created separately. Give me 1 week of time I will get back on this issue.
Currently I am bit occupied with pending works. 
https://community.infineon.com/t5/XMC/QSPI-Connection-in-XMC7100D/td-p/744187


Thanks & Regards
Sateesh M

bluefish97
Level 2
Level 2
10 sign-ins 5 questions asked 5 replies posted

Hi Maragani,

I look forward to you response within a week.

 

Meanwhile, I tried to implement the littlefs filesystem by calling cy_serial_flash_qspi in the lfs_config struct. I am getting an error when running the program:

PrasadA_2-1713872609013.png

 

 

Do you know why this error occur? I dont have multiple file, this is my main.c:

 

/*******************************************************************************
* File Name: main.c
*
* Description: This is the source code for the Serial Flash Read and Write example
* for ModusToolbox.
*
* Related Document: See README.md
*
*
********************************************************************************
* Copyright 2018-2024, Cypress Semiconductor Corporation (an Infineon company) or
* an affiliate of Cypress Semiconductor Corporation.  All rights reserved.
*
* This software, including source code, documentation and related
* materials ("Software") is owned by Cypress Semiconductor Corporation
* or one of its affiliates ("Cypress") and is protected by and subject to
* worldwide patent protection (United States and foreign),
* United States copyright laws and international treaty provisions.
* Therefore, you may use this Software only as provided in the license
* agreement accompanying the software package from which you
* obtained this Software ("EULA").
* If no EULA applies, Cypress hereby grants you a personal, non-exclusive,
* non-transferable license to copy, modify, and compile the Software
* source code solely for use in connection with Cypress's
* integrated circuit products.  Any reproduction, modification, translation,
* compilation, or representation of this Software except as specified
* above is prohibited without the express written permission of Cypress.
*
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Cypress
* reserves the right to make changes to the Software without notice. Cypress
* does not assume any liability arising out of the application or use of the
* Software or any product or circuit described in the Software. Cypress does
* not authorize its products for use in any products where a malfunction or
* failure of the Cypress product may reasonably be expected to result in
* significant property damage, injury or death ("High Risk Product"). By
* including Cypress's product in a High Risk Product, the manufacturer
* of such system or application assumes all risk of such use and in doing
* so agrees to indemnify Cypress against all liability.
*******************************************************************************/

/*******************************************************************************
* Header Files
*******************************************************************************/
#include "cycfg_qspi_memslot.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include "cy_serial_flash_qspi.h"
#include <inttypes.h>
#include <string.h>
#include "lfs.h"
#include "lfs_spi_flash_bd.h"
/* FreeRTOS headers */
#include "FreeRTOS.h"
#include "task.h"
/*******************************************************************************
* Macros
*******************************************************************************/
#define PACKET_SIZE             (64u)     /* Memory Read/Write size */

/* Used when an array of data is printed on the console */
#define NUM_BYTES_PER_LINE      (16u)
#define LED_TOGGLE_DELAY_MSEC   (1000u)   /* LED blink delay */
#define MEM_SLOT_NUM            (0u)      /* Slot number of the memory to use */
#define QSPI_BUS_FREQUENCY_HZ   (50000000lu)
#define FLASH_DATA_AFTER_ERASE  (0xFFu)   /* Flash data after erase */

#define STORAGE_DEVICE_SD_CARD              (0)

#define LITTLEFS_TASK_STACK_SIZE            (512U)
#define USER_BUTTON_INTERRUPT_PRIORITY      (7U)

/* Debounce delay for the user button. */
#define DEBOUNCE_DELAY_MS                   (50U)
/*******************************************************************************
* Global Variables
*******************************************************************************/
static TaskHandle_t littlefs_task_handle;
static cyhal_gpio_callback_data_t user_btn_callback_data;

/* This enables RTOS aware debugging */
static volatile int uxTopUsedPriority;


/*******************************************************************************
* Function Prototypes
*******************************************************************************/
static void user_button_interrupt_handler(void *handler_arg, cyhal_gpio_event_t event);

/*******************************************************************************
* Function Definitions
*******************************************************************************/

/*******************************************************************************
* Function Name: check_status
********************************************************************************
* Summary:
*  Prints the message, indicates the non-zero status by turning the LED on, and
*  asserts the non-zero status.
*
* Parameters:
*  message - message to print if status is non-zero.
*  status - status for evaluation.
*
* Return:
*  void
*
*******************************************************************************/
void check_status(char *message, uint32_t status)
{
    if (0u != status)
    {
        printf("\r\n=====================================================\r\n");
        printf("\nFAIL: %s\r\n", message);
        printf("Error Code: 0x%08"PRIX32"\n", status);
        printf("\r\n=====================================================\r\n");

        /* On failure, turn the LED ON */
        cyhal_gpio_write(CYBSP_USER_LED, CYBSP_LED_STATE_ON);
        while(true); /* Wait forever here when error occurs. */
    }
}


/*******************************************************************************
* Function Name: print_array
********************************************************************************
* Summary:
*  Prints the content of the buffer to the UART console.
*
* Parameters:
*  message - message to print before array output
*  buf - buffer to print on the console.
*  size - size of the buffer.
*
* Return:
*  void
*
*******************************************************************************/
void print_array(char *message, uint8_t *buf, uint32_t size)
{
    printf("\r\n%s (%"PRIu32" bytes):\r\n", message, size);
    printf("-------------------------\r\n");

    for (uint32_t index = 0; index < size; index++)
    {
        printf("0x%02X ", buf[index]);

        if (0u == ((index + 1) % NUM_BYTES_PER_LINE))
        {
            printf("\r\n");
        }
    }
}
static void user_button_interrupt_handler(void *handler_arg, cyhal_gpio_event_t event)
{
    (void) handler_arg;
    (void) event;

    BaseType_t higher_priority_task_woken = pdFALSE;
    vTaskNotifyGiveFromISR(littlefs_task_handle, &higher_priority_task_woken);

    /* Yield if xHigherPriorityTaskWoken was set to true */
    portYIELD_FROM_ISR( higher_priority_task_woken );
}

static void print_block_device_parameters(struct lfs_config *lfs_cfg)
{
    printf("Number of blocks: %"PRIu32"\n", lfs_cfg->block_count);
    printf("Erase block size: %"PRIu32" bytes\n", lfs_cfg->block_size);
    printf("Prog size: %"PRIu32" bytes\n\n", lfs_cfg->prog_size);
}
static void increment_boot_count(lfs_t *lfs, struct lfs_config *lfs_cfg)
{
    uint32_t boot_count = 0;
    lfs_file_t file;

    /* Mount the filesystem */
    int err = lfs_mount(lfs, lfs_cfg);

    /* Reformat if we cannot mount the filesystem.
     * This should only happen when littlefs is set up on the storage device for
     * the first time.
     */
    if (err) {
        printf("\nError in mounting. This could be the first time littlefs is used on the storage device.\n");
        printf("Formatting the block device...\n\n");

        lfs_format(lfs, lfs_cfg);
        lfs_mount(lfs, lfs_cfg);
    }

    /* Read the current boot count. */
    lfs_file_open(lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT);
    lfs_file_read(lfs, &file, &boot_count, sizeof(boot_count));

    /* Update the boot count. */
    boot_count += 1;
    lfs_file_rewind(lfs, &file);
    lfs_file_write(lfs, &file, &boot_count, sizeof(boot_count));

    /* The storage is not updated until the file_sd is closed successfully. */
    lfs_file_close(lfs, &file);

    /* Release any resources we were using. */
    lfs_unmount(lfs);

    /* Print the boot count. */
    printf("boot_count: %"PRIu32"\n\n", boot_count);
}
static void littlefs_task(void* arg)
{
    cy_rslt_t result;
    lfs_t lfs;
    struct lfs_config lfs_cfg;

    /* Step 1: Get the default configuration for the block device.
     * Step 2: Initialize the lfs_config structure to zero (not required if it
     *         is a global variable)
     * Step 3: Create the block device
     * Step 4: Print the block device parameters such as erase block size
     * Step 5: Perform file system operations to increment the boot count
     */

#if(STORAGE_DEVICE_SD_CARD)
    lfs_sd_bd_config_t sd_bd_cfg;

    printf("Incrementing the boot count on SD Card...\n\n");

    /* Get the default configuration for the SD card block device. */
    lfs_sd_bd_get_default_config(&sd_bd_cfg);

    /* Initialize the pointers in lfs_cfg to NULL. */
    memset(&lfs_cfg, 0, sizeof(lfs_cfg));

    /* Create the SD card block device. */
    result = lfs_sd_bd_create(&lfs_cfg, &sd_bd_cfg);
    check_status("Creating SD card block device failed", result);
#else
    lfs_spi_flash_bd_config_t spi_flash_bd_cfg;

    printf("\nIncrementing the boot count on SPI flash...\n\n");

    /* Get the default configuration for the SPI flash block device. */
    lfs_spi_flash_bd_get_default_config(&spi_flash_bd_cfg);

    /* Initialize the pointers in lfs_cfg to NULL. */
    memset(&lfs_cfg, 0, sizeof(lfs_cfg));

    /* Create the SPI flash block device. */
    result = lfs_spi_flash_bd_create(&lfs_cfg, &spi_flash_bd_cfg);
    check_status("Creating SPI flash block device failed", result);
#endif /* #if(STORAGE_DEVICE_SD_CARD) */

    print_block_device_parameters(&lfs_cfg);
    increment_boot_count(&lfs, &lfs_cfg);

    /* Enable the user button interrupt */
    cyhal_gpio_enable_event(CYBSP_USER_BTN, CYHAL_GPIO_IRQ_FALL, USER_BUTTON_INTERRUPT_PRIORITY, true);

    printf("Press the user button to format the block device or press reset to increment the boot count again\n\n");

    /* Wait until the user button press is notified through the interrupt */
    while (true)
    {
        if(1lu == ulTaskNotifyTake(pdTRUE, portMAX_DELAY))
        {
            /* Debounce the button press. */
            vTaskDelay(pdMS_TO_TICKS(DEBOUNCE_DELAY_MS));

            if(!cyhal_gpio_read(CYBSP_USER_BTN)) { break; }
        }
    }

    /* User button is pressed. Format the block device. */
    printf("Formatting the block device...\n");
    lfs_format(&lfs, &lfs_cfg);
    printf("Formatting completed...\n");

#if(STORAGE_DEVICE_SD_CARD)
    lfs_sd_bd_destroy(&lfs_cfg);
#else
    lfs_spi_flash_bd_destroy(&lfs_cfg);
#endif /* #if(STORAGE_DEVICE_SD_CARD) */

    printf("Press reset to continue...\n");
}
/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
*  This is the main function for CM4 CPU. It does...
*     1. Initializes UART for console output and SMIF for interfacing a QSPI
*       flash.
*     2. Performs erase followed by write and verifies the written data by
*       reading it back.
*
* Parameters:
*  void
*
* Return:
*  int
*
*******************************************************************************/
int main(void)
{
    cy_rslt_t result;

    /* This enables RTOS aware debugging in OpenOCD */
    uxTopUsedPriority = configMAX_PRIORITIES - 1;

    /* Initialize the device and board peripherals */
    result = cybsp_init() ;
    CY_ASSERT (result == CY_RSLT_SUCCESS);

    /* Initialize retarget-io to use the debug UART port */
    result = cy_retarget_io_init(CYBSP_DEBUG_UART_TX, CYBSP_DEBUG_UART_RX, CY_RETARGET_IO_BAUDRATE);
    CY_ASSERT (result == CY_RSLT_SUCCESS);

    /* Initialize the user button used for erasing the block device. */
    result = cyhal_gpio_init(CYBSP_USER_BTN, CYHAL_GPIO_DIR_INPUT, CYHAL_GPIO_DRIVE_PULLUP, CYBSP_BTN_OFF);
    CY_ASSERT (result == CY_RSLT_SUCCESS);

    /* Configure GPIO interrupt */
    user_btn_callback_data.callback = user_button_interrupt_handler;

    /* Configure & the user button interrupt */
    cyhal_gpio_register_callback(CYBSP_USER_BTN, &user_btn_callback_data);

    /* Enable global interrupts */
    __enable_irq();

    /* \x1b[2J\x1b[;H - ANSI ESC sequence for clear screen */
    printf("\x1b[2J\x1b[;H");

    printf("************* "
           "Littlefs File System on SD Card and QSPI NOR Flash "
           "************* \n\n");

    /* Create the user tasks. See the respective task definition for more
     * details of these tasks.
     */
    xTaskCreate(littlefs_task, "Littlefs Task", LITTLEFS_TASK_STACK_SIZE,
                NULL, (configMAX_PRIORITIES - 1), &littlefs_task_handle);

    /* Start the RTOS scheduler. This function should never return */
    vTaskStartScheduler();

    (void) result; /* To avoid compiler warning */

    for (;;)
    {
    }
}


/* [] END OF FILE */

 

Best,

PrasadA

 

0 Likes
bluefish97
Level 2
Level 2
10 sign-ins 5 questions asked 5 replies posted

Hi, I tried to implement the mtb-littlefs in my xmc7100D board  with few modification to mq serial-read/write program: But I am encountering an error: could you tell me why I am unable to do "

lfs_file_read(lfs, &file, &boot_count, sizeof(boot_count));

"

My COM Port:

PrasadA_0-1713941252904.png

in my lfs.c:

lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
        void *buffer, lfs_size_t size) {
    int err = LFS_LOCK(lfs->cfg);
    if (err) {
        return err;
    }
    LFS_TRACE("lfs_file_read(%p, %p, %p, %"PRIu32")",
            (void*)lfs, (void*)file, buffer, size);
    printf("lfs_file_read(%p, %p, %p, %"PRIu32")",
                (void*)lfs, (void*)file, buffer, size);
    LFS_ASSERT(lfs_mlist_isopen(lfs->mlist, (struct lfs_mlist*)file));

    lfs_ssize_t res = lfs_file_rawread(lfs, file, buffer, size);

    LFS_TRACE("lfs_file_read -> %"PRId32, res);
    LFS_UNLOCK(lfs->cfg);
    return res;
}

How do I solve the LS_ASSERT function from failing?

 

Best,

PrasadA

 

0 Likes
Maragani
Moderator
Moderator
Moderator
25 solutions authored 10 likes received 100 replies posted

Hi @bluefish97 
can you please check the same code by  changing the P6_4 as output mode and output values is high in your code and since this GPIO is used for QSPI Reset. 

Best Wishes
Sateesh M

0 Likes

Hi , I assigned the pins for qspi (P6[4]CYBSP_FLASH_RST) in device configurator as such:

bluefish97_1-1714380236016.png

 

but it gives the following error: 

output1.PNG
this is my spi_flash_bd.c

 

 

 

 

#include "lfs_spi_flash_bd.h"
#include "lfs_util.h"
#include "cyhal_gpio.h"
#include "cy_serial_flash_qspi.h"
#include "cycfg_qspi_memslot.h"
#include "cycfg_pins.h"

#if defined(COMPONENT_RTOS_AWARE) || defined(LFS_THREADSAFE)
#include "cyabs_rtos.h"
#endif /* #if defined(COMPONENT_RTOS_AWARE) || defined(LFS_THREADSAFE) */

#if defined(__cplusplus)
extern "C"
{
#endif

#define RESULT_OK                                   (0)
#define RESULT_ERROR                                (-1)
#define GET_INT_RETURN_VALUE(result)                ((CY_RSLT_SUCCESS == (result)) ? RESULT_OK : RESULT_ERROR)

#define DEFAULT_QSPI_FREQUENCY_HZ                   (50000000UL)
#define QSPI_MIN_READ_SIZE                          (1UL)

/* Recommended value as per the comment in lfs.c is in the range of 100-1000. */
#define LFS_CFG_DEFAULT_BLOCK_CYCLES                (100UL)
#define LFS_CFG_LOOKAHEAD_SIZE_MIN                  (64UL) /* Must be a multiple of 8. */

#if defined(COMPONENT_RTOS_AWARE)
#define QSPI_READ_SEMA_MAX_COUNT                    (1UL)
#define QSPI_READ_SEMA_INIT_COUNT                   (0UL)

#ifndef LFS_SPI_FLASH_BD_ASYNC_READ_TIMEOUT_MS
#define LFS_SPI_FLASH_BD_ASYNC_READ_TIMEOUT_MS      (100UL) /* in milliseconds */
#endif /* #ifndef LFS_SPI_FLASH_BD_ASYNC_READ_TIMEOUT_MS */

/* Semaphore used while waiting for the QSPI read operation to complete. */
static cy_semaphore_t qspi_read_sema;

void qspi_read_complete_callback(cy_rslt_t status, void *arg)
{
    cy_rslt_t result;

    *((cy_rslt_t *) arg) = status;
    result = cy_rtos_set_semaphore(&qspi_read_sema, true);
    LFS_ASSERT(CY_RSLT_SUCCESS == result);
    CY_UNUSED_PARAMETER(result); /* To avoid compiler warning in Release mode. */
}
#endif /* #if defined(COMPONENT_RTOS_AWARE) */

#if defined(LFS_THREADSAFE)

#ifndef LFS_SPI_FLASH_BD_GET_MUTEX_TIMEOUT_MS
#define LFS_SPI_FLASH_BD_GET_MUTEX_TIMEOUT_MS      (500UL)
#endif /* #ifndef LFS_SPI_FLASH_BD_GET_MUTEX_TIMEOUT_MS */

static cy_mutex_t _spi_flash_bd_mutex;
#endif /* #if defined(LFS_THREADSAFE) */

void lfs_spi_flash_bd_get_default_config(lfs_spi_flash_bd_config_t *bd_cfg)
{
    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_get_default_config(%p)", (void*)bd_cfg);
    LFS_ASSERT(NULL != bd_cfg);

    bd_cfg->mem_config = &S25HL512T_SlaveSlot_1;

    bd_cfg->io0 = NC;
    bd_cfg->io1 = NC;
    bd_cfg->io2 = NC;
    bd_cfg->io3 = NC;
    bd_cfg->io4 = NC;
    bd_cfg->io5 = NC;
    bd_cfg->io6 = NC;
    bd_cfg->io7 = NC;
    bd_cfg->sclk = NC;
    bd_cfg->ssel = NC;
    bd_cfg->freq_hz = DEFAULT_QSPI_FREQUENCY_HZ;

#ifdef CYBSP_QSPI_D0
    bd_cfg->io0 = CYBSP_QSPI_D0;
#endif

#ifdef CYBSP_QSPI_D1
    bd_cfg->io1 = CYBSP_QSPI_D1;
#endif

#ifdef CYBSP_QSPI_D2
    bd_cfg->io2 = CYBSP_QSPI_D2;
#endif

#ifdef CYBSP_QSPI_D3
    bd_cfg->io3 = CYBSP_QSPI_D3;
#endif

#ifdef CYBSP_QSPI_SCK
    bd_cfg->sclk = CYBSP_QSPI_SCK;
#endif
#ifdef CYBSP_QSPI_SS
    bd_cfg->ssel = CYBSP_QSPI_SS;
#endif

    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_get_default_config -> %d", 0);
}

cy_rslt_t lfs_spi_flash_bd_create(struct lfs_config *lfs_cfg, const lfs_spi_flash_bd_config_t *bd_cfg)
{
    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_create(%p, %p)", (void*)lfs_cfg, (void*)bd_cfg);

    LFS_ASSERT(NULL != lfs_cfg);
    LFS_ASSERT(NULL != bd_cfg);

    /* Initialize the custom Card Detect pin. */
    cy_rslt_t result = cy_serial_flash_qspi_init(
                                bd_cfg->mem_config,
                                bd_cfg->io0, bd_cfg->io1, bd_cfg->io2, bd_cfg->io3,
                                bd_cfg->io4, bd_cfg->io5, bd_cfg->io6, bd_cfg->io7,
                                bd_cfg->sclk, bd_cfg->ssel, bd_cfg->freq_hz);

    uint32_t ext_mem_address = (smifMemConfigs[0]->deviceCfg->memSize);

    printf("\r\next_mem_address:%x bytes\r\n",ext_mem_address);
    uint32_t sectorSize = cy_serial_flash_qspi_get_erase_size(0);

    printf("\r\nTotal Flash Size:%x bytes\r\n",cy_serial_flash_qspi_get_size());
    printf("\r\nErase sector Size:%x bytes\r\n",sectorSize);
        /* Erase before write */
	printf("\r\n1. Erasing %x bytes of memory\r\n", sectorSize);
	result = cy_serial_flash_qspi_erase(0, sectorSize);
    check_status("Erasing memory failed", result);
#if defined(LFS_THREADSAFE)
    if(CY_RSLT_SUCCESS == result)
    {
        /* Initialize the mutex. */
        result = cy_rtos_init_mutex(&_spi_flash_bd_mutex);
    }
#endif /* #if defined(LFS_THREADSAFE) */

    if(CY_RSLT_SUCCESS == result)
    {
        /* Block device operations */
        lfs_cfg->read        = lfs_spi_flash_bd_read;
        lfs_cfg->prog        = lfs_spi_flash_bd_prog;
        lfs_cfg->erase       = lfs_spi_flash_bd_erase;
        lfs_cfg->sync        = lfs_spi_flash_bd_sync;

#if defined(LFS_THREADSAFE)
        lfs_cfg->lock        = lfs_spi_flash_bd_lock;
        lfs_cfg->unlock      = lfs_spi_flash_bd_unlock;
#endif /* #if defined(LFS_THREADSAFE) */

        /* Block device configuration */
        lfs_cfg->read_size   = QSPI_MIN_READ_SIZE;
        lfs_cfg->prog_size   = cy_serial_flash_qspi_get_prog_size(0);
        lfs_cfg->block_size  = cy_serial_flash_qspi_get_erase_size(0);
        lfs_cfg->block_count = cy_serial_flash_qspi_get_size() / lfs_cfg->block_size;

        /* Refer to lfs.h for the description of the following parameters. */

        /* Number of erase cycles before the data is moved to a new block.
         * A larger value results in more efficient filesystem performance, but
         * causes less even-wear distribution.
         *
         * Setting this to -1 disables dynamic wear leveling.
         */
        lfs_cfg->block_cycles = LFS_CFG_DEFAULT_BLOCK_CYCLES;

        /* cache_size must be a multiple of prog & read sizes.
         * i.e., cache_size % prog_size = 0 and cache_size % read_size = 0
         * block_size must be a multiple of cache_size. i.e., block_size % cache_size = 0.
         *
         * littlefs allocates 1 cache for each file and 2 caches for
         * internal operations.
         * The higher the cache size, the better the performance is, but the
         * RAM consumption is also higher.
         */
        lfs_cfg->cache_size = lfs_cfg->prog_size;

        /* A larger Lookahead size reduces the number of scans performed by
         * the block allocation algorithm thus increasing the filesystem
         * performance, but results in higher RAM consumption.
         *
         * Must be a multiple of 8.
         */
        lfs_cfg->lookahead_size = lfs_min((lfs_size_t) LFS_CFG_LOOKAHEAD_SIZE_MIN, 8UL * ((lfs_cfg->block_count + 63UL)/64UL) );

        printf("\n\rread_size:%d\n\r",lfs_cfg->read_size);
        printf("prog_size:%d\n\r",lfs_cfg->prog_size);
        printf("block_size:%d\n\r",lfs_cfg->block_size);
        printf("block_count:%d\n\r",lfs_cfg->block_count);
        printf("block_cycles:%d\n\r",lfs_cfg->block_cycles);
        printf("cache_size:%d\n\r",lfs_cfg->cache_size);
        printf("lookahead_size:%d\n\r",lfs_cfg->lookahead_size);

#if defined(COMPONENT_RTOS_AWARE)
        result = cy_rtos_init_semaphore(&qspi_read_sema, QSPI_READ_SEMA_MAX_COUNT, QSPI_READ_SEMA_INIT_COUNT);
#endif /* #if defined(COMPONENT_RTOS_AWARE) */
    }

    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_create -> %"PRIu32"", result);
    return result;
}
void lfs_spi_flash_bd_destroy(const struct lfs_config *lfs_cfg)
{
    cy_rslt_t result = CY_RSLT_SUCCESS;

    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_destroy(%p)", (void*)lfs_cfg);

    CY_UNUSED_PARAMETER(lfs_cfg);
    cy_serial_flash_qspi_deinit();

#if defined(COMPONENT_RTOS_AWARE)
    result = cy_rtos_deinit_semaphore(&qspi_read_sema);
    LFS_ASSERT(CY_RSLT_SUCCESS == result);
#endif /* #if defined(COMPONENT_RTOS_AWARE) */

#if defined(LFS_THREADSAFE)
    result = cy_rtos_deinit_mutex(&_spi_flash_bd_mutex);
    LFS_ASSERT(CY_RSLT_SUCCESS == result);
#endif /* #if defined(LFS_THREADSAFE) */

    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_destroy -> %d", 0);
    CY_UNUSED_PARAMETER(result); /* To avoid compiler warning in Release mode. */
}
int lfs_spi_flash_bd_read(const struct lfs_config *lfs_cfg, lfs_block_t block,
        lfs_off_t off, void *buffer, lfs_size_t size)
{
    cy_rslt_t result;

    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_read(%p, "
                    "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
                (void*)lfs_cfg, block, off, buffer, size);

    /* Check if parameters are valid. */
    LFS_ASSERT(NULL != lfs_cfg);
    LFS_ASSERT(block < lfs_cfg->block_count);
    LFS_ASSERT((off % lfs_cfg->read_size) == 0);
    LFS_ASSERT(NULL != buffer);
    LFS_ASSERT((size % lfs_cfg->read_size) == 0);

#if defined(COMPONENT_RTOS_AWARE)
    cy_rslt_t qspi_read_status = CY_RSLT_SUCCESS;

    /* Disable interrupts to ensure interrupt occurs only when we are ready to
     * get the semaphore.
     */
    uint32_t saved_intr_status = cyhal_system_critical_section_enter();
    result = cy_serial_flash_qspi_read_async((block * lfs_cfg->block_size) + off, size, buffer, qspi_read_complete_callback, (void *)&qspi_read_status);
    cyhal_system_critical_section_exit(saved_intr_status);

    if(CY_RSLT_SUCCESS == result)
    {
        /* Wait until the read semaphore is set. */
        result = cy_rtos_get_semaphore(&qspi_read_sema, LFS_SPI_FLASH_BD_ASYNC_READ_TIMEOUT_MS, false);

        if(CY_RSLT_SUCCESS == result)
        {
            result = qspi_read_status;
        }
    }
#else
    result = cy_serial_flash_qspi_read((block * lfs_cfg->block_size) + off, size, buffer);
#endif /* #if defined(COMPONENT_RTOS_AWARE) */

    int res = GET_INT_RETURN_VALUE(result);

    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_read -> %d", res);
    return res;
}

int lfs_spi_flash_bd_prog(const struct lfs_config *lfs_cfg, lfs_block_t block,
        lfs_off_t off, const void *buffer, lfs_size_t size)
{
    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_prog(%p, "
                    "0x%"PRIx32", %"PRIu32", %p, %"PRIu32")",
                (void*)lfs_cfg, block, off, buffer, size);

    /* Check if parameters are valid. */
    LFS_ASSERT(NULL != lfs_cfg);
    LFS_ASSERT(block < lfs_cfg->block_count);
    LFS_ASSERT(off  % lfs_cfg->prog_size == 0);
    LFS_ASSERT(NULL != buffer);
    LFS_ASSERT(size % lfs_cfg->prog_size == 0);

    cy_rslt_t result = cy_serial_flash_qspi_write((block * lfs_cfg->block_size) + off, size, buffer);
    int res = GET_INT_RETURN_VALUE(result);

    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_prg -> %d", res);
    return res;
}
int lfs_spi_flash_bd_erase(const struct lfs_config *lfs_cfg, lfs_block_t block)
{
    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_erase(%p, 0x%"PRIx32")", (void*)lfs_cfg, block);

    /* Check if parameters are valid. */
    LFS_ASSERT(NULL != lfs_cfg);
    LFS_ASSERT(block < lfs_cfg->block_count);

    uint32_t addr = block * lfs_cfg->block_size;
    cy_rslt_t result = cy_serial_flash_qspi_erase(addr, lfs_cfg->block_size);
    int res = GET_INT_RETURN_VALUE(result);

    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_erase -> %d", res);
    return res;
}
/* Simply return zero because the QSPI block does not have any write cache in MMIO
 * mode.
 */
int lfs_spi_flash_bd_sync(const struct lfs_config *lfs_cfg)
{
    CY_UNUSED_PARAMETER(lfs_cfg);

    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_sync(%p)", (void*)lfs_cfg);
    LFS_SPI_FLASH_BD_TRACE("lfs_spi_flash_bd_sync -> %d", 0);
    return 0;
}
#if defined(LFS_THREADSAFE)
int lfs_spi_flash_bd_lock(const struct lfs_config *lfs_cfg)
{
    CY_UNUSED_PARAMETER(lfs_cfg);
    return GET_INT_RETURN_VALUE(cy_rtos_get_mutex(&_spi_flash_bd_mutex, LFS_SPI_FLASH_BD_GET_MUTEX_TIMEOUT_MS));
}
int lfs_spi_flash_bd_unlock(const struct lfs_config *lfs_cfg)
{
    CY_UNUSED_PARAMETER(lfs_cfg);
    return GET_INT_RETURN_VALUE(cy_rtos_set_mutex(&_spi_flash_bd_mutex));
}
#endif /* #if defined(LFS_THREADSAFE) */
#ifdef __cplusplus
} /* extern "C" */
#endif

 

I think I may have found the reason: since littlefs seems to not read asyncronouslyI have to change qspi read . Do you have an idea how to counter this, it seems to be related to DMA.

0 Likes
bluefish97
Level 2
Level 2
10 sign-ins 5 questions asked 5 replies posted

Hi,
With synchro read I think I was able to lfs_format after erasing the full chip and lfs_mount.

But I am getting this error:

bluefish97_0-1714395729404.png

    /* Mount the filesystem */
    int err = lfs_mount(lfs, lfs_cfg);

    /* Reformat if we cannot mount the filesystem.
     * This should only happen when littlefs is set up on the storage device for
     * the first time.
     */
    if (err) {
        printf("\nError in mounting. This could be the first time littlefs is used on the storage device.\n");

    	uint32_t erasesize = cy_serial_flash_qspi_get_size();
    	cy_rslt_t result = cy_serial_flash_qspi_erase(0, erasesize);
    	check_status("Erasing memory failed", result);

        printf("Formatting the block device...\n\n");

        err = lfs_format(lfs, lfs_cfg);
        if (err)
        {
        	printf("\nError in formating:%d\n", err);
        }

        err = lfs_mount(lfs, lfs_cfg);
        if (err) {
        	printf("\nError in mounting:%d\n", err);
              }
    }

    /* Read the current boot count. */
    err = lfs_file_open(lfs, &file, "boot_count",  LFS_O_RDWR | LFS_O_CREAT);
    if (err) {
    	printf("\nError in file opening:%d\n", err);
      }
    err = lfs_file_write(lfs, &file, &boot_count, sizeof(boot_count));
    if (err) {
    	printf("\nError in File writing:%d\n", err);
      }
    lfs_ssize_t err1 = lfs_file_read(lfs, &file, &boot_count, sizeof(boot_count));
    if (err) {
    	printf("\nError in File reading:%d\n", err1);
      }

    boot_count += 2;
    err = lfs_file_rewind(lfs, &file);
    if (err) {
    	printf("\nError in rewinding:%d\n", err);
      }
    err1 = lfs_file_write(lfs, &file, &boot_count, sizeof(boot_count));
    if (err) {
    	printf("\nError in writing:%d\n", err1);
      }

    /* The storage is not updated until the file_sd is closed successfully. */
    err = lfs_file_close(lfs, &file);
    if (err) {
    	printf("\nError in closing:%d\n", err);
      }
    /* Release any resources we were using. */
    err =lfs_unmount(lfs);
    if (err) {
    	printf("\nError in unmounting:%d\n", err);
      }
    /* Print the boot count. */
    printf("boot_count: %"PRIu32"\n\n", boot_count);

 

0 Likes