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.
w5200.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 "w5200.h" 00014 00015 SPI* pSPI; 00016 DigitalOut* pCS; 00017 void initSS(){ pCS->write(1); } 00018 void setSS() { pCS->write(0); } 00019 void resetSS() { pCS->write(1); } 00020 00021 // W5200 controller instance 00022 W5200Class W5200; 00023 00024 #define TX_RX_MAX_BUF_SIZE 2048 00025 #define TX_BUF 0x1100 00026 #define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE) 00027 00028 #define TXBUF_BASE 0x8000 00029 #define RXBUF_BASE 0xC000 00030 00031 #if defined(TARGET_KL25Z) 00032 #define RESET_PIN PTD5 00033 #define CS_PIN PTD0 00034 #define MOSI_PIN PTD2 00035 #define MISO_PIN PTD3 00036 #define SCLK_PIN PTD1 00037 #endif 00038 00039 void W5200Class::init(void) 00040 { 00041 if (!pSPI) { 00042 pSPI = new SPI(MOSI_PIN, MISO_PIN, SCLK_PIN); // mosi, miso, sclk 00043 } 00044 if (!pCS) { 00045 pCS = new DigitalOut(CS_PIN); 00046 } 00047 initSS(); 00048 writeMR(1<<RST); 00049 00050 for (int i=0; i<MAX_SOCK_NUM; i++) { 00051 write((0x4000 + i * 0x100 + 0x001F), 2); 00052 write((0x4000 + i * 0x100 + 0x001E), 2); 00053 } 00054 00055 for (int i=0; i<MAX_SOCK_NUM; i++) { 00056 SBASE[i] = TXBUF_BASE + SSIZE * i; 00057 RBASE[i] = RXBUF_BASE + RSIZE * i; 00058 } 00059 } 00060 00061 uint16_t W5200Class::getTXFreeSize(SOCKET s) 00062 { 00063 uint16_t val=0, val1=0; 00064 do { 00065 val1 = readSnTX_FSR(s); 00066 if (val1 != 0) 00067 val = readSnTX_FSR(s); 00068 } 00069 while (val != val1); 00070 return val; 00071 } 00072 00073 uint16_t W5200Class::getRXReceivedSize(SOCKET s) 00074 { 00075 uint16_t val=0,val1=0; 00076 do { 00077 val1 = readSnRX_RSR(s); 00078 if (val1 != 0) 00079 val = readSnRX_RSR(s); 00080 } 00081 while (val != val1); 00082 return val; 00083 } 00084 00085 00086 void W5200Class::send_data_processing(SOCKET s, const uint8_t *data, uint16_t len) 00087 { 00088 // This is same as having no offset in a call to send_data_processing_offset 00089 send_data_processing_offset(s, 0, data, len); 00090 } 00091 00092 void W5200Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len) 00093 { 00094 uint16_t ptr = readSnTX_WR(s); 00095 ptr += data_offset; 00096 uint16_t offset = ptr & SMASK; 00097 uint16_t dstAddr = offset + SBASE[s]; 00098 00099 if (offset + len > SSIZE) 00100 { 00101 // Wrap around circular buffer 00102 uint16_t size = SSIZE - offset; 00103 write(dstAddr, data, size); 00104 write(SBASE[s], data + size, len - size); 00105 } 00106 else { 00107 write(dstAddr, data, len); 00108 } 00109 00110 ptr += len; 00111 writeSnTX_WR(s, ptr); 00112 } 00113 00114 00115 void W5200Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek) 00116 { 00117 uint16_t ptr; 00118 ptr = readSnRX_RD(s); 00119 read_data(s, (uint8_t *)ptr, data, len); 00120 if (!peek) 00121 { 00122 ptr += len; 00123 writeSnRX_RD(s, ptr); 00124 } 00125 } 00126 00127 void W5200Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len) 00128 { 00129 uint16_t size; 00130 uint16_t src_mask; 00131 uint16_t src_ptr; 00132 00133 //src_mask = (uint16_t)src & RMASK; 00134 src_mask = (int)src & RMASK; 00135 src_ptr = RBASE[s] + src_mask; 00136 00137 if( (src_mask + len) > RSIZE ) 00138 { 00139 size = RSIZE - src_mask; 00140 read(src_ptr, (uint8_t *)dst, size); 00141 dst += size; 00142 read(RBASE[s], (uint8_t *) dst, len - size); 00143 } 00144 else 00145 read(src_ptr, (uint8_t *) dst, len); 00146 } 00147 00148 00149 uint8_t W5200Class::write(uint16_t _addr, uint8_t _data) 00150 { 00151 setSS(); 00152 00153 pSPI->write(_addr >> 8); 00154 pSPI->write(_addr & 0xFF); 00155 pSPI->write(0x80); 00156 pSPI->write(0x01); 00157 pSPI->write(_data); 00158 resetSS(); 00159 return 1; 00160 } 00161 00162 uint16_t W5200Class::write(uint16_t _addr, const uint8_t *_buf, uint16_t _len) 00163 { 00164 setSS(); 00165 pSPI->write(_addr >> 8); 00166 pSPI->write(_addr & 0xFF); 00167 pSPI->write((0x80 | ((_len & 0x7F00) >> 8))); 00168 pSPI->write(_len & 0x00FF); 00169 00170 for (uint16_t i=0; i<_len; i++) 00171 { 00172 pSPI->write(_buf[i]); 00173 } 00174 resetSS(); 00175 00176 return _len; 00177 } 00178 00179 uint8_t W5200Class::read(uint16_t _addr) 00180 { 00181 setSS(); 00182 pSPI->write(_addr >> 8); 00183 pSPI->write(_addr & 0xFF); 00184 pSPI->write(0x00); 00185 pSPI->write(0x01); 00186 uint8_t _data = pSPI->write(0); 00187 resetSS(); 00188 return _data; 00189 } 00190 00191 uint16_t W5200Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len) 00192 { 00193 setSS(); 00194 pSPI->write(_addr >> 8); 00195 pSPI->write(_addr & 0xFF); 00196 pSPI->write((0x00 | ((_len & 0x7F00) >> 8))); 00197 pSPI->write(_len & 0x00FF); 00198 00199 for (uint16_t i=0; i<_len; i++) 00200 { 00201 _buf[i] = pSPI->write(0); 00202 } 00203 resetSS(); 00204 return _len; 00205 } 00206 00207 void W5200Class::execCmdSn(SOCKET s, SockCMD _cmd) { 00208 // Send command to socket 00209 writeSnCR(s, _cmd); 00210 // Wait for command to complete 00211 while (readSnCR(s)) 00212 ; 00213 }
Generated on Tue Jul 12 2022 13:04:15 by
1.7.2