📄 zphy_cc2420.cpp
字号:
}
packetSize = RxBuffer[RxRead];
params.PD_DATA_indication.psdu = SRAMalloc(packetSize);
if(params.PD_DATA_indication.psdu == NULL)
{
phyError.failedToMallocRx = 1;
PHYTasksPending.bits.PHY_RX = 0;
return NO_PRIMITIVE;
}
/* save the packet head somewhere so that it can be freed later */
if(CurrentRxPacket == NULL)
{
CurrentRxPacket = params.PD_DATA_indication.psdu;
params.PD_DATA_indication.psduLength = packetSize;
RxRead++;
if(RxRead == RX_BUFFER_SIZE)
{
RxRead = 0;
}
while(packetSize--)
{
*params.PD_DATA_indication.psdu++ = PHYGet();
}
/* reset the psdu to the head of the alloc-ed RAM, just happens to me CurrentRxPacket */
params.PD_DATA_indication.psdu = CurrentRxPacket;
/* disable interrupts before checking to see if this was the
last packet in the FIFO so that if we get a packet(interrupt) after the check,
but before the clearing of the bit then the new indication will not
get cleared */
savedBits.bGIEH = GIEH;
GIEH = 0;
if(RxRead == RxWrite)
{
PHYTasksPending.bits.PHY_RX = 0;
}
GIEH = savedBits.bGIEH;
return PD_DATA_indication;
}
}
if(ZigBeeStatus.flags.bits.bRxBufferOverflow == 1)
{
ZigBeeStatus.flags.bits.bRxBufferOverflow = 0;
CCP2IF = 1;
}
}
else
{
// if tx is already busy sending a packet then we can't RX a packet because of resource control issues
return NO_PRIMITIVE;
}
}
else
{
/* handle primitive here */
switch(inputPrimitive)
{
// case PD_DATA_request:
// This is handled by CC2420 hardware
// break;
// case PLME_CCA_request:
// This is handled by CC2420 hardware
// break;
// case PLME_ED_request:
// This is handled by CC2420 hardware, just read variable out of CC2420
// break;
// case PLME_SET_request:
// User will access variables directly
// break;
// case PLME_GET_request:
// User will access variables directly
// break;
case PLME_SET_TRX_STATE_request:
/* input_state RX_ON, TRX_OFF, FORCE_TRX_OFF, or TX_ON */
/* returns PLME_SET_TRX_STATE_confirm with SUCCESS, RX_ON, TRX_OFF, TX_ON, BUSY_RX, or BUSY_TX */
if(params.PLME_SET_TRX_STATE_request.state == TRXCurrentState)
{
params.PLME_SET_TRX_STATE_confirm.status = params.PLME_SET_TRX_STATE_request.state;
break;
}
if(params.PLME_SET_TRX_STATE_request.state == phyRX_ON || params.PLME_SET_TRX_STATE_request.state == phyTRX_OFF)
{
BYTE_VAL status;
/* get status of CC2420 */
status.Val = CC2420GetStatus();
if(status.bits.b3 == 1)
{
params.PLME_SET_TRX_STATE_confirm.status = phyBUSY_TX;
break;
}
}
/* if we are in the middle of an RX then don't allow switch to TX */
if((params.PLME_SET_TRX_STATE_request.state == phyTX_ON || params.PLME_SET_TRX_STATE_request.state == phyTRX_OFF) && (TRXCurrentState == phyRX_ON) )
{
if(PHY_SFD == 1)
{
params.PLME_SET_TRX_STATE_confirm.status = phyBUSY_RX;
PHYTasksPending.bits.PLME_SET_TRX_STATE_request_task = 1;
return PLME_SET_TRX_STATE_confirm;
}
}
if(params.PLME_SET_TRX_STATE_request.state == phyFORCE_TRX_OFF || params.PLME_SET_TRX_STATE_request.state == phyTRX_OFF)
{
/* force it off here */
PHY_CSn_0();
SPIPut(STROBE_SRFOFF);
PHY_CSn_1();
TRXCurrentState = phyTRX_OFF;
/* SUCCESS */
params.PLME_SET_TRX_STATE_confirm.status = phySUCCESS;
break;
}
else if(params.PLME_SET_TRX_STATE_request.state == phyRX_ON)
{
PHY_CSn_0();
SPIPut(STROBE_SRXON);
PHY_CSn_1();
}
//don't use this one because it is automatically handled in the CC2420 when we use the STXONCCA command strobe
// else if(params.PLME_SET_TRX_STATE_request.state == phyTX_ON)
// {
// PHY_CSn_0();
// SPIPut(STROBE_STXON);
// PHY_CSn_1();
// }
/* passed all of the tests to change the state of the TRX */
TRXCurrentState = params.PLME_SET_TRX_STATE_request.state;
/* SUCCESS */
params.PLME_SET_TRX_STATE_confirm.status = phySUCCESS;
break;
}
}
return NO_PRIMITIVE;
}
BYTE CC2420GetStatus(void)
{
BYTE GIEHsave;
BYTE status;
GIEHsave = GIEH;
GIEH = 0;
PHY_CSn_0();
status = SPIGet();
PHY_CSn_1();
GIEH = GIEHsave;
return status;
}
#if defined(MCHP_C18)
#pragma interruptlow HighISR
void HighISR(void)
#elif defined(HITECH_C18)
void interrupt HighISR(void)
#else
void HighISR(void)
#endif
{
if(CCP2IF)
{
if(CCP2IE)
{
BYTE_VAL ack_status;
BYTE count;
BYTE_VAL w;
#if (RX_BUFFER_SIZE > 256)
#error "Rx buffer must be <= 256"
#else
#define BUFFER_CAST BYTE
BYTE RxBytesRemaining;
BYTE OldRxWrite;
#endif
CCP2IF = 0;
ack_status.Val = 0;
count = 0;
if(RxData.inUse == 0)
{
if(PHY_FIFO == 0)
{
// Flush the RX FIFO
iPHY_CSn_0();
SPIPut(REG_RXFIFO | CMD_READ);
SPIGet();
iPHY_CSn_1();
iPHY_CSn_0();
SPIPut(STROBE_SFLUSHRX);
SPIPut(STROBE_SFLUSHRX);
iPHY_CSn_1();
RxData.inUse = 0;
ZigBeeStatus.flags.bits.bRxBufferOverflow = 0;
return;
}
iPHY_CSn_0();
SPIPut(REG_RXFIFO | CMD_READ);
RxData.size=SPIGet();
RxData.inUse=1;
}
else
{
// We are recovering from an overflow. We already have the size.
iPHY_CSn_0();
SPIPut(REG_RXFIFO | CMD_READ);
}
/* save the old write so that we can restore it if there isn't enough room left */
OldRxWrite = RxWrite;
if(RxWrite < RxRead)
{
RxBytesRemaining = (BUFFER_CAST)(RxRead - RxWrite - 1);
}
else
{
RxBytesRemaining = (BUFFER_CAST)(RX_BUFFER_SIZE - 1 - RxWrite + RxRead);
}
w.Val = RxData.size;
/* this is less then because we need one extra byte for the length (which worst case would make it equivent to less then or equal to )*/
if(w.Val < RxBytesRemaining)
{
MAC_FRAME_CONTROL mfc;
/* there is room in the buffer */
RxData.inUse = 0;
/* add the packet */
RxBuffer[RxWrite++]=w.Val;
if(RxWrite==RX_BUFFER_SIZE)
{
RxWrite = 0;
}
while(w.Val--)
{
//Note: I am counting on the fact that RxWrite doesn't get incremented here anymore such that the ACK packet doesn't get written into the Buffer and the RxWrite doesn't get modified.
RxBuffer[RxWrite]=SPIGet();
if(count==0)
{
//if the frame control indicates that this packet is an ack
mfc.word.byte.LSB=RxBuffer[RxWrite];
//only enable this code if you don't want to use autoAck
// if(mfc.bits.ACKRequest == 1)
// {
// iPHY_CSn_1();
// iPHY_CSn_0();
// SPIPut(STROBE_SACKPEND);
// iPHY_CSn_1();
//
// iPHY_CSn_0();
// SPIPut(REG_RXFIFO | CMD_READ);
// }
if(mfc.bits.FrameType == 0x02)
{
//it was an ack then set the ack_status.bits.b0 to 1 showing it was an ack
ack_status.bits.b0 = 1;
//ConsolePut('@');
}
}
else if(count==2)
{
//if we are reading the sequence number and the packet was an ack
if(ack_status.bits.b0)
{
if ((macTasksPending.bits.packetPendingAck) &&
(RxBuffer[RxWrite] == currentPacket.sequenceNumber))
{
// If this is the ACK we've been waiting for, set the flag to
// send up the confirm and save the Frame Control.
macTasksPending.bits.bSendUpMACConfirm = 1;
pendingAckFrameControl = mfc;
}
// Throw away the ACK
while(w.Val--)
{
SPIGet();
}
RxWrite = OldRxWrite;
goto DoneReceivingPacket;
}
}
count++;
RxWrite++;
//roll buffer if required
if(RxWrite==RX_BUFFER_SIZE)
{
RxWrite = 0;
}
}
if(RxWrite==0)
{
w.Val = RxBuffer[RX_BUFFER_SIZE-1];
}
else
{
w.Val = RxBuffer[RxWrite - 1];
}
if(w.bits.b7 == 0)
{
/* crc failed. Erase packet from the array */
RxWrite = OldRxWrite;
// Flush the RX FIFO
iPHY_CSn_0();
SPIPut(REG_RXFIFO | CMD_READ);
SPIGet();
iPHY_CSn_1();
iPHY_CSn_0();
SPIPut(STROBE_SFLUSHRX);
SPIPut(STROBE_SFLUSHRX);
iPHY_CSn_1();
RxData.inUse = 0;
ZigBeeStatus.flags.bits.bRxBufferOverflow = 0;
}
else
{
PHYTasksPending.bits.PHY_RX = 1;
}
}
else
{
RxWrite = OldRxWrite;
ZigBeeStatus.flags.bits.bRxBufferOverflow = 1;
}
DoneReceivingPacket:
iPHY_CSn_1();
}
}
if(TMR0IF)
{
if(TMR0IE)
{
/* there was a timer overflow */
TMR0IF = 0;
timerExtension1++;
if(timerExtension1 == 0)
{
timerExtension2++;
}
}
}
UserInterruptHandler();
}
//******************************************************************************
// Interrupt Vectors
//******************************************************************************
#if defined(MCHP_C18)
#pragma code highVector=0x08
void HighVector (void)
{
//_asm goto HighISR _endasm
}
#pragma code /* return to default code section */
#endif
#if defined(MCHP_C18)
#pragma code lowhVector=0x18
void LowVector (void)
{
// _asm goto HighISR _endasm
}
#pragma code /* return to default code section */
#endif
#else
#error Please link the appropriate PHY file for the selected transceiver.
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -