📄 pucspi.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 + -