arch/arm/stm32h7: multiple fixes for stm32h7 flash interface
Signed-off-by: Petro Karashchenko <petro.karashchenko@gmail.com>
This commit is contained in:
parent
1feb0e759d
commit
4c71075ea5
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user