3
3
#![ no_std]
4
4
#![ no_main]
5
5
6
- use panic_rtt_target as _ ;
6
+ extern crate panic_itm ;
7
7
8
8
use cortex_m:: asm;
9
9
use cortex_m_rt:: { entry, exception} ;
10
10
use stm32_eth:: {
11
+ hal:: flash:: FlashExt ,
11
12
hal:: gpio:: GpioExt ,
12
13
hal:: rcc:: RccExt ,
13
14
stm32:: { interrupt, CorePeripherals , Peripherals , SYST } ,
14
- RxDescriptor , TxDescriptor ,
15
15
} ;
16
16
17
17
use core:: cell:: RefCell ;
18
18
use cortex_m:: interrupt:: Mutex ;
19
19
20
20
use core:: fmt:: Write ;
21
+ use cortex_m_semihosting:: hio;
21
22
22
- use smoltcp:: iface:: { EthernetInterfaceBuilder , NeighborCache } ;
23
- use smoltcp:: socket:: { SocketSet , TcpSocket , TcpSocketBuffer } ;
23
+ use fugit:: RateExtU32 ;
24
+ use log:: { Level , LevelFilter , Metadata , Record } ;
25
+ use smoltcp:: iface:: { InterfaceBuilder , NeighborCache } ;
26
+ use smoltcp:: socket:: { TcpSocket , TcpSocketBuffer } ;
24
27
use smoltcp:: time:: Instant ;
25
28
use smoltcp:: wire:: { EthernetAddress , IpAddress , IpCidr , Ipv4Address } ;
26
- use stm32_eth:: { Eth , EthPins , PhyAddress , RingEntry } ;
27
29
28
- use rtt_target:: { rprintln, rtt_init_print} ;
29
- use stm32f1xx_hal:: { flash:: FlashExt , prelude:: * } ;
30
+ use stm32_eth:: { Eth , EthPins , RingEntry } ;
31
+
32
+ static mut LOGGER : HioLogger = HioLogger { } ;
33
+
34
+ struct HioLogger { }
35
+
36
+ impl log:: Log for HioLogger {
37
+ fn enabled ( & self , metadata : & Metadata ) -> bool {
38
+ metadata. level ( ) <= Level :: Trace
39
+ }
40
+
41
+ fn log ( & self , record : & Record ) {
42
+ if self . enabled ( record. metadata ( ) ) {
43
+ let mut stdout = hio:: hstdout ( ) . unwrap ( ) ;
44
+ writeln ! ( stdout, "{} - {}" , record. level( ) , record. args( ) ) . unwrap ( ) ;
45
+ }
46
+ }
47
+ fn flush ( & self ) { }
48
+ }
30
49
31
50
const SRC_MAC : [ u8 ; 6 ] = [ 0x00 , 0x00 , 0xDE , 0xAD , 0xBE , 0xEF ] ;
32
51
@@ -35,91 +54,39 @@ static ETH_PENDING: Mutex<RefCell<bool>> = Mutex::new(RefCell::new(false));
35
54
36
55
#[ entry]
37
56
fn main ( ) -> ! {
38
- rtt_init_print ! ( ) ;
57
+ unsafe {
58
+ log:: set_logger ( & LOGGER ) . unwrap ( ) ;
59
+ }
60
+ log:: set_max_level ( LevelFilter :: Info ) ;
39
61
40
- let p = stm32f1xx_hal:: stm32:: Peripherals :: take ( ) . unwrap ( ) ;
62
+ let mut stdout = hio:: hstdout ( ) . unwrap ( ) ;
63
+
64
+ let p = Peripherals :: take ( ) . unwrap ( ) ;
41
65
let mut cp = CorePeripherals :: take ( ) . unwrap ( ) ;
42
66
43
67
let mut flash = p. FLASH . constrain ( ) ;
44
68
69
+ let rcc = p. RCC . constrain ( ) ;
45
70
// HCLK must be at least 25MHz to use the ethernet peripheral
46
- rprintln ! ( "Setting up clocks" ) ;
47
-
48
- // Code below handle situation when ethernet controller has its own clock
49
-
50
- // let mut rcc = p.RCC.constrain();
51
- // let clocks = rcc
52
- // .cfgr
53
- // .use_hse(8.mhz())
54
- // .sysclk(72.mhz())
55
- // .hclk(72.mhz())
56
- // .pclk1(36.mhz())
57
- // .freeze(&mut flash.acr);
58
- ///////////////////////////////////////////////////////////////////////////////
59
-
60
- // This case handles case when ethernet controller clock is connected to MCO pin of STM32F107
61
- // MCU has connected 25 MHz oscillator to XTAL
62
- // Prescaller valuses (see clock diagram for STM32F107)
63
- // PREDIV2 = /5
64
- // PLL2MUL = x8
65
- // PREDIV1 = /5 (We have 8 Mhz for 'Clock from PREDIV1')
66
- // PLL3MUL = x10
67
- // PREDIV1SRC = PPL2
68
- let rcc = p. RCC ;
69
- rcc. cfgr2 . write ( |w| {
70
- w. prediv2 ( )
71
- . div5 ( )
72
- . pll2mul ( )
73
- . mul8 ( )
74
- . prediv1src ( )
75
- . pll2 ( )
76
- . prediv1 ( )
77
- . div5 ( )
78
- . pll3mul ( )
79
- . mul10 ( )
80
- } ) ;
81
-
82
- // enable HSE and wait for it to be ready
83
- rcc. cr . modify ( |_, w| w. hseon ( ) . set_bit ( ) ) ;
84
- while rcc. cr . read ( ) . hserdy ( ) . bit_is_clear ( ) { }
85
-
86
- // enable PLL2 and wait until ready
87
- rcc. cr . modify ( |_, w| w. pll2on ( ) . set_bit ( ) ) ;
88
- while rcc. cr . read ( ) . pll2rdy ( ) . bit_is_clear ( ) { }
89
-
90
- // enable PLL3 and wait until ready
91
- rcc. cr . modify ( |_, w| w. pll3on ( ) . set_bit ( ) ) ;
92
- while rcc. cr . read ( ) . pll3rdy ( ) . bit_is_clear ( ) { }
93
-
94
- // Get PLL3 clock on PA8 pin (MCO)
95
- rcc. cfgr . modify ( |_, w| w. mco ( ) . pll3ethernet ( ) ) ;
96
-
97
- let mut rcc = rcc. constrain ( ) ;
98
- let acr = & mut flash. acr ;
99
-
100
71
let clocks = rcc
101
72
. cfgr
102
- . use_hse ( 8 . mhz ( ) ) // HSE (Clock from PREDIV1), PLL configuration PREDIV2/PLL2MUL changes 25Mhz to 8Mhz
103
- . sysclk ( 72 . mhz ( ) )
104
- . pclk1 ( 36 . mhz ( ) )
105
- . freeze ( acr) ;
106
- ///////////////////////////////////////////////////////////////////////////////
73
+ . sysclk ( 32 . MHz ( ) )
74
+ . hclk ( 32 . MHz ( ) )
75
+ . freeze ( & mut flash. acr ) ;
107
76
108
- rprintln ! ( "Setting up systick" ) ;
109
77
setup_systick ( & mut cp. SYST ) ;
110
78
111
- //writeln!(stdout, "Enabling ethernet...").unwrap();
112
- let mut gpioa = p. GPIOA . split ( & mut rcc. apb2 ) ;
113
- let mut gpiob = p. GPIOB . split ( & mut rcc. apb2 ) ;
114
- let mut gpioc = p. GPIOC . split ( & mut rcc. apb2 ) ;
79
+ writeln ! ( stdout, "Enabling ethernet..." ) . unwrap ( ) ;
80
+
81
+ let mut gpioa = p. GPIOA . split ( ) ;
82
+ let mut gpiob = p. GPIOB . split ( ) ;
83
+ let mut gpioc = p. GPIOC . split ( ) ;
115
84
116
85
// PLL3CLK goes to MCO (Main Clock Output) (PA8)
117
86
let _mco = gpioa. pa8 . into_alternate_push_pull ( & mut gpioa. crh ) ;
118
87
119
88
let ref_clk = gpioa. pa1 . into_floating_input ( & mut gpioa. crl ) ;
120
- let md_io = gpioa. pa2 . into_alternate_push_pull ( & mut gpioa. crl ) ;
121
89
let crs = gpioa. pa7 . into_floating_input ( & mut gpioa. crl ) ;
122
- let md_clk = gpioc. pc1 . into_alternate_push_pull ( & mut gpioc. crl ) ;
123
90
let tx_en = gpiob. pb11 . into_alternate_push_pull ( & mut gpiob. crh ) ;
124
91
let tx_d0 = gpiob. pb12 . into_alternate_push_pull ( & mut gpiob. crh ) ;
125
92
let tx_d1 = gpiob. pb13 . into_alternate_push_pull ( & mut gpiob. crh ) ;
@@ -128,8 +95,6 @@ fn main() -> ! {
128
95
129
96
let eth_pins = EthPins {
130
97
ref_clk,
131
- md_io,
132
- md_clk,
133
98
crs,
134
99
tx_en,
135
100
tx_d0,
@@ -138,42 +103,29 @@ fn main() -> ! {
138
103
rx_d1,
139
104
} ;
140
105
141
- rprintln ! ( "Constructing `Eth`" ) ;
142
- let mut rx_ring: [ RingEntry < _ > ; 8 ] = [
143
- RingEntry :: < RxDescriptor > :: new ( ) ,
144
- RingEntry :: < RxDescriptor > :: new ( ) ,
145
- RingEntry :: < RxDescriptor > :: new ( ) ,
146
- RingEntry :: < RxDescriptor > :: new ( ) ,
147
- RingEntry :: < RxDescriptor > :: new ( ) ,
148
- RingEntry :: < RxDescriptor > :: new ( ) ,
149
- RingEntry :: < RxDescriptor > :: new ( ) ,
150
- RingEntry :: < RxDescriptor > :: new ( ) ,
151
- ] ;
152
- let mut tx_ring: [ RingEntry < _ > ; 2 ] = [
153
- RingEntry :: < TxDescriptor > :: new ( ) ,
154
- RingEntry :: < TxDescriptor > :: new ( ) ,
155
- ] ;
106
+ let mut rx_ring: [ RingEntry < _ > ; 8 ] = Default :: default ( ) ;
107
+ let mut tx_ring: [ RingEntry < _ > ; 2 ] = Default :: default ( ) ;
156
108
let mut eth = Eth :: new (
157
109
p. ETHERNET_MAC ,
158
110
p. ETHERNET_DMA ,
159
111
& mut rx_ring[ ..] ,
160
112
& mut tx_ring[ ..] ,
161
- PhyAddress :: _0,
162
113
clocks,
163
114
eth_pins,
164
115
)
165
116
. unwrap ( ) ;
166
117
eth. enable_interrupt ( ) ;
167
118
168
- rprintln ! ( "Setting up TCP/IP" ) ;
169
- let local_addr = Ipv4Address :: new ( 10 , 101 , 0 , 1 ) ;
170
- let ip_addr = IpCidr :: new ( IpAddress :: from ( local_addr) , 16 ) ;
119
+ let local_addr = Ipv4Address :: new ( 10 , 0 , 0 , 1 ) ;
120
+ let ip_addr = IpCidr :: new ( IpAddress :: from ( local_addr) , 24 ) ;
171
121
let mut ip_addrs = [ ip_addr] ;
172
122
let mut neighbor_storage = [ None ; 16 ] ;
173
123
let neighbor_cache = NeighborCache :: new ( & mut neighbor_storage[ ..] ) ;
174
124
let ethernet_addr = EthernetAddress ( SRC_MAC ) ;
175
- let mut iface = EthernetInterfaceBuilder :: new ( & mut eth)
176
- . ethernet_addr ( ethernet_addr)
125
+
126
+ let mut sockets: [ _ ; 1 ] = Default :: default ( ) ;
127
+ let mut iface = InterfaceBuilder :: new ( & mut eth, & mut sockets[ ..] )
128
+ . hardware_addr ( ethernet_addr. into ( ) )
177
129
. ip_addrs ( & mut ip_addrs[ ..] )
178
130
. neighbor_cache ( neighbor_cache)
179
131
. finalize ( ) ;
@@ -184,48 +136,48 @@ fn main() -> ! {
184
136
TcpSocketBuffer :: new ( & mut server_rx_buffer[ ..] ) ,
185
137
TcpSocketBuffer :: new ( & mut server_tx_buffer[ ..] ) ,
186
138
) ;
187
- let mut sockets_storage = [ None , None ] ;
188
- let mut sockets = SocketSet :: new ( & mut sockets_storage[ ..] ) ;
189
- let server_handle = sockets. add ( server_socket) ;
139
+ let server_handle = iface. add_socket ( server_socket) ;
190
140
191
- rprintln ! ( "Ready, listening at {}" , ip_addr) ;
141
+ writeln ! ( stdout , "Ready, listening at {}" , ip_addr) . unwrap ( ) ;
192
142
loop {
193
143
let time: u64 = cortex_m:: interrupt:: free ( |cs| * TIME . borrow ( cs) . borrow ( ) ) ;
194
144
cortex_m:: interrupt:: free ( |cs| {
195
145
let mut eth_pending = ETH_PENDING . borrow ( cs) . borrow_mut ( ) ;
196
146
* eth_pending = false ;
197
147
} ) ;
198
- match iface. poll ( & mut sockets , Instant :: from_millis ( time as i64 ) ) {
148
+ match iface. poll ( Instant :: from_millis ( time as i64 ) ) {
199
149
Ok ( true ) => {
200
- let mut socket = sockets . get :: < TcpSocket > ( server_handle) ;
150
+ let socket = iface . get_socket :: < TcpSocket > ( server_handle) ;
201
151
if !socket. is_open ( ) {
202
152
socket
203
153
. listen ( 80 )
204
- . unwrap_or_else ( |e| rprintln ! ( "TCP listen error: {:?}" , e) ) ;
154
+ . or_else ( |e| writeln ! ( stdout, "TCP listen error: {:?}" , e) )
155
+ . unwrap ( ) ;
205
156
}
206
157
207
158
if socket. can_send ( ) {
208
159
write ! ( socket, "hello\n " )
209
160
. map ( |_| {
210
161
socket. close ( ) ;
211
162
} )
212
- . unwrap_or_else ( |e| rprintln ! ( "TCP send error: {:?}" , e) ) ;
163
+ . or_else ( |e| writeln ! ( stdout, "TCP send error: {:?}" , e) )
164
+ . unwrap ( ) ;
213
165
}
214
166
}
215
167
Ok ( false ) => {
216
168
// Sleep if no ethernet work is pending
217
169
cortex_m:: interrupt:: free ( |cs| {
218
170
let eth_pending = ETH_PENDING . borrow ( cs) . borrow_mut ( ) ;
219
171
if !* eth_pending {
220
- // Awaken by interrupt
221
172
asm:: wfi ( ) ;
173
+ // Awaken by interrupt
222
174
}
223
175
} ) ;
224
176
}
225
177
Err ( e) =>
226
178
// Ignore malformed packets
227
179
{
228
- rprintln ! ( "Error: {:?}" , e) ;
180
+ writeln ! ( stdout , "Error: {:?}" , e) . unwrap ( )
229
181
}
230
182
}
231
183
}
0 commit comments