00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <stdio.h>
00011 #include <string.h>
00012 #include <avr/interrupt.h>
00013
00014 #include "w5100.h"
00015
00016
00017 W5100Class W5100;
00018
00019 #define TX_RX_MAX_BUF_SIZE 2048
00020 #define TX_BUF 0x1100
00021 #define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE)
00022
00023 #define TXBUF_BASE 0x4000
00024 #define RXBUF_BASE 0x6000
00025
00026 void W5100Class::init(void)
00027 {
00028 delay(300);
00029
00030 SPI.begin();
00031 initSS();
00032
00033 writeMR(1<<RST);
00034 writeTMSR(0x55);
00035 writeRMSR(0x55);
00036
00037 for (int i=0; i<MAX_SOCK_NUM; i++) {
00038 SBASE[i] = TXBUF_BASE + SSIZE * i;
00039 RBASE[i] = RXBUF_BASE + RSIZE * i;
00040 }
00041 }
00042
00043 uint16_t W5100Class::getTXFreeSize(SOCKET s)
00044 {
00045 uint16_t val=0, val1=0;
00046 do {
00047 val1 = readSnTX_FSR(s);
00048 if (val1 != 0)
00049 val = readSnTX_FSR(s);
00050 }
00051 while (val != val1);
00052 return val;
00053 }
00054
00055 uint16_t W5100Class::getRXReceivedSize(SOCKET s)
00056 {
00057 uint16_t val=0,val1=0;
00058 do {
00059 val1 = readSnRX_RSR(s);
00060 if (val1 != 0)
00061 val = readSnRX_RSR(s);
00062 }
00063 while (val != val1);
00064 return val;
00065 }
00066
00067
00068 void W5100Class::send_data_processing(SOCKET s, uint8_t *data, uint16_t len)
00069 {
00070 uint16_t ptr = readSnTX_WR(s);
00071
00072 uint16_t offset = ptr & SMASK;
00073 uint16_t dstAddr = offset + SBASE[s];
00074
00075 if (offset + len > SSIZE)
00076 {
00077
00078 uint16_t size = SSIZE - offset;
00079 write(dstAddr, data, size);
00080 write(SBASE[s], data + size, len - size);
00081 }
00082 else {
00083 write(dstAddr, data, len);
00084 }
00085
00086 ptr += len;
00087 writeSnTX_WR(s, ptr);
00088 }
00089
00090
00091 void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek)
00092 {
00093 uint16_t ptr;
00094 ptr = readSnRX_RD(s);
00095 read_data(s, (uint8_t *)ptr, data, len);
00096 if (!peek)
00097 {
00098 ptr += len;
00099 writeSnRX_RD(s, ptr);
00100 }
00101 }
00102
00103 void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
00104 {
00105 uint16_t size;
00106 uint16_t src_mask;
00107 uint16_t src_ptr;
00108
00109 src_mask = (uint16_t)src & RMASK;
00110 src_ptr = RBASE[s] + src_mask;
00111
00112 if( (src_mask + len) > RSIZE )
00113 {
00114 size = RSIZE - src_mask;
00115 read(src_ptr, (uint8_t *)dst, size);
00116 dst += size;
00117 read(RBASE[s], (uint8_t *) dst, len - size);
00118 }
00119 else
00120 read(src_ptr, (uint8_t *) dst, len);
00121 }
00122
00123
00124 uint8_t W5100Class::write(uint16_t _addr, uint8_t _data)
00125 {
00126 setSS();
00127 SPI.transfer(0xF0);
00128 SPI.transfer(_addr >> 8);
00129 SPI.transfer(_addr & 0xFF);
00130 SPI.transfer(_data);
00131 resetSS();
00132 return 1;
00133 }
00134
00135 uint16_t W5100Class::write(uint16_t _addr, uint8_t *_buf, uint16_t _len)
00136 {
00137 for (int i=0; i<_len; i++)
00138 {
00139 setSS();
00140 SPI.transfer(0xF0);
00141 SPI.transfer(_addr >> 8);
00142 SPI.transfer(_addr & 0xFF);
00143 _addr++;
00144 SPI.transfer(_buf[i]);
00145 resetSS();
00146 }
00147 return _len;
00148 }
00149
00150 uint8_t W5100Class::read(uint16_t _addr)
00151 {
00152 setSS();
00153 SPI.transfer(0x0F);
00154 SPI.transfer(_addr >> 8);
00155 SPI.transfer(_addr & 0xFF);
00156 uint8_t _data = SPI.transfer(0);
00157 resetSS();
00158 return _data;
00159 }
00160
00161 uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len)
00162 {
00163 for (int i=0; i<_len; i++)
00164 {
00165 setSS();
00166 SPI.transfer(0x0F);
00167 SPI.transfer(_addr >> 8);
00168 SPI.transfer(_addr & 0xFF);
00169 _addr++;
00170 _buf[i] = SPI.transfer(0);
00171 resetSS();
00172 }
00173 return _len;
00174 }
00175
00176 void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) {
00177
00178 writeSnCR(s, _cmd);
00179
00180 while (readSnCR(s))
00181 ;
00182 }