--- 验证spi flash驱动接口 目前该驱动兼容w25q32 bh25q32
require"spiFlash"
require "pm"
require"utils"
pm.wake("testSpiFlash")
local flashlist = {
[0xEF15] = 'w25q32',
[0xEF16] = 'w25q64',
[0xEF17] = 'w25q128',
[0x6815] = 'bh25q32',
}
function HexToChar(bChar)
if((bChar>=0x30)and(bChar<=0x39)) then
bChar=bChar- 0x30;
else if((bChar>=0x41)and(bChar<=0x46)) then--// Capital
bChar=bChar- 0x37;
else if((bChar>=0x61)and(bChar<=0x66)) then --//littlecase
bChar=bChar- 0x57;
else
bChar = 0xff;
end
end
end
return bChar;
end
-- spiflash 大小 256*16*4*1024 字节
FLASH_COUNT=10*16 --数量*4K
SPI_MAXSIZE=FLASH_COUNT*16
SPI_COUNT=0
ReadIndex=0
ReadIndex_S=1
WriteIndex=0
WriteIndex_S=1
spi_flash = spiFlash.setup(spi.SPI_1, pio.P0_10)
--把数据格式化为16进制 高位补0 ,2字节 写入spiflash指定地址
function write_Index(addr,data)
local strhex=string.format("%04X",data)
spi_flash:write(addr,string.fromHex(strhex))
local readindexdata= spi_flash:read(addr, 2)
local readdatahex=string.toHex(readindexdata)
if(readdatahex==strhex) then
else
spi_flash:write(addr,string.fromHex(strhex))
readindexdata= spi_flash:read(addr, 2)
readdatahex=string.toHex(readindexdata)
log.error("index err",readdatahex,addr,data)
end
end
function SPI_READ()
local indexaddr=0
if (ReadIndex==WriteIndex) then -- //空队列,直接返回
log.info("empty")
else
-- local readSPIdata_pre= spi_flash:read(ReadIndex*256, 10)
-- local readSPIdata_pre_hex=string.toHex(readSPIdata_pre)
--if( (readSPIdata_pre_hex~='30303030303030303030') and (readSPIdata_pre_hex~='FFFFFFFFFFFFFFFFFFFF') ) then --预读 不等于空 或者 0
readSPIdata= spi_flash:read(ReadIndex*256, 60)
-- STRLENGTH=string.len(readSPIdata)
-- log.info("leng:",STRLENGTH)
spi_flash:write(ReadIndex*256,"000000000000") --读取完毕后清零
-- log.debug("W",WriteIndex)
-- else --队列非空 但是预读不准确,强制清零
-- log.error("RF:",ReadIndex)
-- log.info("W",WriteIndex)
--log.error("RFF:",readSPIdata_pre_hex)
-- spi_flash:write(ReadIndex*256,"000000000000")
-- end
ReadIndex= (ReadIndex+ 1) %SPI_MAXSIZE;
if(ReadIndex%16==0) then
if(ReadIndex==0) then --第一次读地址
spi_flash:erase4K((FLASH_COUNT-1)*4096)
else -- >=16
spi_flash:erase4K((ReadIndex-1)*256)
end
log.error("erase4K",ReadIndex)
end
if(ReadIndex%2048==0) then
spi_flash:erase4K((FLASH_COUNT+6)*4*1024)
spi_flash:erase4K((FLASH_COUNT+7)*4*1024)
spi_flash:erase4K((FLASH_COUNT+8)*4*1024)
end --索引写完了一遍
indexaddr=ReadIndex%2048
write_Index(indexaddr*2+(FLASH_COUNT+6)*4096,ReadIndex)
write_Index(indexaddr*2+(FLASH_COUNT+7)*4096,ReadIndex)
write_Index(indexaddr*2+(FLASH_COUNT+8)*4096,ReadIndex)
--strhex_index=string.format("%04X",ReadIndex)
-- spi_flash:write(ReadIndex*2+(FLASH_COUNT+4)*4096,string.fromHex(strhex_index))
log.debug("+",readSPIdata)
log.debug("R",ReadIndex)
end
-- return readSPIdata
end
--判断spiflash 是否有剩余空间 返回 0-没有空间 1-有空间
function SPI_Free()
local result=0
--注意: WriteIndex+16不可以大于65535 否则为nil 报错!!!!!!
if((WriteIndex+16)% SPI_MAXSIZE==ReadIndex) then -- //队列已满时,不执行入队操作
result=0
else --队列空
result=1
end
return result
end
function SPI_WRITE(SPI_user_data)
local result=0
writeDataLength=string.len(SPI_user_data)
local readSPIdata_pre= spi_flash:read((WriteIndex)*256, 10)
local readSPIdata_pre_hex=string.toHex(readSPIdata_pre)
local indexaddr=0
if(readSPIdata_pre_hex=='FFFFFFFFFFFFFFFFFFFF') then -- 预写地址数据正确
spi_flash:write(WriteIndex*256,SPI_user_data)
DATA01= spi_flash:read(WriteIndex*256, writeDataLength)
if( DATA01==SPI_user_data) then --写入正确
result=1
else --写入错误
result=0
end
else
result=0
end
WriteIndex= (WriteIndex+1) % SPI_MAXSIZE; --//尾部元素指向下一个空间位置,取模运算保证了索引不越界(余数一定小于除数)
if(WriteIndex%2048==0) then
spi_flash:erase4K((FLASH_COUNT+3)*4*1024)
spi_flash:erase4K((FLASH_COUNT+4)*4*1024)
spi_flash:erase4K((FLASH_COUNT+5)*4*1024)
end --索引写完了一遍
indexaddr=WriteIndex%2048
write_Index(indexaddr*2+(FLASH_COUNT+3)*4096,WriteIndex)
write_Index(indexaddr*2+(FLASH_COUNT+4)*4096,WriteIndex)
write_Index(indexaddr*2+(FLASH_COUNT+5)*4096,WriteIndex)
--local strhex=string.format("%04X",WriteIndex)
--spi_flash:write(WriteIndex*2+(FLASH_COUNT+3)*4096,string.fromHex(strhex)) --记录下一个地址索引
log.debug("W",WriteIndex)
return result
end
--带比较写入spiflash 返回 0-满了 1-写入成功
function spiWriteDataCheck(userdata)
local result=0
if(SPI_Free()==1) then --有空间
result=SPI_WRITE(userdata)
if(result==0) then --写入错误 再写一遍
if(SPI_Free()==1) then
SPI_WRITE(teststr)
else
result=0
end
end
else
result=0
end
return result
end
-- 从spiflash读qu size个字节数据 转为16进制
function spiHexToDec(address,size)
local hexdata=spi_flash:read(address,size)
local readdatahex=string.toHex(hexdata)
return readdatahex
end
--二分查找索引
function findIndex(MAXINDEX,baseAddress1,baseAddress2,baseAddress3,W_R_index)
local miniindex=0
local maxindex=MAXINDEX
local read_flags1='0000'
local read_flags2='0000'
local read_flags3='0000'
local offsetAddress=0
local erFenCount=11 --分11段查找
while(erFenCount>0) do
offsetAddress=(maxindex-miniindex)/2+miniindex -- 重新确定偏移量 对于基地址的绝对位置
read_flags1=spiHexToDec(baseAddress1+offsetAddress,2)
read_flags2=spiHexToDec(baseAddress2+offsetAddress,2)
read_flags3=spiHexToDec(baseAddress3+offsetAddress,2)
if((read_flags1==read_flags2) and (read_flags2==read_flags3) and (read_flags1=='FFFF')) then --全部相等
maxindex=offsetAddress
else --取后半部分
miniindex=offsetAddress
end
erFenCount=erFenCount-1
sys.wait(2)
end
if((maxindex-miniindex)==2) then log.info('%%%%%',miniindex,maxindex) end
readflags1=spi_flash:read(baseAddress1+miniindex,2)
readflags2=spi_flash:read(baseAddress2+miniindex,2)
readflags3=spi_flash:read(baseAddress3+miniindex,2)
readIndex_fromhex1=string.toHex(readflags1)
readIndex_fromhex2=string.toHex(readflags2)
readIndex_fromhex3=string.toHex(readflags3)
readIndex1=tonumber(readIndex_fromhex1,16) --十进制数
readIndex2=tonumber(readIndex_fromhex2,16) --十进制数
readIndex3=tonumber(readIndex_fromhex3,16) --十进制数
if((readIndex_fromhex1==readIndex_fromhex2) and (readIndex_fromhex1~='FFFF') ) then
-- readIndex1=tonumber(readIndex_fromhex1,16) --十进制数
if(W_R_index==1) then --写索引
WriteIndex=readIndex1
log.error("W index1",readIndex_fromhex1)
log.error("writeIndex1",readIndex1)
spi_flash:erase4K((FLASH_COUNT+5)*4*1024)
findresult=1
else --读索引
ReadIndex=readIndex1
log.error("R index1",readIndex_fromhex1)
log.error("readIndex1",readIndex1)
spi_flash:erase4K((FLASH_COUNT+8)*4*1024)
findresult=1
end
else
if((readIndex_fromhex2==readIndex_fromhex3) and (readIndex_fromhex2~='FFFF') ) then
-- readIndex2=tonumber(readIndex_fromhex2,16) --十进制数
if(W_R_index==1) then --写索引
WriteIndex=readIndex2
log.error("W index2",readIndex_fromhex2)
log.error("writeIndex2",readIndex2)
spi_flash:erase4K((FLASH_COUNT+4)*4*1024)
findresult=1
else --读索引
ReadIndex=readIndex2
log.error("R index2",readIndex_fromhex2)
log.error("readIndex2",readIndex2)
spi_flash:erase4K((FLASH_COUNT+7)*4*1024)
findresult=1
end
else
if((readIndex_fromhex1==readIndex_fromhex3) and (readIndex_fromhex1~='FFFF') ) then
-- readIndex3=tonumber(readIndex_fromhex3,16) --十进制数
if(W_R_index==1) then --写索引
WriteIndex=readIndex3
log.error("W index3",readIndex_fromhex3)
log.error("writeIndex3",readIndex3)
spi_flash:erase4K((FLASH_COUNT+4)*4*1024)
findresult=1
else --读索引
ReadIndex=readIndex3
log.error("R index3",readIndex_fromhex3)
log.error("readIndex3",readIndex3)
spi_flash:erase4K((FLASH_COUNT+7)*4*1024)
findresult=1
end
else
if(miniindex>=2) then
readflags1=spi_flash:read(baseAddress1+miniindex-2,2)
readflags2=spi_flash:read(baseAddress2+miniindex-2,2)
readflags3=spi_flash:read(baseAddress3+miniindex-2,2)
readIndex_fromhex1=string.toHex(readflags1)
readIndex_fromhex2=string.toHex(readflags2)
readIndex_fromhex3=string.toHex(readflags3)
if((readIndex_fromhex1==readIndex_fromhex2) and (readIndex_fromhex2==readIndex_fromhex3) and (readIndex_fromhex1~='FFFF') ) then
--这是最后的救命稻草了
readIndex1=tonumber(readIndex_fromhex1,16) --十进制数
if(W_R_index==1) then --写索引
WriteIndex=readIndex1
log.error("W index_pre",readIndex_fromhex1)
log.error("writeIndex_pre",readIndex1)
findresult=1
else --读索引
ReadIndex=readIndex1
log.error("R index_pre",readIndex_fromhex1)
log.error("readIndex_pre",readIndex1)
findresult=1
end
else -- 前一个也不对 死定了
findresult=0
end
else --接收死刑吧,确实找不到索引了 重新初始化。
findresult=0
end
end
end
end
--出现异常情况,理论上不可能为nil
if((readIndex1==nil) or (readIndex2==nil) or (readIndex3==nil) ) then log.error("nil err err") findresult=0 end
end
--;预读初始化
flash_Inint_Flags="17513167902"
function SPI_ININT_PRE()
ReadIndex=0
WriteIndex=0
spi_flash:erase4K((FLASH_COUNT+1)*4*1024) --清除必须操作 必须清楚后才能写数据
local writeOK_flag= spi_flash:read((FLASH_COUNT+2)*4*1024,11) --是否第一次写入数据
local next_step=0
print("writeOK_flag",writeOK_flag)
if(writeOK_flag==flash_Inint_Flags) then
next_step=1
else
spi_flash:erase4K((FLASH_COUNT+2)*4*1024)
print("writeOK_flag14", spi_flash:write((FLASH_COUNT+2)*4*1024,flash_Inint_Flags))
next_step=2
end
print("next_step=",next_step)
local count=0
local readindex_start=0
local writeindex_start=0
local readIndex_flag=0
if(next_step==1) then
if(findIndex(4096,(FLASH_COUNT+3)*4096,(FLASH_COUNT+4)*4096,(FLASH_COUNT+5)*4096,1)==0) then --没有找到上次的 写索引 全部清除
next_step=2
end
print("========================")
if(findIndex(4096,(FLASH_COUNT+6)*4096,(FLASH_COUNT+7)*4096,(FLASH_COUNT+8)*4096,0)==0) then --没有找到上次的 读索引 全部清除
next_step=2
end
if(next_step==1) then
log.error("indexR_W1",ReadIndex,WriteIndex)
end
count=0
readIndex_flag=0
end
count=0
if(next_step==2) then
log.error("indexR_W2",ReadIndex,WriteIndex)
print('spi flash erase..........')
while(count<(FLASH_COUNT/16)) do
spi_flash:erase64K(count*1024*4*16) count=count+1 sys.wait(1) --清除数据区
end
--清除读写索引区
spi_flash:erase4K((FLASH_COUNT+3)*4*1024)
spi_flash:erase4K((FLASH_COUNT+4)*4*1024)
spi_flash:erase4K((FLASH_COUNT+5)*4*1024)
spi_flash:erase4K((FLASH_COUNT+6)*4*1024)
spi_flash:erase4K((FLASH_COUNT+7)*4*1024)
spi_flash:erase4K((FLASH_COUNT+8)*4*1024)
--第一次读写flash 索引置零
ReadIndex=0
WriteIndex=0
--把下一次预读写的索引写入spiflash
write_Index(WriteIndex*2+(FLASH_COUNT+3)*4096,WriteIndex)
write_Index(WriteIndex*2+(FLASH_COUNT+4)*4096,WriteIndex)
write_Index(WriteIndex*2+(FLASH_COUNT+5)*4096,WriteIndex)
write_Index(ReadIndex*2+(FLASH_COUNT+6)*4096,ReadIndex)
write_Index(ReadIndex*2+(FLASH_COUNT+7)*4096,ReadIndex)
write_Index(ReadIndex*2+(FLASH_COUNT+8)*4096,ReadIndex)
print('spi flash eraseinit OK')
sys.wait(1000)
end
end
SPI_ININT_OK=0
SPI_ININT_PRE()
SPI_ININT_OK=2
yesycount=1
xinhaoliang=0
function writespiflashtest()
syserrrcode=0
while(true) do
--- if(xinhaoliang==0) then
if(SPI_ININT_OK==2) then
teststr=string.format("test adcde:ftydtyfdfdfgurgjfdhguirhgujgh#>: %d", yesycount)
if(spiWriteDataCheck(teststr)==1) then --写入正确
yesycount=yesycount+1
else --满了
print("full",WriteIndex)
end
end
sys.wait(5)
end
end
sys.taskInit(writespiflashtest)
while true do
if(SPI_ININT_OK==2) then
SPI_READ()
end
sys.wait(15)
end
end)