For a question in forum this is a working example, there will be the example that is not working

Dependencies:   mbed

Fork of eth_v13 by Heiko Greiner

Committer:
hggerdd
Date:
Thu Mar 27 21:55:57 2014 +0000
Revision:
4:a10e3d1bdb17
Parent:
3:79dc3337d9da
working with wiznet w5100

Who changed what in which revision?

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