source: firmware/FSC/usb_src/w5100_spi_interface.c@ 17038

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