📄 iai_ezmac_plus.c
字号:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* *
* FILE NAME: IAI_EZMac_Plus.c *
* *
* DESIGNER: Kovacs, Krisztian; Lukacs, Miklos *
* PROGRAMMER: Kovacs, Krisztian; Lukacs, Miklos; Sz閘l Andr醩 *
* *
* DESCRIPTION: EZMac 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, *
* Received PL=0 corrected *
* 01_6 Aug 11, 2005 Clearing the Timer IT flag in the *
* Timer ISR *
* 02_0 March 21, 2006 Finalize the HiTech porting *
* *
* 02_12 Sept 28, 2006 Bug corrected: EZMacBuf_Read() *
* function call during TX stops trans-*
* mission and cause CW signal *
* EZMac Plus: *
* 01_0 Sept 28, 2006 Create EZMac Plus from EZMac *
* *
* *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//===============================================================================================
#pragma separate
char EZMac_Wake_Up(void)
{
if (EZ_state!=EZMac_S_Sleep) return STATE_ERROR;
//switch on EZRadio oscillator
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Power_command] |= 0x0008;
EZRadio_Write(EZ_commands.arr[Power_command]);
#endif
//set EZMac state
EZ_state = EZMac_S_WakeUp;
EZInternalState = EZ_WakeUp;
// setup timer1 to wake up after crystal is running
_Set_Timer1(WAKING_UP_PERIOD);
return MAC_OK;
}
//===============================================================================================
#pragma separate
char EZMac_Sleep(void)
{
// state check
if (EZ_state!=EZMac_S_Idle) return STATE_ERROR;
// switch off EZRadio
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Fifo_command] &=0xFFFD; //reset synchron latch
EZRadio_Write(EZ_commands.arr[Fifo_command]);
EZ_commands.arr[Power_command] &= 0xff07; //switch off XTAL osc.
EZ_commands.arr[Power_command] |= 0x0001; //to be sure that clk out is off
EZRadio_Write(EZ_commands.arr[Power_command]);
#endif
//set EZMac state
EZ_state = EZMac_S_Sleep;
EZInternalState = EZ_Sleep;
return MAC_OK;
}
//===============================================================================================
#pragma separate
#ifdef HITECH_COMPILER
#pragma interrupt_level 1
#endif
char EZMac_Idle(void)
{
#ifdef HITECH_COMPILER
static int8 bank2 dosleep;
static int8 bank2 retstate = MAC_OK;
#endif
#ifdef CCS_C_COMPILER
int8 dosleep;
int8 retstate = MAC_OK;
#endif
//disable all interrupts
_Turn_Off_Timer1();
disable_interrupts(INT_EXT);
if (EZ_state==EZMac_S_Idle) return MAC_OK;
// sleep mode or unfinished wakeup
if ((EZ_state==EZMac_S_WakeUp) || (EZ_state==EZMac_S_Sleep)) return WKUP_ERROR;
// receiving or transmission is in process?
if ( (EZ_state == EZMac_S_Receiving) || (EZ_state == EZMac_S_TxPacket) )
retstate = STATE_ERROR;
// AXOT/AXOR test
if ( (EZ_state == EZMac_S_Receiving) || (EZ_state == EZMac_S_PacketValid) || (EZ_state == EZMac_S_SendingAck)) // receiving states
dosleep = EZ_reg.bits.RCRB.AXOR;
else
dosleep = EZ_reg.bits.TCRB.AXOT; // transmission, idle, or AckWaiting state ?
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Fifo_command] &=0xFFFD; //reset synchron latch
EZRadio_Write(EZ_commands.arr[Fifo_command]);
EZ_commands.arr[Config_command]=0x8000 | FREQ_Band | XTAL_COMP; //switch off TX latch, and RX FIFO
EZRadio_Write(EZ_commands.arr[Config_command]);
#endif
// go to sleep or idle state
if (dosleep)
{
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Power_command] &= 0xff07;
EZRadio_Write(EZ_commands.arr[Power_command]);
#endif
EZ_state = EZMac_S_Sleep;
EZInternalState = EZ_Sleep;
}
else
{
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Power_command] &= 0xff0f;
EZRadio_Write(EZ_commands.arr[Power_command]);
#endif
EZ_state = EZMac_S_Idle;
EZInternalState = EZ_Idle;
}
#ifdef SM_REAL_FUNCTION
EZRadio_Statusread (); //reset all non latched IT in Trixie
#endif
return retstate;
}
//===============================================================================================
#pragma separate
char EZMac_Transmit (void)
{
// state check: state must be Idle or TransmitError
if ((EZ_state==EZMac_S_Sleep) || (EZ_state==EZMac_S_WakeUp))
return WKUP_ERROR;
if ((EZ_state!=EZMac_S_Idle) && (EZ_state!=EZMac_S_TxError) && (EZ_state!=EZMac_S_AckReceiveError))
return STATE_ERROR;
//check the length of the packet: if it is incorrect, then back with error!
if( (EZ_reg.bytes.PLENB > PLEN_MAX) || (EZ_reg.bytes.PLENB < 1) )
return VALUE_ERROR;
//if it isn't network address mode, then copy the self address to the correct register
if( !EZ_reg.bits.MCRB.NWAD )
EZ_reg.bytes.SIDB = EZ_reg.bytes.SFIDB;
//set the preamble value: number of frequency + 3 (the first 2 copied automatically by Trixie)
DataByteCounter = EZ_reg.bits.MCRB.NRF + 1;
//Init the CRC calc. function
Crc_Init();
//set the frequency
Frequency = EZ_reg.bits.TCRB.TF;
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Freq_command]=0xA000 + ((int16)(EZ_reg.bytes.FR[Frequency]-1)*FREQ_step+FREQ_start);
EZRadio_Write(EZ_commands.arr[Freq_command]);
#endif
//next states will not read data bytes -> External Interrupt routine should set the SPI select pin
SetSpiEn = TRUE;
if( EZ_reg.bits.TCRB.LBTEN )
{//listen before talk enable
#ifdef SM_REAL_FUNCTION //configure Trixie for receiving
EZRadio_Statusread ();
EZ_commands.arr[Power_command] |= 0x0080; //switch on the receiver
EZRadio_Write(EZ_commands.arr[Power_command]);
#endif
EZInternalState = EZ_TxCheckChannel; //set the next state
EZ_state = EZMac_S_TxCheckChannel;
Data = 0; //the parameters for LBT
Data1 = 0;
csmaCycle = 0;
csmaCounter = CSMA_COUNTER_BASE;
_Set_Timer1(FIRST_DQD_TIMER_LIMIT); //set up T1 for DQD check
}
else
{//listen before talk isn't enable
#ifdef SM_REAL_FUNCTION //configure Trixie for transmit
//switch on TX reg.
EZ_commands.arr[Config_command]=0x8000 | FREQ_Band | XTAL_COMP | TXREG_USED;
EZRadio_Write(EZ_commands.arr[Config_command]);
EZRadio_Statusread ();
EZ_commands.arr[Power_command] |= 0x0020; //switch on the transmitter
EZRadio_Write(EZ_commands.arr[Power_command]);
#endif
EZ_state = EZMac_S_TxPacket; //set the next state
EZInternalState = EZ_TxSendPreamble;
#ifdef SM_SOFTWDT_EN //set up the SW Watch dog timer for packet transmitting
_Set_Timer1(MAX_TX_PACKET_TIMER);
#endif
clear_interrupt( INT_EXT ); //clear IT flag
enable_interrupts( INT_EXT ); //enable ext IT
}
return MAC_OK;
}
//===============================================================================================
#pragma separate
char EZMac_Receive (void)
{
// state check
if ((EZ_state==EZMac_S_Sleep) || (EZ_state==EZMac_S_WakeUp))
return WKUP_ERROR;
if (EZ_state!=EZMac_S_Idle)
return STATE_ERROR;
#ifdef ARSSI_USED
setup_adc(ADC_CLOCK_DIV_32);
set_adc_channel(ARSSI_CHANNEL);
#endif
//configure Trixie
#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
//set the frequency
Frequency = EZ_reg.bits.RCRB.RF;
//setup T1 to wake up the state machine (Ch_Check_Start in IAI_EZmac_internal.c will do)
Ch_Check_Start(FALSE);
//next states will not read data bytes -> Interrupt routine should set the SPI select pin
SetSpiEn = TRUE;
//parameters for channel check
Data = 0;
Data1 = 0;
return MAC_OK;
}
//===============================================================================================
#pragma separate
char EZMacReg_Write(MacRegs Name, char Value)
{
// register name check
if (Name>EZ_LASTREG) return NAME_ERROR;
// state check
if ((EZ_state != EZMac_S_Idle) && (EZ_state != EZMac_S_Sleep) && (EZ_state != EZMac_S_WakeUp) )
return STATE_ERROR;
// check the parameters
if ( (Name==PLEN) || (Name == RPL_MPL) ) if ( (Value>PLEN_MAX) || (Value == 0) ) return VALUE_ERROR;// too long or 0 buffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -