W5200(WIZ820io) network interface

Committer:
va009039
Date:
Sat Apr 14 17:21:11 2012 +0000
Revision:
0:61831b843b44
Child:
1:803123933c5a

        

Who changed what in which revision?

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