D:/DRISSI/arduino-0022/arduino-0022/libraries/Ethernet/utility/w5100.h
00001 /*
00002  * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
00003  *
00004  * This file is free software; you can redistribute it and/or modify
00005  * it under the terms of either the GNU General Public License version 2
00006  * or the GNU Lesser General Public License version 2.1, both as
00007  * published by the Free Software Foundation.
00008  */
00009 
00010 #ifndef W5100_H_INCLUDED
00011 #define W5100_H_INCLUDED
00012 
00013 #include <avr/pgmspace.h>
00014 #include <SPI.h>
00015 
00016 #define MAX_SOCK_NUM 4
00017 
00018 typedef uint8_t SOCKET;
00019 
00020 #define IDM_OR  0x8000
00021 #define IDM_AR0 0x8001
00022 #define IDM_AR1 0x8002
00023 #define IDM_DR  0x8003
00024 /*
00025 class MR {
00026 public:
00027   static const uint8_t RST   = 0x80;
00028   static const uint8_t PB    = 0x10;
00029   static const uint8_t PPPOE = 0x08;
00030   static const uint8_t LB    = 0x04;
00031   static const uint8_t AI    = 0x02;
00032   static const uint8_t IND   = 0x01;
00033 };
00034 */
00035 /*
00036 class IR {
00037 public:
00038   static const uint8_t CONFLICT = 0x80;
00039   static const uint8_t UNREACH  = 0x40;
00040   static const uint8_t PPPoE    = 0x20;
00041   static const uint8_t SOCK0    = 0x01;
00042   static const uint8_t SOCK1    = 0x02;
00043   static const uint8_t SOCK2    = 0x04;
00044   static const uint8_t SOCK3    = 0x08;
00045   static inline uint8_t SOCK(SOCKET ch) { return (0x01 << ch); };
00046 };
00047 */
00048 
00049 class SnMR {
00050 public:
00051   static const uint8_t CLOSE  = 0x00;
00052   static const uint8_t TCP    = 0x01;
00053   static const uint8_t UDP    = 0x02;
00054   static const uint8_t IPRAW  = 0x03;
00055   static const uint8_t MACRAW = 0x04;
00056   static const uint8_t PPPOE  = 0x05;
00057   static const uint8_t ND     = 0x20;
00058   static const uint8_t MULTI  = 0x80;
00059 };
00060 
00061 enum SockCMD {
00062   Sock_OPEN      = 0x01,
00063   Sock_LISTEN    = 0x02,
00064   Sock_CONNECT   = 0x04,
00065   Sock_DISCON    = 0x08,
00066   Sock_CLOSE     = 0x10,
00067   Sock_SEND      = 0x20,
00068   Sock_SEND_MAC  = 0x21,
00069   Sock_SEND_KEEP = 0x22,
00070   Sock_RECV      = 0x40
00071 };
00072 
00073 /*class SnCmd {
00074 public:
00075   static const uint8_t OPEN      = 0x01;
00076   static const uint8_t LISTEN    = 0x02;
00077   static const uint8_t CONNECT   = 0x04;
00078   static const uint8_t DISCON    = 0x08;
00079   static const uint8_t CLOSE     = 0x10;
00080   static const uint8_t SEND      = 0x20;
00081   static const uint8_t SEND_MAC  = 0x21;
00082   static const uint8_t SEND_KEEP = 0x22;
00083   static const uint8_t RECV      = 0x40;
00084 };
00085 */
00086 
00087 class SnIR {
00088 public:
00089   static const uint8_t SEND_OK = 0x10;
00090   static const uint8_t TIMEOUT = 0x08;
00091   static const uint8_t RECV    = 0x04;
00092   static const uint8_t DISCON  = 0x02;
00093   static const uint8_t CON     = 0x01;
00094 };
00095 
00096 class SnSR {
00097 public:
00098   static const uint8_t CLOSED      = 0x00;
00099   static const uint8_t INIT        = 0x13;
00100   static const uint8_t LISTEN      = 0x14;
00101   static const uint8_t SYNSENT     = 0x15;
00102   static const uint8_t SYNRECV     = 0x16;
00103   static const uint8_t ESTABLISHED = 0x17;
00104   static const uint8_t FIN_WAIT    = 0x18;
00105   static const uint8_t CLOSING     = 0x1A;
00106   static const uint8_t TIME_WAIT   = 0x1B;
00107   static const uint8_t CLOSE_WAIT  = 0x1C;
00108   static const uint8_t LAST_ACK    = 0x1D;
00109   static const uint8_t UDP         = 0x22;
00110   static const uint8_t IPRAW       = 0x32;
00111   static const uint8_t MACRAW      = 0x42;
00112   static const uint8_t PPPOE       = 0x5F;
00113 };
00114 
00115 class IPPROTO {
00116 public:
00117   static const uint8_t IP   = 0;
00118   static const uint8_t ICMP = 1;
00119   static const uint8_t IGMP = 2;
00120   static const uint8_t GGP  = 3;
00121   static const uint8_t TCP  = 6;
00122   static const uint8_t PUP  = 12;
00123   static const uint8_t UDP  = 17;
00124   static const uint8_t IDP  = 22;
00125   static const uint8_t ND   = 77;
00126   static const uint8_t RAW  = 255;
00127 };
00128 
00129 class W5100Class {
00130 
00131 public:
00132   void init();
00133 
00141   void read_data(SOCKET s, volatile uint8_t * src, volatile uint8_t * dst, uint16_t len);
00142   
00149   void send_data_processing(SOCKET s, uint8_t *data, uint16_t len);
00150 
00158   void recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek = 0);
00159 
00160   inline void setGatewayIp(uint8_t *_addr);
00161   inline void getGatewayIp(uint8_t *_addr);
00162 
00163   inline void setSubnetMask(uint8_t *_addr);
00164   inline void getSubnetMask(uint8_t *_addr);
00165 
00166   inline void setMACAddress(uint8_t * addr);
00167   inline void getMACAddress(uint8_t * addr);
00168 
00169   inline void setIPAddress(uint8_t * addr);
00170   inline void getIPAddress(uint8_t * addr);
00171 
00172   inline void setRetransmissionTime(uint16_t timeout);
00173   inline void setRetransmissionCount(uint8_t _retry);
00174 
00175   void execCmdSn(SOCKET s, SockCMD _cmd);
00176   
00177   uint16_t getTXFreeSize(SOCKET s);
00178   uint16_t getRXReceivedSize(SOCKET s);
00179   
00180 
00181   // W5100 Registers
00182   // ---------------
00183 private:
00184   static uint8_t write(uint16_t _addr, uint8_t _data);
00185   static uint16_t write(uint16_t addr, uint8_t *buf, uint16_t len);
00186   static uint8_t read(uint16_t addr);
00187   static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len);
00188   
00189 #define __GP_REGISTER8(name, address)             \
00190   static inline void write##name(uint8_t _data) { \
00191     write(address, _data);                        \
00192   }                                               \
00193   static inline uint8_t read##name() {            \
00194     return read(address);                         \
00195   }
00196 #define __GP_REGISTER16(name, address)            \
00197   static void write##name(uint16_t _data) {       \
00198     write(address,   _data >> 8);                 \
00199     write(address+1, _data & 0xFF);               \
00200   }                                               \
00201   static uint16_t read##name() {                  \
00202     uint16_t res = read(address);                 \
00203     res = (res << 8) + read(address + 1);         \
00204     return res;                                   \
00205   }
00206 #define __GP_REGISTER_N(name, address, size)      \
00207   static uint16_t write##name(uint8_t *_buff) {   \
00208     return write(address, _buff, size);           \
00209   }                                               \
00210   static uint16_t read##name(uint8_t *_buff) {    \
00211     return read(address, _buff, size);            \
00212   }
00213 
00214 public:
00215   __GP_REGISTER8 (MR,     0x0000);    // Mode
00216   __GP_REGISTER_N(GAR,    0x0001, 4); // Gateway IP address
00217   __GP_REGISTER_N(SUBR,   0x0005, 4); // Subnet mask address
00218   __GP_REGISTER_N(SHAR,   0x0009, 6); // Source MAC address
00219   __GP_REGISTER_N(SIPR,   0x000F, 4); // Source IP address
00220   __GP_REGISTER8 (IR,     0x0015);    // Interrupt
00221   __GP_REGISTER8 (IMR,    0x0016);    // Interrupt Mask
00222   __GP_REGISTER16(RTR,    0x0017);    // Timeout address
00223   __GP_REGISTER8 (RCR,    0x0019);    // Retry count
00224   __GP_REGISTER8 (RMSR,   0x001A);    // Receive memory size
00225   __GP_REGISTER8 (TMSR,   0x001B);    // Transmit memory size
00226   __GP_REGISTER8 (PATR,   0x001C);    // Authentication type address in PPPoE mode
00227   __GP_REGISTER8 (PTIMER, 0x0028);    // PPP LCP Request Timer
00228   __GP_REGISTER8 (PMAGIC, 0x0029);    // PPP LCP Magic Number
00229   __GP_REGISTER_N(UIPR,   0x002A, 4); // Unreachable IP address in UDP mode
00230   __GP_REGISTER16(UPORT,  0x002E);    // Unreachable Port address in UDP mode
00231   
00232 #undef __GP_REGISTER8
00233 #undef __GP_REGISTER16
00234 #undef __GP_REGISTER_N
00235 
00236   // W5100 Socket registers
00237   // ----------------------
00238 private:
00239   static inline uint8_t readSn(SOCKET _s, uint16_t _addr);
00240   static inline uint8_t writeSn(SOCKET _s, uint16_t _addr, uint8_t _data);
00241   static inline uint16_t readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
00242   static inline uint16_t writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
00243 
00244   static const uint16_t CH_BASE = 0x0400;
00245   static const uint16_t CH_SIZE = 0x0100;
00246 
00247 #define __SOCKET_REGISTER8(name, address)                    \
00248   static inline void write##name(SOCKET _s, uint8_t _data) { \
00249     writeSn(_s, address, _data);                             \
00250   }                                                          \
00251   static inline uint8_t read##name(SOCKET _s) {              \
00252     return readSn(_s, address);                              \
00253   }
00254 #define __SOCKET_REGISTER16(name, address)                   \
00255   static void write##name(SOCKET _s, uint16_t _data) {       \
00256     writeSn(_s, address,   _data >> 8);                      \
00257     writeSn(_s, address+1, _data & 0xFF);                    \
00258   }                                                          \
00259   static uint16_t read##name(SOCKET _s) {                    \
00260     uint16_t res = readSn(_s, address);                      \
00261     res = (res << 8) + readSn(_s, address + 1);              \
00262     return res;                                              \
00263   }
00264 #define __SOCKET_REGISTER_N(name, address, size)             \
00265   static uint16_t write##name(SOCKET _s, uint8_t *_buff) {   \
00266     return writeSn(_s, address, _buff, size);                \
00267   }                                                          \
00268   static uint16_t read##name(SOCKET _s, uint8_t *_buff) {    \
00269     return readSn(_s, address, _buff, size);                 \
00270   }
00271   
00272 public:
00273   __SOCKET_REGISTER8(SnMR,        0x0000)        // Mode
00274   __SOCKET_REGISTER8(SnCR,        0x0001)        // Command
00275   __SOCKET_REGISTER8(SnIR,        0x0002)        // Interrupt
00276   __SOCKET_REGISTER8(SnSR,        0x0003)        // Status
00277   __SOCKET_REGISTER16(SnPORT,     0x0004)        // Source Port
00278   __SOCKET_REGISTER_N(SnDHAR,     0x0006, 6)     // Destination Hardw Addr
00279   __SOCKET_REGISTER_N(SnDIPR,     0x000C, 4)     // Destination IP Addr
00280   __SOCKET_REGISTER16(SnDPORT,    0x0010)        // Destination Port
00281   __SOCKET_REGISTER16(SnMSSR,     0x0012)        // Max Segment Size
00282   __SOCKET_REGISTER8(SnPROTO,     0x0014)        // Protocol in IP RAW Mode
00283   __SOCKET_REGISTER8(SnTOS,       0x0015)        // IP TOS
00284   __SOCKET_REGISTER8(SnTTL,       0x0016)        // IP TTL
00285   __SOCKET_REGISTER16(SnTX_FSR,   0x0020)        // TX Free Size
00286   __SOCKET_REGISTER16(SnTX_RD,    0x0022)        // TX Read Pointer
00287   __SOCKET_REGISTER16(SnTX_WR,    0x0024)        // TX Write Pointer
00288   __SOCKET_REGISTER16(SnRX_RSR,   0x0026)        // RX Free Size
00289   __SOCKET_REGISTER16(SnRX_RD,    0x0028)        // RX Read Pointer
00290   __SOCKET_REGISTER16(SnRX_WR,    0x002A)        // RX Write Pointer (supported?)
00291   
00292 #undef __SOCKET_REGISTER8
00293 #undef __SOCKET_REGISTER16
00294 #undef __SOCKET_REGISTER_N
00295 
00296 
00297 private:
00298   static const uint8_t  RST = 7; // Reset BIT
00299 
00300   static const int SOCKETS = 4;
00301   static const uint16_t SMASK = 0x07FF; // Tx buffer MASK
00302   static const uint16_t RMASK = 0x07FF; // Rx buffer MASK
00303 public:
00304   static const uint16_t SSIZE = 2048; // Max Tx buffer size
00305 private:
00306   static const uint16_t RSIZE = 2048; // Max Rx buffer size
00307   uint16_t SBASE[SOCKETS]; // Tx buffer base address
00308   uint16_t RBASE[SOCKETS]; // Rx buffer base address
00309 
00310 private:
00311 #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
00312   inline static void initSS()    { DDRB  |=  _BV(4); };
00313   inline static void setSS()     { PORTB &= ~_BV(4); };
00314   inline static void resetSS()   { PORTB |=  _BV(4); };
00315 #else
00316   inline static void initSS()    { DDRB  |=  _BV(2); };
00317   inline static void setSS()     { PORTB &= ~_BV(2); };
00318   inline static void resetSS()   { PORTB |=  _BV(2); };
00319 #endif
00320 
00321 };
00322 
00323 extern W5100Class W5100;
00324 
00325 uint8_t W5100Class::readSn(SOCKET _s, uint16_t _addr) {
00326   return read(CH_BASE + _s * CH_SIZE + _addr);
00327 }
00328 
00329 uint8_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) {
00330   return write(CH_BASE + _s * CH_SIZE + _addr, _data);
00331 }
00332 
00333 uint16_t W5100Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
00334   return read(CH_BASE + _s * CH_SIZE + _addr, _buf, _len);
00335 }
00336 
00337 uint16_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
00338   return write(CH_BASE + _s * CH_SIZE + _addr, _buf, _len);
00339 }
00340 
00341 void W5100Class::getGatewayIp(uint8_t *_addr) {
00342   readGAR(_addr);
00343 }
00344 
00345 void W5100Class::setGatewayIp(uint8_t *_addr) {
00346   writeGAR(_addr);
00347 }
00348 
00349 void W5100Class::getSubnetMask(uint8_t *_addr) {
00350   readSUBR(_addr);
00351 }
00352 
00353 void W5100Class::setSubnetMask(uint8_t *_addr) {
00354   writeSUBR(_addr);
00355 }
00356 
00357 void W5100Class::getMACAddress(uint8_t *_addr) {
00358   readSHAR(_addr);
00359 }
00360 
00361 void W5100Class::setMACAddress(uint8_t *_addr) {
00362   writeSHAR(_addr);
00363 }
00364 
00365 void W5100Class::getIPAddress(uint8_t *_addr) {
00366   readSIPR(_addr);
00367 }
00368 
00369 void W5100Class::setIPAddress(uint8_t *_addr) {
00370   writeSIPR(_addr);
00371 }
00372 
00373 void W5100Class::setRetransmissionTime(uint16_t _timeout) {
00374   writeRTR(_timeout);
00375 }
00376 
00377 void W5100Class::setRetransmissionCount(uint8_t _retry) {
00378   writeRCR(_retry);
00379 }
00380 
00381 #endif