W5200(WIZ820io) network interface
Embed:
(wiki syntax)
Show/hide line numbers
w5100.cpp
00001 /* 00002 * Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st> 00003 * 00004 * This file is free software; you can redistribute it and/or modify 00005 * it under the terms of either the GNU General Public License version 2 00006 * or the GNU Lesser General Public License version 2.1, both as 00007 * published by the Free Software Foundation. 00008 */ 00009 00010 #include <stdio.h> 00011 #include <string.h> 00012 #include "mbed.h" 00013 #include "w5100.h" 00014 #ifndef MBED 00015 #include <avr/interrupt.h> 00016 #endif //MBED 00017 00018 // W5100 controller instance 00019 W5100Class W5100; 00020 00021 #define TX_RX_MAX_BUF_SIZE 2048 00022 #define TX_BUF 0x1100 00023 #define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE) 00024 00025 #ifdef W5200 00026 #define TXBUF_BASE 0x8000 00027 #define RXBUF_BASE 0xC000 00028 #else 00029 #define TXBUF_BASE 0x4000 00030 #define RXBUF_BASE 0x6000 00031 #endif 00032 00033 #ifdef MBED 00034 00035 SPI* pSPI = NULL; 00036 DigitalOut* pCS = NULL; 00037 00038 inline void delay(int n) { wait_ms(n); } 00039 inline static void initSS(){ pCS->write(1); } 00040 inline static void setSS() { pCS->write(0); } 00041 inline static void resetSS() { pCS->write(1); } 00042 00043 #endif //MBED 00044 00045 void W5100Class::init(void) 00046 { 00047 if (!pSPI) { 00048 pSPI = new SPI(p11, p12, p13); // mosi, miso, sclk 00049 } 00050 if (!pCS) { 00051 pCS = new DigitalOut(p14); 00052 } 00053 initSS(); 00054 writeMR(1<<RST); 00055 00056 #ifdef W5200 00057 for (int i=0; i<MAX_SOCK_NUM; i++) { 00058 write((0x4000 + i * 0x100 + 0x001F), 2); 00059 write((0x4000 + i * 0x100 + 0x001E), 2); 00060 } 00061 #else 00062 writeTMSR(0x55); 00063 writeRMSR(0x55); 00064 #endif 00065 00066 for (int i=0; i<MAX_SOCK_NUM; i++) { 00067 SBASE[i] = TXBUF_BASE + SSIZE * i; 00068 RBASE[i] = RXBUF_BASE + RSIZE * i; 00069 } 00070 } 00071 00072 uint16_t W5100Class::getTXFreeSize(SOCKET s) 00073 { 00074 uint16_t val=0, val1=0; 00075 do { 00076 val1 = readSnTX_FSR(s); 00077 if (val1 != 0) 00078 val = readSnTX_FSR(s); 00079 } 00080 while (val != val1); 00081 return val; 00082 } 00083 00084 uint16_t W5100Class::getRXReceivedSize(SOCKET s) 00085 { 00086 uint16_t val=0,val1=0; 00087 do { 00088 val1 = readSnRX_RSR(s); 00089 if (val1 != 0) 00090 val = readSnRX_RSR(s); 00091 } 00092 while (val != val1); 00093 return val; 00094 } 00095 00096 00097 void W5100Class::send_data_processing(SOCKET s, const uint8_t *data, uint16_t len) 00098 { 00099 // This is same as having no offset in a call to send_data_processing_offset 00100 send_data_processing_offset(s, 0, data, len); 00101 } 00102 00103 void W5100Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len) 00104 { 00105 uint16_t ptr = readSnTX_WR(s); 00106 ptr += data_offset; 00107 uint16_t offset = ptr & SMASK; 00108 uint16_t dstAddr = offset + SBASE[s]; 00109 00110 if (offset + len > SSIZE) 00111 { 00112 // Wrap around circular buffer 00113 uint16_t size = SSIZE - offset; 00114 write(dstAddr, data, size); 00115 write(SBASE[s], data + size, len - size); 00116 } 00117 else { 00118 write(dstAddr, data, len); 00119 } 00120 00121 ptr += len; 00122 writeSnTX_WR(s, ptr); 00123 } 00124 00125 00126 void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek) 00127 { 00128 uint16_t ptr; 00129 ptr = readSnRX_RD(s); 00130 read_data(s, (uint8_t *)ptr, data, len); 00131 if (!peek) 00132 { 00133 ptr += len; 00134 writeSnRX_RD(s, ptr); 00135 } 00136 } 00137 00138 void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len) 00139 { 00140 uint16_t size; 00141 uint16_t src_mask; 00142 uint16_t src_ptr; 00143 00144 #ifdef MBED 00145 src_mask = (int)src & RMASK; 00146 #else 00147 src_mask = (uint16_t)src & RMASK; 00148 #endif //MBED 00149 src_ptr = RBASE[s] + src_mask; 00150 00151 if( (src_mask + len) > RSIZE ) 00152 { 00153 size = RSIZE - src_mask; 00154 read(src_ptr, (uint8_t *)dst, size); 00155 dst += size; 00156 read(RBASE[s], (uint8_t *) dst, len - size); 00157 } 00158 else 00159 read(src_ptr, (uint8_t *) dst, len); 00160 } 00161 00162 00163 uint8_t W5100Class::write(uint16_t _addr, uint8_t _data) 00164 { 00165 setSS(); 00166 00167 #ifdef W5200 00168 pSPI->write(_addr >> 8); 00169 pSPI->write(_addr & 0xFF); 00170 pSPI->write(0x80); 00171 pSPI->write(0x01); 00172 #else 00173 pSPI->write(0xF0); 00174 pSPI->write(_addr >> 8); 00175 pSPI->write(_addr & 0xFF); 00176 #endif 00177 pSPI->write(_data); 00178 resetSS(); 00179 return 1; 00180 } 00181 00182 uint16_t W5100Class::write(uint16_t _addr, const uint8_t *_buf, uint16_t _len) 00183 { 00184 00185 #ifdef W5200 00186 setSS(); 00187 pSPI->write(_addr >> 8); 00188 pSPI->write(_addr & 0xFF); 00189 pSPI->write((0x80 | ((_len & 0x7F00) >> 8))); 00190 pSPI->write(_len & 0x00FF); 00191 00192 for (uint16_t i=0; i<_len; i++) 00193 { 00194 pSPI->write(_buf[i]); 00195 00196 } 00197 resetSS(); 00198 #else 00199 00200 for (uint16_t i=0; i<_len; i++) 00201 { 00202 setSS(); 00203 pSPI->write(0xF0); 00204 pSPI->write(_addr >> 8); 00205 pSPI->write(_addr & 0xFF); 00206 _addr++; 00207 pSPI->write(_buf[i]); 00208 resetSS(); 00209 } 00210 #endif 00211 00212 return _len; 00213 } 00214 00215 uint8_t W5100Class::read(uint16_t _addr) 00216 { 00217 setSS(); 00218 #ifdef W5200 00219 pSPI->write(_addr >> 8); 00220 pSPI->write(_addr & 0xFF); 00221 pSPI->write(0x00); 00222 pSPI->write(0x01); 00223 #else 00224 pSPI->write(0x0F); 00225 pSPI->write(_addr >> 8); 00226 pSPI->write(_addr & 0xFF); 00227 #endif 00228 00229 uint8_t _data = pSPI->write(0); 00230 resetSS(); 00231 return _data; 00232 } 00233 00234 uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len) 00235 { 00236 #ifdef W5200 00237 setSS(); 00238 pSPI->write(_addr >> 8); 00239 pSPI->write(_addr & 0xFF); 00240 pSPI->write((0x00 | ((_len & 0x7F00) >> 8))); 00241 pSPI->write(_len & 0x00FF); 00242 00243 for (uint16_t i=0; i<_len; i++) 00244 { 00245 _buf[i] = pSPI->write(0); 00246 00247 } 00248 resetSS(); 00249 00250 #else 00251 00252 for (uint16_t i=0; i<_len; i++) 00253 { 00254 setSS(); 00255 pSPI->write(0x0F); 00256 pSPI->write(_addr >> 8); 00257 pSPI->write(_addr & 0xFF); 00258 _addr++; 00259 _buf[i] = pSPI->write(0); 00260 resetSS(); 00261 } 00262 #endif 00263 return _len; 00264 } 00265 00266 void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) { 00267 // Send command to socket 00268 writeSnCR(s, _cmd); 00269 // Wait for command to complete 00270 while (readSnCR(s)) 00271 ; 00272 }
Generated on Tue Jul 12 2022 19:58:52 by 1.7.2