arch/arm/stm32h7: multiple fixes for stm32h7 flash interface

Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
Petro Karashchenko 2022-10-23 22:33:03 +02:00 committed by David Sidrane
parent 1feb0e759d
commit 4c71075ea5
2 changed files with 59 additions and 85 deletions

View File

@ -152,7 +152,7 @@
#define FLASH_OPTKEY1 0x08192a3b
#define FLASH_OPTKEY2 0x4c5d6e7f
#define FLASH_ERASEDVALUE 0xffu
#define FLASH_ERASEDVALUE_DW 0xffffffff
#define FLASH_ERASEDVALUE_DW 0xffffffffu
#define PROGMEM_NBLOCKS STM32_FLASH_NBLOCKS
#define FLASH_NPAGES (STM32_FLASH_SIZE / FLASH_PAGE_SIZE)
@ -186,11 +186,11 @@ static struct stm32h7_flash_priv_s stm32h7_flash_bank1_priv =
#if STM32_DUAL_BANK
static struct stm32h7_flash_priv_s stm32h7_flash_bank2_priv =
{
.lock = NXMUTEX_INITIALIZER,
.ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET,
.base = STM32_FLASH_BANK2,
.lock = NXMUTEX_INITIALIZER,
.ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET,
.base = STM32_FLASH_BANK2,
.stblock = PROGMEM_NBLOCKS / 2,
.stpage = FLASH_NPAGES / 2,
.stpage = FLASH_NPAGES / 2,
};
#endif
@ -363,7 +363,7 @@ static int stm32h7_israngeerased(size_t startaddress, size_t size)
count += 4;
}
baddr = (uint8_t *)startaddress;
baddr = (uint8_t *)addr;
while (count < size)
{
if (getreg8(baddr) != FLASH_ERASEDVALUE)
@ -407,7 +407,7 @@ static int stm32h7_wait_for_last_operation(struct stm32h7_flash_priv_s
for (i = 0; i < FLASH_TIMEOUT_VALUE; i++)
{
if (!(stm32h7_flash_getreg32(priv, STM32_FLASH_SR1_OFFSET) &
(FLASH_SR_QW | FLASH_SR_BSY | FLASH_SR_WBNE)))
(FLASH_SR_QW | FLASH_SR_BSY | FLASH_SR_WBNE)))
{
timeout = false;
break;
@ -796,8 +796,11 @@ ssize_t up_progmem_eraseblock(size_t block)
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SER, 0);
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, FLASH_CR_SNB_MASK,
0);
ret = 0;
up_invalidate_dcache(block_address, block_address + FLASH_SECTOR_SIZE);
exit_with_unlock:
stm32h7_lock_flash(priv);
@ -824,14 +827,14 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
struct stm32h7_flash_priv_s *priv;
uint32_t *fp;
uint32_t *rp;
uint32_t *ll = (uint32_t *) buf;
uint32_t *ll = (uint32_t *)buf;
size_t faddr;
size_t written = count;
int ret;
int ret;
const size_t pagesize = up_progmem_pagesize(0); /* 256 bit, 32 bytes per page */
const size_t llperpage = pagesize / sizeof(uint32_t);
size_t pcount = count / pagesize;
uint32_t sr;
uint32_t sr;
priv = stm32h7_flash_bank(addr);
@ -874,10 +877,10 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR1_OFFSET, 0, FLASH_CR_PG);
for (ll = (uint32_t *) buf, faddr = addr; pcount;
for (ll = (uint32_t *)buf, faddr = addr; pcount;
pcount -= 1, ll += llperpage, faddr += pagesize)
{
fp = (uint32_t *) faddr;
fp = (uint32_t *)faddr;
rp = ll;
ARM_DSB();
@ -933,10 +936,10 @@ exit_with_unlock:
if (written > 0)
{
for (ll = (uint32_t *) buf, faddr = addr, pcount = count / pagesize;
for (ll = (uint32_t *)buf, faddr = addr, pcount = count / pagesize;
pcount; pcount -= 1, ll += llperpage, faddr += pagesize)
{
fp = (uint32_t *) faddr;
fp = (uint32_t *)faddr;
rp = ll;
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR1_OFFSET,
@ -975,4 +978,3 @@ uint8_t up_progmem_erasestate(void)
{
return FLASH_ERASEDVALUE;
}

View File

@ -58,7 +58,7 @@
#include <nuttx/config.h>
#include <nuttx/arch.h>
#include <nuttx/semaphore.h>
#include <nuttx/mutex.h>
#include <stdbool.h>
#include <assert.h>
@ -135,7 +135,7 @@
#define FLASH_OPTKEY1 0x08192a3b
#define FLASH_OPTKEY2 0x4c5d6e7f
#define FLASH_ERASEDVALUE 0xffu
#define FLASH_ERASEDVALUE_DW 0xffffffff
#define FLASH_ERASEDVALUE_DW 0xffffffffu
#define PROGMEM_NBLOCKS STM32_FLASH_NBLOCKS
#define FLASH_NPAGES (STM32_FLASH_SIZE / FLASH_PAGE_SIZE)
@ -147,7 +147,7 @@
struct stm32h7_flash_priv_s
{
sem_t sem; /* Bank exclusive */
mutex_t lock; /* Bank exclusive */
uint32_t ifbase; /* FLASHIF interface base address */
uint32_t base; /* FLASH base address */
uint32_t stblock; /* The first Block Number */
@ -160,7 +160,7 @@ struct stm32h7_flash_priv_s
static struct stm32h7_flash_priv_s stm32h7_flash_bank1_priv =
{
.sem = SEM_INITIALIZER(1),
.lock = NXMUTEX_INITIALIZER,
.ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK1_OFFSET,
.base = STM32_FLASH_BANK1,
.stblock = 0,
@ -169,11 +169,11 @@ static struct stm32h7_flash_priv_s stm32h7_flash_bank1_priv =
#if STM32_FLASH_NBLOCKS > 1
static struct stm32h7_flash_priv_s stm32h7_flash_bank2_priv =
{
.sem = SEM_INITIALIZER(1),
.ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET,
.base = STM32_FLASH_BANK2,
.lock = NXMUTEX_INITIALIZER,
.ifbase = STM32_FLASHIF_BASE + STM32_FLASH_BANK2_OFFSET,
.base = STM32_FLASH_BANK2,
.stblock = PROGMEM_NBLOCKS / 2,
.stpage = FLASH_NPAGES / 2,
.stpage = FLASH_NPAGES / 2,
};
#endif
@ -226,33 +226,6 @@ static inline void stm32h7_flash_modifyreg32(struct stm32h7_flash_priv_s
modifyreg32(priv->ifbase + offset, clearbits, setbits);
}
/****************************************************************************
* Name: stm32h7_flash_sem_lock
*
* Description:
* Take the Bank exclusive access semaphore
*
****************************************************************************/
static int stm32h7_flash_sem_lock(struct stm32h7_flash_priv_s *priv)
{
return nxsem_wait_uninterruptible(&priv->sem);
}
/****************************************************************************
* Name: stm32h7_flash_sem_unlock
*
* Description:
* Release the Bank exclusive access semaphore
*
****************************************************************************/
static inline void stm32h7_flash_sem_unlock(struct stm32h7_flash_priv_s
*priv)
{
nxsem_post(&priv->sem);
}
/****************************************************************************
* Name: stm32h7_unlock_flash
*
@ -347,7 +320,7 @@ static int stm32h7_israngeerased(size_t startaddress, size_t size)
size_t bwritten = 0;
if (!stm32h7_flash_bank(startaddress) ||
!stm32h7_flash_bank(startaddress + size))
!stm32h7_flash_bank(startaddress + size - 1))
{
return -EIO;
}
@ -372,6 +345,7 @@ static int stm32h7_israngeerased(size_t startaddress, size_t size)
bwritten++;
}
baddr++;
count++;
}
@ -397,7 +371,7 @@ static int stm32h7_israngeerased(size_t startaddress, size_t size)
****************************************************************************/
static int stm32h7_wait_for_last_operation(struct stm32h7_flash_priv_s
*priv)
*priv)
{
int i;
bool timeout = true;
@ -413,7 +387,7 @@ static int stm32h7_wait_for_last_operation(struct stm32h7_flash_priv_s
break;
}
up_udelay(1);
up_udelay(1);
}
if (timeout)
@ -524,14 +498,14 @@ int stm32h7_flash_unlock(size_t addr)
if (priv)
{
ret = stm32h7_flash_sem_lock(priv);
ret = nxmutex_lock(&priv->lock);
if (ret < 0)
{
return ret;
}
stm32h7_unlock_flash(priv);
stm32h7_flash_sem_unlock(priv);
nxmutex_unlock(&priv->lock);
}
return ret;
@ -552,14 +526,14 @@ int stm32h7_flash_lock(size_t addr)
if (priv)
{
ret = stm32h7_flash_sem_lock(priv);
ret = nxmutex_lock(&priv->lock);
if (ret < 0)
{
return ret;
}
stm32h7_lock_flash(priv);
stm32h7_flash_sem_unlock(priv);
nxmutex_unlock(&priv->lock);
}
return ret;
@ -759,19 +733,16 @@ ssize_t up_progmem_eraseblock(size_t block)
priv = stm32h7_flash_bank(block_address);
ret = stm32h7_flash_sem_lock(priv);
ret = nxmutex_lock(&priv->lock);
if (ret < 0)
{
return (ssize_t)ret;
}
up_invalidate_dcache((uintptr_t)block_address,
(uintptr_t)(block_address + FLASH_SECTOR_SIZE - 1));
if (stm32h7_wait_for_last_operation(priv))
{
ret = -EIO;
goto exit_with_sem;
goto exit_with_lock;
}
/* Get flash ready and begin erasing single block */
@ -783,28 +754,29 @@ ssize_t up_progmem_eraseblock(size_t block)
FLASH_CR_SSN(block - priv->stblock));
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET,
0, FLASH_CR_SER | FLASH_CR_START);
0, FLASH_CR_SER | FLASH_CR_START);
/* Wait for erase operation to complete */
if (stm32h7_wait_for_last_operation(priv))
{
ret = -EIO;
goto exit_with_lock_sem;
goto exit_with_unlock;
}
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET,
FLASH_CR_SER, 0);
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET,
FLASH_CR_SSN_MASK, 0);
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, FLASH_CR_SER, 0);
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, FLASH_CR_SSN_MASK,
0);
ret = 0;
exit_with_lock_sem:
up_invalidate_dcache(block_address, block_address + FLASH_SECTOR_SIZE);
exit_with_unlock:
stm32h7_lock_flash(priv);
exit_with_sem:
stm32h7_flash_sem_unlock(priv);
exit_with_lock:
nxmutex_unlock(&priv->lock);
/* Verify */
@ -826,14 +798,14 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
struct stm32h7_flash_priv_s *priv;
uint32_t *fp;
uint32_t *rp;
uint32_t *ll = (uint32_t *) buf;
uint32_t *ll = (uint32_t *)buf;
size_t faddr;
size_t written = count;
int ret;
int ret;
const size_t pagesize = 16; /* 128 bit, 16 bytes per page */
const size_t llperpage = pagesize / sizeof(uint32_t);
size_t pcount = count / pagesize;
uint32_t sr;
uint32_t sr;
priv = stm32h7_flash_bank(addr);
@ -850,7 +822,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
return -EFAULT;
}
ret = stm32h7_flash_sem_lock(priv);
ret = nxmutex_lock(&priv->lock);
if (ret < 0)
{
return (ssize_t)ret;
@ -864,7 +836,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
if (stm32h7_wait_for_last_operation(priv))
{
written = -EIO;
goto exit_with_sem;
goto exit_with_lock;
}
/* Get flash ready and begin flashing */
@ -873,10 +845,10 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CR_OFFSET, 0, FLASH_CR_PG);
for (ll = (uint32_t *) buf, faddr = addr; pcount;
for (ll = (uint32_t *)buf, faddr = addr; pcount;
pcount -= 1, ll += llperpage, faddr += pagesize)
{
fp = (uint32_t *) faddr;
fp = (uint32_t *)faddr;
rp = ll;
ARM_DSB();
@ -900,7 +872,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
if (stm32h7_wait_for_last_operation(priv))
{
written = -EIO;
goto exit_with_lock_sem;
goto exit_with_unlock;
}
sr = stm32h7_flash_getreg32(priv, STM32_FLASH_SR_OFFSET);
@ -913,7 +885,7 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR_OFFSET,
0, ~0);
ret = -EIO;
goto exit_with_lock_sem;
goto exit_with_unlock;
}
}
@ -921,17 +893,17 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count)
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR_OFFSET,
0, ~0);
exit_with_lock_sem:
exit_with_unlock:
stm32h7_lock_flash(priv);
/* Verify */
if (written > 0)
{
for (ll = (uint32_t *) buf, faddr = addr, pcount = count / pagesize;
for (ll = (uint32_t *)buf, faddr = addr, pcount = count / pagesize;
pcount; pcount -= 1, ll += llperpage, faddr += pagesize)
{
fp = (uint32_t *) faddr;
fp = (uint32_t *)faddr;
rp = ll;
stm32h7_flash_modifyreg32(priv, STM32_FLASH_CCR_OFFSET,
@ -957,8 +929,8 @@ exit_with_lock_sem:
0, ~0);
}
exit_with_sem:
stm32h7_flash_sem_unlock(priv);
exit_with_lock:
nxmutex_unlock(&priv->lock);
return written;
}