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

Last change on this file since 10902 was 10698, checked in by neise, 14 years ago
File size: 9.2 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{
61 // setup the SPI interface according to W5100 specs.
62 // This is needed, because AD7719 has different SPI specs.
63 spi_setup_w5100();
64
65spi_write_buffer[0]=0xF0;
66spi_write_buffer[1]=(U08)(addr>>8);
67spi_write_buffer[2]=(U08)(addr);
68spi_write_buffer[3]=data;
69
70spi_transfer_w5100(4);
71// spi_read_buffer should contain 0x00 0x01 0x02 and 0x03 ... nice check!
72}
73
74U08 w5100_read( U16 addr)
75{
76 // setup the SPI interface according to W5100 specs.
77 // This is needed, because AD7719 has different SPI specs.
78 spi_setup_w5100();
79
80spi_write_buffer[0]=0x0F;
81spi_write_buffer[1]=(U08)(addr>>8);
82spi_write_buffer[2]=(U08)(addr);
83spi_write_buffer[3]=0x00;
84
85spi_transfer_w5100(4);
86return spi_read_buffer[3];
87// spi_read_buffer should contain 0x00 0x01 0x02 and data ... nice check!
88}
89
90U08 w5100_init (void)
91{
92U08 sock0_status = 0x00;
93
94 // set FSCs MAC Address to value defined in w5100_spi_interface.h
95 w5100_write( CM_SHAR0, FSC_MAC_ADDRESS0 );
96 w5100_write( CM_SHAR1, FSC_MAC_ADDRESS1 );
97 w5100_write( CM_SHAR2, FSC_MAC_ADDRESS2 );
98 w5100_write( CM_SHAR3, FSC_MAC_ADDRESS3 );
99 w5100_write( CM_SHAR4, FSC_MAC_ADDRESS4 );
100 w5100_write( CM_SHAR5, FSC_MAC_ADDRESS5 );
101
102 //set IP
103 w5100_write( CM_SIPR0, FSC_IP_ADDRESS0 );
104 w5100_write( CM_SIPR1, FSC_IP_ADDRESS1 );
105 w5100_write( CM_SIPR2, FSC_IP_ADDRESS2 );
106 w5100_write( CM_SIPR3, FSC_IP_ADDRESS3 );
107
108 // set subnet mask
109 w5100_write( CM_SUBR0, FSC_SUBNET_MASK0 );
110 w5100_write( CM_SUBR1, FSC_SUBNET_MASK1 );
111 w5100_write( CM_SUBR2, FSC_SUBNET_MASK2 );
112 w5100_write( CM_SUBR3, FSC_SUBNET_MASK3 );
113
114 // set IP of Gateway used by FSC
115 w5100_write( CM_GAR0, FSC_GATEWAY_ADDRESS0 );
116 w5100_write( CM_GAR1, FSC_GATEWAY_ADDRESS1 );
117 w5100_write( CM_GAR2, FSC_GATEWAY_ADDRESS2 );
118 w5100_write( CM_GAR3, FSC_GATEWAY_ADDRESS3 );
119
120 //set socket read and write fifo sizes
121 w5100_write( CM_RMSR, 0x0A); // --> 4k for socket 0 and 1
122 w5100_write( CM_TMSR, 0x0A); // --> 4k for socket 0 and 1
123
124
125 w5100_write ( S0_MR, 0x01); // set Socket 0 as TCP
126 w5100_write ( S0_PORT0, 0x13 ); // Port 5000 -> 0x1388
127 w5100_write ( S0_PORT1, 0x88 );
128 w5100_write ( S0_CR, CR_OPEN ); // issue Socket open command
129 while (sock0_status != SR_SOCK_INIT) {
130 sock0_status = w5100_read(S0_SR); // request socket 0 status
131 }
132
133 w5100_write ( S0_CR, CR_LISTEN ); // issue Socket listen command
134 while (sock0_status != SR_SOCK_LISTEN) {
135 sock0_status = w5100_read(S0_SR); // request socket 0 status
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 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.
301U16 w5100_set_TX(U08* string, U16 NumBytes) {
302
303 U16 freesize = get_S0_TX_FSR();
304 if (freesize == 0)
305 {
306 return 0;
307 }
308 usart_write_str((U08*)"sending via eth: with pointer:");
309 usart_write_U16_hex(string);
310 usart_write_str((U08*)" #of bytes: ");
311 usart_write_U16(NumBytes,4 );
312 usart_write_char(' \n');
313
314 U16 last_TX_write_pointer = get_S0_TX_WR();
315 U16 offset = last_TX_write_pointer & S0_TX_MASK;
316 U16 start_address = S0_TX_BASE + offset;
317
318
319 U16 upper_size, lower_size;
320 /*
321 if (NumBytes > ETH_WRITE_BUFFER_SIZE)
322 {
323 NumBytes = ETH_WRITE_BUFFER_SIZE;
324 }
325 if (freesize == 0)
326 {
327 return 0;
328 }
329 else */
330 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, string[i]);
345 }
346 for (U08 i = 0; i < lower_size; ++i)
347 {
348 w5100_write(S0_RX_BASE + i, string[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, string[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.