Skip to content

STM32G4 QSPIF not working #15235

@pilotak

Description

@pilotak

Description of defect

First of all QSPI is not enabled for G4 family, the simplest change is to add following to targets\TARGET_STM\TARGET_STM32G4\objects.h
(i just followed #14392)

#if DEVICE_QSPI
struct qspi_s {
    QSPI_HandleTypeDef handle;
    QSPIName qspi;
    PinName io0;
    PinName io1;
    PinName io2;
    PinName io3;
    PinName sclk;
    PinName ssel;
};
#endif

In custom targets add

"device_has_add": ["QSPI"]
"components_add": ["QSPIF"]

The problem is that my flash (W25Q64JV) is not recognized by QSPIFBlockDevice, the reply is not what is actually sent

--- Mbed OS QSPIF block device example ---
[DBG ][QSPIF]: QSPIFBlockDevice csel: 75
[DBG ][STQS]: qspi_frequency hz 10000000
[DBG ][QSPIF]: Inst: 0x5h, addr: ffffffffffffffff, tx length: 0, rx length: 1
[DBG ][STQS]: qspi_command_transfer tx 0 rx 1 command 0x05
[DBG ][QSPIF]: Inst: 0x9fh, addr: ffffffffffffffff, tx length: 0, rx length: 3
[DBG ][STQS]: qspi_command_transfer tx 0 rx 3 command 0x9f
[DBG ][QSPIF]: Vendor device ID = 0xff 0xc0 0x3f
[INFO][SFDP]: SIG_B0: 247 (▒)
[INFO][SFDP]: SIG_B1: 206 (▒)
[INFO][SFDP]: SIG_B2: 204 (▒)
[INFO][SFDP]: SIG_B3: 240 (▒)
[INFO][SFDP]: R_MINOR: 15
[INFO][SFDP]: R_MAJOR: 3
[INFO][SFDP]: NPH: 1
[INFO][SFDP]: ACP: 255
[ERR ][SFDP]: Verify SFDP signature and version Failed
[ERR ][QSPIF]: Init - Parse SFDP Headers Failed
bd.init -> -4002
--------------------------- Block device geometry ---
read_size:    1 B
program_size: 1 B
erase_size:   0 B
size:         0 B
---
bd.read(0x20003850, 0, 15)
[DBG ][QSPIF]: Read Inst: 0x3h
[DBG ][QSPIF]: Inst: 0x3h, addr: 0, size: 15
bd.read -> 0
--- Stored data ---
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff     ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
---
bd.erase(0, 0)
[DBG ][QSPIF]: Erase - addr: 0, size: 0
bd.erase -> 0
bd.program(0x20003850, 0, 15)
[DBG ][QSPIF]: Program - Buff: 0x20003850, addr: 0, size: 15
[DBG ][QSPIF]: Inst: 0x6h, addr: ffffffffffffffff, tx length: 0, rx length: 0
[DBG ][STQS]: qspi_command_transfer tx 0 rx 0 command 0x06
[DBG ][QSPIF]: Inst: 0x5h, addr: ffffffffffffffff, tx length: 0, rx length: 1
[DBG ][STQS]: qspi_command_transfer tx 0 rx 1 command 0x05
[DBG ][QSPIF]: Inst: 0x5h, addr: ffffffffffffffff, tx length: 0, rx length: 1
[DBG ][STQS]: qspi_command_transfer tx 0 rx 1 command 0x05
[DBG ][QSPIF]: Inst: 0x2h, addr: 0, size: 0
[ERR ][QSPIF]: QSPI Write failed
[ERR ][QSPIF]: Write failed
bd.program -> -4001
bd.read(0x20003850, 0, 15)
[DBG ][QSPIF]: Read Inst: 0x3h
[DBG ][QSPIF]: Inst: 0x3h, addr: 0, size: 15
bd.read -> 0
--- Stored data ---
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff     ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
---
bd.deinit()
bd.deinit -> 0
--- done! ---

So i hooked up my analyzer and here are actual steps
[DBG ][QSPIF]: Inst: 0x5h, addr: ffffffffffffffff, tx length: 0, rx length: 1 is
1

[DBG ][QSPIF]: Inst: 0x9fh, addr: ffffffffffffffff, tx length: 0, rx length: 3 is
2
as you can see the flash reply correctly but for some reason mbed sees Vendor device ID = 0xff 0xc0 0x3f

[DBG ][STQS]: qspi_command_transfer tx 0 rx 3 command 0x9f is
3

you can clearly see that the reply is SFDP

Target(s) affected by this defect ?

STM32G4 specifically G484VE

Toolchain(s) (name and version) displaying this defect ?

GCC ARM 9.3.1

What version of Mbed-os are you using (tag or sha) ?

a58f8dd

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

mbed-cli 1.10.1

How is this defect reproduced ?

#include "mbed.h"
#include <stdio.h>
#include <algorithm>
#include "QSPIFBlockDevice.h"

QSPIFBlockDevice bd(QSPI_FLASH1_IO0, QSPI_FLASH1_IO1, QSPI_FLASH1_IO2, QSPI_FLASH1_IO3,
                    QSPI_FLASH1_SCK, QSPI_FLASH1_CSN, QSPIF_POLARITY_MODE_0, 10000000);

#if MBED_CONF_MBED_TRACE_ENABLE
#include "mbed-trace/mbed_trace.h"
static Mutex trace_mutex;

static void trace_wait() {
    trace_mutex.lock();
}

static void trace_release() {
    trace_mutex.unlock();
}

void trace_init() {
    mbed_trace_init();
    // mbed_trace_exclude_filters_set(const_cast<char*>("UBX "));

    mbed_trace_mutex_wait_function_set(trace_wait);
    mbed_trace_mutex_release_function_set(trace_release);
}
#endif

// Entry point for the example
int main() {

#if MBED_CONF_MBED_TRACE_ENABLE
    trace_init();
#endif

    printf("--- Mbed OS QSPIF block device example ---\n");

    // Initialize the block device
    int err = bd.init();
    printf("bd.init -> %d\n", err);

    if (err != BD_ERROR_OK) {
        printf("------------------------");
    }

    int erase_val = bd.get_erase_value();

    // Get device geometry
    bd_size_t read_size    = bd.get_read_size();
    bd_size_t program_size = bd.get_program_size();
    bd_size_t erase_size   = bd.get_erase_size();
    bd_size_t size         = bd.size();

    printf("--- Block device geometry ---\n");
    printf("read_size:    %lld B\n", read_size);
    printf("program_size: %lld B\n", program_size);
    printf("erase_size:   %lld B\n", erase_size);
    printf("size:         %lld B\n", size);
    printf("---\n");

    // Allocate a block with enough space for our data, aligned to the
    // nearest program_size. This is the minimum size necessary to write
    // data to a block.
    size_t buffer_size = sizeof("Hello Storage!") + program_size - 1;
    buffer_size = buffer_size - (buffer_size % program_size);
    char *buffer = new char[buffer_size];

    // Read what is currently stored on the block device. We haven't written
    // yet so this may be garbage
    printf("bd.read(%p, %d, %d)\n", buffer, 0, buffer_size);
    err = bd.read(buffer, 0, buffer_size);
    printf("bd.read -> %d\n", err);

    printf("--- Stored data ---\n");

    for (size_t i = 0; i < buffer_size; i += 16) {
        for (size_t j = 0; j < 16; j++) {
            if (i + j < buffer_size) {
                printf("%02x ", buffer[i + j]);

            } else {
                printf("   ");
            }
        }

        printf(" %.*s\n", buffer_size - i, &buffer[i]);
    }

    printf("---\n");

    // Update buffer with our string we want to store
    strncpy(buffer, "Hello Storage!", buffer_size);

    // Write data to first block, write occurs in two parts,
    // an erase followed by a program
    printf("bd.erase(%d, %lld)\n", 0, erase_size);
    err = bd.erase(0, erase_size);
    printf("bd.erase -> %d\n", err);

    printf("bd.program(%p, %d, %d)\n", buffer, 0, buffer_size);
    err = bd.program(buffer, 0, buffer_size);
    printf("bd.program -> %d\n", err);

    // Clobber the buffer so we don't get old data
    memset(buffer, 0xcc, buffer_size);

    // Read the data from the first block, note that the program_size must be
    // a multiple of the read_size, so we don't have to check for alignment
    printf("bd.read(%p, %d, %d)\n", buffer, 0, buffer_size);
    err = bd.read(buffer, 0, buffer_size);
    printf("bd.read -> %d\n", err);

    printf("--- Stored data ---\n");

    for (size_t i = 0; i < buffer_size; i += 16) {
        for (size_t j = 0; j < 16; j++) {
            if (i + j < buffer_size) {
                printf("%02x ", buffer[i + j]);

            } else {
                printf("   ");
            }
        }

        printf(" %.*s\n", buffer_size - i, &buffer[i]);
    }

    printf("---\n");

    // Deinitialize the block device
    printf("bd.deinit()\n");
    err = bd.deinit();
    printf("bd.deinit -> %d\n", err);

    printf("--- done! ---\n");
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions