2025-05-20 14:02:07 +08:00
|
|
|
#include "qspi.h"
|
|
|
|
|
|
|
|
|
|
|
|
//等待状态标志
|
|
|
|
//flag:需要等待的标志位
|
|
|
|
//sta:需要等待的状态
|
|
|
|
//wtime:等待时间
|
|
|
|
//返回值:0,等待成功.
|
|
|
|
// 1,等待失败.
|
|
|
|
u8 QSPI_Wait_Flag(u32 flag,u8 sta,u32 wtime)
|
|
|
|
{
|
|
|
|
u8 flagsta=0;
|
|
|
|
while(wtime)
|
|
|
|
{
|
|
|
|
flagsta=(QUADSPI->SR&flag)?1:0;
|
|
|
|
if(flagsta==sta)break;
|
|
|
|
wtime--;
|
|
|
|
}
|
|
|
|
if(wtime)return 0;
|
|
|
|
else return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//初始化QSPI接口
|
|
|
|
//返回值:0,成功;
|
|
|
|
// 1,失败;
|
|
|
|
void QSPI_Init(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//QSPI发送命令
|
|
|
|
//cmd:要发送的指令
|
|
|
|
//addr:发送到的目的地址
|
|
|
|
//mode:模式,详细位定义如下:
|
|
|
|
// mode[1:0]:指令模式;00,无指令;01,单线传输指令;10,双线传输指令;11,四线传输指令.
|
|
|
|
// mode[3:2]:地址模式;00,无地址;01,单线传输地址;10,双线传输地址;11,四线传输地址.
|
|
|
|
// mode[5:4]:地址长度;00,8位地址;01,16位地址;10,24位地址;11,32位地址.
|
|
|
|
// mode[7:6]:数据模式;00,无数据;01,单线传输数据;10,双线传输数据;11,四线传输数据.
|
|
|
|
//dmcycle:空指令周期数
|
|
|
|
void QSPI_Send_CMD(u8 cmd,u32 addr,u8 mode,u8 dmcycle)
|
|
|
|
{
|
|
|
|
u32 tempreg=0;
|
|
|
|
u8 status;
|
|
|
|
if(QSPI_Wait_Flag(1<<5,0,0XFFFF)==0) //等待BUSY空闲
|
|
|
|
{
|
|
|
|
tempreg=0<<31; //禁止DDR模式
|
|
|
|
tempreg|=0<<28; //每次都发送指令
|
|
|
|
tempreg|=0<<26; //间接写模式
|
|
|
|
tempreg|=((u32)mode>>6)<<24; //设置数据模式
|
|
|
|
tempreg|=(u32)dmcycle<<18; //设置空指令周期数
|
|
|
|
tempreg|=((u32)(mode>>4)&0X03)<<12; //设置地址长度
|
|
|
|
tempreg|=((u32)(mode>>2)&0X03)<<10; //设置地址模式
|
|
|
|
tempreg|=((u32)(mode>>0)&0X03)<<8; //设置指令模式
|
|
|
|
tempreg|=cmd; //设置指令
|
|
|
|
QUADSPI->CCR=tempreg; //设置CCR寄存器
|
|
|
|
if(mode&0X0C) //有指令+地址要发送
|
|
|
|
{
|
|
|
|
QUADSPI->AR=addr; //设置地址寄存器
|
|
|
|
}
|
|
|
|
if((mode&0XC0)==0) //无数据传输,等待指令发送完成
|
|
|
|
{
|
|
|
|
status=QSPI_Wait_Flag(1<<1,1,0XFFFF);//等待TCF,即传输完成
|
|
|
|
if(status==0)
|
|
|
|
{
|
|
|
|
QUADSPI->FCR|=1<<1; //清除TCF标志位
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//QSPI接收指定长度的数据
|
|
|
|
//buf:接收数据缓冲区首地址
|
|
|
|
//datalen:要传输的数据长度
|
|
|
|
//返回值:0,正常
|
2025-05-21 15:35:29 +08:00
|
|
|
// 其他,错误代码
|
2025-05-20 14:02:07 +08:00
|
|
|
u8 QSPI_Receive(u8* buf,u32 datalen)
|
|
|
|
{
|
|
|
|
u32 tempreg=QUADSPI->CCR;
|
|
|
|
u32 addrreg=QUADSPI->AR;
|
|
|
|
u8 status;
|
|
|
|
vu32 *data_reg=&QUADSPI->DR;
|
|
|
|
QUADSPI->DLR=datalen-1; //设置数据传输长度
|
|
|
|
tempreg&=~(3<<26); //清除FMODE原来的设置
|
|
|
|
tempreg|=1<<26; //设置FMODE为间接读取模式
|
|
|
|
QUADSPI->FCR|=1<<1; //清除TCF标志位
|
|
|
|
QUADSPI->CCR=tempreg; //回写CCR寄存器
|
|
|
|
QUADSPI->AR=addrreg; //回写AR寄存器,触发传输
|
|
|
|
while(datalen)
|
|
|
|
{
|
|
|
|
status=QSPI_Wait_Flag(3<<1,1,0XFFFF);//等到FTF和TCF,即接收到了数据
|
|
|
|
if(status==0) //等待成功
|
|
|
|
{
|
|
|
|
*buf++=*(vu8 *)data_reg;
|
|
|
|
datalen--;
|
|
|
|
}else break;
|
|
|
|
}
|
|
|
|
if(status==0)
|
|
|
|
{
|
|
|
|
QUADSPI->CR|=1<<2; //终止传输
|
|
|
|
status=QSPI_Wait_Flag(1<<1,1,0XFFFF); //等待TCF,即数据传输完成
|
|
|
|
if(status==0)
|
|
|
|
{
|
|
|
|
QUADSPI->FCR|=1<<1; //清除TCF标志位
|
|
|
|
status=QSPI_Wait_Flag(1<<5,0,0XFFFF); //等待BUSY位清零
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
//QSPI发送指定长度的数据
|
|
|
|
//buf:发送数据缓冲区首地址
|
|
|
|
//datalen:要传输的数据长度
|
|
|
|
//返回值:0,正常
|
|
|
|
// 其他,错误代码
|
|
|
|
u8 QSPI_Transmit(u8* buf,u32 datalen)
|
|
|
|
{
|
|
|
|
u32 tempreg=QUADSPI->CCR;
|
|
|
|
u32 addrreg=QUADSPI->AR;
|
|
|
|
u8 status;
|
|
|
|
vu32 *data_reg=&QUADSPI->DR;
|
|
|
|
QUADSPI->DLR=datalen-1; //设置数据传输长度
|
|
|
|
tempreg&=~(3<<26); //清除FMODE原来的设置
|
|
|
|
tempreg|=0<<26; //设置FMODE为间接写入模式
|
|
|
|
QUADSPI->FCR|=1<<1; //清除TCF标志位
|
|
|
|
QUADSPI->CCR=tempreg; //回写CCR寄存器
|
|
|
|
while(datalen)
|
|
|
|
{
|
|
|
|
status=QSPI_Wait_Flag(1<<2,1,0XFFFF);//等到FTF
|
|
|
|
if(status!=0) //等待成功
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
*(vu8 *)data_reg=*buf++;
|
|
|
|
datalen--;
|
|
|
|
}
|
|
|
|
if(status==0)
|
|
|
|
{
|
|
|
|
QUADSPI->CR|=1<<2; //终止传输
|
|
|
|
status=QSPI_Wait_Flag(1<<1,1,0XFFFF); //等待TCF,即数据传输完成
|
|
|
|
if(status==0)
|
|
|
|
{
|
|
|
|
QUADSPI->FCR|=1<<1; //清除TCF标志位
|
|
|
|
status=QSPI_Wait_Flag(1<<5,0,0XFFFF); //等待BUSY位清零
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|