1.前言
TC4系列的flash性能肯定是优于TC3的,但是在DFlash/Pflash的操作接口上差别不是很大。对于DFlash的擦除、写入,以及读取,往往使用Mcal中的Fls和Fee模块。也可以基于官方提供的ILLD库实现简单的地址擦写。ILLD提供的驱动,如果写入较多page,往往需要循环写入多个命令+等待才能完成。如果用户想要实现异步(非阻塞)的Dflash擦写,可以实现类似Mcal中Mainfunction的形式来周期执行,也可以像本文一样采用中断的方式。
2.Dfash擦除/写入限制
- Dflash的page大小为8 Bytes,单次执行写入(载入)只能为1个page(write page)或者4个page(write burst)。


- 写Dflash的起始地址必须为页大小(8 byte)的整数倍。
- Dflash的sector大小为2048 Bytes。单次擦除的起始地址必须为sector大小的整数倍。
- 单次擦除的长度最大为256K Bytes。

3.Dfash指令序列分析
3.1 读取
读取的实现较为简单,直接取(uint32*)地址读取就可以。
3.2 写入

结合手册和ILLD中的demo,操作如下:
- 进入page mode,等待page mode进入完成或进入出错
IfxFlash_enterPageMode(Addr);
while(FALSE == IfxFlash_isDflashInPageMode() &&
MODULE_DMU.HCI.ERR.B.SQER == 0 &&
MODULE_DMU.HCI.ERR.B.PROER == 0 ){}
- 清除flag
IfxFlash_clearStatus(FLASH_MODULE);
- 载入并写入数据。如果是写page,需要载入一次两个32 bit的数据。如果是burst写,需要载入四次,每次两个32 bit的数据。载入完成后,调用writePage或writeBurst指令。
Uint32 Index = 0u;
for(Index = 0u; (Index < Len/2u ); Index++)
{
__dsync();
IfxFlash_loadPage2X32(pageAddr , Data[Index*2u] , Data[Index*2u+1]); /* Load two words of 32 bits each */
}
IfxFlash_clearStatus(FLASH_MODULE);/* Clear flags */
if(Len == 2u)
{
IfxFlash_writePage(pageAddr); /* Write the page */
}
else
{
IfxFlash_writeBurst(pageAddr); /* Write the pages */
}
- 等待写入完成
while(FALSE == IfxFlash_isRequestExecuted())
{}
/* Clear flags */
IfxFlash_clearStatus(FLASH_MODULE);
3.3 擦除

步骤如下:
- 进入read模式
/* Reset the addressed command sequence interpreter */
IfxFlash_resetToRead(FLASH_MODULE);
- 清除Flag
- 调用擦除指令擦除一个或多个sector
IfxFlash_eraseMultipleSectors(Addr, (Len * 4u)/ DFLASH_LOG_SECTOR_LENGTH);
- 等待指令执行完成,再次清除Flag
4.实现异步操作思路
可以看出无论读取、写入、还是擦除的指令操作还是不复杂的,基本上按照Demo和手册跟着调用就行了。注意入参地址、长度和指令次序不要出错,不然可能会造成指令执行失败或者进入异常。
那么,当写入数据长度大于32个字节,或者一次擦除长度大于256K字节,想要实现非阻塞式的一次函数调用就能执行完成,可以通过中断的方式。开启NVM的“End of Busy”中断后,可以不必再等待指令执行完成,因为擦除和写入完成都会触发一次中断,在中断函数中可以继续把要写/擦除的地址和长度通过命令写入寄存器,直到写/擦除完所有的地址。
开启Nvm中断的方式和其他中断相同。中断源为IFX_INTPRIO_NVM_HOST。
同时要执行
MODULE_DMU.HCI.INTEN.B.EOBM = 1; /* Enable "End of Busy" interrupt */
来使能“End of Busy”中断。
4003

被折叠的 条评论
为什么被折叠?



