/**
******************************************************************************************************************************************************************************************
*@file     ws18xxx_interface_driver.c
*@author         
*@data                       
*@version                    v1.0
*@par Copyright(c):
*
*@par History:
*     version:author,date,desc
*     v1.0   :create this file
*
*******************************************************************************************************************************************************************************************
*/
#include "ws18xxx_interface_driver.h"
#include <stdint.h>
#include "rfid.h"
#include "user_uart.h"

#if(INTERFACE_SPI)
/**********SPI WRITE****************/
void SPIWriteByte(unsigned char SPIData)
{
  uint8_t SPICount;                                       // Counter used to clock out the data

  for(SPICount = 0; SPICount < 8; SPICount++)
  {
    if (SPIData & 0x80)
    {
      WS_MOSI_HIGH;
    }
    else
    {
      WS_MOSI_LOW;  
    } 
    WS_SCK_HIGH; 
    WS_SCK_LOW;
    SPIData <<= 1;
  }          	
} 

/********SPI READ*********/
unsigned char SPIReadByte(void)
{
  uint8_t SPICount;                                       // Counter used to clock out the data
  uint8_t SPIData;                  

  SPIData = 0;
  for (SPICount = 0; SPICount < 8; SPICount++)                  // Prepare to clock in the data to be read
  {
    SPIData <<=1;                                               // Rotate the data
    WS_SCK_HIGH;
    if(WS_MISO)
    {
      SPIData|=0x01;
    }                                         
 		WS_SCK_LOW;
  }                                                             // and loop back
  return (SPIData);                              // Finally return the read data
} 
#endif


/*****IIC*****/
//* 起始位 */
#if(INTERFACE_I2C)
void I2C_Start(void)
{
  IIC_SDA_OUT();
	IIC_SDA_H;
  IIC_SCL_H;
  delay_us(1);
  IIC_SDA_L;
  delay_us(1);
  IIC_SCL_L;
  delay_us(1);
}

/* 终止位 */
void I2C_Stop(void)
{
  IIC_SDA_OUT();
  IIC_SCL_L;
  IIC_SDA_L;
  delay_us(1);
  IIC_SCL_H;
  delay_us(1);
  IIC_SDA_H;
  delay_us(1);
}

/*
功能： This function sends a device Ack or NAck signal
输入： When you want to send ACK signal to slave device, you make bAck 0.
When you want to send NACK signal to slave device, you make bAck 1.
返回： NONE
*/
static void I2C_SendAck(uint8_t bAck)
{
  IIC_SCL_L;	
  IIC_SDA_OUT();
  if(bAck)
  IIC_SDA_H;
  else
  IIC_SDA_L;
  delay_us(1);
  IIC_SCL_H;
  delay_us(1);
  IIC_SCL_L;
  delay_us(1);
}



/* 功能：等待从器件 ACK 应答信号
输入：无
输出： 0-有 ACK 信号， 1-无 ACK 信号
*/
static uint8_t I2C_WaitAck(void)
{
  uint8_t ucErrTime =0;
  IIC_SDA_IN();
  IIC_SCL_H;
  delay_us(1);
	while(IIC_SDA_READ())
	{
	   ucErrTime++;
     if(ucErrTime>20)
     {
       IIC_SCL_L;
       delay_us(1);
       return 1;
     }
	}
  IIC_SCL_L;
  delay_us(1);
	//	IIC_SDA_H;
  IIC_SDA_OUT();
	IIC_SDA_H;
  return 0;
}

/* 功能：将字节数据 dat 发送出去 (写)
输入： 8 位 dat 数据
返回：无
说明：数据 dat 可以是数据，也可以是地址
*/
static void I2C_WriteByte(uint8_t dat)
{
  uint8_t i;
	IIC_SCL_L;
  for(i=0; i<8; i++ )
  {
    if(dat & 0x80)
    {
      IIC_SDA_H;
    }
  else
  {
    IIC_SDA_L;
  }
  dat <<= 1;
  IIC_SCL_H;/* 置时钟线为高，通知被控器开始接收数据位 */
  delay_us(1);
  IIC_SCL_L;
  delay_us(1);
  }
}


/*-----------------------------------------------------------------------------
功能：用来接收从器件传过来的数据，并判断总线错误（不发应答信号）
输入：无
返回：接收到的数据
------------------------------------------------------------------------------*/
static uint8_t I2C_ReadByte(void)
{
  uint8_t i,temp = 0;
  IIC_SDA_IN();/* 置数据线为输入方式 */
	delay_us(1);
 // IIC_SCL_L;/* 置时钟线为低，准备接收数据位 */
  for(i= 0; i<8; i++)
  {
		IIC_SCL_L;/* 置时钟线为低，准备接收数据位 */
		delay_us(1);
    IIC_SCL_H; /* 置时钟线为高使数据线上数据有效 */
    delay_us(1);
    temp <<= 1;
    if(IIC_SDA_READ()) /* 读数据位，数据存放于 temp 中 */
    {
      temp++;
    }
   // IIC_SCL_L;
  }
  return temp;
}
/* ----------------- Beautiful part line -------------------------------------*/
/*-----------------------------------------------------------------------------
功能：向 TSM12 写单字节数据或命令
输入： writeData-- 被写数据， WriteAddr-- 待写入数据寄存器地址返回： ErrorStatus
------------------------------------------------------------------------------*/
uint8_t IIC_Write_Byte(uint8_t WriteAddr,uint8_t WriteData)
{
  /* 发送起始位 */
  I2C_Start();
  
  /* 发送器件地址 */
  I2C_WriteByte(DEVICE_WRITE_ADDR);
  delay_us(1);
  if(I2C_WaitAck()) return 1;
  
  /* 发送待写入数据的寄存器地址 */
  I2C_WriteByte(WriteAddr);
  delay_us(1);
  if(I2C_WaitAck()) return 1;
  
  /* 发送数据到寄存器中 */
  I2C_WriteByte(WriteData);
  delay_us(1);
  if(I2C_WaitAck()) return 1;
  /* 产生停止位 */

  I2C_Stop();
  //return SUCCESS;
  return 0;

}
/* ----------------------------------------------------------------------------
功能：向 GT216L 写双字节数据或命令
输入： writeData1 ， 2--被写数据， WriteAddr-- 待写入数据寄存器地址
返回： ErrorStatus
------------------------------------------------------------------------------*/
uint8_t IIC_Write_2Byte(uint8_t WriteAddr, uint8_t WriteData1, uint8_t WriteData2)
{
  /* 发送起始位 */
  I2C_Start();
  /* 发送器件地址 */
  I2C_WriteByte(DEVICE_WRITE_ADDR);
  if(I2C_WaitAck()) return 1;
  /* 发送待写入数据的寄存器起始地址 */
  I2C_WriteByte(WriteAddr);
  if(I2C_WaitAck()) return 1;
  /* 发送数据 1 到寄存器中，即 LSB */
  I2C_WriteByte(WriteData1);
  if(I2C_WaitAck()) return 1;
  /* 发送数据 2 到寄存器中，即 MSB */
  I2C_WriteByte(WriteData2);
  if(I2C_WaitAck()) return 1;
  /* 产生停止位 */
  I2C_Stop();
  return 0;
}


/*******************************************************************************
* 名 称: TSM_ReadOneByte()
* 功 能: 读单个字节数据* 入口参数 : writeAddr-- 待写入数据寄存器地址
* 出口参数 : 被读出数据 , ERROR
* 说 明:
*******************************************************************************/
uint8_t IIC_ReadOneByte(uint8_t writeAddr)
{
  uint8_t buffer = 0;
  // 第一阶段
  I2C_Start();
  I2C_WriteByte(DEVICE_WRITE_ADDR);
  if(I2C_WaitAck()) goto L_OUT;
  I2C_WriteByte(writeAddr);
  if(I2C_WaitAck()) goto L_OUT;
  I2C_Stop();
  // 第二阶段
  I2C_Start();
  I2C_WriteByte(DEVICE_READ_ADDR);
  if(I2C_WaitAck()) goto L_OUT;
  buffer = I2C_ReadByte();
  I2C_SendAck(1);
  I2C_Stop();
  return buffer;
  L_OUT:
  I2C_Stop();
  return 1;
}  

/*-----------------------------------------------------------------------------
功能：连续读多个字节数据
输入： writeAddr -- 待写入数据寄存器地址
*butter --读缓冲区的地址。
length -- 到的数据长度
返回： ErrorStatus
------------------------------------------------------------------------------*/
uint8_t IIC_ReadMutiBytes(uint8_t writeAddr, uint8_t *buffer, uint8_t length)
{
  uint8_t i;
  /* Power ON */
  
  // 第一阶段
  /* 发送起始位 */
  I2C_Start();
  /* 发送器件地址 */
  I2C_WriteByte(DEVICE_WRITE_ADDR);
  if(I2C_WaitAck()) goto L_OUT;
  /* 发送被操作寄存器首地址 */
  I2C_WriteByte(writeAddr);
  if(I2C_WaitAck()) goto L_OUT;
  /* 产生停止位 */
  I2C_Stop();
  // 第二阶段
  /* 发送起始位 */
  I2C_Start();
  /* 发送 GT216L 器件地址 */
  I2C_WriteByte(DEVICE_READ_ADDR);
  if(I2C_WaitAck()) goto L_OUT;
  /* 产生一个应该应答信号 */
  for( i = 0; i<length; i++ )
  {
  buffer[i] = I2C_ReadByte();
  if( i == (length-1) )
  I2C_SendAck(1); // NAck = 1
  else
  I2C_SendAck(0); // Ack = 0
  }/* 产生停止位 */
  I2C_Stop();
  return 0;
  L_OUT:
  /* 产生停止位 */
  I2C_Stop();
  return 1;
}
#endif

/***********************************************************************************************
*串口写一个字节
***********************************************************************************************/
void Uart_WriteByte(uint8_t Byte)
{
   uart_send_data(UART0, Byte);
}
/***********************************************************************************************
*串口读取一个字节
uint32_t ui_uart_readbuf(ws_dev  dev,uint8_t *buf,uint32_t len)
{
	uint32_t read_len = 0;
	while((read_len < len) && ui_uart_recvchar(dev,&buf[read_len])){
		read_len ++;
	}
	return read_len;
}
***********************************************************************************************/
uint8_t Uart_ReadByte(uint8_t *buf,uint8_t len)
{  
	  uint8_t temp;
	  temp = uart_receive_data(UART0);
	  return temp;
}

/************NFC READ****************/
unsigned char ReadRawRC(unsigned char Address)
{ 
	 uint8_t ucAddr,ucResult=0;
    
#if (INTERFACE == INTERFACE_SPI)
    {
        WS_NSS_LOW;
        ucAddr = ((Address<<1)&0x7E)|0x80;
        SPIWriteByte(ucAddr);
        ucResult=SPIReadByte();
        WS_NSS_HIGH;
    }
#elif (INTERFACE == INTERFACE_I2C) //IIC
    {
		   ucResult = IIC_ReadOneByte(Address);
    }
#else
    {   
        ucAddr = Address|0x80;
			  delay_ms(1);
        Uart_WriteByte(ucAddr); 
        delay_ms(2);    
			  ucResult = uart_receive_data(UART0);		
    }
#endif
    return ucResult;
}

/**********NFC WRITE******************/
void WriteRawRC(unsigned char Address, unsigned char value)
{  
    uint8_t ucAddr;

#if (INTERFACE == INTERFACE_SPI)
    {
			  WS_NSS_LOW;
        ucAddr = ((Address<<1)&0x7E);
        SPIWriteByte(ucAddr);
        SPIWriteByte(value);
        WS_NSS_HIGH;
    }
#elif (INTERFACE == INTERFACE_I2C) //IIC
    {
	    	IIC_Write_Byte(Address,value);
    }
#else
    {
        ucAddr = Address&0x7F;
//			if(uart_is_received_data_ready(UART0) & UART_LINE_STATUS_RX_RECVD)//串口处于接收状态
//			{
				Uart_WriteByte(ucAddr);  
		//	}				
        delay_ms(2);	
				Uart_WriteByte(value);
    }
#endif
    
}

/**
 ****************************************************************
 * @brief SetBitMask() 
 *
 * 将寄存器的某些bit位值1
 *
 * @param: reg 寄存器地址
 * @param: mask 需要置位的bit位
 ****************************************************************
 */
void SetBitMask(unsigned char reg,unsigned char mask)  
{
   uint8_t tmp = 0x0;
   tmp = ReadRawRC(reg);
   WriteRawRC(reg,tmp | mask);  // set bit mask
}

/**
 ****************************************************************
 * @brief ClearBitMask() 
 *
 * 将寄存器的某些bit位清0
 *
 * @param: reg 寄存器地址
 * @param: mask 需要清0的bit位
 ****************************************************************
 */
void ClearBitMask(unsigned char reg,unsigned char mask)  
{
   uint8_t tmp = 0x0;
   tmp = ReadRawRC(reg);//SPI发送地址 SPI接收数据
   WriteRawRC(reg, tmp & ~mask);  // clear bit mask //将数据的位清零
} 


#if 0
#if (HARD_SPI)	
	nfc_master_spi_init();	
	gpio_remap_config(NSS_PIN,GPIO_Remap_GPIO);//NSS
	gpio_init(NSS_PIN,GPIO_Mode_Output);
#else
	INIT_MISO_ON(); 	
#endif
#endif

//	set_spi_dile();








