DHCP Client for WIZ820io(W5200)

Dependencies:   EthernetNetIf mbed

Committer:
va009039
Date:
Tue Apr 10 03:38:22 2012 +0000
Revision:
0:db4242c89949

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:db4242c89949 1 /*
va009039 0:db4242c89949 2 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
va009039 0:db4242c89949 3 *
va009039 0:db4242c89949 4 * This file is free software; you can redistribute it and/or modify
va009039 0:db4242c89949 5 * it under the terms of either the GNU General Public License version 2
va009039 0:db4242c89949 6 * or the GNU Lesser General Public License version 2.1, both as
va009039 0:db4242c89949 7 * published by the Free Software Foundation.
va009039 0:db4242c89949 8 */
va009039 0:db4242c89949 9
va009039 0:db4242c89949 10 #include <stdio.h>
va009039 0:db4242c89949 11 #include <string.h>
va009039 0:db4242c89949 12 #include "w5100.h"
va009039 0:db4242c89949 13 #ifndef MBED
va009039 0:db4242c89949 14 #include <avr/interrupt.h>
va009039 0:db4242c89949 15 #endif //MBED
va009039 0:db4242c89949 16
va009039 0:db4242c89949 17 // W5100 controller instance
va009039 0:db4242c89949 18 W5100Class W5100;
va009039 0:db4242c89949 19
va009039 0:db4242c89949 20 #define TX_RX_MAX_BUF_SIZE 2048
va009039 0:db4242c89949 21 #define TX_BUF 0x1100
va009039 0:db4242c89949 22 #define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE)
va009039 0:db4242c89949 23
va009039 0:db4242c89949 24 #ifdef W5200
va009039 0:db4242c89949 25 #define TXBUF_BASE 0x8000
va009039 0:db4242c89949 26 #define RXBUF_BASE 0xC000
va009039 0:db4242c89949 27 #else
va009039 0:db4242c89949 28 #define TXBUF_BASE 0x4000
va009039 0:db4242c89949 29 #define RXBUF_BASE 0x6000
va009039 0:db4242c89949 30 #endif
va009039 0:db4242c89949 31
va009039 0:db4242c89949 32 #ifdef MBED
va009039 0:db4242c89949 33 SPI spi(p11, p12, p13); // mosi, miso, sclk
va009039 0:db4242c89949 34 DigitalOut _cs(p14);
va009039 0:db4242c89949 35 DigitalOut _reset(p15);
va009039 0:db4242c89949 36 inline void delay(int n) { wait_ms(n); }
va009039 0:db4242c89949 37 inline static void initSS(){ _cs = 1; }
va009039 0:db4242c89949 38 inline static void setSS() { _cs = 0; }
va009039 0:db4242c89949 39 inline static void resetSS() { _cs = 1; }
va009039 0:db4242c89949 40
va009039 0:db4242c89949 41 void W5100Class::hardware_reset() {
va009039 0:db4242c89949 42 _reset = 1;
va009039 0:db4242c89949 43 _reset = 0;
va009039 0:db4242c89949 44 wait_us(2);
va009039 0:db4242c89949 45 _reset = 1;
va009039 0:db4242c89949 46 wait_ms(150);
va009039 0:db4242c89949 47 }
va009039 0:db4242c89949 48 #endif //MBED
va009039 0:db4242c89949 49
va009039 0:db4242c89949 50 void W5100Class::init(void)
va009039 0:db4242c89949 51 {
va009039 0:db4242c89949 52 initSS();
va009039 0:db4242c89949 53 writeMR(1<<RST);
va009039 0:db4242c89949 54
va009039 0:db4242c89949 55 #ifdef W5200
va009039 0:db4242c89949 56 for (int i=0; i<MAX_SOCK_NUM; i++) {
va009039 0:db4242c89949 57 write((0x4000 + i * 0x100 + 0x001F), 2);
va009039 0:db4242c89949 58 write((0x4000 + i * 0x100 + 0x001E), 2);
va009039 0:db4242c89949 59 }
va009039 0:db4242c89949 60 #else
va009039 0:db4242c89949 61 writeTMSR(0x55);
va009039 0:db4242c89949 62 writeRMSR(0x55);
va009039 0:db4242c89949 63 #endif
va009039 0:db4242c89949 64
va009039 0:db4242c89949 65 for (int i=0; i<MAX_SOCK_NUM; i++) {
va009039 0:db4242c89949 66 SBASE[i] = TXBUF_BASE + SSIZE * i;
va009039 0:db4242c89949 67 RBASE[i] = RXBUF_BASE + RSIZE * i;
va009039 0:db4242c89949 68 }
va009039 0:db4242c89949 69 }
va009039 0:db4242c89949 70
va009039 0:db4242c89949 71 uint16_t W5100Class::getTXFreeSize(SOCKET s)
va009039 0:db4242c89949 72 {
va009039 0:db4242c89949 73 uint16_t val=0, val1=0;
va009039 0:db4242c89949 74 do {
va009039 0:db4242c89949 75 val1 = readSnTX_FSR(s);
va009039 0:db4242c89949 76 if (val1 != 0)
va009039 0:db4242c89949 77 val = readSnTX_FSR(s);
va009039 0:db4242c89949 78 }
va009039 0:db4242c89949 79 while (val != val1);
va009039 0:db4242c89949 80 return val;
va009039 0:db4242c89949 81 }
va009039 0:db4242c89949 82
va009039 0:db4242c89949 83 uint16_t W5100Class::getRXReceivedSize(SOCKET s)
va009039 0:db4242c89949 84 {
va009039 0:db4242c89949 85 uint16_t val=0,val1=0;
va009039 0:db4242c89949 86 do {
va009039 0:db4242c89949 87 val1 = readSnRX_RSR(s);
va009039 0:db4242c89949 88 if (val1 != 0)
va009039 0:db4242c89949 89 val = readSnRX_RSR(s);
va009039 0:db4242c89949 90 }
va009039 0:db4242c89949 91 while (val != val1);
va009039 0:db4242c89949 92 return val;
va009039 0:db4242c89949 93 }
va009039 0:db4242c89949 94
va009039 0:db4242c89949 95
va009039 0:db4242c89949 96 void W5100Class::send_data_processing(SOCKET s, const uint8_t *data, uint16_t len)
va009039 0:db4242c89949 97 {
va009039 0:db4242c89949 98 // This is same as having no offset in a call to send_data_processing_offset
va009039 0:db4242c89949 99 send_data_processing_offset(s, 0, data, len);
va009039 0:db4242c89949 100 }
va009039 0:db4242c89949 101
va009039 0:db4242c89949 102 void W5100Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len)
va009039 0:db4242c89949 103 {
va009039 0:db4242c89949 104 uint16_t ptr = readSnTX_WR(s);
va009039 0:db4242c89949 105 ptr += data_offset;
va009039 0:db4242c89949 106 uint16_t offset = ptr & SMASK;
va009039 0:db4242c89949 107 uint16_t dstAddr = offset + SBASE[s];
va009039 0:db4242c89949 108
va009039 0:db4242c89949 109 if (offset + len > SSIZE)
va009039 0:db4242c89949 110 {
va009039 0:db4242c89949 111 // Wrap around circular buffer
va009039 0:db4242c89949 112 uint16_t size = SSIZE - offset;
va009039 0:db4242c89949 113 write(dstAddr, data, size);
va009039 0:db4242c89949 114 write(SBASE[s], data + size, len - size);
va009039 0:db4242c89949 115 }
va009039 0:db4242c89949 116 else {
va009039 0:db4242c89949 117 write(dstAddr, data, len);
va009039 0:db4242c89949 118 }
va009039 0:db4242c89949 119
va009039 0:db4242c89949 120 ptr += len;
va009039 0:db4242c89949 121 writeSnTX_WR(s, ptr);
va009039 0:db4242c89949 122 }
va009039 0:db4242c89949 123
va009039 0:db4242c89949 124
va009039 0:db4242c89949 125 void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek)
va009039 0:db4242c89949 126 {
va009039 0:db4242c89949 127 uint16_t ptr;
va009039 0:db4242c89949 128 ptr = readSnRX_RD(s);
va009039 0:db4242c89949 129 read_data(s, (uint8_t *)ptr, data, len);
va009039 0:db4242c89949 130 if (!peek)
va009039 0:db4242c89949 131 {
va009039 0:db4242c89949 132 ptr += len;
va009039 0:db4242c89949 133 writeSnRX_RD(s, ptr);
va009039 0:db4242c89949 134 }
va009039 0:db4242c89949 135 }
va009039 0:db4242c89949 136
va009039 0:db4242c89949 137 void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
va009039 0:db4242c89949 138 {
va009039 0:db4242c89949 139 uint16_t size;
va009039 0:db4242c89949 140 uint16_t src_mask;
va009039 0:db4242c89949 141 uint16_t src_ptr;
va009039 0:db4242c89949 142
va009039 0:db4242c89949 143 #ifdef MBED
va009039 0:db4242c89949 144 src_mask = (int)src & RMASK;
va009039 0:db4242c89949 145 #else
va009039 0:db4242c89949 146 src_mask = (uint16_t)src & RMASK;
va009039 0:db4242c89949 147 #endif //MBED
va009039 0:db4242c89949 148 src_ptr = RBASE[s] + src_mask;
va009039 0:db4242c89949 149
va009039 0:db4242c89949 150 if( (src_mask + len) > RSIZE )
va009039 0:db4242c89949 151 {
va009039 0:db4242c89949 152 size = RSIZE - src_mask;
va009039 0:db4242c89949 153 read(src_ptr, (uint8_t *)dst, size);
va009039 0:db4242c89949 154 dst += size;
va009039 0:db4242c89949 155 read(RBASE[s], (uint8_t *) dst, len - size);
va009039 0:db4242c89949 156 }
va009039 0:db4242c89949 157 else
va009039 0:db4242c89949 158 read(src_ptr, (uint8_t *) dst, len);
va009039 0:db4242c89949 159 }
va009039 0:db4242c89949 160
va009039 0:db4242c89949 161
va009039 0:db4242c89949 162 uint8_t W5100Class::write(uint16_t _addr, uint8_t _data)
va009039 0:db4242c89949 163 {
va009039 0:db4242c89949 164 setSS();
va009039 0:db4242c89949 165
va009039 0:db4242c89949 166 #ifdef W5200
va009039 0:db4242c89949 167 spi.write(_addr >> 8);
va009039 0:db4242c89949 168 spi.write(_addr & 0xFF);
va009039 0:db4242c89949 169 spi.write(0x80);
va009039 0:db4242c89949 170 spi.write(0x01);
va009039 0:db4242c89949 171 #else
va009039 0:db4242c89949 172 spi.write(0xF0);
va009039 0:db4242c89949 173 spi.write(_addr >> 8);
va009039 0:db4242c89949 174 spi.write(_addr & 0xFF);
va009039 0:db4242c89949 175 #endif
va009039 0:db4242c89949 176 spi.write(_data);
va009039 0:db4242c89949 177 resetSS();
va009039 0:db4242c89949 178 return 1;
va009039 0:db4242c89949 179 }
va009039 0:db4242c89949 180
va009039 0:db4242c89949 181 uint16_t W5100Class::write(uint16_t _addr, const uint8_t *_buf, uint16_t _len)
va009039 0:db4242c89949 182 {
va009039 0:db4242c89949 183
va009039 0:db4242c89949 184 #ifdef W5200
va009039 0:db4242c89949 185 setSS();
va009039 0:db4242c89949 186 spi.write(_addr >> 8);
va009039 0:db4242c89949 187 spi.write(_addr & 0xFF);
va009039 0:db4242c89949 188 spi.write((0x80 | ((_len & 0x7F00) >> 8)));
va009039 0:db4242c89949 189 spi.write(_len & 0x00FF);
va009039 0:db4242c89949 190
va009039 0:db4242c89949 191 for (uint16_t i=0; i<_len; i++)
va009039 0:db4242c89949 192 {
va009039 0:db4242c89949 193 spi.write(_buf[i]);
va009039 0:db4242c89949 194
va009039 0:db4242c89949 195 }
va009039 0:db4242c89949 196 resetSS();
va009039 0:db4242c89949 197 #else
va009039 0:db4242c89949 198
va009039 0:db4242c89949 199 for (uint16_t i=0; i<_len; i++)
va009039 0:db4242c89949 200 {
va009039 0:db4242c89949 201 setSS();
va009039 0:db4242c89949 202 spi.write(0xF0);
va009039 0:db4242c89949 203 spi.write(_addr >> 8);
va009039 0:db4242c89949 204 spi.write(_addr & 0xFF);
va009039 0:db4242c89949 205 _addr++;
va009039 0:db4242c89949 206 spi.write(_buf[i]);
va009039 0:db4242c89949 207 resetSS();
va009039 0:db4242c89949 208 }
va009039 0:db4242c89949 209 #endif
va009039 0:db4242c89949 210
va009039 0:db4242c89949 211 return _len;
va009039 0:db4242c89949 212 }
va009039 0:db4242c89949 213
va009039 0:db4242c89949 214 uint8_t W5100Class::read(uint16_t _addr)
va009039 0:db4242c89949 215 {
va009039 0:db4242c89949 216 setSS();
va009039 0:db4242c89949 217 #ifdef W5200
va009039 0:db4242c89949 218 spi.write(_addr >> 8);
va009039 0:db4242c89949 219 spi.write(_addr & 0xFF);
va009039 0:db4242c89949 220 spi.write(0x00);
va009039 0:db4242c89949 221 spi.write(0x01);
va009039 0:db4242c89949 222 #else
va009039 0:db4242c89949 223 spi.write(0x0F);
va009039 0:db4242c89949 224 spi.write(_addr >> 8);
va009039 0:db4242c89949 225 spi.write(_addr & 0xFF);
va009039 0:db4242c89949 226 #endif
va009039 0:db4242c89949 227
va009039 0:db4242c89949 228 uint8_t _data = spi.write(0);
va009039 0:db4242c89949 229 resetSS();
va009039 0:db4242c89949 230 return _data;
va009039 0:db4242c89949 231 }
va009039 0:db4242c89949 232
va009039 0:db4242c89949 233 uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len)
va009039 0:db4242c89949 234 {
va009039 0:db4242c89949 235 #ifdef W5200
va009039 0:db4242c89949 236 setSS();
va009039 0:db4242c89949 237 spi.write(_addr >> 8);
va009039 0:db4242c89949 238 spi.write(_addr & 0xFF);
va009039 0:db4242c89949 239 spi.write((0x00 | ((_len & 0x7F00) >> 8)));
va009039 0:db4242c89949 240 spi.write(_len & 0x00FF);
va009039 0:db4242c89949 241
va009039 0:db4242c89949 242 for (uint16_t i=0; i<_len; i++)
va009039 0:db4242c89949 243 {
va009039 0:db4242c89949 244 _buf[i] = spi.write(0);
va009039 0:db4242c89949 245
va009039 0:db4242c89949 246 }
va009039 0:db4242c89949 247 resetSS();
va009039 0:db4242c89949 248
va009039 0:db4242c89949 249 #else
va009039 0:db4242c89949 250
va009039 0:db4242c89949 251 for (uint16_t i=0; i<_len; i++)
va009039 0:db4242c89949 252 {
va009039 0:db4242c89949 253 setSS();
va009039 0:db4242c89949 254 spi.write(0x0F);
va009039 0:db4242c89949 255 spi.write(_addr >> 8);
va009039 0:db4242c89949 256 spi.write(_addr & 0xFF);
va009039 0:db4242c89949 257 _addr++;
va009039 0:db4242c89949 258 _buf[i] = spi.write(0);
va009039 0:db4242c89949 259 resetSS();
va009039 0:db4242c89949 260 }
va009039 0:db4242c89949 261 #endif
va009039 0:db4242c89949 262 return _len;
va009039 0:db4242c89949 263 }
va009039 0:db4242c89949 264
va009039 0:db4242c89949 265 void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) {
va009039 0:db4242c89949 266 // Send command to socket
va009039 0:db4242c89949 267 writeSnCR(s, _cmd);
va009039 0:db4242c89949 268 // Wait for command to complete
va009039 0:db4242c89949 269 while (readSnCR(s))
va009039 0:db4242c89949 270 ;
va009039 0:db4242c89949 271 }