source: firmware/FSC/src/w5100_spi_interface.c@ 15174

Last change on this file since 15174 was 11696, checked in by neise, 13 years ago
the changes we made with thomas B did not work. I have to find out why... only crap is send away now.
File size: 13.0 KB
Line 
1//-----------------------------------------------------------------------------
2
3#include "w5100_spi_interface.h"
4#include "spi_master.h"
5#include "usart.h"
6volatile BOOL sock0_connection_established = false;
7volatile U08 eth_read_buffer[ETH_READ_BUFFER_SIZE];
8volatile U08 eth_write_buffer[ETH_WRITE_BUFFER_SIZE];
9
10U08 eth_write_index;
11//-----------------------------------------------------------------------------
12// INTERFACE CONTROL VARS
13
14bool w5100_needs_init = true;
15bool w5100_ready = false;
16
17U16 last_samurai = 0x0000;
18
19U08 w5100_caretaker() {
20U08 socket_status;
21
22 socket_status = w5100_sock_status();
23 //usart_write_str((pU08)"ss:");
24 //usart_write_U08_hex(socket_status);
25 //usart_write_char(' ');
26
27 if (socket_status == SR_SOCK_ESTABLISHED) {
28 w5100_ready = true;
29 // everything is fine...
30 }
31 else if (socket_status == SR_SOCK_LISTEN) {
32 w5100_ready = false;
33 // wait for connection
34 }
35 else {
36 socket_status = w5100_sock_status();
37 //usart_write_str((pU08)"ss2:");
38 //usart_write_U08_hex(socket_status);
39 //usart_write_char(' ');
40
41 if (socket_status == SR_SOCK_ESTABLISHED) {
42 w5100_ready = true;
43 // everything is fine...
44 }
45 else if (socket_status == SR_SOCK_LISTEN) {
46 w5100_ready = false;
47 // wait for connection
48 }
49 else
50 {
51 // this should never happen
52 w5100_ready = false;
53 w5100_reset();
54 w5100_init();
55 }
56 }
57
58 //usart_write_crlf();
59return socket_status;
60}
61
62void w5100_reset() {
63 PORTB &= ~(1<<PB2); //#reset = LOW --> W5100 is in reset ...
64 _delay_ms(50); //reset
65
66 PORTB |= 1<<PB2; //#reset = HIGH --> W5100 is active
67 _delay_ms(5); // give it 5ms to accomodate.
68}
69
70
71void w5100_write( U16 addr, U08 data)
72{
73 // setup the SPI interface according to W5100 specs.
74 // This is needed, because AD7719 has different SPI specs.
75 spi_setup_w5100();
76
77spi_write_buffer[0]=0xF0;
78spi_write_buffer[1]=(U08)(addr>>8);
79spi_write_buffer[2]=(U08)(addr);
80spi_write_buffer[3]=data;
81
82spi_transfer_w5100(4);
83// spi_read_buffer should contain 0x00 0x01 0x02 and 0x03 ... nice check!
84}
85
86U08 w5100_read( U16 addr)
87{
88 // setup the SPI interface according to W5100 specs.
89 // This is needed, because AD7719 has different SPI specs.
90 spi_setup_w5100();
91
92spi_write_buffer[0]=0x0F;
93spi_write_buffer[1]=(U08)(addr>>8);
94spi_write_buffer[2]=(U08)(addr);
95spi_write_buffer[3]=0x00;
96
97spi_transfer_w5100(4);
98return spi_read_buffer[3];
99// spi_read_buffer should contain 0x00 0x01 0x02 and data ... nice check!
100}
101
102U08 w5100_init (void)
103{
104U08 sock0_status = 0x00;
105
106 // set FSCs MAC Address to value defined in w5100_spi_interface.h
107 w5100_write( CM_SHAR0, FSC_MAC_ADDRESS0 );
108 w5100_write( CM_SHAR1, FSC_MAC_ADDRESS1 );
109 w5100_write( CM_SHAR2, FSC_MAC_ADDRESS2 );
110 w5100_write( CM_SHAR3, FSC_MAC_ADDRESS3 );
111 w5100_write( CM_SHAR4, FSC_MAC_ADDRESS4 );
112 w5100_write( CM_SHAR5, FSC_MAC_ADDRESS5 );
113
114 //set IP
115 w5100_write( CM_SIPR0, FSC_IP_ADDRESS0 );
116 w5100_write( CM_SIPR1, FSC_IP_ADDRESS1 );
117 w5100_write( CM_SIPR2, FSC_IP_ADDRESS2 );
118 w5100_write( CM_SIPR3, FSC_IP_ADDRESS3 );
119
120 // set subnet mask
121 w5100_write( CM_SUBR0, FSC_SUBNET_MASK0 );
122 w5100_write( CM_SUBR1, FSC_SUBNET_MASK1 );
123 w5100_write( CM_SUBR2, FSC_SUBNET_MASK2 );
124 w5100_write( CM_SUBR3, FSC_SUBNET_MASK3 );
125
126 // set IP of Gateway used by FSC
127 w5100_write( CM_GAR0, FSC_GATEWAY_ADDRESS0 );
128 w5100_write( CM_GAR1, FSC_GATEWAY_ADDRESS1 );
129 w5100_write( CM_GAR2, FSC_GATEWAY_ADDRESS2 );
130 w5100_write( CM_GAR3, FSC_GATEWAY_ADDRESS3 );
131
132 //set socket read and write fifo sizes
133 w5100_write( CM_RMSR, 0x0A); // --> 4k for socket 0 and 1
134 w5100_write( CM_TMSR, 0x0A); // --> 4k for socket 0 and 1
135
136
137 w5100_write ( S0_MR, 0x01); // set Socket 0 as TCP
138 w5100_write ( S0_PORT0, 0x13 ); // Port 5000 -> 0x1388
139 w5100_write ( S0_PORT1, 0x88 );
140 w5100_write ( S0_CR, CR_OPEN ); // issue Socket open command
141 while (sock0_status != SR_SOCK_INIT) {
142 sock0_status = w5100_read(S0_SR); // request socket 0 status
143 }
144
145 w5100_write ( S0_CR, CR_LISTEN ); // issue Socket listen command
146 while (sock0_status != SR_SOCK_LISTEN) {
147 sock0_status = w5100_read(S0_SR); // request socket 0 status
148 }
149 return sock0_status;
150}
151
152
153BOOL w5100_is_established()
154{
155 if ( w5100_read(S0_SR) == SR_SOCK_ESTABLISHED )
156 {
157 sock0_connection_established = true;
158 }
159 else
160 {
161 sock0_connection_established = false;
162 }
163 return sock0_connection_established;
164
165}
166
167U08 w5100_sock_status()
168{
169 return w5100_read(S0_SR);
170}
171
172
173// getters of TX and RX registers
174// S0_TX_FSR
175U16 get_S0_TX_FSR()
176{
177U16 freesize;
178freesize=w5100_read(S0_TX_FSR0); // datasheet: user should read upper byte first, and lower byte later
179freesize = freesize << 8; // to get correct value
180freesize += w5100_read(S0_TX_FSR1);
181return freesize;
182}
183
184// S0_TX_RD
185U16 get_S0_TX_RD()
186{
187U16 readpointer;
188readpointer=w5100_read(S0_TX_RD0);
189readpointer = readpointer << 8;
190readpointer += w5100_read(S0_TX_RD1);
191return readpointer;
192}
193
194// S0_TX_WR
195U16 get_S0_TX_WR()
196{
197U16 writepointer;
198writepointer=w5100_read(S0_TX_WR0);
199writepointer = writepointer << 8;
200writepointer += w5100_read(S0_TX_WR1);
201return writepointer;
202}
203
204// S0_RX_RSR
205U16 get_S0_RX_RSR()
206{
207U16 received_size;
208U08 highbyte, lowbyte;
209 highbyte = w5100_read(S0_RX_RSR0);
210 lowbyte = w5100_read(S0_RX_RSR1);
211 received_size = (highbyte<<8) | lowbyte;
212
213// usart_write_str((pU08)"hi:");
214// usart_write_U08_hex(highbyte);
215// usart_write_crlf();
216//
217// usart_write_str((pU08)"lo:");
218// usart_write_U08_hex(lowbyte);
219// usart_write_crlf();
220//
221// usart_write_str((pU08)"total:");
222// usart_write_U16_hex(received_size);
223// usart_write_crlf();
224
225// _delay_ms(200);
226
227 return received_size;
228}
229
230// S0_RX_RD
231U16 get_S0_RX_RD()
232{
233U16 readpointer;
234readpointer=w5100_read(S0_RX_RD0);
235readpointer = readpointer << 8;
236readpointer += w5100_read(S0_RX_RD1);
237return readpointer;
238}
239
240// setters for some RX and TX registers
241// S0_TX_WR
242void set_S0_TX_WR(U16 value)
243{
244U08 high_byte = (value>>8);
245U08 low_byte = value&0x00FF;
246w5100_write(S0_TX_WR0, high_byte);
247w5100_write(S0_TX_WR1, low_byte);
248}
249
250// S0_TX_RD
251void set_S0_RX_RD(U16 value)
252{
253U08 high_byte = (value>>8);
254U08 low_byte = value&0x00FF;
255w5100_write(S0_RX_RD0, high_byte);
256w5100_write(S0_RX_RD1, low_byte);
257}
258
259U08 w5100_get_RX(U08 NumBytes, BOOL send_ACK)
260{
261 U16 size = get_S0_RX_RSR();
262 U16 upper_size, lower_size;
263 if (NumBytes > ETH_READ_BUFFER_SIZE)
264 {
265 NumBytes = ETH_READ_BUFFER_SIZE;
266 }
267 if (size == 0)
268 {
269 return 0;
270 }
271 else if ( size < NumBytes )
272 {
273 NumBytes = size;
274 }
275
276 // now calculate the offset address
277 // calculated according to W5100 datasheet page: 43
278 U16 last_RX_read_pointer = get_S0_RX_RD();
279 U16 offset = last_RX_read_pointer & S0_RX_MASK;
280 U16 start_address = S0_RX_BASE + offset;
281
282 usart_write_str((pU08)"lrp:");
283 usart_write_U16_hex(last_RX_read_pointer);
284 usart_write_crlf();
285 usart_write_str((pU08)"off:");
286 usart_write_U16_hex(offset);
287 usart_write_crlf();
288 usart_write_str((pU08)"sad:");
289 usart_write_U16_hex(start_address);
290 usart_write_crlf();
291
292
293 if ((offset + NumBytes) > (S0_RX_MASK + 1) ) // if data is turned over in RX-mem
294 {
295 upper_size = (S0_RX_MASK + 1) - offset;
296 lower_size = NumBytes - upper_size;
297 for (U08 i = 0; i < upper_size; ++i)
298 {
299 eth_read_buffer[i] = w5100_read(start_address + i);
300 }
301 for (U08 i = 0; i < lower_size; ++i)
302 {
303 eth_read_buffer[upper_size + i] = w5100_read(S0_RX_BASE + i);
304 }
305 }
306 else // if not data turn over in RX-mem
307 {
308 for (U08 i = 0; i < NumBytes; ++i)
309 {
310 eth_read_buffer[i] = w5100_read(start_address + i);
311 }
312 }
313
314 // inform W5100 about how much data was read out.
315 U16 new_read_pointer = last_RX_read_pointer + NumBytes;
316 usart_write_str((pU08)"nrp:");
317 usart_write_U16_hex(new_read_pointer);
318 usart_write_crlf();
319
320 set_S0_RX_RD(new_read_pointer);
321 w5100_write ( S0_CR, CR_RECV );
322
323 /*
324 usart_write_U16_hex(get_S0_TX_FSR()); usart_write_char('\t'); usart_write_char('|');
325 usart_write_U16_hex(get_S0_TX_RD()); usart_write_char('\t'); usart_write_char('|');
326 usart_write_U16_hex(get_S0_TX_WR()); usart_write_char('\t'); usart_write_char('|');
327 usart_write_U16_hex(get_S0_RX_RSR()); usart_write_char('\t'); usart_write_char('|');
328 usart_write_U16_hex(get_S0_RX_RD()); usart_write_char('\t'); usart_write_char('|');
329 */
330
331 // if user wishes, W5100 may inform peer about receiption.
332 // this should be done quickly, otherwise timeout may occur on
333 // peer side, and peer retransmitts or so ...
334 //
335 // maybe it is necessary to acknowledge receiption very early.
336 // I think there is an option in Socket mode register for this.
337 if (send_ACK)
338 {
339 //w5100_write ( S0_CR, CR_RECV );
340 }
341
342 return NumBytes;
343}
344
345// returns number of words, transmitted into TX - buffer.
346U16 w5100_set_TX(U08* string, U16 NumBytes) {
347
348 U08 repetitions;
349 U16 freesize;
350 U16 last_TX_write_pointer;
351
352 //usart_write_str((pU08)"S0_IR:");
353 //usart_write_U08_hex( w5100_read(S0_IR) );
354 //usart_write_crlf();
355
356 freesize = get_S0_TX_FSR();
357 for (repetitions=0 ; repetitions < 3; ) // increase is *inside the loop*
358 {
359 if ( freesize != get_S0_TX_FSR()) {
360 freesize = get_S0_TX_FSR();
361 } else {
362 repetitions++;
363 }
364 }
365
366 if (freesize == 0)
367 {
368 return 0;
369 }
370
371 last_TX_write_pointer = get_S0_TX_WR();
372 for (repetitions=0 ; repetitions < 3; ) // increase is *inside the loop*
373 {
374 if ( last_TX_write_pointer != get_S0_TX_WR()) {
375 last_TX_write_pointer = get_S0_TX_WR();
376 } else {
377 repetitions++;
378 }
379 }
380
381 U16 offset = last_TX_write_pointer & S0_TX_MASK;
382 U16 start_address = S0_TX_BASE + offset;
383
384 if (last_samurai != last_TX_write_pointer)
385 usart_write_str((pU08)"Hilfeeeeeeeeeeeeeee\n");
386
387 //usart_write_crlf();
388 //usart_write_char('|');usart_write_U16_hex( last_TX_write_pointer );
389 //usart_write_char('|');usart_write_U16_hex( offset );
390 //usart_write_char('|');usart_write_U16_hex( start_address );
391
392
393 //usart_write_crlf();
394 //usart_write_crlf();
395 //usart_write_str((pU08)"lwp :");
396 //usart_write_U16_hex(last_TX_write_pointer);
397 //usart_write_crlf();
398 //
399 //usart_write_str((pU08)"off :");
400 //usart_write_U16_hex(offset);
401 //usart_write_crlf();
402 //
403 //usart_write_str((pU08)"stad:");
404 //usart_write_U16_hex(start_address);
405 //usart_write_crlf();
406
407
408 U16 upper_size, lower_size;
409 /*
410 if (NumBytes > ETH_WRITE_BUFFER_SIZE)
411 {
412 NumBytes = ETH_WRITE_BUFFER_SIZE;
413 }
414 if (freesize == 0)
415 {
416 return 0;
417 }
418 else */
419 if ( freesize < NumBytes )
420 {
421 NumBytes = freesize;
422 }
423 //usart_write_char('|');usart_write_U16_hex( NumBytes );
424
425 // now calculate the offset address
426 // calculated according to W5100 datasheet page: 44
427 if ((offset + NumBytes) > (S0_RX_MASK + 1) ) // if data is turned over in RX-mem
428 {
429 upper_size = (S0_RX_MASK + 1) - offset;
430 lower_size = NumBytes - upper_size;
431 for (U16 i = 0; i < upper_size; ++i)
432 {
433 w5100_write(start_address + i, string[i]);
434 //usart_write_str((pU08)"wr:");
435 //usart_write_U16_hex(start_address + i);
436 //usart_write_char(' ');
437 //usart_write_char(string[i]);
438 //usart_write_crlf();
439
440 }
441 for (U16 i = 0; i < lower_size; ++i)
442 {
443 w5100_write(S0_RX_BASE + i, string[upper_size+i]);
444 //usart_write_str((pU08)"wr:");
445 //usart_write_U16_hex(S0_RX_BASE + i);
446 //usart_write_char(' ');
447 //usart_write_char(string[upper_size+i]);
448 //usart_write_crlf();
449
450 }
451 }
452 else // if not data turn over in RX-mem
453 {
454 for (U16 i = 0; i < NumBytes; ++i)
455 {
456 w5100_write(start_address + i, string[i]);
457 //usart_write_str((pU08)"wr:");
458 //usart_write_U16_hex(start_address + i);
459 //usart_write_char(' ');
460 //usart_write_char(string[i]);
461 //usart_write_crlf();
462
463 }
464 }
465
466 // inform W5100 about how much data was written.
467 U16 new_write_pointer = last_TX_write_pointer + NumBytes;
468 last_samurai = new_write_pointer;
469
470
471 set_S0_TX_WR(new_write_pointer);
472 //usart_write_char('|');usart_write_U16_hex( new_write_pointer );
473
474 //usart_write_char('|');
475 //usart_write_crlf();
476
477
478 //usart_write_str((pU08)"wrpt:");
479 //usart_write_U16_hex(last_TX_write_pointer + NumBytes);
480 //usart_write_crlf();
481
482 // tell it to send now the data away
483 w5100_write( S0_CR, CR_SEND);
484
485
486
487 return NumBytes;
488}
489
490void eth_write_str( U08* str ){
491
492 while (*str) {
493 if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
494 eth_write_buffer[eth_write_index++] = *str++;
495 }
496
497 }
498 w5100_set_TX(eth_write_buffer, eth_write_index);
499 eth_write_index = 0;
500}
501
502void eth_writeln_str( U08* str ){
503
504 while (*str)
505 {
506 if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
507 eth_write_buffer[eth_write_index++] = *str++;
508 }
509 }
510 if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
511 eth_write_buffer[eth_write_index++] = '\n';
512 }
513 w5100_set_TX(eth_write_buffer, eth_write_index);
514 eth_write_index = 0;
515}
516
517void eth_write_lf(void) {
518 if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
519 eth_write_buffer[eth_write_index++] = '\n';
520 }
521 w5100_set_TX(eth_write_buffer, eth_write_index);
522 eth_write_index = 0;
523}
Note: See TracBrowser for help on using the repository browser.