📄 iai_ezmac_plus_internal.c
字号:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* *
* FILE NAME: IAI_EZMac_Plus_Internal.c *
* *
* DESIGNER: Kovacs, Krisztian; Lukacs, Miklos *
* PROGRAMMER: Kovacs, Krisztian; Lukacs, Miklos; Szell Andras *
* *
* DESCRIPTION: EZMac internal functions *
* *
* REVISION: 01_2 March 04, 2005 deviation 75kHz *
* 01_3 March 23, 2005 Transmit and receive packet lenght *
* can be different in fixed leght mode*
* 01_4 April 20, 2005 EZradio initialization fime tuning, *
* Wake-up timer is in on state *
* between Wake_Up() and Sleep() *
* (not correct POR fix) *
* 01_5 April 28, 2005 Clock Recovery lock checking after *
* DQD check, *
* 01_6 Aug 11, 2005 FIFO restart after HW error, *
* Timer IT handling improvements *
* 02_0 March 21, 2006 Finalize the HiTech porting *
* EZMac Plus: *
* 01_0 Sept 28, 2006 Create EZMac Plus from EZMac *
* *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#define SM_REAL_FUNCTION
#ifdef SM_REAL_FUNCTION
#define SM_SOFTWDT_EN //turn on the software watchdog timers
#endif
//#define LED_DEBUG
//===============================================================================================
#pragma separate
void Ch_Check_Start (bool ChangeFreq)
{
#ifdef HITECH_COMPILER
static bool bank2 NextFreq;
static int bank2 Reg;
#endif
#ifdef CCS_C_COMPILER
bool NextFreq;
int Reg;
#endif
#ifdef FIX_MEM_ADDRESS
#pragma byte ChangeFreq = 0x63
#pragma bit NextFreq = 0x64.0
#pragma byte Reg = 0x65
#endif
//next states will not read data bytes -> External Interrupt routine should set the SPI select pin
SetSpiEn = TRUE;
#ifdef SM_REAL_FUNCTION
if(EZ_commands.arr[Fifo_command] & 0x0002)
{
EZ_commands.arr[Fifo_command] &=0xFFFD; //reset synchron latch
EZRadio_CMD_Write(Fifo_command);
}
#endif
disable_interrupts( INT_EXT );
//set the frequency
if( ChangeFreq && EZ_reg.bits.RCRB.SCHEN )
{
Reg = (0xFF >> (7 - EZ_reg.bits.MCRB.NRF));
//are all of the available frequencys masked?
if( (EZ_reg.bytes.FMASKB & Reg) == Reg )
//all of the freq are masked -> failure; the state machine stay in the current frequency
NextFreq = FALSE;
else
NextFreq = TRUE;
while(NextFreq)
{
if( Frequency < EZ_reg.bits.MCRB.NRF )
{//it isn't the last frequency
Frequency++;
if( ((EZ_reg.bytes.FMASKB >> Frequency) & 0x01) == 0 )
//this frequency isn't masked -> end of search
NextFreq = FALSE;
}
else
{//go to the first frequency
Frequency = 0;
if( ((EZ_reg.bytes.FMASKB >> Frequency) & 0x01) == 0 )
//this frequency isn't masked -> end of search
NextFreq = FALSE;
}
}
}
//if the search of the channel isn't active, set the default frequency
if( !EZ_reg.bits.RCRB.SCHEN )
Frequency = (int8)EZ_reg.bits.RCRB.RF;
//configure Trixie for new freq (Frequency)
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Freq_command]=0xA000 + ((int16)(EZ_reg.bytes.FR[Frequency]-1)*FREQ_step+FREQ_start);
EZRadio_CMD_Write(Freq_command);
#endif
#ifdef SM_PRINTF
printf("F: %x\n\r",Frequency);
#endif
//set the RSR register to the default value
EZ_reg.bytes.RSRB = 0;
//Set the next state
EZ_state = EZMac_S_RxDQDCheck;
EZInternalState = EZ_RxDQDCheck;
//set the DQD Check init values
Data = 0;
Data1 = 0;
//Start T1 to first DQD check
_Set_Timer1(FIRST_DQD_TIMER_LIMIT);
}
//===============================================================================================
#pragma separate
bool _DQD_Check (void)
{
#ifdef SM_REAL_FUNCTION
if( MISO_PIN )
return 1;
else
return 0;
#else
return TRUE; //only for debug
#endif
}
//===============================================================================================
#pragma separate
bool _DRSSI_Read (void)
{
//Read the DRSSI from the Trixie
SEL_PIN = 0;
STRH=Spi_Comm0();
SEL_PIN = 1;
return (STRH & DRSSI_bit);
}
//===============================================================================================
#pragma separate
void _GotoTxErrorState(void)
{
unsigned char led_temp;
SetSpiEn = TRUE;
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Power_command] &= 0xff0f; //switch off Trixie
EZRadio_CMD_Write(Power_command);
#endif
//disable all IT
_Turn_Off_Timer1();
disable_interrupts( INT_EXT );
if (EZ_state == EZMac_S_Forwarding)
{
if(StateAfterForward != EZMac_S_PacketValid)
{
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Config_command]=0x8000 | FREQ_Band | XTAL_COMP | FIFO_USED; //switch on RX FIFO
EZRadio_Write(EZ_commands.arr[Config_command]);
EZRadio_Statusread ();
EZ_commands.arr[Power_command] |= 0x0080; //switch on the receiver
EZRadio_Write(EZ_commands.arr[Power_command]);
#endif
Ch_Check_Start(TRUE);
}
else
{
EZ_state = EZMac_S_PacketValid;
EZInternalState = EZ_RxEnd;
}
}
else
{
//Set the next state
if (EZ_state == EZMac_S_WaitingForAck)
EZ_state = EZMac_S_AckReceiveError;
else
EZ_state = EZMac_S_TxError;
EZInternalState = EZ_TransmitError;
}
}
//===============================================================================================
#pragma separate
void _TrixieHWError(void)
{
#ifdef SM_REAL_FUNCTION
_Turn_Off_Timer1();
//restart Trixie
disable_interrupts( INT_EXT );
EZ_commands.arr[Config_command]=0x8000 | FREQ_Band | XTAL_COMP;
EZ_commands.arr[Fifo_command]=FIFO_cmd_init_value; //Fill:synchron pattern; IT level:8; disable sensitive reset
EZ_commands.arr[Data_Rate_command]=DR_cmd_init_value; //8842bps
EZ_commands.arr[RX_Ctrl_command]=RX_cmd_init_value; // BW:135kHz; VDI:always on; LNA:max; DRSSI:-103; Pin8: VDIout
EZ_commands.arr[RX_Ctrl_command] &= 0xFFF8;
EZ_commands.arr[RX_Ctrl_command] |= (int16)((EZ_reg.bytes.RCRB & 0x70) >> 4);
EZ_commands.arr[TX_Ctrl_command]=TX_cmd_init_value & 0xfff1; //f0+df; df:75kHz; Pout:-3dB!!!!
EZ_commands.arr[TX_Ctrl_command] &= 0xFFF8;
EZ_commands.arr[TX_Ctrl_command] |= (int16)((EZ_reg.bytes.TCRB & 0x38) >> 3);
EZ_commands.arr[Data_Filter_command]=DF_cmd_init_value; //CR:slow; Digital LPF; DQD:7
EZ_commands.arr[AFC_command]=AFC_cmd_init_value; //enabled; fine mode; auto,keep offset; +7/-8; output enabled
EZRadio_CMD_Write(Config_command);
EZRadio_CMD_Write(Fifo_command);
EZRadio_CMD_Write(Data_Rate_command);
EZRadio_CMD_Write(TX_Ctrl_command);
EZRadio_CMD_Write(RX_Ctrl_command);
EZRadio_CMD_Write(Data_Filter_command);
EZRadio_CMD_Write(AFC_command);
EZRadio_Statusread (); //read all IT status bit
#endif
//next states will not read data bytes -> External Interrupt routine should set the SPI select pin
SetSpiEn = TRUE;
//In which state did the failure occured?
if( EZInternalState > EZ_RxEnd )
{//during tx -> goto TxError state or signal that the forward is done
if (EZ_state == EZMac_S_Forwarding)
if(StateAfterForward != EZMac_S_PacketValid)
{
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Config_command]=0x8000 | FREQ_Band | XTAL_COMP | FIFO_USED; //switch on RX FIFO
EZRadio_Write(EZ_commands.arr[Config_command]);
EZRadio_Statusread ();
EZ_commands.arr[Power_command] |= 0x0080; //switch on the receiver
EZRadio_Write(EZ_commands.arr[Power_command]);
#endif
Ch_Check_Start(TRUE);
}
else
{
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Power_command] &= 0xff0f; //switch off Trixie
EZRadio_CMD_Write(Power_command);
#endif
EZ_state = EZMac_S_PacketValid; //Signal that the packet is ready
EZInternalState = EZ_RxEnd;
}
else
_GotoTxErrorState();
return;
}
if ( (EZInternalState < EZ_TxCheckChannel) && (EZInternalState > EZ_WakeUp) )
{//during rx
//switch on Rx and FIFO
EZ_commands.arr[Config_command]=0x8000 | FREQ_Band | XTAL_COMP | FIFO_USED; //switch on RX FIFO
EZRadio_Write(EZ_commands.arr[Config_command]);
EZRadio_Statusread ();
//goto new freq or keep waiting for ACK
if(EZ_state == EZMac_S_WaitingForAck)
EZMac_Ackwait(20);
else
Ch_Check_Start(TRUE);
return;
}
//if else, then stay in the current state
}
//===============================================================================================
#pragma separate
int8 _ReadByte_Trixie(void)
{
#ifdef HITECH_COMPILER
static int8 bank2 data;
#endif
#ifdef CCS_C_COMPILER
int8 data;
#endif
data=Spi_Comm0();
SEL_PIN = 1;
return data;
}
//===============================================================================================
#pragma separate
void _WriteByte_Trixie (int8 data)
{
SEL_PIN = 0; //SEL=0
EZ_Spi_Write(0x0B8);
EZ_Spi_Write(data);
SEL_PIN = 1; //SEL=1
}
//===============================================================================================
#pragma separate
void State_Machine (char It_Source)
{
#ifdef HITECH_COMPILER
static bool bank2 AddrSID, AddrDID, FirstError;
static int16 bank2 TimerSet;
#endif
#ifdef CCS_C_COMPILER
bool AddrSID, AddrDID, FirstError;
int16 TimerSet;
#endif
#ifdef FIX_MEM_ADDRESS
#pragma byte It_Source = 0x67
#pragma bit AddrSID = 0x64.1
#pragma bit AddrDID = 0x64.2
#pragma bit FirstError = 0x64.3
#endif
if( (It_Source == IT_SOURCE_OVUR) || (It_Source == IT_SOURCE_COMM_OVUR) )
{//Trixie HW error: overrun or underrun!
_TrixieHWError();
return;
}
switch( EZInternalState )
{
/*Idle state*/
case EZ_Idle:
break;
/*Sleep state*/
case EZ_Sleep:
break;
/*after waking up*/
case EZ_WakeUp:
if ( It_Source != IT_SOURCE_T1 )
{
//waking up error
_TrixieHWError();
_Turn_Off_Timer1();
}
//set next state
EZ_state = EZMac_S_Idle;
EZInternalState = EZ_Idle;
break;
/*channel check before receiving*/
case EZ_RxDQDCheck:
if( Data1 == 0 )
{//it will be the first DQD
//multiplex the DQD bit to the MISO pin
SEL_PIN = 0;
Spi_Comm0();
}
//is the DQD 1 or 0?
//save DQD value: only the last logic high value of the DQD will increment the counter
if( _DQD_Check() )
Data++;
else
Data = 0;
//increment the number of the sample counter
Data1++;
if(Data1 == DQD_SAMPLE)
{//after sampling we should check the result
//set the select pin
SEL_PIN = 1;
if( Data > 2)
{//at least the last 3 DQD was logic high
//we can receive any data; wait for IRQ -> after TIMER1 IT and the DQD is OK, or after EXT IT (the sync pattern is received)
//Turn on the FIFO of Trixie
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Fifo_command] |= 0x0002; //enable synchron latch
EZRadio_CMD_Write(Fifo_command);
#endif
clear_interrupt( INT_EXT );
enable_interrupts( INT_EXT );
//init CRC calculation routine
Crc_Init();
Data = EZ_reg.bits.MCRB.NRF + 7; //number of preamble + 3 (2D D4 and the first data byte)
_Set_Timer1( 65535 - (ONE_BYTE_TIMER_LIMIT) ); //we will check the CRL bit 2.5ms later than we switched
//on the receiver (DQD check=1.5ms + 1ms)
//next states will read data byte from the FIFO, the External Interrupt routine shouldn't set the SPI select pin!
SetSpiEn = FALSE;
//Set next state EzMacPlus
EZInternalState = EZ_RxCheckControl;
if(EZ_state != EZMac_S_WaitingForAck)
EZ_state = EZMac_S_Receiving;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -