一、stm32H7 HAL库操作内部Flash BANK2读写不正常
超过1M写道bank2(0x08100000) 后面的内容不正常
HAL_FLASH_Program函数 返回错误 由于用的旧版本HAL库
看到安富莱贴子中关于旧版HAL BUG的问题参考新版HAL做了更改后仍然出现错误 不能正常写
决定采用寄存器方式写 不用HAL库 便将正点原子的寄存器版本中的STMFLASH_Write8Word
底层函数移植过来 问题解决
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint64_t DataAddress)
{
HAL_StatusTypeDef status = HAL_ERROR;
__IO uint64_t *dest_addr = (__IO uint64_t *)FlashAddress;
__IO uint64_t *src_addr = (__IO uint64_t*)((uint32_t)DataAddress);
uint32_t bank;
uint8_t row_index = 4;
/* Process Locked */
__HAL_LOCK(&pFlash);
/* Check the parameters */
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
{
bank = FLASH_BANK_1;
}
else
{
bank = FLASH_BANK_2;
}
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
if(status == HAL_OK)
{
if(bank == FLASH_BANK_1)
{
/* Clear bank 1 pending flags (if any) */
__HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1 | FLASH_FLAG_QW_BANK1 | FLASH_FLAG_WBNE_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK1);
/* Set PG bit */
SET_BIT(FLASH->CR1, FLASH_CR_PG);
}
else
{
/* Clear bank 2 pending flags (if any) */
__HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2 | FLASH_FLAG_QW_BANK2 | FLASH_FLAG_WBNE_BANK2 | FLASH_FLAG_ALL_ERRORS_BANK2);
/* Set PG bit */
SET_BIT(FLASH->CR2, FLASH_CR_PG);
}
__ISB();
__DSB();
/* Program the 256 bits flash word */
#if 0
do
{
*dest_addr++ = *src_addr++;
} while (--row_index != 0);
#else
do
{
*dest_addr = *src_addr;
dest_addr++;
src_addr++;
row_index--;
} while (row_index != 0U);
#endif
__ISB();
__DSB();
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
if(bank == FLASH_BANK_1)
{
/* Check FLASH End of Operation flag */
if (__HAL_FLASH_GET_FLAG_BANK1(FLASH_FLAG_EOP_BANK1))
{
/* Clear FLASH End of Operation pending bit */
__HAL_FLASH_CLEAR_FLAG_BANK1(FLASH_FLAG_EOP_BANK1);
}
/* If the program operation is completed, disable the PG*/
CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
}
else
{
/* Check FLASH End of Operation flag */
if (__HAL_FLASH_GET_FLAG_BANK2(FLASH_FLAG_EOP_BANK2))
{
/* Clear FLASH End of Operation pending bit */
__HAL_FLASH_CLEAR_FLAG_BANK2(FLASH_FLAG_EOP_BANK2);
}
/* If the program operation is completed, disable the PG */
CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
}
}
/* Process Unlocked */
__HAL_UNLOCK(&pFlash);
return status;
}
u8 STMFLASH_Write8Word(u32 faddr, u32* pdata)
{
u8 nword=8; //每次写8个字,256bit
u8 res;
u8 bankx=0;
if(faddr<BANK2_FLASH_SECTOR_0)bankx=0; //判断地址是在bank0,还是在bank1
else bankx=1;
res=STMFLASH_WaitDone(bankx,0XFF);
if(res==0) //OK
{
if(bankx==0) //BANK1 编程
{
FLASH->CR1&=~(3<<4); //PSIZE1[1:0]=0,清除原来的设置
FLASH->CR1|=2<<4; //设置为32bit宽
FLASH->CR1|=1<<1; //PG1=1,编程使能
}else //BANK2 编程
{
FLASH->CR2&=~(3<<4); //PSIZE2[1:0]=0,清除原来的设置
FLASH->CR2|=2<<4; //设置为32bit宽
FLASH->CR2|=1<<1; //PG2=1,编程使能
}
while(nword)
{
*(vu32*)faddr=*pdata; //写入数据
faddr+=4; //写地址+4
pdata++; //偏移到下一个数据首地址
nword--;
}
__DSB(); //写操作完成后,屏蔽数据同步,使CPU重新执行指令序列
res=STMFLASH_WaitDone(bankx,0XFF); //等待操作完成,一个字编程,最多100us.
if(bankx==0)FLASH->CR1&=~(1<<1);//PG1=0,清除扇区擦除标志
else FLASH->CR2&=~(1<<1); //PG2=0,清除扇区擦除标志
}
return res;
}