EFLASH driver for STM32L4xx.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12735 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
78bb68667c
commit
d767ce2c49
|
@ -33,11 +33,34 @@
|
|||
* @name Flash attributes
|
||||
* @{
|
||||
*/
|
||||
#define FLASH_ATTR_ERASED_IS_ONE 0x00000001
|
||||
#define FLASH_ATTR_MEMORY_MAPPED 0x00000002
|
||||
#define FLASH_ATTR_REWRITABLE 0x00000004
|
||||
#define FLASH_ATTR_READ_ECC_CAPABLE 0x00000008
|
||||
#define FLASH_ATTR_SUSPEND_ERASE_CAPABLE 0x00000010
|
||||
/**
|
||||
* @brief Defines one as the erased bit state.
|
||||
*/
|
||||
#define FLASH_ATTR_ERASED_IS_ONE 0x00000001U
|
||||
/**
|
||||
* @brief The memory is accessible in a memory mapped mode.
|
||||
*/
|
||||
#define FLASH_ATTR_MEMORY_MAPPED 0x00000002U
|
||||
/**
|
||||
* @brief Programmed pages can be programmed again.
|
||||
* @note This is incompatible and alternative to @p FLASH_ATTR_ECC_CAPABLE.
|
||||
*/
|
||||
#define FLASH_ATTR_REWRITABLE 0x00000004U
|
||||
/**
|
||||
* @brief The memory is protected by an ECC mechanism.
|
||||
* @note This usually puts restrictions on the program operations.
|
||||
* - Program operations can only happen at offsets aligned to
|
||||
* write page boundaries.
|
||||
* - The programmed data size must be a multiple of the write
|
||||
* page size.
|
||||
* - Programmed pages cannot be re-programmed.
|
||||
* .
|
||||
*/
|
||||
#define FLASH_ATTR_ECC_CAPABLE 0x00000008U
|
||||
/**
|
||||
* @brief The device is able to suspend erase operations.
|
||||
*/
|
||||
#define FLASH_ATTR_SUSPEND_ERASE_CAPABLE 0x00000010U
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -131,9 +154,13 @@ typedef struct {
|
|||
uint32_t sectors_size;
|
||||
/**
|
||||
* @brief Flash address if memory mapped or zero.
|
||||
* @note Conventionally, non memory mapped devices have address zero.
|
||||
* @note Conventionally, non memory mapped devices have address @p NULL.
|
||||
*/
|
||||
flash_offset_t address;
|
||||
uint8_t *address;
|
||||
/**
|
||||
* @brief Flash size.
|
||||
*/
|
||||
uint32_t size;
|
||||
} flash_descriptor_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,540 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hal_efl_lld.c
|
||||
* @brief STM32L4xx Embedded Flash subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup HAL_EFL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define STM32_FLASH_SECTOR_SIZE 2048U
|
||||
#define STM32_FLASH_LINE_SIZE 8U
|
||||
#define STM32_FLASH_LINE_MASK (STM32_FLASH_LINE_SIZE - 1U)
|
||||
|
||||
#define FLASH_PDKEY1 0x04152637U
|
||||
#define FLASH_PDKEY2 0xFAFBFCFDU
|
||||
|
||||
#define FLASH_KEY1 0x45670123U
|
||||
#define FLASH_KEY2 0xCDEF89ABU
|
||||
|
||||
#define FLASH_OPTKEY1 0x08192A3BU
|
||||
#define FLASH_OPTKEY2 0x4C5D6E7FU
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EFL1 driver identifier.
|
||||
*/
|
||||
EFlashDriver EFLD1;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static const flash_descriptor_t efl_lld_descriptor = {
|
||||
.attributes = FLASH_ATTR_ERASED_IS_ONE |
|
||||
FLASH_ATTR_MEMORY_MAPPED |
|
||||
FLASH_ATTR_ECC_CAPABLE,
|
||||
.page_size = STM32_FLASH_LINE_SIZE,
|
||||
.sectors_count = STM32_FLASH_NUMBER_OF_BANKS *
|
||||
STM32_FLASH_SECTORS_PER_BANK,
|
||||
.sectors = NULL,
|
||||
.sectors_size = STM32_FLASH_SECTOR_SIZE,
|
||||
.address = (uint8_t *)0x08000000U,
|
||||
.size = STM32_FLASH_NUMBER_OF_BANKS *
|
||||
STM32_FLASH_SECTORS_PER_BANK *
|
||||
STM32_FLASH_SECTOR_SIZE
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
|
||||
static inline void stm32_flash_lock(EFlashDriver *eflp) {
|
||||
|
||||
eflp->flash->CR |= FLASH_CR_LOCK;
|
||||
}
|
||||
|
||||
static inline void stm32_flash_unlock(EFlashDriver *eflp) {
|
||||
|
||||
eflp->flash->KEYR |= FLASH_KEY1;
|
||||
eflp->flash->KEYR |= FLASH_KEY2;
|
||||
}
|
||||
|
||||
static inline void stm32_flash_enable_pgm(EFlashDriver *eflp) {
|
||||
|
||||
eflp->flash->CR |= FLASH_CR_PG;
|
||||
}
|
||||
|
||||
static inline void stm32_flash_disable_pgm(EFlashDriver *eflp) {
|
||||
|
||||
eflp->flash->CR &= ~FLASH_CR_PG;
|
||||
}
|
||||
|
||||
static inline void stm32_flash_clear_status(EFlashDriver *eflp) {
|
||||
|
||||
eflp->flash->SR = 0x0000FFFFU;
|
||||
}
|
||||
|
||||
static inline void stm32_flash_wait_busy(EFlashDriver *eflp) {
|
||||
|
||||
/* Wait for busy bit clear.*/
|
||||
while ((eflp->flash->SR & FLASH_SR_BSY) != 0U) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline flash_error_t stm32_flash_check_errors(EFlashDriver *eflp) {
|
||||
uint32_t sr = eflp->flash->SR;
|
||||
|
||||
/* Clearing error conditions.*/
|
||||
eflp->flash->SR = sr & 0x0000FFFFU;
|
||||
|
||||
/* Some errors are only caught by assertion.*/
|
||||
osalDbgAssert((sr & (FLASH_SR_FASTERR |
|
||||
FLASH_SR_MISERR |
|
||||
FLASH_SR_PGSERR |
|
||||
FLASH_SR_SIZERR)) != 0U, "unexpected flash error");
|
||||
|
||||
/* Decoding relevant errors.*/
|
||||
if ((sr & FLASH_SR_WRPERR) != 0U) {
|
||||
return FLASH_ERROR_HW_FAILURE;
|
||||
}
|
||||
|
||||
if ((sr & (FLASH_SR_PROGERR | FLASH_SR_OPERR)) != 0U) {
|
||||
return eflp->state == FLASH_PGM ? FLASH_ERROR_PROGRAM : FLASH_ERROR_ERASE;
|
||||
}
|
||||
|
||||
return FLASH_NO_ERROR;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level Embedded Flash driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void efl_lld_init(void) {
|
||||
|
||||
/* Driver initialization.*/
|
||||
eflObjectInit(&EFLD1);
|
||||
EFLD1.flash = FLASH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the Embedded Flash peripheral.
|
||||
*
|
||||
* @param[in] eflp pointer to a @p EFlashDriver structure
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void efl_lld_start(EFlashDriver *eflp) {
|
||||
|
||||
stm32_flash_unlock(eflp);
|
||||
FLASH->CR = 0x00000000U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the Embedded Flash peripheral.
|
||||
*
|
||||
* @param[in] eflp pointer to a @p EFlashDriver structure
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void efl_lld_stop(EFlashDriver *eflp) {
|
||||
|
||||
stm32_flash_lock(eflp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the flash descriptor structure.
|
||||
*
|
||||
* @param[in] ip pointer to a @p EFlashDriver instance
|
||||
* @return A flash device descriptor.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
const flash_descriptor_t *efl_lld_get_descriptor(void *instance) {
|
||||
|
||||
(void)instance;
|
||||
|
||||
return &efl_lld_descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read operation.
|
||||
*
|
||||
* @param[in] ip pointer to a @p EFlashDriver instance
|
||||
* @param[in] offset flash offset
|
||||
* @param[in] n number of bytes to be read
|
||||
* @param[out] rp pointer to the data buffer
|
||||
* @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.
|
||||
* @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
flash_error_t efl_lld_read(void *instance, flash_offset_t offset,
|
||||
size_t n, uint8_t *rp) {
|
||||
EFlashDriver *devp = (EFlashDriver *)instance;
|
||||
flash_error_t err = FLASH_NO_ERROR;
|
||||
|
||||
osalDbgCheck((instance != NULL) && (rp != NULL) && (n > 0U));
|
||||
osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size);
|
||||
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
||||
"invalid state");
|
||||
|
||||
/* No reading while erasing.*/
|
||||
if (devp->state == FLASH_ERASE) {
|
||||
return FLASH_BUSY_ERASING;
|
||||
}
|
||||
|
||||
/* FLASH_READY state while the operation is performed.*/
|
||||
devp->state = FLASH_READ;
|
||||
|
||||
/* Clearing error status bits.*/
|
||||
stm32_flash_clear_status(devp);
|
||||
|
||||
/* Actual read implementation.*/
|
||||
memcpy((void *)rp, (const void *)efl_lld_descriptor.address + offset, n);
|
||||
|
||||
/* Checking for errors after reading.*/
|
||||
if ((devp->flash->SR & FLASH_SR_RDERR) != 0U) {
|
||||
err = FLASH_ERROR_READ;
|
||||
}
|
||||
|
||||
/* Ready state again.*/
|
||||
devp->state = FLASH_READY;
|
||||
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program operation.
|
||||
* @note The device supports ECC, it is only possible to write erased
|
||||
* pages once except when writing all zeroes.
|
||||
*
|
||||
* @param[in] ip pointer to a @p EFlashDriver instance
|
||||
* @param[in] offset flash offset
|
||||
* @param[in] n number of bytes to be programmed
|
||||
* @param[in] pp pointer to the data buffer
|
||||
* @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.
|
||||
* @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
flash_error_t efl_lld_program(void *instance, flash_offset_t offset,
|
||||
size_t n, const uint8_t *pp) {
|
||||
EFlashDriver *devp = (EFlashDriver *)instance;
|
||||
flash_error_t err = FLASH_NO_ERROR;
|
||||
|
||||
osalDbgCheck((instance != NULL) && (pp != NULL) && (n > 0U));
|
||||
osalDbgCheck((size_t)offset + n <= (size_t)efl_lld_descriptor.size);
|
||||
|
||||
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
||||
"invalid state");
|
||||
|
||||
/* No programming while erasing.*/
|
||||
if (devp->state == FLASH_ERASE) {
|
||||
return FLASH_BUSY_ERASING;
|
||||
}
|
||||
|
||||
/* FLASH_PGM state while the operation is performed.*/
|
||||
devp->state = FLASH_PGM;
|
||||
|
||||
/* Clearing error status bits.*/
|
||||
stm32_flash_clear_status(devp);
|
||||
|
||||
/* Enabling PGM mode in the controller.*/
|
||||
stm32_flash_enable_pgm(devp);
|
||||
|
||||
/* Actual program implementation.*/
|
||||
while (n > 0U) {
|
||||
volatile uint32_t *address;
|
||||
|
||||
union {
|
||||
uint32_t w[STM32_FLASH_LINE_SIZE / sizeof (uint32_t)];
|
||||
uint8_t b[STM32_FLASH_LINE_SIZE / sizeof (uint8_t)];
|
||||
} line;
|
||||
|
||||
/* Unwritten bytes are initialized to all ones.*/
|
||||
line.w[0] = 0xFFFFFFFFU;
|
||||
line.w[1] = 0xFFFFFFFFU;
|
||||
|
||||
/* Copying data inside the prepared line.*/
|
||||
do {
|
||||
line.b[offset & STM32_FLASH_LINE_MASK] = *pp;
|
||||
offset++;
|
||||
n--;
|
||||
pp++;
|
||||
}
|
||||
while ((n > 0U) & ((offset & STM32_FLASH_LINE_MASK) != 0U));
|
||||
|
||||
/* Programming line.*/
|
||||
address = (volatile uint32_t *)(efl_lld_descriptor.address + offset);
|
||||
address[0] = line.w[0];
|
||||
address[1] = line.w[1];
|
||||
stm32_flash_wait_busy(devp);
|
||||
err = stm32_flash_check_errors(devp);
|
||||
if (err != FLASH_NO_ERROR) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disabling PGM mode in the controller.*/
|
||||
stm32_flash_disable_pgm(devp);
|
||||
|
||||
/* Ready state again.*/
|
||||
devp->state = FLASH_READY;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a whole-device erase operation.
|
||||
* @note This function only erases bank 2 if it is present. Bank 1 is not
|
||||
* touched because it is where the program is running on.
|
||||
* Pages on bank 1 can be individually erased.
|
||||
*
|
||||
* @param[in] ip pointer to a @p EFlashDriver instance
|
||||
* @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_HW_FAILURE if access to the memory failed.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
flash_error_t efl_lld_start_erase_all(void *instance) {
|
||||
EFlashDriver *devp = (EFlashDriver *)instance;
|
||||
|
||||
osalDbgCheck(instance != NULL);
|
||||
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
||||
"invalid state");
|
||||
|
||||
/* No erasing while erasing.*/
|
||||
if (devp->state == FLASH_ERASE) {
|
||||
return FLASH_BUSY_ERASING;
|
||||
}
|
||||
|
||||
/* FLASH_PGM state while the operation is performed.*/
|
||||
devp->state = FLASH_ERASE;
|
||||
|
||||
/* Clearing error status bits.*/
|
||||
stm32_flash_clear_status(devp);
|
||||
|
||||
#if defined(FLASH_CR_MER2)
|
||||
devp->flash->CR |= FLASH_CR_MER2;
|
||||
devp->flash->CR |= FLASH_CR_STRT;
|
||||
#endif
|
||||
|
||||
return FLASH_NO_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts an sector erase operation.
|
||||
*
|
||||
* @param[in] ip pointer to a @p EFlashDriver instance
|
||||
* @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.
|
||||
* @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
flash_error_t efl_lld_start_erase_sector(void *instance,
|
||||
flash_sector_t sector) {
|
||||
EFlashDriver *devp = (EFlashDriver *)instance;
|
||||
|
||||
osalDbgCheck(instance != NULL);
|
||||
osalDbgCheck(sector < efl_lld_descriptor.sectors_count);
|
||||
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
||||
"invalid state");
|
||||
|
||||
/* No erasing while erasing.*/
|
||||
if (devp->state == FLASH_ERASE) {
|
||||
return FLASH_BUSY_ERASING;
|
||||
}
|
||||
|
||||
/* FLASH_PGM state while the operation is performed.*/
|
||||
devp->state = FLASH_ERASE;
|
||||
|
||||
/* Clearing error status bits.*/
|
||||
stm32_flash_clear_status(devp);
|
||||
|
||||
/* Enable page erase.*/
|
||||
devp->flash->CR |= FLASH_CR_PER;
|
||||
|
||||
#if defined(FLASH_CR_BKER)
|
||||
/* Bank selection.*/
|
||||
if (sector < STM32_FLASH_SECTORS_PER_BANK) {
|
||||
/* First bank.*/
|
||||
devp->flash->CR &= ~FLASH_CR_BKER;
|
||||
}
|
||||
else {
|
||||
/* Second bank.*/
|
||||
devp->flash->CR |= FLASH_CR_BKER;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Mask off the page selection bits.*/
|
||||
devp->flash->CR &= ~FLASH_CR_PNB;
|
||||
|
||||
/* Set the page selection bits.*/
|
||||
devp->flash->CR |= sector << FLASH_CR_PNB_Pos;
|
||||
|
||||
/* Start the erase.*/
|
||||
devp->flash->CR |= FLASH_CR_STRT;
|
||||
|
||||
return FLASH_NO_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Queries the driver for erase operation progress.
|
||||
*
|
||||
* @param[in] ip pointer to a @p EFlashDriver instance
|
||||
* @param[out] msec recommended time, in milliseconds, that
|
||||
* 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.
|
||||
* @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
flash_error_t efl_lld_query_erase(void *instance, uint32_t *msec){
|
||||
EFlashDriver *devp = (EFlashDriver *)instance;
|
||||
flash_error_t err;
|
||||
|
||||
/* If there is an erase in progress then the device must be checked.*/
|
||||
if (devp->state == FLASH_ERASE) {
|
||||
|
||||
/* Checking for operation in progress.*/
|
||||
if ((devp->flash->SR & FLASH_SR_BSY) == 0U) {
|
||||
|
||||
/* Disabling the various erase control bits.*/
|
||||
devp->flash->CR &= ~(FLASH_CR_MER1 |
|
||||
#if defined(FLASH_CR_MER2)
|
||||
FLASH_CR_MER2 |
|
||||
#endif
|
||||
FLASH_CR_PER);
|
||||
|
||||
/* No operation in progress, checking for errors.*/
|
||||
err = stm32_flash_check_errors(devp);
|
||||
|
||||
/* Back to ready state.*/
|
||||
devp->state = FLASH_READY;
|
||||
}
|
||||
else {
|
||||
/* Recommended time before polling again, this is a simplified
|
||||
implementation.*/
|
||||
if (msec != NULL) {
|
||||
*msec = (uint32_t)STM32_FLASH_WAIT_TIME_MS;
|
||||
}
|
||||
|
||||
err = FLASH_BUSY_ERASING;
|
||||
}
|
||||
}
|
||||
else {
|
||||
err = FLASH_NO_ERROR;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the erase state of a sector.
|
||||
*
|
||||
* @param[in] ip pointer to a @p EFlashDriver instance
|
||||
* @param[in] sector sector to be verified
|
||||
* @return An error code.
|
||||
* @retval FLASH_NO_ERROR if the sector is erased.
|
||||
* @retval FLASH_BUSY_ERASING if there is an erase operation in progress.
|
||||
* @retval FLASH_ERROR_VERIFY if the verify operation failed.
|
||||
* @retval FLASH_ERROR_HW_FAILURE if access to the memory failed.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector) {
|
||||
EFlashDriver *devp = (EFlashDriver *)instance;
|
||||
uint32_t *address;
|
||||
flash_error_t err = FLASH_NO_ERROR;
|
||||
unsigned i;
|
||||
|
||||
osalDbgCheck(instance != NULL);
|
||||
osalDbgCheck(sector < efl_lld_descriptor.sectors_count);
|
||||
osalDbgAssert((devp->state == FLASH_READY) || (devp->state == FLASH_ERASE),
|
||||
"invalid state");
|
||||
|
||||
/* No verifying while erasing.*/
|
||||
if (devp->state == FLASH_ERASE) {
|
||||
return FLASH_BUSY_ERASING;
|
||||
}
|
||||
|
||||
/* Address of the sector.*/
|
||||
address = (uint32_t *)(efl_lld_descriptor.address +
|
||||
flashGetSectorOffset(getBaseFlash(devp), sector));
|
||||
|
||||
/* FLASH_READY state while the operation is performed.*/
|
||||
devp->state = FLASH_READ;
|
||||
|
||||
/* Scanning the sector space.*/
|
||||
for (i = 0U; i < STM32_FLASH_SECTOR_SIZE / sizeof(uint32_t); i++) {
|
||||
if (*address != 0xFFFFFFFFU) {
|
||||
err = FLASH_ERROR_VERIFY;
|
||||
break;
|
||||
}
|
||||
address++;
|
||||
}
|
||||
|
||||
/* Ready state again.*/
|
||||
devp->state = FLASH_READY;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_EFL == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hal_efl_lld.h
|
||||
* @brief STM32L4xx Embedded Flash subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup HAL_EFL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_EFL_LLD_H
|
||||
#define HAL_EFL_LLD_H
|
||||
|
||||
#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name STM32L4xx configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Suggested wait time during erase operations polling.
|
||||
*/
|
||||
#if !defined(STM32_FLASH_WAIT_TIME_MS) || defined(__DOXYGEN__)
|
||||
#define STM32_FLASH_WAIT_TIME_MS 5
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(STM32_FLASH_NUMBER_OF_BANKS)
|
||||
#error "STM32_FLASH_NUMBER_OF_BANKS not defined in registry"
|
||||
#endif
|
||||
|
||||
#if !defined(STM32_FLASH_SECTORS_PER_BANK)
|
||||
#error "STM32_FLASH_SECTORS_PER_BANK not defined in registry"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the embedded flash driver structure.
|
||||
*/
|
||||
#define efl_lld_driver_fields \
|
||||
/* Flash registers.*/ \
|
||||
FLASH_TypeDef *flash
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the embedded flash configuration structure.
|
||||
*/
|
||||
#define efl_lld_config_fields \
|
||||
/* Dummy configuration, it is not needed.*/ \
|
||||
uint32_t dummy
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern EFlashDriver EFLD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void efl_lld_init(void);
|
||||
void efl_lld_start(EFlashDriver *eflp);
|
||||
void efl_lld_stop(EFlashDriver *eflp);
|
||||
const flash_descriptor_t *efl_lld_get_descriptor(void *instance);
|
||||
flash_error_t efl_lld_read(void *instance, flash_offset_t offset,
|
||||
size_t n, uint8_t *rp);
|
||||
flash_error_t efl_lld_program(void *instance, flash_offset_t offset,
|
||||
size_t n, const uint8_t *pp);
|
||||
flash_error_t efl_lld_start_erase_all(void *instance);
|
||||
flash_error_t efl_lld_start_erase_sector(void *instance,
|
||||
flash_sector_t sector);
|
||||
flash_error_t efl_lld_query_erase(void *instance, uint32_t *wait_time);
|
||||
flash_error_t efl_lld_verify_erase(void *instance, flash_sector_t sector);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_EFL == TRUE */
|
||||
|
||||
#endif /* HAL_EFL_LLD_H */
|
||||
|
||||
/** @} */
|
|
@ -194,8 +194,8 @@
|
|||
|
||||
/* Flash attributes.*/
|
||||
#define STM32_FLASH_NUMBER_OF_BANKS 1
|
||||
#if !defined(STM32_FLASH_PAGES_PER_BANK) || defined(__DOXYGEN__)
|
||||
#define STM32_FLASH_PAGES_PER_BANK 256 /* Maximum, can be redefined.*/
|
||||
#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
|
||||
#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
|
||||
#endif
|
||||
|
||||
/* GPIO attributes.*/
|
||||
|
@ -531,8 +531,8 @@
|
|||
|
||||
/* Flash attributes.*/
|
||||
#define STM32_FLASH_NUMBER_OF_BANKS 1
|
||||
#if !defined(STM32_FLASH_PAGES_PER_BANK) || defined(__DOXYGEN__)
|
||||
#define STM32_FLASH_PAGES_PER_BANK 256 /* Maximum, can be redefined.*/
|
||||
#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
|
||||
#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
|
||||
#endif
|
||||
|
||||
/* GPIO attributes.*/
|
||||
|
@ -889,8 +889,8 @@
|
|||
|
||||
/* Flash attributes.*/
|
||||
#define STM32_FLASH_NUMBER_OF_BANKS 2
|
||||
#if !defined(STM32_FLASH_PAGES_PER_BANK) || defined(__DOXYGEN__)
|
||||
#define STM32_FLASH_PAGES_PER_BANK 256 /* Maximum, can be redefined.*/
|
||||
#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
|
||||
#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
|
||||
#endif
|
||||
|
||||
/* GPIO attributes.*/
|
||||
|
@ -1306,8 +1306,8 @@
|
|||
|
||||
/* Flash attributes.*/
|
||||
#define STM32_FLASH_NUMBER_OF_BANKS 2
|
||||
#if !defined(STM32_FLASH_PAGES_PER_BANK) || defined(__DOXYGEN__)
|
||||
#define STM32_FLASH_PAGES_PER_BANK 256 /* Maximum, can be redefined.*/
|
||||
#if !defined(STM32_FLASH_SECTORS_PER_BANK) || defined(__DOXYGEN__)
|
||||
#define STM32_FLASH_SECTORS_PER_BANK 256 /* Maximum, can be redefined.*/
|
||||
#endif
|
||||
|
||||
/* GPIO attributes.*/
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hal_efl_lld.c
|
||||
* @brief PLATFORM Embedded Flash subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup HAL_EFL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EFL1 driver identifier.
|
||||
*/
|
||||
#if (PLATFORM_EFL_USE_EFL1 == TRUE) || defined(__DOXYGEN__)
|
||||
EFlashDriver EFLD1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level Embedded Flash driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void efl_lld_init(void) {
|
||||
|
||||
#if PLATFORM_EFL_USE_EFL1 == TRUE
|
||||
/* Driver initialization.*/
|
||||
eflObjectInit(&EFLD1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the Embedded Flash peripheral.
|
||||
*
|
||||
* @param[in] eflp pointer to a @p EFlashDriver structure
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void efl_lld_start(EFlashDriver *eflp) {
|
||||
|
||||
if (eflp->state == FLASH_STOP) {
|
||||
/* Enables the peripheral.*/
|
||||
#if PLATFORM_EFL_USE_EFL1 == TRUE
|
||||
if (&EFLD1 == eflp) {
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* Configures the peripheral.*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the Embedded Flash peripheral.
|
||||
*
|
||||
* @param[in] eflp pointer to a @p EFlashDriver structure
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void efl_lld_stop(EFlashDriver *eflp) {
|
||||
|
||||
if (eflp->state == FLASH_READY) {
|
||||
/* Resets the peripheral.*/
|
||||
|
||||
/* Disables the peripheral.*/
|
||||
#if PLATFORM_EFL_USE_EFL1 == TRUE
|
||||
if (&EFLD1 == eflp) {
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_EFL == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file hal_efl_lld.h
|
||||
* @brief PLATFORM Embedded Flash subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup HAL_EFL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef HAL_EFL_LLD_H
|
||||
#define HAL_EFL_LLD_H
|
||||
|
||||
#if (HAL_USE_EFL == TRUE) || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PLATFORM configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief EFL1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for EFL1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(PLATFORM_EFL_USE_EFL1) || defined(__DOXYGEN__)
|
||||
#define PLATFORM_EFL_USE_EFL1 FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the embedded flash driver structure.
|
||||
*/
|
||||
#define efl_lld_driver_fields \
|
||||
/* Dummy field, it is not needed.*/ \
|
||||
uint32_t dummy
|
||||
|
||||
/**
|
||||
* @brief Low level fields of the embedded flash configuration structure.
|
||||
*/
|
||||
#define efl_lld_config_fields \
|
||||
/* Dummy configuration, it is not needed.*/ \
|
||||
uint32_t dummy
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (PLATFORM_EFL_USE_EFL1 == TRUE) && !defined(__DOXYGEN__)
|
||||
extern EFlashDriver EFLD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void efl_lld_init(void);
|
||||
void efl_lld_start(EFlashDriver *eflp);
|
||||
void efl_lld_stop(EFlashDriver *eflp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_EFL == TRUE */
|
||||
|
||||
#endif /* HAL_EFL_LLD_H */
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue