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

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