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

Last change on this file since 20115 was 18182, checked in by dneise, 10 years ago
fixing communication bug and getting rid of compiler warning, and removing unneded repeated reading
File size: 11.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
175// Contains Socket free size in bytes
176U16 get_S0_TX_FSR() {
177 U16 freesize;
178 freesize=w5100_read(S0_TX_FSR0); // datasheet: user should read upper byte first, and lower byte later
179 freesize = freesize << 8; // to get correct value
180 freesize += w5100_read(S0_TX_FSR1);
181 return 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 bytes, transmitted into TX - buffer.
346U16 w5100_set_TX(volatile U08* string, U16 NumBytes) {
347
348 U16 freesize;
349 U16 last_TX_write_pointer;
350
351 freesize = get_S0_TX_FSR();
352 if (freesize == 0) {
353 return 0;
354 }
355
356 last_TX_write_pointer = get_S0_TX_WR();
357
358 U16 offset = last_TX_write_pointer & S0_TX_MASK;
359 U16 start_address = S0_TX_BASE + offset;
360 U16 upper_size;
361 U16 lower_size;
362 if ( freesize < NumBytes ) {
363 NumBytes = freesize;
364 }
365
366 // now calculate the offset address
367 // calculated according to W5100 datasheet page: 44
368 if ((offset + NumBytes) > (S0_RX_MASK + 1) ) { // if data is turned over in RX-mem
369 upper_size = (S0_RX_MASK + 1) - offset;
370 lower_size = NumBytes - upper_size;
371 for (U16 i = 0; i < upper_size; ++i) {
372 w5100_write(start_address + i, string[i]);
373 }
374 for (U16 i = 0; i < lower_size; ++i) {
375 w5100_write(S0_TX_BASE + i, string[upper_size+i]);
376 }
377 }
378 else { // if not data turn over in RX-mem
379 for (U16 i = 0; i < NumBytes; ++i) {
380 w5100_write(start_address + i, string[i]);
381 }
382 }
383
384 // inform W5100 about how much data was written.
385 U16 new_write_pointer = last_TX_write_pointer + NumBytes;
386 set_S0_TX_WR(new_write_pointer);
387
388 // tell it to send now the data away
389 w5100_write( S0_CR, CR_SEND);
390 return NumBytes;
391}
392
393void eth_write_str( U08* str ){
394
395 while (*str) {
396 if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
397 eth_write_buffer[eth_write_index++] = *str++;
398 }
399
400 }
401 w5100_set_TX(eth_write_buffer, eth_write_index);
402 eth_write_index = 0;
403}
404
405void eth_writeln_str( U08* str ){
406
407 while (*str)
408 {
409 if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
410 eth_write_buffer[eth_write_index++] = *str++;
411 }
412 }
413 if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
414 eth_write_buffer[eth_write_index++] = '\n';
415 }
416 w5100_set_TX(eth_write_buffer, eth_write_index);
417 eth_write_index = 0;
418}
419
420void eth_write_lf(void) {
421 if (eth_write_index < ETH_WRITE_BUFFER_SIZE) {
422 eth_write_buffer[eth_write_index++] = '\n';
423 }
424 w5100_set_TX(eth_write_buffer, eth_write_index);
425 eth_write_index = 0;
426}
Note: See TracBrowser for help on using the repository browser.