📄 iai_ezmac_plus_internal.c
字号:
{
//save data
EZ_reg.bytes.PLENB = Data;
//calc CRC
Crc_On_Fly(Data);
//temporary save the length file
Data1 = EZ_reg.bytes.PLENB;
//configure for data receiving
DataByteCounter = 0;
//set next state
if( Data==0 )
{//the data length = 0
EZInternalState = EZ_RxCheckEDC;
}
else
{//the length higher than 0
EZInternalState = EZ_RxDataByte;
}
}
else
{//filter failed
//inc error counter
if( EZ_reg.bits.EDCRB.BPLEN && (EZ_reg.bytes.EC[Frequency] < 255))
EZ_reg.bytes.EC[Frequency]++;
//go to the next freq.
if(EZ_state == EZMac_S_WaitingForAck)
EZMac_Ackwait(18);
else
Ch_Check_Start(TRUE);
}
}
break;
/*Receiving the Data bytes*/
case EZ_RxDataByte:
if( It_Source == IT_SOURCE_T1 )
//SW Watchdog timer overrun -> Trixie HW error
_TrixieHWError();
else
{//Data byte received, read the data from the Trixie (Data)
#ifdef SM_REAL_FUNCTION
Data = _ReadByte_Trixie();
#else
Data = DataByteCounter;
#endif
//save Data
EZ_reg.bytes.DBuff[DataByteCounter] = Data;
//calc CRC
Crc_On_Fly(Data);
DataByteCounter++;
//was it the last byte?
if( (DataByteCounter == Data1) || (DataByteCounter == PLEN_MAX))
EZInternalState = EZ_RxCheckEDC;
}
break;
/*Receiving the EDC bytes*/
case EZ_RxCheckEDC:
if( It_Source == IT_SOURCE_T1 )
//SW Watchdog timer overrun -> Trixie HW error
_TrixieHWError();
else
{//EDC byte received, read the data from the Trixie (Data)
#ifdef SM_REAL_FUNCTION
Data = _ReadByte_Trixie();
#else
if( (DataByteCounter == (Data1 + 1)) || (DataByteCounter == PLEN_MAX + 1) )
//second CRC
Data = 0x50;
else
//first CRC
Data = 0x29;
#endif
//Calc the CRC for the received CRC
Crc_On_Fly(Data);
DataByteCounter++;
if(DataByteCounter == (Data1 + 2) || (DataByteCounter == PLEN_MAX + 2) )
{//secondCRC byte
//Is the CRC correct?
if(EZ_crc.adat == 0)
{
// Check if it is a repeted rx or not
if (!EZMac_IsRepeatedRx())
{
if(EZ_state == EZMac_S_WaitingForAck)
{// Check if we are waiting for this ACK
if ( (AckSender == EZ_reg.bytes.SIDB) && (EZ_reg.bytes.SFIDB == EZ_reg.bytes.DIDB) && (ControlField & 0x08) && ((ControlField & 0xF0) == (SequenceNumber<<4)))
EZMac_Idle(); // Yes we were waiting for this ACK
else
{
EZMac_Ackwait(20); //No keep searching
}
}
else
{
//turn off Trixie after correct Rx
#ifdef ARSSI_USED
ARSSI_value=(read_adc( ADC_READ_ONLY ));
//switch off ADC, save current
setup_adc( ADC_OFF );
#else
ARSSI_value = 0x23;
#endif
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Fifo_command] &=0xFFFD; //reset synchron latch
EZRadio_CMD_Write(Fifo_command);
EZ_commands.arr[Config_command]=0x8000 | FREQ_Band | XTAL_COMP; //switch off TX latch, and RX FIFO
EZRadio_CMD_Write(Config_command);
EZ_commands.arr[Power_command] &= 0xff0f; //switch off receiver
EZRadio_CMD_Write(Power_command);
EZRadio_Statusread (); //reset all non latched IT in Trixie
EZ_reg.bits.RSRB.PRF = Frequency & 0x07;
#endif
_Turn_Off_Timer1();
disable_interrupts( INT_EXT );
//next states will not read data bytes -> External Interrupt routine should set the SPI select pin
SetSpiEn = TRUE;
// Is ACK needed
if( AckNeeded && (EZ_reg.bytes.SFIDB == EZ_reg.bytes.DIDB))
{
// We are the destination so we have to send an ACK
EZMac_AckTransmit();
}
else
{// There is no ACK needed
// Is forwarding is needed and radious conter didn't exepire, and we are not the Destination
if( EZ_reg.bits.PFWCRB.PFEN && (EZ_reg.bytes.SFIDB != EZ_reg.bytes.DIDB) && (ControlField&0x03) && (EZ_reg.bytes.SFIDB != EZ_reg.bytes.SIDB))
{
// We are forwarding the packet
#ifdef LED_DEBUG
LED4 = 0;
#endif
// Set the state after forwarding
if (ForwardOnly)
StateAfterForward = EZMac_S_Receiving; // We just forward the packet and continue receiveing
else
StateAfterForward = EZMac_S_PacketValid; // This packet is valid for the application
EZMac_ForwardPacket();
}
else
{// If the packet is valid for receive then signal it
EZ_state = EZMac_S_PacketValid;
EZInternalState = EZ_RxEnd;
}
}
}
}
else
{// It is a repeted receive drop the packet
#ifdef LED_DEBUG
LED3=0;
#endif
if(EZ_state == EZMac_S_WaitingForAck)
EZMac_Ackwait(22);
else
Ch_Check_Start(TRUE);
#ifdef LED_DEBUG
LED3=1;
#endif
}
}
else
{ //CRC error
//inc the error counter
if( EZ_reg.bits.EDCRB.BCRC && (EZ_reg.bytes.EC[Frequency] < 255))
EZ_reg.bytes.EC[Frequency]++;
//go to the next freq
if(EZ_state == EZMac_S_WaitingForAck)
EZMac_Ackwait(20);
else
Ch_Check_Start(TRUE);
}
}
else
{//first CRC byte
//read out the DRSSI value from the Trixie (EZ_reg.bits.RSRB.DRSSI)
#ifdef SM_REAL_FUNCTION
EZ_reg.bits.RSRB.DRSSI = _DRSSI_Read();
#endif
if(EZ_reg.bits.MCRB.ADEN)
{//start AD conversion to measure the ARSSI value
#ifdef ARSSI_USED
read_adc(ADC_START_ONLY);
#endif
}
}
}
break;
/*End of the receiving*/
case EZ_RxEnd:
break;
/*Transmit error state*/
case EZ_TransmitError:
break;
/*Channel check before transmit*/
case EZ_TxCheckChannel:
if( It_Source != IT_SOURCE_T1 )
{//HW error, not T1 IT
_TrixieHWError();
return;
}
//Waiting for the CSMA time
// Is it a first call
if ( (csmaCycle == 0) && (csmaCounter == CSMA_COUNTER_BASE))
{// This is the first try : select DQD input
SEL_PIN = 0;
Spi_Comm0();
}
if(csmaCycle < MAX_CSMA_CYCLE)
{
if (csmaCounter == 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 sample we should check the result
//is the DQD 1 or 0?
if( Data > 2)
{//channel occupied, but the CSMA cycle not finished
// Reinicialise the CSMA variables
Data = 0;
Data1 = 0;
csmaCycle++;
csmaCounter = CSMA_COUNTER_BASE;
//keep waiting
_Set_Timer1(DQD_TIMER_LIMIT);
}
else
{//the channel is IDLE, the packet can be sent
// Configure Trixie to start TX
//set the select pin
SEL_PIN = 1;
#ifdef SM_REAL_FUNCTION
EZ_commands.arr[Power_command] &= 0xff0f; //switch off receiver
EZRadio_CMD_Write(Power_command);
EZ_commands.arr[Config_command]=0x8000 | FREQ_Band | XTAL_COMP | TXREG_USED; //switch on TX reg.
EZRadio_CMD_Write(Config_command);
EZ_commands.arr[Power_command] |= 0x0020; //switch on the transmitter
EZRadio_CMD_Write(Power_command);
#endif
//set next state
if(EZ_state != EZMac_S_Forwarding)
EZ_state = EZMac_S_TxPacket;
EZInternalState = EZ_TxSendPreamble;
//setup SW Watchdog timer
#ifdef SM_SOFTWDT_EN
_Set_Timer1(MAX_TX_PACKET_TIMER);
#endif
//enable ext IT
clear_interrupt( INT_EXT );
enable_interrupts( INT_EXT );
// Reinit CSMA variables
Data = 0;
Data1 = 0;
csmaCycle = 0;
csmaCounter = CSMA_COUNTER_BASE;
}
}
else
{
//next sample Start Timer1
_Set_Timer1(DQD_TIMER_LIMIT);
}
}
else
{
//keep waiting
csmaCounter--;
_Set_Timer1(DQD_TIMER_LIMIT);
}
}
else
{// Transmit error CSMA failed
// Reinit CSMA variables
SEL_PIN = 1; // Reset the DQD selection
Data = 0;
Data1 = 0;
csmaCycle = 0;
csmaCounter = CSMA_COUNTER_BASE;
if( EZ_reg.bits.EDCRB.CB && (EZ_reg.bytes.EC[Frequency] < 255) )
EZ_reg.bytes.EC[Frequency]++;
//go to the TxError state
_GotoTxErrorState();
return;
}
break;
/*Send preamble bytes*/
case EZ_TxSendPreamble:
if (It_Source == IT_SOURCE_T1)
{//SW Watchdog timer overrun -> Trixie HW error
_TrixieHWError();
return;
}
//write byte (0xAA) to the Trixie
#ifdef SM_REAL_FUNCTION
_WriteByte_Trixie (0xAA);
#endif
AddrSID = TRUE;
if(DataByteCounter == 0)
EZInternalState = EZ_TxSendSyncPattern0;
else
DataByteCounter--;
break;
/*Send the first sync pattern: 2D, calc the CRC for the first header byte*/
case EZ_TxSendSyncPattern0:
if( It_Source == IT_SOURCE_T1 )
{//SW Watchdog timer overrun -> Trixie HW error
_TrixieHWError();
return;
}
//write byte (0x2D) to the Trixie
#ifdef SM_REAL_FUNCTION
_WriteByte_Trixie (0x2d);
#endif
DataByteCounter = 0;
//Calculating the Control Byte
if(EZ_state == EZMac_S_SendingAck)
Data = ((ControlField & 0xF0) | 0x08) + FORWARD_RADIUS; // Clearing the ACKRQ field and keeping the seq
// setting the ACK field, the Radius to max
else if (EZ_state == EZMac_S_Forwarding)
Data = --ControlField; // Decrementing the Radius counter
else
Data = FORWARD_RADIUS + (++SequenceNumber << 4) + (EZ_reg.bits.PFWCRB.ACKRQ << 2) ; //EzMacPlus
if(SequenceNumber > 15)
SequenceNumber = 0;
//calc CRC for this byte
Crc_On_Fly(Data);
//go to the next state
EZInternalState = EZ_TxSendSyncPattern1;
break;
/*Send the second sync pattern byte: D4, calc the CRC for the 2nd header byte*/
case EZ_TxSendSyncPattern1:
if( It_Source == IT_SOURCE_T1 )
{//SW Watchdog timer overrun -> Trixie HW error
_TrixieHWError();
return;
}
//write byte (0xD4) to the Trixie
#ifdef SM_REAL_FUNCTION
_WriteByte_Trixie (0xd4);
#endif
//save the previosly calculated data byte
Data1 = Data;
//next state
EZInternalState = EZ_TxSendControl;
//what can be the first header byte (H1)?
if( EZ_reg.bits.MCRB.CIDEN )
//CID is used, this is the first byte of the header
Data = EZ_reg.bytes.CIDB;
else
{//CID is not used
if( EZ_reg.bits.MCRB.RAR && !(EZ_reg.bits.MCRB.NWAD) )
{//reduced address mode and not network address -> 8 bit address is copied from lower nibble of the SID and DID registers
if(EZ_state == EZMac_S_SendingAck) //EzMacPlus
{// For ACK sending we need to swap the DID and the SID
Data = (EZ_reg.bytes.DIDB & 0x0F) << 4;
Data += EZ_reg.bytes.SIDB & 0x0F;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -