首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

spi flash 调试总结

spi flash 调试总结

抓狂的spi终于弄完了,想死的心都有了,本来不想到这么麻烦,大意了。


一、都不知道从何说起了,先说说我们的spi的“变态点”吧。


变态点一:
四种模式(CONTROL0 寄存器TMOD域),一个简单的spi协议还得搞出四种模式,好智能啊。
变态点二:
CS信号和SCLK信号不能单独受控,只能由写操作来控制,好智能啊。
变态点三:
我把你前两点的脾气摸到了之后,我该能控制你了吧,不行,你还非得在给我弄出一个EEPROM Read的模式,这个模式更智能,在写完命令和地址之后,CS信号和SCLK信号自己产生,不用再用写操作来控制了,好智能啊。


真得谢谢设计这东西的人,你太为我们软件着想了,把我们的事都给干了,你想让我们下岗啊。


二、奥,想起怎么写了,得总结一下我的各种需要怎么来仿真


1、
flash芯片的状态寄存器,代码如下

UINT8 byte = 0;





//
读之前,必须得设置一下模式


NST_SPI->SSIENR= 0x00;


NST_SPI->CTRLR0= (SPI_TMOD_TR << SPI_TMOD_OFFSET) | (SPI_FRF_SPI << SPI_FRF_OFFSET) |(SPI_FRM_SIZE - 1) |( SPI_MODE_3 << 6);

NST_SPI->SSIENR= 0x01;



NST_SPI->DR = FLASH_CMD_SRR;





//
发送一个伪码为的是产生时钟和CS有效


NST_SPI->DR = DUMMY_BYTE;




BSP_SpiWait();
//
到这里,我们一个模拟过程算是完成了




byte = NST_SPI->DR;
//
在这种模式下,只要sck有,cs为低,sdi就会被采样,我们在FIFO中就能读到(必须在调用BSP_SpiWait函数之后,再读),因此我们必须得把命令占的一个时钟从sdi移位到FIFO中的数据丢掉。

   

byte = NST_SPI->DR;
//
这才是真正想要的数据

   
return byte;


备注:
1)、BSP_SpiWait函数如下,该函数用于一次读写逻辑过程的完成。
VOID BSP_SpiWait(VOID)
{

UINT8 retry=0;

      

while(!(NST_SPI->SR & SR_TF_EMPT))//
等待发送区空      


{


retry++;


}








retry=0;


while(NST_SPI->SR & SR_BUSY) //
等待接收完一个byte


{


retry++;


}



}
2)、FIFO现在默认的大小是8,因此你一次读逻辑只能获得7个以下的字节(8得减去命令所占时钟,还得减去地址所占的时钟)

3)、上面加红的部分全部是变态点



2、
flash芯片的写一个字节,代码如下:
VOID BSP_SpiFlashWriteByte(UINT8 Byte,UINT32 WriteAddr)
{
UINT32 FlashAdr = (((WriteAddr/FLASH_PAGE_SIZE) << 9) | (WriteAddr % FLASH_PAGE_SIZE));


// 写之前,得设置一下模式


NST_SPI->SSIENR= 0x00;


NST_SPI->CTRLR0=
(SPI_TMOD_TO << SPI_TMOD_OFFSET) | (SPI_FRF_SPI << SPI_FRF_OFFSET) |(SPI_FRM_SIZE - 1) |( SPI_MODE_3 << 6);


NST_SPI->SSIENR= 0x01;

   

NST_SPI->DR = FLASH_CMD_MMPPTB1;


NST_SPI->DR = (UINT8)((FlashAdr)>>16);


NST_SPI->DR = (UINT8)((FlashAdr)>>8);


NST_SPI->DR = (UINT8)FlashAdr;




while(!(NST_SPI->SR & SR_TF_NOT_FULL)); //spi
的状态寄存器就是这么用,很经典。


NST_SPI->DR = Byte;




BSP_SpiWait(); //
一个写逻辑的完成

BSP_SpiFlashWaitBusy(); //等待芯片写操作完成,这和芯片有关跟我们内部spi没有关系
}
备注:
你还别说他搞的这个写的时候自动产生时钟和cs有效,对于写还是很好用的,上面我标准红色的比较少,说明写还是很让人满意的。



3、
flash芯片的连续读,代码如下:
VOID
SPI_FlashRead(UINT8* pBuf)

{


UINT32 ReadAddr = 0;


UINT8* pRxData = pBuf;


UINT32 FWLen = 0;


UINT32 DnldByteCnt = 0;


UINT32 BatchRdCnt = 0; //
批量读的次数


UINT32 FlashAdr = (((ReadAddr/FLASH_PAGE_SIZE) << 9) | (ReadAddr % FLASH_PAGE_SIZE));
//
需要按照芯片手册转换一下地址,在读命令中会介绍地址怎么安排。




//BSP_SpiFlashEraseChip();



//BSP_SpiFlashWaitBusy();
继承事业,薪火相传
返回列表