📄 rf_remote_unit.h
字号:
#ifndef RF_CC2511_H
#define RF_CC2511_H
/** \addtogroup module_rfru RF Remote Unit protocol for CC2510 (rfru)
* \brief Simple radio framework intended to be used between CC2511 USB Dongle and CC2510 external devices.
*
* This is the Remote Unit protocol for CC2510 (rfru), it shold be implemented on the CC2510.
*
* Please see \ref page_cc2511_rf_library "RF protocol CC2510 / CC2511 (rfru/rfud)"
* for an overview of the entire RF framework.
*
* To implement the rfru module on the CC2510, do the following:
*
* Call the function \ref rfruInit() to setup the radio, and to give the RF module the minimum maximum packet size (buffer size).\n
* See example below:
* \par Example 1: Setup radio.
*
* \code
* rfruInit(100); //init RF framework, use buffers with length of 100 bytes.
* \endcode
*
* Implement the \ref rfruHookRfEvent() hook in the main application: \n
* When an RF event occurs, a call will be made to the hook from the RF framework. \n
* See example below, the \ref module_fifo_buffer "FIFO Buffer (fifo)" is used for buffer handling in the example:
* \par Example 2: Implement hook.
*
* \code
* void rfruHookRfEvent(BYTE rfEvent, BYTE eventData){
* switch (rfEvent) {
* case RFRU_EVENT_DATA_PACKET_RECEIVED :
* // A data packet is received.
* // This will only happen after sending a RF_DATA_REQUEST to CC2511 USB Dongle with rfruSendDataRequest()
* // save the packet received, it is located in the buffer given as "pRxPacketBuffer" in the rfruSendDataRequest() call.
* fifoFinishedEnqueue(RECEIVED_DATA_BUFFER);
* break;
* case RFRU_EVENT_RETRANSMSSION_RECEIVED :
* // A retransmission is received, this will happen if a RF_ACK packet sent from this device have been lost.
* // Do not care, the RF framework will automaticly send a new RF_ACK packet.
* // No handling is done here.
* break;
* case RFRU_EVENT_ACK_RECEIVED :
* // A packet successfully sent to the CC2511 USB Dongle
* fifoFinishedDequeue(OUTGOING_DATA_BUFFER); //remove packet from the send buffer
* break;
* case RFRU_EVENT_NACK_RECEIVED :
* // The CC2511 USB Dongle did receive the last packet sent, but was unable to process it.
* // No handling is done, the packet is left in the OUTGOING_DATA_BUFFER. Application will try to send again later.
* break;
* case RFRU_EVENT_DATA_REQUEST_NACKED:
* // The CC2511 USB Dongle did not have any data ready when it received a RF_DATA_REQUEST.
* // No handling is done. Application will send more RF_DATA_REQUEST's later.
* break;
* case RFRU_EVENT_BIND_SUCCESSFULL :
* // After sending a rfruSendBindRequest() the CC2511 USB Dongle have replied and assigned a address to this device.
* // The address assigned to this device and the network address is automatically stored in the
* // RF framework and inserted into all packets.
* // We need to save the device address of the CC2511 USB Dongle, so we know where to send packets and data requests.
* dongleAddress = eventData;
* break;
* case RFRU_EVENT_ACK_TIMEOUT :
* // The CC2511 USB Dongle did not receive the last packet sent.
* // No handling is done, the packet is left in the OUTGOING_DATA_BUFFER. Application will try to send again later.
* break;
* case RFRU_EVENT_DATA_PACKET_REQUEST_TIMEOUT:
* // The CC2511 USB Dongle did not receive the last RF_DATA_REQUEST sent.
* // No handling is done. Application will send more RF_DATA_REQUEST's later.
* break;
* case RFRU_EVENT_BIND_REQUEST_TIMEOUT:
* // The CC2511 USB Dongle did not receive the last RF_BIND_REQUEST sent, or it refused to accept the bind request.
* // No handling is done. Application / user will try again later.
* break;
* }
* }
* \endcode
*
*
* Before any data can be transferred between the CC2510 and the CC2511 USB Dongle, the CC2510 must have an address. \n
* The address can be set in two ways: \n
* Manually by calling \ref rfruSetMyAddress(). This can be done if both the network address and the device address is known to the
* CC2510 remote device. \n
* Automatically by performing a full bind sequence with the CC2511 USB Dongle. This is done by calling the \ref rfruSendBindRequest().
* This will result in a \ref rfruHookRfEvent() with one of the following events (See code example 2 above):
* \li \ref RFRU_EVENT_BIND_SUCCESSFULL
* \li \ref RFRU_EVENT_BIND_REQUEST_TIMEOUT
*
* To send data to the CC2511 USB Dongle, check if radio is ready by calling \ref rfruIsRadioReady() and then call rfruSendDataPacket().
* See code example 3 below. \n
* If the \ref RF_ACK_REQUEST flag is set,
* this will result in a \ref rfruHookRfEvent() with one of the following events (See code example 2 above):
* \li \ref RFRU_EVENT_ACK_RECEIVED
* \li \ref RFRU_EVENT_NACK_RECEIVED
* \li \ref RFRU_EVENT_ACK_TIMEOUT
*
* To check for and receive any data from the CC2511 USB Dongle to this device, check if radio is ready by calling \ref rfruIsRadioReady()
* and then call \ref rfruSendDataRequest() \n
* See code example 3 below. \n
* This will result in a \ref rfruHookRfEvent() with one of the following events (See code example 2 above):
* \li \ref RFRU_EVENT_DATA_PACKET_RECEIVED
* \li \ref RFRU_EVENT_NACK_RECEIVED
* \li \ref RFRU_EVENT_DATA_PACKET_REQUEST_TIMEOUT
*
* The \ref module_fifo_buffer "FIFO Buffer (fifo)" is used for buffer handling in example 3 below.
* \par Example 3: Send data packet or a data request to the CC2511 USB Dongle .
*
* \code
* //this code sequence is included into the main loop:
*
* if(rfruIsRadioReady() && dongleAddress) {
* // radio is ready, and we have a dongleAddress (a successful bind has occurred)
* if(fifoGetUsedSlots(OUTGOING_DATA_BUFFER)) {
* // we have a packet ready to send
* pTempPacketBuffer = (RF_PACKET __xdata *) fifoStartDequeue(OUTGOING_DATA_BUFFER); // get data packet
* pTempPacketBuffer->destAddress = dongleAddress; //set destination address on packet to be sent.
* pTempPacketBuffer->flag = RF_ACK_REQUEST; // Clear all flag and set the RF_ACK_REQUEST flag
* if(fifoGetUsedSlots(OUTGOING_DATA_BUFFER) > 1) {
* //we have more than one data packet ready, so we set the RF_DATA_PENDING flag
* pTempPacketBuffer->flag |= RF_DATA_PENDING;
* }
* rfruSendDataPacket(pTempPacketBuffer); // send the packet
* } else {
* //we have no data to send, send a data request to see if CC2511 USB Dongle have data for ready for us
* if(fifoGetFreeSlots(RECEIVED_DATA_BUFFER)) { // check that we have a receive buffer available.
* rfruSendDataRequest(dongleAddress, (RF_PACKET __xdata *) fifoStartEnqueue(RECEIVED_DATA_BUFFER));
* }
* }
* }
* \endcode
*
* To stop the radio e.g. before entering power mode 1 - 3, call \ref rfruStopRadio().
*
* Please see the CC2511 Application Examples for implementations of the RF framework.
*
* @{
*/
/// \name Functions
//@{
BOOL rfruInit(BYTE bufferSize);
BOOL rfruIsRadioReady(void);
BOOL rfruSendDataPacket(RF_PACKET __xdata* pTxPacket);
BOOL rfruSendDataRequest(BYTE destAdr, RF_PACKET __xdata* pRxPacketBuffer);
void rfruSendBindRequest(BYTE preferredAddress);
void rfruStopRadio(void);
void rfruSetMyAddress(BYTE networkAddress0, BYTE networkAddress1, BYTE networkAddress2, BYTE deviceAddress);
BYTE rfruGetMyDeviceAddress(void);
UINT32 rfruGetNetworkAddress(void);
RF_PACKET __xdata * rfruGetpRxAckPkt(void);
//@}
/// \name Callback function
/// This callBack function must be defined somewhere in the application.
/// It is called from the rfru module when a rf event occurs.
//@{
/**
* \brief Called from the rfud module to notify the main application each time a RF event occurs.
*
* This function is called from within an interrupt, so it should be short and efficient. \n
* The parameter \c rfEvent will say which event has occurred. The parameter \c eventData may hold additional information for some of the events. \n
* The following rfEvents may occur:
*
* \li \ref RFRU_EVENT_DATA_PACKET_RECEIVED - A new data packet is received and ready to be read from the rx buffer.
* It will always be from the device to which the last \ref RF_DATA_REQUEST was sent, using \ref rfruSendDataRequest()
* \c eventData contain no data.
*
* \li \ref RFRU_EVENT_RETRANSMSSION_RECEIVED - A retransmitted data packet is received.
* Retransmissions are automatically acked, and thrown away by the rfru module.
* It will always be from the device to which the last \ref RF_DATA_REQUEST was sent, using \ref rfruSendDataRequest()
* \c eventData contain no data.
*
* \li \ref RFRU_EVENT_ACK_RECEIVED - An ACK packet is received for a data packet.
* It will always be from the device to which the last \ref RF_DATA_PACKET was sent, using \ref rfruSendDataPacket()
* \c eventData Contain the status flags, see \ref RF_PACKET_TYPE "Packet flags" from the received ACK packet.
*
* \li \ref RFRU_EVENT_NACK_RECEIVED - An NACK packet is received for a data packet.
* It will always be from the device to which the last \ref RF_DATA_PACKET was sent, using \ref rfruSendDataPacket()
* \c eventData Contain the status flags, see \ref RF_PACKET_TYPE "Packet flags" from the received NACK packet.
*
* \li \ref RFRU_EVENT_DATA_REQUEST_NACKED - An NACK packet is received for a data request.
* It will always be from the device to which the last \ref RF_DATA_REQUEST was sent, using \ref rfruSendDataRequest()
* \c eventData Contain the status flags, see \ref RF_PACKET_TYPE "Packet flags" from the received NACK packet.
*
* \li \ref RFRU_EVENT_BIND_SUCCESSFULL - A successful bind has occurred to the dongle.
* The address assigned to this unit can be found by calling \ref rfruGetMyDeviceAddress() and \ref rfruGetNetworkAddress().
* \c eventData The device address of the dongle.
*
* \li \ref RFUD_EVENT_ACK_TIMEOUT - No ACK/NACK packet is received within the ack timeout period after sending a \ref RF_DATA_PACKET, using \ref rfruSendDataPacket().
* \c eventData contain no data.
*
* \li \ref RFRU_EVENT_DATA_PACKET_REQUEST_TIMEOUT - No data packet is received within timeout period after sending a \ref RF_DATA_REQUEST using \ref rfruSendDataRequest().
* \c eventData contain no data.
*
* \li \ref RFRU_EVENT_BIND_REQUEST_TIMEOUT - No reply received within timeout period after attempting to bind using \ref rfruSendBindRequest().
* \c eventData contain no data.
*
* \param[in] rfEvent \n
* This variable will tell what RF event that has occurred.
* \param[in] eventData \n
* This variable may hold additional information about the event.
*/
void rfruHookRfEvent(BYTE rfEvent, BYTE eventData);
//@}
/// \name Module Data
//@{
/// RFRD internal module data
typedef struct {
DMA_DESC dmaToRadioDesc; ///< Holds the DMA descriptor that is used to send data to the radio.
DMA_DESC dmaFromRadioDesc; ///< Holds the DMA descriptor that is used to read data from the radio.
BYTE timer2Cnt; ///< Holds the reset value for timer 2 / mac timer, used to time out replyes.
BYTE pNetworkAddress[3]; ///< Holds the current network address.
BYTE pTxSequenceBits[RF_SEQUENCE_BYTES]; ///< Holds sequence bit used in outgoing packets.
BYTE pRxSequenceBits[RF_SEQUENCE_BYTES]; ///< Holds sequence bit used in incomming packets.
RF_PACKET pTxAckPkt; ///< Buffer that holds an ack packet ready to be transmitted.
RF_PACKET pTxDataRequestPkt; ///< Buffer that holds an data request packet ready to be trasnmitted.
RF_PACKET __xdata * pRxAckPkt; ///< Buffer that incoming ack packet are stored in.
RF_PACKET __xdata * pRxPacket; ///< Pointer to where incoming (non ack) packets should be stored.
BYTE maxPacketLength; ///< Max packet length that can be received (buffer size).
BYTE lastPktSentTo; ///< Address to witch the last packet was sent, and ack is expected from.
BYTE radio_state; ///< The radio state machines current state
BYTE bindRequestRetries; ///< Used to keep track of number of bind requests sent
BOOL rfTimeout; ///< Is set to TRUE when a timeout occures.
} RFRU_DATA;
//@}
/// \name RF_EVENT
///Used as a parameter in the \ref rfCallBackRfEvent() to tell application what rf event has occurred
//@{
/// A new data packet is received and ready to be read from the rx buffer.
#define RFRU_EVENT_DATA_PACKET_RECEIVED 0x01
/// A packet is received, the sequence indicates that it is a retransmission
#define RFRU_EVENT_RETRANSMSSION_RECEIVED 0x02
/// A ack packet is received and ready to be read from the rx buffer.
#define RFRU_EVENT_ACK_RECEIVED 0x03
/// A nack packet is received and ready to be read form the rx buffer
#define RFRU_EVENT_NACK_RECEIVED 0x04
/// A nack packet is received and ready to be read form the rx buffer
#define RFRU_EVENT_DATA_REQUEST_NACKED 0x05
/// A successful bind has occurred to the dongle
#define RFRU_EVENT_BIND_SUCCESSFULL 0x06
/// No ack packet i received within the ack timeout period.
#define RFRU_EVENT_ACK_TIMEOUT 0x07
/// No data packet i received after sending a data packet request within timeout period.
#define RFRU_EVENT_DATA_PACKET_REQUEST_TIMEOUT 0x08
/// No \ref RF_BIND_REQUEST received within timeout period.
#define RFRU_EVENT_BIND_REQUEST_TIMEOUT 0x09
//@}
/// \name radio_state
/// Used by the rf modules internal state machine.
//@{
/// Radio is in idle.
#define RFRU_STATE_IDLE 0x00
/// The radio is sending a packet, with the \ref RF_ACK_REQUEST bit set.
#define RFRU_STATE_TX_PKT_EXPECT_ACK 0x01
/// The radio is sending a packet, with the \ref RF_ACK_REQUEST bit cleared.
#define RFRU_STATE_TX_PKT_NO_ACK 0x02
/// Sending a \ref RF_ACK of \ref RF_NACK packet.
#define RFRU_STATE_TX_ACK_NACK 0x03
/// The radio is sending a data request.
#define RFRU_STATE_TX_DATA_REQ 0x04
/// Sending a \ref RF_BIND_REQUEST (remote unit)
#define RFRU_STATE_TX_BIND_REQUEST 0x05
/// The radio is waiting for / receiving a packet.
#define RFRU_STATE_RX_DATA_PACKET 0x06
/// The radio is waiting for / receiving a \ref RF_ACK or \ref RF_NACK packet.
#define RFRU_STATE_RX_ACK 0x07
/// In rx, waiting for or receiving a \ref RF_BIND_RESPONSE (remote unit).
#define RFRU_STATE_RX_BIND_RESPONSE 0x08
//@}
#endif //RF_CC2511_H
///@}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -