📄 ia443x_rf.c
字号:
/*
** ============================================================================
**
** FILE
** IA443x_rf.c
**
** DESCRIPTION
** Contains the RF dependent functions
**
** CREATED
** Silicon Laboratories Hungary Ltd
**
** COPYRIGHT
** Copyright 2008 Silicon Laboratories, Inc.
** http://www.silabs.com
**
** ============================================================================
*/
/*------------------------------------------------------------------------*/
/* INCLUDE */
/*------------------------------------------------------------------------*/
#include "IA443x_rf.h"
#include "IA443x_rf_callback.h"
#include "timers.h"
#include "IAI_EBID.h"
#include "global_definitions.h"
/*------------------------------------------------------------------------*/
/* GLOBAL variables */
/*------------------------------------------------------------------------*/
idata RF_STATES RfState;
idata uint8 ItStatus1, ItStatus2, Rssi_ant1, Rssi_ant2, ByteTime;
bit fPacketReceived;
idata uint8 Tmr2SwPrescaler;
idata UU16 RfTimer;
extern xdata ANTENNA_TYPE SelectedAntennaType;
extern code uint8 GFSKRfSettings[NMBR_OF_GFSK_SAMPLE_SETTING][NMBR_OF_PARAMETER];
extern code uint8 OOKRfSettings[NMBR_OF_OOK_SAMPLE_SETTING][NMBR_OF_PARAMETER];
extern code uint8 AribRfSettings[NMBR_OF_ARIB_SAMPLE_SETTING][NMBR_OF_PARAMETER];
/*------------------------------------------------------------------------*/
/* LOCAL function prototypes */
/*------------------------------------------------------------------------*/
void RFStateMachine(RF_ENUM ItSource);
void GotoPreambleSearchState(void);
/*------------------------------------------------------------------------*/
/* LOCAL definitions */
/*------------------------------------------------------------------------*/
//#define RF_LED_DEBUG
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ FUNCTION NAME: void RfInitHw(void)
+
+ DESCRIPTION: initializes the used I/O pins, SPI and timer peripherals,
+ IT routines needed for the RF stack
+
+ RETURN: None
+
+ NOTES: 1.) has to be called in the power-on routine
+ 2.) it doesn't initialize the RF chip registers
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
RF_ENUM RfInitHw(void)
{
//initialize I/O port directions
RF_NSEL_PIN = 1;
EE_NSEL_PIN = 1;
//TMR2 is used for the RF stack
DisableTmr2It();
//set MAC EXT IT - INT0 is used for this purpose (falling edge)
SetExt0ItFallingEdge();
DisableExt0It();
//setup RF stack state machine
RfState = sRFPOR;
//release all IT flag to set IRQ high
ItStatus1 = SpiRfReadRegister(InterruptStatus1);
ItStatus2 = SpiRfReadRegister(InterruptStatus2);
//SW reset -> wait for POR interrupt
SpiRfWriteAddressData((REG_WRITE | OperatingFunctionControl1), 0x80);
//timeout for POR interrupt
RfTimer.U16 = RESET_TIMEOUT;
StartTmr2(RESET_TIMEOUT_DIV,RfTimer,FALSE);
do{
}while( (Tmr2Expired() == FALSE) );
//check the status of the POR
ItStatus1 = SpiRfReadRegister( InterruptStatus1 );
ItStatus2 = SpiRfReadRegister( InterruptStatus2 );
if( (ItStatus2 & 0x03) == 0x03 )
{//POR performed correctly
//disable XTAL
SpiRfWriteAddressData((REG_WRITE | OperatingFunctionControl1), 0x00);
//set RF stack state
RfState = sRFStandBy;
DisableTmr2It();
}
else
{//POR error
DisableTmr2It();
return RF_ERROR_TIMING;
}
//disable all ITs, except 'ichiprdy'
SpiRfWriteAddressData((REG_WRITE | InterruptEnable1), 0x00);
SpiRfWriteAddressData((REG_WRITE | InterruptEnable2), 0x02);
//release all IT flag to set IRQ high
ItStatus1 = SpiRfReadRegister(InterruptStatus1);
ItStatus2 = SpiRfReadRegister(InterruptStatus2);
//set the special registers (what has to be different than the POR-default)
SetSpecialRegisters();
//reset digital testbus, disable scan test
SpiRfWriteAddressData((REG_WRITE | DigitalTestBus), 0x00);
//select nothing to the Analog Testbus
SpiRfWriteAddressData((REG_WRITE | AnalogTestBus), 0x0B);
return RF_OK;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ FUNCTION NAME: RF_ENUM RFWakeUp(void)
+
+ DESCRIPTION: wakes up the RF chip from STANDBY.
+
+ RETURN: RF_OK: the operation was succesfull
+ RF_ERROR_STATE: the operation is ignored, because the
+ RF stack was not in STANDBY state.
+
+ NOTES:
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
RF_ENUM RFWakeUp(void)
{
uint8 temp8;
if( RfState != sRFStandBy )
return RF_ERROR_STATE;
//start the crystal oscillator
temp8 = SpiRfReadRegister( OperatingFunctionControl1 );
temp8 |= 0x01;
SpiRfWriteAddressData((REG_WRITE | OperatingFunctionControl1), temp8);
//set RF stack state
RfState = sRFWakingUp;
//set timeout for XTAL startup
RfTimer.U16 = XTAL_WAKE_UP_PERIOD;
Tmr2SwPrescaler = XTAL_WAKE_UP_PERIOd_SW_DIV;
StartTmr2(XTAL_WAKE_UP_PERIOD_DIV,RfTimer,TRUE);
EnableExt0It();
return RF_OK;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ FUNCTION NAME: RF_ENUM RFSleep(void)
+
+ DESCRIPTION: sets the transceiver into STANDBY state.
+
+ RETURN: RF_OK: the operation was succesfull
+ RF_ERROR_STATE: the operation is ignored, because the
+ RF stack was not in IDLE state.
+
+ NOTES:
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
RF_ENUM RFSleep(void)
{
uint8 temp8;
if( RfState != sRFIdle )
return RF_ERROR_STATE;
//release all IT flag
ItStatus1 = SpiRfReadRegister( InterruptStatus1 );
ItStatus2 = SpiRfReadRegister( InterruptStatus2 );
//stop the crystal oscillator
temp8 = SpiRfReadRegister( OperatingFunctionControl1 );
temp8 &= 0xFE;
SpiRfWriteAddressData((REG_WRITE | OperatingFunctionControl1), temp8);
//set next state
RfState = sRFStandBy;
return RF_OK;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ FUNCTION NAME: RF_ENUM RFSetParameter(RF_PARAMETER parameter, uint8 * value, uint8 length)
+
+ DESCRIPTION: sets the appropiate registers
+
+ INPUT: parameter: name of the RF parameter needs to be change
+ value: value of the parameter (it maybe more bytes)
+ length: number of bytes of the value
+
+ RETURN: RF_OK: the operation was succesfull
+ RF_ERROR_STATE: the operation is ignored, because the
+ RF stack was not in IDLE state.
+ RF_ERROR_PARAMETER: the input paramter is invalid, operation is ignored
+
+ NOTES:
+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
RF_ENUM RFSetParameter(RF_PARAMETER parameter, uint8 * value, uint8 length)
{
uint8 temp8, i;
if( (RfState != sRFIdle) || (length > 100) )
return RF_ERROR_STATE;
switch(parameter)
{
/*
value[0] - frequency band
value[1] - Carrier frequency1
value[2] - Carrier frequency2
*/
case pRfFrequency:
//set frequency band
SpiRfWriteAddressData((REG_WRITE | FrequencyBandSelect), *value++);
//set frequency
SpiRfWriteAddressData((REG_WRITE | NominalCarrierFrequency1), *value++);
SpiRfWriteAddressData((REG_WRITE | NominalCarrierFrequency0), *value);
break;
/*
value[0] - GPIO0
value[1] - GPIO1
value[2] - GPIO2
*/
case pRfGpios:
SpiRfWriteAddressData((REG_WRITE | GPIO0Configuration), *value++);
SpiRfWriteAddressData((REG_WRITE | GPIO1Configuration), *value++);
SpiRfWriteAddressData((REG_WRITE | GPIO2Configuration), *value++);
break;
/*
value[0] - DIGITAL OUT: bit<0> - GPIO0, bit<1> - GPIO1, bit<2> - GPIO2
*/
case pRfDigitalOut:
SpiRfWriteAddressData((REG_WRITE | IOPortConfiguration), (*value & 0x07));
break;
/*
value[0] - DIGITAL INPUT: bit<0> - GPIO0, bit<1> - GPIO1, bit<2> - GPIO2
value[1] - INTERRUPT INPUT STATE: bit<0> - GPIO0, bit<1> - GPIO1, bit<2> - GPIO2
*/
case pRfDigitalIn:
temp8 = SpiRfReadRegister( IOPortConfiguration );
*value++ = temp8 & 0x07;
*value = (temp8 >> 4) & 0x07;
break;
/*
value[0] - Output power
*/
case pRfTransmitPower:
SpiRfWriteAddressData((REG_WRITE | TXPower), *value);
break;
/*
value[0] - Preamble length in nibbles: bit[8]
value[1] - Preamble length in nibbles: bit[7..0]
*/
case pRfPreambleLength:
//set MSB if needed
temp8 = SpiRfReadRegister( HeaderControl2 );
if( *value++ == 0)
{
temp8 &= 0xFE;
}
else
{
temp8 |= 0x01;
}
SpiRfWriteAddressData((REG_WRITE | HeaderControl2), (temp8 & 0x07));
//set lower byte
SpiRfWriteAddressData((REG_WRITE | PreambleLength), *value);
break;
/*
value[0] - Number of nibbles needs to be match (0...31)
*/
case pRfPremableDetection:
temp8 += ((*value & 0x1F) << 3);
SpiRfWriteAddressData((REG_WRITE | PreambleDetectionControl), temp8 );
break;
/*
value[0] - Length of the synchron word (1...4)
value[1] - synchron word 3
value[2] - synchron word 2 -if enabled-
value[3] - synchron word 1 -if enabled-
value[4] - synchron word 0 -if enabled-
*/
case pRfSynchronWord:
temp8 = ((*value++ - 1) << 1) & 0x06;
i = SpiRfReadRegister( HeaderControl2 ) & 0xF9;
i += temp8;
SpiRfWriteAddressData((REG_WRITE | HeaderControl2), i);
for(i=0;i<temp8;i++)
{
SpiRfWriteAddressData((REG_WRITE | (SyncWord3 + i)), *value++);
}
break;
/*
value[0] - new value of the modulation mode ctrl 2 register.
(Refer to the IA443x_rf.h for available definitions!)
*/
case pRfModulation:
temp8 = SpiRfReadRegister( ModulationModeControl1 );
temp8 &= 0x2C;
SpiRfWriteAddressData((REG_WRITE | ModulationModeControl1), temp8);
SpiRfWriteAddressData((REG_WRITE | ModulationModeControl2), *value);
break;
/*
value[0] - wheather the TX / RX packet handler, CRC is enabled or not .
(Refer to the IA443x_rf.h for available definitions!)
*/
case pRfPacketHandler:
SpiRfWriteAddressData((REG_WRITE | DataAccessControl), *value);
break;
/*
value[0] - whether it uses antenna diversity algorithm or not
*/
case pRfAntennaDiversity:
temp8 = SpiRfReadRegister( OperatingFunctionControl2 );
temp8 &= 0x1F;
if( *value == TRUE)
{//enable antenna diversity algorithm
temp8 |= 0x80;
SpiRfWriteAddressData((REG_WRITE | OperatingFunctionControl2), temp8);
}
else
{//disable antenna diversity algorithm
SpiRfWriteAddressData((REG_WRITE | OperatingFunctionControl2), temp8);
}
break;
/*
value[0] - TRUE: enable the LBD; FALSE: disable the LBD
value[1] - TRUE: enable IT, FALSE: disable IT
value[2] - LBD Threshold
*/
case pLowBatteryDetector:
temp8 = SpiRfReadRegister( OperatingFunctionControl1 );
if(*value++ == TRUE)
{//enable the Low Battery Detector
temp8 |= 0x40;
SpiRfWriteAddressData((REG_WRITE | OperatingFunctionControl1), temp8);
temp8 = SpiRfReadRegister( InterruptStatus2 );
if(*value++ == TRUE)
{//enable LBD IT
temp8 |= 0x04;
}
else
{//disable LBD IT
temp8 &= 0xFB;
}
SpiRfWriteAddressData((REG_WRITE | InterruptStatus2), temp8);
SpiRfWriteAddressData((REG_WRITE | LowBatteryDetectorThreshold), *value);
}
else
{//disable the Low Battery Detector
temp8 &= 0xBF;
SpiRfWriteAddressData((REG_WRITE | OperatingFunctionControl1), temp8);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -