This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

FATFS working on MXIC MX25R6435F but not on S25FS128S

Hello,

We have integrated the FATFS example as shown in the usbd_msc example project into our own firmware application. It works perfectly on the nRF52840dk and when we modify our own hardware with the MX25R6435F chip it also runs fine on our own hardware. Meaning I can mount the filesystem, list the filesystem contents, create files, read files and modify the files.

However when we try to run it on our hardware with S25FS128S (which is the flash chip we use in production) we can only (seemingly) write the filesystem and mount it. When we try to create new files they do seem to get written (the lower level qspi functions are being called) but the filesystem itself does not get updated.

We looked on the devzone and found these examples: https://devzone.nordicsemi.com/f/nordic-q-a/50534/qspi-block-device-issue-with-s25fs-flash-part  and https://devzone.nordicsemi.com/f/nordic-q-a/56928/qspi-32bit-addressing-mode but I was not able to get the FS to behave properly. I am however able to use the memory in both 24 and 32bit addressing mode and get similar behavior.

This are the flash_params we used: static const nrf_serial_flash_params_t m_sflash_params[] = {
    {    /*S25FS128S*/
        .read_id = { 0x01, 0x20, 0x18 },
        .capabilities = 0x00,
        .size = 16 * 1024 * 1024,
        .erase_size = 4 * 1024,
        .program_size = 256,
    }
};

The chip ID is being read just fine.

How can it be that i seem to be able to read and write the FS itself but I'm not able to add files, let alone modify them. We are running on sdk 15.2 with softdevice 140 btw. 

Looking forward to your reply,

Best regards,

