Implemente support for STM32 F1 banked FLASH
Squashed commit of the following: arch/arm/src/stm32/stm32f10xxf30xx_flash.c: Re-implemented Dmitriy Linikov's change to support multi-banked FLASH on the STM32 F1 parts AFTER separating the FLASH support by architecture and implementing more standard base+offset register addressing. Now the change goes in rather cleanly. arch/arm/src/stm32/stm32f10xxf30xx_flash.c: Use base + offset address to simplify implementation of dual bank flash.
This commit is contained in:
parent
fb07bd7e27
commit
6fd4caf00f
@ -67,11 +67,16 @@
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
#define FLASH_KEY1 0x45670123
|
||||
#define FLASH_KEY2 0xcdef89ab
|
||||
#define FLASH_OPTKEY1 0x08192a3b
|
||||
#define FLASH_OPTKEY2 0x4c5d6e7f
|
||||
#define FLASH_ERASEDVALUE 0xff
|
||||
#define FLASH_KEY1 0x45670123
|
||||
#define FLASH_KEY2 0xcdef89ab
|
||||
#define FLASH_OPTKEY1 0x08192a3b
|
||||
#define FLASH_OPTKEY2 0x4c5d6e7f
|
||||
#define FLASH_ERASEDVALUE 0xff
|
||||
|
||||
#if !defined(STM32_FLASH_DUAL_BANK)
|
||||
# define STM32_FLASH_BANK0_NPAGES STM32_FLASH_NPAGES
|
||||
# define STM32_FLASH_BANK0_BASE STM32_FLASH_BASE
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Private Data
|
||||
@ -107,25 +112,25 @@ static inline void sem_unlock(void)
|
||||
nxsem_post(&g_sem);
|
||||
}
|
||||
|
||||
static void flash_unlock(void)
|
||||
static void flash_unlock(uintptr_t base)
|
||||
{
|
||||
while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY)
|
||||
while ((getreg32(base + STM32_FLASH_SR_OFFSET) & FLASH_SR_BSY) != 0)
|
||||
{
|
||||
up_waste();
|
||||
}
|
||||
|
||||
if (getreg32(STM32_FLASH_CR) & FLASH_CR_LOCK)
|
||||
if ((getreg32(base + STM32_FLASH_CR_OFFSET) & FLASH_CR_LOCK) != 0)
|
||||
{
|
||||
/* Unlock sequence */
|
||||
|
||||
putreg32(FLASH_KEY1, STM32_FLASH_KEYR);
|
||||
putreg32(FLASH_KEY2, STM32_FLASH_KEYR);
|
||||
putreg32(FLASH_KEY1, base + STM32_FLASH_KEYR_OFFSET);
|
||||
putreg32(FLASH_KEY2, base + STM32_FLASH_KEYR_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
static void flash_lock(void)
|
||||
static void flash_lock(uintptr_t base)
|
||||
{
|
||||
modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_LOCK);
|
||||
modifyreg32(base + STM32_FLASH_CR_OFFSET, 0, FLASH_CR_LOCK);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
@ -135,14 +140,20 @@ static void flash_lock(void)
|
||||
void stm32_flash_unlock(void)
|
||||
{
|
||||
sem_lock();
|
||||
flash_unlock();
|
||||
flash_unlock(STM32_FLASH_BANK0_BASE);
|
||||
#if defined(STM32_FLASH_DUAL_BANK)
|
||||
flash_unlock(STM32_FLASH_BANK1_BASE);
|
||||
#endif
|
||||
sem_unlock();
|
||||
}
|
||||
|
||||
void stm32_flash_lock(void)
|
||||
{
|
||||
sem_lock();
|
||||
flash_lock();
|
||||
flash_lock(STM32_FLASH_BANK0_BASE);
|
||||
#if defined(STM32_FLASH_DUAL_BANK)
|
||||
flash_lock(STM32_FLASH_BANK1_BASE);
|
||||
#endif
|
||||
sem_unlock();
|
||||
}
|
||||
|
||||
@ -222,6 +233,7 @@ ssize_t up_progmem_ispageerased(size_t page)
|
||||
|
||||
ssize_t up_progmem_erasepage(size_t page)
|
||||
{
|
||||
uintptr_t base;
|
||||
size_t page_address;
|
||||
|
||||
if (page >= STM32_FLASH_NPAGES)
|
||||
@ -229,9 +241,24 @@ ssize_t up_progmem_erasepage(size_t page)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
#if defined(STM32_FLASH_DUAL_BANK)
|
||||
/* Handle paged FLASH */
|
||||
|
||||
if (page >= STM32_FLASH_BANK0_NPAGES)
|
||||
{
|
||||
base = STM32_FLASH_BANK1_BASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = STM32_FLASH_BANK0_BASE;
|
||||
}
|
||||
#else
|
||||
base = STM32_FLASH_BANK0_BASE;
|
||||
#endif
|
||||
|
||||
sem_lock();
|
||||
|
||||
if (!(getreg32(STM32_RCC_CR) & RCC_CR_HSION))
|
||||
if ((getreg32(base + STM32_RCC_CR_OFFSET) & RCC_CR_HSION) == 0)
|
||||
{
|
||||
sem_unlock();
|
||||
return -EPERM;
|
||||
@ -239,20 +266,23 @@ ssize_t up_progmem_erasepage(size_t page)
|
||||
|
||||
/* Get flash ready and begin erasing single page */
|
||||
|
||||
flash_unlock();
|
||||
flash_unlock(base);
|
||||
|
||||
modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PER);
|
||||
modifyreg32(base + STM32_FLASH_CR_OFFSET, 0, FLASH_CR_PER);
|
||||
|
||||
/* Must be valid - page index checked above */
|
||||
|
||||
page_address = up_progmem_getaddress(page);
|
||||
putreg32(page_address, STM32_FLASH_AR);
|
||||
putreg32(page_address, base + STM32_FLASH_AR_OFFSET);
|
||||
|
||||
modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_STRT);
|
||||
modifyreg32(base + STM32_FLASH_CR_OFFSET, 0, FLASH_CR_STRT);
|
||||
|
||||
while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste();
|
||||
while ((getreg32(base + STM32_FLASH_SR_OFFSET) & FLASH_SR_BSY) != 0)
|
||||
{
|
||||
up_waste();
|
||||
}
|
||||
|
||||
modifyreg32(STM32_FLASH_CR, FLASH_CR_PER, 0);
|
||||
modifyreg32(base + STM32_FLASH_CR_OFFSET, FLASH_CR_PER, 0);
|
||||
sem_unlock();
|
||||
|
||||
/* Verify */
|
||||
@ -269,9 +299,25 @@ ssize_t up_progmem_erasepage(size_t page)
|
||||
|
||||
ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
|
||||
{
|
||||
uintptr_t base;
|
||||
uint16_t *hword = (uint16_t *)buf;
|
||||
size_t written = count;
|
||||
|
||||
#if defined(STM32_FLASH_DUAL_BANK)
|
||||
/* Handle paged FLASH */
|
||||
|
||||
if (page >= STM32_FLASH_BANK0_NPAGES)
|
||||
{
|
||||
base = STM32_FLASH_BANK1_BASE;
|
||||
}
|
||||
else
|
||||
{
|
||||
base = STM32_FLASH_BANK0_BASE;
|
||||
}
|
||||
#else
|
||||
base = STM32_FLASH_BANK0_BASE;
|
||||
#endif
|
||||
|
||||
/* STM32 requires half-word access */
|
||||
|
||||
if (count & 1)
|
||||
@ -293,7 +339,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
|
||||
|
||||
sem_lock();
|
||||
|
||||
if (!(getreg32(STM32_RCC_CR) & RCC_CR_HSION))
|
||||
if ((getreg32(base + STM32_RCC_CR_OFFSET) & RCC_CR_HSION) == 0)
|
||||
{
|
||||
sem_unlock();
|
||||
return -EPERM;
|
||||
@ -301,9 +347,9 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
|
||||
|
||||
/* Get flash ready and begin flashing */
|
||||
|
||||
flash_unlock();
|
||||
flash_unlock(base);
|
||||
|
||||
modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PG);
|
||||
modifyreg32(base + STM32_FLASH_CR_OFFSET, 0, FLASH_CR_PG);
|
||||
|
||||
for (addr += STM32_FLASH_BASE; count; count -= 2, hword++, addr += 2)
|
||||
{
|
||||
@ -311,26 +357,29 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
|
||||
|
||||
putreg16(*hword, addr);
|
||||
|
||||
while (getreg32(STM32_FLASH_SR) & FLASH_SR_BSY) up_waste();
|
||||
while ((getreg32(base + STM32_FLASH_SR_OFFSET) & FLASH_SR_BSY) != 0)
|
||||
{
|
||||
up_waste();
|
||||
}
|
||||
|
||||
/* Verify */
|
||||
|
||||
if (getreg32(STM32_FLASH_SR) & FLASH_SR_WRPRT_ERR)
|
||||
if ((getreg32(base + STM32_FLASH_SR_OFFSET) & FLASH_SR_WRPRT_ERR) != 0)
|
||||
{
|
||||
modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0);
|
||||
modifyreg32(base + STM32_FLASH_CR_OFFSET, FLASH_CR_PG, 0);
|
||||
sem_unlock();
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
if (getreg16(addr) != *hword)
|
||||
{
|
||||
modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0);
|
||||
modifyreg32(base + STM32_FLASH_CR_OFFSET, FLASH_CR_PG, 0);
|
||||
sem_unlock();
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0);
|
||||
modifyreg32(base + STM32_FLASH_CR_OFFSET, FLASH_CR_PG, 0);
|
||||
|
||||
sem_unlock();
|
||||
return written;
|
||||
|
Loading…
Reference in New Issue
Block a user