Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements in flash driver #358

Merged
merged 6 commits into from
Jun 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,27 @@ typedef struct SMT32FlashDriver {
// From STMicroelectronics Cube HAL
#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != RESET)
#define FLASH_FLAG_BSY FLASH_SR_BSY // FLASH Busy flag

#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Operation flag */
#define FLASH_FLAG_OPERR FLASH_SR_SOP /*!< FLASH operation Error flag */
#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */
#define FLASH_FLAG_PGAERR FLASH_SR_PGAERR /*!< FLASH Programming Alignment error flag */
#define FLASH_FLAG_PGPERR FLASH_SR_PGPERR /*!< FLASH Programming Parallelism error flag */
#define FLASH_FLAG_PGSERR FLASH_SR_PGSERR /*!< FLASH Programming Sequence error flag */
#if defined(FLASH_SR_RDERR)
#define FLASH_FLAG_RDERR FLASH_SR_RDERR /*!< Read Protection error flag (PCROP) */
#endif /* FLASH_SR_RDERR */
#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */

// FLASH_Program_Parallelism FLASH Program Parallelism
#define FLASH_PSIZE_BYTE ((uint32_t)0x00000000U)
#define FLASH_PSIZE_HALF_WORD ((uint32_t)0x00000100U)
#define FLASH_PSIZE_WORD ((uint32_t)0x00000200U)
#define FLASH_PSIZE_DOUBLE_WORD ((uint32_t)0x00000300U)
#define CR_PSIZE_MASK ((uint32_t)0xFFFFFCFFU)

#define __HAL_FLASH_GET_FLAG(__FLAG__) ((FLASH->SR & (__FLAG__)))
#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) (FLASH->SR = (__FLAG__))

#define F0_SERIES_SECTOR_SIZE ((uint32_t)0x00001000U)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ SMT32FlashDriver STM32FLASH;
// Unlock the FLASH control register access
bool HAL_FLASH_Unlock(void)
{
if (HAL_IS_BIT_SET(FLASH->CR, FLASH_CR_LOCK))
if((FLASH->CR & FLASH_CR_LOCK) != RESET)
{
/* Authorize the FLASH Registers access */
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
// Authorize the FLASH Registers access
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
}
else
{
Expand All @@ -47,13 +47,61 @@ bool HAL_FLASH_Unlock(void)
}

// Locks the FLASH control register access
bool HAL_FLASH_Lock(void)
void HAL_FLASH_Lock(void)
{
/* Set the LOCK Bit to lock the FLASH Registers access */
SET_BIT(FLASH->CR, FLASH_CR_LOCK);
// Set the LOCK Bit to lock the FLASH Registers access
FLASH->CR |= FLASH_CR_LOCK;
}

bool FLASH_WaitForLastOperation()
{
// Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
// Even if the FLASH operation fails, the BUSY flag will be reset and an error
// flag will be set

while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET)
{
// TODO: add a timeout here using an OS function
__NOP();
}

// If there is no error flag set
return true;
}

#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) ||\
defined(STM32F469xx) || defined(STM32F479xx) ||\
defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F412Zx) ||\
defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\
defined(STM32F401xC) ||\
defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) ||\
defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx)

void FLASH_FlushCaches(void)
{
// Flush instruction cache
if(READ_BIT(FLASH->ACR, FLASH_ACR_ICEN)!= RESET)
{
// Disable instruction cache
__HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
// Reset instruction cache
__HAL_FLASH_INSTRUCTION_CACHE_RESET();
// Enable instruction cache
__HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
}

return true;
// Flush data cache
if(READ_BIT(FLASH->ACR, FLASH_ACR_DCEN) != RESET)
{
// Disable data cache
__HAL_FLASH_DATA_CACHE_DISABLE();
// Reset data cache
__HAL_FLASH_DATA_CACHE_RESET();
// Enable data cache
__HAL_FLASH_DATA_CACHE_ENABLE();
}
}
#endif // define STM32F4xxxx

