Skip to content

QSPI example for default mode, read-write #1

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

Merged
merged 3 commits into from
Oct 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions QSPI/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# QSPI example #

QSPI driver usage example for mbed OS

This is a example showing how to use mbed-OS QSPI driver to access a device interfaced over Quad-SPI
The program does read/write operations on Flash memory connected over Quad-SPI interface using driver APIs in default QSPI mode.

QSPI can be configured into different modes, based on underlying interface support. Refer to QSPI flash block device for more information (https://github.com/ARMmbed/qspif-blockdevice)
179 changes: 179 additions & 0 deletions QSPI/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
#if !DEVICE_QSPI
#error [NOT_SUPPORTED] QSPI not supported for this target
#endif

#include "mbed.h"
#include "drivers/QSPI.h"

#define CMD_WRITE 0x02
#define CMD_READ 0x03
#define CMD_ERASE 0x20
#define CMD_RDSR 0x5
#define CMD_WREN 0x6
#define CMD_RSTEN 0x66
#define CMD_RST 0x99
#define STATUS_REG_SIZE 2
#define BIT_WIP 0x1
#define BIT_WEL 0x2
#define BUF_SIZE 10

// hardware ssel (where applicable)
QSPI qspi_device(QSPI_FLASH1_IO0, QSPI_FLASH1_IO1, QSPI_FLASH1_IO2, QSPI_FLASH1_IO3, QSPI_FLASH1_SCK, QSPI_FLASH1_CSN); // io0, io1, io2, io3, sclk, ssel

static bool mem_ready()
{
char status_value[STATUS_REG_SIZE] = {0xFF};
int retries = 10000;
bool mem_ready = true;

do {
retries--;
if (QSPI_STATUS_OK != qspi_device.command_transfer(CMD_RDSR, -1, NULL, 0, status_value, STATUS_REG_SIZE)) {
printf("Reading Status Register failed \n");
}
wait_ms(1);
} while ( (status_value[0] & BIT_WIP) != 0 && retries);

if ((status_value[0] & BIT_WIP) != 0) {
printf ("mem_ready FALSE: status value = 0x%x\n", (int)status_value[0]);
mem_ready = false;
}
return mem_ready;
}

static int write_enable()
{
char status_value[STATUS_REG_SIZE] = {0};
int status = -1;

if (QSPI_STATUS_OK != qspi_device.command_transfer(CMD_WREN, -1, NULL, 0, NULL, 0)) {
printf("Sending WREN command FAILED \n");
return status;
}

if ( false == mem_ready()) {
printf("Device not ready \n");
return status;
}

if (QSPI_STATUS_OK != qspi_device.command_transfer(CMD_RDSR, -1, NULL, 0, status_value, STATUS_REG_SIZE)) {
printf("Reading Status Register failed \n");
return status;
}

if ((status_value[0] & BIT_WEL)) {
status = 0;
}
return status;
}

static int flash_init()
{
int status = QSPI_STATUS_OK;
char status_value[STATUS_REG_SIZE] = {0};

// Read the Status Register from device
status = qspi_device.command_transfer(CMD_RDSR, -1, NULL, 0, status_value, STATUS_REG_SIZE);
if (status != QSPI_STATUS_OK) {
printf("Reading Status Register failed: value = 0x%x\n", (int)status_value[0]);
return status;
}

// Send Reset Enable
status = qspi_device.command_transfer(CMD_RSTEN, -1, NULL, 0, NULL, 0);
if (status == QSPI_STATUS_OK) {
printf("Sending RSTEN Success \n");
} else {
printf("Sending RSTEN failed \n");
return status;
}

if ( false == mem_ready()) {
printf("Device not ready \n");
return -1;
}

// Send Reset
status = qspi_device.command_transfer(CMD_RST, -1, NULL, 0, NULL, 0);
if (status == QSPI_STATUS_OK) {
printf("Sending RST Success \n");
} else {
printf("Sending RST failed \n");
return status;
}

if ( false == mem_ready()) {
printf("Device not ready \n");
return -1;
}
return status;
}

static int sector_erase(unsigned int flash_addr)
{
if (0 != write_enable()) {
printf("Write Enabe failed \n");
return -1;
}

if( QSPI_STATUS_OK!= qspi_device.command_transfer(CMD_ERASE, (((int)flash_addr) & 0x00FFF000), NULL, 0, NULL, 0))
{
printf("Erase failed\n");
return -1;
}

if ( false == mem_ready()) {
printf("Device not ready \n");
return -1;
}

return 0;
}

int main() {
char tx_buf[] = { 'h', 'e', 'l', 'l', 'o', '\0' };
char rx_buf[BUF_SIZE] = {0};
size_t buf_len = sizeof(tx_buf);
qspi_status_t result;
uint32_t address = 0x1000;

result = qspi_device.configure_format(QSPI_CFG_BUS_SINGLE, QSPI_CFG_BUS_SINGLE,
QSPI_CFG_ADDR_SIZE_24, QSPI_CFG_BUS_SINGLE,
QSPI_CFG_ALT_SIZE_8, QSPI_CFG_BUS_SINGLE, 0);
if (result != QSPI_STATUS_OK) {
printf("Config format failed\n");
}

if (QSPI_STATUS_OK != flash_init()) {
printf ("Init failed\n");
return -1;
}

if (0 != sector_erase(address)) {
return -1;
}

if (0 != write_enable()) {
printf("Write Enabe failed \n");
return -1;
}
result = qspi_device.write(CMD_WRITE, -1, address, tx_buf, &buf_len);
if (result != QSPI_STATUS_OK) {
printf("Write failed\n");
return result;
}
printf("Write done: %s \n", tx_buf);

if ( false == mem_ready()) {
printf("Device not ready \n");
return -1;
}

result = qspi_device.read(CMD_READ, -1, address, rx_buf, &buf_len);
if (result != QSPI_STATUS_OK) {
printf("Read failed\n");
return result;
}
printf ("Data Read = %s\n", rx_buf);
return 0;
}
1 change: 1 addition & 0 deletions QSPI/mbed-os.lib
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/ARMmbed/mbed-os/#c53d51fe9220728bf8ed27afe7afc1ecc3f6f5d7