www.pudn.com > rfid.rar > host.c, change:2012-05-14,size:16787b


/******************************************************************************* 
 * 文件名称:host.c 
 * 功    能:HOST模式相关代码(PC作为HOST)以及SPI设置 
 * 作    者:Ronnie 
 * 公    司:湘潭斯凯电子科技有限公司 
 *           www.sikai-tech.com 
 * 日    期:2011-06-22 
 ******************************************************************************/ 
 
 
/* 包含头文件 */ 
/********************************************************************/ 
#include "hardware.h" 
#include "spi.h" 
#include "15693.h" 
#include "globals.h" 
#include "tag-it.h" 
#include "14443.h" 
#include "host.h" 
#include "findtags.h" 
#include "lcd.h" 
/********************************************************************/ 
 
 
/* 变量定义 */ 
/********************************************************************/ 
unsigned char	RXdone; 
unsigned char	ENABLE; 
unsigned char	FirstSPIdata = 1; 
unsigned char   LCDcon = 0;  
/********************************************************************/ 
 
 
/********************************************************************* 
 * 函数名称:UARTset 
 * 功    能:串口设置 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void UARTset(void) 
{ 
  /* 设置P3.4,P3.5为UART模式 */ 
  P3SEL |= BIT4 + BIT5; 
   
  /* 设置P3.4为输出 */ 
  P3DIR |= BIT4; 
   
  /* 禁止UART */ 
  UCA0CTL1 |= UCSWRST; 
  UCA0CTL0 = 0x00; 
   
  /* 选择使用SMCLK */ 
  UCA0CTL1 |= UCSSEL_2; 
   
  /* 波特率115200 */ 
  UCA0BR0 = BAUD0; 
  UCA0BR1 = BAUD1; 
   
  /* 调制参数UCBRSx = 5 */ 
  UCA0MCTL = 0; 
   
  /* 初始化USCI状态机 */ 
  UCA0CTL1 &= ~UCSWRST; 
   
  /* 使能USCI_AO RX中断 */ 
  IE2 |= UCA0RXIE; 
} 
 
 
/********************************************************************* 
 * 函数名称:USARTset 
 * 功    能:SPI设置 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void USARTset(void) 
{ 
  /* 禁止USCI */ 
  UCB0CTL1 |= UCSWRST; 
   
  /* 3引脚,8比特SPI主机 */ 
  UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; 
   
  /* 选择使用SMCLK */ 
  UCB0CTL1 |= UCSSEL_2; 
   
  /* P3.1为UCB0SIMO,P3.2为UCB0SOMI,P3.3为UCB0CLK */ 
  UCB0BR0 = 0x00; 
  UCB0BR1 = 0x00; 
  P3SEL |= BIT1 + BIT2 + BIT3; 
 
  /* P3.0为从机选择 */ 
  SlaveSelectPortSet 
     
  /* 从机选择信号初始化为高 */ 
  SlaveSelectHIGH 
 
  /* 初始化USCI状态机 */ 
  UCB0CTL1 &= ~UCSWRST; 
} 
 
 
/********************************************************************* 
 * 函数名称:USARTEXTCLKset 
 * 功    能:SPI设置 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void USARTEXTCLKset(void) 
{ 
  /* 禁止USCI */ 
  UCB0CTL1 |= UCSWRST; 
   
  /* 3引脚,8比特SPI主机 */ 
  UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; 
 
  /* 选择使用SMCLK */ 
  UCB0CTL1 |= UCSSEL_2; 
   
  /* P3.1为UCB0SIMO,P3.2为UCB0SOMI,P3.3为UCB0CLK */ 
  UCB0BR0 = 0x00; 
  UCB0BR1 = 0x00; 
  P3SEL |= BIT1 + BIT2 + BIT3; 
 
  /* P3.0为从机选择 */ 
  SlaveSelectPortSet 
     
  /* 从机选择信号初始化为高 */ 
  SlaveSelectHIGH 
 
  /* 初始化USCI状态机 */ 
  UCB0CTL1 &= ~UCSWRST; 
} 
 
 
/********************************************************************* 
 * 函数名称:BaudSet 
 * 功    能:串口波特率相关设置 
 * 入口参数:mode  模式设置 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void BaudSet(unsigned char mode) 
{ 
  /* 使用外部6.78MHz时钟时,115200bps的相应设置 */ 
  if(mode == 0x00) 
  { 
    UCA0BR0 = BAUD0; 
    UCA0BR1 = BAUD1; 
  } 
  /* 使用内部DCO = 4.9MHz时,115200bps的相应设置 */ 
  else 
  { 
    UCA0BR0 = BAUD0EN; 
    UCA0BR1 = BAUD1EN; 
  } 
} 
 
 
/********************************************************************* 
 * 函数名称:kputchar 
 * 功    能:从串口输出一个字符 
 * 入口参数:TXchar  待输出的字符 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void kputchar(char TXchar) 
{ 
  /* 等待TX缓冲区就绪 */ 
  while(!(IFG2 & UCA0TXIFG)); 
 
  /* 发送字符 */ 
  UCA0TXBUF = TXchar; 
} 
 
 
/********************************************************************* 
 * 函数名称:put_bksp 
 * 功    能:从串口输出一个退格Backspace符号 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void put_bksp(void) 
{ 
  kputchar('\b'); 
  kputchar(' '); 
  kputchar('\b'); 
} 
 
 
/********************************************************************* 
 * 函数名称:put_space 
 * 功    能:从串口输出一个空格符号 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void put_space(void) 
{ 
  kputchar(' '); 
} 
 
 
/********************************************************************* 
 * 函数名称:put_crlf 
 * 功    能:从串口输出回车+换行符号 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void put_crlf(void) 
{ 
  kputchar('\r'); 
  kputchar('\n'); 
} 
 
 
/********************************************************************* 
 * 函数名称:send_cstring 
 * 功    能:从串口输出字符串 
 * 入口参数:pstr  指向待输出字符串的指针 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void send_cstring(char *pstr) 
{ 
  while(*pstr != '\0') 
  { 
    kputchar(*pstr++); 
  } 
} 
 
 
/********************************************************************* 
 * 函数名称:Nibble2Ascii 
 * 功    能:将4比特值转换为相应的十六进制字符,例如将10转换为A, 
 *           15转换为F。 
 * 入口参数:anibble  待转换的4比特值 
 * 出口参数:无 
 * 返 回 值:相应的六进制字符 
 ********************************************************************/ 
