@@ -188,8 +188,10 @@ mod app {
188
188
} ) ;
189
189
}
190
190
191
- #[ task( binds = ETH , shared = [ dma, tx_id, ptp, scheduled_time] , priority = 2 ) ]
191
+ #[ task( binds = ETH , shared = [ dma, tx_id, ptp, scheduled_time] , local = [ rx_packet_id : u32 = 0 ] , priority = 2 ) ]
192
192
fn eth_interrupt ( cx : eth_interrupt:: Context ) {
193
+ let packet_id = cx. local . rx_packet_id ;
194
+
193
195
(
194
196
cx. shared . dma ,
195
197
cx. shared . tx_id ,
@@ -212,26 +214,50 @@ mod app {
212
214
}
213
215
}
214
216
215
- let mut packet_id = 0 ;
217
+ let mut buffer = [ 0u8 ; 22 ] ;
218
+
219
+ while let Ok ( ( data, rx_timestamp, used_packet_id) ) = {
220
+ let used_packet_id = * packet_id;
221
+ let result = if let Ok ( packet) = dma. recv_next ( Some ( used_packet_id. into ( ) ) ) {
222
+ let data_len = packet. len ( ) . min ( 22 ) ;
223
+ buffer[ ..data_len] . copy_from_slice ( & packet[ ..data_len] ) ;
224
+ let data = & buffer[ ..data_len] ;
216
225
217
- while let Ok ( packet) = dma. recv_next ( Some ( packet_id. into ( ) ) ) {
218
- let mut dst_mac = [ 0u8 ; 6 ] ;
219
- dst_mac. copy_from_slice ( & packet[ ..6 ] ) ;
226
+ // For RX packets, we can grab the timestamp directly or
227
+ // indirectly using [`EthernetDMA::get_timestamp_for_id`].
228
+ //
229
+ // Using `timestamp` directly is easier, because you don't
230
+ // have to re-borrow the DMA for it.
231
+ let timestamp = packet. timestamp ( ) ;
220
232
221
- // Note that, instead of grabbing the timestamp from the `RxPacket` directly, it
222
- // is also possible to retrieve a cached version of the timestamp using
223
- // `EthernetDMA::get_timestamp_for_id` (in the same way as for TX timestamps).
224
- let ts = if let Some ( timestamp) = packet. timestamp ( ) {
233
+ * packet_id += 1 ;
234
+ * packet_id &= !0x8000_0000 ;
235
+
236
+ Ok ( ( data, timestamp, used_packet_id) )
237
+ } else {
238
+ Err ( ( ) )
239
+ } ;
240
+ result
241
+ } {
242
+ let rx_timestamp = if let Some ( timestamp) = rx_timestamp {
225
243
timestamp
226
244
} else {
227
245
continue ;
228
246
} ;
229
247
230
- defmt:: debug!( "RX timestamp: {}" , ts) ;
248
+ // Get the timestamp "the long way" around by asking the DMA to retrieve
249
+ // the value cached in the RX packet.
250
+ let cached_timestamp = dma. get_timestamp_for_id ( used_packet_id) ;
251
+
252
+ // Assert that they are the same.
253
+ defmt:: assert_eq!( cached_timestamp, Ok ( rx_timestamp) ) ;
231
254
232
- let timestamp = if dst_mac == [ 0xAB , 0xCD , 0xEF , 0x12 , 0x34 , 0x56 ] {
255
+ defmt:: debug!( "RX timestamp: {}" , rx_timestamp) ;
256
+
257
+ let dst_mac = & data[ ..6 ] ;
258
+ let tx_timestamp = if dst_mac == [ 0xAB , 0xCD , 0xEF , 0x12 , 0x34 , 0x56 ] {
233
259
let mut timestamp_data = [ 0u8 ; 8 ] ;
234
- timestamp_data. copy_from_slice ( & packet [ 14 ..22 ] ) ;
260
+ timestamp_data. copy_from_slice ( & data [ 14 ..22 ] ) ;
235
261
let raw = i64:: from_be_bytes ( timestamp_data) ;
236
262
237
263
let timestamp = Timestamp :: new_raw ( raw) ;
@@ -240,9 +266,9 @@ mod app {
240
266
continue ;
241
267
} ;
242
268
243
- defmt:: debug!( "Contained TX timestamp: {}" , ts ) ;
269
+ defmt:: debug!( "Contained TX timestamp: {}" , rx_timestamp ) ;
244
270
245
- let diff = timestamp - ts ;
271
+ let diff = tx_timestamp - rx_timestamp ;
246
272
247
273
defmt:: info!( "Difference between TX and RX time: {}" , diff) ;
248
274
@@ -263,9 +289,6 @@ mod app {
263
289
defmt:: warn!( "Updated time." ) ;
264
290
ptp. update_time ( diff) ;
265
291
}
266
-
267
- packet_id += 1 ;
268
- packet_id &= !0x8000_0000 ;
269
292
}
270
293
271
294
if let Some ( ( tx_id, sent_time) ) = tx_id. take ( ) {
0 commit comments