www.pudn.com > rfid.rar > spi.c, change:2012-04-22,size:14732b


/******************************************************************************* 
 * 文件名称:spi.c 
 * 功    能:MSP430与TRF7960的SPI接口驱动文件 
 * 作    者:Ronnie 
 * 公    司:湘潭斯凯电子科技有限公司 
 *           www.sikai-tech.com 
 * 日    期:2011-06-22 
 ******************************************************************************/ 
 
 
/* 包含头文件 */ 
/********************************************************************/ 
#include "spi.h" 
#include "globals.h" 
/********************************************************************/ 
 
 
/* 宏定义 */ 
/********************************************************************/ 
#define DBG		0  // 定义为1可输出调试信息 
/********************************************************************/ 
 
 
/* 变量定义 */ 
/********************************************************************/ 
unsigned char temp; 
unsigned int DUMMYREAD = 0; 
unsigned int mask = 0x80; 
/********************************************************************/ 
 
 
/********************************************************************* 
 * 函数名称:SPIStartCondition 
 * 功    能:SPI开始条件 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void SPIStartCondition(void) 
{ 
  /* 拉高SCLK */ 
  P3SEL &= ~ BIT3; 
  P3DIR |= BIT3; 
  P3OUT |= BIT3; 
} 
 
 
/********************************************************************* 
 * 函数名称:SPIStopCondition 
 * 功    能:SPI停止条件 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void SPIStopCondition(void) 
{ 
  /* 拉低SCLK */ 
  P3SEL &= ~ BIT3; 
  P3OUT &= ~BIT3;  
  P3DIR |= BIT3; 
  P3OUT &= ~BIT3; 
} 
 
 
/********************************************************************* 
 * 函数名称:WriteSingle 
 * 功    能:写单个寄存器或者特殊地址的多个寄存器 
 * 入口参数:pbuf    待写入数据 
 *           lenght  待写入数据的长度 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void WriteSingle(unsigned char *pbuf, unsigned char lenght) 
{ 
  unsigned char	i; 
   
  SlaveSelectLOW;  
 
  while(lenght > 0) 
  { 
    *pbuf = (0x1f &*pbuf);	 
     for(i = 0; i < 2; i++) 
     { 
       while (!(IFG2 & UCB0TXIFG));            
       UCB0TXBUF = *pbuf;    
       temp=UCB0RXBUF; 
       pbuf++; 
       lenght--; 
     } 
  } 
                        
  SlaveSelectHIGH; 
} 
 
 
/********************************************************************* 
 * 函数名称:WriteCont 
 * 功    能:连续写寄存器或者特殊地址的多个寄存器 
 * 入口参数:pbuf    待写入数据 
 *           lenght  待写入数据的长度 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void WriteCont(unsigned char *pbuf, unsigned char lenght) 
{ 
  SlaveSelectLOW;  
                               
  *pbuf = (0x20 | *pbuf);  
  *pbuf = (0x3f &*pbuf);	 
                               
  while(lenght > 0) 
  { 
    while (!(IFG2 & UCB0TXIFG));             
    UCB0TXBUF = *pbuf;                  
 
    while (!(IFG2 & UCB0RXIFG)); 
    temp=UCB0RXBUF; 
 
    pbuf++; 
    lenght--; 
  }						 
 
  SlaveSelectHIGH; 
} 
 
 
/********************************************************************* 
 * 函数名称:ReadSingle 
 * 功    能:读单个寄存器 
 * 入口参数:pbuf    指向保存待读出数据缓冲区的指针 
 *           lenght  待读出数据的长度 
 * 出口参数:pbuf    指向保存待读出数据缓冲区的指针 
 * 返 回 值:无 
 ********************************************************************/ 
