aboutsummaryrefslogtreecommitdiffstats
path: root/os/ex
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2016-06-02 17:42:37 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2016-06-02 17:42:37 +0000
commitf3c38b36f5e3039ef78736f568105a703c1046b0 (patch)
tree9c9982e0ffcd8045976bd03d4f1cb46c0591af3c /os/ex
parent41212137418b35ce36f8bf3e9f92eb602314c371 (diff)
downloadChibiOS-f3c38b36f5e3039ef78736f568105a703c1046b0.tar.gz
ChibiOS-f3c38b36f5e3039ef78736f568105a703c1046b0.tar.bz2
ChibiOS-f3c38b36f5e3039ef78736f568105a703c1046b0.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9558 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/ex')
-rw-r--r--os/ex/Micron/m25q.c217
1 files changed, 119 insertions, 98 deletions
diff --git a/os/ex/Micron/m25q.c b/os/ex/Micron/m25q.c
index cc11b9d63..a8a226c7d 100644
--- a/os/ex/Micron/m25q.c
+++ b/os/ex/Micron/m25q.c
@@ -152,54 +152,6 @@ static const qspi_command_t cmd_write_enable = {
.alt = 0
};
-/* 1x M25Q_CMD_RESET_ENABLE command.*/
-static const qspi_command_t cmd_reset_enable_1 = {
- .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) |
- QSPI_CFG_CMD_MODE_ONE_LINE,
- .addr = 0,
- .alt = 0
-};
-
-/* 2x M25Q_CMD_RESET_ENABLE command.*/
-static const qspi_command_t cmd_reset_enable_2 = {
- .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) |
- QSPI_CFG_CMD_MODE_TWO_LINES,
- .addr = 0,
- .alt = 0
-};
-
-/* 4x M25Q_CMD_RESET_ENABLE command.*/
-static const qspi_command_t cmd_reset_enable_4 = {
- .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) |
- QSPI_CFG_CMD_MODE_FOUR_LINES,
- .addr = 0,
- .alt = 0
-};
-
-/* 1x M25Q_CMD_RESET_MEMORY command.*/
-static const qspi_command_t cmd_reset_memory_1 = {
- .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_MEMORY) |
- QSPI_CFG_CMD_MODE_ONE_LINE,
- .addr = 0,
- .alt = 0
-};
-
-/* 2x M25Q_CMD_RESET_MEMORY command.*/
-static const qspi_command_t cmd_reset_memory_2 = {
- .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_MEMORY) |
- QSPI_CFG_CMD_MODE_TWO_LINES,
- .addr = 0,
- .alt = 0
-};
-
-/* 4x M25Q_CMD_RESET_MEMORY command.*/
-static const qspi_command_t cmd_reset_memory_4 = {
- .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_MEMORY) |
- QSPI_CFG_CMD_MODE_FOUR_LINES,
- .addr = 0,
- .alt = 0
-};
-
/* Bus width initialization.*/
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L
static const uint8_t evconf_value[1] = {0xCF};
@@ -208,19 +160,6 @@ static const uint8_t evconf_value[1] = {0x8F};
#else
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 */
/*===========================================================================*/
@@ -513,24 +452,99 @@ static void flash_cmd_addr_dummy_receive(M25QDriver *devp,
qspiReceive(devp->config->qspip, &mode, n, p);
}
-void flash_xip_reset(M25QDriver *devp) {
+void flash_reset_xip(M25QDriver *devp) {
qspi_command_t cmd;
+ uint8_t buf[1];
- /* The only mode to generate an odd number of clock cycles is to write
- data on 4 lines in DDR mode.*/
+ /* Resetting XIP mode by reading one byte without XIP confirmation bit.*/
+ cmd.cfg = QSPI_CFG_CMD(M25Q_CMD_FAST_READ) |
+ QSPI_CFG_ADDR_SIZE_24 |
#if M25Q_BUS_MODE == M25Q_BUS_MODE_QSPI1L
- cmd.cfg = QSPI_CFG_DUMMY_CYCLES(25);
+ 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
- cmd.cfg = QSPI_CFG_DUMMY_CYCLES(13);
+ QSPI_CFG_CMD_MODE_TWO_LINES |
+ QSPI_CFG_ADDR_MODE_TWO_LINES |
+ QSPI_CFG_DATA_MODE_TWO_LINES |
#else
- cmd.cfg = QSPI_CFG_CMD(0x11) |
- QSPI_CFG_CMD_MODE_FOUR_LINES |
- QSPI_CFG_DUMMY_CYCLES(8) |
- QSPI_CFG_DATA_MODE_FOUR_LINES;
+ QSPI_CFG_CMD_MODE_FOUR_LINES |
+ QSPI_CFG_ADDR_MODE_FOUR_LINES |
+ QSPI_CFG_DATA_MODE_FOUR_LINES |
#endif
- cmd.addr = 0U;
- cmd.alt = 0U;
- qspiSend(devp->config->qspip, &cmd, 2, flash_reset_xip_pattern);
+ QSPI_CFG_ALT_MODE_FOUR_LINES | /* Always 4 lines, note.*/
+ QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2);
+ cmd.alt = 0xFF;
+ cmd.addr = 0;
+ qspiReceive(devp->config->qspip, &cmd, 1, buf);
+}
+
+void flash_reset_memory(M25QDriver *devp) {
+
+ /* 1x M25Q_CMD_RESET_ENABLE command.*/
+ static const qspi_command_t cmd_reset_enable_1 = {
+ .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) |
+ QSPI_CFG_CMD_MODE_ONE_LINE,
+ .addr = 0,
+ .alt = 0
+ };
+
+ /* 1x M25Q_CMD_RESET_MEMORY command.*/
+ static const qspi_command_t cmd_reset_memory_1 = {
+ .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_MEMORY) |
+ QSPI_CFG_CMD_MODE_ONE_LINE,
+ .addr = 0,
+ .alt = 0
+ };
+
+ /* 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 commands are accepted and the device is reset to
+ one bit mode.*/
+#if M25Q_BUS_MODE == M25Q_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) |
+ QSPI_CFG_CMD_MODE_FOUR_LINES,
+ .addr = 0,
+ .alt = 0
+ };
+
+ /* 4x M25Q_CMD_RESET_MEMORY command.*/
+ static const qspi_command_t cmd_reset_memory_4 = {
+ .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_MEMORY) |
+ QSPI_CFG_CMD_MODE_FOUR_LINES,
+ .addr = 0,
+ .alt = 0
+ };
+
+ qspiCommand(devp->config->qspip, &cmd_reset_enable_4);
+ qspiCommand(devp->config->qspip, &cmd_reset_memory_4);
+#else
+ /* 2x M25Q_CMD_RESET_ENABLE command.*/
+ static const qspi_command_t cmd_reset_enable_2 = {
+ .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_ENABLE) |
+ QSPI_CFG_CMD_MODE_TWO_LINES,
+ .addr = 0,
+ .alt = 0
+ };
+
+ /* 2x M25Q_CMD_RESET_MEMORY command.*/
+ static const qspi_command_t cmd_reset_memory_2 = {
+ .cfg = QSPI_CFG_CMD(M25Q_CMD_RESET_MEMORY) |
+ QSPI_CFG_CMD_MODE_TWO_LINES,
+ .addr = 0,
+ .alt = 0
+ };
+
+ 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 /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */
@@ -911,26 +925,13 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) {
/* QSPI initialization.*/
qspiStart(devp->config->qspip, devp->config->qspicfg);
- /* Resetting XIP mode on entry.*/
- flash_xip_reset(devp);
+ /* 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);
-#if M25Q_SWITCH_WIDTH == TRUE
- /* 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
+ /* 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);
/* Reading device ID and unique ID.*/
qspiReceive(devp->config->qspip, &cmd_read_id,
@@ -968,10 +969,16 @@ void m25qStart(M25QDriver *devp, const M25QConfig *config) {
descriptor.sectors_count = (1U << (size_t)devp->device_id[2]) / SECTOR_SIZE;
#if (M25Q_BUS_MODE != M25Q_BUS_MODE_SPI)
- /* Setting up the dummy cycles to be used for rast read operations.*/
- flash_cmd(devp, M25Q_CMD_WRITE_ENABLE);
- flash_cmd_send(devp, M25Q_CMD_WRITE_V_CONF_REGISTER,
- 1, flash_status);
+ {
+ static const uint8_t flash_status[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_status);
+ }
#endif
/* Driver in ready state.*/
@@ -1030,8 +1037,14 @@ void m25qStop(M25QDriver *devp) {
* @api
*/
void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) {
+ static const uint8_t flash_status_xip[1] = {
+ (M25Q_READ_DUMMY_CYCLES << 4U) | 0x07U
+ };
qspi_command_t cmd;
+ /* Bus acquisition.*/
+ flash_bus_acquire(devp);
+
/* Activating XIP mode in the device.*/
flash_cmd(devp, M25Q_CMD_WRITE_ENABLE);
flash_cmd_send(devp, M25Q_CMD_WRITE_V_CONF_REGISTER,
@@ -1058,6 +1071,9 @@ void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) {
QSPI_CFG_DUMMY_CYCLES(M25Q_READ_DUMMY_CYCLES - 2);
qspiMapFlash(devp->config->qspip, &cmd, addrp);
+
+ /* Bus release.*/
+ flash_bus_release(devp);
}
/**
@@ -1069,10 +1085,15 @@ void m25qMemoryMap(M25QDriver *devp, uint8_t **addrp) {
*/
void m25qMemoryUnmap(M25QDriver *devp) {
+ /* Bus acquisition.*/
+ flash_bus_acquire(devp);
+
qspiUnmapFlash(devp->config->qspip);
- /* Resetting XIP mode.*/
- flash_xip_reset(devp);
+ flash_reset_xip(devp);
+
+ /* Bus release.*/
+ flash_bus_release(devp);
}
#endif /* QSPI_SUPPORTS_MEMMAP == TRUE */
#endif /* M25Q_BUS_MODE != M25Q_BUS_MODE_SPI */