WIZ820io(W5200) network interface、EthernetNetIf compatible.
example
#include "WIZ820ioNetIf.h" #include "HTTPClient.h" #include "HTTPServer.h" #if defined(TARGET_KL25Z) WIZ820ioNetIf eth(PTD2,PTD3,PTD1,PTD0,PTD5); #endif HTTPClient http; HTTPStream stream; void callback(HTTPResult r){ printf("callback %d %s\n", r, HTTPClient::ResultStr(r)); } int main() { int err = eth.setup(); if (err < 0) { printf("setup error %d\n", err); exit(-1); } HTTPServer svr; svr.addHandler<SimpleHandler>("/"); svr.bind(80); const char* uri = "http://va009039-mbed.appspot.com/kl25z/"; http.get(uri, &stream, callback); uint8_t buf[256]; int total = 0; stream.readNext(buf, sizeof(buf)); while(1) { if(stream.readable()) { int len = stream.readLen(); total += len; printf("%d %d\n", total, len); stream.readNext(buf, sizeof(buf)); } Net::poll(); } }
Diff: w5200.cpp
- Revision:
- 1:22b9052d864d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/w5200.cpp Sun Mar 24 11:25:31 2013 +0000 @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st> + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of either the GNU General Public License version 2 + * or the GNU Lesser General Public License version 2.1, both as + * published by the Free Software Foundation. + */ + +#include <stdio.h> +#include <string.h> +#include "mbed.h" +#include "w5200.h" + +SPI* pSPI; +DigitalOut* pCS; +void initSS(){ pCS->write(1); } +void setSS() { pCS->write(0); } +void resetSS() { pCS->write(1); } + +// W5200 controller instance +W5200Class W5200; + +#define TX_RX_MAX_BUF_SIZE 2048 +#define TX_BUF 0x1100 +#define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE) + +#define TXBUF_BASE 0x8000 +#define RXBUF_BASE 0xC000 + +#if defined(TARGET_KL25Z) +#define RESET_PIN PTD5 +#define CS_PIN PTD0 +#define MOSI_PIN PTD2 +#define MISO_PIN PTD3 +#define SCLK_PIN PTD1 +#endif + +void W5200Class::init(void) +{ + if (!pSPI) { + pSPI = new SPI(MOSI_PIN, MISO_PIN, SCLK_PIN); // mosi, miso, sclk + } + if (!pCS) { + pCS = new DigitalOut(CS_PIN); + } + initSS(); + writeMR(1<<RST); + + for (int i=0; i<MAX_SOCK_NUM; i++) { + write((0x4000 + i * 0x100 + 0x001F), 2); + write((0x4000 + i * 0x100 + 0x001E), 2); + } + + for (int i=0; i<MAX_SOCK_NUM; i++) { + SBASE[i] = TXBUF_BASE + SSIZE * i; + RBASE[i] = RXBUF_BASE + RSIZE * i; + } +} + +uint16_t W5200Class::getTXFreeSize(SOCKET s) +{ + uint16_t val=0, val1=0; + do { + val1 = readSnTX_FSR(s); + if (val1 != 0) + val = readSnTX_FSR(s); + } + while (val != val1); + return val; +} + +uint16_t W5200Class::getRXReceivedSize(SOCKET s) +{ + uint16_t val=0,val1=0; + do { + val1 = readSnRX_RSR(s); + if (val1 != 0) + val = readSnRX_RSR(s); + } + while (val != val1); + return val; +} + + +void W5200Class::send_data_processing(SOCKET s, const uint8_t *data, uint16_t len) +{ + // This is same as having no offset in a call to send_data_processing_offset + send_data_processing_offset(s, 0, data, len); +} + +void W5200Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len) +{ + uint16_t ptr = readSnTX_WR(s); + ptr += data_offset; + uint16_t offset = ptr & SMASK; + uint16_t dstAddr = offset + SBASE[s]; + + if (offset + len > SSIZE) + { + // Wrap around circular buffer + uint16_t size = SSIZE - offset; + write(dstAddr, data, size); + write(SBASE[s], data + size, len - size); + } + else { + write(dstAddr, data, len); + } + + ptr += len; + writeSnTX_WR(s, ptr); +} + + +void W5200Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek) +{ + uint16_t ptr; + ptr = readSnRX_RD(s); + read_data(s, (uint8_t *)ptr, data, len); + if (!peek) + { + ptr += len; + writeSnRX_RD(s, ptr); + } +} + +void W5200Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len) +{ + uint16_t size; + uint16_t src_mask; + uint16_t src_ptr; + + //src_mask = (uint16_t)src & RMASK; + src_mask = (int)src & RMASK; + src_ptr = RBASE[s] + src_mask; + + if( (src_mask + len) > RSIZE ) + { + size = RSIZE - src_mask; + read(src_ptr, (uint8_t *)dst, size); + dst += size; + read(RBASE[s], (uint8_t *) dst, len - size); + } + else + read(src_ptr, (uint8_t *) dst, len); +} + + +uint8_t W5200Class::write(uint16_t _addr, uint8_t _data) +{ + setSS(); + + pSPI->write(_addr >> 8); + pSPI->write(_addr & 0xFF); + pSPI->write(0x80); + pSPI->write(0x01); + pSPI->write(_data); + resetSS(); + return 1; +} + +uint16_t W5200Class::write(uint16_t _addr, const uint8_t *_buf, uint16_t _len) +{ + setSS(); + pSPI->write(_addr >> 8); + pSPI->write(_addr & 0xFF); + pSPI->write((0x80 | ((_len & 0x7F00) >> 8))); + pSPI->write(_len & 0x00FF); + + for (uint16_t i=0; i<_len; i++) + { + pSPI->write(_buf[i]); + } + resetSS(); + + return _len; +} + +uint8_t W5200Class::read(uint16_t _addr) +{ + setSS(); + pSPI->write(_addr >> 8); + pSPI->write(_addr & 0xFF); + pSPI->write(0x00); + pSPI->write(0x01); + uint8_t _data = pSPI->write(0); + resetSS(); + return _data; +} + +uint16_t W5200Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len) +{ + setSS(); + pSPI->write(_addr >> 8); + pSPI->write(_addr & 0xFF); + pSPI->write((0x00 | ((_len & 0x7F00) >> 8))); + pSPI->write(_len & 0x00FF); + + for (uint16_t i=0; i<_len; i++) + { + _buf[i] = pSPI->write(0); + } + resetSS(); + return _len; +} + +void W5200Class::execCmdSn(SOCKET s, SockCMD _cmd) { + // Send command to socket + writeSnCR(s, _cmd); + // Wait for command to complete + while (readSnCR(s)) + ; +}