46
46
#define RF_QUEUE_SIZE 8
47
47
#endif
48
48
49
+ /* 802.15.4 maximum size of a single packet including PHY byte is 128 bytes */
50
+ #define MAC_PACKET_MAX_LENGTH 128
51
+ /* Offsets of prepended data in packet buffer */
52
+ #define MAC_PACKET_OFFSET_RSSI 0
53
+ #define MAC_PACKET_OFFSET_LQI 1
54
+ /* This driver prepends RSSI and LQI */
55
+ #define MAC_PACKET_INFO_LENGTH 2
49
56
50
57
/* RFThreadSignal used to signal from interrupts to the adaptor thread */
51
58
enum RFThreadSignal {
@@ -68,12 +75,12 @@ enum RFThreadSignal {
68
75
/* Adaptor thread definitions */
69
76
static void rf_thread_loop (const void *arg);
70
77
static osThreadDef (rf_thread_loop, osPriorityRealtime, RF_THREAD_STACK_SIZE);
71
- static osThreadId rf_thread_id;
78
+ static osThreadId rf_thread_id = 0 ;
72
79
73
80
/* Queue for passing messages from interrupt to adaptor thread */
74
- static volatile void * rx_queue[8 ];
75
- static volatile size_t rx_queue_head;
76
- static volatile size_t rx_queue_tail;
81
+ static volatile uint8_t rx_queue[RF_QUEUE_SIZE][MAC_PACKET_MAX_LENGTH + MAC_PACKET_INFO_LENGTH ];
82
+ static volatile size_t rx_queue_head = 0 ;
83
+ static volatile size_t rx_queue_tail = 0 ;
77
84
78
85
/* Silicon Labs headers */
79
86
extern " C" {
@@ -123,7 +130,7 @@ static const RAIL_CsmaConfig_t csma_config = RAIL_CSMA_CONFIG_802_15_4_2003_2p4_
123
130
#error "Not a valid target."
124
131
#endif
125
132
126
- #ifdef MBED_CONF_SL_RAIL_HAS_SUBGIG
133
+ #if MBED_CONF_SL_RAIL_HAS_SUBGIG
127
134
static RAIL_ChannelConfigEntryAttr_t entry_868;
128
135
static RAIL_ChannelConfigEntryAttr_t entry_915;
129
136
static const RAIL_ChannelConfigEntry_t entry[] = {
@@ -151,7 +158,7 @@ static const RAIL_ChannelConfigEntry_t entry[] = {
151
158
#endif
152
159
153
160
#if MBED_CONF_SL_RAIL_BAND == 868
154
- #ifndef MBED_CONF_SL_RAIL_HAS_SUBGIG
161
+ #if ! MBED_CONF_SL_RAIL_HAS_SUBGIG
155
162
#error "Sub-Gigahertz band is not supported on this target."
156
163
#endif
157
164
static const RAIL_ChannelConfig_t channels = {
@@ -161,7 +168,7 @@ static const RAIL_ChannelConfig_t channels = {
161
168
1
162
169
};
163
170
#elif MBED_CONF_SL_RAIL_BAND == 915
164
- #ifndef MBED_CONF_SL_RAIL_HAS_SUBGIG
171
+ #if ! MBED_CONF_SL_RAIL_HAS_SUBGIG
165
172
#error "Sub-Gigahertz band is not supported on this target."
166
173
#endif
167
174
static const RAIL_ChannelConfig_t channels = {
@@ -187,7 +194,7 @@ static const RAIL_TxPowerConfig_t paInit2p4 = {
187
194
};
188
195
#endif
189
196
190
- #if defined ( MBED_CONF_SL_RAIL_HAS_SUBGIG)
197
+ #if MBED_CONF_SL_RAIL_HAS_SUBGIG
191
198
// Set up the PA for sub-GHz operation
192
199
static const RAIL_TxPowerConfig_t paInitSubGhz = {
193
200
.mode = RAIL_TX_POWER_MODE_SUBGIG,
@@ -210,9 +217,9 @@ static const RAIL_StateTiming_t timings = {
210
217
static const RAIL_IEEE802154_Config_t config = {
211
218
.addresses = NULL ,
212
219
.ackConfig = {
213
- .enable = true ,
214
- .ackTimeout = 1200 ,
215
- .rxTransitions = {
220
+ .enable = true ,
221
+ .ackTimeout = 1200 ,
222
+ .rxTransitions = {
216
223
.success = RAIL_RF_STATE_RX,
217
224
.error = RAIL_RF_STATE_RX // ignored
218
225
},
@@ -270,16 +277,13 @@ static void rf_thread_loop(const void *arg)
270
277
if (event.value .signals & SL_RX_DONE) {
271
278
while (rx_queue_tail != rx_queue_head) {
272
279
uint8_t * packet = (uint8_t *) rx_queue[rx_queue_tail];
273
- SL_DEBUG_PRINT (" rPKT %d\n " , packet[2 ] - 2 );
280
+ SL_DEBUG_PRINT (" rPKT %d\n " , packet[MAC_PACKET_INFO_LENGTH ] - 2 );
274
281
device_driver.phy_rx_cb (
275
- &packet[3 ], /* Data payload for Nanostack starts at FCS */
276
- packet[2 ] - 2 , /* Payload length is part of frame, but need to subtract CRC bytes */
277
- packet[1 ], /* LQI in second byte */
278
- packet[0 ], /* RSSI in first byte */
282
+ &packet[MAC_PACKET_INFO_LENGTH + 1 ], /* Data payload for Nanostack starts at FCS */
283
+ packet[MAC_PACKET_INFO_LENGTH ] - 2 , /* Payload length is part of frame, but need to subtract CRC bytes */
284
+ packet[MAC_PACKET_OFFSET_LQI ], /* LQI in second byte */
285
+ packet[MAC_PACKET_OFFSET_RSSI ], /* RSSI in first byte */
279
286
rf_radio_driver_id);
280
-
281
- free (packet);
282
- rx_queue[rx_queue_tail] = NULL ;
283
287
rx_queue_tail = (rx_queue_tail + 1 ) % RF_QUEUE_SIZE;
284
288
}
285
289
@@ -887,6 +891,12 @@ static void radioEventHandler(RAIL_Handle_t railHandle,
887
891
if (railHandle != gRailHandle )
888
892
return ;
889
893
894
+ #ifdef MBED_CONF_RTOS_PRESENT
895
+ if (rf_thread_id == 0 ) {
896
+ return ;
897
+ }
898
+ #endif
899
+
890
900
size_t index = 0 ;
891
901
do {
892
902
if (events & 1ull ) {
@@ -956,43 +966,20 @@ static void radioEventHandler(RAIL_Handle_t railHandle,
956
966
957
967
/* Only process the packet if it had a correct CRC */
958
968
if (rxPacketInfo.packetStatus == RAIL_RX_PACKET_READY_SUCCESS) {
959
- /* Get RSSI and LQI information about this packet */
960
- RAIL_RxPacketDetails_t rxPacketDetails;
961
- rxPacketDetails.timeReceived .timePosition = RAIL_PACKET_TIME_DEFAULT;
962
- rxPacketDetails.timeReceived .totalPacketBytes = 0 ;
963
- RAIL_GetRxPacketDetails (gRailHandle , rxHandle, &rxPacketDetails);
964
-
965
- /* Allocate a contiguous buffer for this packet's payload */
966
- uint8_t * packetBuffer = (uint8_t *) malloc (rxPacketInfo.packetBytes + 2 );
967
- if (packetBuffer == NULL ) {
968
- SL_DEBUG_PRINT (" Out of memory\n " );
969
- break ;
970
- }
971
-
972
- /* First two bytes are RSSI and LQI, respecitvely */
973
- packetBuffer[0 ] = (uint8_t )rxPacketDetails.rssi ;
974
- packetBuffer[1 ] = (uint8_t )rxPacketDetails.lqi ;
975
-
976
- /* Copy packet payload from circular FIFO into contiguous memory */
977
- memcpy (&packetBuffer[2 ], rxPacketInfo.firstPortionData , rxPacketInfo.firstPortionBytes );
978
- if (rxPacketInfo.firstPortionBytes < rxPacketInfo.packetBytes ) {
979
- memcpy (&packetBuffer[2 +rxPacketInfo.firstPortionBytes ],
980
- rxPacketInfo.lastPortionData ,
981
- rxPacketInfo.packetBytes - rxPacketInfo.firstPortionBytes );
982
- }
983
-
984
- /* Release RAIL resources early */
985
- RAIL_ReleaseRxPacket (gRailHandle , rxHandle);
969
+ uint8_t header[4 ];
970
+ RAIL_PeekRxPacket (gRailHandle , rxHandle, header, 4 , 0 );
986
971
987
- /* If this is an ACK, deal with it */
988
- if ( packetBuffer[ 2 ] == 5 &&
989
- packetBuffer[ 2 + 3 ] == ( current_tx_sequence) &&
972
+ /* If this is an ACK, deal with it early */
973
+ if ( (header[ 0 ] == 5 ) &&
974
+ (header[ 3 ] == current_tx_sequence) &&
990
975
waiting_for_ack) {
991
976
/* Tell the radio to not ACK an ACK */
992
977
RAIL_CancelAutoAck (gRailHandle );
993
978
waiting_for_ack = false ;
994
979
/* Save the pending bit */
995
- last_ack_pending_bit = (packetBuffer[2 +1 ] & (1 << 4 )) != 0 ;
980
+ last_ack_pending_bit = (header[1 ] & (1 << 4 )) != 0 ;
981
+ /* Release packet */
982
+ RAIL_ReleaseRxPacket (gRailHandle , rxHandle);
996
983
/* Tell the stack we got an ACK */
997
984
#ifdef MBED_CONF_RTOS_PRESENT
998
985
osSignalSet (rf_thread_id, SL_ACK_RECV | (last_ack_pending_bit ? SL_ACK_PEND : 0 ));
@@ -1004,8 +991,37 @@ static void radioEventHandler(RAIL_Handle_t railHandle,
1004
991
1 ,
1005
992
1 );
1006
993
#endif
1007
- free (packetBuffer);
1008
994
} else {
995
+ /* Get RSSI and LQI information about this packet */
996
+ RAIL_RxPacketDetails_t rxPacketDetails;
997
+ rxPacketDetails.timeReceived .timePosition = RAIL_PACKET_TIME_DEFAULT;
998
+ rxPacketDetails.timeReceived .totalPacketBytes = 0 ;
999
+ RAIL_GetRxPacketDetails (gRailHandle , rxHandle, &rxPacketDetails);
1000
+
1001
+ #ifdef MBED_CONF_RTOS_PRESENT
1002
+ /* Drop this packet if we're out of space */
1003
+ if (((rx_queue_head + 1 ) % RF_QUEUE_SIZE) == rx_queue_tail) {
1004
+ osSignalSet (rf_thread_id, SL_QUEUE_FULL);
1005
+ RAIL_ReleaseRxPacket (gRailHandle , rxHandle);
1006
+ break ;
1007
+ }
1008
+
1009
+ /* Copy into queue */
1010
+ uint8_t * packetBuffer = (uint8_t *)rx_queue[rx_queue_head];
1011
+ #else
1012
+ /* Packet going temporarily onto stack for bare-metal apps */
1013
+ uint8_t packetBuffer[MAC_PACKET_MAX_LENGTH + MAC_PACKET_INFO_LENGTH];
1014
+ #endif
1015
+ /* First two bytes are RSSI and LQI, respecitvely */
1016
+ packetBuffer[MAC_PACKET_OFFSET_RSSI] = (uint8_t )rxPacketDetails.rssi ;
1017
+ packetBuffer[MAC_PACKET_OFFSET_LQI] = (uint8_t )rxPacketDetails.lqi ;
1018
+
1019
+ /* Copy packet payload from circular FIFO into contiguous memory */
1020
+ RAIL_CopyRxPacket (&packetBuffer[MAC_PACKET_INFO_LENGTH], &rxPacketInfo);
1021
+
1022
+ /* Release RAIL resources early */
1023
+ RAIL_ReleaseRxPacket (gRailHandle , rxHandle);
1024
+
1009
1025
/* Figure out whether we want to not ACK this packet */
1010
1026
1011
1027
/*
@@ -1015,27 +1031,20 @@ static void radioEventHandler(RAIL_Handle_t railHandle,
1015
1031
* [1] => b[0:2] frame type, b[3] = security enabled, b[4] = frame pending, b[5] = ACKreq, b[6] = intrapan
1016
1032
* [2] => b[2:3] destmode, b[4:5] version, b[6:7] srcmode
1017
1033
*/
1018
- if ( (packetBuffer[2 + 1 ] & (1 << 5 )) == 0 ) {
1034
+ if ( (packetBuffer[MAC_PACKET_INFO_LENGTH + 1 ] & (1 << 5 )) == 0 ) {
1019
1035
/* Cancel the ACK if the sender did not request one */
1020
1036
RAIL_CancelAutoAck (gRailHandle );
1021
1037
}
1022
1038
#ifdef MBED_CONF_RTOS_PRESENT
1023
- if (((rx_queue_head + 1 ) % RF_QUEUE_SIZE) != rx_queue_tail) {
1024
- rx_queue[rx_queue_head] = (void *)packetBuffer;
1025
- rx_queue_head = (rx_queue_head + 1 ) % RF_QUEUE_SIZE;
1026
- osSignalSet (rf_thread_id, SL_RX_DONE);
1027
- } else {
1028
- free (packetBuffer);
1029
- osSignalSet (rf_thread_id, SL_QUEUE_FULL);
1030
- }
1039
+ rx_queue_head = (rx_queue_head + 1 ) % RF_QUEUE_SIZE;
1040
+ osSignalSet (rf_thread_id, SL_RX_DONE);
1031
1041
#else
1032
- SL_DEBUG_PRINT (" rPKT %d\n " , rxPacket[ 2 ] - 2 );
1033
- device_driver.phy_rx_cb (&rxPacket[ 3 ], /* Data payload for Nanostack starts at FCS */
1034
- rxPacket[ 2 ] - 2 , /* Payload length is part of frame, but need to subtract CRC bytes */
1035
- rxPacket[ 1 ], /* LQI in second byte */
1036
- rxPacket[ 0 ], /* RSSI in first byte */
1042
+ SL_DEBUG_PRINT (" rPKT %d\n " , packetBuffer[MAC_PACKET_INFO_LENGTH ] - 2 );
1043
+ device_driver.phy_rx_cb (&packetBuffer[MAC_PACKET_INFO_LENGTH + 1 ], /* Data payload for Nanostack starts at FCS */
1044
+ packetBuffer[MAC_PACKET_INFO_LENGTH ] - 2 , /* Payload length is part of frame, but need to subtract CRC bytes */
1045
+ packetBuffer[MAC_PACKET_OFFSET_LQI ], /* LQI in second byte */
1046
+ packetBuffer[MAC_PACKET_OFFSET_RSSI ], /* RSSI in first byte */
1037
1047
rf_radio_driver_id);
1038
- free (packetBuffer);
1039
1048
#endif
1040
1049
}
1041
1050
}
@@ -1265,4 +1274,4 @@ static void radioEventHandler(RAIL_Handle_t railHandle,
1265
1274
index += 1 ;
1266
1275
}
1267
1276
while (events != 0 );
1268
- }
1277
+ }
0 commit comments