@@ -29,22 +29,13 @@ unsigned char macadr[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00};
29
29
30
30
u32_t clock_ms ;
31
31
32
- static void clock_init (void )
33
- {
34
- timer0_en_write (0 );
35
- timer0_load_write (0xffffffff );
36
- timer0_reload_write (0xffffffff );
37
- timer0_en_write (1 );
38
- clock_ms = 0 ;
39
- }
40
-
41
32
u32_t sys_now (void )
42
33
{
43
34
unsigned int freq ;
44
35
unsigned int prescaler ;
45
36
46
37
freq = identifier_frequency_read ();
47
- prescaler = freq /1000 ; /* sys_now expect time in ms */
38
+ prescaler = freq /1000 ; /* sys_now expects time in ms */
48
39
timer0_update_value_write (1 );
49
40
clock_ms += (0xffffffff - timer0_value_read ())/prescaler ;
50
41
/* Reset timer to avoid rollover, this will increase clock_ms
@@ -64,20 +55,246 @@ static void lwip_service(void)
64
55
ethmac_sram_writer_ev_pending_write (ETHMAC_EV_SRAM_WRITER );
65
56
}
66
57
}
67
- #endif
68
58
69
- void comm_service (void )
59
+ static void network_init (void )
60
+ {
61
+ struct ip4_addr local_ip ;
62
+ struct ip4_addr netmask ;
63
+ struct ip4_addr gateway_ip ;
64
+
65
+ timer0_en_write (0 );
66
+ timer0_load_write (0xffffffff );
67
+ timer0_reload_write (0xffffffff );
68
+ timer0_en_write (1 );
69
+ clock_ms = 0 ;
70
+
71
+ IP4_ADDR (& local_ip , 192 , 168 , 0 , 42 );
72
+ IP4_ADDR (& netmask , 255 , 255 , 255 , 0 );
73
+ IP4_ADDR (& gateway_ip , 192 , 168 , 0 , 1 );
74
+
75
+ lwip_init ();
76
+
77
+ netif_add (& netif , & local_ip , & netmask , & gateway_ip , 0 , liteeth_init , ethernet_input );
78
+ netif_set_default (& netif );
79
+ netif_set_up (& netif );
80
+ netif_set_link_up (& netif );
81
+ }
82
+
83
+ struct kserver_connstate {
84
+ int magic_recognized ;
85
+ struct pbuf * rp ;
86
+ int rp_offset ;
87
+ };
88
+
89
+ static struct kserver_connstate * cs_new (void )
90
+ {
91
+ struct kserver_connstate * cs ;
92
+
93
+ cs = (struct kserver_connstate * )mem_malloc (sizeof (struct kserver_connstate ));
94
+ if (!cs )
95
+ return NULL ;
96
+ cs -> magic_recognized = 0 ;
97
+ cs -> rp = NULL ;
98
+ cs -> rp_offset = 0 ;
99
+ return cs ;
100
+ }
101
+
102
+ static void cs_free (struct kserver_connstate * cs )
103
+ {
104
+ if (cs -> rp )
105
+ pbuf_free (cs -> rp );
106
+ mem_free (cs );
107
+ }
108
+
109
+ static const char kserver_magic [] = "ARTIQ coredev\n" ;
110
+
111
+ static int magic_ok (struct kserver_connstate * cs )
112
+ {
113
+ return cs -> magic_recognized >= 14 ;
114
+ }
115
+
116
+ static struct kserver_connstate * active_cs ;
117
+ static struct tcp_pcb * active_pcb ;
118
+
119
+ static void kserver_close (struct kserver_connstate * cs , struct tcp_pcb * pcb )
120
+ {
121
+ if (cs == active_cs ) {
122
+ session_end ();
123
+ active_cs = NULL ;
124
+ active_pcb = NULL ;
125
+ }
126
+
127
+ /* lwip loves to call back with broken pointers. Prevent that. */
128
+ tcp_arg (pcb , NULL );
129
+ tcp_recv (pcb , NULL );
130
+ tcp_sent (pcb , NULL );
131
+ tcp_err (pcb , NULL );
132
+
133
+ cs_free (cs );
134
+ tcp_close (pcb );
135
+ }
136
+
137
+ static err_t kserver_recv (void * arg , struct tcp_pcb * pcb , struct pbuf * p , err_t err )
138
+ {
139
+ struct kserver_connstate * cs ;
140
+
141
+ cs = (struct kserver_connstate * )arg ;
142
+ if (p ) {
143
+ if (cs -> rp )
144
+ pbuf_cat (cs -> rp , p );
145
+ else {
146
+ cs -> rp = p ;
147
+ cs -> rp_offset = 0 ;
148
+ }
149
+ } else
150
+ kserver_close (cs , pcb );
151
+ return ERR_OK ;
152
+ }
153
+
154
+ static err_t kserver_sent (void * arg , struct tcp_pcb * pcb , u16_t len )
155
+ {
156
+ session_ack_mem (len );
157
+ return ERR_OK ;
158
+ }
159
+
160
+ static void tcp_pcb_service (void * arg , struct tcp_pcb * pcb )
161
+ {
162
+ struct kserver_connstate * cs ;
163
+ int remaining_in_pbuf ;
164
+ char * rpp ;
165
+ struct pbuf * next ;
166
+ int r ;
167
+
168
+ cs = (struct kserver_connstate * )arg ;
169
+
170
+ while (cs -> rp ) {
171
+ remaining_in_pbuf = cs -> rp -> len - cs -> rp_offset ;
172
+ rpp = (char * )cs -> rp -> payload ;
173
+ while (remaining_in_pbuf > 0 ) {
174
+ if (cs == active_cs ) {
175
+ r = session_input (& rpp [cs -> rp_offset ], remaining_in_pbuf );
176
+ if (r > 0 ) {
177
+ tcp_recved (pcb , r );
178
+ cs -> rp_offset += r ;
179
+ remaining_in_pbuf -= r ;
180
+ } else if (r == 0 )
181
+ return ;
182
+ else
183
+ kserver_close (cs , pcb );
184
+ } else {
185
+ if (rpp [cs -> rp_offset ] == kserver_magic [cs -> magic_recognized ]) {
186
+ cs -> magic_recognized ++ ;
187
+ if (magic_ok (cs )) {
188
+ if (active_cs )
189
+ kserver_close (active_cs , active_pcb );
190
+ session_start ();
191
+ active_cs = cs ;
192
+ active_pcb = pcb ;
193
+ tcp_sent (pcb , kserver_sent );
194
+ }
195
+ } else {
196
+ kserver_close (cs , pcb );
197
+ return ;
198
+ }
199
+ remaining_in_pbuf -- ;
200
+ cs -> rp_offset ++ ;
201
+ tcp_recved (pcb , 1 );
202
+ }
203
+ }
204
+ next = cs -> rp -> next ;
205
+ if (cs -> rp -> tot_len != cs -> rp -> len ) {
206
+ pbuf_ref (next );
207
+ pbuf_free (cs -> rp );
208
+ cs -> rp = next ;
209
+ cs -> rp_offset = 0 ;
210
+ } else {
211
+ pbuf_free (cs -> rp );
212
+ cs -> rp = NULL ;
213
+ }
214
+ }
215
+ }
216
+
217
+ static void kserver_err (void * arg , err_t err )
218
+ {
219
+ struct kserver_connstate * cs ;
220
+
221
+ cs = (struct kserver_connstate * )arg ;
222
+ cs_free (cs );
223
+ }
224
+
225
+ static struct tcp_pcb * listen_pcb ;
226
+
227
+ static err_t kserver_accept (void * arg , struct tcp_pcb * newpcb , err_t err )
228
+ {
229
+ struct kserver_connstate * cs ;
230
+
231
+ cs = cs_new ();
232
+ if (!cs )
233
+ return ERR_MEM ;
234
+ tcp_accepted (listen_pcb );
235
+ tcp_arg (newpcb , cs );
236
+ tcp_recv (newpcb , kserver_recv );
237
+ tcp_err (newpcb , kserver_err );
238
+ return ERR_OK ;
239
+ }
240
+
241
+ static void kserver_init (void )
242
+ {
243
+ listen_pcb = tcp_new ();
244
+ tcp_bind (listen_pcb , IP_ADDR_ANY , 1381 );
245
+ listen_pcb = tcp_listen (listen_pcb );
246
+ tcp_accept (listen_pcb , kserver_accept );
247
+ }
248
+
249
+ extern struct tcp_pcb * tcp_active_pcbs ;
250
+
251
+ static void kserver_service (void )
252
+ {
253
+ struct tcp_pcb * pcb ;
254
+ void * data ;
255
+ int len , sndbuf ;
256
+
257
+ /* Assume all active TCP PCBs with a non-NULL arg are our connections. */
258
+ pcb = tcp_active_pcbs ;
259
+ while (pcb ) {
260
+ if (pcb -> callback_arg )
261
+ tcp_pcb_service (pcb -> callback_arg , pcb );
262
+ pcb = pcb -> next ;
263
+ }
264
+
265
+ if (active_cs ) {
266
+ session_poll (& data , & len );
267
+ if (len > 0 ) {
268
+ sndbuf = tcp_sndbuf (active_pcb );
269
+ if (len > sndbuf )
270
+ len = sndbuf ;
271
+ tcp_write (active_pcb , data , len , 0 );
272
+ session_ack_data (len );
273
+ }
274
+ }
275
+ }
276
+
277
+ static void regular_main (void )
278
+ {
279
+ network_init ();
280
+ kserver_init ();
281
+
282
+ while (1 ) {
283
+ lwip_service ();
284
+ kserver_service ();
285
+ }
286
+ }
287
+
288
+ #else /* CSR_ETHMAC_BASE */
289
+
290
+ static void serial_service (void )
70
291
{
71
292
char * txdata ;
72
293
int txlen ;
73
294
static char rxdata ;
74
295
static int rxpending ;
75
296
int r , i ;
76
297
77
- #ifdef CSR_ETHMAC_BASE
78
- lwip_service ();
79
- #endif
80
-
81
298
if (!rxpending && uart_read_nonblock ()) {
82
299
rxdata = uart_read ();
83
300
rxpending = 1 ;
@@ -86,43 +303,30 @@ void comm_service(void)
86
303
r = session_input (& rxdata , 1 );
87
304
if (r > 0 )
88
305
rxpending = 0 ;
306
+ if (r < 0 ) {
307
+ session_end ();
308
+ session_start ();
309
+ }
89
310
}
90
311
91
312
session_poll ((void * * )& txdata , & txlen );
92
313
if (txlen > 0 ) {
93
314
for (i = 0 ;i < txlen ;i ++ )
94
315
uart_write (txdata [i ]);
95
- session_ack (txlen );
316
+ session_ack_data (txlen );
317
+ session_ack_mem (txlen );
96
318
}
97
319
}
98
320
99
321
static void regular_main (void )
100
322
{
101
- #ifdef CSR_ETHMAC_BASE
102
- struct ip4_addr local_ip ;
103
- struct ip4_addr netmask ;
104
- struct ip4_addr gateway_ip ;
105
-
106
- time_init ();
107
- clock_init ();
108
-
109
- IP4_ADDR (& local_ip , 192 , 168 , 0 , 42 );
110
- IP4_ADDR (& netmask , 255 , 255 , 255 , 0 );
111
- IP4_ADDR (& gateway_ip , 192 , 168 , 0 , 1 );
112
-
113
- lwip_init ();
114
-
115
- netif_add (& netif , & local_ip , & netmask , & gateway_ip , 0 , liteeth_init , ethernet_input );
116
- netif_set_default (& netif );
117
- netif_set_up (& netif );
118
- netif_set_link_up (& netif );
119
- #endif
120
-
323
+ /* Open the session for the serial control. */
121
324
session_start ();
122
325
while (1 )
123
- comm_service ();
326
+ serial_service ();
124
327
}
125
328
329
+ #endif
126
330
127
331
static void blink_led (void )
128
332
{
@@ -169,6 +373,12 @@ int main(void)
169
373
#else
170
374
puts ("ARTIQ runtime built " __DATE__ " " __TIME__ " for UP systems\n" );
171
375
#endif
376
+ #ifdef CSR_ETHMAC_BASE
377
+ puts ("Accepting sessions on Ethernet" );
378
+ #else
379
+ puts ("Accepting sessions on serial link" );
380
+ #endif
381
+ puts ("Press 't' to enter test mode..." );
172
382
blink_led ();
173
383
174
384
if (check_test_mode ()) {
0 commit comments