aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2016-05-24 20:10:57 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2016-05-24 20:10:57 +0000
commitc0c9fe70b0dbce03d83d0c5b5c2177c01e7faa91 (patch)
treeb152a2e9500d2836bbaabae2bef5786ac3ebca9d /os
parent8c8a1441fd198586aa1abd0e4b1231ac3445355b (diff)
downloadChibiOS-c0c9fe70b0dbce03d83d0c5b5c2177c01e7faa91.tar.gz
ChibiOS-c0c9fe70b0dbce03d83d0c5b5c2177c01e7faa91.tar.bz2
ChibiOS-c0c9fe70b0dbce03d83d0c5b5c2177c01e7faa91.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9519 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/ex/Micron/m25q.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/os/ex/Micron/m25q.c b/os/ex/Micron/m25q.c
index 84a67f2cc..ac93a4f54 100644
--- a/os/ex/Micron/m25q.c
+++ b/os/ex/Micron/m25q.c
@@ -565,21 +565,151 @@ static flash_error_t program(void *instance, flash_address_t addr,
}
static flash_error_t start_erase_all(void *instance) {
+ M25QDriver *devp = (M25QDriver *)instance;
+
+ osalDbgCheck(instance != NULL);
+ osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
+ "invalid state");
+
+ if (devp->state == FLASH_ERASE) {
+ return FLASH_BUSY_ERASING;
+ }
+
+ /* Bus acquired.*/
+ flash_bus_acquire(devp);
+
+ /* FLASH_ERASE state while the operation is performed.*/
+ devp->state = FLASH_ERASE;
+
+ /* Enabling write operation.*/
+ flash_cmd(devp, M25Q_CMD_WRITE_ENABLE);
+
+ /* Bulk erase command.*/
+ flash_cmd(devp, M25Q_CMD_BULK_ERASE);
+
+ /* Ready state again.*/
+ devp->state = FLASH_READY;
+
+ /* Bus released.*/
+ flash_bus_release(devp);
return FLASH_NO_ERROR;
}
static flash_error_t 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);
+ osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
+ "invalid state");
+
+ if (devp->state == FLASH_ERASE) {
+ return FLASH_BUSY_ERASING;
+ }
+
+ /* Bus acquired.*/
+ flash_bus_acquire(devp);
+
+ /* FLASH_ERASE state while the operation is performed.*/
+ devp->state = FLASH_ERASE;
+
+ /* Enabling write operation.*/
+ flash_cmd(devp, M25Q_CMD_WRITE_ENABLE);
+
+ /* Sector erase command.*/
+ flash_cmd_addr(devp, M25Q_CMD_SECTOR_ERASE, addr);
+
+ /* Ready state again.*/
+ devp->state = FLASH_READY;
+
+ /* Bus released.*/
+ flash_bus_release(devp);
return FLASH_NO_ERROR;
}
static flash_error_t verify_erase(void *instance, flash_sector_t sector) {
+ M25QDriver *devp = (M25QDriver *)instance;
+ unsigned i;
+
+ osalDbgCheck(instance != NULL);
+ osalDbgCheck(sector < descriptor.sectors_count);
+ osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
+ "invalid state");
+
+ if (devp->state == FLASH_ERASE) {
+ return FLASH_BUSY_ERASING;
+ }
+
+ /* Bus acquired.*/
+ flash_bus_acquire(devp);
+
+ /* FLASH_READY state while the operation is performed.*/
+ devp->state = FLASH_READ;
+
+ /* Read command.*/
+
+ /* Ready state again.*/
+ devp->state = FLASH_READY;
+
+ /* Bus released.*/
+ flash_bus_release(devp);
return FLASH_NO_ERROR;
}
static flash_error_t query_erase(void *instance, uint32_t *msec) {
+ M25QDriver *devp = (M25QDriver *)instance;
+ uint8_t sts;
+
+ osalDbgCheck(instance != NULL);
+ osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
+ "invalid state");
+
+ /* If there is an erase in progress then the device must be checked.*/
+ if (devp->state == FLASH_ERASE) {
+
+ /* Bus acquired.*/
+ flash_bus_acquire(devp);
+
+ /* Read status command.*/
+ flash_cmd_receive(devp, 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.*/
+ if (((sts & M25Q_FLAGS_PROGRAM_ERASE) == 0U) ||
+ ((sts & M25Q_FLAGS_ERASE_SUSPEND) != 0U)) {
+
+ /* Bus released.*/
+ flash_bus_release(devp);
+
+ /* Recommended time before polling again, this is a simplified
+ implementation.*/
+ if (msec != NULL) {
+ *msec = 1U;
+ }
+
+ return FLASH_BUSY_ERASING;
+ }
+
+ /* The device is ready to accept commands.*/
+ devp->state = FLASH_READY;
+
+ /* Checking for errors.*/
+ if ((sts & M25Q_FLAGS_ALL_ERRORS) != 0U) {
+
+ /* Clearing status register.*/
+ flash_cmd(devp, M25Q_CMD_CLEAR_FLAG_STATUS_REGISTER);
+
+ /* Erase operation failed.*/
+ return FLASH_ERROR_ERASE;
+ }
+
+ /* Bus released.*/
+ flash_bus_release(devp);
+ }
return FLASH_NO_ERROR;
}