///////////////////////////////////////////////////////////////////////////////
// Driver exported functions. //
Expand Down Expand Up @@ -83,6 +131,12 @@ bool flash_lld_write(uint32_t startAddress, uint32_t length, const uint8_t* buff
// unlock the FLASH
if(HAL_FLASH_Unlock())
{
// Clear pending flags (if any)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);

// clear the program size mask
CLEAR_BIT(FLASH->CR, CR_PSIZE_MASK);

// proceed to program the flash by setting the PG Bit
SET_BIT(FLASH->CR, FLASH_CR_PG);

Expand All @@ -92,6 +146,9 @@ bool flash_lld_write(uint32_t startAddress, uint32_t length, const uint8_t* buff
// NOTE: assuming that the supply voltage is able to cope with half-word programming
if((endAddress - cursor) >= 2)
{
// set the size of of the programming word to HALF WORD
SET_BIT(FLASH->CR, FLASH_PSIZE_HALF_WORD);

*((__IO uint16_t*)cursor++) = *((uint16_t*)buffer++);

// update flash and buffer pointers by the 'extra' byte that was programmed
Expand All @@ -100,24 +157,40 @@ bool flash_lld_write(uint32_t startAddress, uint32_t length, const uint8_t* buff
}
else
{
// program single byte
// program single byte

// clear the program size mask
CLEAR_BIT(FLASH->CR, CR_PSIZE_MASK);
// set the size of of the programming word to BYTE
SET_BIT(FLASH->CR, FLASH_PSIZE_BYTE);

*cursor = *buffer++;
}

// wait for program operation to be completed
// TODO: add a timeout here using an OS function
while(((FLASH->SR) & (FLASH_FLAG_BSY)) == (FLASH_FLAG_BSY)){};

// wait for any flash operation to be completed
if(!FLASH_WaitForLastOperation())
{
// lock the FLASH
HAL_FLASH_Lock();

return false;
}
}

// after the program operation is completed disable the PG Bit
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);

// lock the FLASH
if(HAL_FLASH_Lock())
HAL_FLASH_Lock();

// check for errors
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_ALL_ERRORS) != RESET)
{
// lock succesfull, done here
return true;
return false;
}

// done here
return true;
}

// default to false
Expand Down Expand Up @@ -164,43 +237,65 @@ uint8_t flash_lld_getSector(uint32_t address)
}

bool flash_lld_erase(uint32_t address) {

uint32_t tmp_psize = 0;

// unlock the FLASH
if(HAL_FLASH_Unlock())
{
// Clear pending flags (if any)
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);

// get the sector number to erase
uint8_t sectorNumber = flash_lld_getSector(address);

/* Need to add offset of 4 when sector higher than FLASH_SECTOR_11 */
// Need to add offset of 4 when sector higher than FLASH_SECTOR_11
if(sectorNumber > FLASH_SECTOR_11)
{
sectorNumber += 4U;
}

// erase the sector
// If the previous operation is completed, proceed to erase the sector
CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);

// set program size to half-word (16 bits) to be conservative
FLASH->CR |= FLASH_PSIZE_HALF_WORD;
SET_BIT(FLASH->CR, FLASH_PSIZE_HALF_WORD);
CLEAR_BIT(FLASH->CR, FLASH_CR_SNB);
FLASH->CR |= FLASH_CR_SER | (sectorNumber << POSITION_VAL(FLASH_CR_SNB));

// start erase operation
FLASH->CR |= FLASH_CR_STRT;

// wait for erase operation to be completed
// TODO: add a timeout here using an OS function
while(((FLASH->SR) & (FLASH_FLAG_BSY)) == (FLASH_FLAG_BSY)){};
if(FLASH_WaitForLastOperation())
{
// lock the FLASH anyways
HAL_FLASH_Lock();

return false;
}

// after erase operation completed disable the SER and SNB Bits
CLEAR_BIT(FLASH->CR, (FLASH_CR_SER | FLASH_CR_SNB));

#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) ||\
defined(STM32F469xx) || defined(STM32F479xx) ||\
defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F412Zx) ||\
defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\
defined(STM32F401xC) ||\
defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) ||\
defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx)

// Flush the caches to be sure of the data consistency
FLASH_FlushCaches();
#endif

// lock the FLASH
if(HAL_FLASH_Lock())
HAL_FLASH_Lock();

// check for errors
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_ALL_ERRORS) != RESET)
{
// lock succesfull, done here
return true;
return false;
}

// done here
return true;
}

// default to false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,64 @@ typedef struct SMT32FlashDriver {
// From STMicroelectronics Cube HAL
#define FLASH ((FLASH_TypeDef *) FLASH_R_BASE)
#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != RESET)
#define FLASH_FLAG_BSY FLASH_SR_BSY // FLASH Busy flag
#define FLASH_KEY1 ((uint32_t)0x45670123U)
#define FLASH_KEY2 ((uint32_t)0xCDEF89ABU)
#define FLASH_KEY1 ((uint32_t)0x45670123U)
#define FLASH_KEY2 ((uint32_t)0xCDEF89ABU)
#define SECTOR_MASK ((uint32_t)0xFFFFFF07)

//---------------------------------- STM32F4xx ------------------------------//
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) ||\
defined(STM32F469xx) || defined(STM32F479xx) ||\
defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F412Zx) ||\
defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\
defined(STM32F401xC) ||\
defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) ||\
defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx)