void ReadSingle(unsigned char *pbuf, unsigned char lenght) 
{ 
  SlaveSelectLOW; 
 
  while(lenght > 0) 
  { 
    *pbuf = (0x40 | *pbuf); 
    *pbuf = (0x5f &*pbuf); 
 
    while (!(IFG2 & UCB0TXIFG)); 
    UCB0TXBUF = *pbuf;  
 
    UCB0CTL0 &= ~UCCKPH; 
 
    SPIStartCondition(); 
    P3SEL |=  BIT3; 
 
    while (!(IFG2 & UCB0TXIFG));  
    UCB0TXBUF = 0x00; 
 
    while (!(IFG2 & UCB0RXIFG));  
    _NOP(); 
    _NOP(); 
    *pbuf = UCB0RXBUF; 
    pbuf++; 
    lenght--; 
 
    UCB0CTL0 |= UCCKPH; 
  } 
 
  SlaveSelectHIGH;         
} 
 
 
/********************************************************************* 
 * 函数名称:ReadCont 
 * 功    能:连续读寄存器或者特殊地址的多个寄存器 
 * 入口参数:pbuf    指向保存待读出数据缓冲区的指针 
 *           lenght  待读出数据的长度 
 * 出口参数:pbuf    指向保存待读出数据缓冲区的指针 
 * 返 回 值:无 
 ********************************************************************/ 
