root / arduino-1.0 / libraries / Ethernet / utility / w5100.h @ 58d82c77
History | View | Annotate | Download (13.6 KB)
1 |
/*
|
---|---|
2 |
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
|
3 |
*
|
4 |
* This file is free software; you can redistribute it and/or modify
|
5 |
* it under the terms of either the GNU General Public License version 2
|
6 |
* or the GNU Lesser General Public License version 2.1, both as
|
7 |
* published by the Free Software Foundation.
|
8 |
*/
|
9 |
|
10 |
#ifndef W5100_H_INCLUDED
|
11 |
#define W5100_H_INCLUDED
|
12 |
|
13 |
#include <avr/pgmspace.h> |
14 |
#include <SPI.h> |
15 |
|
16 |
#define MAX_SOCK_NUM 4 |
17 |
|
18 |
typedef uint8_t SOCKET;
|
19 |
|
20 |
#define IDM_OR 0x8000 |
21 |
#define IDM_AR0 0x8001 |
22 |
#define IDM_AR1 0x8002 |
23 |
#define IDM_DR 0x8003 |
24 |
/*
|
25 |
class MR {
|
26 |
public:
|
27 |
static const uint8_t RST = 0x80;
|
28 |
static const uint8_t PB = 0x10;
|
29 |
static const uint8_t PPPOE = 0x08;
|
30 |
static const uint8_t LB = 0x04;
|
31 |
static const uint8_t AI = 0x02;
|
32 |
static const uint8_t IND = 0x01;
|
33 |
};
|
34 |
*/
|
35 |
/*
|
36 |
class IR {
|
37 |
public:
|
38 |
static const uint8_t CONFLICT = 0x80;
|
39 |
static const uint8_t UNREACH = 0x40;
|
40 |
static const uint8_t PPPoE = 0x20;
|
41 |
static const uint8_t SOCK0 = 0x01;
|
42 |
static const uint8_t SOCK1 = 0x02;
|
43 |
static const uint8_t SOCK2 = 0x04;
|
44 |
static const uint8_t SOCK3 = 0x08;
|
45 |
static inline uint8_t SOCK(SOCKET ch) { return (0x01 << ch); };
|
46 |
};
|
47 |
*/
|
48 |
|
49 |
class SnMR { |
50 |
public:
|
51 |
static const uint8_t CLOSE = 0x00; |
52 |
static const uint8_t TCP = 0x01; |
53 |
static const uint8_t UDP = 0x02; |
54 |
static const uint8_t IPRAW = 0x03; |
55 |
static const uint8_t MACRAW = 0x04; |
56 |
static const uint8_t PPPOE = 0x05; |
57 |
static const uint8_t ND = 0x20; |
58 |
static const uint8_t MULTI = 0x80; |
59 |
}; |
60 |
|
61 |
enum SockCMD {
|
62 |
Sock_OPEN = 0x01,
|
63 |
Sock_LISTEN = 0x02,
|
64 |
Sock_CONNECT = 0x04,
|
65 |
Sock_DISCON = 0x08,
|
66 |
Sock_CLOSE = 0x10,
|
67 |
Sock_SEND = 0x20,
|
68 |
Sock_SEND_MAC = 0x21,
|
69 |
Sock_SEND_KEEP = 0x22,
|
70 |
Sock_RECV = 0x40
|
71 |
}; |
72 |
|
73 |
/*class SnCmd {
|
74 |
public:
|
75 |
static const uint8_t OPEN = 0x01;
|
76 |
static const uint8_t LISTEN = 0x02;
|
77 |
static const uint8_t CONNECT = 0x04;
|
78 |
static const uint8_t DISCON = 0x08;
|
79 |
static const uint8_t CLOSE = 0x10;
|
80 |
static const uint8_t SEND = 0x20;
|
81 |
static const uint8_t SEND_MAC = 0x21;
|
82 |
static const uint8_t SEND_KEEP = 0x22;
|
83 |
static const uint8_t RECV = 0x40;
|
84 |
};
|
85 |
*/
|
86 |
|
87 |
class SnIR { |
88 |
public:
|
89 |
static const uint8_t SEND_OK = 0x10; |
90 |
static const uint8_t TIMEOUT = 0x08; |
91 |
static const uint8_t RECV = 0x04; |
92 |
static const uint8_t DISCON = 0x02; |
93 |
static const uint8_t CON = 0x01; |
94 |
}; |
95 |
|
96 |
class SnSR { |
97 |
public:
|
98 |
static const uint8_t CLOSED = 0x00; |
99 |
static const uint8_t INIT = 0x13; |
100 |
static const uint8_t LISTEN = 0x14; |
101 |
static const uint8_t SYNSENT = 0x15; |
102 |
static const uint8_t SYNRECV = 0x16; |
103 |
static const uint8_t ESTABLISHED = 0x17; |
104 |
static const uint8_t FIN_WAIT = 0x18; |
105 |
static const uint8_t CLOSING = 0x1A; |
106 |
static const uint8_t TIME_WAIT = 0x1B; |
107 |
static const uint8_t CLOSE_WAIT = 0x1C; |
108 |
static const uint8_t LAST_ACK = 0x1D; |
109 |
static const uint8_t UDP = 0x22; |
110 |
static const uint8_t IPRAW = 0x32; |
111 |
static const uint8_t MACRAW = 0x42; |
112 |
static const uint8_t PPPOE = 0x5F; |
113 |
}; |
114 |
|
115 |
class IPPROTO { |
116 |
public:
|
117 |
static const uint8_t IP = 0; |
118 |
static const uint8_t ICMP = 1; |
119 |
static const uint8_t IGMP = 2; |
120 |
static const uint8_t GGP = 3; |
121 |
static const uint8_t TCP = 6; |
122 |
static const uint8_t PUP = 12; |
123 |
static const uint8_t UDP = 17; |
124 |
static const uint8_t IDP = 22; |
125 |
static const uint8_t ND = 77; |
126 |
static const uint8_t RAW = 255; |
127 |
}; |
128 |
|
129 |
class W5100Class { |
130 |
|
131 |
public:
|
132 |
void init();
|
133 |
|
134 |
/**
|
135 |
* @brief This function is being used for copy the data form Receive buffer of the chip to application buffer.
|
136 |
*
|
137 |
* It calculate the actual physical address where one has to read
|
138 |
* the data from Receive buffer. Here also take care of the condition while it exceed
|
139 |
* the Rx memory uper-bound of socket.
|
140 |
*/
|
141 |
void read_data(SOCKET s, volatile uint8_t * src, volatile uint8_t * dst, uint16_t len); |
142 |
|
143 |
/**
|
144 |
* @brief This function is being called by send() and sendto() function also.
|
145 |
*
|
146 |
* This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
|
147 |
* register. User should read upper byte first and lower byte later to get proper value.
|
148 |
*/
|
149 |
void send_data_processing(SOCKET s, const uint8_t *data, uint16_t len); |
150 |
/**
|
151 |
* @brief A copy of send_data_processing that uses the provided ptr for the
|
152 |
* write offset. Only needed for the "streaming" UDP API, where
|
153 |
* a single UDP packet is built up over a number of calls to
|
154 |
* send_data_processing_ptr, because TX_WR doesn't seem to get updated
|
155 |
* correctly in those scenarios
|
156 |
* @param ptr value to use in place of TX_WR. If 0, then the value is read
|
157 |
* in from TX_WR
|
158 |
* @return New value for ptr, to be used in the next call
|
159 |
*/
|
160 |
// FIXME Update documentation
|
161 |
void send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len); |
162 |
|
163 |
/**
|
164 |
* @brief This function is being called by recv() also.
|
165 |
*
|
166 |
* This function read the Rx read pointer register
|
167 |
* and after copy the data from receive buffer update the Rx write pointer register.
|
168 |
* User should read upper byte first and lower byte later to get proper value.
|
169 |
*/
|
170 |
void recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek = 0); |
171 |
|
172 |
inline void setGatewayIp(uint8_t *_addr); |
173 |
inline void getGatewayIp(uint8_t *_addr); |
174 |
|
175 |
inline void setSubnetMask(uint8_t *_addr); |
176 |
inline void getSubnetMask(uint8_t *_addr); |
177 |
|
178 |
inline void setMACAddress(uint8_t * addr); |
179 |
inline void getMACAddress(uint8_t * addr); |
180 |
|
181 |
inline void setIPAddress(uint8_t * addr); |
182 |
inline void getIPAddress(uint8_t * addr); |
183 |
|
184 |
inline void setRetransmissionTime(uint16_t timeout); |
185 |
inline void setRetransmissionCount(uint8_t _retry); |
186 |
|
187 |
void execCmdSn(SOCKET s, SockCMD _cmd);
|
188 |
|
189 |
uint16_t getTXFreeSize(SOCKET s); |
190 |
uint16_t getRXReceivedSize(SOCKET s); |
191 |
|
192 |
|
193 |
// W5100 Registers
|
194 |
// ---------------
|
195 |
private:
|
196 |
static uint8_t write(uint16_t _addr, uint8_t _data);
|
197 |
static uint16_t write(uint16_t addr, const uint8_t *buf, uint16_t len); |
198 |
static uint8_t read(uint16_t addr);
|
199 |
static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len);
|
200 |
|
201 |
#define __GP_REGISTER8(name, address) \
|
202 |
static inline void write##name(uint8_t _data) { \ |
203 |
write(address, _data); \ |
204 |
} \ |
205 |
static inline uint8_t read##name() { \ |
206 |
return read(address); \
|
207 |
} |
208 |
#define __GP_REGISTER16(name, address) \
|
209 |
static void write##name(uint16_t _data) { \ |
210 |
write(address, _data >> 8); \
|
211 |
write(address+1, _data & 0xFF); \ |
212 |
} \ |
213 |
static uint16_t read##name() { \ |
214 |
uint16_t res = read(address); \ |
215 |
res = (res << 8) + read(address + 1); \ |
216 |
return res; \
|
217 |
} |
218 |
#define __GP_REGISTER_N(name, address, size) \
|
219 |
static uint16_t write##name(uint8_t *_buff) { \ |
220 |
return write(address, _buff, size); \
|
221 |
} \ |
222 |
static uint16_t read##name(uint8_t *_buff) { \ |
223 |
return read(address, _buff, size); \
|
224 |
} |
225 |
|
226 |
public: |
227 |
__GP_REGISTER8 (MR, 0x0000); // Mode |
228 |
__GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address |
229 |
__GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address |
230 |
__GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address |
231 |
__GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address |
232 |
__GP_REGISTER8 (IR, 0x0015); // Interrupt |
233 |
__GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask |
234 |
__GP_REGISTER16(RTR, 0x0017); // Timeout address |
235 |
__GP_REGISTER8 (RCR, 0x0019); // Retry count |
236 |
__GP_REGISTER8 (RMSR, 0x001A); // Receive memory size |
237 |
__GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size |
238 |
__GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode |
239 |
__GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer |
240 |
__GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number |
241 |
__GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode |
242 |
__GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode |
243 |
|
244 |
#undef __GP_REGISTER8
|
245 |
#undef __GP_REGISTER16
|
246 |
#undef __GP_REGISTER_N
|
247 |
|
248 |
// W5100 Socket registers
|
249 |
// ----------------------
|
250 |
private:
|
251 |
static inline uint8_t readSn(SOCKET _s, uint16_t _addr); |
252 |
static inline uint8_t writeSn(SOCKET _s, uint16_t _addr, uint8_t _data); |
253 |
static inline uint16_t readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len); |
254 |
static inline uint16_t writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len); |
255 |
|
256 |
static const uint16_t CH_BASE = 0x0400; |
257 |
static const uint16_t CH_SIZE = 0x0100; |
258 |
|
259 |
#define __SOCKET_REGISTER8(name, address) \
|
260 |
static inline void write##name(SOCKET _s, uint8_t _data) { \ |
261 |
writeSn(_s, address, _data); \ |
262 |
} \ |
263 |
static inline uint8_t read##name(SOCKET _s) { \ |
264 |
return readSn(_s, address); \
|
265 |
} |
266 |
#define __SOCKET_REGISTER16(name, address) \
|
267 |
static void write##name(SOCKET _s, uint16_t _data) { \ |
268 |
writeSn(_s, address, _data >> 8); \
|
269 |
writeSn(_s, address+1, _data & 0xFF); \ |
270 |
} \ |
271 |
static uint16_t read##name(SOCKET _s) { \ |
272 |
uint16_t res = readSn(_s, address); \ |
273 |
res = (res << 8) + readSn(_s, address + 1); \ |
274 |
return res; \
|
275 |
} |
276 |
#define __SOCKET_REGISTER_N(name, address, size) \
|
277 |
static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \ |
278 |
return writeSn(_s, address, _buff, size); \
|
279 |
} \ |
280 |
static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \ |
281 |
return readSn(_s, address, _buff, size); \
|
282 |
} |
283 |
|
284 |
public: |
285 |
__SOCKET_REGISTER8(SnMR, 0x0000) // Mode |
286 |
__SOCKET_REGISTER8(SnCR, 0x0001) // Command |
287 |
__SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt |
288 |
__SOCKET_REGISTER8(SnSR, 0x0003) // Status |
289 |
__SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port |
290 |
__SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr |
291 |
__SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr |
292 |
__SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port |
293 |
__SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size |
294 |
__SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode |
295 |
__SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS |
296 |
__SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL |
297 |
__SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size |
298 |
__SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer |
299 |
__SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer |
300 |
__SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size |
301 |
__SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer |
302 |
__SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?) |
303 |
|
304 |
#undef __SOCKET_REGISTER8
|
305 |
#undef __SOCKET_REGISTER16
|
306 |
#undef __SOCKET_REGISTER_N
|
307 |
|
308 |
|
309 |
private: |
310 |
static const uint8_t RST = 7; // Reset BIT |
311 |
|
312 |
static const int SOCKETS = 4; |
313 |
static const uint16_t SMASK = 0x07FF; // Tx buffer MASK |
314 |
static const uint16_t RMASK = 0x07FF; // Rx buffer MASK |
315 |
public:
|
316 |
static const uint16_t SSIZE = 2048; // Max Tx buffer size |
317 |
private:
|
318 |
static const uint16_t RSIZE = 2048; // Max Rx buffer size |
319 |
uint16_t SBASE[SOCKETS]; // Tx buffer base address
|
320 |
uint16_t RBASE[SOCKETS]; // Rx buffer base address
|
321 |
|
322 |
private:
|
323 |
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
324 |
inline static void initSS() { DDRB |= _BV(4); }; |
325 |
inline static void setSS() { PORTB &= ~_BV(4); }; |
326 |
inline static void resetSS() { PORTB |= _BV(4); }; |
327 |
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__)
|
328 |
inline static void initSS() { DDRB |= _BV(0); }; |
329 |
inline static void setSS() { PORTB &= ~_BV(0); }; |
330 |
inline static void resetSS() { PORTB |= _BV(0); }; |
331 |
#else
|
332 |
inline static void initSS() { DDRB |= _BV(2); }; |
333 |
inline static void setSS() { PORTB &= ~_BV(2); }; |
334 |
inline static void resetSS() { PORTB |= _BV(2); }; |
335 |
#endif
|
336 |
|
337 |
}; |
338 |
|
339 |
extern W5100Class W5100;
|
340 |
|
341 |
uint8_t W5100Class::readSn(SOCKET _s, uint16_t _addr) { |
342 |
return read(CH_BASE + _s * CH_SIZE + _addr);
|
343 |
} |
344 |
|
345 |
uint8_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) { |
346 |
return write(CH_BASE + _s * CH_SIZE + _addr, _data);
|
347 |
} |
348 |
|
349 |
uint16_t W5100Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { |
350 |
return read(CH_BASE + _s * CH_SIZE + _addr, _buf, _len);
|
351 |
} |
352 |
|
353 |
uint16_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { |
354 |
return write(CH_BASE + _s * CH_SIZE + _addr, _buf, _len);
|
355 |
} |
356 |
|
357 |
void W5100Class::getGatewayIp(uint8_t *_addr) {
|
358 |
readGAR(_addr); |
359 |
} |
360 |
|
361 |
void W5100Class::setGatewayIp(uint8_t *_addr) {
|
362 |
writeGAR(_addr); |
363 |
} |
364 |
|
365 |
void W5100Class::getSubnetMask(uint8_t *_addr) {
|
366 |
readSUBR(_addr); |
367 |
} |
368 |
|
369 |
void W5100Class::setSubnetMask(uint8_t *_addr) {
|
370 |
writeSUBR(_addr); |
371 |
} |
372 |
|
373 |
void W5100Class::getMACAddress(uint8_t *_addr) {
|
374 |
readSHAR(_addr); |
375 |
} |
376 |
|
377 |
void W5100Class::setMACAddress(uint8_t *_addr) {
|
378 |
writeSHAR(_addr); |
379 |
} |
380 |
|
381 |
void W5100Class::getIPAddress(uint8_t *_addr) {
|
382 |
readSIPR(_addr); |
383 |
} |
384 |
|
385 |
void W5100Class::setIPAddress(uint8_t *_addr) {
|
386 |
writeSIPR(_addr); |
387 |
} |
388 |
|
389 |
void W5100Class::setRetransmissionTime(uint16_t _timeout) {
|
390 |
writeRTR(_timeout); |
391 |
} |
392 |
|
393 |
void W5100Class::setRetransmissionCount(uint8_t _retry) {
|
394 |
writeRCR(_retry); |
395 |
} |
396 |
|
397 |
#endif
|