Michiel

  • Hi Michiel

    This sounds strange indeed, as I would assume it would be all or nothing. I think the SDK configuration for addressing mode (I.E. 32-bit addressing mode) only changes the addressing mode in the QSPI peripheral. The external flash also needs to be told what mode it's expected to work in somehow. This command can be different from flash vendor to flash vendor, so it's hard to implement in one of our drivers.

    To do that for the S25FS series, I think you need to issue the 4BAM (see S25FS128S datasheet) command using a custom instruction (which is described in our QSPI peripheral documentation in the nRF52840 PS).

    When both the flash and QSPI peripheral are in 4-byte addressing mode, our peripheral uses the commands from the Flash part's datasheet with 4-byte addresses.

    Best regards,

    Simon

  • Hi Simon,

    Thanks for your response.

    I too find it strange. Indeed all or nothing behavior would make way more sense.

    What you mention with regards to the 4-byte addressing mode is correct. To get the device working in 4-byte addressing mode one does indeed need to issue the 4BAM command. Which I did like this (based on one of the threads is mentioned above).

                #define QSPI_STD_CMD_EN4B  0xB7 
        
                nrf_qspi_cinstr_conf_t cinstr_cfg2 = {
                        .opcode    = QSPI_STD_CMD_EN4B,
                        .length    = NRF_QSPI_CINSTR_LEN_1B,
                        .io2_level = true,
                        .io3_level = true,
                        .wipwait   = true,
                        .wren      = true
                };
                
                uint32_t err_code = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg2, NULL, NULL);
                APP_ERROR_CHECK(err_code);

    I used the following sdk_config.h setting:

    // <e> NRFX_QSPI_ENABLED - nrfx_qspi - QSPI peripheral driver
    //==========================================================
    #ifndef NRFX_QSPI_ENABLED
    #define NRFX_QSPI_ENABLED 1
    #endif
    // <o> NRFX_QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).  <0-255> 
    
    
    #ifndef NRFX_QSPI_CONFIG_SCK_DELAY
    #define NRFX_QSPI_CONFIG_SCK_DELAY 1
    #endif
    
    // <o> NRFX_QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation. 
    #ifndef NRFX_QSPI_CONFIG_XIP_OFFSET
    #define NRFX_QSPI_CONFIG_XIP_OFFSET 0
    #endif
    
    // <o> NRFX_QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
     
    // <0=> FastRead 
    // <1=> Read2O 
    // <2=> Read2IO 
    // <3=> Read4O 
    // <4=> Read4IO 
    
    #ifndef NRFX_QSPI_CONFIG_READOC
    #define NRFX_QSPI_CONFIG_READOC 0
    #endif
    
    // <o> NRFX_QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
     
    // <0=> PP 
    // <1=> PP2O 
    // <2=> PP4O 
    // <3=> PP4IO 
    
    #ifndef NRFX_QSPI_CONFIG_WRITEOC
    #define NRFX_QSPI_CONFIG_WRITEOC 0
    #endif
    
    // <o> NRFX_QSPI_CONFIG_ADDRMODE  - Addressing mode.
     
    // <0=> 24bit 
    // <1=> 32bit 
    
    #ifndef NRFX_QSPI_CONFIG_ADDRMODE
    #define NRFX_QSPI_CONFIG_ADDRMODE 1
    #endif
    
    // <o> NRFX_QSPI_CONFIG_MODE  - SPI mode.
     
    // <0=> Mode 0 
    // <1=> Mode 1 
    
    #ifndef NRFX_QSPI_CONFIG_MODE
    #define NRFX_QSPI_CONFIG_MODE 0
    #endif
    
    // <o> NRFX_QSPI_CONFIG_FREQUENCY  - Frequency divider.
     
    // <0=> 32MHz/1 
    // <1=> 32MHz/2 
    // <2=> 32MHz/3 
    // <3=> 32MHz/4 
    // <4=> 32MHz/5 
    // <5=> 32MHz/6 
    // <6=> 32MHz/7 
    // <7=> 32MHz/8 
    // <8=> 32MHz/9 
    // <9=> 32MHz/10 
    // <10=> 32MHz/11 
    // <11=> 32MHz/12 
    // <12=> 32MHz/13 
    // <13=> 32MHz/14 
    // <14=> 32MHz/15 
    // <15=> 32MHz/16 
    
    #ifndef NRFX_QSPI_CONFIG_FREQUENCY
    #define NRFX_QSPI_CONFIG_FREQUENCY 15
    #endif
    
    // <s> NRFX_QSPI_PIN_SCK - SCK pin value.
    #ifndef NRFX_QSPI_PIN_SCK
    #define NRFX_QSPI_PIN_SCK NRF_QSPI_PIN_NOT_CONNECTED
    #endif
    
    // <s> NRFX_QSPI_PIN_CSN - CSN pin value.
    #ifndef NRFX_QSPI_PIN_CSN
    #define NRFX_QSPI_PIN_CSN NRF_QSPI_PIN_NOT_CONNECTED
    #endif
    
    // <s> NRFX_QSPI_PIN_IO0 - IO0 pin value.
    #ifndef NRFX_QSPI_PIN_IO0
    #define NRFX_QSPI_PIN_IO0 NRF_QSPI_PIN_NOT_CONNECTED
    #endif
    
    // <s> NRFX_QSPI_PIN_IO1 - IO1 pin value.
    #ifndef NRFX_QSPI_PIN_IO1
    #define NRFX_QSPI_PIN_IO1 NRF_QSPI_PIN_NOT_CONNECTED
    #endif
    
    // <s> NRFX_QSPI_PIN_IO2 - IO2 pin value.
    #ifndef NRFX_QSPI_PIN_IO2
    #define NRFX_QSPI_PIN_IO2 NRF_QSPI_PIN_NOT_CONNECTED
    #endif
    
    // <s> NRFX_QSPI_PIN_IO3 - IO3 pin value.
    #ifndef NRFX_QSPI_PIN_IO3
    #define NRFX_QSPI_PIN_IO3 NRF_QSPI_PIN_NOT_CONNECTED
    #endif
    
    // <o> NRFX_QSPI_CONFIG_IRQ_PRIORITY  - Interrupt priority
     
    // <0=> 0 (highest) 
    // <1=> 1 
    // <2=> 2 
    // <3=> 3 
    // <4=> 4 
    // <5=> 5 
    // <6=> 6 
    // <7=> 7 
    
    #ifndef NRFX_QSPI_CONFIG_IRQ_PRIORITY
    #define NRFX_QSPI_CONFIG_IRQ_PRIORITY 6
    #endif
    

    But like I said when I properly configure the addressing mode and I create the file system within the same addressing mode I get the same behavior: A mountable filesystem to which I cannot seem to write anything.

    Do you know if there are cases where somebody successfully used the fatfs with this memory chip or at least one in the same "family"? We are really confused about what could be wrong since I would guess with all the checks in the nrf_block_dev_qspi.c code actual malfunctioning on the qspi level would be caught (I am thinking timeouts, non responsive qspi, etc).

    Thanks and best regards,

    Michiel

  • Hi again

    Seeing as you use SDK v15.2, this could be related to the bug mentioned in this case. Please try implemenitng the nrf_blovk_dev_qspi.c driver file uploaded by my colleague Susheel instead of the one you're using now to see if that helps. If that doesn't help either. This was the only other case in the DevZone archive mentioning the S25FS family, so if you have no luck here either, please double and triple check that the read_id is correct in your case, and if the problem persists, I'll open an internal ticket on the matter, so the developers of our QSPI driver can look at this issue.

    Best regards,

    Simon

  • Hi Simon,

    I tried to modify the nrf_block_dev_qspi.c with the suggested file in the other thread without any luck. I tried for with my flash memory both in 24 and 32bit addressing mode.

    As for the read_id I triple checked it and cross referenced it with the s25f data sheet and it is correct. Also if I make this value to be anything else the memory will not initialize and in that case I cannot mount the file system, which I currently can so I am pretty positive this is not the culprit.

    It would be nice if you could open an internal ticket. As by this time I really have no clue what could still be going wrong. Specially since it does work fine with the other memory chip and there are no more obvious things to try and verify as far as I can see.

    I did also make a log of the read and write addresses used by the firmware during the creation of the filesystem both on the working device and our custom hardware. Here I can see that at the end of the creation of the file system the working device writes to the front of the memory (starting from address 0 up to address 3584) and on our hardware it only reads address 0 but does not perform the writes. Maybe this is a good indication for you on what is going on?

    Thanks again for your support,

    Michiel

    <info> app: Initializing disk 0 (QSPI)...
    <info> app: Mounting volume...
    <info> app: reading from: 0
    <error> app: Mount failed. Filesystem not found. Please format device.
    <info> app: 
    Creating filesystem...
    <info> app: reading from: 28672
    <info> app: writing to: 28672
    <info> app: writing to: 29184
    <info> app: writing to: 29696
    <info> app: writing to: 30208
    <info> app: writing to: 30720
    <info> app: writing to: 31232
    <info> app: writing to: 31744
    <info> app: writing to: 32256
    <info> app: reading from: 32768
    <info> app: writing to: 32768
    <info> app: writing to: 33280
    <info> app: writing to: 33792
    <info> app: writing to: 34304
    <info> app: writing to: 34816
    <info> app: writing to: 35328
    <info> app: writing to: 35840
    <info> app: writing to: 36352
    <info> app: reading from: 36864
    <info> app: reading from: 40960
    <info> app: reading from: 45056
    <info> app: reading from: 49152
    <info> app: writing to: 49152
    <info> app: writing to: 49664
    <info> app: writing to: 50176
    <info> app: writing to: 50688
    <info> app: writing to: 51200
    <info> app: writing to: 51712
    <info> app: writing to: 52224
    <info> app: writing to: 52736
    <info> app: reading from: 53248
    <info> app: reading from: 57344
    <info> app: reading from: 61440
    <info> app: reading from: 0
    <info> app: writing to: 0
    <info> app: writing to: 512
    <info> app: writing to: 1024
    <info> app: writing to: 1536
    <info> app: writing to: 2048
    <info> app: writing to: 2560
    <info> app: writing to: 3072
    <info> app: writing to: 3584
    <info> app: Mounting volume...
    <info> app: reading from: 0
    <info> app: reading from: 32256
    <info> app: Done

    <info> app: Initializing disk 0 (QSPI)...
    <info> app: Mounting volume...
    <info> app: reading from: 0
    <error> app: Mount failed. Filesystem not found. Please format device.
    <info> app: 
    Creating filesystem...
    <info> app: reading from: 28672
    <info> app: writing to: 32256
    <info> app: reading from: 32768
    <info> app: writing to: 32768
    <info> app: writing to: 33280
    <info> app: writing to: 33792
    <info> app: writing to: 34304
    <info> app: writing to: 34816
    <info> app: writing to: 35328
    <info> app: writing to: 35840
    <info> app: writing to: 36352
    <info> app: reading from: 36864
    <info> app: writing to: 36864
    <info> app: writing to: 37376
    <info> app: writing to: 37888
    <info> app: writing to: 38400
    <info> app: writing to: 38912
    <info> app: writing to: 39424
    <info> app: writing to: 39936
    <info> app: writing to: 40448
    <info> app: reading from: 40960
    <info> app: writing to: 40960
    <info> app: writing to: 41472
    <info> app: writing to: 41984
    <info> app: writing to: 42496
    <info> app: writing to: 43008
    <info> app: writing to: 43520
    <info> app: writing to: 44032
    <info> app: writing to: 44544
    <info> app: reading from: 45056
    <info> app: writing to: 45056
    <info> app: writing to: 45568
    <info> app: writing to: 46080
    <info> app: writing to: 46592
    <info> app: writing to: 47104
    <info> app: writing to: 47616
    <info> app: writing to: 48128
    <info> app: writing to: 48640
    <info> app: reading from: 49152
    <info> app: writing to: 49152
    <info> app: writing to: 49664
    <info> app: writing to: 50176
    <info> app: writing to: 50688
    <info> app: writing to: 51200
    <info> app: writing to: 51712
    <info> app: writing to: 52224
    <info> app: writing to: 52736
    <info> app: reading from: 53248
    <info> app: writing to: 53248
    <info> app: writing to: 53760
    <info> app: writing to: 54272
    <info> app: writing to: 54784
    <info> app: writing to: 55296
    <info> app: writing to: 55808
    <info> app: writing to: 56320
    <info> app: writing to: 56832
    <info> app: reading from: 57344
    <info> app: writing to: 57344
    <info> app: writing to: 57856
    <info> app: writing to: 58368
    <info> app: writing to: 58880
    <info> app: writing to: 59392
    <info> app: writing to: 59904
    <info> app: writing to: 60416
    <info> app: writing to: 60928
    <info> app: reading from: 61440
    <info> app: writing to: 61440
    <info> app: writing to: 61952
    <info> app: writing to: 62464
    <info> app: writing to: 62976
    <info> app: writing to: 63488
    <info> app: writing to: 64000
    <info> app: writing to: 64512
    <info> app: writing to: 65024
    <info> app: reading from: 65536
    <info> app: writing to: 65536
    <info> app: writing to: 66048
    <info> app: writing to: 66560
    <info> app: writing to: 67072
    <info> app: writing to: 67584
    <info> app: writing to: 68096
    <info> app: writing to: 68608
    <info> app: writing to: 69120
    <info> app: reading from: 69632
    <info> app: writing to: 69632
    <info> app: writing to: 70144
    <info> app: writing to: 70656
    <info> app: writing to: 71168
    <info> app: writing to: 71680
    <info> app: writing to: 72192
    <info> app: writing to: 72704
    <info> app: writing to: 73216
    <info> app: reading from: 73728
    <info> app: writing to: 73728
    <info> app: writing to: 74240
    <info> app: writing to: 74752
    <info> app: writing to: 75264
    <info> app: writing to: 75776
    <info> app: writing to: 76288
    <info> app: writing to: 76800
    <info> app: writing to: 77312
    <info> app: reading from: 77824
    <info> app: writing to: 77824
    <info> app: writing to: 78336
    <info> app: writing to: 78848
    <info> app: writing to: 79360
    <info> app: writing to: 79872
    <info> app: writing to: 80384
    <info> app: writing to: 80896
    <info> app: writing to: 81408
    <info> app: reading from: 0
    <info> app: writing to: 0
    <info> app: Mounting volume...
    <info> app: reading from: 0
    <info> app: reading from: 32256
    <info> app: Done

  • Hi,

    I found another piece of information that might be interesting to consider.

    On the website of the manufacturer of the flash I found (I could share the link if you deem this appropriate):

    By default, the S25FS128S flash device comes with hybrid sectors (the first sector of 64KB divided into 9 sectors (8 sectors of 4KB and one 32KB sector).  All remaining sectors are uniform (64KB each).

    When you use the Control Center application from the FX3 SDK, the internal programming utility (CyBootProgrammer.img) assumes uniform sector size for the flash device; this leads to corrupted data in the first sector, which is a hybrid sector.

    To prevent this, configure the flash device to use uniform sectors of 64KB each by modifying the Configuration Register 3 (CR3NV) – see Figure 1.

    Figure 1. Configuration Register 3 (CR3NV): Address = 0x00000004

         

    To configure the flash with uniform 64KB sectors, write ‘1’ to CR3NV[3] and ‘0’ to CR3NV[1] using the  WRAR 71h command (write 0x08 into the CR3NV register). After updating this register, use the default Control Center application to load the firmware image to the flash.

    Could it be that these so called "hybrid sectors" are confusing the file system implementation? I would assume the implementation expects uniform sectors? I am currently trying to modify the settings of the memory chip.

    Best regards,

    Michiel

Related