void ReadCont(unsigned char *pbuf, unsigned char lenght) 
{ 
  unsigned char	j; 
 
  SlaveSelectLOW;  
                                 
  *pbuf = (0x60 | *pbuf);  
  *pbuf = (0x7f &*pbuf);	 
                                  
  while (!(IFG2 & UCB0TXIFG));             
  UCB0TXBUF = *pbuf;                   
 
  temp=UCB0RXBUF; 
  UCB0CTL0 &= ~UCCKPH; 
 
  if(*pbuf != 0x6C) 
  { 
    if (lenght != 0x1F) 
    { 
      for (j=0;j<2;j++) 
      { 
        while (!(IFG2 & UCB0TXIFG)); 
        UCB0TXBUF = 0x00;  
 
        while (!(IFG2 & UCB0RXIFG)); 
        _NOP(); 
        _NOP(); 
        temp = UCB0RXBUF; 
      } 
    } 
  } 
 
  while(lenght > 0) 
  { 
    while (!(IFG2 & UCB0TXIFG)); 
    UCB0TXBUF = 0x00;  
 
    while (!(IFG2 & UCB0RXIFG)); 
    _NOP(); 
    _NOP(); 
    *pbuf = UCB0RXBUF; 
    pbuf++; 
    lenght--; 
  } 
   
  UCB0CTL0 |= UCCKPH; 
   
  SlaveSelectHIGH;  
} 
 
 
/********************************************************************* 
 * 函数名称:DirectCommand 
 * 功    能:发送直接命令 
 * 入口参数:pbuf    待发送的命令数据 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void DirectCommand(unsigned char *pbuf) 
{ 
  SlaveSelectLOW;  
                        
  *pbuf = (0x80 | *pbuf);  
  *pbuf = (0x9f &*pbuf);	 
                         
  while (!(IFG2 & UCB0TXIFG));           
  UCB0TXBUF = *pbuf;                 
 
  temp=UCB0RXBUF; 
 
  SPIStartCondition();  
 
  SlaveSelectHIGH;  
 
  P3SEL |=  BIT3; 
} 
 
 
/********************************************************************* 
 * 函数名称:RAWwrite 
 * 功    能:直接写数据或命令 
 * 入口参数:pbuf    待发送的命令数据 
 *           lenght  待发送命令数据的长度 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void RAWwrite(unsigned char *pbuf, unsigned char lenght) 
{ 
  SlaveSelectLOW;  
 
  while(lenght > 0) 
  { 
    while (!(IFG2 & UCB0TXIFG));             
    UCB0TXBUF = *pbuf;                   
     
    temp=UCB0RXBUF; 
 
    pbuf++; 
    lenght--; 
  } 
   
  SlaveSelectHIGH;  
} 
 
 
/********************************************************************* 
 * 函数名称:DirectMode 
 * 功    能:直接模式(无停止条件) 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void DirectMode(void) 
{ 
  OOKdirOUT; 
                          
  SlaveSelectLOW; 
                          
  while (!(IFG2 & UCB0TXIFG)); 
  UCB0TXBUF = ChipStateControl; 
 
  while (!(IFG2 & UCB0RXIFG)); 
  temp=UCB0RXBUF; 
 
  while (!(IFG2 & UCB0TXIFG)); 
  UCB0TXBUF = 0x61;                        
} 
 
 
/********************************************************************* 
 * 函数名称:Response 
 * 功    能:响应主机(PC) 
 * 入口参数:pbuf    响应数据 
 *           lenght  响应数据长度 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void Response(unsigned char *pbuf, unsigned char lenght) 
{ 
  while(lenght > 0) 
  { 
    kputchar('['); 
    Put_byte(*pbuf); 
    kputchar(']'); 
    pbuf++; 
    lenght--; 
  } 
 
  put_crlf(); 
} 
 
 
/********************************************************************* 
 * 函数名称:InitialSettings 
 * 功    能:初始化TRF7960设置 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void InitialSettings(void) 
{ 
  unsigned char	command[2]; 
 
  command[0] = ModulatorControl; 
  command[1] = 0x21;   // 6.78MHz OOK(100%) 
  WriteSingle(command, 2); 
} 
 
 
/********************************************************************* 
 * 函数名称:ReInitialize15693Settings 
 * 功    能:为ISO15693标准重新初始化TRF7960设置 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void ReInitialize15693Settings(void) 
{ 
  unsigned char	command2[2]; 
 
  command2[0] = RXNoResponseWaitTime; 
  command2[1] = 0x14; 
  WriteSingle(command2, 2); 
 
  command2[0] = RXWaitTime; 
  command2[1] = 0x20; 
  WriteSingle(command2, 2); 
} 
 
 
/********************************************************************* 
 * 函数名称:InterruptHandlerReader 
 * 功    能:TRF7960中断处理 
 * 入口参数:Register  TRF7960中断状态寄存器的值 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void InterruptHandlerReader(unsigned char *Register) 
{ 
  unsigned char	len; 
 
#if DBG 
  Put_byte(*Register); 
#endif 
	 
  /* TX正在进行并且FIFO只剩余3字节 */ 
  if(*Register == 0xA0) 
  { 
    i_reg = 0x00; 
#if DBG 
    kputchar('.'); 
#endif 
  } 
 
  /* TX完成 */ 
  else if(*Register == BIT7) 
  {					 
    i_reg = 0x00; 
     
    /* 复位FIFO */ 
    *Register = Reset; 
    DirectCommand(Register); 
#if DBG 
    kputchar('T'); 
#endif 
  } 
 
  /* 碰撞错误 */ 
  else if((*Register & BIT1) == BIT1) 
  { 
    i_reg = 0x02; 
 
    *Register = StopDecoders; 
    DirectCommand(Register); 
 
    CollPoss = CollisionPosition; 
    ReadSingle(&CollPoss, 1); 
 
    len = CollPoss - 0x20; 
 
    if(!POLLING) 
    { 
      kputchar('{'); 
      Put_byte(CollPoss); 
      kputchar('}'); 
    } 
 
    if((len & 0x0f) != 0x00) len = len + 0x10; 
    len = len >> 4; 
 
    if(len != 0x00) 
    { 
      buf[RXTXstate] = FIFO; 
      ReadCont(&buf[RXTXstate], len); 
      RXTXstate = RXTXstate + len; 
    } 
		 
    *Register = Reset; 
    DirectCommand(Register); 
 
    *Register = IRQStatus; 
    *(Register + 1) = IRQMask; 
    ReadCont(Register, 2); 
 
    irqCLR; 
  } 
	 
  /* 接收到EOF */ 
  else if(*Register == BIT6) 
  { 
    if(RXErrorFlag == 0x02) 
    { 
      i_reg = 0x02; 
      return; 
    } 
 
    *Register = FIFOStatus; 
    ReadSingle(Register, 1); 
		 
    *Register = (0x0F &*Register) + 0x01; 
    buf[RXTXstate] = FIFO; 
													 
    ReadCont(&buf[RXTXstate], *Register); 
    RXTXstate = RXTXstate +*Register; 
 
    *Register = TXLenghtByte2; 
    ReadCont(Register, 1); 
 
		 
    if((*Register & BIT0) == BIT0) 
    { 
      *Register = (*Register >> 1) & 0x07;	 
      *Register = 8 -*Register; 
      buf[RXTXstate - 1] &= 0xFF << *Register; 
    }								 
 
#if DBG 
    kputchar('E'); 
#endif 
    *Register = Reset;				 
    DirectCommand(Register); 
 
    i_reg = 0xFF;					 
  } 
	 
  /* RX结束且有9个字节在FIFO中 */ 
  else if(*Register == 0x60) 
  {									 
    i_reg = 0x01; 
		 
    buf[RXTXstate] = FIFO; 
    ReadCont(&buf[RXTXstate], 9);	 
    RXTXstate = RXTXstate + 9; 
#if DBG 
    kputchar('F'); 
#endif 
		 
    if(irqPORT & irqPIN) 
    { 
      *Register = IRQStatus;		 
      *(Register + 1) = IRQMask; 
      ReadCont(Register, 2); 
	 
      irqCLR; 
 
      if(*Register == 0x40) 
      { 
        *Register = FIFOStatus; 
	ReadSingle(Register, 1);					 
	*Register = 0x0F & (*Register + 0x01); 
	buf[RXTXstate] = FIFO;						 
															 
        ReadCont(&buf[RXTXstate], *Register); 
	RXTXstate = RXTXstate +*Register; 
 
	*Register = TXLenghtByte2;			 
	ReadSingle(Register, 1);	 
 
	if((*Register & BIT0) == BIT0) 
	{ 
	  *Register = (*Register >> 1) & 0x07; 
	  *Register = 8 -*Register; 
	  buf[RXTXstate - 1] &= 0xFF << *Register; 
	} 
#if DBG 
        kputchar('E'); 
#endif 
        i_reg = 0xFF;		 
	*Register = Reset; 
	DirectCommand(Register); 
      } 
      else if(*Register == 0x50) 
      {							 
        i_reg = 0x02; 
#if DBG 
        kputchar('x'); 
#endif 
      } 
    } 
    else 
    { 
      Register[0] = IRQStatus; 
      Register[1] = IRQMask; 
      ReadCont(Register, 2); 
 
      if(Register[0] == 0x00) i_reg = 0xFF; 
    } 
  } 
   
  /* CRC错误 */ 
  else if((*Register & BIT4) == BIT4) 
  { 
    if((*Register & BIT5) == BIT5) 
    { 
      i_reg = 0x01;	 
      RXErrorFlag = 0x02; 
    } 
    else 
      i_reg = 0x02;	 
  } 
 
  /* 字节成帧错误 */ 
  else if((*Register & BIT2) == BIT2) 
  {						 
    if((*Register & BIT5) == BIT5) 
    { 
      i_reg = 0x01;	 
      RXErrorFlag = 0x02; 
    } 
    else 
      i_reg = 0x02;	 
  } 
	 
  /* 无响应中断 */ 
  else if(*Register == BIT0) 
  {						 
    i_reg = 0x00; 
#if DBG 
    kputchar('N'); 
#endif 
  } 
	 
  /* 中断寄存器设置错误 */ 
  else 
  {				 
    if(!POLLING) 
    { 
      send_cstring("Interrupt error"); 
      Put_byte(*Register); 
    } 
 
    i_reg = 0x02; 
 
    *Register = StopDecoders; 
    DirectCommand(Register); 
 
    *Register = Reset; 
    DirectCommand(Register); 
 
    *Register = IRQStatus; 
    *(Register + 1) = IRQMask; 
    ReadCont(Register, 2); 
 
    irqCLR; 
  } 
} 
 
 
/********************************************************************* 
 * 函数名称:Port_B 
 * 功    能:MSP430的端口2中断服务函数 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
#pragma vector = PORT2_VECTOR 
__interrupt void Port_B (void) 
{ 
  unsigned char Register[4]; 
 
  stopCounter;					 
 
  do 
  { 
    irqCLR;				 
    Register[0] = IRQStatus;	 
    Register[1] = IRQMask;		 
    ReadCont(Register, 2); 
 
    if(*Register == 0xA0) 
    { 
      goto FINISH; 
    } 
		 
    InterruptHandlerReader(&Register[0]); 
	 
  } while((irqPORT & irqPIN) == irqPIN); 
 
FINISH: 
  __low_power_mode_off_on_exit(); 
} 
 
 
/********************************************************************* 
 * 函数名称:EnableSlotCounter 
 * 功    能:使能时隙计数器 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void EnableSlotCounter(void) 
{ 
  buf[41] = IRQMask; 
  buf[40] = IRQMask; 
  ReadSingle(&buf[41], 1); 
	 
  buf[41] |= BIT0; 
  WriteSingle(&buf[40], 2); 
} 
 
 
/********************************************************************* 
 * 函数名称:DisableSlotCounter 
 * 功    能:禁止时隙计数器 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void DisableSlotCounter(void) 
{ 
  buf[41] = IRQMask; 
  buf[40] = IRQMask; 
  ReadSingle(&buf[41], 1); 
	 
  buf[41] &= 0xfe; 
  WriteSingle(&buf[40], 2); 
}