天天看点

20141227 【 RFID 2.4GHz 读写器及标签代码 】

结构:

AppDemo

    RFID_2.4GHz_Reader_Demo.c // RFID的2.4G读写器应用程序

    RFID_2.4GHz_Tag_Demo.c // RFID的2.4G标签应用程序

READER

    hal_2.4GHz_Reader.c // RFID的2.4G读写器硬件层驱动

    hal_2.4GHz_Tag.c // RFID的2.4G标签硬件层驱动

SYSCLK

    SYSCLK.c // MCU时钟选择

UART0

    UART0.c // CC2530的UART0驱动

/*******************************************************************************
 * 文件名称:RFID_2.4GHz_Reader_Demo.c
 * 功    能:RFID基础实验工程 --- 2.4GHz RFID 读卡器演示
 *           将接收到的Tag信息通过CC2530的UART0输出,波特率为115200
 * 作    者:
 * 公    司:
 ******************************************************************************/

#if !defined ( TAG_FLAG )
/* 包含头文件 */
/*************************************************************/
#include "hal_2.4GHz_Reader.h"  // RFID-2.4GHz-Reader硬件抽象层头文件
#include "UART0.h"              // CC2530的UART0驱动的头文件
#include "SYSCLK.h"             // CC2530的时钟选择头文件
#include "stdlib.h"             // C语言标准库文件
#include "stdio.h"              // C语言标准输入/输出库文件
/*************************************************************/


/* RFID Reader的数据管道0接收地址为"READR" */
/*************************************************************/
unsigned char RFID_READER_ADDR_P0[] = {'R', 'D', 'A', 'E', 'R'};
/*************************************************************/


/* XXTEA加密块数量 */
/*************************************************************/
#define TEA_ENCRYPTION_BLOCK_COUNT 4
/*************************************************************/


/* XXTEA密钥 */
/*************************************************************/
const long XXTEA_KEY[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
/*************************************************************/


/* XXTEA算法相关变量和宏定义 */
/*************************************************************/
unsigned long z, y, sum, tmp, mx;
unsigned char e;
#define TEA_ROUNDS_COUNT (6+52/4)
#define MX ((((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(XXTEA_KEY[(p&3)^e]^z)))
#define DELTA 0x9E3779B9
/*************************************************************/


/* 数据包结构体类型 */
/*************************************************************/
typedef struct
{
  unsigned char len;        // 数据包的长度字段(单位:字节)
  unsigned char protocol;   // 数据包的协议类型字段
  unsigned char flags;      // 数据包的标志字段(按下Tag上的按键,flag为0x02;否则为0x00)
  unsigned char txpower;    // 数据包的发送功率字段
  unsigned long seq;        // 数据包的序号字段
  unsigned long oid;        // 数据包的对象标识符字段
  unsigned short reserved;  // 数据包的保留字段
  unsigned short crc;       // 数据包的CRC字段
}PKT;
/*************************************************************/


/* 加密数据包结构体类型 */
/*************************************************************/
typedef union
{
  PKT pkt;
  unsigned long dataUL[TEA_ENCRYPTION_BLOCK_COUNT];
  unsigned char dataB[TEA_ENCRYPTION_BLOCK_COUNT * sizeof (unsigned long)];
}ENCRYPTED_PKT;
/*************************************************************/


/* 用于Tag的加密数据包结构体变量 */
/*************************************************************/
static ENCRYPTED_PKT g_Tag;
/*************************************************************/


/* "打乱"功能宏 — SHUFFLE */
/*************************************************************/
#define SHUFFLE(a,b) 	tmp = g_Tag.dataB[a];\
			g_Tag.dataB[a] = g_Tag.dataB[b];\
			g_Tag.dataB[b] = tmp;
/*************************************************************/


/*********************************************************************
 * 函数名称:htonl
 * 功    能:将主机字节顺序表达的32位无符号长整形数转换成网络字节顺序
 *           表达的32位无符号长整形数
 * 入口参数:hostlong  主机字节顺序表达的32位无符号长整形数
 * 出口参数:无
 * 返 回 值:网络字节顺序表达的32位无符号长整形数
 ********************************************************************/
static unsigned long htonl (unsigned long hostlong)
{
  unsigned long res;

  ((unsigned char *) &res)[0] = ((unsigned char *) &hostlong)[3];
  ((unsigned char *) &res)[1] = ((unsigned char *) &hostlong)[2];
  ((unsigned char *) &res)[2] = ((unsigned char *) &hostlong)[1];
  ((unsigned char *) &res)[3] = ((unsigned char *) &hostlong)[0];

  return res;
}


/*********************************************************************
 * 函数名称:htons
 * 功    能:将主机字节顺序表达的16位无符号短整形数转换成网络字节顺序
 *           表达的16位无符号短整形数
 * 入口参数:hostlong  主机字节顺序表达的16位无符号短整形数
 * 出口参数:无
 * 返 回 值:网络字节顺序表达的16位无符号短整形数
 ********************************************************************/
static unsigned short htons (unsigned short hostshort)
{
  unsigned short res;

  ((unsigned char *) &res)[0] = ((unsigned char *) &hostshort)[1];
  ((unsigned char *) &res)[1] = ((unsigned char *) &hostshort)[0];

  return res;
}


/*********************************************************************
 * 函数名称:Shuffle_TX_ByteOrder
 * 功    能:"打乱"待发送数据的字节顺序
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
static void Shuffle_TX_ByteOrder (void)
{
  unsigned char tmp;

  SHUFFLE (0 + 0, 3 + 0);
  SHUFFLE (1 + 0, 2 + 0);
  SHUFFLE (0 + 4, 3 + 4);
  SHUFFLE (1 + 4, 2 + 4);
  SHUFFLE (0 + 8, 3 + 8);
  SHUFFLE (1 + 8, 2 + 8);
  SHUFFLE (0 + 12, 3 + 12);
  SHUFFLE (1 + 12, 2 + 12);
}


/*********************************************************************
 * 函数名称:CRC16
 * 功    能:CRC16计算
 * 入口参数:buffer  指向存储待进行CRC16计算的数据的缓冲区的指针
 *           size    待进行CRC16计算的数据的长度    
 * 出口参数:无
 * 返 回 值:CRC16计算结果
 * 注    意:CC2530自身带有CRC计算功能,但为了提高代码的可移植性,我们
 *           不使用CC2530自身带有的CRC计算功能,而使用该函数。
 ********************************************************************/
static unsigned short CRC16 (const unsigned char *buffer, unsigned char size)
{
  unsigned short crc = 0xFFFF;
  
  if(buffer)
  {
    while(size--)
    {
      crc = (crc >> 8) | (crc << 8);
      crc ^= *buffer++;
      crc ^= ((unsigned char) crc) >> 4;
      crc ^= crc << 12;
      crc ^= (crc & 0xFF) << 5;
    }
  }
  
  return crc;
}

/*********************************************************************
 * 函数名称:MX_Update
 * 功    能:XXTEA算法的MX更新
 * 入口参数:p
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
static void MX_Update (unsigned char p)
{
  mx = MX;
}


/*********************************************************************
 * 函数名称:MX_Decode
 * 功    能:XXTEA算法的MX解码
 * 入口参数:p
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
static void MX_Decode (unsigned char p)
{
  MX_Update (p);
  y = tmp - mx;
}


/*********************************************************************
 * 函数名称:MX_Decode
 * 功    能:XXTEA解码
 * 入口参数:p
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void XXTEA_Decode (void)
{
  y = g_Tag.dataUL[0];
  sum = DELTA * TEA_ROUNDS_COUNT;

  while (sum != 0)
    {
      e = sum >> 2 & 3;

      z = g_Tag.dataUL[2];
      tmp = g_Tag.dataUL[3];
      MX_Decode (3);
      g_Tag.dataUL[3] = y;

      z = g_Tag.dataUL[1];
      tmp = g_Tag.dataUL[2];
      MX_Decode (2);
      g_Tag.dataUL[2] = y;

      z = g_Tag.dataUL[0];
      tmp = g_Tag.dataUL[1];
      MX_Decode (1);
      g_Tag.dataUL[1] = y;

      z = g_Tag.dataUL[3];
      tmp = g_Tag.dataUL[0];
      MX_Decode (0);
      g_Tag.dataUL[0] = y;

      sum -= DELTA;
    }
}

void changeToAscii (unsigned char *pUString, unsigned char teData)
{
  unsigned char temp8i;
  
  temp8i = teData >> 4;
  if ( temp8i < 0x0a)
    *pUString = temp8i + 0x30;
  else
    *pUString = temp8i + 0x37;
  
  pUString++;
  temp8i = teData & 0x0f;
  if ( temp8i < 0x0a)
    *pUString = temp8i + 0x30;
  else
    *pUString = temp8i + 0x37;
}
/*********************************************************************
 * 函数名称:InitNRF4Reader
 * 功    能:针对RFID Reader功能初始化nRF24L01+
 * 入口参数:无    
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void InitNRF4Reader(void)
{
  hal_nrf_nop();
  
  hal_nrf_write_reg(CONFIG, 0x00);
  
  hal_nrf_write_reg(EN_AA, 0x00);
  
  hal_nrf_write_reg(SETUP_AW, 0x03);
  
  hal_nrf_set_address(HAL_NRF_PIPE0, RFID_READER_ADDR_P0);
  
  hal_nrf_write_reg(EN_RXADDR, 0x01);
  
  hal_nrf_write_reg(RX_PW_P0, 16);  
  
  hal_nrf_write_reg(RF_CH, 81);    
  
  hal_nrf_write_reg(STATUS, 0x70);
  
  hal_nrf_write_reg(CONFIG, 0x01);
}

/*********************************************************************
 * 函数名称:calcFCS
 * 功    能:该函数用来验证GPS数据FCS校验和。
 * 入口参数:pBuf   指向被校验的数据
 *           len    数据长度 
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
unsigned char calcFCS(unsigned char *pBuf, unsigned char len)
{
  unsigned char rtrn = 0;

  while (len--)
  {
    rtrn ^= *pBuf++;
  }

  return rtrn;
}

/*********************************************************************
 * 函数名称:main
 * 功    能:2.4GHz RFID 读卡器演示
 *           将接收到的Tag信息通过CC2530的UART0输出,波特率为115200
 * 入口参数:无    
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
int main(void)
{
  /* 定义相关变量 */
  unsigned char i;
  unsigned short crc;
  unsigned long oid;
  unsigned char uartString[64];
  
  /* 选择32MHz晶体振荡器作为系统时钟源(主时钟源) */
  SystemClockSourceSelect(XOSC_32MHz);  

  /* RFID-2.4GHz-Reader硬件抽象层初始化 */
  hal_2G4Hz_Reader_Init();

  /* UART0初始化 */
  InitUART0();
    
  /* LED1和LED2闪烁指定次数 */
  for(i = 0; i <= 20; i++)
  {
    if(i & 1)
    {
      HAL_2G4Hz_LED1_TURN_ON();
      HAL_2G4Hz_LED2_TURN_ON();
    }
    else
    {
      HAL_2G4Hz_LED1_TURN_OFF();
      HAL_2G4Hz_LED2_TURN_OFF();    
    }
    CC2530SleepTimer_Delay(100);
  }
  
  /* 针对RFID Reader功能初始化nRF24L01+ */
  InitNRF4Reader();

  /* 永久循环 */
  while(1)
  {
    hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
    
    CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);    
    
    HAL_2G4Hz_CE = 1;
    
    SetCC2530PowerMode(2);
    
    /* 点亮LED1 */
    HAL_2G4Hz_LED1_TURN_ON();
      
    /* 读取接收到的数据 */
    for(i = 0; i < 16; i++)
    {
      g_Tag.dataB[i] = Radio_Get_Pload_Byte(i);
    }
    
    /* 解码接收到的数据 */
    Shuffle_TX_ByteOrder();
    XXTEA_Decode();
    Shuffle_TX_ByteOrder();
    
    /* 校验接收到的数据 */ 
    crc = CRC16(g_Tag.dataB, sizeof(g_Tag.pkt) - sizeof (g_Tag.pkt.crc));
   
    /*  接收到的g_Tag数据包CRC16校验错误 */
    if(htons(g_Tag.pkt.crc) != crc)
    {
      /* 用户自行处理 */
    }
    /* 接收到的g_Tag数据包CRC16校验正确 */
    else
    { /* 点亮LED2 */
      HAL_2G4Hz_LED2_TURN_ON();
      
      /* 从CC2530的UART0输出接收到来自Tag的信息 */
      oid = htonl(g_Tag.pkt.oid);
//      sprintf(uartString,"OID:%08lx\nTX power:%d\nButton push:%d\n\n", oid, g_Tag.pkt.txpower, g_Tag.pkt.flags);  
      uartString[0] = 0x5a;
      uartString[1] = 14;
      uartString[2] = 0;//g_Tag.dataB[7];
      uartString[3] = 0x01;
      uartString[4] = 0x0a;
      changeToAscii (&uartString[5], g_Tag.dataB[8]);
      changeToAscii (&uartString[7], g_Tag.dataB[9]);
      changeToAscii (&uartString[9], g_Tag.dataB[10]);
      changeToAscii (&uartString[11], g_Tag.dataB[11]);
      uartString[13] = g_Tag.dataB[2];
      uartString[14] = calcFCS(&uartString[1], 13);
      uartString[15] = 0xa5;
      uartString[16] = 0;
      UART0SendString((unsigned char *)uartString, 16);
    }
    
    /* 设置nrf24L01+的RF为IDLE */
    Radio_Set_Status(RF_IDLE);
  
    /* 熄灭LED1和LED2 */
    HAL_2G4Hz_LED1_TURN_OFF();
    HAL_2G4Hz_LED2_TURN_OFF();     
  }
}
#endif
           
/*******************************************************************************
 * 文件名称:RFID_2.4GHz_Tag_Demo.c
 * 功    能:RFID基础实验工程 --- 2.4GHz RFID 的Tag
 * 作    者:
 * 公    司:
 ******************************************************************************/

#if defined ( TAG_FLAG )
/* 包含头文件 */
/*************************************************************/
#include "hal_2.4GHz_Tag.h"  // RFID-2.4GHz-Tag硬件抽象层头文件
#include "SYSCLK.h"             // CC2530的时钟选择头文件
#include "stdlib.h"             // C语言标准库文件
#include "stdio.h"              // C语言标准输入/输出库文件
/*************************************************************/
unsigned char keyFlag;
unsigned int txNumber;

/* RFID Reader的数据管道0接收地址为"READR" */
/*************************************************************/
unsigned char RFID_READER_ADDR_P0[] = {'R', 'D', 'A', 'E', 'R'};
/*************************************************************/


/* XXTEA加密块数量 */
/*************************************************************/
#define TEA_ENCRYPTION_BLOCK_COUNT 4
/*************************************************************/
#define DATA_LONG        0x10
#define DATA_PROTOCOL    0x01

/* XXTEA密钥 */
/*************************************************************/
const long XXTEA_KEY[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
/*************************************************************/


/* XXTEA算法相关变量和宏定义 */
/*************************************************************/
unsigned long z, y, sum, tmp, mx;
unsigned char e;
#define TEA_ROUNDS_COUNT (6+52/4)
#define MX ((((z>>5)^(y<<2))+((y>>3)^(z<<4)))^((sum^y)+(XXTEA_KEY[(p&3)^e]^z)))
#define DELTA 0x9E3779B9
/*************************************************************/
#define KEYDELAY 80

/* 数据包结构体类型 */
/*************************************************************/
typedef struct
{
  unsigned char len;        // 数据包的长度字段(单位:字节)
  unsigned char protocol;   // 数据包的协议类型字段
  unsigned char flags;      // 数据包的标志字段(按下Tag上的按键,flag为0x02;否则为0x00)
  unsigned char txpower;    // 数据包的发送功率字段
  unsigned long seq;        // 数据包的序号字段
  unsigned long oid;        // 数据包的对象标识符字段
  unsigned short reserved;  // 数据包的保留字段
  unsigned short crc;       // 数据包的CRC字段
}PKT;
/*************************************************************/


/* 加密数据包结构体类型 */
/*************************************************************/
typedef union
{
  PKT pkt;
  unsigned long dataUL[TEA_ENCRYPTION_BLOCK_COUNT];
  unsigned char dataB[TEA_ENCRYPTION_BLOCK_COUNT * sizeof (unsigned long)];
}ENCRYPTED_PKT;
/*************************************************************/


/* 用于Tag的加密数据包结构体变量 */
/*************************************************************/
static ENCRYPTED_PKT g_Tag;
/*************************************************************/


/* "打乱"功能宏 — SHUFFLE */
/*************************************************************/
#define SHUFFLE(a,b) 	tmp = g_Tag.dataB[a];\
			g_Tag.dataB[a] = g_Tag.dataB[b];\
			g_Tag.dataB[b] = tmp;
/*************************************************************/


/*********************************************************************
 * 函数名称:Shuffle_TX_ByteOrder
 * 功    能:"打乱"待发送数据的字节顺序
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
static void Shuffle_TX_ByteOrder (void)
{
  unsigned char tmp;

  SHUFFLE (0 + 0, 3 + 0);
  SHUFFLE (1 + 0, 2 + 0);
  SHUFFLE (0 + 4, 3 + 4);
  SHUFFLE (1 + 4, 2 + 4);
  SHUFFLE (0 + 8, 3 + 8);
  SHUFFLE (1 + 8, 2 + 8);
  SHUFFLE (0 + 12, 3 + 12);
  SHUFFLE (1 + 12, 2 + 12);
}


/*********************************************************************
 * 函数名称:CRC16
 * 功    能:CRC16计算
 * 入口参数:buffer  指向存储待进行CRC16计算的数据的缓冲区的指针
 *           size    待进行CRC16计算的数据的长度    
 * 出口参数:无
 * 返 回 值:CRC16计算结果
 * 注    意:CC2530自身带有CRC计算功能,但为了提高代码的可移植性,我们
 *           不使用CC2530自身带有的CRC计算功能,而使用该函数。
 ********************************************************************/
static unsigned short CRC16 (const unsigned char *buffer, unsigned char size)
{
  unsigned short crc = 0xFFFF;
  
  if(buffer)
  {
    while(size--)
    {
      crc = (crc >> 8) | (crc << 8);
      crc ^= *buffer++;
      crc ^= ((unsigned char) crc) >> 4;
      crc ^= crc << 12;
      crc ^= (crc & 0xFF) << 5;
    }
  }
  
  return crc;
}

/*********************************************************************
 * 函数名称:XXTEA_Encode
 * 功    能:XXTEA编码
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void XXTEA_Encode (void)
{
  long n = 4;
  long p, q ;
  
  z=g_Tag.dataUL[n-1], y=g_Tag.dataUL[0], sum=0;
  
  q = 6 + 52/n;
  while (q-- > 0)
  {
    sum += DELTA;
    e = (sum >> 2) & 3;
    for (p=0; p<n-1; p++)
    y = g_Tag.dataUL[p+1], z = g_Tag.dataUL[p] += MX;
    y = g_Tag.dataUL[0];
    z = g_Tag.dataUL[n-1] += MX;
  }
}


/*********************************************************************
 * 函数名称:InitNRF4Reader
 * 功    能:针对RFID Reader功能初始化nRF24L01+
 * 入口参数:无    
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void InitNRF4Reader(void)
{
  hal_nrf_nop();
  hal_nrf_write_reg(CONFIG, 0x20);  //使用与nRF2401/ nRF2402/ nRF24E1/ nRF24E2 相同的CRC 配置 
                                    //设置PRIM_RX 位为0 
  hal_nrf_write_reg(EN_AA, 0x00);
  hal_nrf_write_reg(SETUP_RETR, 0); //设置自动重发计数器为0 禁止自动重发功能
  hal_nrf_write_reg(SETUP_AW, 0x03);//与nRF2401/ nRF2402/ nRF24E1/ nRF24E2 使用相同的地址宽度 

  hal_nrf_set_address(HAL_NRF_PIPE0, RFID_READER_ADDR_P0);
  hal_nrf_set_address(HAL_NRF_TX, RFID_READER_ADDR_P0);
  hal_nrf_write_reg(RF_CH, 81);     //与nRF2401/ nRF2402/ nRF24E1/ nRF24E2 使用相同的频道
 
  hal_nrf_write_reg(EN_RXADDR, 0x00);
  hal_nrf_set_power_mode(HAL_NRF_PWR_UP);//设置PWR_UP 为高
}

void delay65ms(unsigned int microSecs)
{
  while(microSecs--)
  {
   /*  32 NOPs == 1 usecs */
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop");
  }
}

void keyScan ()
{
  unsigned char keyCount,temp8i;
  
  keyCount = 0;
  temp8i = 0;
  while ( temp8i < KEYDELAY )
  {
    delay65ms(500);
    if ( P2_0 == 1 )
      keyCount++;
    else
      keyCount = 0;
    temp8i++;
  }
  if ( keyCount >= KEYDELAY)
    keyFlag = 0x31;
  else
    keyFlag = 0x30;
}

unsigned char secondAddr[8];

void HalFlashRead()
{
  // Calculate the offset into the containing flash bank as it gets mapped into XDATA.
  unsigned char memctr = MEMCTR;  // Save to restore.
  unsigned char i;

  // Calculate and map the containing flash bank into XDATA.
  MEMCTR = (MEMCTR & 0xF8) | 7;
  
  asm("push DPH");
  asm("push DPL");
  asm("push A");
  asm("push B");
  asm("mov DPH,#0xff");
  asm("mov DPL,#0xe8");
  i = 0;
  while (i < 8)
  {
    asm("movx A,@DPTR");
    asm("mov B,A");
    secondAddr[i] = B;
    asm("inc DPTR");
    i++;
  }
  asm("pop B");
  asm("pop A");
  asm("pop DPL");
  asm("pop DPH");

  MEMCTR = memctr;
}
/*********************************************************************
 * 函数名称:main
 * 功    能:2.4GHz RFID 读卡器演示
 *           将接收到的Tag信息通过CC2530的UART0输出,波特率为115200
 * 入口参数:无    
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
int main(void)
{
  /* 定义相关变量 */
  unsigned char i;
  unsigned short crc;
  
  /* 选择32MHz晶体振荡器作为系统时钟源(主时钟源) */
  SystemClockSourceSelect(XOSC_32MHz);  

  /* RFID-2.4GHz-Reader硬件抽象层初始化 */
  hal_2G4Hz_Tag_Init();
  
  /* 使能P2.0为通用I/O,且为输入 */
  P2SEL = P2SEL & 0xfe;
  P2DIR = P2DIR & 0xfe;
  /* P2.0为下拉模式 */
  P2INP = P2INP  & 0xfe;
  P2INP = P2INP  | 0x80;

  /* LED1和LED2闪烁指定次数 */
  for(i = 0; i <= 20; i++)
  {
    if(i & 1)
    {
      HAL_2G4Hz_LED1_TURN_ON();
      HAL_2G4Hz_LED2_TURN_ON();
    }
    else
    {
      HAL_2G4Hz_LED1_TURN_OFF();
      HAL_2G4Hz_LED2_TURN_OFF();    
    }
    CC2530SleepTimer_Delay(100);
  }
  
  /* 针对RFID Tag功能初始化nRF24L01+ */
  InitNRF4Reader();
  
  do
  {
    HalFlashRead ();
    delay65ms(60000);
    P1_1 = !P1_1;
  }while ( (secondAddr[0] == 0xff) && (secondAddr[1] == 0xff) && (secondAddr[2] == 0xff) && (secondAddr[3] == 0xff) );
  P1_1 = 0;

  /* 永久循环 */
  while(1)
  {
    g_Tag.dataB[0] = DATA_LONG;
    g_Tag.dataB[1] = DATA_PROTOCOL;
    g_Tag.dataB[4] = 0x00;
    g_Tag.dataB[5] = 0x3a;
    g_Tag.dataB[8] = secondAddr[3];//0x08;
    g_Tag.dataB[9] = secondAddr[2];//0x86;
    g_Tag.dataB[10] = secondAddr[1];//0x00;
    g_Tag.dataB[11] = secondAddr[0];//0x4d;
    g_Tag.dataB[12] = 0x0;
    g_Tag.dataB[13] = 0x0;
    
    /* 点亮LED1 */
    HAL_2G4Hz_LED1_TURN_ON();

    g_Tag.dataB[2] = keyFlag;
    
    g_Tag.dataB[3] = hal_nrf_get_output_power ();
    g_Tag.dataB[3]++;
    if ( g_Tag.dataB[3] >= 0x04 )
    {
      g_Tag.dataB[3] = 0;
      txNumber++;
    }
    hal_nrf_set_output_power(g_Tag.dataB[3]);
    
    g_Tag.dataB[6] = (char)(txNumber >> 8);
    g_Tag.dataB[7] = (char)txNumber;
    
    crc = CRC16(g_Tag.dataB, sizeof(g_Tag.pkt) - sizeof (g_Tag.pkt.crc));
    g_Tag.dataB[14] = (char)(crc >> 8);
    g_Tag.dataB[15] = (char)crc;
    
    /* 编码接收到的数据 */
    Shuffle_TX_ByteOrder();
    XXTEA_Encode();
    Shuffle_TX_ByteOrder();
    
    hal_nrf_write_tx_pload(g_Tag.dataB, DATA_LONG);
    /* RF发送 */
    HAL_2G4Hz_CE_PULSE();
    
    /* 熄灭LED1和LED2 */
    HAL_2G4Hz_LED1_TURN_OFF();
    HAL_2G4Hz_LED2_TURN_OFF();     
    
    keyScan ();
  }
}
#endif
           
/*******************************************************************************
 * 文件名称:hal_2.4GHz_Tag.c
 * 功    能:RFID-2.4GHz-Reader硬件抽象层
 * 作    者:虫虫
 * 公    司:
 ******************************************************************************/

#if !defined ( TAG_FLAG )
/* 包含头文件 */
/********************************************************************/
#include "ioCC2530.h"           // CC2530的头文件,包含对CC2530的寄存器、中断向量等的定义
#include "hal_2.4GHz_Reader.h"  // RFID-2.4GHz-Reader硬件抽象层头文件
/********************************************************************/



/* 
   通过RF发送的数据载荷。也包含接收数据。 
   使用Radio_Get_Pload_Byte()函数读取
*/
/********************************************************************/
static unsigned char pload[16];
/********************************************************************/


/* 
   RF的当前状态 
   使用Radio_Set_Status函数来设置该变量;
   使用Radio_Get_Status函数来读取该变量。
*/
/********************************************************************/
static radio_status_t status;
/********************************************************************/


/*********************************************************************
 * 函数名称:SetCC2530SleepTime
 * 功    能:设置CC2530睡眠时间,即设置CC2530的睡眠定时器的比较值。
 * 入口参数:ms  处于功耗模式IDLE、PM0、PM1或PM2的时间。
 * 出口参数:无
 * 返 回 值:无
 * 注    意:使用外部32.768KHz晶体
 ********************************************************************/
static void 
SetCC2530SleepTime(unsigned short ms)
{
  unsigned long sleeptime = 0;
  
  /* 读取睡眠定时器的当前计数值 */
  sleeptime |= ST0;
  sleeptime |= (unsigned long)ST1 <<  8;
  sleeptime |= (unsigned long)ST2 << 16;
  
  /* 根据指定的睡眠时间计算出应设置的比较值 */
  sleeptime += (ms * (unsigned long)(32768 / 1000));
  
  /* 设置比较值 */
  while((STLOAD & 0x01) == 0);  // 等待允许加载新的比较值
  ST2 = (unsigned char)(sleeptime >> 16);
  ST1 = (unsigned char)(sleeptime >> 8);
  ST0 = (unsigned char) sleeptime;  
}


/*********************************************************************
 * 函数名称:SetCC2530PowerMode
 * 功    能:设置CC2530功耗模式
 * 入口参数:pm : 0     空闲模式
 *                1     功耗模式PM1
 *                2     功耗模式PM2
 *                3     功耗模式PM3
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
SetCC2530PowerMode(unsigned char pm)
{

  if(pm == 0)
  {
    SLEEPCMD &= ~0x03;
  }
  else if(pm == 3)
  {
    SLEEPCMD |= ~0x03;
  }
  else
  {
    SLEEPCMD &= ~0x03;
    SLEEPCMD |= pm;
  }

  /* 进入所选择的功耗模式 */
  PCON |= 0x01;                            
  
  asm("NOP");    
}


/*********************************************************************
 * 函数名称:CC2530SleepTimer_Delay
 * 功    能:延时函数,延时过程中CC2530处于PM2模式。
 * 入口参数:nMs  延时时长
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void CC2530SleepTimer_Delay(unsigned nMs)
{

  SetCC2530SleepTime(nMs);
  

  IRCON &= ~0x80;
  

  IEN0 |= (0x01 << 5);
  

  SetCC2530PowerMode(2);
}


/*********************************************************************
 * 函数名称:ST_ISR
 * 功    能:CC2530睡眠定时器中断服务函数
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
#pragma vector=ST_VECTOR
__interrupt void ST_ISR(void)
{
  /* 清除CC2530睡眠定时器中断标志 */
  IRCON &= ~0x80;
  
  /* 禁止CC2530睡眠定时器中断 */
  IEN0 &= ~(0x01 << 5);
}


/*********************************************************************
 * 函数名称:SW_SPI_RW
 * 功    能:CC2530模拟SPI总线发送1字节数据并从SPI总线读取1字节数据。
 * 入口参数:value  待发送的1字节数据
 * 出口参数:无
 * 返 回 值:读回的1字节数据
 ********************************************************************/
unsigned char
SW_SPI_RW(unsigned char value)
{
  unsigned char i;
   	
  for(i = 0; i < 8; i++)         
  {
    HAL_2G4Hz_MOSI = (value & 0x80)? 1 : 0;   
    value <<= 1;             
    HAL_2G4Hz_SCK = 1;                
    value |= HAL_2G4Hz_MISO;       	
    HAL_2G4Hz_SCK = 0;            	
  }
  HAL_2G4Hz_MOSI = 0; 
  return(value);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_irq_mode
 * 功    能:使能或禁止nRF24L01+的指定中断源
 * 入口参数:int_source  nRF24L01+的指定中断源
 *           irq_state   使能或禁止
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void hal_nrf_set_irq_mode(hal_nrf_irq_source_t int_source, bool irq_state)
{
  if(irq_state)
  {
    hal_nrf_write_reg(CONFIG, hal_nrf_read_reg(CONFIG) & ~SET_BIT(int_source));
  }
  else
  {
    hal_nrf_write_reg(CONFIG, hal_nrf_read_reg(CONFIG) | SET_BIT(int_source));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_clear_irq_flags
 * 功    能:获取并清除nRF24L01+的中断标志
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:中断标志
 *               0x10  最大重传次数中断
 *               0x20  TX数据发送中断
 *               0x40  RX数据接收中断
 ********************************************************************/
unsigned char
hal_nrf_get_clear_irq_flags(void)
{
  return hal_nrf_write_reg(STATUS, (BIT_6|BIT_5|BIT_4)) & (BIT_6|BIT_5|BIT_4);
}


/*********************************************************************
 * 函数名称:hal_nrf_clear_irq_flag
 * 功    能:清除nRF24L01+的指定中断标志
 * 入口参数:int_source  指定中断源
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_clear_irq_flag(hal_nrf_irq_source_t int_source)
{
  hal_nrf_write_reg(STATUS, SET_BIT(int_source));
}


/*********************************************************************
 * 函数名称:hal_nrf_get_irq_mode
 * 功    能:获取指定中断的模式
 * 入口参数:int_type  指定中断源
 * 出口参数:无
 * 返 回 值:FALSE 禁止
 *           TRUE  使能
 ********************************************************************/
bool 
hal_nrf_get_irq_mode(unsigned char int_type)
{
  if(hal_nrf_read_reg(CONFIG) & SET_BIT(int_type))
    return false;
  else
    return true;
}


/*********************************************************************
 * 函数名称:hal_nrf_nop
 * 功    能:调用该函数接收nRF24L01+的状态寄存器
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:状态寄存器的值
 ********************************************************************/
unsigned char
hal_nrf_nop(void)
{
  return hal_nrf_write_reg(NOP,0);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_irq_flags
 * 功    能:获取nRF24L01+的中断标志
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:中断标志
 *               0x10  最大重传次数中断
 *               0x20  TX数据发送中断
 *               0x40  RX数据接收中断
 ********************************************************************/
unsigned char
hal_nrf_get_irq_flags(void)
{
  return hal_nrf_nop() & (BIT_6|BIT_5|BIT_4);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_crc_mode
 * 功    能:设置nRF24L01+的CRC模式
 * 入口参数:crc_mode  禁止
 *                     1字节
 *                     2字节
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_crc_mode(hal_nrf_crc_mode_t crc_mode)
{
  hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(BIT_3|BIT_2)) | 
                    (UINT8(crc_mode)<<2));
}


/*********************************************************************
 * 函数名称:hal_nrf_open_pipe
 * 功    能:打开nRF24L01+的1个或所有管道,并设置带有/不带自动ACK特性。
 * 入口参数:pipe_num  管道号
 *           auto_ack  自动ACK特性开/关
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_open_pipe(hal_nrf_address_t pipe_num, bool auto_ack)
{
  switch(pipe_num)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_PIPE2:
    case HAL_NRF_PIPE3:
    case HAL_NRF_PIPE4:
    case HAL_NRF_PIPE5:
      hal_nrf_write_reg(EN_RXADDR, hal_nrf_read_reg(EN_RXADDR) | SET_BIT(pipe_num));

      if(auto_ack)
        hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) | SET_BIT(pipe_num));
      else
        hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) & ~SET_BIT(pipe_num));
      break;

    case HAL_NRF_ALL:
      hal_nrf_write_reg(EN_RXADDR, ~(BIT_7|BIT_6));

      if(auto_ack)
        hal_nrf_write_reg(EN_AA, ~(BIT_7|BIT_6));
      else
        hal_nrf_write_reg(EN_AA, 0);
      break;
      
    default:
      break;
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_close_pipe
 * 功    能:关闭nRF24L01+的1个或所有管道
 * 入口参数:pipe_num  管道号
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_close_pipe(hal_nrf_address_t pipe_num)
{
  switch(pipe_num)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_PIPE2:
    case HAL_NRF_PIPE3:
    case HAL_NRF_PIPE4:
    case HAL_NRF_PIPE5:
      hal_nrf_write_reg(EN_RXADDR, hal_nrf_read_reg(EN_RXADDR) & ~SET_BIT(pipe_num));
      hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) & ~SET_BIT(pipe_num));
      break;
    
    case HAL_NRF_ALL:
      hal_nrf_write_reg(EN_RXADDR, 0);
      hal_nrf_write_reg(EN_AA, 0);
      break;
      
    default:
      break;
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_set_address
 * 功    能:设置RX或TX地址
 * 入口参数:address  设置哪个地址
 *           addr     指向保存地址值的缓冲区的指针
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_address(hal_nrf_address_t address, unsigned char *addr)
{
  switch(address)
  {
    case HAL_NRF_TX:
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
      hal_nrf_write_multibyte_reg((unsigned char) address, addr, 0);
      break;

    case HAL_NRF_PIPE2:
    case HAL_NRF_PIPE3:
    case HAL_NRF_PIPE4:
    case HAL_NRF_PIPE5:
      hal_nrf_write_reg(RX_ADDR_P0 + (unsigned char) address, *addr);
      break;

    default:
      break;
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_set_auto_retr
 * 功    能:设置重传次数和重传延时
 * 入口参数:retr   重传次数
 *           delay  重传延时(单位:us)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_auto_retr(unsigned char retr, unsigned short delay)
{
  hal_nrf_write_reg(SETUP_RETR, (((delay/250)-1)<<4) | retr);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_address_width
 * 功    能:设置地址宽度
 * 入口参数:address_width  地址宽度
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_address_width(hal_nrf_address_width_t address_width)
{
  hal_nrf_write_reg(SETUP_AW, (UINT8(address_width) - 2));
}


/*********************************************************************
 * 函数名称:hal_nrf_set_rx_pload_width
 * 功    能:设置指定管道上期望接收的数据长度(单位:字节)
 * 入口参数:pipe_num     管道
 *           pload_width  期望接收的字节数量
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_rx_pload_width(unsigned char pipe_num, unsigned char pload_width)
{
  hal_nrf_write_reg(RX_PW_P0 + pipe_num, pload_width);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_crc_mode
 * 功    能:获取所使用的CRC模式
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  无CRC
 *           0x02  CRC-8
 *           0x03  CRC-16
 ********************************************************************/
unsigned char
hal_nrf_get_crc_mode(void)
{
  return (hal_nrf_read_reg(CONFIG) & (BIT_3|BIT_2)) >> CRCO;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_pipe_status
 * 功    能:获取指定管道的状态
 * 入口参数:pipe_num  管道号
 * 出口参数:无
 * 返 回 值:0x00  管道关闭,自动ACK禁止
 *           0x01  管道打开,自动ACK禁止
 *           0x03  管道打开,自动ACK打开
 ********************************************************************/
unsigned char
hal_nrf_get_pipe_status(unsigned char pipe_num)
{
  unsigned char en_rx, en_aa;

  en_rx = hal_nrf_read_reg(EN_RXADDR) & (1<<pipe_num);
  en_aa = hal_nrf_read_reg(EN_AA) & (1<<pipe_num);

  en_rx >>= pipe_num;
  en_aa >>= pipe_num;

  return (en_aa << 1) + en_rx;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_address
 * 功    能:获取指定管道的地址
 * 入口参数:address  要获取哪一种地址,PIPE或TX地址
 *           addr     获取到得地址数据将写入该指针指向的缓冲区
 * 出口参数:无
 * 返 回 值:地址宽度(单位:字节)
 ********************************************************************/
unsigned char 
hal_nrf_get_address(unsigned char address, unsigned char *addr)
{
  switch(address)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_TX:
      return hal_nrf_read_multibyte_reg(address, addr);

    default:
      *addr = hal_nrf_read_reg(RX_ADDR_P0 + address);
      return hal_nrf_get_address_width();
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_auto_retr_status
 * 功    能:获取自动重传参数,即重传次数和重传延时。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:高4位  重传延时
 *           低4位  重传次数
 ********************************************************************/
unsigned char
hal_nrf_get_auto_retr_status(void)
{
  return hal_nrf_read_reg(OBSERVE_TX);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_packet_lost_ctr
 * 功    能:获取丢包计数器的值
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:丢包计数器的值
 ********************************************************************/
unsigned char 
hal_nrf_get_packet_lost_ctr(void)
{
  return (hal_nrf_read_reg(OBSERVE_TX) & (BIT_7|BIT_6|BIT_5|BIT_4)) >> 4;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_rx_pload_width
 * 功    能:获取所指定管道上所期望接收的数据宽度(单位:字节)
 * 入口参数:pipe_num  管道号
 * 出口参数:无
 * 返 回 值:数据宽度(单位:字节)
 ********************************************************************/
unsigned char  
hal_nrf_get_rx_pload_width(unsigned char  pipe_num)
{
  return hal_nrf_read_reg(RX_PW_P0 + pipe_num);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_operation_mode
 * 功    能:进入 PTX (primary TX) 或 PRX (primary RX)模式
 * 入口参数:op_mode  运行模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_operation_mode(hal_nrf_operation_mode_t op_mode)
{
  if(op_mode == HAL_NRF_PRX)
  {
    hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) | (1<<PRIM_RX)));
  }
  else
  {
    hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(1<<PRIM_RX)));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_set_power_mode
 * 功    能:上电或掉电RF
 * 入口参数:pwr_mode  POWER_UP 或 POWER_DOWN  
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_power_mode(hal_nrf_pwr_mode_t pwr_mode)
{
  if(pwr_mode == HAL_NRF_PWR_UP)
  {
    hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) | (1<<PWR_UP)));
  }
  else
  {
    hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(1<<PWR_UP)));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_set_rf_channel
 * 功    能:选择所使用的RF信道
 * 入口参数:channel  RF信道  
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_rf_channel(unsigned char channel)
{
  hal_nrf_write_reg(RF_CH, channel);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_output_power
 * 功    能:选择RF TX输出功率
 * 入口参数:power  RF TX输出功率 
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_output_power(hal_nrf_output_power_t power)
{
  hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & 
                    ~((1<<RF_PWR1)|(1<<RF_PWR0))) | (UINT8(power)<<1));
}


/*********************************************************************
 * 函数名称:hal_nrf_set_datarate
 * 功    能:设置无线通信数据速率
 * 入口参数:datarate  无线通信数据速率 
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_datarate(hal_nrf_datarate_t datarate)
{
  if(datarate == HAL_NRF_1MBPS)
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<RF_DR)));
  }
  else
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<RF_DR)));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_operation_mode
 * 功    能:获取运行模式
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  Primary RX (PRX) 
 *           0x01  Primary TX (PTX) 
 ********************************************************************/
unsigned char
hal_nrf_get_operation_mode(void)
{
  return (hal_nrf_read_reg(CONFIG) & (1<<PRIM_RX)) >> PRIM_RX;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_power_mode
 * 功    能:获取功耗模式
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  POWER_DOWN  
 *           0x01  POWER_UP   
 ********************************************************************/
unsigned char 
hal_nrf_get_power_mode(void)
{
  return (hal_nrf_read_reg(CONFIG) & (1<<PWR_UP)) >> PWR_UP;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_rf_channel
 * 功    能:获取所使用的RF信道
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:RF信道
 ********************************************************************/
unsigned char  
hal_nrf_get_rf_channel(void)
{
  return hal_nrf_read_reg(RF_CH);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_output_power
 * 功    能:获取所使用的RF TX输出功率
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  -18dBm
 *           0x01  -12dBm
 *           0x02  -6dBm
 *           0x03  0dBm
 ********************************************************************/
unsigned char  
hal_nrf_get_output_power(void)
{
  return (hal_nrf_read_reg(RF_SETUP) & ((1<<RF_PWR1)|(1<<RF_PWR0))) >> RF_PWR0;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_datarate
 * 功    能:获取所使用的无线通信数据速率
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  1Mbps 
 *           0x01  2Mbps
 ********************************************************************/
unsigned char
hal_nrf_get_datarate(void)
{
  return (hal_nrf_read_reg(RF_SETUP) & (1<<RF_DR)) >> RF_DR;
}


/*********************************************************************
 * 函数名称:hal_nrf_rx_fifo_empty
 * 功    能:检查RX FIFO是否为空
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  RX FIFO 不空   
 *           TRUE   RX FIFO 空
 ********************************************************************/
bool 
hal_nrf_rx_fifo_empty(void)
{
 if(hal_nrf_get_rx_data_source()==7)
  {
    return true;
  }
  else
  {
    return false;
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_rx_fifo_full
 * 功    能:检查RX FIFO是否为满
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  RX FIFO 不满   
 *           TRUE   RX FIFO 满
 ********************************************************************/
bool 
hal_nrf_rx_fifo_full(void)
{
  return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> RX_EMPTY) & 1);
}


/*********************************************************************
 * 函数名称:hal_nrf_tx_fifo_empty
 * 功    能:检查TX FIFO是否为空
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  TX FIFO 不空   
 *           TRUE   TX FIFO 空
 ********************************************************************/
bool 
hal_nrf_tx_fifo_empty(void)
{
  return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> TX_EMPTY) & 1);
}


/*********************************************************************
 * 函数名称:hal_nrf_tx_fifo_full
 * 功    能:检查TX FIFO是否为满
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  TX FIFO 不满  
 *           TRUE   TX FIFO 满
 ********************************************************************/
bool 
hal_nrf_tx_fifo_full(void)
{
  return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> TX_FIFO_FULL) & 1);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_tx_fifo_status
 * 功    能:检查TX FIFO的状态
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  TX FIFO 不空, 也不满    
 *           0x01  TX FIFO 空
 *           0x02  TX FIFO 满
 ********************************************************************/
unsigned char
hal_nrf_get_tx_fifo_status(void)
{
  return ((hal_nrf_read_reg(FIFO_STATUS) & 
           ((1<<TX_FIFO_FULL)|(1<<TX_EMPTY))) >> 4);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_rx_fifo_status
 * 功    能:检查RX FIFO的状态
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  RX FIFO 不空, 也不满    
 *           0x01  RX FIFO 空
 *           0x02  RX FIFO 满
 ********************************************************************/
unsigned char
hal_nrf_get_rx_fifo_status(void)
{
  return (hal_nrf_read_reg(FIFO_STATUS) & ((1<<RX_FULL)|(1<<RX_EMPTY)));
}


/*********************************************************************
 * 函数名称:hal_nrf_get_fifo_status
 * 功    能:检查FIFO状态
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FIFO状态寄存器的值
 ********************************************************************/
unsigned char 
hal_nrf_get_fifo_status(void)
{
  return hal_nrf_read_reg(FIFO_STATUS);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_transmit_attempts
 * 功    能:获取重传尝试的次数和丢包数量
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:重传尝试计数器的值
 ********************************************************************/
unsigned char 
hal_nrf_get_transmit_attempts(void)
{
  return hal_nrf_read_reg(OBSERVE_TX) & (BIT_3|BIT_2|BIT_1|BIT_0);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_carrier_detect
 * 功    能:获取载波检测标志
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  未检测到载波
 *           TRUE   检测到载波
 ********************************************************************/
bool 
hal_nrf_get_carrier_detect(void)
{
  return hal_nrf_read_reg(CD) & 1;
}


/*********************************************************************
 * 函数名称:hal_nrf_write_tx_pload
 * 功    能:写数据包的数据载荷部分到RF
 * 入口参数:tx_pload  指向存储数据载荷的缓冲区的指针
 *           length    数据载荷的长度(单位:字节)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_write_tx_pload(unsigned char *tx_pload, unsigned char length)
{
  hal_nrf_write_multibyte_reg(UINT8(HAL_NRF_TX_PLOAD), tx_pload, length);
}


/*********************************************************************
 * 函数名称:hal_nrf_setup_dyn_pl
 * 功    能:设置接收管道的动态数据负载特性。
 * 入口参数:setup  管道特性位掩码
 *                  例如:bit0设置为1时,管道0使用ACK数据负载。
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_setup_dyn_pl(unsigned char setup)
{
  hal_nrf_write_reg(DYNPD, setup & ~0xC0); 
}


/*********************************************************************
 * 函数名称:hal_nrf_enable_dynamic_pl
 * 功    能:使能动态数据负载特性。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_enable_dynamic_pl(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x04));   
}


/*********************************************************************
 * 函数名称:hal_nrf_disable_dynamic_pl
 * 功    能:禁止动态数据负载特性。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_disable_dynamic_pl(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x04));   
}


/*********************************************************************
 * 函数名称:hal_nrf_enable_ack_pl
 * 功    能:使能ACK数据负载特性。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_enable_ack_pl(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x02));   
}


/*********************************************************************
 * 函数名称:hal_nrf_disable_ack_pl
 * 功    能:禁止ACK数据负载特性。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_disable_ack_pl(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x02));   
}


/*********************************************************************
 * 函数名称:hal_nrf_enable_dynamic_ack
 * 功    能:使能no-ack特性
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_enable_dynamic_ack(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x01));   
}


/*********************************************************************
 * 函数名称:hal_nrf_disable_dynamic_ack
 * 功    能:禁止no-ack特性
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_disable_dynamic_ack(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x01));   
}


/*********************************************************************
 * 函数名称:hal_nrf_write_ack_pload
 * 功    能:给指定管道写入带ACK特性的数据负载。
 * 入口参数:pipe      管道号
 *           tx_pload  指向存储待写入数据的缓冲区的指针
 *           length    待写入数据的长度(单位:字节)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_write_ack_pload(unsigned char pipe, unsigned char *tx_pload, 
                        unsigned char length)
{
  HAL_2G4Hz_CSN = 0;

  SW_SPI_RW(WR_ACK_PLOAD | pipe);
  while(length--)
  {
    SW_SPI_RW(*tx_pload++);
  }

  HAL_2G4Hz_CSN = 1;
}


/*********************************************************************
 * 函数名称:hal_nrf_read_rx_pl_w
 * 功    能:读取接收到的ACK数据负载的宽度
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:接收到的ACK数据负载的宽度
 ********************************************************************/
unsigned char 
hal_nrf_read_rx_pl_w()
{
  unsigned char temp;
  
  HAL_2G4Hz_CSN = 0;

  SW_SPI_RW(RD_RX_PLOAD_W);
  temp = SW_SPI_RW(0);
  
  HAL_2G4Hz_CSN = 1;

  return temp;
}


/*********************************************************************
 * 函数名称:hal_nrf_lock_unlock
 * 功    能:给nRF24L01+发送ACTIVATE命令
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_lock_unlock()
{
  HAL_2G4Hz_CSN = 0;

  SW_SPI_RW(LOCK_UNLOCK);             
  SW_SPI_RW(0x73);

  HAL_2G4Hz_CSN = 1;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_rx_data_source
 * 功    能:获取当前哪一个管道接收的数据包是当前最高级别数据包
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:管道号
 ********************************************************************/
unsigned char 
hal_nrf_get_rx_data_source(void)
{
  return ((hal_nrf_nop() & (BIT_3|BIT_2|BIT_1)) >> 1);
}


/*********************************************************************
 * 函数名称:hal_nrf_read_reg
 * 功    能:读取nRF24L01+的寄存器内容
 * 入口参数:reg  要读取的寄存器
 * 出口参数:无
 * 返 回 值:读出的寄存器内容
 ********************************************************************/
unsigned char
hal_nrf_read_reg(unsigned char reg)
{
  unsigned char temp;
  
  HAL_2G4Hz_CSN = 0;
  SW_SPI_RW(reg);
  temp = SW_SPI_RW(0);
  HAL_2G4Hz_CSN = 1;
  
  return temp;
}


/*********************************************************************
 * 函数名称:hal_nrf_read_rx_pload
 * 功    能:读取RX FIFO中可用的最高级别数据载荷
 * 入口参数:rx_pload  指向存储读出数据的缓冲区的指针
 * 出口参数:无
 * 返 回 值:高8位  管道号
 *           低8位  数据长度(单位:字节)
 *           数据长度为0且管道号为7意味着FIFO为空
 ********************************************************************/
unsigned short 
hal_nrf_read_rx_pload(unsigned char *rx_pload)
{
  return hal_nrf_read_multibyte_reg(UINT8(HAL_NRF_RX_PLOAD), rx_pload);
}


/*********************************************************************
 * 函数名称:hal_nrf_reuse_tx
 * 功    能:设置RF使用最后一次发送的数据载荷作为下一个数据包
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_reuse_tx(void)
{
  hal_nrf_write_reg(REUSE_TX_PL, 0);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_reuse_tx_status
 * 功    能:检查reuse_tx功能的状态
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  未激活
 *           TRUE   激活
 ********************************************************************/
bool 
hal_nrf_get_reuse_tx_status(void)
{
  return (bool)((hal_nrf_get_fifo_status() & (1<<TX_REUSE)) >> TX_REUSE);
}


/*********************************************************************
 * 函数名称:hal_nrf_flush_rx
 * 功    能:清空RX FIFO
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_flush_rx(void)
{
  hal_nrf_write_reg(FLUSH_RX, 0);
}


/*********************************************************************
 * 函数名称:hal_nrf_flush_tx
 * 功    能:清空TX FIFO
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_flush_tx(void)
{
  hal_nrf_write_reg(FLUSH_TX, 0);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_pll_mode
 * 功    能:LOCK或UNLOCK RF PLL
 * 入口参数:pll_mode  PLL locked: TRUE 或 FALSE 
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_pll_mode(hal_nrf_pll_mode_t pll_mode)
{
  if(pll_mode == HAL_NRF_PLL_LOCK)
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<PLL_LOCK)));
  }
  else
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<PLL_LOCK)));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_pll_mode
 * 功    能:获取 RF PLL的当前模式
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:RF PLL的当前模式
 ********************************************************************/
hal_nrf_pll_mode_t 
hal_nrf_get_pll_mode(void)
{
  return (hal_nrf_pll_mode_t)((hal_nrf_read_reg(RF_SETUP) & 
                               (1<<PLL_LOCK)) >> PLL_LOCK);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_lna_gain
 * 功    能:设置RF使用的LNA增益模式
 * 入口参数:lna_gain  LNA增益模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_lna_gain(hal_nrf_lna_mode_t lna_gain)
{
  if(lna_gain == HAL_NRF_LNA_HCURR)
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<LNA_HCURR)));
  }
  else
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<LNA_HCURR)));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_lna_gain
 * 功    能:获取RF当前使用的LNA增益模式
 * 入口参数:lna_gain  LNA增益模式
 * 出口参数:无
 * 返 回 值:0  LNA 低电流
 *           1  LNA 高电流
 ********************************************************************/
hal_nrf_lna_mode_t 
hal_nrf_get_lna_gain(void)
{
  return (hal_nrf_lna_mode_t) ( (hal_nrf_read_reg(RF_SETUP) & 
                                 (1<<LNA_HCURR)) >> LNA_HCURR );
}


/*********************************************************************
 * 函数名称:hal_nrf_read_multibyte_reg
 * 功    能:从nRF24L01+的指定寄存器读取多字节数据
 * 入口参数:reg    nRF24L01+的指定寄存器
 *           pbuf   指向存储读出数据的缓冲区的指针
 * 出口参数:无
 * 返 回 值:高8位:接收数据的管道号(用于hal_nrf_read_rx_pload函数)
 *           低8位:读取数据的长度(用于hal_nrf_read_rx_pload 或hal_nrf_get_address函数)
 ********************************************************************/
unsigned short
hal_nrf_read_multibyte_reg(unsigned char reg, unsigned char *pbuf)
{
  unsigned char ctr, length;
  switch(reg)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_TX:
      length = ctr = hal_nrf_get_address_width();
      HAL_2G4Hz_CSN = 0;
      SW_SPI_RW(RX_ADDR_P0 + reg);
      break;
      
    case HAL_NRF_RX_PLOAD:
      if( (reg = hal_nrf_get_rx_data_source()) < 7)
      {
        length = ctr = hal_nrf_read_rx_pl_w();

        HAL_2G4Hz_CSN = 0;
        SW_SPI_RW(RD_RX_PLOAD);
      }
      else
      {
       ctr = length = 0;
      }
      break;

    default:
      ctr = length = 0;
      break;
  }

  while(ctr--)
  {
    *pbuf++ = SW_SPI_RW(0);
  }

    HAL_2G4Hz_CSN = 1;

  return (((unsigned short) reg << 8) | length);
}


/*********************************************************************
 * 函数名称:hal_nrf_write_reg
 * 功    能:写一个新值到nRF24L01+的指定寄存器
 * 入口参数:reg    待写入新值的寄存器
 *           value  待写入的新值
 * 出口参数:无
 * 返 回 值:1字节返回值
 ********************************************************************/
unsigned char
hal_nrf_write_reg(unsigned char reg, unsigned char value)
{
  unsigned char retval;
  
  HAL_2G4Hz_CSN = 0;

  if(reg < WRITE_REG)
  {
    retval = SW_SPI_RW(WRITE_REG + reg);
    SW_SPI_RW(value);
  }

  else
  {
    if(!(reg == FLUSH_TX) && !(reg == FLUSH_RX) && !(reg == REUSE_TX_PL) && !(reg == NOP))
    {
      retval = SW_SPI_RW(reg);
      SW_SPI_RW(value);
    }

    else
    {
      retval = SW_SPI_RW(reg);
    }
  }
  HAL_2G4Hz_CSN = 1;

  return retval;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_address_width
 * 功    能:获取nRF24L01+射频使用的地址宽度,包括RX和TX
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:地址宽度(单位:字节)
 ********************************************************************/
unsigned char
hal_nrf_get_address_width(void)
{
  return (hal_nrf_read_reg(SETUP_AW) + 2);
}


/*********************************************************************
 * 函数名称:hal_nrf_write_multibyte_reg
 * 功    能:写多个字节数据到nRF24L01+的指定寄存器
 * 入口参数:reg    待写入数据的寄存器
 *           pbuf   指向保存待写入数据的缓冲区的指针
 *           length  待写入数据的长度(单位:字节)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_write_multibyte_reg(unsigned char reg, unsigned char *pbuf, 
                            unsigned char length)
{
  switch(reg)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_TX:
      length = hal_nrf_get_address_width();
      HAL_2G4Hz_CSN = 0;
      SW_SPI_RW(WRITE_REG + RX_ADDR_P0 + reg);
      break;

    case HAL_NRF_TX_PLOAD:
      HAL_2G4Hz_CSN = 0;
      SW_SPI_RW(WR_TX_PLOAD);
      break;      
   
    default:
      break;
  }

  while(length--)
  {
    SW_SPI_RW(*pbuf++);
  } 
  
  HAL_2G4Hz_CSN = 1;
}


/*********************************************************************
 * 函数名称:hal_2G4Hz_Reader_Init
 * 功    能:RFID-2.4GHz-Reader硬件抽象层初始化
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 * 注    意:本函数使能了CC2530的全局中断
 ********************************************************************/
void hal_2G4Hz_Reader_Init(void)
{
  /* 使能CC2530的缓存预取模式 */ 
  PREFETCH_ENABLE();
  
  /* LED相关初始化 */
  HAL_2G4Hz_LED1_TURN_OFF();
  HAL_2G4Hz_LED1_DDR |= HAL_2G4Hz_LED1_BV;
  HAL_2G4Hz_LED2_TURN_OFF();
  HAL_2G4Hz_LED2_DDR |= HAL_2G4Hz_LED2_BV;
  
  /* CC2530与nRF24L01+相连引脚初始化 */
  HAL_2G4Hz_CSN = 1;
  HAL_2G4Hz_CE = 0;
  HAL_2G4Hz_MOSI = 0;
  HAL_2G4Hz_SCK = 0;
  HAL_2G4Hz_CSN_DDR |= HAL_2G4Hz_CSN_BV;
  HAL_2G4Hz_CE_DDR |= HAL_2G4Hz_CE_BV;
  HAL_2G4Hz_SCK_DDR |= HAL_2G4Hz_SCK_BV;
  HAL_2G4Hz_MOSI_DDR |= HAL_2G4Hz_MOSI_BV;
  HAL_2G4Hz_MISO_DDR &= ~HAL_2G4Hz_MISO_BV;
  HAL_2G4Hz_IRQ_DDR &= ~HAL_2G4Hz_IRQ_BV;
    
                               
  P0INP |= HAL_2G4Hz_BUTTON_BV;
  PICTL |= 0x01;
  P0IEN |= HAL_2G4Hz_IRQ_BV;
  IEN1 |= (1 << 5);

  EA = 1;
}


/*********************************************************************
 * 函数名称:Radio_Set_Status
 * 功    能:更新status全局变量
 * 入口参数:new_status  新状态值
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_Set_Status (radio_status_t new_status)
{
  status = new_status;
}


/*********************************************************************
 * 函数名称:Radio_Get_Status
 * 功    能:读取status全局变量
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:RF当前状态标志变量status的当前值
 ********************************************************************/
radio_status_t 
Radio_Get_Status (void)
{
  return status;
}


/*********************************************************************
 * 函数名称:HAL_2G4Hz_CE_PULSE
 * 功    能:脉动nRF24L01+的CE信号至少10us
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
HAL_2G4Hz_CE_PULSE(void)
{
  unsigned char count;
  
  count = 20;
  HAL_2G4Hz_CE =  1;
  while(count--);
  HAL_2G4Hz_CE =  0;
}


/*********************************************************************
 * 函数名称:Radio_SB_MODE_Init
 * 功    能:nRF24L01+的ShockBurst(TM)模式初始化
 * 入口参数:address           设备地址
 *           operational_mode  PTX(Primary TX operation)模式
 *                             RTX(Primary RX operation)模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_SB_MODE_Init (unsigned char *address, 
                    hal_nrf_operation_mode_t operational_mode)
{

  hal_nrf_close_pipe(HAL_NRF_ALL);
  hal_nrf_open_pipe(HAL_NRF_PIPE0, false);
  hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
  hal_nrf_set_auto_retr(0, RF_RETRANS_DELAY);
  hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
  hal_nrf_set_address(HAL_NRF_TX, address);
  hal_nrf_set_address(HAL_NRF_PIPE0, address);  
  if(operational_mode == HAL_NRF_PTX)
  {
    hal_nrf_set_operation_mode(HAL_NRF_PTX);
  }

  else
  {
   hal_nrf_set_operation_mode(HAL_NRF_PRX);
   hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);
  }

  hal_nrf_set_rf_channel(RF_CHANNEL);
  hal_nrf_set_datarate(HAL_NRF_2MBPS);
  hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
  CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);
  Radio_Set_Status (RF_IDLE);
}


/*********************************************************************
 * 函数名称:Radio_ESB_MODE_Init
 * 功    能:nRF24L01+的Enhanced ShockBurst(TM)模式初始化
 * 入口参数:address           设备地址
 *           operational_mode  PTX(Primary TX operation)模式
 *                             RTX(Primary RX operation)模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_ESB_MODE_Init (unsigned char *address, 
                     hal_nrf_operation_mode_t operational_mode)
{
  /* nRF24L01+默认情况下管道0和1是打开的,因此首先关闭所有管道 */
  hal_nrf_close_pipe(HAL_NRF_ALL);
  
  hal_nrf_open_pipe(HAL_NRF_PIPE0, true);

  /* 使用CRC-16模式 */
  hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
  
  /* 使能自动重传:重传次数为RF_RETRANSMITS,重传延时为RF_RETRANS_DELAY */
  hal_nrf_set_auto_retr(RF_RETRANSMITS, RF_RETRANS_DELAY);                 
          
  hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
 
  hal_nrf_set_address(HAL_NRF_TX, address);
  
  hal_nrf_set_address(HAL_NRF_PIPE0, address);
  
  /* 设置为PTX模式 */
  if(operational_mode == HAL_NRF_PTX)
  {
    hal_nrf_set_operation_mode(HAL_NRF_PTX);
  }
  /* 设置为RTX模式 */
  else
  {
    hal_nrf_set_operation_mode(HAL_NRF_PRX);
    hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);                               
  }

  /* 设置运行信道为 频率 = 2400 + RF_CHANNEL */
  hal_nrf_set_rf_channel(RF_CHANNEL);
  
  hal_nrf_set_power_mode(HAL_NRF_PWR_UP);

  CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);

  /* RF就绪 */
  Radio_Set_Status (RF_IDLE);
}


/*********************************************************************
 * 函数名称:Radio_ESB_MODE_PL_Init
 * 功    能:nRF24L01+的Enhanced ShockBurst(TM) with bidirectional Data模式初始化
 * 入口参数:address           设备地址
 *           operational_mode  PTX(Primary TX operation)模式
 *                             RTX(Primary RX operation)模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_ESB_MODE_PL_Init (unsigned char *address, 
                        hal_nrf_operation_mode_t operational_mode)
{
  /* nRF24L01+默认情况下管道0和1是打开的,因此首先关闭所有管道 */
  hal_nrf_close_pipe(HAL_NRF_ALL);
  
  hal_nrf_open_pipe(HAL_NRF_PIPE0, true);

  hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
  
  hal_nrf_set_auto_retr(RF_RETRANSMITS, RF_RETRANS_DELAY);                 
          
  hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
  
  hal_nrf_set_address(HAL_NRF_TX, address);
  
  hal_nrf_set_address(HAL_NRF_PIPE0, address);

  /* 
     以下部分与Radio_ESB_MODE_Init函数不同
     使能ACK数据载荷
     使能动态数据载荷宽度
     使能动态ACK
  */
  /****************************************************************************/
  /* 使能ACK数据载荷特性 */
  hal_nrf_enable_ack_pl();

  if(hal_nrf_read_reg(FEATURE) == 0x00 && (hal_nrf_read_reg(DYNPD) == 0x00))
  {
    hal_nrf_lock_unlock ();
    
    hal_nrf_enable_ack_pl();
  }

  /* 使能动态数据载荷特性 */
  hal_nrf_enable_dynamic_pl();
  
  /* 设置所有接收管道具有动态数据载荷特性 */
  hal_nrf_setup_dyn_pl(ALL_PIPES);
  /****************************************************************************/
   
  /* 设置为PTX模式 */
  if(operational_mode == HAL_NRF_PTX)
  {
    hal_nrf_set_operation_mode(HAL_NRF_PTX);
  }
  /* 设置为RTX模式 */
  else
  {
    hal_nrf_set_operation_mode(HAL_NRF_PRX);
    
    hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);                               
  }

  hal_nrf_set_rf_channel(RF_CHANNEL);
  
  hal_nrf_set_power_mode(HAL_NRF_PWR_UP);

  CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);

  Radio_Set_Status (RF_IDLE);
}


/*********************************************************************
 * 函数名称:Radio_Send_Packet
 * 功    能:RF发送数据包
 * 入口参数:packet   指向保存待发送数据包的缓冲区的指针
 *           length   待发送数据包的长度(单位:字节)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void
Radio_Send_Packet(unsigned char *packet, unsigned char length)
{
  /* 加载数据包到RF */
  hal_nrf_write_tx_pload(packet, length);
  
  /* RF发送 */
  HAL_2G4Hz_CE_PULSE();

  /* 更新RF状态变量status 为RF_BUSY */
  Radio_Set_Status (RF_BUSY);
}


/*********************************************************************
 * 函数名称:Radio_Get_Pload_Byte
 * 功    能:byte_index  数据载荷的字节索引
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:数据载荷字节索引所指定的1字节数据
 ********************************************************************/
unsigned char 
Radio_Get_Pload_Byte (unsigned char byte_index)
{
  return pload[byte_index];
}


/*********************************************************************
 * 函数名称:Radio_IRQ
 * 功    能:nRF24L01+的中断处理函数
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_IRQ(void) 
{
  /* 若nRF24L01+触发了CC2530的外部中断 */
  if(RADIO_ACTIVITY())
  { 
    hal_nrf_set_power_mode(HAL_NRF_PWR_DOWN);
    
      HAL_2G4Hz_CE = 0;
            
    switch(hal_nrf_get_clear_irq_flags ())
    {
      /* 达到最大重传次数中断 */
      case (1<<HAL_NRF_MAX_RT):
        hal_nrf_flush_tx();           
        Radio_Set_Status (RF_MAX_RT);  
        break;
      
      /* TX数据发送中断 */
      case (1<<HAL_NRF_TX_DS):
        Radio_Set_Status (RF_TX_DS);   
        break;
      
      /* RX数据接收中断 */
      case (1<<HAL_NRF_RX_DR):
        while (!hal_nrf_rx_fifo_empty ())  
        {
          hal_nrf_read_rx_pload(pload);
        }
        Radio_Set_Status (RF_RX_DR);      

        break;
  
      /* 接收到ACK数据载荷中断 */
      case ((1<<HAL_NRF_RX_DR)|(1<<HAL_NRF_TX_DS)):
        while (!hal_nrf_rx_fifo_empty ())  
        {
          hal_nrf_read_rx_pload(pload);
        }
        Radio_Set_Status (RF_TX_AP);       
        break;
  
      default:
        break;    
    }
    RESET_RADIO_ACTIVITY();
  }
}


/*********************************************************************
 * 函数名称:P0INT_ISR
 * 功    能:CC2530的P0口中断服务函数
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
#pragma vector=P0INT_VECTOR
__interrupt void P0INT_ISR(void)
{
  Radio_IRQ();
}
#endif
           
/*******************************************************************************
 * 文件名称:hal_2.4GHz_Tag.c
 * 功    能:RFID-2.4GHz-Reader硬件抽象层
 * 作    者:
 * 公    司:
 ******************************************************************************/

#if defined ( TAG_FLAG )
/* 包含头文件 */
/********************************************************************/
#include "ioCC2530.h"           // CC2530的头文件,包含对CC2530的寄存器、中断向量等的定义
#include "hal_2.4GHz_Tag.h"  // RFID-2.4GHz-Tag硬件抽象层头文件
/********************************************************************/



/* 
   通过RF发送的数据载荷。也包含接收数据。 
   使用Radio_Get_Pload_Byte()函数读取
*/
/********************************************************************/
static unsigned char pload[16];
/********************************************************************/


/* 
   RF的当前状态 
   使用Radio_Set_Status函数来设置该变量;
   使用Radio_Get_Status函数来读取该变量。
*/
/********************************************************************/
static radio_status_t status;
/********************************************************************/


/*********************************************************************
 * 函数名称:SetCC2530SleepTime
 * 功    能:设置CC2530睡眠时间,即设置CC2530的睡眠定时器的比较值。
 * 入口参数:ms  处于功耗模式IDLE、PM0、PM1或PM2的时间。
 * 出口参数:无
 * 返 回 值:无
 * 注    意:使用外部32.768KHz晶体
 ********************************************************************/
static void 
SetCC2530SleepTime(unsigned short ms)
{
  unsigned long sleeptime = 0;
  
  /* 读取睡眠定时器的当前计数值 */
  sleeptime |= ST0;
  sleeptime |= (unsigned long)ST1 <<  8;
  sleeptime |= (unsigned long)ST2 << 16;
  
  /* 根据指定的睡眠时间计算出应设置的比较值 */
  sleeptime += (ms * (unsigned long)(32768 / 1000));
  
  /* 设置比较值 */
  while((STLOAD & 0x01) == 0);  // 等待允许加载新的比较值
  ST2 = (unsigned char)(sleeptime >> 16);
  ST1 = (unsigned char)(sleeptime >> 8);
  ST0 = (unsigned char) sleeptime;  
}


/*********************************************************************
 * 函数名称:SetCC2530PowerMode
 * 功    能:设置CC2530功耗模式
 * 入口参数:pm : 0     空闲模式
 *                1     功耗模式PM1
 *                2     功耗模式PM2
 *                3     功耗模式PM3
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
SetCC2530PowerMode(unsigned char pm)
{

  if(pm == 0)
  {
    SLEEPCMD &= ~0x03;
  }
  else if(pm == 3)
  {
    SLEEPCMD |= ~0x03;
  }
  else
  {
    SLEEPCMD &= ~0x03;
    SLEEPCMD |= pm;
  }

  /* 进入所选择的功耗模式 */
  PCON |= 0x01;                            
  
  asm("NOP");    
}


/*********************************************************************
 * 函数名称:CC2530SleepTimer_Delay
 * 功    能:延时函数,延时过程中CC2530处于PM2模式。
 * 入口参数:nMs  延时时长
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void CC2530SleepTimer_Delay(unsigned nMs)
{

  SetCC2530SleepTime(nMs);
  

  IRCON &= ~0x80;
  

  IEN0 |= (0x01 << 5);
  

  SetCC2530PowerMode(2);
}


/*********************************************************************
 * 函数名称:ST_ISR
 * 功    能:CC2530睡眠定时器中断服务函数
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
#pragma vector=ST_VECTOR
__interrupt void ST_ISR(void)
{
  /* 清除CC2530睡眠定时器中断标志 */
  IRCON &= ~0x80;
  
  /* 禁止CC2530睡眠定时器中断 */
  IEN0 &= ~(0x01 << 5);
}


/*********************************************************************
 * 函数名称:SW_SPI_RW
 * 功    能:CC2530模拟SPI总线发送1字节数据并从SPI总线读取1字节数据。
 * 入口参数:value  待发送的1字节数据
 * 出口参数:无
 * 返 回 值:读回的1字节数据
 ********************************************************************/
unsigned char
SW_SPI_RW(unsigned char value)
{
  unsigned char i;
   	
  for(i = 0; i < 8; i++)         
  {
    HAL_2G4Hz_MOSI = (value & 0x80)? 1 : 0;   
    value <<= 1;             
    HAL_2G4Hz_SCK = 1;                
    value |= HAL_2G4Hz_MISO;       	
    HAL_2G4Hz_SCK = 0;            	
  }
  HAL_2G4Hz_MOSI = 0; 
  return(value);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_irq_mode
 * 功    能:使能或禁止nRF24L01+的指定中断源
 * 入口参数:int_source  nRF24L01+的指定中断源
 *           irq_state   使能或禁止
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void hal_nrf_set_irq_mode(hal_nrf_irq_source_t int_source, bool irq_state)
{
  if(irq_state)
  {
    hal_nrf_write_reg(CONFIG, hal_nrf_read_reg(CONFIG) & ~SET_BIT(int_source));
  }
  else
  {
    hal_nrf_write_reg(CONFIG, hal_nrf_read_reg(CONFIG) | SET_BIT(int_source));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_clear_irq_flags
 * 功    能:获取并清除nRF24L01+的中断标志
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:中断标志
 *               0x10  最大重传次数中断
 *               0x20  TX数据发送中断
 *               0x40  RX数据接收中断
 ********************************************************************/
unsigned char
hal_nrf_get_clear_irq_flags(void)
{
  return hal_nrf_write_reg(STATUS, (BIT_6|BIT_5|BIT_4)) & (BIT_6|BIT_5|BIT_4);
}


/*********************************************************************
 * 函数名称:hal_nrf_clear_irq_flag
 * 功    能:清除nRF24L01+的指定中断标志
 * 入口参数:int_source  指定中断源
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_clear_irq_flag(hal_nrf_irq_source_t int_source)
{
  hal_nrf_write_reg(STATUS, SET_BIT(int_source));
}


/*********************************************************************
 * 函数名称:hal_nrf_get_irq_mode
 * 功    能:获取指定中断的模式
 * 入口参数:int_type  指定中断源
 * 出口参数:无
 * 返 回 值:FALSE 禁止
 *           TRUE  使能
 ********************************************************************/
bool 
hal_nrf_get_irq_mode(unsigned char int_type)
{
  if(hal_nrf_read_reg(CONFIG) & SET_BIT(int_type))
    return false;
  else
    return true;
}


/*********************************************************************
 * 函数名称:hal_nrf_nop
 * 功    能:调用该函数接收nRF24L01+的状态寄存器
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:状态寄存器的值
 ********************************************************************/
unsigned char
hal_nrf_nop(void)
{
  return hal_nrf_write_reg(NOP,0);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_irq_flags
 * 功    能:获取nRF24L01+的中断标志
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:中断标志
 *               0x10  最大重传次数中断
 *               0x20  TX数据发送中断
 *               0x40  RX数据接收中断
 ********************************************************************/
unsigned char
hal_nrf_get_irq_flags(void)
{
  return hal_nrf_nop() & (BIT_6|BIT_5|BIT_4);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_crc_mode
 * 功    能:设置nRF24L01+的CRC模式
 * 入口参数:crc_mode  禁止
 *                     1字节
 *                     2字节
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_crc_mode(hal_nrf_crc_mode_t crc_mode)
{
  hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(BIT_3|BIT_2)) | 
                    (UINT8(crc_mode)<<2));
}


/*********************************************************************
 * 函数名称:hal_nrf_open_pipe
 * 功    能:打开nRF24L01+的1个或所有管道,并设置带有/不带自动ACK特性。
 * 入口参数:pipe_num  管道号
 *           auto_ack  自动ACK特性开/关
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_open_pipe(hal_nrf_address_t pipe_num, bool auto_ack)
{
  switch(pipe_num)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_PIPE2:
    case HAL_NRF_PIPE3:
    case HAL_NRF_PIPE4:
    case HAL_NRF_PIPE5:
      hal_nrf_write_reg(EN_RXADDR, hal_nrf_read_reg(EN_RXADDR) | SET_BIT(pipe_num));

      if(auto_ack)
        hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) | SET_BIT(pipe_num));
      else
        hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) & ~SET_BIT(pipe_num));
      break;

    case HAL_NRF_ALL:
      hal_nrf_write_reg(EN_RXADDR, ~(BIT_7|BIT_6));

      if(auto_ack)
        hal_nrf_write_reg(EN_AA, ~(BIT_7|BIT_6));
      else
        hal_nrf_write_reg(EN_AA, 0);
      break;
      
    default:
      break;
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_close_pipe
 * 功    能:关闭nRF24L01+的1个或所有管道
 * 入口参数:pipe_num  管道号
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_close_pipe(hal_nrf_address_t pipe_num)
{
  switch(pipe_num)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_PIPE2:
    case HAL_NRF_PIPE3:
    case HAL_NRF_PIPE4:
    case HAL_NRF_PIPE5:
      hal_nrf_write_reg(EN_RXADDR, hal_nrf_read_reg(EN_RXADDR) & ~SET_BIT(pipe_num));
      hal_nrf_write_reg(EN_AA, hal_nrf_read_reg(EN_AA) & ~SET_BIT(pipe_num));
      break;
    
    case HAL_NRF_ALL:
      hal_nrf_write_reg(EN_RXADDR, 0);
      hal_nrf_write_reg(EN_AA, 0);
      break;
      
    default:
      break;
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_set_address
 * 功    能:设置RX或TX地址
 * 入口参数:address  设置哪个地址
 *           addr     指向保存地址值的缓冲区的指针
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_address(hal_nrf_address_t address, unsigned char *addr)
{
  switch(address)
  {
    case HAL_NRF_TX:
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
      hal_nrf_write_multibyte_reg((unsigned char) address, addr, 0);
      break;

    case HAL_NRF_PIPE2:
    case HAL_NRF_PIPE3:
    case HAL_NRF_PIPE4:
    case HAL_NRF_PIPE5:
      hal_nrf_write_reg(RX_ADDR_P0 + (unsigned char) address, *addr);
      break;

    default:
      break;
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_set_auto_retr
 * 功    能:设置重传次数和重传延时
 * 入口参数:retr   重传次数
 *           delay  重传延时(单位:us)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_auto_retr(unsigned char retr, unsigned short delay)
{
  hal_nrf_write_reg(SETUP_RETR, (((delay/250)-1)<<4) | retr);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_address_width
 * 功    能:设置地址宽度
 * 入口参数:address_width  地址宽度
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_address_width(hal_nrf_address_width_t address_width)
{
  hal_nrf_write_reg(SETUP_AW, (UINT8(address_width) - 2));
}


/*********************************************************************
 * 函数名称:hal_nrf_set_rx_pload_width
 * 功    能:设置指定管道上期望接收的数据长度(单位:字节)
 * 入口参数:pipe_num     管道
 *           pload_width  期望接收的字节数量
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_rx_pload_width(unsigned char pipe_num, unsigned char pload_width)
{
  hal_nrf_write_reg(RX_PW_P0 + pipe_num, pload_width);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_crc_mode
 * 功    能:获取所使用的CRC模式
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  无CRC
 *           0x02  CRC-8
 *           0x03  CRC-16
 ********************************************************************/
unsigned char
hal_nrf_get_crc_mode(void)
{
  return (hal_nrf_read_reg(CONFIG) & (BIT_3|BIT_2)) >> CRCO;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_pipe_status
 * 功    能:获取指定管道的状态
 * 入口参数:pipe_num  管道号
 * 出口参数:无
 * 返 回 值:0x00  管道关闭,自动ACK禁止
 *           0x01  管道打开,自动ACK禁止
 *           0x03  管道打开,自动ACK打开
 ********************************************************************/
unsigned char
hal_nrf_get_pipe_status(unsigned char pipe_num)
{
  unsigned char en_rx, en_aa;

  en_rx = hal_nrf_read_reg(EN_RXADDR) & (1<<pipe_num);
  en_aa = hal_nrf_read_reg(EN_AA) & (1<<pipe_num);

  en_rx >>= pipe_num;
  en_aa >>= pipe_num;

  return (en_aa << 1) + en_rx;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_address
 * 功    能:获取指定管道的地址
 * 入口参数:address  要获取哪一种地址,PIPE或TX地址
 *           addr     获取到得地址数据将写入该指针指向的缓冲区
 * 出口参数:无
 * 返 回 值:地址宽度(单位:字节)
 ********************************************************************/
unsigned char 
hal_nrf_get_address(unsigned char address, unsigned char *addr)
{
  switch(address)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_TX:
      return hal_nrf_read_multibyte_reg(address, addr);

    default:
      *addr = hal_nrf_read_reg(RX_ADDR_P0 + address);
      return hal_nrf_get_address_width();
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_auto_retr_status
 * 功    能:获取自动重传参数,即重传次数和重传延时。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:高4位  重传延时
 *           低4位  重传次数
 ********************************************************************/
unsigned char
hal_nrf_get_auto_retr_status(void)
{
  return hal_nrf_read_reg(OBSERVE_TX);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_packet_lost_ctr
 * 功    能:获取丢包计数器的值
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:丢包计数器的值
 ********************************************************************/
unsigned char 
hal_nrf_get_packet_lost_ctr(void)
{
  return (hal_nrf_read_reg(OBSERVE_TX) & (BIT_7|BIT_6|BIT_5|BIT_4)) >> 4;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_rx_pload_width
 * 功    能:获取所指定管道上所期望接收的数据宽度(单位:字节)
 * 入口参数:pipe_num  管道号
 * 出口参数:无
 * 返 回 值:数据宽度(单位:字节)
 ********************************************************************/
unsigned char  
hal_nrf_get_rx_pload_width(unsigned char  pipe_num)
{
  return hal_nrf_read_reg(RX_PW_P0 + pipe_num);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_operation_mode
 * 功    能:进入 PTX (primary TX) 或 PRX (primary RX)模式
 * 入口参数:op_mode  运行模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_operation_mode(hal_nrf_operation_mode_t op_mode)
{
  if(op_mode == HAL_NRF_PRX)
  {
    hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) | (1<<PRIM_RX)));
  }
  else
  {
    hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) & ~(1<<PRIM_RX)));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_set_power_mode
 * 功    能:上电或掉电RF
 * 入口参数:pwr_mode  POWER_UP 或 POWER_DOWN  
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_power_mode(hal_nrf_pwr_mode_t pwr_mode)
{
  if(pwr_mode == HAL_NRF_PWR_UP)
  {
    hal_nrf_write_reg(CONFIG, (hal_nrf_read_reg(CONFIG) | (1<<PWR_UP)));
  }
  else
  {
    asm("nop"); 
    asm("nop");
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_set_rf_channel
 * 功    能:选择所使用的RF信道
 * 入口参数:channel  RF信道  
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_rf_channel(unsigned char channel)
{
  hal_nrf_write_reg(RF_CH, channel);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_output_power
 * 功    能:选择RF TX输出功率
 * 入口参数:power  RF TX输出功率 
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_output_power(hal_nrf_output_power_t power)
{
  hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & 
                    ~((1<<RF_PWR1)|(1<<RF_PWR0))) | (UINT8(power)<<1));
}


/*********************************************************************
 * 函数名称:hal_nrf_set_datarate
 * 功    能:设置无线通信数据速率
 * 入口参数:datarate  无线通信数据速率 
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_datarate(hal_nrf_datarate_t datarate)
{
  if(datarate == HAL_NRF_1MBPS)
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<RF_DR)));
  }
  else
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<RF_DR)));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_operation_mode
 * 功    能:获取运行模式
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  Primary RX (PRX) 
 *           0x01  Primary TX (PTX) 
 ********************************************************************/
unsigned char
hal_nrf_get_operation_mode(void)
{
  return (hal_nrf_read_reg(CONFIG) & (1<<PRIM_RX)) >> PRIM_RX;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_power_mode
 * 功    能:获取功耗模式
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  POWER_DOWN  
 *           0x01  POWER_UP   
 ********************************************************************/
unsigned char 
hal_nrf_get_power_mode(void)
{
  return (hal_nrf_read_reg(CONFIG) & (1<<PWR_UP)) >> PWR_UP;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_rf_channel
 * 功    能:获取所使用的RF信道
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:RF信道
 ********************************************************************/
unsigned char  
hal_nrf_get_rf_channel(void)
{
  return hal_nrf_read_reg(RF_CH);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_output_power
 * 功    能:获取所使用的RF TX输出功率
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  -18dBm
 *           0x01  -12dBm
 *           0x02  -6dBm
 *           0x03  0dBm
 ********************************************************************/
unsigned char  
hal_nrf_get_output_power(void)
{
  return (hal_nrf_read_reg(RF_SETUP) & ((1<<RF_PWR1)|(1<<RF_PWR0))) >> RF_PWR0;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_datarate
 * 功    能:获取所使用的无线通信数据速率
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  1Mbps 
 *           0x01  2Mbps
 ********************************************************************/
unsigned char
hal_nrf_get_datarate(void)
{
  return (hal_nrf_read_reg(RF_SETUP) & (1<<RF_DR)) >> RF_DR;
}


/*********************************************************************
 * 函数名称:hal_nrf_rx_fifo_empty
 * 功    能:检查RX FIFO是否为空
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  RX FIFO 不空   
 *           TRUE   RX FIFO 空
 ********************************************************************/
bool 
hal_nrf_rx_fifo_empty(void)
{
 if(hal_nrf_get_rx_data_source()==7)
  {
    return true;
  }
  else
  {
    return false;
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_rx_fifo_full
 * 功    能:检查RX FIFO是否为满
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  RX FIFO 不满   
 *           TRUE   RX FIFO 满
 ********************************************************************/
bool 
hal_nrf_rx_fifo_full(void)
{
  return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> RX_EMPTY) & 1);
}


/*********************************************************************
 * 函数名称:hal_nrf_tx_fifo_empty
 * 功    能:检查TX FIFO是否为空
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  TX FIFO 不空   
 *           TRUE   TX FIFO 空
 ********************************************************************/
bool 
hal_nrf_tx_fifo_empty(void)
{
  return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> TX_EMPTY) & 1);
}


/*********************************************************************
 * 函数名称:hal_nrf_tx_fifo_full
 * 功    能:检查TX FIFO是否为满
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  TX FIFO 不满  
 *           TRUE   TX FIFO 满
 ********************************************************************/
bool 
hal_nrf_tx_fifo_full(void)
{
  return (bool)((hal_nrf_read_reg(FIFO_STATUS) >> TX_FIFO_FULL) & 1);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_tx_fifo_status
 * 功    能:检查TX FIFO的状态
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  TX FIFO 不空, 也不满    
 *           0x01  TX FIFO 空
 *           0x02  TX FIFO 满
 ********************************************************************/
unsigned char
hal_nrf_get_tx_fifo_status(void)
{
  return ((hal_nrf_read_reg(FIFO_STATUS) & 
           ((1<<TX_FIFO_FULL)|(1<<TX_EMPTY))) >> 4);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_rx_fifo_status
 * 功    能:检查RX FIFO的状态
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:0x00  RX FIFO 不空, 也不满    
 *           0x01  RX FIFO 空
 *           0x02  RX FIFO 满
 ********************************************************************/
unsigned char
hal_nrf_get_rx_fifo_status(void)
{
  return (hal_nrf_read_reg(FIFO_STATUS) & ((1<<RX_FULL)|(1<<RX_EMPTY)));
}


/*********************************************************************
 * 函数名称:hal_nrf_get_fifo_status
 * 功    能:检查FIFO状态
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FIFO状态寄存器的值
 ********************************************************************/
unsigned char 
hal_nrf_get_fifo_status(void)
{
  return hal_nrf_read_reg(FIFO_STATUS);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_transmit_attempts
 * 功    能:获取重传尝试的次数和丢包数量
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:重传尝试计数器的值
 ********************************************************************/
unsigned char 
hal_nrf_get_transmit_attempts(void)
{
  return hal_nrf_read_reg(OBSERVE_TX) & (BIT_3|BIT_2|BIT_1|BIT_0);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_carrier_detect
 * 功    能:获取载波检测标志
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  未检测到载波
 *           TRUE   检测到载波
 ********************************************************************/
bool 
hal_nrf_get_carrier_detect(void)
{
  return hal_nrf_read_reg(CD) & 1;
}


/*********************************************************************
 * 函数名称:hal_nrf_write_tx_pload
 * 功    能:写数据包的数据载荷部分到RF
 * 入口参数:tx_pload  指向存储数据载荷的缓冲区的指针
 *           length    数据载荷的长度(单位:字节)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_write_tx_pload(unsigned char *tx_pload, unsigned char length)
{
  hal_nrf_write_multibyte_reg(UINT8(HAL_NRF_TX_PLOAD), tx_pload, length);
}


/*********************************************************************
 * 函数名称:hal_nrf_setup_dyn_pl
 * 功    能:设置接收管道的动态数据负载特性。
 * 入口参数:setup  管道特性位掩码
 *                  例如:bit0设置为1时,管道0使用ACK数据负载。
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_setup_dyn_pl(unsigned char setup)
{
  hal_nrf_write_reg(DYNPD, setup & ~0xC0); 
}


/*********************************************************************
 * 函数名称:hal_nrf_enable_dynamic_pl
 * 功    能:使能动态数据负载特性。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_enable_dynamic_pl(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x04));   
}


/*********************************************************************
 * 函数名称:hal_nrf_disable_dynamic_pl
 * 功    能:禁止动态数据负载特性。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_disable_dynamic_pl(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x04));   
}


/*********************************************************************
 * 函数名称:hal_nrf_enable_ack_pl
 * 功    能:使能ACK数据负载特性。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_enable_ack_pl(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x02));   
}


/*********************************************************************
 * 函数名称:hal_nrf_disable_ack_pl
 * 功    能:禁止ACK数据负载特性。
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_disable_ack_pl(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x02));   
}


/*********************************************************************
 * 函数名称:hal_nrf_enable_dynamic_ack
 * 功    能:使能no-ack特性
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_enable_dynamic_ack(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) | 0x01));   
}


/*********************************************************************
 * 函数名称:hal_nrf_disable_dynamic_ack
 * 功    能:禁止no-ack特性
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_disable_dynamic_ack(void)
{
  hal_nrf_write_reg(FEATURE, (hal_nrf_read_reg(FEATURE) & ~0x01));   
}


/*********************************************************************
 * 函数名称:hal_nrf_write_ack_pload
 * 功    能:给指定管道写入带ACK特性的数据负载。
 * 入口参数:pipe      管道号
 *           tx_pload  指向存储待写入数据的缓冲区的指针
 *           length    待写入数据的长度(单位:字节)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_write_ack_pload(unsigned char pipe, unsigned char *tx_pload, 
                        unsigned char length)
{
  HAL_2G4Hz_CSN = 0;

  SW_SPI_RW(WR_ACK_PLOAD | pipe);
  while(length--)
  {
    SW_SPI_RW(*tx_pload++);
  }

  HAL_2G4Hz_CSN = 1;
}


/*********************************************************************
 * 函数名称:hal_nrf_read_rx_pl_w
 * 功    能:读取接收到的ACK数据负载的宽度
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:接收到的ACK数据负载的宽度
 ********************************************************************/
unsigned char 
hal_nrf_read_rx_pl_w()
{
  unsigned char temp;
  
  HAL_2G4Hz_CSN = 0;

  SW_SPI_RW(RD_RX_PLOAD_W);
  temp = SW_SPI_RW(0);
  
  HAL_2G4Hz_CSN = 1;

  return temp;
}


/*********************************************************************
 * 函数名称:hal_nrf_lock_unlock
 * 功    能:给nRF24L01+发送ACTIVATE命令
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_lock_unlock()
{
  HAL_2G4Hz_CSN = 0;

  SW_SPI_RW(LOCK_UNLOCK);             
  SW_SPI_RW(0x73);

  HAL_2G4Hz_CSN = 1;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_rx_data_source
 * 功    能:获取当前哪一个管道接收的数据包是当前最高级别数据包
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:管道号
 ********************************************************************/
unsigned char 
hal_nrf_get_rx_data_source(void)
{
  return ((hal_nrf_nop() & (BIT_3|BIT_2|BIT_1)) >> 1);
}


/*********************************************************************
 * 函数名称:hal_nrf_read_reg
 * 功    能:读取nRF24L01+的寄存器内容
 * 入口参数:reg  要读取的寄存器
 * 出口参数:无
 * 返 回 值:读出的寄存器内容
 ********************************************************************/
unsigned char
hal_nrf_read_reg(unsigned char reg)
{
  unsigned char temp;
  
  HAL_2G4Hz_CSN = 0;
  SW_SPI_RW(reg);
  temp = SW_SPI_RW(0);
  HAL_2G4Hz_CSN = 1;
  
  return temp;
}


/*********************************************************************
 * 函数名称:hal_nrf_read_rx_pload
 * 功    能:读取RX FIFO中可用的最高级别数据载荷
 * 入口参数:rx_pload  指向存储读出数据的缓冲区的指针
 * 出口参数:无
 * 返 回 值:高8位  管道号
 *           低8位  数据长度(单位:字节)
 *           数据长度为0且管道号为7意味着FIFO为空
 ********************************************************************/
unsigned short 
hal_nrf_read_rx_pload(unsigned char *rx_pload)
{
  return hal_nrf_read_multibyte_reg(UINT8(HAL_NRF_RX_PLOAD), rx_pload);
}


/*********************************************************************
 * 函数名称:hal_nrf_reuse_tx
 * 功    能:设置RF使用最后一次发送的数据载荷作为下一个数据包
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_reuse_tx(void)
{
  hal_nrf_write_reg(REUSE_TX_PL, 0);
}


/*********************************************************************
 * 函数名称:hal_nrf_get_reuse_tx_status
 * 功    能:检查reuse_tx功能的状态
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:FALSE  未激活
 *           TRUE   激活
 ********************************************************************/
bool 
hal_nrf_get_reuse_tx_status(void)
{
  return (bool)((hal_nrf_get_fifo_status() & (1<<TX_REUSE)) >> TX_REUSE);
}


/*********************************************************************
 * 函数名称:hal_nrf_flush_rx
 * 功    能:清空RX FIFO
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_flush_rx(void)
{
  hal_nrf_write_reg(FLUSH_RX, 0);
}


/*********************************************************************
 * 函数名称:hal_nrf_flush_tx
 * 功    能:清空TX FIFO
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_flush_tx(void)
{
  hal_nrf_write_reg(FLUSH_TX, 0);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_pll_mode
 * 功    能:LOCK或UNLOCK RF PLL
 * 入口参数:pll_mode  PLL locked: TRUE 或 FALSE 
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_pll_mode(hal_nrf_pll_mode_t pll_mode)
{
  if(pll_mode == HAL_NRF_PLL_LOCK)
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<PLL_LOCK)));
  }
  else
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<PLL_LOCK)));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_pll_mode
 * 功    能:获取 RF PLL的当前模式
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:RF PLL的当前模式
 ********************************************************************/
hal_nrf_pll_mode_t 
hal_nrf_get_pll_mode(void)
{
  return (hal_nrf_pll_mode_t)((hal_nrf_read_reg(RF_SETUP) & 
                               (1<<PLL_LOCK)) >> PLL_LOCK);
}


/*********************************************************************
 * 函数名称:hal_nrf_set_lna_gain
 * 功    能:设置RF使用的LNA增益模式
 * 入口参数:lna_gain  LNA增益模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_set_lna_gain(hal_nrf_lna_mode_t lna_gain)
{
  if(lna_gain == HAL_NRF_LNA_HCURR)
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) | (1<<LNA_HCURR)));
  }
  else
  {
    hal_nrf_write_reg(RF_SETUP, (hal_nrf_read_reg(RF_SETUP) & ~(1<<LNA_HCURR)));
  }
}


/*********************************************************************
 * 函数名称:hal_nrf_get_lna_gain
 * 功    能:获取RF当前使用的LNA增益模式
 * 入口参数:lna_gain  LNA增益模式
 * 出口参数:无
 * 返 回 值:0  LNA 低电流
 *           1  LNA 高电流
 ********************************************************************/
hal_nrf_lna_mode_t 
hal_nrf_get_lna_gain(void)
{
  return (hal_nrf_lna_mode_t) ( (hal_nrf_read_reg(RF_SETUP) & 
                                 (1<<LNA_HCURR)) >> LNA_HCURR );
}


/*********************************************************************
 * 函数名称:hal_nrf_read_multibyte_reg
 * 功    能:从nRF24L01+的指定寄存器读取多字节数据
 * 入口参数:reg    nRF24L01+的指定寄存器
 *           pbuf   指向存储读出数据的缓冲区的指针
 * 出口参数:无
 * 返 回 值:高8位:接收数据的管道号(用于hal_nrf_read_rx_pload函数)
 *           低8位:读取数据的长度(用于hal_nrf_read_rx_pload 或hal_nrf_get_address函数)
 ********************************************************************/
unsigned short
hal_nrf_read_multibyte_reg(unsigned char reg, unsigned char *pbuf)
{
  unsigned char ctr, length;
  switch(reg)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_TX:
      length = ctr = hal_nrf_get_address_width();
      HAL_2G4Hz_CSN = 0;
      SW_SPI_RW(RX_ADDR_P0 + reg);
      break;
      
    case HAL_NRF_RX_PLOAD:
      if( (reg = hal_nrf_get_rx_data_source()) < 7)
      {
        length = ctr = hal_nrf_read_rx_pl_w();

        HAL_2G4Hz_CSN = 0;
        SW_SPI_RW(RD_RX_PLOAD);
      }
      else
      {
       ctr = length = 0;
      }
      break;

    default:
      ctr = length = 0;
      break;
  }

  while(ctr--)
  {
    *pbuf++ = SW_SPI_RW(0);
  }

    HAL_2G4Hz_CSN = 1;

  return (((unsigned short) reg << 8) | length);
}


/*********************************************************************
 * 函数名称:hal_nrf_write_reg
 * 功    能:写一个新值到nRF24L01+的指定寄存器
 * 入口参数:reg    待写入新值的寄存器
 *           value  待写入的新值
 * 出口参数:无
 * 返 回 值:1字节返回值
 ********************************************************************/
unsigned char
hal_nrf_write_reg(unsigned char reg, unsigned char value)
{
  unsigned char retval;
  
  HAL_2G4Hz_CSN = 0;

  if(reg < WRITE_REG)
  {
    retval = SW_SPI_RW(WRITE_REG + reg);
    SW_SPI_RW(value);
  }

  else
  {
    if(!(reg == FLUSH_TX) && !(reg == FLUSH_RX) && !(reg == REUSE_TX_PL) && !(reg == NOP))
    {
      retval = SW_SPI_RW(reg);
      SW_SPI_RW(value);
    }

    else
    {
      retval = SW_SPI_RW(reg);
    }
  }
  HAL_2G4Hz_CSN = 1;

  return retval;
}


/*********************************************************************
 * 函数名称:hal_nrf_get_address_width
 * 功    能:获取nRF24L01+射频使用的地址宽度,包括RX和TX
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:地址宽度(单位:字节)
 ********************************************************************/
unsigned char
hal_nrf_get_address_width(void)
{
  return (hal_nrf_read_reg(SETUP_AW) + 2);
}


/*********************************************************************
 * 函数名称:hal_nrf_write_multibyte_reg
 * 功    能:写多个字节数据到nRF24L01+的指定寄存器
 * 入口参数:reg    待写入数据的寄存器
 *           pbuf   指向保存待写入数据的缓冲区的指针
 *           length  待写入数据的长度(单位:字节)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
hal_nrf_write_multibyte_reg(unsigned char reg, unsigned char *pbuf, 
                            unsigned char length)
{
  switch(reg)
  {
    case HAL_NRF_PIPE0:
    case HAL_NRF_PIPE1:
    case HAL_NRF_TX:
      length = hal_nrf_get_address_width();
      HAL_2G4Hz_CSN = 0;
      SW_SPI_RW(WRITE_REG + RX_ADDR_P0 + reg);
      break;

    case HAL_NRF_TX_PLOAD:
      HAL_2G4Hz_CSN = 0;
      SW_SPI_RW(WR_TX_PLOAD);
      break;      

    default:
      break;
  }

  while(length--)
  {
    SW_SPI_RW(*pbuf++);
  } 
  
  HAL_2G4Hz_CSN = 1;
}


/*********************************************************************
 * 函数名称:hal_2G4Hz_Tag_Init
 * 功    能:RFID-2.4GHz-Tag硬件抽象层初始化
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 * 注    意:本函数使能了CC2530的全局中断
 ********************************************************************/
void hal_2G4Hz_Tag_Init(void)
{
  /* 使能CC2530的缓存预取模式 */ 
  PREFETCH_ENABLE();
  
  /* LED相关初始化 */
  HAL_2G4Hz_LED1_TURN_OFF();
  HAL_2G4Hz_LED1_DDR |= HAL_2G4Hz_LED1_BV;
  HAL_2G4Hz_LED2_TURN_OFF();
  HAL_2G4Hz_LED2_DDR |= HAL_2G4Hz_LED2_BV;
  
  /* CC2530与nRF24L01+相连引脚初始化 */
  HAL_2G4Hz_CSN = 1;
  HAL_2G4Hz_CE = 0;
  HAL_2G4Hz_MOSI = 0;
  HAL_2G4Hz_SCK = 0;
  HAL_2G4Hz_CSN_DDR |= HAL_2G4Hz_CSN_BV;
  HAL_2G4Hz_CE_DDR |= HAL_2G4Hz_CE_BV;
  HAL_2G4Hz_SCK_DDR |= HAL_2G4Hz_SCK_BV;
  HAL_2G4Hz_MOSI_DDR |= HAL_2G4Hz_MOSI_BV;
  HAL_2G4Hz_MISO_DDR &= ~HAL_2G4Hz_MISO_BV;
  HAL_2G4Hz_IRQ_DDR &= ~HAL_2G4Hz_IRQ_BV;
    
                               
  P0INP |= HAL_2G4Hz_BUTTON_BV;
  PICTL |= 0x01;
  P0IEN |= HAL_2G4Hz_IRQ_BV;
  IEN1 |= (1 << 5);

  EA = 1;
}


/*********************************************************************
 * 函数名称:Radio_Set_Status
 * 功    能:更新status全局变量
 * 入口参数:new_status  新状态值
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_Set_Status (radio_status_t new_status)
{
  status = new_status;
}


/*********************************************************************
 * 函数名称:Radio_Get_Status
 * 功    能:读取status全局变量
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:RF当前状态标志变量status的当前值
 ********************************************************************/
radio_status_t 
Radio_Get_Status (void)
{
  return status;
}


/*********************************************************************
 * 函数名称:HAL_2G4Hz_CE_PULSE
 * 功    能:脉动nRF24L01+的CE信号至少10us
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
HAL_2G4Hz_CE_PULSE(void)
{
  unsigned char count;
  
  count = 40;
  HAL_2G4Hz_CE =  1;
  while(count--);
  HAL_2G4Hz_CE =  0;
}


/*********************************************************************
 * 函数名称:Radio_SB_MODE_Init
 * 功    能:nRF24L01+的ShockBurst(TM)模式初始化
 * 入口参数:address           设备地址
 *           operational_mode  PTX(Primary TX operation)模式
 *                             RTX(Primary RX operation)模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_SB_MODE_Init (unsigned char *address, 
                    hal_nrf_operation_mode_t operational_mode)
{

  hal_nrf_close_pipe(HAL_NRF_ALL);
  hal_nrf_open_pipe(HAL_NRF_PIPE0, false);
  hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
  hal_nrf_set_auto_retr(0, RF_RETRANS_DELAY);
  hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
  hal_nrf_set_address(HAL_NRF_TX, address);
  hal_nrf_set_address(HAL_NRF_PIPE0, address);  
  if(operational_mode == HAL_NRF_PTX)
  {
    hal_nrf_set_operation_mode(HAL_NRF_PTX);
  }

  else
  {
   hal_nrf_set_operation_mode(HAL_NRF_PRX);
   hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);
  }

  hal_nrf_set_rf_channel(RF_CHANNEL);
  hal_nrf_set_datarate(HAL_NRF_2MBPS);
  hal_nrf_set_power_mode(HAL_NRF_PWR_UP);
  CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);
  Radio_Set_Status (RF_IDLE);
}


/*********************************************************************
 * 函数名称:Radio_ESB_MODE_Init
 * 功    能:nRF24L01+的Enhanced ShockBurst(TM)模式初始化
 * 入口参数:address           设备地址
 *           operational_mode  PTX(Primary TX operation)模式
 *                             RTX(Primary RX operation)模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_ESB_MODE_Init (unsigned char *address, 
                     hal_nrf_operation_mode_t operational_mode)
{
  /* nRF24L01+默认情况下管道0和1是打开的,因此首先关闭所有管道 */
  hal_nrf_close_pipe(HAL_NRF_ALL);
  
  hal_nrf_open_pipe(HAL_NRF_PIPE0, true);

  /* 使用CRC-16模式 */
  hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
  
  /* 使能自动重传:重传次数为RF_RETRANSMITS,重传延时为RF_RETRANS_DELAY */
  hal_nrf_set_auto_retr(RF_RETRANSMITS, RF_RETRANS_DELAY);                 
          
  hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
 
  hal_nrf_set_address(HAL_NRF_TX, address);
  
  hal_nrf_set_address(HAL_NRF_PIPE0, address);
  
  /* 设置为PTX模式 */
  if(operational_mode == HAL_NRF_PTX)
  {
    hal_nrf_set_operation_mode(HAL_NRF_PTX);
  }
  /* 设置为RTX模式 */
  else
  {
    hal_nrf_set_operation_mode(HAL_NRF_PRX);
    hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);                               
  }

  /* 设置运行信道为 频率 = 2400 + RF_CHANNEL */
  hal_nrf_set_rf_channel(RF_CHANNEL);
  
  hal_nrf_set_power_mode(HAL_NRF_PWR_UP);

  CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);

  /* RF就绪 */
  Radio_Set_Status (RF_IDLE);
}


/*********************************************************************
 * 函数名称:Radio_ESB_MODE_PL_Init
 * 功    能:nRF24L01+的Enhanced ShockBurst(TM) with bidirectional Data模式初始化
 * 入口参数:address           设备地址
 *           operational_mode  PTX(Primary TX operation)模式
 *                             RTX(Primary RX operation)模式
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_ESB_MODE_PL_Init (unsigned char *address, 
                        hal_nrf_operation_mode_t operational_mode)
{
  /* nRF24L01+默认情况下管道0和1是打开的,因此首先关闭所有管道 */
  hal_nrf_close_pipe(HAL_NRF_ALL);
  
  hal_nrf_open_pipe(HAL_NRF_PIPE0, true);

  hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
  
  hal_nrf_set_auto_retr(RF_RETRANSMITS, RF_RETRANS_DELAY);                 
          
  hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
  
  hal_nrf_set_address(HAL_NRF_TX, address);
  
  hal_nrf_set_address(HAL_NRF_PIPE0, address);

  /* 
     以下部分与Radio_ESB_MODE_Init函数不同
     使能ACK数据载荷
     使能动态数据载荷宽度
     使能动态ACK
  */
  /****************************************************************************/
  /* 使能ACK数据载荷特性 */
  hal_nrf_enable_ack_pl();

  if(hal_nrf_read_reg(FEATURE) == 0x00 && (hal_nrf_read_reg(DYNPD) == 0x00))
  {
    hal_nrf_lock_unlock ();
    
    hal_nrf_enable_ack_pl();
  }

  /* 使能动态数据载荷特性 */
  hal_nrf_enable_dynamic_pl();
  
  /* 设置所有接收管道具有动态数据载荷特性 */
  hal_nrf_setup_dyn_pl(ALL_PIPES);
  /****************************************************************************/
   
  /* 设置为PTX模式 */
  if(operational_mode == HAL_NRF_PTX)
  {
    hal_nrf_set_operation_mode(HAL_NRF_PTX);
  }
  /* 设置为RTX模式 */
  else
  {
    hal_nrf_set_operation_mode(HAL_NRF_PRX);
    
    hal_nrf_set_rx_pload_width((unsigned char)HAL_NRF_PIPE0, RF_PAYLOAD_LENGTH);                               
  }

  hal_nrf_set_rf_channel(RF_CHANNEL);
  
  hal_nrf_set_power_mode(HAL_NRF_PWR_UP);

  CC2530SleepTimer_Delay(RF_POWER_UP_DELAY);

  Radio_Set_Status (RF_IDLE);
}


/*********************************************************************
 * 函数名称:Radio_Send_Packet
 * 功    能:RF发送数据包
 * 入口参数:packet   指向保存待发送数据包的缓冲区的指针
 *           length   待发送数据包的长度(单位:字节)
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void
Radio_Send_Packet(unsigned char *packet, unsigned char length)
{
  /* 加载数据包到RF */
  hal_nrf_write_tx_pload(packet, length);
  
  /* RF发送 */
  HAL_2G4Hz_CE_PULSE();

  /* 更新RF状态变量status 为RF_BUSY */
  Radio_Set_Status (RF_BUSY);
}


/*********************************************************************
 * 函数名称:Radio_Get_Pload_Byte
 * 功    能:byte_index  数据载荷的字节索引
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:数据载荷字节索引所指定的1字节数据
 ********************************************************************/
unsigned char 
Radio_Get_Pload_Byte (unsigned char byte_index)
{
  return pload[byte_index];
}


/*********************************************************************
 * 函数名称:Radio_IRQ
 * 功    能:nRF24L01+的中断处理函数
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
Radio_IRQ(void) 
{
  /* 若nRF24L01+触发了CC2530的外部中断 */
  if(RADIO_ACTIVITY())
  { 
    hal_nrf_set_power_mode(HAL_NRF_PWR_DOWN);
    
      HAL_2G4Hz_CE = 0;
            
    switch(hal_nrf_get_clear_irq_flags ())
    {
      /* 达到最大重传次数中断 */
      case (1<<HAL_NRF_MAX_RT):
        hal_nrf_flush_tx();           
        Radio_Set_Status (RF_MAX_RT);  
        break;
      
      /* TX数据发送中断 */
      case (1<<HAL_NRF_TX_DS):
        Radio_Set_Status (RF_TX_DS);   
        break;
      
      /* RX数据接收中断 */
      case (1<<HAL_NRF_RX_DR):
        while (!hal_nrf_rx_fifo_empty ())  
        {
          hal_nrf_read_rx_pload(pload);
        }
        Radio_Set_Status (RF_RX_DR);      

        break;
  
      /* 接收到ACK数据载荷中断 */
      case ((1<<HAL_NRF_RX_DR)|(1<<HAL_NRF_TX_DS)):
        while (!hal_nrf_rx_fifo_empty ())  
        {
          hal_nrf_read_rx_pload(pload);
        }
        Radio_Set_Status (RF_TX_AP);       
        break;
  
      default:
        break;    
    }
    RESET_RADIO_ACTIVITY();
  }
}


/*********************************************************************
 * 函数名称:P0INT_ISR
 * 功    能:CC2530的P0口中断服务函数
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
#pragma vector=P0INT_VECTOR
__interrupt void P0INT_ISR(void)
{
  Radio_IRQ();
}
#endif
           
/*******************************************************************************
 * 文件名称:SYSCLK.c
 * 功    能:MCU时钟选择
 * 作    者:
 * 公    司:
 ******************************************************************************/

/* 包含头文件 */
/********************************************************************/
#include "SYSCLK.h"
#include "iocc2530.h"
/********************************************************************/


/*********************************************************************
 * 函数名称:SystemClockSourceSelect
 * 功    能:选择系统时钟源(主时钟源)
 * 入口参数:source
 *             XOSC_32MHz  32MHz晶体振荡器
 *             RC_16MHz    16MHz RC振荡器
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void SystemClockSourceSelect(enum SYSCLK_SRC source)
{
  unsigned char osc32k_bm = CLKCONCMD & 0x80;
  unsigned char __clkconcmd,__clkconsta;
      
  /*
     系统时钟源(主时钟源)选择16MHz RC振荡器,定时器tick设置为16MHz,时钟速度设置为16MHz
     CLKCONCMD.OSC32K[b7]不改变      32KHz时钟源选择保持先前设置
     CLKCONCMD.OSC[b6] = 1           系统时钟源(主时钟源)选择16MHz RC振荡器
     CLKCONCMD.TICKSPD[b5..b3] = 001 定时器tick设置为16MHz
     CLKCONCMD.CLKSPD[b2..b0] = 001  时钟速度设置为16MHz
   */
  if(source == RC_16MHz)
  {              /* CLKCONCMD.OSC32K[b7] */
    CLKCONCMD = ((osc32k_bm) | \
                 /* CLKCONCMD.OSC[b6] = 1 */
                 (0x01 << 6) | \
                 /* CLKCONCMD.TICKSPD[b5..b3] = 001 */  
                 (0x01 << 3) | \
                 /* CLKCONCMD.CLKSPD[b2..b0] = 001 */
                 (0x01 << 0));
  }

  
  /*
     系统时钟源(主时钟源)选择32MHz晶体振荡器,定时器tick设置为32MHz,时钟速度设置为32MHz
     CLKCONCMD.OSC32K[b7]不改变      32KHz时钟源选择保持先前设置
     CLKCONCMD.OSC[b6] = 0           系统时钟源(主时钟源)选择32MHz晶体振荡器
     CLKCONCMD.TICKSPD[b5..b3] = 000 定时器tick设置为32MHz
     CLKCONCMD.CLKSPD[b2..b0] = 000  时钟速度设置为32MHz
   */  
  else if(source == XOSC_32MHz)
  {
    CLKCONCMD = (osc32k_bm /*| (0x00<<6) | (0x00<<3) | (0x00 << 0)*/);
  }
  
  
  /* 等待所选择的系统时钟源(主时钟源)稳定 */
  __clkconcmd = CLKCONCMD;             
  do
  {
    __clkconsta = CLKCONSTA;          
  }while(__clkconsta != __clkconcmd);  
                                       
                                      
}
           
/*******************************************************************************
 * 文件名称:UART0.c
 * 功    能:CC2530的UART0驱动
 * 作    者:
 * 公    司:
 ******************************************************************************/

#if !defined ( TAG_FLAG )
/* 包含头文件 */
/********************************************************************/
#include "ioCC2530.h"    // CC2530的头文件,包含对CC2530的寄存器、中断向量等的定义
#include "UART0.h"
/********************************************************************/


/*********************************************************************
 * 函数名称:InitUART0
 * 功    能:UART0初始化
 *           P0.2  RX                  
 *           P0.3  TX
 *           波特率:115200
 *           数据位:8
 *           停止位:1
 *           奇偶校验:无
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void InitUART0(void)
{
  /* 片内外设引脚位置采用上电复位默认值,即PERCFG寄存器采用默认值 */
  /*
      P0.2   RX
      P0.3   TX
      P0.4   CT
      P0.5   RT
   */
    
  /* UART0相关引脚初始化 */
  P0SEL |= ((0x01 << 2) | (0x01 << 3));  
  
  /* P0口外设优先级采用上电复位默认值,即P2DIR寄存器采用默认值 */
  /*
     第一优先级:USART0
     第二优先级:USART1
     第三优先级:Timer1
   */
  
  /* UART0波特率设置 */
  /* 波特率:115200   
     当使用32MHz 晶体振荡器作为系统时钟时,要获得115200波特率需要如下设置:
         UxBAUD.BAUD_M = 216
         UxGCR.BAUD_E = 11
     该设置误差为0.03%
   */
  U0BAUD = 216;
  U0GCR = 11;
  
  /* USART模式选择 */
  U0CSR |= 0x80;  // UART模式
  
  /* UART0配置 */
  U0UCR |= 0x80;  // 进行USART清除
  /*
     以下配置参数采用上电复位默认值:
         硬件流控:无
         奇偶校验位(第9位):奇校验
         第9位数据使能:否
         奇偶校验使能:否
         停止位:1个
         停止位电平:高电平
         起始位电平:低电平
   */
  
  /* 用于发送的位顺序采用上电复位默认值,即U0GCR寄存器采用上电复位默认值 */
  /* LSB先发送 */
  
  UTX0IF = 0;  // 清零UART0 TX中断标志
}


/*********************************************************************
 * 函数名称:UART0SendByte
 * 功    能:UART0发送一个字节
 * 入口参数:c
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void UART0SendByte(unsigned char c)
{
  U0DBUF = c;       // 将要发送的1字节数据写入U0DBUF  
  while (!UTX0IF);  // 等待TX中断标志,即U0DBUF就绪
  UTX0IF = 0;       // 清零TX中断标志 
}


/*********************************************************************
 * 函数名称:UART0SendString
 * 功    能:UART0发送一个字符串
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void UART0SendString(unsigned char *str, unsigned char longStr)
{
  while( longStr > 0 )
  {
//    if(*str == '\0') break;  // 遇到结束符,退出
    UART0SendByte(*str++);   // 发送一字节
    longStr--;
  } 
}


/*********************************************************************
 * 函数名称:UART0Send_BackSpace
 * 功    能:UART0发送退格键
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void UART0Send_BackSpace(void)
{
  UART0SendByte('\b');
  UART0SendByte(' ');
  UART0SendByte('\b');
}


/*********************************************************************
 * 函数名称:UART0Send_Space
 * 功    能:UART0发送空格键
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void UART0Send_Space(void)
{
  UART0SendByte(' ');
}


/*********************************************************************
 * 函数名称:UART0Send_Crlf
 * 功    能:UART0发送换行键
 * 入口参数:无
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void UART0Send_Crlf(void)
{
  UART0SendByte('\r');
  UART0SendByte('\n');
}


/*********************************************************************
 * 函数名称:Nibble2Ascii
 * 功    能:将4位二进制比特转换为ASCII HEX字节
 * 入口参数:anibble  4位二进制比特
 * 出口参数:无
 * 返 回 值:ASCII HEX字节
 ********************************************************************/
static unsigned char 
Nibble2Ascii(unsigned char anibble)
{
  unsigned char	AsciiOut = anibble;

  if(anibble > 9)  AsciiOut = AsciiOut + 0x07;

  AsciiOut = AsciiOut + 0x30;

  return(AsciiOut);
}


/*********************************************************************
 * 函数名称:UART0Send_2HEX
 * 功    能:将1个字节的数据按两个十六进制字符方式输出
 * 入口参数:abyte  字节数据
 * 出口参数:无
 * 返 回 值:无
 ********************************************************************/
void 
UART0Send_2HEX(unsigned char abyte)
{
  unsigned char	temp1, temp2;

  temp1 = (abyte >> 4) & 0x0F;
  
  temp2 = Nibble2Ascii(temp1);
  
  UART0SendByte(temp2);

  temp1 = abyte & 0x0F;
  
  temp2 = Nibble2Ascii(temp1);
  
  UART0SendByte(temp2);
}
#endif
           

继续阅读