📄 sppisr.c
字号:
/*****************************************************************************
* *
* ********** *
* ************ *
* *** *** *
* *** +++ *** *
* *** + + *** *
* *** + CHIPCON CC1010 *
* *** + + *** CUL - spp *
* *** +++ *** *
* *** *** *
* *********** *
* ********* *
* *
*****************************************************************************
* *
*****************************************************************************
* Author: JOL *
*****************************************************************************
* Revision history: *
* *
* $Log: sppISR.c,v $
* Revision 1.2 2003/08/12 13:53:55 tos
* Corrected inconsistent LOCK control.
*
* Revision 1.1 2002/10/14 12:27:33 tos
* Initial version in CVS.
*
* *
****************************************************************************/
#include <chipcon/sppInternal.h>
// Internal data variable (struct)
SPP_INTERNAL_DATA xdata sppIntData;
pCBF xdata sppRFStateFunc;
//----------------------------------------------------------------------------
// MACRO: FSM_RESET()
//
// Description:
// Disable the RF interrupt, turn off the transceiver, and enter IDLE
// mode.
//----------------------------------------------------------------------------
#define FSM_RESET() \
do { \
INT_ENABLE (INUM_RF, INT_OFF); \
SPP_DISABLE_TIMEOUT(); \
sppIntData.mode = SPP_IDLE_MODE; \
SPP_FAST_POWER_DOWN(); \
} while (0)
//----------------------------------------------------------------------------
// MACRO: FSM_RESTART_RX()
//
// Description:
// Restarts reception by resetting the preamble detection and
// average filter. The next state is RX_WAIT.
//----------------------------------------------------------------------------
#define FSM_RESTART_RX() \
do { \
RF_LOCK_AVERAGE_FILTER(FALSE); \
PDET &= ~0x80; \
PDET |= 0x80; \
sppRFStateFunc = RX_WAIT; \
sppIntData.pRXI->status = SPP_RX_WAITING; \
} while (0)
//----------------------------------------------------------------------------
// MACRO: fsmTryRestartTx()
//
// Description:
// If no valid TX ack is received, this macro will be called from
// either the fsm (rf interrupt) or the timeout function (t3 interrupt).
//----------------------------------------------------------------------------
#define FSM_TRY_RESTART_TX() \
do { \
if (sppIntData.usedTxAttempts == sppSettings.txAttempts) { \
FSM_RESET(); \
} else { \
sppRFStateFunc = TX_START; \
SPP_FAST_POWER_UP_TX(); \
} \
} while (0)
//----------------------------------------------------------------------------
// TX FUNCTIONS
//----------------------------------------------------------------------------
void TX_START (void) {
sppIntData.mode = SPP_TX_MODE;
sppIntData.pTXI->status = SPP_TX_TRANSMITTING;
sppIntData.counter = sppSettings.txPreambleByteCount - 1;
sppIntData.usedTxAttempts++;
RF_SEND_BYTE (RF_PREAMBLE_BYTE);
sppRFStateFunc = TX_PREAMBLE;
}
void TX_PREAMBLE (void) {
RF_SEND_BYTE (RF_PREAMBLE_BYTE);
if (!--sppIntData.counter) {
sppRFStateFunc = TX_SYNC;
}
}
void TX_SYNC (void) {
RF_SEND_BYTE (RF_SUITABLE_SYNC_BYTE);
sppRFStateFunc = TX_DAB;
}
void TX_DAB (void) {
RF_SEND_BYTE (sppIntData.pTXI->destination);
FAST_CRC8_INIT(sppIntData.crc8);
FAST_CRC8(sppIntData.pTXI->destination, sppIntData.crc8);
sppRFStateFunc = TX_SAB;
}
void TX_SAB (void) {
RF_SEND_BYTE (sppSettings.myAddress);
FAST_CRC8(sppSettings.myAddress, sppIntData.crc8);
sppRFStateFunc = TX_DATA_LEN;
}
void TX_DATA_LEN (void) {
RF_SEND_BYTE (sppIntData.pTXI->dataLen);
FAST_CRC8(sppIntData.pTXI->dataLen, sppIntData.crc8);
sppRFStateFunc = TX_FLAG;
}
void TX_FLAG (void) {
RF_SEND_BYTE (sppIntData.pTXI->flags);
FAST_CRC8(sppIntData.pTXI->flags, sppIntData.crc8);
sppRFStateFunc = TX_CRC8;
}
void TX_CRC8 (void) {
RF_SEND_BYTE (sppIntData.crc8);
if (!sppIntData.pTXI->dataLen) {
sppRFStateFunc = TX_ZEROPAD_START;
} else {
sppRFStateFunc = TX_DBX_START;
}
}
void TX_DBX_START (void) {
sppIntData.counter = 0;
sppRFStateFunc = TX_DBX;
RF_SEND_BYTE (sppIntData.pTXI->pDataBuffer[sppIntData.counter]);
FAST_CRC16_INIT(sppIntData.crc16);
FAST_CRC16(sppIntData.pTXI->pDataBuffer[sppIntData.counter], sppIntData.crc16);
if (++sppIntData.counter == sppIntData.pTXI->dataLen) {
sppRFStateFunc = TX_CRC16_DATA_H;
}
}
void TX_DBX (void) {
RF_SEND_BYTE (sppIntData.pTXI->pDataBuffer[sppIntData.counter]);
FAST_CRC16(sppIntData.pTXI->pDataBuffer[sppIntData.counter], sppIntData.crc16);
if (++sppIntData.counter == sppIntData.pTXI->dataLen) {
sppRFStateFunc = TX_CRC16_DATA_H;
}
}
void TX_CRC16_DATA_H (void) {
RF_SEND_BYTE (sppIntData.crc16 >> 8);
sppRFStateFunc = TX_CRC16_DATA_L;
}
void TX_CRC16_DATA_L (void) {
RF_SEND_BYTE (sppIntData.crc16 & 0xFF);
sppRFStateFunc = TX_ZEROPAD_START;
}
void TX_ZEROPAD_START (void) {
sppIntData.counter = SPP_ZEROPAD_COUNT - 1;
RF_SEND_BYTE (0);
sppRFStateFunc = TX_ZEROPAD;
}
void TX_ZEROPAD (void) {
RF_SEND_BYTE (0);
if (!--sppIntData.counter) {
if (sppIntData.pTXI->flags & SPP_ACK_REQ) {
sppRFStateFunc = TXACK_START;
} else {
sppIntData.pTXI->flags ^= SPP_SEQUENCE_BIT; // Toggle the packet sequence number bit
sppIntData.pTXI->status = SPP_TX_FINISHED;
FSM_RESET();
}
}
}
//----------------------------------------------------------------------------
// TXACK FUNCTIONS
//----------------------------------------------------------------------------
void TXACK_START (void) {
sppIntData.mode = SPP_TXACK_MODE;
SPP_ENABLE_TIMEOUT(sppSettings.txAckTimeout);
SPP_FAST_POWER_UP_RX();
sppIntData.pTXI->status = SPP_TX_WAITING_FOR_ACK;
sppRFStateFunc = TXACK_WAIT;
}
void TXACK_WAIT (void) {
// Drop the sync byte
RF_LOCK_AVERAGE_FILTER(TRUE);
SPP_DISABLE_TIMEOUT();
sppRFStateFunc = TXACK_DAB;
}
void TXACK_DAB (void) {
if (RF_RECEIVE_BYTE() == sppSettings.myAddress) {
FAST_CRC8_INIT(sppIntData.crc8);
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
sppRFStateFunc = TXACK_SAB;
} else {
sppIntData.pTXI->status = SPP_TX_ACK_INVALID;
FSM_TRY_RESTART_TX();
}
}
void TXACK_SAB (void) {
if (RF_RECEIVE_BYTE() == sppIntData.pTXI->destination) {
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
sppRFStateFunc = TXACK_DATA_LEN;
} else {
sppIntData.pTXI->status = SPP_TX_ACK_INVALID;
FSM_TRY_RESTART_TX();
}
}
void TXACK_DATA_LEN (void) {
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
sppRFStateFunc = TXACK_FLAG;
}
void TXACK_FLAG (void) {
if (RF_RECEIVE_BYTE() & SPP_ACK) {
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
sppRFStateFunc = TXACK_CRC8;
} else {
sppIntData.pTXI->status = SPP_TX_ACK_INVALID;
FSM_TRY_RESTART_TX();
}
}
void TXACK_CRC8 (void) {
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
if (sppIntData.crc8 == CRC_OK) {
sppIntData.pTXI->flags ^= SPP_SEQUENCE_BIT; // Toggle the packet sequence number bit
sppIntData.pTXI->status = SPP_TX_FINISHED;
FSM_RESET();
} else {
sppIntData.pTXI->status = SPP_TX_ACK_INVALID;
FSM_TRY_RESTART_TX();
}
}
//----------------------------------------------------------------------------
// RX FUNCTIONS
//----------------------------------------------------------------------------
void RX_WAIT (void) {
// Drop the sync byte
RF_LOCK_AVERAGE_FILTER(TRUE);
sppIntData.mode = SPP_RX_MODE;
sppRFStateFunc = RX_DAB;
}
void RX_DAB (void) {
sppIntData.pRXI->status = SPP_RX_RECEIVING;
FAST_CRC8_INIT(sppIntData.crc8);
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
if ((RF_RECEIVE_BYTE() == sppSettings.myAddress) || (RF_RECEIVE_BYTE() == SPP_BROADCAST)) {
sppRFStateFunc = RX_SAB;
} else {
FSM_RESTART_RX();
}
}
void RX_SAB (void) {
sppIntData.pRXI->source = RF_RECEIVE_BYTE();
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
sppRFStateFunc = RX_DATA_LEN;
}
void RX_DATA_LEN (void) {
sppIntData.pRXI->dataLen = RF_RECEIVE_BYTE();
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
sppRFStateFunc = RX_FLAG;
}
void RX_FLAG (void) {
sppIntData.pRXI->flags = RF_RECEIVE_BYTE();
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
sppRFStateFunc = RX_CRC8_HEADER;
}
void RX_CRC8_HEADER (void) {
FAST_CRC8(RF_RECEIVE_BYTE(), sppIntData.crc8);
sppIntData.counter = 0;
if (sppIntData.crc8 == CRC_OK) {
if (sppIntData.pRXI->dataLen == 0) {
SPP_DISABLE_TIMEOUT();
if (sppIntData.pRXI->flags & SPP_ACK_REQ) {
SPP_FAST_POWER_UP_TX();
sppRFStateFunc = RXACK_START;
} else {
sppIntData.pRXI->status = SPP_RX_FINISHED;
FSM_RESET();
}
} else if (sppIntData.pRXI->dataLen > sppIntData.pRXI->maxDataLen) {
sppIntData.pRXI->status = SPP_RX_TOO_LONG;
FSM_RESET();
} else {
sppRFStateFunc = RX_DBX_START;
}
} else {
FSM_RESTART_RX();
}
}
void RX_DBX_START (void) {
sppIntData.pRXI->pDataBuffer[sppIntData.counter] = RF_RECEIVE_BYTE();
FAST_CRC16_INIT(sppIntData.crc16);
FAST_CRC16(RF_RECEIVE_BYTE(), sppIntData.crc16);
sppIntData.counter = 1;
if (sppIntData.counter == sppIntData.pRXI->dataLen) {
sppRFStateFunc = RX_CRC16_DATA_H;
} else {
sppRFStateFunc = RX_DBX;
}
}
void RX_DBX (void) {
sppIntData.pRXI->pDataBuffer[sppIntData.counter] = RF_RECEIVE_BYTE();
FAST_CRC16(RF_RECEIVE_BYTE(), sppIntData.crc16);
sppIntData.counter++;
if (sppIntData.counter == sppIntData.pRXI->dataLen) {
sppRFStateFunc = RX_CRC16_DATA_H;
}
}
void RX_CRC16_DATA_H (void) {
FAST_CRC16(RF_RECEIVE_BYTE(), sppIntData.crc16);
sppRFStateFunc = RX_CRC16_DATA_L;
}
void RX_CRC16_DATA_L (void) {
FAST_CRC16(RF_RECEIVE_BYTE(), sppIntData.crc16);
if (sppIntData.crc16 == CRC_OK) {
SPP_DISABLE_TIMEOUT();
if (sppIntData.pRXI->flags & SPP_ACK_REQ) {
SPP_FAST_POWER_UP_TX();
sppRFStateFunc = RXACK_START;
} else {
FSM_RESET();
sppIntData.pRXI->status = SPP_RX_FINISHED;
}
} else {
FSM_RESTART_RX();
}
}
//----------------------------------------------------------------------------
// RXACK FUNCTIONS
//----------------------------------------------------------------------------
void RXACK_START (void) {
sppIntData.mode = SPP_RXACK_MODE;
sppIntData.pRXI->status = SPP_RX_ACKING;
sppIntData.counter = sppSettings.txPreambleByteCount - 1;
RF_SEND_BYTE (RF_PREAMBLE_BYTE);
sppRFStateFunc = RXACK_PREAMBLE;
}
void RXACK_PREAMBLE (void) {
RF_SEND_BYTE (RF_PREAMBLE_BYTE);
if (!--sppIntData.counter) {
sppRFStateFunc = RXACK_SYNC;
}
}
void RXACK_SYNC (void) {
RF_SEND_BYTE (RF_SUITABLE_SYNC_BYTE);
sppRFStateFunc = RXACK_DAB;
}
void RXACK_DAB (void) {
RF_SEND_BYTE (sppIntData.pRXI->source);
FAST_CRC8_INIT(sppIntData.crc8);
FAST_CRC8(sppIntData.pRXI->source, sppIntData.crc8);
sppRFStateFunc = RXACK_SAB;
}
void RXACK_SAB (void) {
RF_SEND_BYTE (sppSettings.myAddress);
FAST_CRC8(sppSettings.myAddress, sppIntData.crc8);
sppRFStateFunc = RXACK_DATA_LEN;
}
void RXACK_DATA_LEN (void) {
RF_SEND_BYTE (0);
FAST_CRC8(0, sppIntData.crc8);
sppRFStateFunc = RXACK_FLAG;
}
void RXACK_FLAG (void) {
RF_SEND_BYTE (SPP_ACK);
FAST_CRC8(SPP_ACK, sppIntData.crc8);
sppRFStateFunc = RXACK_CRC8;
}
void RXACK_CRC8 (void) {
RF_SEND_BYTE (sppIntData.crc8);
sppIntData.counter = SPP_ZEROPAD_COUNT;
sppRFStateFunc = RXACK_ZEROPAD;
}
void RXACK_ZEROPAD (void) {
RF_SEND_BYTE (0);
if (!--sppIntData.counter) {
sppIntData.pRXI->status = SPP_RX_FINISHED;
FSM_RESET();
}
}
//----------------------------------------------------------------------------
// void RF_ISR (void) interrupt INUM_RF
//
// Description:
// RF interrupt service routine
// Runs the SPP finite state machine
//
// The packet sequence bit:
// TX: Toggle when finished (sppIntData.pTXI->status = SPP_TX_FINISHED).
// RX: The user application must examine the sequence bit.
//----------------------------------------------------------------------------
void RF_ISR (void) interrupt INUM_RF {
INT_GLOBAL_ENABLE (INT_OFF);
INT_SETFLAG (INUM_RF, INT_CLR);
if (sppIntData.mode != SPP_IDLE_MODE) {
sppRFStateFunc();
}
INT_GLOBAL_ENABLE (INT_ON);
return;
} // RF_ISR
//----------------------------------------------------------------------------
// void sppTimeout(void)
//
// Description:
// Timeout
// Callback from sxpTimer: TIMER3_ISR()
//----------------------------------------------------------------------------
void sppTimeout(void) {
INT_GLOBAL_ENABLE (INT_OFF);
if (sppIntData.mode & SPP_TXACK_MODE) {
FSM_TRY_RESTART_TX();
sppIntData.pTXI->status = SPP_TX_ACK_TIMEOUT;
} else if (sppIntData.mode & SPP_RX_MODE) {
if (sppIntData.pRXI->status == SPP_RX_WAITING) {
FSM_RESET();
sppIntData.pRXI->status = SPP_RX_TIMEOUT;
} else {
SPP_ENABLE_TIMEOUT(2); // Try again later (don't mess up the reception)
}
}
INT_GLOBAL_ENABLE (INT_ON);
} // sppTimeout
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -