M25Q driver works over QSPI.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9568 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Giovanni Di Sirio 2016-06-04 12:29:54 +00:00
parent f8f2ea1763
commit ec871b0ef1
7 changed files with 540 additions and 518 deletions

View File

@ -53,33 +53,33 @@
/* Driver local variables and types. */ /* Driver local variables and types. */
/*===========================================================================*/ /*===========================================================================*/
static const uint8_t manufacturer_ids[] = M25Q_SUPPORTED_MANUFACTURE_IDS; static const flash_descriptor_t *m25q_get_descriptor(void *instance);
static const uint8_t memory_type_ids[] = M25Q_SUPPORTED_MEMORY_TYPE_IDS; static flash_error_t m25q_read(void *instance, flash_address_t addr,
static const flash_descriptor_t *get_descriptor(void *instance);
static flash_error_t read(void *instance, flash_address_t addr,
uint8_t *rp, size_t n); uint8_t *rp, size_t n);
static flash_error_t program(void *instance, flash_address_t addr, static flash_error_t m25q_program(void *instance, flash_address_t addr,
const uint8_t *pp, size_t n); const uint8_t *pp, size_t n);
static flash_error_t start_erase_all(void *instance); static flash_error_t m25q_start_erase_all(void *instance);
static flash_error_t start_erase_sector(void *instance, flash_sector_t sector); static flash_error_t m25q_start_erase_sector(void *instance,
static flash_error_t query_erase(void *instance, uint32_t *msec); flash_sector_t sector);
static flash_error_t verify_erase(void *instance, flash_sector_t sector); static flash_error_t m25q_query_erase(void *instance, uint32_t *msec);
static flash_error_t read_id(void *instance, uint8_t *rp, size_t n); static flash_error_t m25q_verify_erase(void *instance, flash_sector_t sector);
static flash_error_t m25q_read_sfdp(void *instance, uint8_t *rp,
flash_address_t addr, size_t n);
/** /**
* @brief Virtual methods table. * @brief Virtual methods table.
*/ */
static const struct M25QDriverVMT m25q_vmt = { static const struct M25QDriverVMT m25q_vmt = {
get_descriptor, read, program, m25q_get_descriptor, m25q_read, m25q_program,
start_erase_all, start_erase_sector, query_erase, verify_erase, m25q_start_erase_all, m25q_start_erase_sector,
read_id m25q_query_erase, m25q_verify_erase,
m25q_read_sfdp
}; };
/** /**
* @brief N25Q128 descriptor. * @brief N25Q128 descriptor.
*/ */
static flash_descriptor_t descriptor = { static flash_descriptor_t m25q_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,
@ -89,18 +89,18 @@ static flash_descriptor_t descriptor = {
.address = 0U .address = 0U
}; };
#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
/* Initial M25Q_CMD_READ_ID command.*/ /* Initial M25Q_CMD_READ_ID command.*/
static const qspi_command_t cmd_read_id = { static const qspi_command_t m25q_cmd_read_id = {
.cfg = QSPI_CFG_CMD(M25Q_CMD_READ_ID) | .cfg = QSPI_CFG_CMD(M25Q_CMD_READ_ID) |
#if M25Q_SWITCH_WIDTH == TRUE #if M25Q_SWITCH_WIDTH == TRUE
QSPI_CFG_CMD_MODE_ONE_LINE | QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_DATA_MODE_ONE_LINE, QSPI_CFG_DATA_MODE_ONE_LINE,
#else #else
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L #if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE | QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_DATA_MODE_ONE_LINE, QSPI_CFG_DATA_MODE_ONE_LINE,
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L #elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES | QSPI_CFG_CMD_MODE_TWO_LINES |
QSPI_CFG_DATA_MODE_TWO_LINES, QSPI_CFG_DATA_MODE_TWO_LINES,
#else #else
@ -113,16 +113,16 @@ static const qspi_command_t cmd_read_id = {
}; };
/* Initial M25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER command.*/ /* Initial M25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER command.*/
static const qspi_command_t cmd_write_evconf = { static const qspi_command_t m25q_cmd_write_evconf = {
.cfg = QSPI_CFG_CMD(M25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER) | .cfg = QSPI_CFG_CMD(M25Q_CMD_WRITE_ENHANCED_V_CONF_REGISTER) |
#if M25Q_SWITCH_WIDTH == TRUE #if M25Q_SWITCH_WIDTH == TRUE
QSPI_CFG_CMD_MODE_ONE_LINE | QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_DATA_MODE_ONE_LINE, QSPI_CFG_DATA_MODE_ONE_LINE,
#else #else
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L #if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE | QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_DATA_MODE_ONE_LINE, QSPI_CFG_DATA_MODE_ONE_LINE,
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L #elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES | QSPI_CFG_CMD_MODE_TWO_LINES |
QSPI_CFG_DATA_MODE_TWO_LINES, QSPI_CFG_DATA_MODE_TWO_LINES,
#else #else
@ -135,14 +135,14 @@ static const qspi_command_t cmd_write_evconf = {
}; };
/* Initial M25Q_CMD_WRITE_ENABLE command.*/ /* Initial M25Q_CMD_WRITE_ENABLE command.*/
static const qspi_command_t cmd_write_enable = { static const qspi_command_t m25q_cmd_write_enable = {
.cfg = QSPI_CFG_CMD(M25Q_CMD_WRITE_ENABLE) | .cfg = QSPI_CFG_CMD(M25Q_CMD_WRITE_ENABLE) |
#if M25Q_SWITCH_WIDTH == TRUE #if M25Q_SWITCH_WIDTH == TRUE
QSPI_CFG_CMD_MODE_ONE_LINE, QSPI_CFG_CMD_MODE_ONE_LINE,
#else #else
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L #if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE, QSPI_CFG_CMD_MODE_ONE_LINE,
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L #elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES, QSPI_CFG_CMD_MODE_TWO_LINES,
#else #else
QSPI_CFG_CMD_MODE_FOUR_LINES, QSPI_CFG_CMD_MODE_FOUR_LINES,
@ -153,20 +153,23 @@ static const qspi_command_t cmd_write_enable = {
}; };
/* Bus width initialization.*/ /* Bus width initialization.*/
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L #if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
static const uint8_t evconf_value[1] = {0xCF}; static const uint8_t m25q_evconf_value[1] = {0xCF};
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L #elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
static const uint8_t evconf_value[1] = {0x8F}; static const uint8_t m25q_evconf_value[1] = {0x8F};
#else #else
static const uint8_t evconf_value[1] = {0x4F}; static const uint8_t m25q_evconf_value[1] = {0x4F};
#endif #endif
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ #endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
static const uint8_t m25q_manufacturer_ids[] = M25Q_SUPPORTED_MANUFACTURE_IDS;
static const uint8_t m25q_memory_type_ids[] = M25Q_SUPPORTED_MEMORY_TYPE_IDS;
/*===========================================================================*/ /*===========================================================================*/
/* Driver local functions. */ /* Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
static bool find_id(const uint8_t *set, size_t size, uint8_t element) { static bool m25q_find_id(const uint8_t *set, size_t size, uint8_t element) {
size_t i; size_t i;
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
@ -177,282 +180,8 @@ static bool find_id(const uint8_t *set, size_t size, uint8_t element) {
return false; return false;
} }
#if ((M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) && (M25Q_SHARED_BUS == TRUE)) || \ #if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__)
defined(__DOXYGEN__) void m25q_reset_xip(M25QDriver *devp) {
static void flash_bus_acquire(M25QDriver *devp) {
qspiAcquireBus(devp->config->qspip);
}
static void flash_bus_release(M25QDriver *devp) {
qspiReleaseBus(devp->config->qspip);
}
#elif (M25Q_BUS_MODE == M25Q_BUS_MODE_SPI) && (M25Q_SHARED_BUS == TRUE)
static void flash_bus_acquire(M25QDriver *devp) {
spiAcquireBus(devp->config->spip);
spiStart(devp->config->spip, devp->config->spicfg);
}
static void flash_bus_release(M25QDriver *devp) {
spiReleaseBus(devp->config->spip);
}
#else
#define flash_bus_acquire(devp)
#define flash_bus_release(devp)
#endif
static void flash_cmd(M25QDriver *devp, uint8_t cmd) {
#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;
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES;
#else
QSPI_CFG_CMD_MODE_FOUR_LINES;
#endif
mode.addr = 0U;
mode.alt = 0U;
qspiCommand(devp->config->qspip, &mode);
#else
uint8_t buf[1];
spiSelect(devp->config->spip);
buf[0] = cmd;
spiSend(devp->config->spip, 1, buf);
spiUnselect(devp->config->spip);
#endif
}
static void flash_cmd_receive(M25QDriver *devp,
uint8_t cmd,
size_t n,
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;
qspiReceive(devp->config->qspip, &mode, n, p);
#else
uint8_t buf[1];
spiSelect(devp->config->spip);
buf[0] = cmd;
spiSend(devp->config->spip, 1, buf);
spiReceive(devp->config->spip, n, p);
spiUnselect(devp->config->spip);
#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,
uint8_t cmd,
flash_address_t addr) {
#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_ADDR_MODE_ONE_LINE |
QSPI_CFG_ADDR_SIZE_24;
#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;
#else
QSPI_CFG_CMD_MODE_FOUR_LINES |
QSPI_CFG_ADDR_MODE_FOUR_LINES |
QSPI_CFG_ADDR_SIZE_24;
#endif
mode.addr = addr;
mode.alt = 0U;
qspiCommand(devp->config->qspip, &mode);
#else
uint8_t buf[4];
spiSelect(devp->config->spip);
buf[0] = cmd;
buf[1] = (uint8_t)(addr >> 16);
buf[2] = (uint8_t)(addr >> 8);
buf[3] = (uint8_t)(addr >> 0);
spiSend(devp->config->spip, 4, buf);
spiUnselect(devp->config->spip);
#endif
}
static void flash_cmd_addr_send(M25QDriver *devp,
uint8_t cmd,
flash_address_t addr,
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_ADDR_MODE_ONE_LINE |
QSPI_CFG_ADDR_SIZE_24 |
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_DATA_MODE_TWO_LINES;
#else
QSPI_CFG_CMD_MODE_FOUR_LINES |
QSPI_CFG_ADDR_MODE_FOUR_LINES |
QSPI_CFG_ADDR_SIZE_24 |
QSPI_CFG_DATA_MODE_FOUR_LINES;
#endif
mode.addr = addr;
mode.alt = 0U;
qspiSend(devp->config->qspip, &mode, n, p);
#else
uint8_t buf[4];
spiSelect(devp->config->spip);
buf[0] = cmd;
buf[1] = (uint8_t)(addr >> 16);
buf[2] = (uint8_t)(addr >> 8);
buf[3] = (uint8_t)(addr >> 0);
spiSend(devp->config->spip, 4, buf);
spiSend(devp->config->spip, n, p);
spiUnselect(devp->config->spip);
#endif
}
static void flash_cmd_addr_receive(M25QDriver *devp,
uint8_t cmd,
flash_address_t addr,
size_t n,
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_ADDR_MODE_ONE_LINE |
QSPI_CFG_ADDR_SIZE_24 |
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_DATA_MODE_TWO_LINES;
#else
QSPI_CFG_CMD_MODE_FOUR_LINES |
QSPI_CFG_ADDR_MODE_FOUR_LINES |
QSPI_CFG_ADDR_SIZE_24 |
QSPI_CFG_DATA_MODE_FOUR_LINES;
#endif
mode.addr = addr;
mode.alt = 0U;
qspiReceive(devp->config->qspip, &mode, n, p);
#else
uint8_t buf[4];
spiSelect(devp->config->spip);
buf[0] = cmd;
buf[1] = (uint8_t)(addr >> 16);
buf[2] = (uint8_t)(addr >> 8);
buf[3] = (uint8_t)(addr >> 0);
spiSend(devp->config->spip, 4, buf);
spiReceive(devp->config->spip, n, p);
spiUnselect(devp->config->spip);
#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);
}
void flash_reset_xip(M25QDriver *devp) {
static const uint8_t flash_conf[1] = { static const uint8_t flash_conf[1] = {
(M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU (M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU
}; };
@ -464,10 +193,10 @@ void flash_reset_xip(M25QDriver *devp) {
cmd.addr = 0; cmd.addr = 0;
cmd.cfg = QSPI_CFG_CMD_MODE_NONE | cmd.cfg = QSPI_CFG_CMD_MODE_NONE |
QSPI_CFG_ADDR_SIZE_24 | QSPI_CFG_ADDR_SIZE_24 |
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L #if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_ADDR_MODE_ONE_LINE | QSPI_CFG_ADDR_MODE_ONE_LINE |
QSPI_CFG_DATA_MODE_ONE_LINE | QSPI_CFG_DATA_MODE_ONE_LINE |
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L #elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
QSPI_CFG_ADDR_MODE_TWO_LINES | QSPI_CFG_ADDR_MODE_TWO_LINES |
QSPI_CFG_DATA_MODE_TWO_LINES | QSPI_CFG_DATA_MODE_TWO_LINES |
#else #else
@ -477,17 +206,17 @@ void flash_reset_xip(M25QDriver *devp) {
QSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/ QSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/
QSPI_CFG_ALT_SIZE_8 | QSPI_CFG_ALT_SIZE_8 |
QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2); QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2);
qspiReceive(devp->config->qspip, &cmd, 1, buf); qspiReceive(devp->config->busp, &cmd, 1, buf);
/* Enabling write operation.*/ /* Enabling write operation.*/
flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
/* Rewriting volatile configuration register.*/ /* Rewriting volatile configuration register.*/
flash_cmd_send(devp, M25Q_CMD_WRITE_V_CONF_REGISTER, 1, flash_conf); jesd216_cmd_send(devp->config->busp, M25Q_CMD_WRITE_V_CONF_REGISTER,
1, flash_conf);
} }
void flash_reset_memory(M25QDriver *devp) { void m25q_reset_memory(M25QDriver *devp) {
/* 1x M25Q_CMD_RESET_ENABLE command.*/ /* 1x M25Q_CMD_RESET_ENABLE command.*/
static const qspi_command_t cmd_reset_enable_1 = { static const qspi_command_t cmd_reset_enable_1 = {
@ -509,7 +238,7 @@ void flash_reset_memory(M25QDriver *devp) {
rejected because shorter than 8 bits. If the device is in multiple rejected because shorter than 8 bits. If the device is in multiple
bits mode then the commands are accepted and the device is reset to bits mode then the commands are accepted and the device is reset to
one bit mode.*/ one bit mode.*/
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI4L #if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI4L
/* 4x M25Q_CMD_RESET_ENABLE command.*/ /* 4x M25Q_CMD_RESET_ENABLE command.*/
static const qspi_command_t cmd_reset_enable_4 = { static const qspi_command_t cmd_reset_enable_4 = {
.cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) | .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) |
@ -526,8 +255,8 @@ void flash_reset_memory(M25QDriver *devp) {
.alt = 0 .alt = 0
}; };
qspiCommand(devp->config->qspip, &cmd_reset_enable_4); qspiCommand(devp->config->busp, &cmd_reset_enable_4);
qspiCommand(devp->config->qspip, &cmd_reset_memory_4); qspiCommand(devp->config->busp, &cmd_reset_memory_4);
#else #else
/* 2x M25Q_CMD_RESET_ENABLE command.*/ /* 2x M25Q_CMD_RESET_ENABLE command.*/
static const qspi_command_t cmd_reset_enable_2 = { static const qspi_command_t cmd_reset_enable_2 = {
@ -545,18 +274,18 @@ void flash_reset_memory(M25QDriver *devp) {
.alt = 0 .alt = 0
}; };
qspiCommand(devp->config->qspip, &cmd_reset_enable_2); qspiCommand(devp->config->busp, &cmd_reset_enable_2);
qspiCommand(devp->config->qspip, &cmd_reset_memory_2); qspiCommand(devp->config->busp, &cmd_reset_memory_2);
#endif #endif
/* Now the device should be in one bit mode for sure and we perform a /* Now the device should be in one bit mode for sure and we perform a
device reset.*/ device reset.*/
qspiCommand(devp->config->qspip, &cmd_reset_enable_1); qspiCommand(devp->config->busp, &cmd_reset_enable_1);
qspiCommand(devp->config->qspip, &cmd_reset_memory_1); qspiCommand(devp->config->busp, &cmd_reset_memory_1);
} }
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ #endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
static flash_error_t flash_poll_status(M25QDriver *devp) { static flash_error_t m25q_poll_status(M25QDriver *devp) {
uint8_t sts; uint8_t sts;
do { do {
@ -564,13 +293,14 @@ static flash_error_t flash_poll_status(M25QDriver *devp) {
osalThreadSleepMilliseconds(1); osalThreadSleepMilliseconds(1);
#endif #endif
/* Read status command.*/ /* Read status command.*/
flash_cmd_receive(devp, M25Q_CMD_READ_FLAG_STATUS_REGISTER, 1, &sts); jesd216_cmd_receive(devp->config->busp, M25Q_CMD_READ_FLAG_STATUS_REGISTER,
1, &sts);
} while ((sts & M25Q_FLAGS_PROGRAM_ERASE) == 0U); } while ((sts & M25Q_FLAGS_PROGRAM_ERASE) == 0U);
/* Checking for errors.*/ /* Checking for errors.*/
if ((sts & M25Q_FLAGS_ALL_ERRORS) != 0U) { if ((sts & M25Q_FLAGS_ALL_ERRORS) != 0U) {
/* Clearing status register.*/ /* Clearing status register.*/
flash_cmd(devp, M25Q_CMD_CLEAR_FLAG_STATUS_REGISTER); jesd216_cmd(devp->config->busp, M25Q_CMD_CLEAR_FLAG_STATUS_REGISTER);
/* Program operation failed.*/ /* Program operation failed.*/
return FLASH_ERROR_PROGRAM; return FLASH_ERROR_PROGRAM;
@ -579,23 +309,23 @@ static flash_error_t flash_poll_status(M25QDriver *devp) {
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
} }
static const flash_descriptor_t *get_descriptor(void *instance) { static const flash_descriptor_t *m25q_get_descriptor(void *instance) {
M25QDriver *devp = (M25QDriver *)instance; M25QDriver *devp = (M25QDriver *)instance;
osalDbgCheck(instance != NULL); osalDbgCheck(instance != NULL);
osalDbgAssert((devp->state != FLASH_UNINIT) && (devp->state != FLASH_STOP), osalDbgAssert((devp->state != FLASH_UNINIT) && (devp->state != FLASH_STOP),
"invalid state"); "invalid state");
return &descriptor; return &m25q_descriptor;
} }
static flash_error_t read(void *instance, flash_address_t addr, static flash_error_t m25q_read(void *instance, flash_address_t addr,
uint8_t *rp, size_t n) { uint8_t *rp, size_t n) {
M25QDriver *devp = (M25QDriver *)instance; M25QDriver *devp = (M25QDriver *)instance;
osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U)); osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U));
osalDbgCheck((size_t)addr + n <= (size_t)descriptor.sectors_count * osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count *
(size_t)descriptor.sectors_size); (size_t)m25q_descriptor.sectors_size);
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
"invalid state"); "invalid state");
@ -604,16 +334,15 @@ static flash_error_t read(void *instance, flash_address_t addr,
} }
/* Bus acquired.*/ /* Bus acquired.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
/* FLASH_READY state while the operation is performed.*/ /* FLASH_READY state while the operation is performed.*/
devp->state = FLASH_READ; devp->state = FLASH_READ;
#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
/* Fast read command in QSPI mode.*/ /* Fast read command in QSPI mode.*/
flash_cmd_addr_dummy_receive(devp, M25Q_CMD_FAST_READ, jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ,
addr, M25Q_READ_DUMMY_CYCLES, addr, M25Q_READ_DUMMY_CYCLES, n, rp);
n, rp);
#else #else
/* Normal read command in SPI mode.*/ /* Normal read command in SPI mode.*/
#endif #endif
@ -622,18 +351,18 @@ static flash_error_t read(void *instance, flash_address_t addr,
devp->state = FLASH_READY; devp->state = FLASH_READY;
/* Bus released.*/ /* Bus released.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
} }
static flash_error_t program(void *instance, flash_address_t addr, static flash_error_t m25q_program(void *instance, flash_address_t addr,
const uint8_t *pp, size_t n) { const uint8_t *pp, size_t n) {
M25QDriver *devp = (M25QDriver *)instance; M25QDriver *devp = (M25QDriver *)instance;
osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
osalDbgCheck((size_t)addr + n <= (size_t)descriptor.sectors_count * osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count *
(size_t)descriptor.sectors_size); (size_t)m25q_descriptor.sectors_size);
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
"invalid state"); "invalid state");
@ -642,7 +371,7 @@ static flash_error_t program(void *instance, flash_address_t addr,
} }
/* Bus acquired.*/ /* Bus acquired.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
/* FLASH_PGM state while the operation is performed.*/ /* FLASH_PGM state while the operation is performed.*/
devp->state = FLASH_PGM; devp->state = FLASH_PGM;
@ -658,17 +387,18 @@ static flash_error_t program(void *instance, flash_address_t addr,
} }
/* Enabling write operation.*/ /* Enabling write operation.*/
flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
/* Page program command.*/ /* Page program command.*/
flash_cmd_addr_send(devp, M25Q_CMD_PAGE_PROGRAM, addr, chunk, pp); jesd216_cmd_addr_send(devp->config->busp, M25Q_CMD_PAGE_PROGRAM, addr,
chunk, pp);
/* Wait for status and check errors.*/ /* Wait for status and check errors.*/
err = flash_poll_status(devp); err = m25q_poll_status(devp);
if (err != FLASH_NO_ERROR) { if (err != FLASH_NO_ERROR) {
/* Bus released.*/ /* Bus released.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
return err; return err;
} }
@ -683,12 +413,12 @@ static flash_error_t program(void *instance, flash_address_t addr,
devp->state = FLASH_READY; devp->state = FLASH_READY;
/* Bus released.*/ /* Bus released.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
} }
static flash_error_t start_erase_all(void *instance) { static flash_error_t m25q_start_erase_all(void *instance) {
M25QDriver *devp = (M25QDriver *)instance; M25QDriver *devp = (M25QDriver *)instance;
osalDbgCheck(instance != NULL); osalDbgCheck(instance != NULL);
@ -700,29 +430,30 @@ static flash_error_t start_erase_all(void *instance) {
} }
/* Bus acquired.*/ /* Bus acquired.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
/* FLASH_ERASE state while the operation is performed.*/ /* FLASH_ERASE state while the operation is performed.*/
devp->state = FLASH_ERASE; devp->state = FLASH_ERASE;
/* Enabling write operation.*/ /* Enabling write operation.*/
flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
/* Bulk erase command.*/ /* Bulk erase command.*/
flash_cmd(devp, M25Q_CMD_BULK_ERASE); jesd216_cmd(devp->config->busp, M25Q_CMD_BULK_ERASE);
/* Bus released.*/ /* Bus released.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
} }
static flash_error_t start_erase_sector(void *instance, flash_sector_t sector) { static flash_error_t m25q_start_erase_sector(void *instance,
flash_sector_t sector) {
M25QDriver *devp = (M25QDriver *)instance; M25QDriver *devp = (M25QDriver *)instance;
flash_address_t addr = (flash_address_t)(sector * SECTOR_SIZE); flash_address_t addr = (flash_address_t)(sector * SECTOR_SIZE);
osalDbgCheck(instance != NULL); osalDbgCheck(instance != NULL);
osalDbgCheck(sector < descriptor.sectors_count); osalDbgCheck(sector < m25q_descriptor.sectors_count);
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
"invalid state"); "invalid state");
@ -731,31 +462,32 @@ static flash_error_t start_erase_sector(void *instance, flash_sector_t sector) {
} }
/* Bus acquired.*/ /* Bus acquired.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
/* FLASH_ERASE state while the operation is performed.*/ /* FLASH_ERASE state while the operation is performed.*/
devp->state = FLASH_ERASE; devp->state = FLASH_ERASE;
/* Enabling write operation.*/ /* Enabling write operation.*/
flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
/* Sector erase command.*/ /* Sector erase command.*/
flash_cmd_addr(devp, M25Q_CMD_SECTOR_ERASE, addr); jesd216_cmd_addr(devp->config->busp, M25Q_CMD_SECTOR_ERASE, addr);
/* Bus released.*/ /* Bus released.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
} }
static flash_error_t verify_erase(void *instance, flash_sector_t sector) { static flash_error_t m25q_verify_erase(void *instance,
flash_sector_t sector) {
M25QDriver *devp = (M25QDriver *)instance; M25QDriver *devp = (M25QDriver *)instance;
uint8_t cmpbuf[M25Q_COMPARE_BUFFER_SIZE]; uint8_t cmpbuf[M25Q_COMPARE_BUFFER_SIZE];
flash_address_t addr; flash_address_t addr;
size_t n; size_t n;
osalDbgCheck(instance != NULL); osalDbgCheck(instance != NULL);
osalDbgCheck(sector < descriptor.sectors_count); osalDbgCheck(sector < m25q_descriptor.sectors_count);
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
"invalid state"); "invalid state");
@ -764,7 +496,7 @@ static flash_error_t verify_erase(void *instance, flash_sector_t sector) {
} }
/* Bus acquired.*/ /* Bus acquired.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
/* FLASH_READY state while the operation is performed.*/ /* FLASH_READY state while the operation is performed.*/
devp->state = FLASH_READ; devp->state = FLASH_READ;
@ -775,8 +507,8 @@ static flash_error_t verify_erase(void *instance, flash_sector_t sector) {
while (n > 0U) { while (n > 0U) {
uint8_t *p; uint8_t *p;
#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI #if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
flash_cmd_addr_dummy_receive(devp, M25Q_CMD_FAST_READ, jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ,
addr, M25Q_READ_DUMMY_CYCLES, addr, M25Q_READ_DUMMY_CYCLES,
sizeof cmpbuf, cmpbuf); sizeof cmpbuf, cmpbuf);
#else #else
@ -790,7 +522,7 @@ static flash_error_t verify_erase(void *instance, flash_sector_t sector) {
devp->state = FLASH_READY; devp->state = FLASH_READY;
/* Bus released.*/ /* Bus released.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
return FLASH_ERROR_VERIFY; return FLASH_ERROR_VERIFY;
} }
@ -804,12 +536,12 @@ static flash_error_t verify_erase(void *instance, flash_sector_t sector) {
devp->state = FLASH_READY; devp->state = FLASH_READY;
/* Bus released.*/ /* Bus released.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
} }
static flash_error_t query_erase(void *instance, uint32_t *msec) { static flash_error_t m25q_query_erase(void *instance, uint32_t *msec) {
M25QDriver *devp = (M25QDriver *)instance; M25QDriver *devp = (M25QDriver *)instance;
uint8_t sts; uint8_t sts;
@ -821,10 +553,11 @@ static flash_error_t query_erase(void *instance, uint32_t *msec) {
if (devp->state == FLASH_ERASE) { if (devp->state == FLASH_ERASE) {
/* Bus acquired.*/ /* Bus acquired.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
/* Read status command.*/ /* Read status command.*/
flash_cmd_receive(devp, M25Q_CMD_READ_FLAG_STATUS_REGISTER, 1, &sts); jesd216_cmd_receive(devp->config->busp, M25Q_CMD_READ_FLAG_STATUS_REGISTER,
1, &sts);
/* If the P/E bit is zero (busy) or the flash in a suspended state then /* If the P/E bit is zero (busy) or the flash in a suspended state then
report that the operation is still in progress.*/ report that the operation is still in progress.*/
@ -832,7 +565,7 @@ static flash_error_t query_erase(void *instance, uint32_t *msec) {
((sts & M25Q_FLAGS_ERASE_SUSPEND) != 0U)) { ((sts & M25Q_FLAGS_ERASE_SUSPEND) != 0U)) {
/* Bus released.*/ /* Bus released.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
/* Recommended time before polling again, this is a simplified /* Recommended time before polling again, this is a simplified
implementation.*/ implementation.*/
@ -850,23 +583,26 @@ static flash_error_t query_erase(void *instance, uint32_t *msec) {
if ((sts & M25Q_FLAGS_ALL_ERRORS) != 0U) { if ((sts & M25Q_FLAGS_ALL_ERRORS) != 0U) {
/* Clearing status register.*/ /* Clearing status register.*/
flash_cmd(devp, M25Q_CMD_CLEAR_FLAG_STATUS_REGISTER); jesd216_cmd(devp->config->busp, M25Q_CMD_CLEAR_FLAG_STATUS_REGISTER);
/* Erase operation failed.*/ /* Erase operation failed.*/
return FLASH_ERROR_ERASE; return FLASH_ERROR_ERASE;
} }
/* Bus released.*/ /* Bus released.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
} }
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
} }
static flash_error_t read_id(void *instance, uint8_t *rp, size_t n) { static flash_error_t m25q_read_sfdp(void *instance, uint8_t *rp,
flash_address_t addr,
size_t n) {
(void)instance; (void)instance;
(void)rp; (void)rp;
(void)addr;
(void)n; (void)n;
return FLASH_NO_ERROR; return FLASH_NO_ERROR;
@ -892,18 +628,6 @@ void m25qObjectInit(M25QDriver *devp) {
devp->config = NULL; devp->config = NULL;
} }
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.
* *
@ -922,50 +646,51 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) {
if (devp->state == FLASH_STOP) { if (devp->state == FLASH_STOP) {
/* Bus acquisition.*/ /* Bus acquisition.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
#if M25Q_BUS_MODE == M25Q_BUS_MODE_SPI #if JESD216_BUS_MODE == JESD216_BUS_MODE_SPI
/* SPI initialization.*/ /* SPI initialization.*/
spiStart(devp->config->spip, devp->config->spicfg); spiStart(devp->config->busp, devp->config->buscfg);
/* Reading device ID.*/ /* Reading device ID.*/
#else /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ #else /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
/* QSPI initialization.*/ /* QSPI initialization.*/
qspiStart(devp->config->qspip, devp->config->qspicfg); qspiStart(devp->config->busp, devp->config->buscfg);
/* Attempting a reset of the XIP mode, it could be in an unexpected state /* Attempting a reset of the XIP mode, it could be in an unexpected state
because a CPU reset does not reset the memory too.*/ because a CPU reset does not reset the memory too.*/
flash_reset_xip(devp); m25q_reset_xip(devp);
/* Attempting a eeset of the device, it could be in an unexpected state /* Attempting a eeset of the device, it could be in an unexpected state
because a CPU reset does not reset the memory too.*/ because a CPU reset does not reset the memory too.*/
flash_reset_memory(devp); m25q_reset_memory(devp);
/* Reading device ID and unique ID.*/ /* Reading device ID and unique ID.*/
qspiReceive(devp->config->qspip, &cmd_read_id, qspiReceive(devp->config->busp, &m25q_cmd_read_id,
sizeof devp->device_id, devp->device_id); sizeof devp->device_id, devp->device_id);
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ #endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
/* Checking if the device is white listed.*/ /* Checking if the device is white listed.*/
osalDbgAssert(find_id(manufacturer_ids, osalDbgAssert(m25q_find_id(m25q_manufacturer_ids,
sizeof manufacturer_ids, sizeof m25q_manufacturer_ids,
devp->device_id[0]), devp->device_id[0]),
"invalid manufacturer id"); "invalid manufacturer id");
osalDbgAssert(find_id(memory_type_ids, osalDbgAssert(m25q_find_id(m25q_memory_type_ids,
sizeof memory_type_ids, sizeof m25q_memory_type_ids,
devp->device_id[1]), 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 (JESD216_BUS_MODE != JESD216_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->busp, &m25q_cmd_write_enable);
qspiSend(devp->config->qspip, &cmd_write_evconf, 1, evconf_value); qspiSend(devp->config->busp, &m25q_cmd_write_evconf, 1, m25q_evconf_value);
{ {
uint8_t id[3]; uint8_t id[3];
/* Reading ID again for confirmation.*/ /* Reading ID again for confirmation.*/
flash_cmd_receive(devp, M25Q_CMD_MULTIPLE_IO_READ_ID, 3, id); jesd216_cmd_receive(devp->config->busp, M25Q_CMD_MULTIPLE_IO_READ_ID,
3, id);
/* Checking if the device is white listed.*/ /* Checking if the device is white listed.*/
osalDbgAssert(memcmp(id, devp->device_id, 3) == 0, osalDbgAssert(memcmp(id, devp->device_id, 3) == 0,
@ -974,17 +699,18 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) {
#endif #endif
/* Setting up the device size.*/ /* Setting up the device size.*/
descriptor.sectors_count = (1U << (size_t)devp->device_id[2]) / SECTOR_SIZE; m25q_descriptor.sectors_count = (1U << (size_t)devp->device_id[2]) /
SECTOR_SIZE;
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) #if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI)
{ {
static const uint8_t flash_conf[1] = { static const uint8_t flash_conf[1] = {
(M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU (M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU
}; };
/* Setting up the dummy cycles to be used for fast read operations.*/ /* Setting up the dummy cycles to be used for fast read operations.*/
flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
flash_cmd_send(devp, M25Q_CMD_WRITE_V_CONF_REGISTER, jesd216_cmd_send(devp->config->busp, M25Q_CMD_WRITE_V_CONF_REGISTER,
1, flash_conf); 1, flash_conf);
} }
#endif #endif
@ -993,7 +719,7 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) {
devp->state = FLASH_READY; devp->state = FLASH_READY;
/* Bus release.*/ /* Bus release.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
} }
} }
@ -1012,12 +738,12 @@ void m25qStop(M25QDriver *devp) {
if (devp->state != FLASH_STOP) { if (devp->state != FLASH_STOP) {
/* Bus acquisition.*/ /* Bus acquisition.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
#if M25Q_BUS_MODE == M25Q_BUS_MODE_SPI #if JESD216_BUS_MODE == JESD216_BUS_MODE_SPI
spiStop(devp->config->spip); spiStop(devp->config->busp);
#else #else
qspiStop(devp->config->qspip); qspiStop(devp->config->busp);
#endif #endif
devp->config = NULL; devp->config = NULL;
@ -1026,11 +752,11 @@ void m25qStop(M25QDriver *devp) {
devp->state = FLASH_STOP; devp->state = FLASH_STOP;
/* Bus release.*/ /* Bus release.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
} }
} }
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) || defined(__DOXYGEN__) #if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__)
#if (QSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__) #if (QSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
/** /**
* @brief Enters the memory Mapping mode. * @brief Enters the memory Mapping mode.
@ -1051,21 +777,21 @@ void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) {
qspi_command_t cmd; qspi_command_t cmd;
/* Bus acquisition.*/ /* Bus acquisition.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
/* Activating XIP mode in the device.*/ /* Activating XIP mode in the device.*/
flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE);
flash_cmd_send(devp, M25Q_CMD_WRITE_V_CONF_REGISTER, jesd216_cmd_send(devp->config->busp, M25Q_CMD_WRITE_V_CONF_REGISTER,
1, flash_status_xip); 1, flash_status_xip);
/* Putting the QSPI driver in memory mapped mode.*/ /* Putting the QSPI driver in memory mapped mode.*/
cmd.cfg = QSPI_CFG_CMD(M25Q_CMD_FAST_READ) | cmd.cfg = QSPI_CFG_CMD(M25Q_CMD_FAST_READ) |
QSPI_CFG_ADDR_SIZE_24 | QSPI_CFG_ADDR_SIZE_24 |
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L #if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE | QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_ADDR_MODE_ONE_LINE | QSPI_CFG_ADDR_MODE_ONE_LINE |
QSPI_CFG_DATA_MODE_ONE_LINE | QSPI_CFG_DATA_MODE_ONE_LINE |
#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L #elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES | QSPI_CFG_CMD_MODE_TWO_LINES |
QSPI_CFG_ADDR_MODE_TWO_LINES | QSPI_CFG_ADDR_MODE_TWO_LINES |
QSPI_CFG_DATA_MODE_TWO_LINES | QSPI_CFG_DATA_MODE_TWO_LINES |
@ -1079,10 +805,10 @@ void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) {
QSPI_CFG_SIOO | QSPI_CFG_SIOO |
QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2); QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2);
qspiMapFlash(devp->config->qspip, &cmd, addrp); qspiMapFlash(devp->config->busp, &cmd, addrp);
/* Bus release.*/ /* Bus release.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
} }
/** /**
@ -1095,16 +821,16 @@ void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) {
void m25qMemoryUnmap(M25QDriver *devp) { void m25qMemoryUnmap(M25QDriver *devp) {
/* Bus acquisition.*/ /* Bus acquisition.*/
flash_bus_acquire(devp); jesd216_bus_acquire(devp->config->busp);
qspiUnmapFlash(devp->config->qspip); qspiUnmapFlash(devp->config->busp);
flash_reset_xip(devp); m25q_reset_xip(devp);
/* Bus release.*/ /* Bus release.*/
flash_bus_release(devp); jesd216_bus_release(devp->config->busp);
} }
#endif /* QSPI_SUPPORTS_MEMMAP == TRUE */ #endif /* QSPI_SUPPORTS_MEMMAP == TRUE */
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ #endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
/** @} */ /** @} */

View File

@ -87,16 +87,6 @@
M25Q_FLAGS_PROTECTION_ERROR) M25Q_FLAGS_PROTECTION_ERROR)
/** @} */ /** @} */
/**
* @name Bus interface.
* @{
*/
#define M25Q_BUS_MODE_SPI 0
#define M25Q_BUS_MODE_QSPI1L 1
#define M25Q_BUS_MODE_QSPI2L 2
#define M25Q_BUS_MODE_QSPI4L 4
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
@ -105,13 +95,6 @@
* @name Configuration options * @name Configuration options
* @{ * @{
*/ */
/**
* @brief Physical transport interface.
*/
#if !defined(M25Q_USE_SPI) || defined(__DOXYGEN__)
#define M25Q_BUS_MODE M25Q_BUS_MODE_QSPI4L
#endif
/** /**
* @brief Number of dummy cycles for fast read (1..15). * @brief Number of dummy cycles for fast read (1..15).
* @details This is the number of dummy cycles to be used for fast read * @details This is the number of dummy cycles to be used for fast read
@ -133,17 +116,6 @@
#define M25Q_SWITCH_WIDTH TRUE #define M25Q_SWITCH_WIDTH TRUE
#endif #endif
/**
* @brief Shared bus switch.
* @details If set to @p TRUE the device acquires bus ownership
* on each transaction.
* @note Requires @p SPI_USE_MUTUAL_EXCLUSION or
* @p SPI_USE_MUTUAL_EXCLUSION.
*/
#if !defined(M25Q_SHARED_BUS) || defined(__DOXYGEN__)
#define M25Q_SHARED_BUS TRUE
#endif
/** /**
* @brief Delays insertions. * @brief Delays insertions.
* @details If enabled this options inserts delays into the flash waiting * @details If enabled this options inserts delays into the flash waiting
@ -191,27 +163,6 @@
/* Derived constants and error checks. */ /* Derived constants and error checks. */
/*===========================================================================*/ /*===========================================================================*/
#if (M25Q_BUS_MODE == M25Q_BUS_MODE_SPI) && (HAL_USE_SPI == FALSE)
#error "M25Q_BUS_MODE_SPI requires HAL_USE_SPI"
#endif
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) && (HAL_USE_QSPI == FALSE)
#error "M25Q_BUS_MODE_QSPIxL requires HAL_USE_QSPI"
#endif
#if (M25Q_BUS_MODE == M25Q_BUS_MODE_SPI) && \
(M25Q_SHARED_SPI == TRUE) && \
(SPI_USE_MUTUAL_EXCLUSION == FALSE)
#error "M25Q_SHARED_SPI requires SPI_USE_MUTUAL_EXCLUSION"
#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) #if (M25Q_READ_DUMMY_CYCLES < 1) || (M25Q_READ_DUMMY_CYCLES > 15)
#error "invalid M25Q_READ_DUMMY_CYCLES value (1..15)" #error "invalid M25Q_READ_DUMMY_CYCLES value (1..15)"
#endif #endif
@ -228,25 +179,7 @@
* @brief Type of a M25Q configuration structure. * @brief Type of a M25Q configuration structure.
*/ */
typedef struct { typedef struct {
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) || defined(__DOXYGEN__) _jesd216_config
/**
* @brief QSPI driver associated to this instance.
*/
QSPIDriver *qspip;
/**
* @brief QSPI configuration associated to this instance.
*/
const QSPIConfig *qspicfg;
#else
/**
* @brief SPI driver associated to this instance.
*/
SPIDriver *spip;
/**
* @brief SPI configuration associated to this instance.
*/
const SPIConfig *spicfg;
#endif
} M25QConfig; } M25QConfig;
/** /**
@ -299,12 +232,12 @@ extern "C" {
void m25qObjectInit(M25QDriver *devp); void m25qObjectInit(M25QDriver *devp);
void m25qStart(M25QDriver *devp, const M25QConfig *config); void m25qStart(M25QDriver *devp, const M25QConfig *config);
void m25qStop(M25QDriver *devp); void m25qStop(M25QDriver *devp);
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) || defined(__DOXYGEN__) #if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__)
#if (QSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__) #if (QSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
void m25qMemoryMap(M25QDriver *devp, uint8_t ** addrp); void m25qMemoryMap(M25QDriver *devp, uint8_t ** addrp);
void m25qMemoryUnmap(M25QDriver *devp); void m25qMemoryUnmap(M25QDriver *devp);
#endif /* QSPI_SUPPORTS_MEMMAP == TRUE */ #endif /* QSPI_SUPPORTS_MEMMAP == TRUE */
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ #endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -46,4 +46,281 @@
/* Driver exported functions. */ /* Driver exported functions. */
/*===========================================================================*/ /*===========================================================================*/
void jesd216_cmd(BUSDriver *busp, uint8_t cmd) {
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
qspi_command_t mode;
mode.cfg = QSPI_CFG_CMD(cmd) |
#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE;
#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES;
#else
QSPI_CFG_CMD_MODE_FOUR_LINES;
#endif
mode.addr = 0U;
mode.alt = 0U;
qspiCommand(busp, &mode);
#else
uint8_t buf[1];
spiSelect(busp);
buf[0] = cmd;
spiSend(busp, 1, buf);
spiUnselect(busp);
#endif
}
void jesd216_cmd_receive(BUSDriver *busp,
uint8_t cmd,
size_t n,
uint8_t *p) {
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
qspi_command_t mode;
mode.cfg = QSPI_CFG_CMD(cmd) |
#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_DATA_MODE_ONE_LINE;
#elif JESD216_BUS_MODE == JESD216_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;
qspiReceive(busp, &mode, n, p);
#else
uint8_t buf[1];
spiSelect(busp);
buf[0] = cmd;
spiSend(busp, 1, buf);
spiReceive(busp, n, p);
spiUnselect(busp);
#endif
}
void jesd216_cmd_send(BUSDriver *busp,
uint8_t cmd,
size_t n,
const uint8_t *p) {
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
qspi_command_t mode;
mode.cfg = QSPI_CFG_CMD(cmd) |
#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_DATA_MODE_ONE_LINE;
#elif JESD216_BUS_MODE == JESD216_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(busp, &mode, n, p);
#else
uint8_t buf[1];
spiSelect(busp);
buf[0] = cmd;
spiSend(busp, 1, buf);
spiSend(busp, n, p);
spiUnselect(busp);
#endif
}
void jesd216_cmd_addr(BUSDriver *busp,
uint8_t cmd,
flash_address_t addr) {
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
qspi_command_t mode;
mode.cfg = QSPI_CFG_CMD(cmd) |
#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_ADDR_MODE_ONE_LINE |
QSPI_CFG_ADDR_SIZE_24;
#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES |
QSPI_CFG_ADDR_MODE_TWO_LINES |
QSPI_CFG_ADDR_SIZE_24;
#else
QSPI_CFG_CMD_MODE_FOUR_LINES |
QSPI_CFG_ADDR_MODE_FOUR_LINES |
QSPI_CFG_ADDR_SIZE_24;
#endif
mode.addr = addr;
mode.alt = 0U;
qspiCommand(busp, &mode);
#else
uint8_t buf[4];
spiSelect(busp);
buf[0] = cmd;
buf[1] = (uint8_t)(addr >> 16);
buf[2] = (uint8_t)(addr >> 8);
buf[3] = (uint8_t)(addr >> 0);
spiSend(busp, 4, buf);
spiUnselect(busp);
#endif
}
void jesd216_cmd_addr_send(BUSDriver *busp,
uint8_t cmd,
flash_address_t addr,
size_t n,
const uint8_t *p) {
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
qspi_command_t mode;
mode.cfg = QSPI_CFG_CMD(cmd) |
#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_ADDR_MODE_ONE_LINE |
QSPI_CFG_ADDR_SIZE_24 |
QSPI_CFG_DATA_MODE_ONE_LINE;
#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES |
QSPI_CFG_ADDR_MODE_TWO_LINES |
QSPI_CFG_ADDR_SIZE_24 |
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_DATA_MODE_FOUR_LINES;
#endif
mode.addr = addr;
mode.alt = 0U;
qspiSend(busp, &mode, n, p);
#else
uint8_t buf[4];
spiSelect(busp);
buf[0] = cmd;
buf[1] = (uint8_t)(addr >> 16);
buf[2] = (uint8_t)(addr >> 8);
buf[3] = (uint8_t)(addr >> 0);
spiSend(busp, 4, buf);
spiSend(busp, n, p);
spiUnselect(busp);
#endif
}
void jesd216_cmd_addr_receive(BUSDriver *busp,
uint8_t cmd,
flash_address_t addr,
size_t n,
uint8_t *p) {
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
qspi_command_t mode;
mode.cfg = QSPI_CFG_CMD(cmd) |
#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L
QSPI_CFG_CMD_MODE_ONE_LINE |
QSPI_CFG_ADDR_MODE_ONE_LINE |
QSPI_CFG_ADDR_SIZE_24 |
QSPI_CFG_DATA_MODE_ONE_LINE;
#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L
QSPI_CFG_CMD_MODE_TWO_LINES |
QSPI_CFG_ADDR_MODE_TWO_LINES |
QSPI_CFG_ADDR_SIZE_24 |
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_DATA_MODE_FOUR_LINES;
#endif
mode.addr = addr;
mode.alt = 0U;
qspiReceive(busp, &mode, n, p);
#else
uint8_t buf[4];
spiSelect(busp);
buf[0] = cmd;
buf[1] = (uint8_t)(addr >> 16);
buf[2] = (uint8_t)(addr >> 8);
buf[3] = (uint8_t)(addr >> 0);
spiSend(busp, 4, buf);
spiReceive(busp, n, p);
spiUnselect(busp);
#endif
}
#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__)
void jesd216_cmd_addr_dummy_receive(BUSDriver *busp,
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 JESD216_BUS_MODE == JESD216_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 JESD216_BUS_MODE == JESD216_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(busp, &mode, n, p);
}
#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
#if ((JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) && \
(JESD216_SHARED_BUS == TRUE)) || defined(__DOXYGEN__)
void jesd216_bus_acquire(BUSDriver *busp) {
qspiAcquireBus(busp);
}
void jesd216_bus_release(BUSDriver *busp) {
qspiReleaseBus(busp);
}
#elif (JESD216_BUS_MODE == JESD216_BUS_MODE_SPI) && \
(JESD216_SHARED_BUS == TRUE)
static void jesd216_bus_acquire(BUSDriver *busp) {
spiAcquireBus(busp);
spiStart(busp, busp->config->spicfg);
}
static void jesd216_bus_release(BUSDriver *busp) {
spiReleaseBus(busp);
}
#else
#define jesd216_bus_acquire(busp)
#define jesd216_bus_release(busp)
#endif
/** @} */ /** @} */

View File

@ -50,25 +50,93 @@
#define JESD216_CMD_PROGRAM_OTP_ARRAY 0x42 #define JESD216_CMD_PROGRAM_OTP_ARRAY 0x42
/** @} */ /** @} */
/**
* @name Bus interface.
* @{
*/
#define JESD216_BUS_MODE_SPI 0
#define JESD216_BUS_MODE_QSPI1L 1
#define JESD216_BUS_MODE_QSPI2L 2
#define JESD216_BUS_MODE_QSPI4L 4
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Driver pre-compile time settings. */ /* Driver pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief Physical transport interface.
*/
#if !defined(JESD216_USE_SPI) || defined(__DOXYGEN__)
#define JESD216_BUS_MODE JESD216_BUS_MODE_QSPI4L
#endif
/**
* @brief Shared bus switch.
* @details If set to @p TRUE the device acquires bus ownership
* on each transaction.
* @note Requires @p SPI_USE_MUTUAL_EXCLUSION or
* @p SPI_USE_MUTUAL_EXCLUSION.
*/
#if !defined(JESD216_SHARED_BUS) || defined(__DOXYGEN__)
#define JESD216_SHARED_BUS TRUE
#endif
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Derived constants and error checks. */ /* Derived constants and error checks. */
/*===========================================================================*/ /*===========================================================================*/
#if (JESD216_BUS_MODE == JESD216_BUS_MODE_SPI) && (HAL_USE_SPI == FALSE)
#error "JESD216_BUS_MODE_SPI requires HAL_USE_SPI"
#endif
#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) && (HAL_USE_QSPI == FALSE)
#error "JESD216_BUS_MODE_QSPIxL requires HAL_USE_QSPI"
#endif
#if (JESD216_BUS_MODE == JESD216_BUS_MODE_SPI) && \
(JESD216_SHARED_SPI == TRUE) && \
(SPI_USE_MUTUAL_EXCLUSION == FALSE)
#error "JESD216_SHARED_SPI requires SPI_USE_MUTUAL_EXCLUSION"
#endif
#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) && \
(JESD216_BUS_MODE != JESD216_BUS_MODE_QSPI1L) && \
(JESD216_BUS_MODE != JESD216_BUS_MODE_QSPI2L) && \
(JESD216_BUS_MODE != JESD216_BUS_MODE_QSPI4L)
#error "invalid JESD216_BUS_MODE selected"
#endif
/*===========================================================================*/ /*===========================================================================*/
/* Driver data structures and types. */ /* Driver data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__)
#define BUSConfig QSPIConfig
#define BUSDriver QSPIDriver
#else
#define BUSConfig SPIConfig
#define BUSDriver SPIDriver
#endif
#define _jesd216_config \
BUSDriver *busp; \
const BUSConfig *buscfg;
/** /**
* @brief @p JESD215Flash specific methods. * @brief @p JESD215Flash specific methods.
* @note No methods so far, just a common ancestor interface. * @note No methods so far, just a common ancestor interface.
*/ */
#define _jesd216_flash_methods_alone \ #define _jesd216_flash_methods_alone \
/* Read SFDP.*/ \ /* Read SFDP.*/ \
flash_error_t (*read_id)(void *instance, uint8_t *rp, size_t max); flash_error_t (*read_sfdp)(void *instance, uint8_t *rp, \
flash_address_t addr, \
size_t n);
/** /**
* @brief @p JESD215Flash specific methods with inherited ones. * @brief @p JESD215Flash specific methods with inherited ones.
@ -116,7 +184,22 @@ typedef struct {
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void jesd216_cmd(BUSDriver *busp, uint8_t cmd);
void jesd216_cmd_receive(BUSDriver *busp, uint8_t cmd, size_t n, uint8_t *p);
void jesd216_cmd_send(BUSDriver *busp, uint8_t cmd, size_t n, const uint8_t *p);
void jesd216_cmd_addr(BUSDriver *busp, uint8_t cmd, flash_address_t addr);
void jesd216_cmd_addr_send(BUSDriver *busp, uint8_t cmd, flash_address_t addr,
size_t n, const uint8_t *p);
void jesd216_cmd_addr_receive(BUSDriver *busp, uint8_t cmd, flash_address_t addr,
size_t n, uint8_t *p);
#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI
void jesd216_cmd_addr_dummy_receive(BUSDriver *busp, uint8_t cmd, flash_address_t addr,
uint8_t dummy, size_t n, uint8_t *p);
#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */
#if JESD216_SHARED_BUS == TRUE
void jesd216_bus_acquire(BUSDriver *busp);
void jesd216_bus_release(BUSDriver *busp);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -73,7 +73,7 @@
* find the details in the data sheet. * find the details in the data sheet.
*/ */
#if !defined(STM32_QSPI_QUADSPI1_PRESCALER_VALUE) || defined(__DOXYGEN__) #if !defined(STM32_QSPI_QUADSPI1_PRESCALER_VALUE) || defined(__DOXYGEN__)
#define STM32_QSPI_QUADSPI1_PRESCALER_VALUE 16 #define STM32_QSPI_QUADSPI1_PRESCALER_VALUE 1
#endif #endif
/** /**

View File

@ -79,6 +79,8 @@
***************************************************************************** *****************************************************************************
*** Next *** *** Next ***
- EX: Added flash implementation for Micron M25Qxxx devices.
- HAL: Added base flash class and JESD216 flash class.
- HAL: Extended PLLI2S for STM32F4xx subfamily. - HAL: Extended PLLI2S for STM32F4xx subfamily.
- HAL: Added QSPI driver implementation for STM32. - HAL: Added QSPI driver implementation for STM32.
- HAL: Added QSPI driver model. - HAL: Added QSPI driver model.
@ -111,6 +113,7 @@
Shell files are now located under ./os/various/shell and have a Shell files are now located under ./os/various/shell and have a
dedicated shell.mk file. dedicated shell.mk file.
- ALL: Reorganized source tree, now ports are shared between RT and NIL. - ALL: Reorganized source tree, now ports are shared between RT and NIL.
- EX: New EX subsystem.
- RT: Merged RT4. - RT: Merged RT4.
- NIL: Merged NIL2. - NIL: Merged NIL2.
- NIL: Added STM32F7 demo. - NIL: Added STM32F7 demo.

File diff suppressed because one or more lines are too long