⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pucspi.c

📁 这是单板上DPRAM的驱动程序
💻 C
字号:
/*Programed by zhoudb 2002-6-21 用通用I/O口实现SPI通讯接口功能*/
#include "bdcomm.h"
#include "pucspi.h"
/*低端接口函数声明*/
void SpiPhyInit(void);
void ChipSelect(unsigned char SlaveID,char EnableFlag);
void SpiWrite8Bit(unsigned char DataByte);
unsigned char SpiRead8Bit(void);
void HalfClkPeriod(int ClkPeriod);
void WritePageAddr(BcmRegStruct *RegStruct);
void WriteRegData(BcmRegStruct *RegStruct);
unsigned char ReadSpiSts(BcmRegStruct *RegStruct);
void ReadRegData(BcmRegStruct *RegStruct);
void DummyRead(BcmRegStruct *RegStruct);

/*---------------------------------------------------------------------
这个文件用于实现SPI物料层驱动,数据链路程驱动
-----------------------------------------------------------------------
物料层驱动的接口函数如下:       
SpiPhyInit   	SpiWrite8Bit 	 SpiRead8Bit      ChipSelect               
----------------------------------------------------------------------*/
/*作用域为SPI.C的静态变量,标识是否更改页地址*/
static char ChangePage=YYES;         
/*作用域为SPI.C的静态变量,标识当前的页地址*/        
static unsigned char GlobalPageAddr=0x00;
static unsigned char GlobalBcmID=0x00;
/*---------------------------------------------------------------------
函 数 名:SpiPhyInit
参   数: 无
函数意义:初试化MOSI,SS1,SS2,SCK
----------------------------------------------------------------------*/

void SpiPhyInit(void)
{
	SCK(1); 
	MOSI(1); 
	SS1(1);
	SS2(1);
	ChangePage=YYES;   
	GlobalPageAddr=0x00;
	GlobalBcmID=0x00;
	return; 
}

/*---------------------------------------------------------------------
函 数 名:ChipSelect
参   数1:EnableFlag
参数意义:0为使能 1为结束使能
参   数2:SlaveID 
参数意义:SlaveID=0 则使ID号为0的器件片选有效
		 SlaveID=1 则使ID号为1的器件片选有效
		 SlaveID=2 则使所有的从器件片选有效
----------------------------------------------------------------------*/
void ChipSelect(unsigned char SlaveID,char EnableFlag)
{	
	if(EnableFlag!=0)EnableFlag=1;
	switch(SlaveID)
	{
		case 0:
		SS1(EnableFlag);
		break;
		case 1:
		SS2(EnableFlag);
		break;
		case 8:
		SS1(EnableFlag);
		SS2(EnableFlag);
		break;	
	}
	return;
}

/*---------------------------------------------------------------------
函 数 名:SpiWrite8Bit
参    数:DataByte
参数意义:DataByte为相MOSI数据线上发送数据。在数据的下降沿发送数据。
                           5328在上升沿采样
                           时钟SCK 起始状态默认为1 ,终止状态也为1
        该函数实现向MOSI上发送8BITS数据
----------------------------------------------------------------------*/

void SpiWrite8Bit(unsigned char DataByte)
{
	int i;
	unsigned char BitVal;
	for(i=0;i<8;i++)
	{
		if((DataByte&(BitMask>>i))!=0)
			BitVal=1;
		else
			BitVal=0;
	    SCK(0);							/*SCK=0*/
		MOSI(BitVal);					/*MOSI=BitVal*/
		/*HalfClkPeriod(HALFPERIOD);		/*delay to control clock frequence*/								
		SCK(1);							/*SCK=1*/
		/*HalfClkPeriod(HALFPERIOD);		/*delay to control clock frequence*/
	}	
	return;
}
/*---------------------------------------------------------------------
函 数 名:SpiRead8Bit
参    数:void
函数意义:该函数实现从MISO上读取8BITS数据
                          数据在下讲沿由5328给出,时钟的上升沿采样。
                          时钟SCK 起始状态默认为1 ,终止状态也为1
----------------------------------------------------------------------*/

unsigned char SpiRead8Bit(void)
{
	unsigned char ReadVal,i;
	ReadVal=0;
	for(i=0;i<8;i++)
	{
		SCK(0);							/*SCK=0*/
		/*HalfClkPeriod(HALFPERIOD);		/*delay to control clock frequence*/								
		SCK(1);							/*SCK=1*/
		if(MISO==1) ReadVal=ReadVal|(BitMask>>i);
		/*HalfClkPeriod(HALFPERIOD);		/*delay to control clock frequence*/	
	}
	return ReadVal;
}

