eeprom_stm32: add stm32f4 series support

based on code by @yulei in https://github.com/qmk/qmk_firmware/pull/7803
This commit is contained in:
Ilya Zhuravlev
2021-07-11 19:20:41 -04:00
parent ae1d581ca7
commit 1ba3126ae4
5 changed files with 76 additions and 25 deletions

View File

@ -16,28 +16,24 @@
* Modifications for QMK and STM32F303 by Yiancar
*/
#if defined(EEPROM_EMU_STM32F303xC)
# define STM32F303xC
# include "stm32f3xx.h"
#elif defined(EEPROM_EMU_STM32F103xB)
# define STM32F103xB
# include "stm32f1xx.h"
#elif defined(EEPROM_EMU_STM32F072xB)
# define STM32F072xB
# include "stm32f0xx.h"
#elif defined(EEPROM_EMU_STM32F042x6)
# define STM32F042x6
# include "stm32f0xx.h"
#else
# error "not implemented."
#endif
#include "flash_stm32.h"
#if defined(EEPROM_EMU_STM32F103xB)
# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
#endif
#if defined(EEPROM_EMU_STM32F4)
# define FLASH_PSIZE_HFWORD FLASH_CR_PSIZE_0
# define FLASH_PSIZE_WORD FLASH_CR_PSIZE_1
# define FLASH_CR_SNB_POS 3
/* the flash key was not defined in the CMSIS used by current chibios */
# define FLASH_KEY1 0x45670123
# define FLASH_KEY2 0xCDEF89AB
# define FLASH_SR_FLAGS (FLASH_SR_PGAERR|FLASH_SR_PGPERR|FLASH_SR_PGSERR|FLASH_SR_WRPERR)
#else
# define FLASH_SR_FLAGS (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR)
#endif
/* Delay definition */
#define EraseTimeout ((uint32_t)0x00000FFF)
#define ProgramTimeout ((uint32_t)0x0000001F)
@ -64,11 +60,14 @@ static void delay(void) {
FLASH_Status FLASH_GetStatus(void) {
if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY) return FLASH_BUSY;
#if defined(EEPROM_EMU_STM32F4)
if ((FLASH->SR & (FLASH_SR_PGSERR | FLASH_SR_PGPERR | FLASH_SR_PGAERR))) return FLASH_ERROR_PG;
if ((FLASH->SR & FLASH_SR_WRPERR)) return FLASH_ERROR_WRP;
#else
if ((FLASH->SR & FLASH_SR_PGERR) != 0) return FLASH_ERROR_PG;
if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP;
if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT;
#endif
return FLASH_COMPLETE;
}
@ -97,30 +96,41 @@ FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) {
/**
* @brief Erases a specified FLASH page.
* @param Page_Address: The page address to be erased.
* @param Page_Address: The page address or sector to be erased.
* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {
FLASH_Status status = FLASH_COMPLETE;
#ifndef EEPROM_EMU_STM32F4
/* Check the parameters */
ASSERT(IS_FLASH_ADDRESS(Page_Address));
#endif
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout);
if (status == FLASH_COMPLETE) {
/* if the previous operation is completed, proceed to erase the page */
#if defined(EEPROM_EMU_STM32F4)
FLASH->CR &= ~FLASH_CR_SNB;
FLASH->CR |= FLASH_CR_SER | (Page_Address << FLASH_CR_SNB_POS);
#else
FLASH->CR |= FLASH_CR_PER;
FLASH->AR = Page_Address;
#endif
FLASH->CR |= FLASH_CR_STRT;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout);
if (status != FLASH_TIMEOUT) {
/* if the erase operation is completed, disable the PER Bit */
/* clear the SER or PER Bit */
#if defined(EEPROM_EMU_STM32F4)
FLASH->CR &= ~(FLASH_CR_SER | FLASH_CR_SNB);
#else
FLASH->CR &= ~FLASH_CR_PER;
#endif
}
FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
FLASH_ClearFlag(FLASH_SR_FLAGS);
}
/* Return the Erase Status */
return status;
@ -136,11 +146,15 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {
FLASH_Status status = FLASH_BAD_ADDRESS;
if (IS_FLASH_ADDRESS(Address)) {
if (IS_FLASH_ADDRESS(Address) && (Address % sizeof(Data)) == 0) {
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
if (status == FLASH_COMPLETE) {
/* if the previous operation is completed, proceed to program the new data */
#if defined(EEPROM_EMU_STM32F4)
FLASH->CR &= ~FLASH_CR_PSIZE;
FLASH->CR |= FLASH_PSIZE_HFWORD;
#endif
FLASH->CR |= FLASH_CR_PG;
*(__IO uint16_t*)Address = Data;
/* Wait for last operation to be completed */
@ -149,7 +163,7 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {
/* if the program operation is completed, disable the PG Bit */
FLASH->CR &= ~FLASH_CR_PG;
}
FLASH->SR = (FLASH_SR_EOP | FLASH_SR_PGERR | FLASH_SR_WRPERR);
FLASH_ClearFlag(FLASH_SR_FLAGS);
}
}
return status;