25 #define RADIO_MAX_PACKET_SIZE (RADIO_LINK_PAYLOAD_SIZE + RADIO_LINK_PACKET_HEADER_LENGTH)
28 #define RADIO_LINK_PACKET_HEADER_LENGTH 1
30 #define RADIO_LINK_PACKET_LENGTH_OFFSET 0
31 #define RADIO_LINK_PACKET_TYPE_OFFSET 1
33 #define RADIO_LINK_PAYLOAD_TYPE_BIT_OFFSET 1
34 #define RADIO_LINK_PAYLOAD_TYPE_MASK 0b00011110
36 #define PACKET_TYPE_MASK (3 << 6) // These are the bits that determine the packet type.
37 #define PACKET_TYPE_PING (0 << 6) // If both bits are zero, it is just a Ping packet (with optional data).
38 #define PACKET_TYPE_NAK (1 << 6) // A NAK packet (with optional data)
39 #define PACKET_TYPE_ACK (2 << 6) // An ACK packet (with optional data)
40 #define PACKET_TYPE_RESET (3 << 6) // A Reset packet (the next packet transmitted by the sender of this packet will have a sequence number of 0)
60 #define RX_PACKET_COUNT 3
61 static volatile uint8 XDATA radioLinkRxPacket[RX_PACKET_COUNT][1 + RADIO_MAX_PACKET_SIZE + 2];
62 volatile uint8 DATA radioLinkRxMainLoopIndex = 0;
63 volatile uint8 DATA radioLinkRxInterruptIndex = 0;
66 #define TX_PACKET_COUNT 16
67 static volatile uint8 XDATA radioLinkTxPacket[TX_PACKET_COUNT][1 + RADIO_MAX_PACKET_SIZE];
68 volatile uint8 DATA radioLinkTxMainLoopIndex = 0;
69 volatile uint8 DATA radioLinkTxInterruptIndex = 0;
76 uint8 DATA radioLinkTxCurrentPacketTries = 0;
78 static volatile BIT sendingReset = 0;
79 static volatile BIT acceptAnySequenceBit = 0;
92 static volatile BIT rxSequenceBit;
96 static volatile BIT txSequenceBit;
113 PKTLEN = RADIO_MAX_PACKET_SIZE;
116 acceptAnySequenceBit = 1;
132 static uint8 randomTxDelay()
135 return (radioLinkTxCurrentPacketTries > 200 ? 250 : 1) + (
randomNumber() & 3);
140 return !sendingReset;
148 return (radioLinkTxInterruptIndex - radioLinkTxMainLoopIndex - 1) & (TX_PACKET_COUNT - 1);
153 return (radioLinkTxMainLoopIndex - radioLinkTxInterruptIndex) & (TX_PACKET_COUNT - 1);
163 return radioLinkTxPacket[radioLinkTxMainLoopIndex] + RADIO_LINK_PACKET_HEADER_LENGTH;
169 radioLinkTxPacket[radioLinkTxMainLoopIndex][0] = radioLinkTxPacket[radioLinkTxMainLoopIndex][RADIO_LINK_PACKET_HEADER_LENGTH] + RADIO_LINK_PACKET_HEADER_LENGTH;
172 radioLinkTxPacket[radioLinkTxMainLoopIndex][RADIO_LINK_PACKET_TYPE_OFFSET] = payloadType << RADIO_LINK_PAYLOAD_TYPE_BIT_OFFSET;
175 if (radioLinkTxMainLoopIndex == TX_PACKET_COUNT - 1)
177 radioLinkTxMainLoopIndex = 0;
181 radioLinkTxMainLoopIndex++;
193 if (radioLinkRxMainLoopIndex == radioLinkRxInterruptIndex)
198 return radioLinkRxPacket[radioLinkRxMainLoopIndex] + RADIO_LINK_PACKET_HEADER_LENGTH;
203 return radioLinkRxPacket[radioLinkRxMainLoopIndex][0];
208 if (radioLinkRxMainLoopIndex == RX_PACKET_COUNT - 1)
210 radioLinkRxMainLoopIndex = 0;
214 radioLinkRxMainLoopIndex++;
220 static void txResetPacket()
222 shortTxPacket[RADIO_LINK_PACKET_LENGTH_OFFSET] = 1;
223 shortTxPacket[RADIO_LINK_PACKET_TYPE_OFFSET] = PACKET_TYPE_RESET;
225 if (radioLinkTxCurrentPacketTries < 255)
227 radioLinkTxCurrentPacketTries++;
231 static void txDataPacket(
uint8 packetType)
233 radioLinkTxPacket[radioLinkTxInterruptIndex][RADIO_LINK_PACKET_TYPE_OFFSET] =
234 (radioLinkTxPacket[radioLinkTxInterruptIndex][RADIO_LINK_PACKET_TYPE_OFFSET] & RADIO_LINK_PAYLOAD_TYPE_MASK) | packetType | txSequenceBit;
235 radioMacTx(radioLinkTxPacket[radioLinkTxInterruptIndex]);
236 if (radioLinkTxCurrentPacketTries < 255)
238 radioLinkTxCurrentPacketTries++;
242 static void takeInitiative()
250 else if (radioLinkTxInterruptIndex != radioLinkTxMainLoopIndex)
253 txDataPacket(PACKET_TYPE_PING);
258 radioMacRx(radioLinkRxPacket[radioLinkRxInterruptIndex], 0);
272 radioMacRx(radioLinkRxPacket[radioLinkRxInterruptIndex], randomTxDelay());
277 uint8 XDATA * currentRxPacket = radioLinkRxPacket[radioLinkRxInterruptIndex];
281 if (radioLinkTxInterruptIndex != radioLinkTxMainLoopIndex)
292 if ((currentRxPacket[RADIO_LINK_PACKET_TYPE_OFFSET] & PACKET_TYPE_MASK) == PACKET_TYPE_RESET)
302 shortTxPacket[RADIO_LINK_PACKET_LENGTH_OFFSET] = 1;
303 shortTxPacket[RADIO_LINK_PACKET_TYPE_OFFSET] = PACKET_TYPE_ACK;
311 if ((currentRxPacket[RADIO_LINK_PACKET_TYPE_OFFSET] & PACKET_TYPE_MASK) == PACKET_TYPE_ACK)
321 radioLinkTxCurrentPacketTries = 0;
326 else if (radioLinkTxInterruptIndex != radioLinkTxMainLoopIndex)
333 if (radioLinkTxInterruptIndex == TX_PACKET_COUNT - 1)
335 radioLinkTxInterruptIndex = 0;
339 radioLinkTxInterruptIndex++;
343 radioLinkTxCurrentPacketTries = 0;
350 if (currentRxPacket[RADIO_LINK_PACKET_LENGTH_OFFSET] > RADIO_LINK_PACKET_HEADER_LENGTH)
354 uint8 responsePacketType = PACKET_TYPE_ACK;
356 if (acceptAnySequenceBit || (rxSequenceBit != (currentRxPacket[RADIO_LINK_PACKET_TYPE_OFFSET] & 1)))
360 uint8 nextradioLinkRxInterruptIndex;
363 if (radioLinkRxInterruptIndex == RX_PACKET_COUNT - 1)
365 nextradioLinkRxInterruptIndex = 0;
369 nextradioLinkRxInterruptIndex = radioLinkRxInterruptIndex + 1;
372 if (nextradioLinkRxInterruptIndex != radioLinkRxMainLoopIndex)
379 rxSequenceBit = (currentRxPacket[RADIO_LINK_PACKET_TYPE_OFFSET] & 1);
380 acceptAnySequenceBit = 0;
383 payloadType = (currentRxPacket[RADIO_LINK_PACKET_TYPE_OFFSET] & RADIO_LINK_PAYLOAD_TYPE_MASK) >> RADIO_LINK_PAYLOAD_TYPE_BIT_OFFSET;
387 currentRxPacket[RADIO_LINK_PACKET_HEADER_LENGTH] = currentRxPacket[RADIO_LINK_PACKET_LENGTH_OFFSET] - RADIO_LINK_PACKET_HEADER_LENGTH;
391 currentRxPacket[0] = payloadType;
393 radioLinkRxInterruptIndex = nextradioLinkRxInterruptIndex;
399 responsePacketType = PACKET_TYPE_NAK;
406 if (radioLinkTxInterruptIndex != radioLinkTxMainLoopIndex)
409 txDataPacket(responsePacketType);
415 shortTxPacket[RADIO_LINK_PACKET_LENGTH_OFFSET] = 1;
416 shortTxPacket[RADIO_LINK_PACKET_TYPE_OFFSET] = responsePacketType;
uint8 XDATA * radioLinkTxCurrentPacket(void)
void radioMacStrobe(void)
uint8 radioLinkRxCurrentPayloadType(void)
BIT radioLinkConnected(void)
void radioLinkRxDoneWithPacket(void)
void radioMacTx(uint8 XDATA *packet)
#define RADIO_MAC_EVENT_RX
#define RADIO_MAC_EVENT_STROBE
uint8 radioLinkTxQueued(void)
#define RADIO_MAC_EVENT_RX_TIMEOUT
uint8 radioLinkTxAvailable(void)
void radioMacEventHandler(uint8 event)
volatile BIT radioLinkResetPacketReceived
void radioMacRx(uint8 XDATA *packet, uint8 timeout)
void randomSeedFromSerialNumber(void)
volatile BIT radioLinkActivityOccurred
uint8 XDATA * radioLinkRxCurrentPacket(void)
#define RADIO_MAC_EVENT_TX
int32 CODE param_radio_channel
void radioLinkTxSendPacket(uint8 payloadType)