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

Last change on this file since 11681 was 11681, checked in by neise, 9 years ago
removed minor typos
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            /*
428        if ((offset + NumBytes) > (S0_TX_MASK + 1) )  // if data is turned over in RX-mem
429        {
430                upper_size = (S0_TX_MASK + 1) - offset;
431                lower_size = NumBytes - upper_size;
432                for (U16 i = 0; i < upper_size; ++i)
433                {
434                        w5100_write(start_address + i, string[i]);
435                        //usart_write_str((pU08)"wr:");
436                        //usart_write_U16_hex(start_address + i);
437                        //usart_write_char(' ');
438                        //usart_write_char(string[i]);
439                        //usart_write_crlf();
440
441                }
442                for (U16 i = 0; i < lower_size; ++i)
443                {
444                        w5100_write(S0_TX_BASE + i, string[upper_size+i]);
445                        //usart_write_str((pU08)"wr:");
446                        //usart_write_U16_hex(S0_RX_BASE + i);
447                        //usart_write_char(' ');
448                        //usart_write_char(string[upper_size+i]);
449                        //usart_write_crlf();
450
451                }
452        }
453        else // if not data turn over in RX-mem
454        {
455          */      for (U16 i = 0; i < NumBytes; ++i)
456                {
457                        w5100_write(S0_TX_BASE + (offset + i)&S0_TX_MASK, string[i]);
458                        //usart_write_str((pU08)"wr:");
459                        //usart_write_U16_hex(start_address + i);
460                        //usart_write_char(' ');
461                        //usart_write_char(string[i]);
462                        //usart_write_crlf();
463
464                }
465        //}
466
467        // inform W5100 about how much data was written.
468        U16 new_write_pointer = last_TX_write_pointer + NumBytes;
469        last_samurai = new_write_pointer;
470       
471       
472        set_S0_TX_WR(new_write_pointer);
473        //usart_write_char('|');usart_write_U16_hex( new_write_pointer );
474       
475        //usart_write_char('|');
476        //usart_write_crlf();
477       
478               
479                //usart_write_str((pU08)"wrpt:");
480                //usart_write_U16_hex(last_TX_write_pointer + NumBytes);
481                //usart_write_crlf();
482
483        // tell it to send now the data away
484        w5100_write( S0_CR, CR_SEND);
485       
486       
487       
488        return NumBytes;
489}
490
491void eth_write_str( U08* str ){
492
493        while (*str && eth_write_index < ETH_WRITE_BUFFER_SIZE)
494        {
495            eth_write_buffer[eth_write_index++] = *str++;
496        }
497        w5100_set_TX(eth_write_buffer, eth_write_index);
498        eth_write_index = 0;
499}
500
501void eth_writeln_str( U08* str ){
502
503        while (*str && eth_write_index < ETH_WRITE_BUFFER_SIZE) 
504        {
505            eth_write_buffer[eth_write_index++] = *str++;
506        }
507        if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
508                eth_write_buffer[eth_write_index++] = '\n';
509        }
510        w5100_set_TX(eth_write_buffer, eth_write_index);
511        eth_write_index = 0;
512}
513
514void eth_write_lf(void) {
515        if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
516                eth_write_buffer[eth_write_index++] = '\n';
517        }
518        w5100_set_TX(eth_write_buffer, eth_write_index);
519        eth_write_index = 0;
520}
Note: See TracBrowser for help on using the repository browser.