From c3d1d75f50ecfe9ae36f58de67d2baf57be1be39 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 11 May 2016 11:22:46 +0000 Subject: Added smart polling and preparation for erase suspend. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9463 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/lib/peripherals/flash/hal_flash.c | 75 +++++++++++++++++++ os/hal/lib/peripherals/flash/hal_flash.h | 121 +++++++++++++++++++------------ 2 files changed, 149 insertions(+), 47 deletions(-) create mode 100644 os/hal/lib/peripherals/flash/hal_flash.c (limited to 'os/hal/lib') diff --git a/os/hal/lib/peripherals/flash/hal_flash.c b/os/hal/lib/peripherals/flash/hal_flash.c new file mode 100644 index 000000000..b65ca3768 --- /dev/null +++ b/os/hal/lib/peripherals/flash/hal_flash.c @@ -0,0 +1,75 @@ +/* + N25Q128 Flash Driver - Copyright (C) 2016 Giovanni Di Sirio + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file hal_flash.c + * @brief Generic flash driver class code. + * + * @addtogroup HAL_FLASH + * @{ + */ + +#include "hal.h" + +#include "hal_flash.h" + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Waits until the current erase operation is finished. + * + * @param[in] devp pointer to a @p BaseFlash object + * @param[in] cb polling callback or @p NULL + */ +flash_error_t flashWaitErase(BaseFlash *devp) { + + while (true) { + flash_error_t err; + uint32_t msec; + + /* Checking operation state.*/ + err = flashQueryErase(devp, &msec); + if (err != FLASH_BUSY_ERASING) { + return err; + } + + /* Interval because nice waiting.*/ + osalThreadSleepMilliseconds(msec); + } +} + +/** @} */ diff --git a/os/hal/lib/peripherals/flash/hal_flash.h b/os/hal/lib/peripherals/flash/hal_flash.h index b62f73d66..d0416b353 100644 --- a/os/hal/lib/peripherals/flash/hal_flash.h +++ b/os/hal/lib/peripherals/flash/hal_flash.h @@ -16,7 +16,7 @@ /** * @file hal_flash.h - * @brief Generic flash interface header. + * @brief Generic flash driver class header. * * @addtogroup HAL_FLASH * @{ @@ -59,10 +59,9 @@ typedef enum { FLASH_UNINIT = 0, FLASH_STOP = 1, FLASH_READY = 2, - FLASH_READING = 3, - FLASH_WRITING = 4, - FLASH_ERASING = 5, - FLASH_SUSPENDED = 6 + FLASH_READ = 3, + FLASH_PGM = 4, + FLASH_ERASE = 5 } flash_state_t; /** @@ -70,12 +69,12 @@ typedef enum { */ typedef enum { FLASH_NO_ERROR = 0, /* No error. */ - FLASH_ECC_ERROR = 1, /* ECC error during read operation. */ - FLASH_PROGRAM_FAILURE = 2, /* Program operation failed. */ - FLASH_ERASE_FAILURE = 3, /* Erase operation failed. */ - FLASH_VERIFY_FAILURE = 4, /* Verify operation failed. */ - FLASH_BUSY = 5, /* Attempt to access a sector being erased. */ - FLASH_HW_FAILURE = 6 /* Controller or communication error. */ + FLASH_BUSY_ERASING = 1, /* Erase operation in progress. */ + FLASH_ERROR_READ = 2, /* ECC or other error during read operation.*/ + FLASH_ERROR_PROGRAM = 3, /* Program operation failed. */ + FLASH_ERROR_ERASE = 4, /* Erase operation failed. */ + FLASH_ERROR_VERIFY = 5, /* Verify operation failed. */ + FLASH_ERROR_HW_FAILURE = 6 /* Controller or communication error. */ } flash_error_t; /** @@ -144,20 +143,20 @@ typedef struct { #define _base_flash_methods_alone \ /* Get flash device attributes.*/ \ const flash_descriptor_t * (*get_descriptor)(void *instance); \ - /* Erase whole flash device.*/ \ - flash_error_t (*erase_all)(void *instance); \ - /* Erase single sector.*/ \ - flash_error_t (*erase_sector)(void *instance, \ - flash_sector_t sector); \ - /* Erase single sector.*/ \ - flash_error_t (*verify_erase)(void *instance, \ - flash_sector_t sector); \ - /* Write operation.*/ \ - flash_error_t (*program)(void *instance, flash_address_t addr, \ - const uint8_t *pp, size_t n); \ /* Read operation.*/ \ flash_error_t (*read)(void *instance, flash_address_t addr, \ - uint8_t *rp, size_t n); + uint8_t *rp, size_t n); \ + /* Program operation.*/ \ + flash_error_t (*program)(void *instance, flash_address_t addr, \ + const uint8_t *pp, size_t n); \ + /* Erase whole flash device.*/ \ + flash_error_t (*start_erase_all)(void *instance); \ + /* Erase single sector.*/ \ + flash_error_t (*start_erase_sector)(void *instance, \ + flash_sector_t sector); \ + flash_error_t (*query_erase)(void *instance, uint32_t *wait_time); \ + /* Verify erase single sector.*/ \ + flash_error_t (*verify_erase)(void *instance, flash_sector_t sector); /** * @brief @p BaseFlash specific methods with inherited ones. @@ -211,68 +210,96 @@ typedef struct { (ip)->vmt_baseflash->get_descriptor(ip) /** - * @brief Whole device erase operation. + * @brief Read operation. * * @param[in] ip pointer to a @p BaseFlash or derived class + * @param[in] addr flash address + * @param[out] rp pointer to the data buffer + * @param[in] n number of bytes to be read * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_READ if the read operation failed. * * @api */ -#define flashEraseAll(ip) \ - (ip)->vmt_baseflash->erase_all(ip) +#define flashRead(ip, addr, rp, n) \ + (ip)->vmt_baseflash->read(ip, addr, rp, n) /** - * @brief Erase operation on a sector. + * @brief Program operation. * * @param[in] ip pointer to a @p BaseFlash or derived class - * @param[in] sector sector to be erased + * @param[in] addr flash address + * @param[in] wp pointer to the data buffer + * @param[in] n number of bytes to be programmed * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_PROGRAM if the program operation failed. * * @api */ -#define flashEraseSector(ip, sector) \ - (ip)->vmt_baseflash->erase_sector(ip, sector) +#define flashProgram(ip, addr, pp, n) \ + (ip)->vmt_baseflash->program(ip, addr, pp, n) /** - * @brief Returns the erase state of a sector. + * @brief Starts a whole-device erase operation. * * @param[in] ip pointer to a @p BaseFlash or derived class - * @param[in] sector sector to be verified * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. * * @api */ -#define flashVerifyErase(ip, sector) \ - (ip)->vmt_baseflash->verify_erase(ip, sector) +#define flashStartEraseAll(ip) \ + (ip)->vmt_baseflash->start_erase_all(ip) /** - * @brief Write operation. + * @brief Starts an sector erase operation. * * @param[in] ip pointer to a @p BaseFlash or derived class - * @param[in] addr flash address - * @param[in] wp pointer to the data buffer - * @param[in] n number of bytes to be programmed + * @param[in] sector sector to be erased * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. * * @api */ -#define flashProgram(ip, addr, pp, n) \ - (ip)->vmt_baseflash->program(ip, addr, pp, n) +#define flashStartEraseSector(ip, sector) \ + (ip)->vmt_baseflash->start_erase_sector(ip, sector) /** - * @brief Read operation. + * @brief Queries the driver for erase operation progress. * * @param[in] ip pointer to a @p BaseFlash or derived class - * @param[in] addr flash address - * @param[out] rp pointer to the data buffer - * @param[in] n number of bytes to be read + * @param[out] msec recommended time, in milliseconds, that what should be + * spent before calling this function again, can be @p NULL * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_ERASE if the erase operation failed. * * @api */ -#define flashRead(ip, addr, rp, n) \ - (ip)->vmt_baseflash->read(ip, addr, rp, n) +#define flashQueryErase(ip, msec) \ + (ip)->vmt_baseflash->query_erase(ip, msec) +/** + * @brief Returns the erase state of a sector. + * + * @param[in] ip pointer to a @p BaseFlash or derived class + * @param[in] sector sector to be verified + * @return An error code. + * @retval FLASH_NO_ERROR if there is no erase operation in progress. + * @retval FLASH_BUSY_ERASING if there is an erase operation in progress. + * @retval FLASH_ERROR_VERIFY if the verify operation failed. + * + * @api + */ +#define flashVerifyErase(ip, sector) \ + (ip)->vmt_baseflash->verify_erase(ip, sector) /** @} */ /*===========================================================================*/ @@ -282,7 +309,7 @@ typedef struct { #ifdef __cplusplus extern "C" { #endif - + flash_error_t flashWaitErase(BaseFlash *devp); #ifdef __cplusplus } #endif -- cgit v1.2.3