1
- use super :: {
2
- raw_descriptor:: { DescriptorRing , DescriptorRingEntry } ,
3
- PacketId ,
4
- } ;
1
+ use core:: marker:: PhantomData ;
2
+
3
+ use super :: { raw_descriptor:: DescriptorRing , PacketId } ;
5
4
use crate :: peripherals:: ETHERNET_DMA ;
6
5
7
6
#[ cfg( feature = "ptp" ) ]
@@ -25,23 +24,55 @@ pub enum RxError {
25
24
/// An RX descriptor ring.
26
25
pub type RxDescriptorRing < ' rx > = DescriptorRing < ' rx , RxDescriptor > ;
27
26
27
+ pub struct NotRunning ;
28
+ pub struct Running ;
29
+
28
30
/// Rx DMA state
29
- pub ( crate ) struct RxRing < ' data > {
31
+ pub struct RxRing < ' data , STATE > {
30
32
ring : RxDescriptorRing < ' data > ,
31
33
next_entry : usize ,
34
+ state : PhantomData < STATE > ,
35
+ }
36
+
37
+ impl < ' data , STATE > RxRing < ' data , STATE > {
38
+ /// Demand that the DMA engine polls the current `RxDescriptor`
39
+ /// (when in `RunningState::Stopped`.)
40
+ pub fn demand_poll ( & self , eth_dma : & ETHERNET_DMA ) {
41
+ eth_dma. dmarpdr . write ( |w| unsafe { w. rpd ( ) . bits ( 1 ) } ) ;
42
+ }
43
+
44
+ /// Get current `RunningState`
45
+ pub fn running_state ( & self , eth_dma : & ETHERNET_DMA ) -> RunningState {
46
+ match eth_dma. dmasr . read ( ) . rps ( ) . bits ( ) {
47
+ // Reset or Stop Receive Command issued
48
+ 0b000 => RunningState :: Stopped ,
49
+ // Fetching receive transfer descriptor
50
+ 0b001 => RunningState :: Running ,
51
+ // Waiting for receive packet
52
+ 0b011 => RunningState :: Running ,
53
+ // Receive descriptor unavailable
54
+ 0b100 => RunningState :: Stopped ,
55
+ // Closing receive descriptor
56
+ 0b101 => RunningState :: Running ,
57
+ // Transferring the receive packet data from receive buffer to host memory
58
+ 0b111 => RunningState :: Running ,
59
+ _ => RunningState :: Unknown ,
60
+ }
61
+ }
32
62
}
33
63
34
- impl < ' data > RxRing < ' data > {
64
+ impl < ' data > RxRing < ' data , NotRunning > {
35
65
/// Allocate
36
66
pub fn new ( ring : RxDescriptorRing < ' data > ) -> Self {
37
67
RxRing {
38
68
ring,
39
69
next_entry : 0 ,
70
+ state : Default :: default ( ) ,
40
71
}
41
72
}
42
73
43
- /// Setup the DMA engine (**required**)
44
- pub fn start ( & mut self , eth_dma : & ETHERNET_DMA ) {
74
+ /// Start the RX ring
75
+ pub fn start ( mut self , eth_dma : & ETHERNET_DMA ) -> RxRing < ' data , Running > {
45
76
// Setup ring
46
77
for ( entry, buffer) in self . ring . descriptors_and_buffers ( ) {
47
78
entry. setup ( buffer) ;
@@ -64,31 +95,21 @@ impl<'data> RxRing<'data> {
64
95
eth_dma. dmaomr . modify ( |_, w| w. sr ( ) . set_bit ( ) ) ;
65
96
66
97
self . demand_poll ( eth_dma) ;
67
- }
68
98
69
- /// Demand that the DMA engine polls the current `RxDescriptor`
70
- /// (when in `RunningState::Stopped`.)
71
- pub fn demand_poll ( & self , eth_dma : & ETHERNET_DMA ) {
72
- eth_dma. dmarpdr . write ( |w| unsafe { w. rpd ( ) . bits ( 1 ) } ) ;
99
+ RxRing {
100
+ ring : self . ring ,
101
+ next_entry : self . next_entry ,
102
+ state : Default :: default ( ) ,
103
+ }
73
104
}
105
+ }
74
106
75
- /// Get current `RunningState`
76
- pub fn running_state ( & self , eth_dma : & ETHERNET_DMA ) -> RunningState {
77
- match eth_dma. dmasr . read ( ) . rps ( ) . bits ( ) {
78
- // Reset or Stop Receive Command issued
79
- 0b000 => RunningState :: Stopped ,
80
- // Fetching receive transfer descriptor
81
- 0b001 => RunningState :: Running ,
82
- // Waiting for receive packet
83
- 0b011 => RunningState :: Running ,
84
- // Receive descriptor unavailable
85
- 0b100 => RunningState :: Stopped ,
86
- // Closing receive descriptor
87
- 0b101 => RunningState :: Running ,
88
- // Transferring the receive packet data from receive buffer to host memory
89
- 0b111 => RunningState :: Running ,
90
- _ => RunningState :: Unknown ,
91
- }
107
+ impl < ' data > RxRing < ' data , Running > {
108
+ /// Stop the DMA engine.
109
+ pub fn stop ( & mut self , eth_dma : & ETHERNET_DMA ) {
110
+ eth_dma. dmaomr . modify ( |_, w| w. sr ( ) . clear_bit ( ) ) ;
111
+
112
+ while self . running_state ( eth_dma) != RunningState :: Stopped { }
92
113
}
93
114
94
115
/// Receive the next packet (if any is ready), or return `None`
@@ -126,7 +147,7 @@ impl<'data> RxRing<'data> {
126
147
}
127
148
128
149
#[ cfg( feature = "ptp" ) ]
129
- impl < ' a > RxRing < ' a > {
150
+ impl < ' data , STATE > RxRing < ' data , STATE > {
130
151
pub fn get_timestamp_for_id ( & mut self , id : PacketId ) -> Result < Timestamp , TimestampError > {
131
152
for descriptor in self . ring . descriptors ( ) {
132
153
if let ( Some ( packet_id) , Some ( timestamp) ) =
0 commit comments