unsigned char Nibble2Ascii(unsigned char anibble) 
{ 
  unsigned char	AsciiOut = anibble; 
 
  if(anibble > 9) AsciiOut = AsciiOut + 0x07; 
 
  AsciiOut = AsciiOut + 0x30; 
 
  return(AsciiOut); 
} 
 
 
/********************************************************************* 
 * 函数名称:Put_byte 
 * 功    能:从串口将字节高4位相应十六进制字符输出,再将字节低4位相应 
 *           十六进制字符输出。 
 * 入口参数:abyte  待输出字节 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void Put_byte(unsigned char abyte) 
{ 
  unsigned char	temp1, temp2; 
 
  temp1 = (abyte >> 4) & 0x0F; 
  temp2 = Nibble2Ascii(temp1); 
  kputchar(temp2); 
 
  temp1 = abyte & 0x0F; 
  temp2 = Nibble2Ascii(temp1); 
  kputchar(temp2); 
} 
 
 
/********************************************************************* 
 * 函数名称:Get_nibble 
 * 功    能:从串口读取一个十六进制字符 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:读取到的十六进制字符 
 ********************************************************************/ 
unsigned char Get_nibble(void) 
{ 
  unsigned char	reading; 
  //unsigned char	rxdata; 
 
  reading = 1; 
  while(reading) 
  { 
    LPM0; 
    if(rxdata >= 'a') 
    { 
      rxdata -= 32; 
    } 
    if(((rxdata >= '0') && (rxdata <= '9')) || ((rxdata >= 'A') && (rxdata <= 'F'))) 
    { 
      reading = 0; 
      kputchar(rxdata); 
      if(rxdata > '9') 
      { 
        rxdata = (rxdata & 0x0F) + 9; 
      } 
    } 
  } 
  return(rxdata); 
} 
 
 
/********************************************************************* 
 * 函数名称:Get_line 
 * 功    能:从串口获取一行字符 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:0:成功;其它值:错误 
 * 注    意:只允许获取"0,..,9","A,..,F" or "a,..,f", <CR>,<LF>, 
 *           <backspace>,忽略其它字符。  
 ********************************************************************/ 
unsigned char Get_line(unsigned char *pline) 
{ 
  unsigned char	reading, err_flg; 
  unsigned char	pos; 
  unsigned char	Length_Byte; 
 
  err_flg = 0;	 
  Length_Byte = 0xff; 
 
  if(!FirstSPIdata) 
  { 
    LPM0;	 
    while(rxdata != '0') 
    { 
    } 
  } 
  else 
  { 
    FirstSPIdata = 0; 
  } 
 
  kputchar('0'); 
  LPM0; 
  while(rxdata != '1') 
  { 
  } 
 
  kputchar('1'); 
 
  RXdone = 0; 
 
  pos = 0; 
  reading = 1; 
  while(reading) 
  { 
    while(RXdone == 0); 
 
    RXdone = 0; 
    switch(rxdata) 
    { 
      case '\r': 
        break;								 
 
      case '\n': 
	reading = 0;						 
	break; 
 
      case '\b': 
	if(pos > 0) 
	{	 
	  pos--;						 
	  put_bksp();						 
	  if(pos & 0x01 > 0) 
	  {							 
	    *pline--; 
	    *pline &= 0xF0;				 
	  } 
	} 
	break; 
 
      default: 
	if(rxdata >= 'a') 
	{ 
	  rxdata -= 32; 
	} 
 
	if((rxdata < '0') || ((rxdata > '9') && (rxdata < 'A')) || (rxdata > 'F')) 
	{ 
	  break; 
	} 
 
	if(pos++ < 2 * BUF_LENGTH) 
	{ 
	  kputchar(rxdata);				 
	  if(rxdata > '9') 
	  {								 
	    rxdata = (rxdata & 0x0F) + 9; 
	  } 
 
	  if((pos & 0x01) == 0) 
	  {								 
	    *pline += (rxdata & 0x0F);	 
	    if(pos == 2) 
	    { 
	      Length_Byte = *pline; 
	    } 
 
	    pline++; 
	    if(((Length_Byte - 1) * 2) == pos) 
	    { 
	      reading = 0; 
	    } 
	  } 
	  else 
	  { 
	    rxdata = rxdata << 4; 
	    *pline = rxdata; 
	  } 
	} 
	else 
        { 
	  err_flg = 1; 
        } 
    } 
  } 
 
  return(err_flg);	 
} 
 
 
/********************************************************************* 
 * 函数名称:RXhandler 
 * 功    能:串口接收中断服务函数 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
#pragma vector = USCIAB0RX_VECTOR 
__interrupt void RXhandler (void) 
{ 
  if (IFG2 & UCA0RXIFG) 
  {	 
    rxdata = UCA0RXBUF; 
    RXdone = 1; 
    if(ENABLE == 0) 
    { 
      TRFEnable; 
      BaudSet(0x01); 
      OSCsel(0x01); 
      InitialSettings(); 
      send_cstring("Reader enabled."); 
      ENABLE = 1; 
    } 
 
    __low_power_mode_off_on_exit(); 
 
    if(FirstSPIdata) 
    { 
      LCDcon = 1; 
      irqOFF; 
      stopCounter; 
      asm("mov.w #HostCommands,10(SP)"); 
    } 
  } 
} 
 
 
/********************************************************************* 
 * 函数名称:HostCommands 
 * 功    能:处理来自PC的命令 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void HostCommands () 
{ 
  char *phello; 
  unsigned char *pbuf, count; 
       
  stopCounter; 
  
  POLLING = 0; 
   
  while(1) 
  { 
    pbuf = &buf[0]; 
    Get_line(pbuf); 
    put_crlf(); 
 
    pbuf = &buf[4]; 
    RXErrorFlag = 0; 
 
    if(*pbuf == 0xFF) 
    {			 
      phello = "TRF7960TB \r\n"; 
      send_cstring(phello); 
    } 
    else if(*pbuf == 0x10) 
    {			 
      send_cstring("Register write request.\r\n"); 
      count = buf[0] - 8; 
      WriteSingle(&buf[5], count); 
    } 
    else if(*pbuf == 0x11) 
    { 
      phello = "Continous write request.\r\n"; 
      send_cstring(phello); 
      count = buf[0] - 8; 
      WriteCont(&buf[5], count); 
    } 
    else if(*pbuf == 0x12) 
    { 
      phello = "Register read request.\r\n"; 
      send_cstring(phello); 
      count = buf[0] - 8; 
      ReadSingle(&buf[5], count); 
      Response(&buf[5], count); 
    } 
    else if(*pbuf == 0x13) 
    { 
      send_cstring("Continous read request\r\n"); 
      pbuf++; 
      count = *pbuf; 
			 
      pbuf++; 
      buf[5] = *pbuf; 
 
      ReadCont(&buf[5], count); 
      Response(&buf[5], count); 
    } 
    else if(*pbuf == 0x14) 
    {									 
      phello = "ISO 15693 Inventory request.\r\n"; 
      send_cstring(phello); 
      flags = buf[5]; 
      if(flags & 0x10) 
      { 
        AFI = buf[7]; 
      } 
      else 
      { 
        AFI = 0; 
      } 
      for(count = 0; count < 8; count++) buf[count + 20] = 0x00; 
      InventoryRequest(&buf[20], 0x00); 
    } 
    else if(*pbuf == 0x15) 
    {									 
      phello = "Direct command.\r\n"; 
      send_cstring(phello); 
      DirectCommand(&buf[5]); 
    } 
    else if(*pbuf == 0x16) 
    {									 
      phello = "RAW mode.\r\n"; 
      send_cstring(phello); 
      count = buf[0] - 8; 
      RAWwrite(&buf[5], count); 
    } 
    else if(*pbuf == 0x18) 
    {									 
      phello = "Request mode.\r\n"; 
      send_cstring(phello); 
      count = buf[0] - 8; 
      RequestCommand(&buf[0], count, 0x00, 0); 
    } 
    else if(*pbuf == 0x19) 
    {									 
      phello = "14443A Request - change bit rate.\r\n"; 
      send_cstring(phello); 
      count = buf[0] - 9; 
      Request14443A(&buf[1], count, buf[5]); 
    } 
    else if(*pbuf == 0x34) 
    {									 
      phello = "Ti SID Poll.\r\n"; 
      send_cstring(phello); 
      flags = buf[5]; 
      for(count = 0; count < 4; count++) buf[count + 20] = 0x00; 
      TIInventoryRequest(&buf[20], 0x00); 
    } 
    else if(*pbuf == 0x0F) 
    {									 
      phello = "Direct mode.\r\n"; 
      send_cstring(phello); 
      DirectMode(); 
    } 
    else if((*pbuf == 0xB0) || (*pbuf == 0xB1)) 
    {			 
      phello = "14443B REQB.\r\n"; 
      send_cstring(phello); 
      AnticollisionSequenceB(*pbuf, *(pbuf + 1)); 
    } 
    else if((*pbuf == 0xA0) || (*pbuf == 0xA1)) 
    {					 
      phello = "14443A REQA.\r\n"; 
      send_cstring(phello); 
      AnticollisionSequenceA(*(pbuf + 1)); 
    } 
    else if(*pbuf == 0xA2) 
    { 
      phello = "14443A Select.\r\n"; 
      send_cstring(phello); 
      switch(buf[0]) 
      { 
        case 0x0D: 
	  for(count = 1; count < 6; count++)  
            buf[99 + count] = *(pbuf + count); 
	  break; 
 
	case 0x11: 
	  for(count = 1; count < 11; count++)  
            buf[100 + count] = *(pbuf + count); 
	  buf[100] = 0x88; 
	  break; 
 
	case 0x15: 
	  for(count = 1; count < 5; count++)  
            buf[100 + count] = *(pbuf + count); 
	  buf[100] = 0x88; 
	  buf[105] = 0x88; 
	  for(count = 1; count < 10; count++)  
            buf[105 + count] = *(pbuf + count + 4); 
      } 
      buf[0] = ISOControl; 
      buf[1] = 0x88;	 
      WriteSingle(buf, 2); 
 
      buf[5] = 0x26; 
      if(RequestCommand(&buf[0], 0x00, 0x0f, 1) == 0) 
      { 
        if(SelectCommand(0x93, &buf[100])) 
	{ 
	  if(SelectCommand(0x95, &buf[105])) SelectCommand(0x97, &buf[110]); 
	} 
      } 
    } 
    else if(*pbuf == 0x03) 
    {				 
      if(*(pbuf + 1) == 0x00) 
      { 
      } 
      else if(*(pbuf + 1) == 0xFF) 
      { 
        BaudSet(*(pbuf + 1)); 
	OSCsel(*(pbuf + 1)); 
	TRFDisable; 
	send_cstring("Reader disabled."); 
	ENABLE = 0; 
      } 
      else if(*(pbuf + 1) == 0x0A) 
      { 
        BaudSet(0x00); 
	OSCsel(0x00); 
	send_cstring("External clock."); 
      } 
      else if(*(pbuf + 1) == 0x0B) 
      { 
        BaudSet(0x01); 
	OSCsel(0x01); 
	send_cstring("Internal clock."); 
      } 
      else 
      { 
      } 
    } 
    else if(*pbuf == 0xF0) 
    {					 
      buf[0] = ChipStateControl; 
      buf[1] = ChipStateControl; 
      ReadSingle(&buf[1], 1); 
      if(*(pbuf + 1) == 0xFF) 
        buf[1] |= BIT2; 
      else 
	buf[1] &= ~BIT2; 
      WriteSingle(buf, 2); 
    } 
    else if(*pbuf == 0xF1) 
    {					 
      buf[0] = ChipStateControl; 
      buf[1] = ChipStateControl; 
      ReadSingle(&buf[1], 1); 
      if(*(pbuf + 1) == 0xFF) 
        buf[1] &= ~BIT3; 
      else 
	buf[1] |= BIT3; 
      WriteSingle(buf, 2); 
    } 
    else if(*pbuf == 0xF2) 
    {					 
      buf[0] = ChipStateControl; 
      buf[1] = ChipStateControl; 
      ReadSingle(&buf[1], 1); 
      if(*(pbuf + 1) == 0xFF) 
        buf[1] &= ~BIT4; 
      else 
	buf[1] |= BIT4; 
      WriteSingle(buf, 2); 
    } 
    else if(*pbuf == 0xFE) 
    {					 
      phello = "Firmware Version 1.0 \r\n"; 
      send_cstring(phello); 
    } 
    else if(*pbuf == 0xF3) 
    {	 
    } 
    else if(*pbuf == 0xF4) 
    { 
    } 
    else if(*pbuf == 0xF5) 
    {					 
      LEDtagitON; 
    } 
    else if(*pbuf == 0xF6) 
    {					 
      LEDtagitOFF; 
    } 
    else if(*pbuf == 0xF7) 
    {					 
      LED15693ON; 
    } 
    else if(*pbuf == 0xF8) 
    {			 
      LED15693OFF; 
    } 
    else if(*pbuf == 0xF9) 
    {					 
      LEDtypeBON; 
    } 
    else if(*pbuf == 0xFA) 
    { 
      LEDtypeBOFF; 
    } 
    else if(*pbuf == 0xFB) 
    {					 
      LEDtypeAON; 
    } 
    else if(*pbuf == 0xFC) 
    {					 
      LEDtypeAOFF; 
    } 
    else if (*pbuf == 0xE6) 
    { 
      AnticollisionSequenceA(0x01); 
      put_crlf(); 
      for (count = 0; count<20; count++) 
      { 
      } 
      AnticollisionSequenceA(0x01); 
  }     
    else 
    { 
      phello = "Unknown command.\r\n"; 
      send_cstring(phello); 
    } 
 
    while(!(IFG2 & UCA0TXIFG)); 
             
    if(LCDcon) 
    { 
      LCDcon = 0; 
     
      LCD_Clear(); 
      LCD_WriteString(10,0,"RFID-13.56MHz-Demo");  
      LCD_WriteString(10,3,"Connected to PC...");  
    } 
  } 
}