From ec871b0ef13545688ddd140520bb49baacb4283a Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sat, 4 Jun 2016 12:29:54 +0000 Subject: M25Q driver works over QSPI. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9568 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/ex/Micron/m25q.c | 588 ++++++----------------- os/ex/Micron/m25q.h | 73 +-- os/hal/lib/peripherals/flash/hal_jesd216_flash.c | 277 +++++++++++ os/hal/lib/peripherals/flash/hal_jesd216_flash.h | 113 ++++- os/hal/ports/STM32/LLD/QUADSPIv1/hal_qspi_lld.h | 2 +- 5 files changed, 536 insertions(+), 517 deletions(-) (limited to 'os') diff --git a/os/ex/Micron/m25q.c b/os/ex/Micron/m25q.c index 21ff90061..cd399181a 100644 --- a/os/ex/Micron/m25q.c +++ b/os/ex/Micron/m25q.c @@ -53,33 +53,33 @@ /* Driver local variables and types. */ /*===========================================================================*/ -static const uint8_t manufacturer_ids[] = M25Q_SUPPORTED_MANUFACTURE_IDS; -static const uint8_t memory_type_ids[] = M25Q_SUPPORTED_MEMORY_TYPE_IDS; - -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); -static flash_error_t program(void *instance, flash_address_t addr, - const uint8_t *pp, size_t n); -static flash_error_t start_erase_all(void *instance); -static flash_error_t start_erase_sector(void *instance, flash_sector_t sector); -static flash_error_t query_erase(void *instance, uint32_t *msec); -static flash_error_t verify_erase(void *instance, flash_sector_t sector); -static flash_error_t read_id(void *instance, uint8_t *rp, size_t n); +static const flash_descriptor_t *m25q_get_descriptor(void *instance); +static flash_error_t m25q_read(void *instance, flash_address_t addr, + uint8_t *rp, size_t n); +static flash_error_t m25q_program(void *instance, flash_address_t addr, + const uint8_t *pp, size_t n); +static flash_error_t m25q_start_erase_all(void *instance); +static flash_error_t m25q_start_erase_sector(void *instance, + flash_sector_t sector); +static flash_error_t m25q_query_erase(void *instance, uint32_t *msec); +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. */ static const struct M25QDriverVMT m25q_vmt = { - get_descriptor, read, program, - start_erase_all, start_erase_sector, query_erase, verify_erase, - read_id + m25q_get_descriptor, m25q_read, m25q_program, + m25q_start_erase_all, m25q_start_erase_sector, + m25q_query_erase, m25q_verify_erase, + m25q_read_sfdp }; /** * @brief N25Q128 descriptor. */ -static flash_descriptor_t descriptor = { +static flash_descriptor_t m25q_descriptor = { .attributes = FLASH_ATTR_ERASED_IS_ONE | FLASH_ATTR_REWRITABLE | FLASH_ATTR_SUSPEND_ERASE_CAPABLE, .page_size = 256U, @@ -89,18 +89,18 @@ static flash_descriptor_t descriptor = { .address = 0U }; -#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI /* 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) | #if M25Q_SWITCH_WIDTH == TRUE QSPI_CFG_CMD_MODE_ONE_LINE | QSPI_CFG_DATA_MODE_ONE_LINE, #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_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_DATA_MODE_TWO_LINES, #else @@ -113,16 +113,16 @@ static const qspi_command_t cmd_read_id = { }; /* 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) | #if M25Q_SWITCH_WIDTH == TRUE QSPI_CFG_CMD_MODE_ONE_LINE | QSPI_CFG_DATA_MODE_ONE_LINE, #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_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_DATA_MODE_TWO_LINES, #else @@ -135,14 +135,14 @@ static const qspi_command_t cmd_write_evconf = { }; /* 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) | #if M25Q_SWITCH_WIDTH == TRUE QSPI_CFG_CMD_MODE_ONE_LINE, #else -#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L +#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L 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, #else QSPI_CFG_CMD_MODE_FOUR_LINES, @@ -153,20 +153,23 @@ static const qspi_command_t cmd_write_enable = { }; /* Bus width initialization.*/ -#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L -static const uint8_t evconf_value[1] = {0xCF}; -#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L -static const uint8_t evconf_value[1] = {0x8F}; +#if JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI1L +static const uint8_t m25q_evconf_value[1] = {0xCF}; +#elif JESD216_BUS_MODE == JESD216_BUS_MODE_QSPI2L +static const uint8_t m25q_evconf_value[1] = {0x8F}; #else -static const uint8_t evconf_value[1] = {0x4F}; +static const uint8_t m25q_evconf_value[1] = {0x4F}; #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. */ /*===========================================================================*/ -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; 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; } -#if ((M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) && (M25Q_SHARED_BUS == TRUE)) || \ - defined(__DOXYGEN__) -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) { +#if (JESD216_BUS_MODE != JESD216_BUS_MODE_SPI) || defined(__DOXYGEN__) +void m25q_reset_xip(M25QDriver *devp) { static const uint8_t flash_conf[1] = { (M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU }; @@ -464,10 +193,10 @@ void flash_reset_xip(M25QDriver *devp) { cmd.addr = 0; cmd.cfg = QSPI_CFG_CMD_MODE_NONE | 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_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_DATA_MODE_TWO_LINES | #else @@ -477,17 +206,17 @@ void flash_reset_xip(M25QDriver *devp) { QSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/ QSPI_CFG_ALT_SIZE_8 | 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.*/ - flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); + jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); /* 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.*/ 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 bits mode then the commands are accepted and the device is reset to 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.*/ static const qspi_command_t cmd_reset_enable_4 = { .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) | @@ -526,8 +255,8 @@ void flash_reset_memory(M25QDriver *devp) { .alt = 0 }; - qspiCommand(devp->config->qspip, &cmd_reset_enable_4); - qspiCommand(devp->config->qspip, &cmd_reset_memory_4); + qspiCommand(devp->config->busp, &cmd_reset_enable_4); + qspiCommand(devp->config->busp, &cmd_reset_memory_4); #else /* 2x M25Q_CMD_RESET_ENABLE command.*/ static const qspi_command_t cmd_reset_enable_2 = { @@ -545,18 +274,18 @@ void flash_reset_memory(M25QDriver *devp) { .alt = 0 }; - qspiCommand(devp->config->qspip, &cmd_reset_enable_2); - qspiCommand(devp->config->qspip, &cmd_reset_memory_2); + qspiCommand(devp->config->busp, &cmd_reset_enable_2); + qspiCommand(devp->config->busp, &cmd_reset_memory_2); #endif /* Now the device should be in one bit mode for sure and we perform a device reset.*/ - qspiCommand(devp->config->qspip, &cmd_reset_enable_1); - qspiCommand(devp->config->qspip, &cmd_reset_memory_1); + qspiCommand(devp->config->busp, &cmd_reset_enable_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; do { @@ -564,13 +293,14 @@ static flash_error_t flash_poll_status(M25QDriver *devp) { osalThreadSleepMilliseconds(1); #endif /* 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); /* Checking for errors.*/ if ((sts & M25Q_FLAGS_ALL_ERRORS) != 0U) { /* 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.*/ return FLASH_ERROR_PROGRAM; @@ -579,23 +309,23 @@ static flash_error_t flash_poll_status(M25QDriver *devp) { 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; osalDbgCheck(instance != NULL); osalDbgAssert((devp->state != FLASH_UNINIT) && (devp->state != FLASH_STOP), "invalid state"); - return &descriptor; + return &m25q_descriptor; } -static flash_error_t read(void *instance, flash_address_t addr, - uint8_t *rp, size_t n) { +static flash_error_t m25q_read(void *instance, flash_address_t addr, + 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); + osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count * + (size_t)m25q_descriptor.sectors_size); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -604,16 +334,15 @@ static flash_error_t read(void *instance, flash_address_t addr, } /* Bus acquired.*/ - flash_bus_acquire(devp); + jesd216_bus_acquire(devp->config->busp); /* FLASH_READY state while the operation is performed.*/ 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.*/ - flash_cmd_addr_dummy_receive(devp, M25Q_CMD_FAST_READ, - addr, M25Q_READ_DUMMY_CYCLES, - n, rp); + jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ, + addr, M25Q_READ_DUMMY_CYCLES, n, rp); #else /* Normal read command in SPI mode.*/ #endif @@ -622,18 +351,18 @@ static flash_error_t read(void *instance, flash_address_t addr, devp->state = FLASH_READY; /* Bus released.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); return FLASH_NO_ERROR; } -static flash_error_t program(void *instance, flash_address_t addr, - const uint8_t *pp, size_t n) { +static flash_error_t m25q_program(void *instance, flash_address_t addr, + const uint8_t *pp, size_t n) { M25QDriver *devp = (M25QDriver *)instance; osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U)); - osalDbgCheck((size_t)addr + n <= (size_t)descriptor.sectors_count * - (size_t)descriptor.sectors_size); + osalDbgCheck((size_t)addr + n <= (size_t)m25q_descriptor.sectors_count * + (size_t)m25q_descriptor.sectors_size); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -642,7 +371,7 @@ static flash_error_t program(void *instance, flash_address_t addr, } /* Bus acquired.*/ - flash_bus_acquire(devp); + jesd216_bus_acquire(devp->config->busp); /* FLASH_PGM state while the operation is performed.*/ devp->state = FLASH_PGM; @@ -658,17 +387,18 @@ static flash_error_t program(void *instance, flash_address_t addr, } /* Enabling write operation.*/ - flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); + jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); /* 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.*/ - err = flash_poll_status(devp); + err = m25q_poll_status(devp); if (err != FLASH_NO_ERROR) { /* Bus released.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); return err; } @@ -683,12 +413,12 @@ static flash_error_t program(void *instance, flash_address_t addr, devp->state = FLASH_READY; /* Bus released.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); 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; osalDbgCheck(instance != NULL); @@ -700,29 +430,30 @@ static flash_error_t start_erase_all(void *instance) { } /* Bus acquired.*/ - flash_bus_acquire(devp); + jesd216_bus_acquire(devp->config->busp); /* FLASH_ERASE state while the operation is performed.*/ devp->state = FLASH_ERASE; /* Enabling write operation.*/ - flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); + jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); /* Bulk erase command.*/ - flash_cmd(devp, M25Q_CMD_BULK_ERASE); + jesd216_cmd(devp->config->busp, M25Q_CMD_BULK_ERASE); /* Bus released.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); 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; flash_address_t addr = (flash_address_t)(sector * SECTOR_SIZE); osalDbgCheck(instance != NULL); - osalDbgCheck(sector < descriptor.sectors_count); + osalDbgCheck(sector < m25q_descriptor.sectors_count); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -731,31 +462,32 @@ static flash_error_t start_erase_sector(void *instance, flash_sector_t sector) { } /* Bus acquired.*/ - flash_bus_acquire(devp); + jesd216_bus_acquire(devp->config->busp); /* FLASH_ERASE state while the operation is performed.*/ devp->state = FLASH_ERASE; /* Enabling write operation.*/ - flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); + jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); /* 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.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); 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; uint8_t cmpbuf[M25Q_COMPARE_BUFFER_SIZE]; flash_address_t addr; size_t n; osalDbgCheck(instance != NULL); - osalDbgCheck(sector < descriptor.sectors_count); + osalDbgCheck(sector < m25q_descriptor.sectors_count); osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE), "invalid state"); @@ -764,7 +496,7 @@ static flash_error_t verify_erase(void *instance, flash_sector_t sector) { } /* Bus acquired.*/ - flash_bus_acquire(devp); + jesd216_bus_acquire(devp->config->busp); /* FLASH_READY state while the operation is performed.*/ devp->state = FLASH_READ; @@ -775,10 +507,10 @@ static flash_error_t verify_erase(void *instance, flash_sector_t sector) { while (n > 0U) { uint8_t *p; -#if M25Q_BUS_MODE != M25Q_BUS_MODE_SPI - flash_cmd_addr_dummy_receive(devp, M25Q_CMD_FAST_READ, - addr, M25Q_READ_DUMMY_CYCLES, - sizeof cmpbuf, cmpbuf); +#if JESD216_BUS_MODE != JESD216_BUS_MODE_SPI + jesd216_cmd_addr_dummy_receive(devp->config->busp, M25Q_CMD_FAST_READ, + addr, M25Q_READ_DUMMY_CYCLES, + sizeof cmpbuf, cmpbuf); #else /* Normal read command in SPI mode.*/ #endif @@ -790,7 +522,7 @@ static flash_error_t verify_erase(void *instance, flash_sector_t sector) { devp->state = FLASH_READY; /* Bus released.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); return FLASH_ERROR_VERIFY; } @@ -804,12 +536,12 @@ static flash_error_t verify_erase(void *instance, flash_sector_t sector) { devp->state = FLASH_READY; /* Bus released.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); 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; uint8_t sts; @@ -821,10 +553,11 @@ static flash_error_t query_erase(void *instance, uint32_t *msec) { if (devp->state == FLASH_ERASE) { /* Bus acquired.*/ - flash_bus_acquire(devp); + jesd216_bus_acquire(devp->config->busp); /* 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 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)) { /* Bus released.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); /* Recommended time before polling again, this is a simplified implementation.*/ @@ -850,23 +583,26 @@ static flash_error_t query_erase(void *instance, uint32_t *msec) { if ((sts & M25Q_FLAGS_ALL_ERRORS) != 0U) { /* 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.*/ return FLASH_ERROR_ERASE; } /* Bus released.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); } 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)rp; + (void)addr; (void)n; return FLASH_NO_ERROR; @@ -892,18 +628,6 @@ void m25qObjectInit(M25QDriver *devp) { 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. * @@ -922,50 +646,51 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) { if (devp->state == FLASH_STOP) { /* 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.*/ - spiStart(devp->config->spip, devp->config->spicfg); + spiStart(devp->config->busp, devp->config->buscfg); /* Reading device ID.*/ -#else /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ +#else /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ /* 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 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 because a CPU reset does not reset the memory too.*/ - flash_reset_memory(devp); + m25q_reset_memory(devp); /* 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); -#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ +#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ /* Checking if the device is white listed.*/ - osalDbgAssert(find_id(manufacturer_ids, - sizeof manufacturer_ids, + osalDbgAssert(m25q_find_id(m25q_manufacturer_ids, + sizeof m25q_manufacturer_ids, devp->device_id[0]), "invalid manufacturer id"); - osalDbgAssert(find_id(memory_type_ids, - sizeof memory_type_ids, + osalDbgAssert(m25q_find_id(m25q_memory_type_ids, + sizeof m25q_memory_type_ids, devp->device_id[1]), "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.*/ - qspiCommand(devp->config->qspip, &cmd_write_enable); - qspiSend(devp->config->qspip, &cmd_write_evconf, 1, evconf_value); + qspiCommand(devp->config->busp, &m25q_cmd_write_enable); + qspiSend(devp->config->busp, &m25q_cmd_write_evconf, 1, m25q_evconf_value); { uint8_t id[3]; /* 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.*/ osalDbgAssert(memcmp(id, devp->device_id, 3) == 0, @@ -974,18 +699,19 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) { #endif /* 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] = { (M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU }; /* Setting up the dummy cycles to be used for fast read operations.*/ - flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); - flash_cmd_send(devp, M25Q_CMD_WRITE_V_CONF_REGISTER, - 1, flash_conf); + jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); + jesd216_cmd_send(devp->config->busp, M25Q_CMD_WRITE_V_CONF_REGISTER, + 1, flash_conf); } #endif @@ -993,7 +719,7 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) { devp->state = FLASH_READY; /* 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) { /* Bus acquisition.*/ - flash_bus_acquire(devp); + jesd216_bus_acquire(devp->config->busp); -#if M25Q_BUS_MODE == M25Q_BUS_MODE_SPI - spiStop(devp->config->spip); +#if JESD216_BUS_MODE == JESD216_BUS_MODE_SPI + spiStop(devp->config->busp); #else - qspiStop(devp->config->qspip); + qspiStop(devp->config->busp); #endif devp->config = NULL; @@ -1026,11 +752,11 @@ void m25qStop(M25QDriver *devp) { devp->state = FLASH_STOP; /* 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__) /** * @brief Enters the memory Mapping mode. @@ -1051,21 +777,21 @@ void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) { qspi_command_t cmd; /* Bus acquisition.*/ - flash_bus_acquire(devp); + jesd216_bus_acquire(devp->config->busp); /* Activating XIP mode in the device.*/ - flash_cmd(devp, M25Q_CMD_WRITE_ENABLE); - flash_cmd_send(devp, M25Q_CMD_WRITE_V_CONF_REGISTER, - 1, flash_status_xip); + jesd216_cmd(devp->config->busp, M25Q_CMD_WRITE_ENABLE); + jesd216_cmd_send(devp->config->busp, M25Q_CMD_WRITE_V_CONF_REGISTER, + 1, flash_status_xip); /* Putting the QSPI driver in memory mapped mode.*/ cmd.cfg = QSPI_CFG_CMD(M25Q_CMD_FAST_READ) | 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_ADDR_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_ADDR_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_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2); - qspiMapFlash(devp->config->qspip, &cmd, addrp); + qspiMapFlash(devp->config->busp, &cmd, addrp); /* 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) { /* 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.*/ - flash_bus_release(devp); + jesd216_bus_release(devp->config->busp); } #endif /* QSPI_SUPPORTS_MEMMAP == TRUE */ -#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ +#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ /** @} */ diff --git a/os/ex/Micron/m25q.h b/os/ex/Micron/m25q.h index f08ca1627..5dbbe6ef7 100644 --- a/os/ex/Micron/m25q.h +++ b/os/ex/Micron/m25q.h @@ -87,16 +87,6 @@ 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. */ /*===========================================================================*/ @@ -105,13 +95,6 @@ * @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). * @details This is the number of dummy cycles to be used for fast read @@ -133,17 +116,6 @@ #define M25Q_SWITCH_WIDTH TRUE #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. * @details If enabled this options inserts delays into the flash waiting @@ -191,27 +163,6 @@ /* 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) #error "invalid M25Q_READ_DUMMY_CYCLES value (1..15)" #endif @@ -228,25 +179,7 @@ * @brief Type of a M25Q configuration structure. */ typedef struct { -#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI) || defined(__DOXYGEN__) - /** - * @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 + _jesd216_config } M25QConfig; /** @@ -299,12 +232,12 @@ extern "C" { void m25qObjectInit(M25QDriver *devp); void m25qStart(M25QDriver *devp, const M25QConfig *config); 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__) void m25qMemoryMap(M25QDriver *devp, uint8_t ** addrp); void m25qMemoryUnmap(M25QDriver *devp); #endif /* QSPI_SUPPORTS_MEMMAP == TRUE */ -#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ +#endif /* JESD216_BUS_MODE != JESD216_BUS_MODE_SPI */ #ifdef __cplusplus } #endif diff --git a/os/hal/lib/peripherals/flash/hal_jesd216_flash.c b/os/hal/lib/peripherals/flash/hal_jesd216_flash.c index 7687a4aa7..07d4aad80 100644 --- a/os/hal/lib/peripherals/flash/hal_jesd216_flash.c +++ b/os/hal/lib/peripherals/flash/hal_jesd216_flash.c @@ -46,4 +46,281 @@ /* 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 + /** @} */ diff --git a/os/hal/lib/peripherals/flash/hal_jesd216_flash.h b/os/hal/lib/peripherals/flash/hal_jesd216_flash.h index 8e46f71e8..69d8a8533 100644 --- a/os/hal/lib/peripherals/flash/hal_jesd216_flash.h +++ b/os/hal/lib/peripherals/flash/hal_jesd216_flash.h @@ -35,40 +35,108 @@ * @name Common command codes * @{ */ -#define JESD216_CMD_READ_ID 0x9F -#define JESD216_CMD_READ 0x03 -#define JESD216_CMD_WRITE_ENABLE 0x06 -#define JESD216_CMD_WRITE_DISABLE 0x04 -#define JESD216_CMD_READ_STATUS_REGISTER 0x05 -#define JESD216_CMD_WRITE_STATUS_REGISTER 0x01 -#define JESD216_CMD_PAGE_PROGRAM 0x02 -#define JESD216_CMD_ERASE_4K 0x20 -#define JESD216_CMD_ERASE_BULK 0xC7 -#define JESD216_CMD_PROGRAM_ERASE_RESUME 0x7A -#define JESD216_CMD_PROGRAM_ERASE_SUSPEND 0x75 -#define JESD216_CMD_READ_OTP_ARRAY 0x4B -#define JESD216_CMD_PROGRAM_OTP_ARRAY 0x42 +#define JESD216_CMD_READ_ID 0x9F +#define JESD216_CMD_READ 0x03 +#define JESD216_CMD_WRITE_ENABLE 0x06 +#define JESD216_CMD_WRITE_DISABLE 0x04 +#define JESD216_CMD_READ_STATUS_REGISTER 0x05 +#define JESD216_CMD_WRITE_STATUS_REGISTER 0x01 +#define JESD216_CMD_PAGE_PROGRAM 0x02 +#define JESD216_CMD_ERASE_4K 0x20 +#define JESD216_CMD_ERASE_BULK 0xC7 +#define JESD216_CMD_PROGRAM_ERASE_RESUME 0x7A +#define JESD216_CMD_PROGRAM_ERASE_SUSPEND 0x75 +#define JESD216_CMD_READ_OTP_ARRAY 0x4B +#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. */ /*===========================================================================*/ +/** + * @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. */ /*===========================================================================*/ +#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. */ /*===========================================================================*/ +#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. * @note No methods so far, just a common ancestor interface. */ #define _jesd216_flash_methods_alone \ /* 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. @@ -116,7 +184,22 @@ typedef struct { #ifdef __cplusplus extern "C" { #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 } #endif diff --git a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_qspi_lld.h b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_qspi_lld.h index 4fdb6ba14..0aacca1ba 100644 --- a/os/hal/ports/STM32/LLD/QUADSPIv1/hal_qspi_lld.h +++ b/os/hal/ports/STM32/LLD/QUADSPIv1/hal_qspi_lld.h @@ -73,7 +73,7 @@ * find the details in the data sheet. */ #if !defined(STM32_QSPI_QUADSPI1_PRESCALER_VALUE) || defined(__DOXYGEN__) -#define STM32_QSPI_QUADSPI1_PRESCALER_VALUE 16 +#define STM32_QSPI_QUADSPI1_PRESCALER_VALUE 1 #endif /** -- cgit v1.2.3