#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Operation flag */
#define FLASH_FLAG_OPERR FLASH_SR_SOP /*!< FLASH operation Error flag */
#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */
#define FLASH_FLAG_PGAERR FLASH_SR_PGAERR /*!< FLASH Programming Alignment error flag */
#define FLASH_FLAG_PGPERR FLASH_SR_PGPERR /*!< FLASH Programming Parallelism error flag */
#define FLASH_FLAG_PGSERR FLASH_SR_PGSERR /*!< FLASH Programming Sequence error flag */
#if defined(FLASH_SR_RDERR)
#define FLASH_FLAG_RDERR FLASH_SR_RDERR /*!< Read Protection error flag (PCROP) */
#endif /* FLASH_SR_RDERR */
#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */

#if defined(FLASH_SR_RDERR)
#define FLASH_FLAG_ALL_ERRORS (FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)

#else
#define FLASH_FLAG_ALL_ERRORS (FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR )

#endif // FLASH_SR_RDERR


//---------------------------------- STM32F7xx ------------------------------//
#elif defined(STM32F756xx) || defined(STM32F746xx) || defined(STM32F745xx) || defined(STM32F767xx) || \
defined(STM32F769xx) || defined(STM32F777xx) || defined(STM32F779xx) || defined(STM32F722xx) || \
defined(STM32F723xx) || defined(STM32F732xx) || defined(STM32F733xx)

#define FLASH_FLAG_EOP FLASH_SR_EOP /*!< FLASH End of Operation flag */
#define FLASH_FLAG_OPERR FLASH_SR_OPERR /*!< FLASH operation Error flag */
#define FLASH_FLAG_WRPERR FLASH_SR_WRPERR /*!< FLASH Write protected error flag */
#define FLASH_FLAG_PGAERR FLASH_SR_PGAERR /*!< FLASH Programming Alignment error flag */
#define FLASH_FLAG_PGPERR FLASH_SR_PGPERR /*!< FLASH Programming Parallelism error flag */
#define FLASH_FLAG_ERSERR FLASH_SR_ERSERR /*!< FLASH Erasing Sequence error flag */
#define FLASH_FLAG_BSY FLASH_SR_BSY /*!< FLASH Busy flag */

#if defined (FLASH_OPTCR2_PCROP)
#define FLASH_FLAG_RDERR FLASH_SR_RDERR /*!< FLASH Read protection error flag */
#define FLASH_FLAG_ALL_ERRORS (FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR | FLASH_FLAG_RDERR)
#else
#define FLASH_FLAG_ALL_ERRORS (FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR)
#endif /* FLASH_OPTCR2_PCROP */

#endif

// FLASH_Program_Parallelism FLASH Program Parallelism
#define FLASH_PSIZE_BYTE ((uint32_t)0x00000000U)
Expand All @@ -55,6 +110,9 @@ typedef struct SMT32FlashDriver {
#define FLASH_PSIZE_DOUBLE_WORD ((uint32_t)0x00000300U)
#define CR_PSIZE_MASK ((uint32_t)0xFFFFFCFFU)

#define __HAL_FLASH_GET_FLAG(__FLAG__) ((FLASH->SR & (__FLAG__)))
#define __HAL_FLASH_CLEAR_FLAG(__FLAG__) (FLASH->SR = (__FLAG__))

// FLASHEx_Sectors FLASH Sectors
/*-------------------------------------- STM32F42xxx/STM32F43xxx/STM32F469xx ------------------------------------*/
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx) ||\
Expand Down Expand Up @@ -168,6 +226,18 @@ typedef struct SMT32FlashDriver {

#endif // efined(STM32F756xx) || defined(STM32F746xx) || defined(STM32F745xx) || defined(STM32F767xx) || .... etc

#define __HAL_FLASH_INSTRUCTION_CACHE_ENABLE() (FLASH->ACR |= FLASH_ACR_ICEN)
#define __HAL_FLASH_INSTRUCTION_CACHE_DISABLE() (FLASH->ACR &= (~FLASH_ACR_ICEN))

#define __HAL_FLASH_DATA_CACHE_DISABLE() (FLASH->ACR &= (~FLASH_ACR_DCEN))
#define __HAL_FLASH_DATA_CACHE_ENABLE() (FLASH->ACR |= FLASH_ACR_DCEN)
#define __HAL_FLASH_INSTRUCTION_CACHE_RESET() do {FLASH->ACR |= FLASH_ACR_ICRST; \
FLASH->ACR &= ~FLASH_ACR_ICRST; \
}while(0U)
#define __HAL_FLASH_DATA_CACHE_RESET() do {FLASH->ACR |= FLASH_ACR_DCRST; \
FLASH->ACR &= ~FLASH_ACR_DCRST; \
}while(0U)

///////////////////////////////////////////////////////////////////////////////
// External declarations. //
///////////////////////////////////////////////////////////////////////////////
Expand Down