168 lines
4.0 KiB
C
Raw Normal View History

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;
}