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

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