diff options
-rw-r--r-- | os/ex/Micron/m25q.c | 70 | ||||
-rw-r--r-- | testhal/STM32/STM32L4xx/QSPI-N25Q128/debug/QSPI-N25Q128 (OpenOCD, Flash and Run).launch | 4 | ||||
-rw-r--r-- | testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c | 7 |
3 files changed, 66 insertions, 15 deletions
diff --git a/os/ex/Micron/m25q.c b/os/ex/Micron/m25q.c index 212d5b787..cc11b9d63 100644 --- a/os/ex/Micron/m25q.c +++ b/os/ex/Micron/m25q.c @@ -210,6 +210,16 @@ static const uint8_t evconf_value[1] = {0x4F}; #endif static const uint8_t flash_status[1] = {(M25Q_READ_DUMMY_CYCLES << 4U) | 0x0FU}; +static const uint8_t flash_status_xip[1] = {(M25Q_READ_DUMMY_CYCLES << 4U) | 0x07U}; +static const uint8_t flash_reset_xip_pattern[50] = { + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11 +}; #endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ @@ -497,12 +507,31 @@ static void flash_cmd_addr_dummy_receive(M25QDriver *devp, 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_xip_reset(M25QDriver *devp) { + qspi_command_t cmd; + + /* The only mode to generate an odd number of clock cycles is to write + data on 4 lines in DDR mode.*/ +#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L + cmd.cfg = QSPI_CFG_DUMMY_CYCLES(25); +#elif M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI2L + cmd.cfg = QSPI_CFG_DUMMY_CYCLES(13); +#else + cmd.cfg = QSPI_CFG_CMD(0x11) | + QSPI_CFG_CMD_MODE_FOUR_LINES | + QSPI_CFG_DUMMY_CYCLES(8) | + QSPI_CFG_DATA_MODE_FOUR_LINES; +#endif + cmd.addr = 0U; + cmd.alt = 0U; + qspiSend(devp->config->qspip, &cmd, 2, flash_reset_xip_pattern); +} #endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ static flash_error_t flash_poll_status(M25QDriver *devp) { @@ -882,17 +911,25 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) { /* QSPI initialization.*/ qspiStart(devp->config->qspip, devp->config->qspicfg); - /* Reading device ID and unique ID.*/ + /* Resetting XIP mode on entry.*/ + flash_xip_reset(devp); #if M25Q_SWITCH_WIDTH == TRUE - /* Attempting a device reset with different bus widths, commands - shorter than 8 bits are ignored.*/ - qspiCommand(devp->config->qspip, &cmd_reset_enable_1); - qspiCommand(devp->config->qspip, &cmd_reset_memory_1); - qspiCommand(devp->config->qspip, &cmd_reset_enable_2); - qspiCommand(devp->config->qspip, &cmd_reset_memory_2); + /* If the device is in one bit mode then the following commands are + rejected because shorter than 8 bits. If the device is in multiple + bits mode then the comands are accepted and the device is reset to + one bit mode.*/ +#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI4L qspiCommand(devp->config->qspip, &cmd_reset_enable_4); qspiCommand(devp->config->qspip, &cmd_reset_memory_4); +#else + qspiCommand(devp->config->qspip, &cmd_reset_enable_2); + qspiCommand(devp->config->qspip, &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); #endif /* Reading device ID and unique ID.*/ @@ -992,29 +1029,33 @@ void m25qStop(M25QDriver *devp) { * * @api */ -void m25qMemoryMap(M25QDriver *devp, uint8_t ** addrp) { +void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) { qspi_command_t cmd; + /* 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); + + /* 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 QSPI_CFG_CMD_MODE_ONE_LINE | QSPI_CFG_ADDR_MODE_ONE_LINE | - QSPI_CFG_ALT_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_ADDR_MODE_TWO_LINES | - QSPI_CFG_ALT_MODE_TWO_LINES | QSPI_CFG_DATA_MODE_TWO_LINES | #else QSPI_CFG_CMD_MODE_FOUR_LINES | QSPI_CFG_ADDR_MODE_FOUR_LINES | - QSPI_CFG_ALT_MODE_FOUR_LINES | QSPI_CFG_DATA_MODE_FOUR_LINES | #endif + QSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/ QSPI_CFG_SIOO | - QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES); + QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2); qspiMapFlash(devp->config->qspip, &cmd, addrp); } @@ -1029,6 +1070,9 @@ void m25qMemoryMap(M25QDriver *devp, uint8_t ** addrp) { void m25qMemoryUnmap(M25QDriver *devp) { qspiUnmapFlash(devp->config->qspip); + + /* Resetting XIP mode.*/ + flash_xip_reset(devp); } #endif /* QSPI_SUPPORTS_MEMMAP == TRUE */ #endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */ diff --git a/testhal/STM32/STM32L4xx/QSPI-N25Q128/debug/QSPI-N25Q128 (OpenOCD, Flash and Run).launch b/testhal/STM32/STM32L4xx/QSPI-N25Q128/debug/QSPI-N25Q128 (OpenOCD, Flash and Run).launch index 9187ae1d8..aa0c8d14a 100644 --- a/testhal/STM32/STM32L4xx/QSPI-N25Q128/debug/QSPI-N25Q128 (OpenOCD, Flash and Run).launch +++ b/testhal/STM32/STM32L4xx/QSPI-N25Q128/debug/QSPI-N25Q128 (OpenOCD, Flash and Run).launch @@ -33,9 +33,9 @@ <intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
-<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="cmd-flash_cmd_receive-(format)" val="4"/><content id="cr2-adc_lld_start_conversion-(format)" val="4"/><content id="CR2-adc-null-port_wait_for_interrupt-(format)" val="4"/><content id="CR2-adc-adcp-adc_lld_start_conversion-(format)" val="4"/><content id="cfg-cmdp-qspiSend-(format)" val="4"/><content id="CR-qspi-qspip-qspi_lld_send-(format)" val="4"/><content id="CCR-qspi-qspip-qspi_lld_send-(format)" val="4"/><content id="cfg-cmdp-qspiReceive-(format)" val="4"/><content id="r2-(format)" val="4"/><content id="config-initgpio-(format)" val="4"/><content id="moder-config-initgpio-(format)" val="4"/><content id="afrh-config-initgpio-(format)" val="4"/><content id="MODER-gpiop-initgpio-(format)" val="4"/><content id="OSPEEDR-gpiop-initgpio-(format)" val="4"/><content id="PUPDR-gpiop-initgpio-(format)" val="4"/><content id="IDR-gpiop-initgpio-(format)" val="4"/><content id="ODR-gpiop-initgpio-(format)" val="4"/><content id="AFRH-gpiop-initgpio-(format)" val="4"/><content id="AFRL-gpiop-initgpio-(format)" val="4"/><content id="id[0]-id-m25qStart-(format)" val="4"/><content id="id[1]-id-m25qStart-(format)" val="4"/><content id="id[2]-id-m25qStart-(format)" val="4"/><content id="cfg-cmdp-qspi_lld_receive-(format)" val="4"/><content id="CCR-qspi-qspip-qspi_lld_receive-(format)" val="4"/></contentList>"/>
+<stringAttribute key="org.eclipse.cdt.launch.FORMAT" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?><contentList><content id="CCR-qspi-qspip-config-null-_idle_thread.lto_priv.71-(format)" val="4"/><content id="SR-qspi-qspip-config-null-_idle_thread.lto_priv.71-(format)" val="4"/><content id="DCR-qspi-qspip-config-null-_idle_thread.lto_priv.71-(format)" val="4"/><content id="CR-qspi-qspip-config-null-_idle_thread.lto_priv.71-(format)" val="4"/><content id="SR-qspi-qspip-config-null-flash_xip_reset-(format)" val="4"/><content id="CR-qspi-qspip-config-null-flash_xip_reset-(format)" val="4"/><content id="channel-dma-qspip-config-null-flash_xip_reset-(format)" val="4"/><content id="SR-qspi-qspip-config-null-port_wait_for_interrupt-(format)" val="4"/><content id="SR-qspi-qspip-config-null-qspi_lld_send-(format)" val="4"/><content id="CMAR-channel-dma-qspip-config-null-port_wait_for_interrupt-(format)" val="4"/><content id="CCR-channel-dma-qspip-config-null-port_wait_for_interrupt-(format)" val="4"/><content id="CMAR-channel-dma-qspip-config-null-qspi_lld_send-(format)" val="4"/><content id="CPAR-channel-dma-qspip-config-null-qspi_lld_send-(format)" val="4"/><content id="CCR-channel-dma-qspip-config-null-qspi_lld_send-(format)" val="4"/><content id="CPAR-channel-dma-qspip-config-null-flash_xip_reset-(format)" val="4"/><content id="ISR-dma-dma-qspip-config-null-port_wait_for_interrupt-(format)" val="4"/><content id="ISR-dma-dma-qspip-config-null-qspi_lld_send-(format)" val="4"/><content id="CCR-qspi-qspip-qspi_lld_map_flash-(format)" val="4"/><content id="DCR-qspi-qspip-qspi_lld_map_flash-(format)" val="4"/><content id="SR-qspi-qspip-qspi_lld_map_flash-(format)" val="4"/><content id="CR-qspi-qspip-qspi_lld_map_flash-(format)" val="4"/><content id="cfg-cmdp-qspiMapFlash-(format)" val="4"/><content id="r2-(format)" val="4"/><content id="cmd-flash_cmd_receive-(format)" val="4"/><content id="cr2-adc_lld_start_conversion-(format)" val="4"/><content id="CR2-adc-null-port_wait_for_interrupt-(format)" val="4"/><content id="CR2-adc-adcp-adc_lld_start_conversion-(format)" val="4"/><content id="cfg-cmdp-qspiSend-(format)" val="4"/><content id="CR-qspi-qspip-qspi_lld_send-(format)" val="4"/><content id="CCR-qspi-qspip-qspi_lld_send-(format)" val="4"/><content id="cfg-cmdp-qspiReceive-(format)" val="4"/><content id="config-initgpio-(format)" val="4"/><content id="moder-config-initgpio-(format)" val="4"/><content id="afrh-config-initgpio-(format)" val="4"/><content id="MODER-gpiop-initgpio-(format)" val="4"/><content id="OSPEEDR-gpiop-initgpio-(format)" val="4"/><content id="PUPDR-gpiop-initgpio-(format)" val="4"/><content id="IDR-gpiop-initgpio-(format)" val="4"/><content id="ODR-gpiop-initgpio-(format)" val="4"/><content id="AFRH-gpiop-initgpio-(format)" val="4"/><content id="AFRL-gpiop-initgpio-(format)" val="4"/><content id="id[0]-id-m25qStart-(format)" val="4"/><content id="id[1]-id-m25qStart-(format)" val="4"/><content id="id[2]-id-m25qStart-(format)" val="4"/><content id="cfg-cmdp-qspi_lld_receive-(format)" val="4"/><content id="CCR-qspi-qspip-qspi_lld_receive-(format)" val="4"/><content id="SR-qspi-qspip-config-null-main-(format)" val="4"/><content id="CR-qspi-qspip-config-null-main-(format)" val="4"/><content id="channel-dma-qspip-config-null-_idle_thread.lto_priv.71-(format)" val="4"/><content id="CCR-channel-dma-qspip-config-null-_idle_thread.lto_priv.71-(format)" val="4"/><content id="CNDTR-channel-dma-qspip-config-null-_idle_thread.lto_priv.71-(format)" val="4"/><content id="CPAR-channel-dma-qspip-config-null-_idle_thread.lto_priv.71-(format)" val="4"/><content id="CMAR-channel-dma-qspip-config-null-_idle_thread.lto_priv.71-(format)" val="4"/></contentList>"/>
<stringAttribute key="org.eclipse.cdt.launch.GLOBAL_VARIABLES" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <globalVariableList/> "/>
-<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList/> "/>
+<stringAttribute key="org.eclipse.cdt.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList> <memoryBlockExpressionItem> <expression text="0x90000000"/> </memoryBlockExpressionItem> </memoryBlockExpressionList> "/>
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="./build/ch.elf"/>
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="STM32L4xx-QSPI-N25Q128"/>
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
diff --git a/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c b/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c index bd506f9e8..08e82a9ea 100644 --- a/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c +++ b/testhal/STM32/STM32L4xx/QSPI-N25Q128/main.c @@ -79,6 +79,7 @@ static THD_FUNCTION(Thread1, arg) { */
int main(void) {
flash_error_t err;
+ uint8_t *addr;
/*
* System initializations.
@@ -127,6 +128,12 @@ int main(void) { if (err != FLASH_ERROR_VERIFY)
chSysHalt("verify non-erase error");
+ /* Memory mapping the device.*/
+ m25qMemoryMap(&m25q, &addr);
+
+ /* Unmapping the device.*/
+ m25qMemoryUnmap(&m25q);
+
/* Reading it back.*/
err = flashRead(&m25q, 0, buffer, 128);
if (err != FLASH_NO_ERROR)
|