git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9508 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
b36f9f5585
commit
a3c37f98cc
|
@ -25,8 +25,9 @@
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hal.h"
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
#include "m25q.h"
|
#include "m25q.h"
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -82,11 +83,7 @@ static flash_descriptor_t descriptor = {
|
||||||
.attributes = FLASH_ATTR_ERASED_IS_ONE | FLASH_ATTR_REWRITABLE |
|
.attributes = FLASH_ATTR_ERASED_IS_ONE | FLASH_ATTR_REWRITABLE |
|
||||||
FLASH_ATTR_SUSPEND_ERASE_CAPABLE,
|
FLASH_ATTR_SUSPEND_ERASE_CAPABLE,
|
||||||
.page_size = 256U,
|
.page_size = 256U,
|
||||||
#if M25Q_USE_SUB_SECTORS == TRUE
|
.sectors_count = 0U, /* It is overwritten.*/
|
||||||
.sectors_count = 4096U,
|
|
||||||
#else
|
|
||||||
.sectors_count = 256U,
|
|
||||||
#endif
|
|
||||||
.sectors = NULL,
|
.sectors = NULL,
|
||||||
.sectors_size = SECTOR_SIZE,
|
.sectors_size = SECTOR_SIZE,
|
||||||
.address = 0U
|
.address = 0U
|
||||||
|
@ -209,9 +206,11 @@ static const uint8_t evconf_value[1] = {0xCF};
|
||||||
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L
|
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L
|
||||||
static const uint8_t evconf_value[1] = {0x8F};
|
static const uint8_t evconf_value[1] = {0x8F};
|
||||||
#else
|
#else
|
||||||
static const uint8_t evconf_value[1] = {0xCF};//{0x4F};
|
static const uint8_t evconf_value[1] = {0x4F};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static const uint8_t flash_status[1] = {(M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU};
|
||||||
|
|
||||||
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */
|
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -314,6 +313,39 @@ static void flash_cmd_receive(M25QDriver *devp,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void flash_cmd_send(M25QDriver *devp,
|
||||||
|
uint8_t cmd,
|
||||||
|
size_t n,
|
||||||
|
const uint8_t *p) {
|
||||||
|
#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI
|
||||||
|
qspi_command_t mode;
|
||||||
|
|
||||||
|
mode.cfg = QSPI_CFG_CMD(cmd) |
|
||||||
|
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L
|
||||||
|
QSPI_CFG_CMD_MODE_ONE_LINE |
|
||||||
|
QSPI_CFG_DATA_MODE_ONE_LINE;
|
||||||
|
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L
|
||||||
|
QSPI_CFG_CMD_MODE_TWO_LINES |
|
||||||
|
QSPI_CFG_DATA_MODE_TWO_LINES;
|
||||||
|
#else
|
||||||
|
QSPI_CFG_CMD_MODE_FOUR_LINES |
|
||||||
|
QSPI_CFG_DATA_MODE_FOUR_LINES;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
mode.addr = 0U;
|
||||||
|
mode.alt = 0U;
|
||||||
|
qspiSend(devp->config->qspip, &mode, n, p);
|
||||||
|
#else
|
||||||
|
uint8_t buf[1];
|
||||||
|
|
||||||
|
spiSelect(devp->config->spip);
|
||||||
|
buf[0] = cmd;
|
||||||
|
spiSend(devp->config->spip, 1, buf);
|
||||||
|
spiSend(devp->config->spip, n, p);
|
||||||
|
spiUnselect(devp->config->spip);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void flash_cmd_addr(M25QDriver *devp,
|
static void flash_cmd_addr(M25QDriver *devp,
|
||||||
uint8_t cmd,
|
uint8_t cmd,
|
||||||
flash_address_t addr) {
|
flash_address_t addr) {
|
||||||
|
@ -437,6 +469,42 @@ static void flash_cmd_addr_receive(M25QDriver *devp,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) || defined(__DOXYGEN__)
|
||||||
|
static void flash_cmd_addr_dummy_receive(M25QDriver *devp,
|
||||||
|
uint8_t cmd,
|
||||||
|
flash_address_t addr,
|
||||||
|
uint8_t dummy,
|
||||||
|
size_t n,
|
||||||
|
uint8_t *p) {
|
||||||
|
qspi_command_t mode;
|
||||||
|
|
||||||
|
mode.cfg = QSPI_CFG_CMD(cmd) |
|
||||||
|
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L
|
||||||
|
QSPI_CFG_CMD_MODE_ONE_LINE |
|
||||||
|
QSPI_CFG_ADDR_MODE_ONE_LINE |
|
||||||
|
QSPI_CFG_ADDR_SIZE_24 |
|
||||||
|
QSPI_CFG_DUMMY_CYCLES(dummy) |
|
||||||
|
QSPI_CFG_DATA_MODE_ONE_LINE;
|
||||||
|
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L
|
||||||
|
QSPI_CFG_CMD_MODE_TWO_LINES |
|
||||||
|
QSPI_CFG_ADDR_MODE_TWO_LINES |
|
||||||
|
QSPI_CFG_ADDR_SIZE_24 |
|
||||||
|
QSPI_CFG_DUMMY_CYCLES(dummy) |
|
||||||
|
QSPI_CFG_DATA_MODE_TWO_LINES;
|
||||||
|
#else
|
||||||
|
QSPI_CFG_CMD_MODE_FOUR_LINES |
|
||||||
|
QSPI_CFG_ADDR_MODE_FOUR_LINES |
|
||||||
|
QSPI_CFG_ADDR_SIZE_24 |
|
||||||
|
QSPI_CFG_DUMMY_CYCLES(dummy) |
|
||||||
|
QSPI_CFG_DATA_MODE_FOUR_LINES;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
mode.addr = addr;
|
||||||
|
mode.alt = 0U;
|
||||||
|
qspiReceive(devp->config->qspip, &mode, n, p);
|
||||||
|
}
|
||||||
|
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */
|
||||||
|
|
||||||
static flash_error_t flash_poll_status(M25QDriver *devp) {
|
static flash_error_t flash_poll_status(M25QDriver *devp) {
|
||||||
|
|
||||||
return FLASH_NO_ERROR;
|
return FLASH_NO_ERROR;
|
||||||
|
@ -454,6 +522,38 @@ static const flash_descriptor_t *get_descriptor(void *instance) {
|
||||||
|
|
||||||
static flash_error_t read(void *instance, flash_address_t addr,
|
static flash_error_t read(void *instance, flash_address_t addr,
|
||||||
uint8_t *rp, size_t n) {
|
uint8_t *rp, size_t n) {
|
||||||
|
M25QDriver *devp = (M25QDriver *)instance;
|
||||||
|
|
||||||
|
osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U));
|
||||||
|
osalDbgCheck((size_t)addr + n <= (size_t)descriptor.sectors_count *
|
||||||
|
(size_t)descriptor.sectors_size);
|
||||||
|
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
||||||
|
"invalid state");
|
||||||
|
|
||||||
|
if (devp->state == FLASH_ERASE) {
|
||||||
|
return FLASH_BUSY_ERASING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bus acquired.*/
|
||||||
|
flash_bus_acquire(devp);
|
||||||
|
|
||||||
|
/* FLASH_READY state while the operation is performed.*/
|
||||||
|
devp->state = FLASH_READ;
|
||||||
|
|
||||||
|
#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI
|
||||||
|
/* Fast read command in QSPI mode.*/
|
||||||
|
flash_cmd_addr_dummy_receive(devp, M25Q_CMD_FAST_READ,
|
||||||
|
addr, M25Q_READ_DUMMY_CYCLES,
|
||||||
|
n, rp);
|
||||||
|
#else
|
||||||
|
/* Normal read command in SPI mode.*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ready state again.*/
|
||||||
|
devp->state = FLASH_READY;
|
||||||
|
|
||||||
|
/* Bus released.*/
|
||||||
|
flash_bus_release(devp);
|
||||||
|
|
||||||
return FLASH_NO_ERROR;
|
return FLASH_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -516,6 +616,18 @@ void m25qObjectInit(M25QDriver *devp) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const qspi_command_t cmd_test_reset_enable_4 = {
|
||||||
|
.cfg = QSPI_CFG_ALT_MODE_FOUR_LINES,
|
||||||
|
.addr = 0,
|
||||||
|
.alt = M25Q_CMD_RESET_ENABLE
|
||||||
|
};
|
||||||
|
|
||||||
|
static const qspi_command_t cmd_test_reset_memory_4 = {
|
||||||
|
.cfg = QSPI_CFG_ALT_MODE_FOUR_LINES,
|
||||||
|
.addr = 0,
|
||||||
|
.alt = M25Q_CMD_RESET_MEMORY
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures and activates N25Q128 driver.
|
* @brief Configures and activates N25Q128 driver.
|
||||||
*
|
*
|
||||||
|
@ -532,7 +644,6 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) {
|
||||||
devp->config = config;
|
devp->config = config;
|
||||||
|
|
||||||
if (devp->state == FLASH_STOP) {
|
if (devp->state == FLASH_STOP) {
|
||||||
uint8_t id[3];
|
|
||||||
|
|
||||||
/* Bus acquisition.*/
|
/* Bus acquisition.*/
|
||||||
flash_bus_acquire(devp);
|
flash_bus_acquire(devp);
|
||||||
|
@ -546,46 +657,62 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) {
|
||||||
/* QSPI initialization.*/
|
/* QSPI initialization.*/
|
||||||
qspiStart(devp->config->qspip, devp->config->qspicfg);
|
qspiStart(devp->config->qspip, devp->config->qspicfg);
|
||||||
|
|
||||||
|
/* Reading device ID and unique ID.*/
|
||||||
|
|
||||||
#if M25Q_SWITCH_WIDTH == TRUE
|
#if M25Q_SWITCH_WIDTH == TRUE
|
||||||
/* Attempting a device reset with decreasing bus widths, commands
|
/* Attempting a device reset with different bus widths, commands
|
||||||
shorter than 8 bits are ignored.*/
|
shorter than 8 bits are ignored.*/
|
||||||
qspiCommand(devp->config->qspip, &cmd_reset_enable_4);
|
|
||||||
qspiCommand(devp->config->qspip, &cmd_reset_memory_4);
|
|
||||||
qspiCommand(devp->config->qspip, &cmd_reset_enable_2);
|
|
||||||
qspiCommand(devp->config->qspip, &cmd_reset_memory_2);
|
|
||||||
qspiCommand(devp->config->qspip, &cmd_reset_enable_1);
|
qspiCommand(devp->config->qspip, &cmd_reset_enable_1);
|
||||||
qspiCommand(devp->config->qspip, &cmd_reset_memory_1);
|
qspiCommand(devp->config->qspip, &cmd_reset_memory_1);
|
||||||
|
qspiCommand(devp->config->qspip, &cmd_reset_enable_2);
|
||||||
|
qspiCommand(devp->config->qspip, &cmd_reset_memory_2);
|
||||||
|
qspiCommand(devp->config->qspip, &cmd_reset_enable_4);
|
||||||
|
qspiCommand(devp->config->qspip, &cmd_reset_memory_4);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Reading device ID.*/
|
/* Reading device ID and unique ID.*/
|
||||||
qspiReceive(devp->config->qspip, &cmd_read_id, 3, id);
|
qspiReceive(devp->config->qspip, &cmd_read_id,
|
||||||
|
sizeof devp->device_id, devp->device_id);
|
||||||
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */
|
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */
|
||||||
|
|
||||||
/* Checking if the device is white listed.*/
|
/* Checking if the device is white listed.*/
|
||||||
osalDbgAssert(find_id(manufacturer_ids, sizeof manufacturer_ids, id[0]),
|
osalDbgAssert(find_id(manufacturer_ids,
|
||||||
|
sizeof manufacturer_ids,
|
||||||
|
devp->device_id[0]),
|
||||||
"invalid manufacturer id");
|
"invalid manufacturer id");
|
||||||
osalDbgAssert(find_id(memory_type_ids, sizeof memory_type_ids, id[1]),
|
osalDbgAssert(find_id(memory_type_ids,
|
||||||
|
sizeof memory_type_ids,
|
||||||
|
devp->device_id[1]),
|
||||||
"invalid memory type id");
|
"invalid memory type id");
|
||||||
|
|
||||||
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) && (M25Q_SWITCH_WIDTH == TRUE)
|
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) && (M25Q_SWITCH_WIDTH == TRUE)
|
||||||
/* Setting up final bus width.*/
|
/* Setting up final bus width.*/
|
||||||
qspiCommand(devp->config->qspip, &cmd_write_enable);
|
qspiCommand(devp->config->qspip, &cmd_write_enable);
|
||||||
qspiSend(devp->config->qspip, &cmd_write_evconf, 1, evconf_value);
|
qspiSend(devp->config->qspip, &cmd_write_evconf, 1, evconf_value);
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t id[3];
|
||||||
|
|
||||||
|
/* Reading ID again for confirmation.*/
|
||||||
|
flash_cmd_receive(devp, M25Q_CMD_MULTIPLE_IO_READ_ID, 3, id);
|
||||||
|
|
||||||
|
/* Checking if the device is white listed.*/
|
||||||
|
osalDbgAssert(memcmp(id, devp->device_id, 3) == 0,
|
||||||
|
"id confirmation failed");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
flash_cmd_receive(devp, M25Q_CMD_READ_ID, 3, id);
|
/* Setting up the device size.*/
|
||||||
|
descriptor.sectors_count = (1U << (size_t)devp->device_id[2]) / SECTOR_SIZE;
|
||||||
|
|
||||||
flash_cmd_receive(devp, M25Q_CMD_READ_ID, 3, id);
|
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI)
|
||||||
|
/* Setting up the dummy cycles to be used for rast read operations.*/
|
||||||
/* Reading device ID.*/
|
flash_cmd(devp, M25Q_CMD_WRITE_ENABLE);
|
||||||
qspiReceive(devp->config->qspip, &cmd_read_id, 3, id);
|
flash_cmd_send(devp, M25Q_CMD_WRITE_V_CONF_REGISTER,
|
||||||
|
1, flash_status);
|
||||||
/* Reset Enable command.*/
|
#endif
|
||||||
// flash_short_cmd(devp, M25Q_CMD_RESET_ENABLE);
|
|
||||||
|
|
||||||
/* Reset Memory command.*/
|
|
||||||
// flash_short_cmd(devp, M25Q_CMD_RESET_MEMORY);
|
|
||||||
|
|
||||||
|
/* Driver in ready state.*/
|
||||||
devp->state = FLASH_READY;
|
devp->state = FLASH_READY;
|
||||||
|
|
||||||
/* Bus release.*/
|
/* Bus release.*/
|
||||||
|
@ -617,6 +744,8 @@ void m25qStop(M25QDriver *devp) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
devp->config = NULL;
|
devp->config = NULL;
|
||||||
|
|
||||||
|
/* Driver stopped.*/
|
||||||
devp->state = FLASH_STOP;
|
devp->state = FLASH_STOP;
|
||||||
|
|
||||||
/* Bus release.*/
|
/* Bus release.*/
|
||||||
|
|
|
@ -41,9 +41,10 @@
|
||||||
#define M25Q_CMD_RESET_ENABLE 0x66
|
#define M25Q_CMD_RESET_ENABLE 0x66
|
||||||
#define M25Q_CMD_RESET_MEMORY 0x99
|
#define M25Q_CMD_RESET_MEMORY 0x99
|
||||||
#define M25Q_CMD_READ_ID 0x9F
|
#define M25Q_CMD_READ_ID 0x9F
|
||||||
|
#define M25Q_CMD_MULTIPLE_IO_READ_ID 0xAF
|
||||||
#define M25Q_CMD_READ_DISCOVERY_PARAMETER 0x5A
|
#define M25Q_CMD_READ_DISCOVERY_PARAMETER 0x5A
|
||||||
#define M25Q_CMD_READ 0x03
|
#define M25Q_CMD_READ 0x03
|
||||||
#define M25Q_CMD_FAST_READ 0x08
|
#define M25Q_CMD_FAST_READ 0x0B
|
||||||
#define M25Q_CMD_WRITE_ENABLE 0x06
|
#define M25Q_CMD_WRITE_ENABLE 0x06
|
||||||
#define M25Q_CMD_WRITE_DISABLE 0x04
|
#define M25Q_CMD_WRITE_DISABLE 0x04
|
||||||
#define M25Q_CMD_READ_STATUS_REGISTER 0x05
|
#define M25Q_CMD_READ_STATUS_REGISTER 0x05
|
||||||
|
@ -111,6 +112,15 @@
|
||||||
#define M25Q_BUS_MODE M25Q_BUS_MODE_QSPI4L
|
#define M25Q_BUS_MODE M25Q_BUS_MODE_QSPI4L
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of dummy cycles for fast read (1..15).
|
||||||
|
* @details This is the number of dummy cycles to be used for fast read
|
||||||
|
* operations.
|
||||||
|
*/
|
||||||
|
#if !defined(M25Q_READ_DUMMY_CYCLES) || defined(__DOXYGEN__)
|
||||||
|
#define M25Q_READ_DUMMY_CYCLES 8
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Switch QSPI bus width on initialization.
|
* @brief Switch QSPI bus width on initialization.
|
||||||
* @details A bus width initialization is performed by writing the
|
* @details A bus width initialization is performed by writing the
|
||||||
|
@ -185,6 +195,17 @@
|
||||||
#error "M25Q_SHARED_SPI requires SPI_USE_MUTUAL_EXCLUSION"
|
#error "M25Q_SHARED_SPI requires SPI_USE_MUTUAL_EXCLUSION"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) && \
|
||||||
|
(M25Q_BUS_MODE != M25Q_BUS_MODE_QSPI1L) && \
|
||||||
|
(M25Q_BUS_MODE != M25Q_BUS_MODE_QSPI2L) && \
|
||||||
|
(M25Q_BUS_MODE != M25Q_BUS_MODE_QSPI4L)
|
||||||
|
#error "invalid M25Q_BUS_MODE selected"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (M25Q_READ_DUMMY_CYCLES < 1) || (M25Q_READ_DUMMY_CYCLES > 15)
|
||||||
|
#error "invalid M25Q_READ_DUMMY_CYCLES value (1..15)"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver data structures and types. */
|
/* Driver data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -250,6 +271,10 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
uint32_t qspi_mode;
|
uint32_t qspi_mode;
|
||||||
#endif
|
#endif
|
||||||
|
/**
|
||||||
|
* @brief Device ID and unique ID.
|
||||||
|
*/
|
||||||
|
uint8_t device_id[20];
|
||||||
} M25QDriver;
|
} M25QDriver;
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
@ -211,6 +211,22 @@ void qspi_lld_stop(QSPIDriver *qspip) {
|
||||||
*/
|
*/
|
||||||
void qspi_lld_command(QSPIDriver *qspip, const qspi_command_t *cmdp) {
|
void qspi_lld_command(QSPIDriver *qspip, const qspi_command_t *cmdp) {
|
||||||
|
|
||||||
|
#if STM32_USE_STM32_D1_WORKAROUND == TRUE
|
||||||
|
/* If it is a command without address and alternate phases then the command
|
||||||
|
is sent as an alternate byte, the command phase is suppressed.*/
|
||||||
|
if ((cmdp->cfg & (QSPI_CFG_ADDR_MODE_MASK | QSPI_CFG_ALT_MODE_MASK)) == 0U) {
|
||||||
|
uint32_t cfg;
|
||||||
|
|
||||||
|
/* The command mode field is copied in the alternate mode field. All
|
||||||
|
other fields are not used in this scenario.*/
|
||||||
|
cfg = (cmdp->cfg & QSPI_CFG_CMD_MODE_MASK) << 6U;
|
||||||
|
|
||||||
|
qspip->qspi->DLR = 0U;
|
||||||
|
qspip->qspi->ABR = cmdp->cfg & QSPI_CFG_CMD_MASK;
|
||||||
|
qspip->qspi->CCR = cfg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
qspip->qspi->DLR = 0U;
|
qspip->qspi->DLR = 0U;
|
||||||
qspip->qspi->ABR = cmdp->alt;
|
qspip->qspi->ABR = cmdp->alt;
|
||||||
qspip->qspi->CCR = cmdp->cfg;
|
qspip->qspi->CCR = cmdp->cfg;
|
||||||
|
|
|
@ -31,6 +31,17 @@
|
||||||
/* Driver constants. */
|
/* Driver constants. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name DCR register options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define STM32_DCR_CK_MODE (1U << 0U)
|
||||||
|
#define STM32_DCR_CSHT_MASK (7U << 8U)
|
||||||
|
#define STM32_DCR_CSHT(n) ((n) << 8U)
|
||||||
|
#define STM32_DCR_FSIZE_MASK (31U << 16U)
|
||||||
|
#define STM32_DCR_FSIZE(n) ((n) << 16U)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver pre-compile time settings. */
|
/* Driver pre-compile time settings. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -85,6 +96,17 @@
|
||||||
#if !defined(STM32_QSPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
#if !defined(STM32_QSPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||||
#define STM32_QSPI_DMA_ERROR_HOOK(qspip) osalSysHalt("DMA failure")
|
#define STM32_QSPI_DMA_ERROR_HOOK(qspip) osalSysHalt("DMA failure")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables a workaround for a STM32L476 QUADSPI errata.
|
||||||
|
* @details The document DM00111498 states: "QUADSPI_BK1_IO1 is always an
|
||||||
|
* input when the command is sent in dual or quad SPI mode".
|
||||||
|
* This workaround makes commands without address or data phases
|
||||||
|
* to be sent as alternate bytes.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_USE_STM32_D1_WORKAROUND) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_USE_STM32_D1_WORKAROUND TRUE
|
||||||
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="id[2]-id-m25qStart-(format)" val="4"/><content id="id[1]-id-m25qStart-(format)" val="4"/><content id="id[0]-id-m25qStart-(format)" val="4"/><content id="cr2-adc_lld_start_conversion-(format)" val="4"/><content id="CR2-adc-null-port_wait_for_interrupt-(format)" val="4"/><content id="CR2-adc-adcp-adc_lld_start_conversion-(format)" val="4"/><content id="cfg-cmdp-qspiSend-(format)" val="4"/><content id="CR-qspi-qspip-qspi_lld_send-(format)" val="4"/><content id="CCR-qspi-qspip-qspi_lld_send-(format)" val="4"/><content id="cfg-cmdp-qspiReceive-(format)" val="4"/><content id="r2-(format)" val="4"/></contentList>"/>
|
<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="CCR-qspi-qspip-qspi_lld_receive-(format)" val="4"/><content id="cfg-cmdp-qspi_lld_receive-(format)" val="4"/><content id="id[2]-id-m25qStart-(format)" val="4"/><content id="id[1]-id-m25qStart-(format)" val="4"/><content id="id[0]-id-m25qStart-(format)" val="4"/><content id="AFRL-gpiop-initgpio-(format)" val="4"/><content id="AFRH-gpiop-initgpio-(format)" val="4"/><content id="ODR-gpiop-initgpio-(format)" val="4"/><content id="IDR-gpiop-initgpio-(format)" val="4"/><content id="PUPDR-gpiop-initgpio-(format)" val="4"/><content id="OSPEEDR-gpiop-initgpio-(format)" val="4"/><content id="MODER-gpiop-initgpio-(format)" val="4"/><content id="afrh-config-initgpio-(format)" val="4"/><content id="moder-config-initgpio-(format)" val="4"/><content id="config-initgpio-(format)" val="4"/><content id="r2-(format)" val="4"/><content id="cfg-cmdp-qspiReceive-(format)" val="4"/><content id="CCR-qspi-qspip-qspi_lld_send-(format)" val="4"/><content id="CR-qspi-qspip-qspi_lld_send-(format)" val="4"/><content id="cfg-cmdp-qspiSend-(format)" val="4"/><content id="CR2-adc-adcp-adc_lld_start_conversion-(format)" val="4"/><content id="CR2-adc-null-port_wait_for_interrupt-(format)" val="4"/><content id="cr2-adc_lld_start_conversion-(format)" val="4"/><content id="cmd-flash_cmd_receive-(format)" val="4"/></contentList>"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
|
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
|
<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
const QSPIConfig qspicfg1 = {
|
const QSPIConfig qspicfg1 = {
|
||||||
NULL,
|
NULL,
|
||||||
0
|
STM32_DCR_FSIZE(24) | STM32_DCR_CSHT(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
qspi_command_t cmd_read_id = {
|
qspi_command_t cmd_read_id = {
|
||||||
|
@ -63,6 +63,7 @@ static THD_FUNCTION(Thread1, arg) {
|
||||||
* Application entry point.
|
* Application entry point.
|
||||||
*/
|
*/
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
flash_error_t err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System initializations.
|
* System initializations.
|
||||||
|
@ -89,8 +90,11 @@ int main(void) {
|
||||||
*/
|
*/
|
||||||
m25qObjectInit(&m25q);
|
m25qObjectInit(&m25q);
|
||||||
m25qStart(&m25q, &m25qcfg1);
|
m25qStart(&m25q, &m25qcfg1);
|
||||||
// qspiStart(&QSPID1, &qspicfg1);
|
|
||||||
// qspiReceive(&QSPID1, &cmd_read_id, 17, buffer);
|
/* Reading it back.*/
|
||||||
|
err = flashRead(&m25q, 0, buffer, 128);
|
||||||
|
if (err != FLASH_NO_ERROR)
|
||||||
|
chSysHalt("read error");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Normal main() thread activity, in this demo it does nothing.
|
* Normal main() thread activity, in this demo it does nothing.
|
||||||
|
|
Loading…
Reference in New Issue