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

Last change on this file since 10674 was 10674, checked in by neise, 9 years ago
ethernet with user interface test
File size: 9.3 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
10//-----------------------------------------------------------------------------
11// INTERFACE CONTROL VARS
12
13bool w5100_needs_reset = true;
14bool w5100_needs_init = true;
15bool w5100_ready = false;
16
17U08 w5100_caretaker() {
18U08 socket_status;
19        if (w5100_needs_reset)
20                w5100_reset();
21               
22        socket_status = w5100_sock_status();
23       
24        if (socket_status == SR_SOCK_ESTABLISHED) {
25                w5100_ready = true;
26                // everything is fine...
27                return 0;
28        }
29        else if(socket_status < SR_SOCK_ESTABLISHED) {
30        // it might be LISTENING ... or not even OPEN
31                if (socket_status == SR_SOCK_CLOSED) {
32                        w5100_init();
33                }
34                if (socket_status == SR_SOCK_INIT) {
35                        w5100_init();
36                }
37                if (socket_status == SR_SOCK_LISTEN) {
38                       
39                }
40        }       
41        else { // all other socket states need a reset
42                w5100_needs_reset = true;
43        }
44w5100_ready = false;
45return 1;
46}
47
48void w5100_reset() {
49        PORTB &= ~(1<<PB2); //#reset = LOW --> W5100 is in reset ...
50        _delay_ms(50); //reset
51       
52        PORTB |= 1<<PB2; //#reset = HIGH --> W5100 is active
53        _delay_ms(5);           // give it 5ms to accomodate.
54        w5100_needs_reset = false;
55}
56
57
58void w5100_write( U16 addr, U08 data)
59{
60spi_write_buffer[0]=0xF0;
61spi_write_buffer[1]=(U08)(addr>>8);
62spi_write_buffer[2]=(U08)(addr);
63spi_write_buffer[3]=data;
64
65spi_transfer(4, 0); 
66// spi_read_buffer should contain 0x00 0x01 0x02 and 0x03 ... nice check!
67}
68
69U08 w5100_read( U16 addr)
70{
71spi_write_buffer[0]=0x0F;
72spi_write_buffer[1]=(U08)(addr>>8);
73spi_write_buffer[2]=(U08)(addr);
74spi_write_buffer[3]=0x00;
75
76spi_transfer(4, 0); 
77return spi_read_buffer[3]; 
78// spi_read_buffer should contain 0x00 0x01 0x02 and data ... nice check!
79}
80
81U08 w5100_init (void) 
82{
83U08 sock0_status = 0x00;
84
85        // set FSCs MAC Address to value defined in w5100_spi_interface.h
86        w5100_write( CM_SHAR0, FSC_MAC_ADDRESS0 );
87        w5100_write( CM_SHAR1, FSC_MAC_ADDRESS1 );
88        w5100_write( CM_SHAR2, FSC_MAC_ADDRESS2 );
89        w5100_write( CM_SHAR3, FSC_MAC_ADDRESS3 );
90        w5100_write( CM_SHAR4, FSC_MAC_ADDRESS4 );
91        w5100_write( CM_SHAR5, FSC_MAC_ADDRESS5 );
92
93        //set IP
94        w5100_write( CM_SIPR0, FSC_IP_ADDRESS0 );
95        w5100_write( CM_SIPR1, FSC_IP_ADDRESS1 );
96        w5100_write( CM_SIPR2, FSC_IP_ADDRESS2 );
97        w5100_write( CM_SIPR3, FSC_IP_ADDRESS3 );
98
99        // set subnet mask
100        w5100_write( CM_SUBR0, FSC_SUBNET_MASK0 );
101        w5100_write( CM_SUBR1, FSC_SUBNET_MASK1 );
102        w5100_write( CM_SUBR2, FSC_SUBNET_MASK2 );
103        w5100_write( CM_SUBR3, FSC_SUBNET_MASK3 );
104
105        // set IP of Gateway used by FSC
106        w5100_write( CM_GAR0, FSC_GATEWAY_ADDRESS0 );
107        w5100_write( CM_GAR1, FSC_GATEWAY_ADDRESS1 );
108        w5100_write( CM_GAR2, FSC_GATEWAY_ADDRESS2 );
109        w5100_write( CM_GAR3, FSC_GATEWAY_ADDRESS3 );
110
111        //set socket read and write fifo sizes
112        w5100_write( CM_RMSR, 0x0A); // --> 4k for socket 0 and 1
113        w5100_write( CM_TMSR, 0x0A); // --> 4k for socket 0 and 1
114
115
116        w5100_write ( S0_MR, 0x01);             // set Socket 0 as TCP
117        w5100_write ( S0_PORT0, 0x13 );         // Port 5000 -> 0x1388
118        w5100_write ( S0_PORT1, 0x88 ); 
119        usart_write_str((pU08)"Issuing Socket open command. NOW\n");
120        w5100_write ( S0_CR, CR_OPEN );         // issue Socket open command
121        while (sock0_status != SR_SOCK_INIT) {
122                sock0_status = w5100_read(S0_SR); // request socket 0 status
123                usart_write_str((pU08)"Socket 0 status is:");
124                usart_write_U08_hex(sock0_status);
125                usart_write_char('\n');
126        }
127
128        usart_write_str((pU08)"Issuing Socket LISTEN command. NOW\n");
129        w5100_write ( S0_CR, CR_LISTEN );               // issue Socket listen command
130       
131        while (sock0_status != SR_SOCK_LISTEN) {
132                sock0_status = w5100_read(S0_SR); // request socket 0 status
133                usart_write_str((pU08)"Socket 0 status is:");
134                usart_write_U08_hex(sock0_status);
135                usart_write_char('\n');
136        }
137        return sock0_status;
138}
139
140
141BOOL w5100_is_established()
142{
143        if ( w5100_read(S0_SR) == SR_SOCK_ESTABLISHED )
144        {
145                sock0_connection_established = true;
146        }
147        else
148        {
149                sock0_connection_established = false;
150        }
151        return sock0_connection_established;
152
153}
154
155U08 w5100_sock_status()
156{
157        return w5100_read(S0_SR);
158}
159
160
161// getters of TX and RX registers
162//              S0_TX_FSR
163U16 get_S0_TX_FSR()
164{
165U16 freesize;
166freesize=w5100_read(S0_TX_FSR0);
167freesize = freesize << 8;
168freesize += w5100_read(S0_TX_FSR1);
169return freesize;
170}
171
172//              S0_TX_RD
173U16 get_S0_TX_RD()
174{
175U16 readpointer;
176readpointer=w5100_read(S0_TX_RD0);
177readpointer = readpointer << 8;
178readpointer += w5100_read(S0_TX_RD1);
179return readpointer;
180}
181
182//              S0_TX_WR
183U16 get_S0_TX_WR()
184{
185U16 writepointer;
186writepointer=w5100_read(S0_TX_WR0);
187writepointer = writepointer << 8;
188writepointer += w5100_read(S0_TX_WR1);
189return writepointer;
190}
191
192//              S0_RX_RSR
193U16 get_S0_RX_RSR()
194{
195U16 received_size;
196received_size=w5100_read(S0_RX_RSR0);
197received_size = received_size << 8;
198received_size += w5100_read(S0_RX_RSR1);   // S0_RX_RSR1 is the least significant byte ...
199return received_size;
200}
201
202//              S0_RX_RD
203U16 get_S0_RX_RD()
204{
205U16 readpointer;
206readpointer=w5100_read(S0_RX_RD0);
207readpointer = readpointer << 8;
208readpointer += w5100_read(S0_RX_RD1);
209return readpointer;
210}
211
212// setters for some RX and TX registers
213//              S0_TX_WR
214void set_S0_TX_WR(U16 value)
215{
216U08 high_byte = (value>>8);
217U08 low_byte = value&0x00FF;
218w5100_write(S0_TX_WR0, high_byte);
219w5100_write(S0_TX_WR1, low_byte);
220}
221
222//              S0_TX_RD
223void set_S0_RX_RD(U16 value)
224{
225U08 high_byte = (value>>8);
226U08 low_byte = value&0x00FF;
227
228w5100_write(S0_RX_RD0, high_byte);
229w5100_write(S0_RX_RD1, low_byte);
230}
231
232U08 w5100_get_RX(U08 NumBytes, BOOL send_ACK)
233{
234        U16 size = get_S0_RX_RSR();
235        U16 upper_size, lower_size;
236        if (NumBytes > ETH_READ_BUFFER_SIZE)
237        {
238                NumBytes = ETH_READ_BUFFER_SIZE;
239        }
240        if (size == 0)
241        {
242                return 0;
243        }
244        else if ( size < NumBytes )
245        {
246                NumBytes = size;
247        }
248
249        // now calculate the offset address
250        // calculated according to W5100 datasheet page: 43
251        U16 last_RX_read_pointer = get_S0_RX_RD();
252        U16 offset = last_RX_read_pointer & S0_RX_MASK;
253        U16 start_address =  S0_RX_BASE + offset;
254       
255        usart_write_str("last_read_pointer:");
256        usart_write_U16_hex(last_RX_read_pointer);
257        usart_write_str("\noffset:");
258        usart_write_U16_hex(offset);
259        usart_write_str("\nstart_address:");
260        usart_write_U16_hex(start_address);
261        usart_write_char('\n');
262
263        if ((offset + NumBytes) > (S0_RX_MASK + 1) )  // if data is turned over in RX-mem
264        {
265                upper_size = (S0_RX_MASK + 1) - offset;
266                lower_size = NumBytes - upper_size;
267                for (U08 i = 0; i < upper_size; ++i)
268                {
269                        eth_read_buffer[i] = w5100_read(start_address + i);
270                }
271                for (U08 i = 0; i < lower_size; ++i)
272                {
273                        eth_read_buffer[upper_size + i] = w5100_read(S0_RX_BASE + i);
274                }
275        }
276        else // if not data turn over in RX-mem
277        {
278                for (U08 i = 0; i < NumBytes; ++i)
279                {
280                        eth_read_buffer[i] = w5100_read(start_address + i);
281                }
282        }
283
284        // inform W5100 about how much data was read out.
285        set_S0_RX_RD(last_RX_read_pointer + NumBytes);
286        w5100_write ( S0_CR, CR_RECV );
287       
288        usart_write_U16_hex(get_S0_TX_FSR()); usart_write_char('\t'); usart_write_char('|');
289        usart_write_U16_hex(get_S0_TX_RD()); usart_write_char('\t'); usart_write_char('|');
290        usart_write_U16_hex(get_S0_TX_WR()); usart_write_char('\t'); usart_write_char('|');
291        usart_write_U16_hex(get_S0_RX_RSR()); usart_write_char('\t'); usart_write_char('|');
292        usart_write_U16_hex(get_S0_RX_RD()); usart_write_char('\t'); usart_write_char('|');
293
294        // if user wishes, W5100 may inform peer about receiption.
295        // this should be done quickly, otherwise timeout may occur on
296        // peer side, and peer retransmitts or so ...
297        //
298        // maybe it is necessary to acknowledge receiption very early.
299        // I think there is an option in Socket mode register for this.
300        if (send_ACK)
301        {
302                //w5100_write ( S0_CR, CR_RECV );
303        }
304
305        return NumBytes;
306}
307
308// returns number of words, transmitted into TX - buffer.
309U08 w5100_set_TX(U08 NumBytes) {
310        U16 freesize = get_S0_TX_FSR();
311        if (freesize == 0)
312        {
313                return 0;
314        }
315       
316        U16 last_TX_write_pointer = get_S0_TX_WR();
317        U16 offset = last_TX_write_pointer & S0_TX_MASK;
318        U16 start_address =  S0_TX_BASE + offset;
319
320
321        U16 upper_size, lower_size;
322        if (NumBytes > ETH_WRITE_BUFFER_SIZE)
323        {
324                NumBytes = ETH_WRITE_BUFFER_SIZE;
325        }
326        if (freesize == 0)
327        {
328                return 0;
329        }
330        else if ( freesize < NumBytes )
331        {
332                NumBytes = freesize;
333        }
334
335        // now calculate the offset address
336        // calculated according to W5100 datasheet page: 44
337
338        if ((offset + NumBytes) > (S0_RX_MASK + 1) )  // if data is turned over in RX-mem
339        {
340                upper_size = (S0_RX_MASK + 1) - offset;
341                lower_size = NumBytes - upper_size;
342                for (U08 i = 0; i < upper_size; ++i)
343                {
344                        w5100_write(start_address + i, eth_write_buffer[i]);
345                }
346                for (U08 i = 0; i < lower_size; ++i)
347                {
348                        w5100_write(S0_RX_BASE + i, eth_write_buffer[upper_size+i]);
349                }
350        }
351        else // if not data turn over in RX-mem
352        {
353                for (U08 i = 0; i < NumBytes; ++i)
354                {
355                        w5100_write(start_address + i, eth_write_buffer[i]);
356                }
357        }
358
359        // inform W5100 about how much data was read out.
360        set_S0_TX_WR(last_TX_write_pointer + NumBytes);
361       
362        // tell it to send now the data away
363        w5100_write( S0_CR, CR_SEND);
364       
365        return NumBytes;
366}
367
Note: See TracBrowser for help on using the repository browser.