/*---------------------------------------------------------------------
函 数 名:HalfClkPeriod
参    数:ClkPeriod
函数意义:该函数用于控制时钟SCK频率。        
----------------------------------------------------------------------*/
void HalfClkPeriod(int ClkPeriod)
{
	int j;
	for(j=0;j<ClkPeriod;j++);	
	return;
}
void Bcm5328CLK(void)
{
    int i = 0;
     for(i=0;i<1000000;i++)
     {
       SCK(1);
	
	SCK(0);
	
	SCK(1);
	
	SCK(0);
	
	SCK(1);
	
	SCK(0);
	
	SCK(1);
	
	SCK(0);
	
	SCK(1);
	
	SCK(0);	
     }	
}

/**********************************************************************
							以下函数为数据链路层接口函数
Bcm5328RegWrite    Bcm5328RegRead     Bcm5328SpiInit     ReadSpiSts                     
WritePageAddr      WriteRegData       ReadRegData        DummyRead   							
**********************************************************************/
/*---------------------------------------------------------------------
函 数 名:Bcm5328SpiInit
参    数:无
函数意义:该函数用于初试化BCM5328寄存器读写接口的初试化。        
----------------------------------------------------------------------*/
void Bcm5328SpiInit(void)
{
        int i;
	unsigned char BitVal;	
	SpiPhyInit();
	ChangePage=NNO;         /*作用域为SPI.C的静态变量,标识是否更改页地址*/
   	GlobalPageAddr=0x00;    /*作用域为SPI.C的静态变量,标识当前的页地址*/
	/*ChipSelect(8,SS_DIS);  	
	SCK(1);
	SCK(0);	
   	ChipSelect(8,SS_EN);	
   	SpiWrite8Bit(COMMANDWRITE|0x0e);
      SpiWrite8Bit(SPI_PAGE);	
      SpiWrite8Bit(GlobalPageAddr);	
      ChipSelect(8,SS_DIS);  
	SCK(0);
	SCK(1);	*/
   	return;
}
/*---------------------------------------------------------------------
函 数 名:WritePageAddr
参    数:*RegStruct
函数意义:该函数用于向BCM5328M发送更新页地址寄存器的命令,最终实现页切换        
----------------------------------------------------------------------*/
void WritePageAddr(BcmRegStruct *RegStruct)
{
       ChipSelect(8,SS_DIS);  	/*SS=1*/
	SCK(1);
	SCK(0);	
	ChipSelect(RegStruct->BcmID,SS_EN); /*SS=0*/
	SpiWrite8Bit(COMMANDWRITE|(RegStruct->BcmID<<1));
    SpiWrite8Bit(SPI_PAGE);	
    SpiWrite8Bit(RegStruct->RegPageAddr);		
    ChipSelect(RegStruct->BcmID,SS_DIS); /*SS=1*/
	SCK(0);
	SCK(1);
    return;
}
/*---------------------------------------------------------------------
函 数 名:WriteRegData
参    数:*RegStruct
函数意义:该函数用于向BCM5328M发送写寄存器的命令和地址        
----------------------------------------------------------------------*/
void WriteRegData(BcmRegStruct *RegStruct)
{
	int j;
	ChipSelect(8,SS_DIS);  	/*SS=1*/
	SCK(1);
	SCK(0);		
	ChipSelect(RegStruct->BcmID,SS_EN); /*SS=0*/	
	SpiWrite8Bit(COMMANDWRITE|(RegStruct->BcmID<<1));
    SpiWrite8Bit(RegStruct->RegAddr);	
       for(j=RegStruct->DataLength-1;j>=0;j--)
	{
		SpiWrite8Bit(RegStruct->DataBuf[j]);/*先发送低位BYTE,再发送高位BYTE*/
	}
	ChipSelect(RegStruct->BcmID,SS_DIS); /*SS=1*/		
	SCK(0);
	SCK(1);	
    return;
}

/*---------------------------------------------------------------------
函 数 名:ReadSpiSts
参    数:*RegStruct
函数意义:该函数用于读取BCM5328M的SPI_STS状态寄存器        
----------------------------------------------------------------------*/
unsigned char ReadSpiSts(BcmRegStruct *RegStruct)
{
	unsigned char val = 0;
	ChipSelect(8,SS_DIS);  	/*SS=1*/
	SCK(1);
	SCK(0);	
	ChipSelect(RegStruct->BcmID,SS_EN); /*SS=0*/
	SpiWrite8Bit(COMMANDREAD|(RegStruct->BcmID<<1));
	SpiWrite8Bit(SPI_STS);
	val=SpiRead8Bit();
	ChipSelect(RegStruct->BcmID,SS_DIS); /*SS=1*/	
	SCK(0);
	SCK(1);	
	return(val);
}
/*---------------------------------------------------------------------
函 数 名:ReadRegData
参    数:*RegStruct
函数意义:该函数用于连续读取MISO上的数据        
----------------------------------------------------------------------*/
void ReadRegData(BcmRegStruct *RegStruct)
{
	 int j;	
	 
	 for(j=RegStruct->DataLength-1;j>=0;j--)
	 {	 	
		 RegStruct->DataBuf[j]=0;
	 }
	 ChipSelect(8,SS_DIS);  	/*SS=1*/	
	SCK(1);
	SCK(0);	
	 ChipSelect(RegStruct->BcmID,SS_EN); /*SS=0*/
	 SpiWrite8Bit(COMMANDREAD|(RegStruct->BcmID<<1));
	 SpiWrite8Bit(SPI_DATA0);
	 for(j=RegStruct->DataLength-1;j>=0;j--)
	 {
	 	RegStruct->DataBuf[j]=SpiRead8Bit();		
	 }
	 ChipSelect(RegStruct->BcmID,SS_DIS); /*SS=1*/	 
	SCK(0);
	SCK(1);	
}
/*---------------------------------------------------------------------
函 数 名:DummyRead
参    数:*RegStruct
函数意义:该函数用于读取MISO上的8bit数据,但不需要结果
		 同时发出读命令和目的寄存器地址        
----------------------------------------------------------------------*/
void DummyRead(BcmRegStruct *RegStruct)
{
	ChipSelect(8,SS_DIS);  	/*SS=1*/	
	SCK(1);
	SCK(0);	
	ChipSelect(RegStruct->BcmID,SS_EN); /*SS=0*/
	SpiWrite8Bit(COMMANDREAD|(RegStruct->BcmID<<1));
	SpiWrite8Bit(RegStruct->RegAddr);
	SpiRead8Bit();	
	ChipSelect(RegStruct->BcmID,SS_DIS); /*SS=1*/	
	SCK(0);
	SCK(1);		
}     
/*---------------------------------------------------------------------
函 数 名:Bcm5328RegWrite
参    数:*RegStruct
函数意义:该函数用于向指定的BCM5328M的寄存器写值
这个函数是实现BCM5328 SPI数据链路程的工作,供应用层调用        
                           简化协议
----------------------------------------------------------------------*/
BCM_STATUS Bcm5328RegWrite(BcmRegStruct *RegStruct)
{
	 int SoftWareTimeOut,MaxTimeOutCounter1,MaxTimeOutCounter2;
	 
	 char StepFlag,i,Start,j;
	 unsigned char SpiStsVal;
	 char SpiStsBitOk;
	 
	 MaxTimeOutCounter1=0;
	 MaxTimeOutCounter2=0;
	 Start=0;
	 SpiStsBitOk=NNO;
	 StepFlag=MASK_STS_SPIF;
	 
	 /*当前需要读写的SPI_STS的BIT*/
	 SoftWareTimeOut=0;
	 
	 /*判断设备号和数据长度正确与否*/
	 if(((RegStruct->BcmID&(~IDMASK))>0x01)&&((RegStruct->BcmID&(~IDMASK))!=0x08)) return(BCM_INVALID_ID);
	 if((RegStruct->DataLength)>0x08)return(BCM_INVLAID_DATA_LENGTH);
	 
	 /*start*/
	       /*printf("\na)  WR PAGE REG\n");
	       getchar();*/
	  
	       WritePageAddr(RegStruct);
	 	do
	 	{
	 	      /* printf("\nb  RD STATUS REG(SPIF bit)\n");
	              getchar();*/
	 		SpiStsVal=ReadSpiSts(RegStruct);/*read SPI_STS*/
	 		if((SpiStsVal&MASK_STS_SPIF)==0)/*SPIF=0*/
	 		{
	 			SpiStsBitOk=YYES;
	 			SoftWareTimeOut=0;	
	 		}
	 		else
	 		{
	 			SpiStsBitOk=NNO;
	 			SoftWareTimeOut++;
				resetSWT();	
	 		}			

		}while((SoftWareTimeOut<SOFTWARETIMEOUT)&&(SpiStsBitOk==NNO));		
	    
		/*判断软件是否超时以及设置流程分支标识*/
		/*根据不同的情况处理是否更新页地址*/
		   /*    printf("\nc)  WR PAGE REG\n");
	              getchar();*/
			WritePageAddr(RegStruct);
		/*正常流程的写处理*/
		       /* printf("\nd)  WR DATA\n");
	              getchar();*/
			WriteRegData(RegStruct);
		       /*printf(" \nWr STS time = %d",SoftWareTimeOut);
			printf(" \nWr page time = %d",MaxTimeOutCounter1);*/
			   	
			return(BCM_OK);	
} 
/*---------------------------------------------------------------------
函 数 名:Bcm5328RegRead
参    数:*RegStruct
函数意义:该函数用于读取指定的BCM5328M的寄存器的值
这个函数是实现BCM5328 SPI数据链路程的工作,供应用层调用        
                         简化协议
----------------------------------------------------------------------*/ 
BCM_STATUS Bcm5328RegRead(BcmRegStruct *RegStruct)
{
	 int SoftWareTimeOut,MaxTimeOutCounter1,MaxTimeOutCounter2;
	 char SpiStsBitOk;
	 char StepFlag,Start;
	 unsigned char SpiStsVal;
	 int i,j;
	 
	 MaxTimeOutCounter1=0;
	 MaxTimeOutCounter2=0;	 
	 Start=0;
	 SpiStsBitOk=NNO;
	 StepFlag=MASK_STS_SPIF; /*当前需要读写的SPI_STS的BIT*/
	 SoftWareTimeOut=0;
	 
	 /*判断设备号和数据长度正确与否*/
	 if(((RegStruct->BcmID&(~IDMASK))>0x01)&&((RegStruct->BcmID&(~IDMASK))!=0x08)) return(BCM_INVALID_ID);
	 if((RegStruct->DataLength)>0x08)return(BCM_INVLAID_DATA_LENGTH);
	 
	 /*start*/
	     /*  printf("\n1)  WR PAGE REG\n");
	       getchar();*/
        
		WritePageAddr(RegStruct);	 
	    	do
	 	{
	 	       /*printf("\n2  RD STATUS REG(SPIF bit)\n");
	              getchar();*/
	 		SpiStsVal=ReadSpiSts(RegStruct);/*read SPI_STS*/
	 		   	 	if((SpiStsVal&MASK_STS_SPIF)==0)/*SPIF=0*/
	 		   	 	{
	 		   	 		SpiStsBitOk=YYES;
	 		   	 		SoftWareTimeOut=0;			
	 		   	 	}
	 		   	 	else
	 		   	 	{
	 		   	 		SpiStsBitOk=NNO;
	 		   	 		SoftWareTimeOut++;
						resetSWT();	
	 		   	 	}		
		 }while((SoftWareTimeOut<SOFTWARETIMEOUT)&&(SpiStsBitOk==NNO));
		    
	      
		/*printf("\n3)  WR PAGE REG\n");
	       getchar();*/
		/*判断软件是否超时以及设置流程分支标识*/
		WritePageAddr(RegStruct);
		/*正常流程的读处理*/
		/*printf("\n4)  DUMMY RD REG\n");
	       getchar();*/
		DummyRead(RegStruct);
		do
	 	{
	 	       /*printf("\n5)   RD STATUS REG (RACK bit) \n");
	              getchar();*/
	 		SpiStsVal=ReadSpiSts(RegStruct);/*read SPI_STS*/
	 		   		if((SpiStsVal&MASK_STS_RACK)==0x20)/*RACK=1*/
	 		   	 	{
	 		   	 		SpiStsBitOk=YYES;	 		   	 					
	 		   	 	}
	 		   	 	else
	 		   	 	{
	 		   	 		SpiStsBitOk=NNO;
	 		   	 		SoftWareTimeOut++;
						resetSWT();	
	 		   	 	}
	 		   	    
		}while((SoftWareTimeOut<SOFTWARETIMEOUT)&&(SpiStsBitOk==NNO));		        
		
		if(SpiStsBitOk==NNO)
		{
                         return(BCM_TIME_OUT);
		}
				/*这儿为简化协议,只支持比64bits短的寄存器的读写!*/
				/*printf("\n6)   RD DATA REG\n");
	                     getchar();*/
				ReadRegData(RegStruct);
				resetSWT();	
				/*printf(" \nRd STS SPIF time = %d",SoftWareTimeOut);
			       printf(" \nRd page time = %d",MaxTimeOutCounter1);
				printf(" \nRd STS RACK time = %d",MaxTimeOutCounter2);*/
				return(BCM_OK);	
	
}    
       

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -