www.pudn.com > rfid.rar > hal_2.45GHz_Reader.c, change:2012-04-22,size:13240b


/******************************************************************************* 
 * 文件名称:hal_2.45GHz_Reader.c 
 * 功    能:RFID-2.45GHz-Reader硬件抽象层 
 * 作    者:Ronnie 
 * 公    司:湘潭斯凯电子科技有限公司 
 *           www.sikai-tech.com 
 * 日    期:2011-06-26 
 ******************************************************************************/ 
 
 
/* 包含头文件 */ 
/********************************************************************/ 
#include "hal_2.45GHz_Reader.h"  
/********************************************************************/ 
 
 
/*  
   通过RF发送的数据载荷。也包含接收数据。  
   使用Radio_Get_Pload_Byte()函数读取 
*/ 
/********************************************************************/ 
static unsigned char pload[16]; 
/********************************************************************/ 
 
 
/*  
   RF的当前状态  
   使用Radio_Set_Status函数来设置该变量; 
   使用Radio_Get_Status函数来读取该变量。 
*/ 
/********************************************************************/ 
radio_status_t status; 
/********************************************************************/ 
 
 
/********************************************************************* 
 * 函数名称:delay_ms 
 * 功    能:毫秒级延时函数 
 * 入口参数:n_ms  延时长度 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void delay_ms(unsigned int n_ms)  
{ 
  unsigned int ii1, ii0; 
     
  for(ii0=n_ms; ii0>0; ii0--)  
  { 
    ii1 = 0x07FF; 
    do (ii1--); 
    while (ii1 != 0); 
  } 
} 
 
 
/********************************************************************* 
 * 函数名称:SW_SPI_RW 
 * 功    能:MSP430模拟SPI总线发送1字节数据并从SPI总线读取1字节数据。 
 * 入口参数:value  待发送的1字节数据 
 * 出口参数:无 
 * 返 回 值:读回的1字节数据 
 ********************************************************************/ 
unsigned char SW_SPI_RW(unsigned char value) 
{ 
  unsigned char i; 
   	 
  for(i = 0; i < 8; i++)          
  { 
    if(value & 0x80) 
    { 
      MOSI_DATA_H; 
    } 
    else 
    { 
      MOSI_DATA_L; 
    }    
     
    value <<= 1;    
         
    SCK_DATA_H; 
 
    value |= MISO_DATA; 
 
    SCK_DATA_L;            	 
  } 
   
  MOSI_DATA_L;  
   
  return(value); 
} 
 
 
/********************************************************************* 
 * 函数名称:hal_nrf_read_reg 
 * 功    能:读取nRF24L01+的寄存器内容 
 * 入口参数:reg  要读取的寄存器 
 * 出口参数:无 
 * 返 回 值:读出的寄存器内容 
 ********************************************************************/ 
unsigned char hal_nrf_read_reg(unsigned char reg) 
{ 
  unsigned char temp; 
   
  CSN_DATA_L; 
  SW_SPI_RW(reg); 
  temp = SW_SPI_RW(0); 
  CSN_DATA_H; 
   
  return temp; 
} 
 
 
/********************************************************************* 
 * 函数名称:hal_nrf_read_rx_pl_w 
 * 功    能:读取接收到的ACK数据负载的宽度 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:接收到的ACK数据负载的宽度 
 ********************************************************************/ 
unsigned char hal_nrf_read_rx_pl_w() 
{ 
  unsigned char temp; 
   
  CSN_DATA_L; 
 
  SW_SPI_RW(RD_RX_PLOAD_W); 
  temp = SW_SPI_RW(0); 
   
  CSN_DATA_H; 
 
  return temp; 
} 
 
 
/********************************************************************* 
 * 函数名称: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(); 
      CSN_DATA_L; 
      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(); 
 
        CSN_DATA_L; 
        SW_SPI_RW(RD_RX_PLOAD); 
      } 
      else 
      { 
       ctr = length = 0; 
      } 
      break; 
 
    default: 
      ctr = length = 0; 
      break; 
  } 
 
  while(ctr--) 
  { 
    *pbuf++ = SW_SPI_RW(0); 
  } 
 
  CSN_DATA_H; 
 
  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; 
   
  CSN_DATA_L; 
 
  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); 
    } 
  } 
  CSN_DATA_H; 
 
  return retval; 
} 
 
 
/********************************************************************* 
 * 函数名称: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(); 
      CSN_DATA_L; 
      SW_SPI_RW(WRITE_REG + RX_ADDR_P0 + reg); 
      break; 
 
    case HAL_NRF_TX_PLOAD: 
      CSN_DATA_L; 
      SW_SPI_RW(WR_TX_PLOAD); 
      break;       
    
    default: 
      break; 
  } 
 
  while(length--) 
  { 
    SW_SPI_RW(*pbuf++); 
  }  
   
  CSN_DATA_H; 
} 
 
 
/********************************************************************* 
 * 函数名称:hal_nrf_nop 
 * 功    能:调用该函数接收nRF24L01+的状态寄存器 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:状态寄存器的值 
 ********************************************************************/ 
unsigned char hal_nrf_nop(void) 
{ 
  return hal_nrf_write_reg(NOP,0); 
} 
 
 
/********************************************************************* 
 * 函数名称: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, (BIT6 | BIT5 | BIT4)) & (BIT6 | BIT5 | BIT4); 
} 
 
 
/********************************************************************* 
 * 函数名称: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_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_get_rx_data_source 
 * 功    能:获取当前哪一个管道接收的数据包是当前最高级别数据包 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:管道号 
 ********************************************************************/ 
unsigned char hal_nrf_get_rx_data_source(void) 
{ 
  return ((hal_nrf_nop() & (BIT3 | BIT2 | BIT1)) >> 1); 
} 
 
 
/********************************************************************* 
 * 函数名称: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((unsigned char)(HAL_NRF_RX_PLOAD), rx_pload); 
} 
 
 
/********************************************************************* 
 * 函数名称:hal_nrf_flush_tx 
 * 功    能:清空TX FIFO 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void hal_nrf_flush_tx(void) 
{ 
  hal_nrf_write_reg(FLUSH_TX, 0); 
} 
 
 
/********************************************************************* 
 * 函数名称: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_2G4Hz_Reader_Init 
 * 功    能:RFID-2.4GHz-Reader硬件抽象层初始化 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 * 注    意:本函数使能了CC2530的全局中断 
 ********************************************************************/ 
void hal_2G4Hz_Reader_Init(void) 
{  
  /* LED相关初始化 */ 
  LED_OFF; 
  LED_DIR_OUT; 
   
  /* MSP430与nRF24L01+相连引脚初始化 */ 
  CSN_DATA_H; 
  CE_DATA_L; 
  MOSI_DATA_L; 
  SCK_DATA_L; 
  CSN_DIR_OUT; 
  CE_DIR_OUT; 
  MOSI_DIR_OUT; 
  SCK_DIR_OUT; 
  MISO_DIR_IN; 
  IRQ_DIR_IN; 
  IRQ_EDGE; 
   
  /* 使能相关中断 */ 
  IRQ_ON; 
} 
 
 
/********************************************************************* 
 * 函数名称:Radio_Set_Status 
 * 功    能:更新status全局变量 
 * 入口参数:new_status  新状态值 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
void Radio_Set_Status (radio_status_t new_status) 
{ 
  status = new_status; 
} 
 
 
/********************************************************************* 
 * 函数名称: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); 
     
    CE_DATA_L; 
             
    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(); 
  } 
} 
 
 
/********************************************************************* 
 * 函数名称:Port_B 
 * 功    能:MSP430的端口2中断服务函数 
 * 入口参数:无 
 * 出口参数:无 
 * 返 回 值:无 
 ********************************************************************/ 
#pragma vector = PORT2_VECTOR 
__interrupt void Port_B (void) 
{ 
  Radio_IRQ(); 
  __low_power_mode_off_on_exit(); 
}