Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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