exeption of receive(TCPSocketconnection)
Dependents: FTP_SDCard_File_Client_WIZwiki-W7500 FTPClient_example Freedman DigitalCamera_OV5642_WIZwiki-W7500 ... more
Fork of WIZnetInterface by
W7500x_toe.cpp
00001 /* Copyright (C) 2012 mbed.org, MIT License 00002 * 00003 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00004 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00005 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00006 * furnished to do so, subject to the following conditions: 00007 * 00008 * The above copyright notice and this permission notice shall be included in all copies or 00009 * substantial portions of the Software. 00010 * 00011 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00012 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00013 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00014 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00015 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00016 */ 00017 #include "eth_arch.h" 00018 #if defined(TARGET_WIZwiki_W7500) 00019 00020 #include "mbed.h" 00021 #include "mbed_debug.h" 00022 #include "DNSClient.h" 00023 00024 00025 /* 00026 * MDIO via GPIO 00027 * mdio via gpio is supported and related functions as follows. 00028 * - mdio_init(),mdio_read(),mdio_write() 00029 * - input_MDIO(),output_MDIO(),turnaroud_MDIO(),idle_MDIO() 00030 * called by ethernet_link() and ethernet_set_link() 00031 */ 00032 #define MDIO GPIO_Pin_14 00033 #define MDC GPIO_Pin_15 00034 #define GPIO_MDC GPIOB 00035 #define PHY_ADDR_IP101G 0x07 00036 #define PHY_ADDR PHY_ADDR_IP101G 00037 #define SVAL 0x2 //right shift val = 2 00038 #define PHYREG_CONTROL 0x0 //Control Register address (Contorl basic register) 00039 #define PHYREG_STATUS 0x1 //Status Register address (Status basic register) 00040 #define CNTL_DUPLEX (0x01ul<< 7) 00041 #define CNTL_AUTONEGO (0x01ul<<11) 00042 #define CNTL_SPEED (0x01ul<<12) 00043 #define MDC_WAIT (1) 00044 void mdio_init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_MDC, uint16_t GPIO_Pin_MDIO); 00045 void mdio_write(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr, uint32_t val); 00046 uint32_t mdio_read(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr); 00047 00048 WIZnet_Chip* WIZnet_Chip::inst; 00049 00050 WIZnet_Chip::WIZnet_Chip() 00051 { 00052 inst = this; 00053 } 00054 00055 bool WIZnet_Chip::setmac() 00056 { 00057 00058 for (int i =0; i < 6; i++) reg_wr<uint8_t>(SHAR+i, mac[i]); 00059 00060 return true; 00061 } 00062 00063 // Set the IP 00064 bool WIZnet_Chip::setip() 00065 { 00066 reg_wr<uint32_t>(SIPR, ip); 00067 reg_wr<uint32_t>(GAR, gateway); 00068 reg_wr<uint32_t>(SUBR, netmask); 00069 return true; 00070 } 00071 00072 bool WIZnet_Chip::setProtocol(int socket, Protocol p) 00073 { 00074 if (socket < 0) { 00075 return false; 00076 } 00077 sreg<uint8_t>(socket, Sn_MR, p); 00078 return true; 00079 } 00080 00081 bool WIZnet_Chip::connect(int socket, const char * host, int port, int timeout_ms) 00082 { 00083 if (socket < 0) { 00084 return false; 00085 } 00086 sreg<uint8_t>(socket, Sn_MR, TCP); 00087 scmd(socket, OPEN); 00088 sreg_ip(socket, Sn_DIPR, host); 00089 sreg<uint16_t>(socket, Sn_DPORT, port); 00090 sreg<uint16_t>(socket, Sn_PORT, new_port()); 00091 scmd(socket, CONNECT); 00092 Timer t; 00093 t.reset(); 00094 t.start(); 00095 while(!is_connected(socket)) { 00096 if (t.read_ms() > timeout_ms) { 00097 return false; 00098 } 00099 } 00100 return true; 00101 } 00102 00103 bool WIZnet_Chip::gethostbyname(const char* host, uint32_t* ip) 00104 { 00105 uint32_t addr = str_to_ip(host); 00106 char buf[17]; 00107 snprintf(buf, sizeof(buf), "%d.%d.%d.%d", 00108 (uint8_t)((addr>>24)&0xff), 00109 (uint8_t)((addr>>16)&0xff), 00110 (uint8_t)((addr>>8)&0xff), 00111 (uint8_t)(addr&0xff)); 00112 if (strcmp(buf, host) == 0) { 00113 *ip = addr; 00114 return true; 00115 } 00116 DNSClient client; 00117 if(client.lookup(host)) { 00118 *ip = client.ip; 00119 return true; 00120 } 00121 return false; 00122 } 00123 00124 00125 bool WIZnet_Chip::is_connected(int socket) 00126 { 00127 /* 00128 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_ESTABLISHED) { 00129 return true; 00130 } 00131 */ 00132 uint8_t tmpSn_SR; 00133 tmpSn_SR = sreg<uint8_t>(socket, Sn_SR); 00134 // packet sending is possible, when state is SOCK_CLOSE_WAIT. 00135 if ((tmpSn_SR == SOCK_ESTABLISHED) || (tmpSn_SR == SOCK_CLOSE_WAIT)) { 00136 return true; 00137 } 00138 return false; 00139 } 00140 // Reset the chip & set the buffer 00141 void WIZnet_Chip::reset() 00142 { 00143 /* S/W Reset PHY */ 00144 mdio_write(GPIO_MDC, PHYREG_CONTROL, 0x8000); 00145 wait_ms(10);//for S/W reset 00146 wait_ms(10);//for MDC I/F RDY 00147 00148 mdio_init(GPIO_MDC, MDC, MDIO); 00149 00150 /* S/W Reset WZTOE */ 00151 reg_wr<uint8_t>(MR, MR_RST); 00152 // set PAD strengh and pull-up for TXD[3:0] and TXE 00153 #ifdef __DEF_USED_IC101AG__ //For using IC+101AG 00154 *(volatile uint32_t *)(0x41003068) = 0x64; //TXD0 00155 *(volatile uint32_t *)(0x4100306C) = 0x64; //TXD1 00156 *(volatile uint32_t *)(0x41003070) = 0x64; //TXD2 00157 *(volatile uint32_t *)(0x41003074) = 0x64; //TXD3 00158 *(volatile uint32_t *)(0x41003050) = 0x64; //TXE 00159 #endif 00160 // set ticker counter 00161 reg_wr<uint32_t>(TIC100US, (SystemCoreClock/10000)); 00162 // write MAC address inside the WZTOE MAC address register 00163 reg_wr_mac(SHAR, mac); 00164 /* 00165 * set RX and TX buffer size 00166 * for (int socket = 0; socket < MAX_SOCK_NUM; socket++) { 00167 * sreg<uint8_t>(socket, Sn_RXBUF_SIZE, 2); 00168 * sreg<uint8_t>(socket, Sn_TXBUF_SIZE, 2); 00169 * } 00170 */ 00171 } 00172 00173 00174 bool WIZnet_Chip::close(int socket) 00175 { 00176 if (socket < 0) { 00177 return false; 00178 } 00179 // if SOCK_CLOSED, return 00180 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) { 00181 return true; 00182 } 00183 // if SOCK_ESTABLISHED, send FIN-Packet to peer 00184 if (sreg<uint8_t>(socket, Sn_MR) == TCP) { 00185 scmd(socket, DISCON); 00186 } 00187 // close socket 00188 scmd(socket, CLOSE); 00189 // clear Socket Interrupt Register 00190 sreg<uint8_t>(socket, Sn_ICR, 0xff); 00191 return true; 00192 } 00193 00194 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size) 00195 { 00196 if (socket < 0) { 00197 return -1; 00198 } 00199 #if 0 00200 Timer t; 00201 t.reset(); 00202 t.start(); 00203 while(1) { 00204 int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00205 if (size > req_size) { 00206 return size; 00207 } 00208 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00209 break; 00210 } 00211 } 00212 return -1; 00213 #endif 00214 return sreg<uint16_t>(socket, Sn_RX_RSR); 00215 } 00216 00217 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size) 00218 { 00219 if (socket < 0) { 00220 return -1; 00221 } 00222 Timer t; 00223 t.reset(); 00224 t.start(); 00225 while(1) { 00226 int size = sreg<uint16_t>(socket, Sn_TX_FSR); 00227 if (size > req_size) { 00228 return size; 00229 } 00230 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00231 break; 00232 } 00233 } 00234 return -1; 00235 } 00236 00237 int WIZnet_Chip::send(int socket, const char * str, int len) 00238 { 00239 if (socket < 0) { 00240 return -1; 00241 } 00242 00243 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00244 uint32_t sn_tx_base = W7500x_TXMEM_BASE + (uint32_t)(socket<<18); 00245 00246 for(int i=0; i<len; i++) 00247 *(volatile uint8_t *)(sn_tx_base + ((ptr+i)&0xFFFF)) = str[i]; 00248 00249 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00250 scmd(socket, SEND); 00251 00252 uint8_t tmp_Sn_IR; 00253 while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) { 00254 // @Jul.10, 2014 fix contant name, and udp sendto function. 00255 switch (sreg<uint8_t>(socket, Sn_SR)) { 00256 case SOCK_CLOSED : 00257 close(socket); 00258 return 0; 00259 //break; 00260 case SOCK_UDP : 00261 // ARP timeout is possible. 00262 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) { 00263 sreg<uint8_t>(socket, Sn_ICR, INT_TIMEOUT); 00264 return 0; 00265 } 00266 break; 00267 default : 00268 break; 00269 } 00270 } 00271 00272 sreg<uint8_t>(socket, Sn_ICR, INT_SEND_OK); 00273 00274 return len; 00275 } 00276 00277 int WIZnet_Chip::recv(int socket, char* buf, int len) 00278 { 00279 if (socket < 0) { 00280 return -1; 00281 } 00282 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00283 uint32_t sn_rx_base = W7500x_RXMEM_BASE + (uint32_t)(socket<<18); 00284 00285 for(int i=0; i<len; i++) 00286 buf[i] = *(volatile uint8_t *)(sn_rx_base + ((ptr+i)&0xFFFF)); 00287 00288 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00289 scmd(socket, RECV); 00290 00291 return len; 00292 } 00293 00294 int WIZnet_Chip::new_socket() 00295 { 00296 for(int s = 0; s < MAX_SOCK_NUM; s++) { 00297 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00298 return s; 00299 } 00300 } 00301 return -1; 00302 } 00303 00304 uint16_t WIZnet_Chip::new_port() 00305 { 00306 uint16_t port = rand(); 00307 port |= 49152; 00308 return port; 00309 } 00310 00311 bool WIZnet_Chip::link(int wait_time_ms) 00312 { 00313 Timer t; 00314 t.reset(); 00315 t.start(); 00316 while(1) { 00317 int is_link = ethernet_link(); 00318 00319 if (is_link) { 00320 return true; 00321 } 00322 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00323 break; 00324 } 00325 } 00326 return 0; 00327 } 00328 00329 void WIZnet_Chip::set_link(PHYMode phymode) 00330 { 00331 int speed = -1; 00332 int duplex = 0; 00333 00334 switch(phymode) { 00335 case AutoNegotiate : speed = -1; duplex = 0; break; 00336 case HalfDuplex10 : speed = 0; duplex = 0; break; 00337 case FullDuplex10 : speed = 0; duplex = 1; break; 00338 case HalfDuplex100 : speed = 1; duplex = 0; break; 00339 case FullDuplex100 : speed = 1; duplex = 1; break; 00340 } 00341 00342 ethernet_set_link(speed, duplex); 00343 } 00344 00345 uint32_t str_to_ip(const char* str) 00346 { 00347 uint32_t ip = 0; 00348 char* p = (char*)str; 00349 for(int i = 0; i < 4; i++) { 00350 ip |= atoi(p); 00351 p = strchr(p, '.'); 00352 if (p == NULL) { 00353 break; 00354 } 00355 ip <<= 8; 00356 p++; 00357 } 00358 return ip; 00359 } 00360 00361 void printfBytes(char* str, uint8_t* buf, int len) 00362 { 00363 printf("%s %d:", str, len); 00364 for(int i = 0; i < len; i++) { 00365 printf(" %02x", buf[i]); 00366 } 00367 printf("\n"); 00368 } 00369 00370 void printHex(uint8_t* buf, int len) 00371 { 00372 for(int i = 0; i < len; i++) { 00373 if ((i%16) == 0) { 00374 printf("%p", buf+i); 00375 } 00376 printf(" %02x", buf[i]); 00377 if ((i%16) == 15) { 00378 printf("\n"); 00379 } 00380 } 00381 printf("\n"); 00382 } 00383 00384 void debug_hex(uint8_t* buf, int len) 00385 { 00386 for(int i = 0; i < len; i++) { 00387 if ((i%16) == 0) { 00388 debug("%p", buf+i); 00389 } 00390 debug(" %02x", buf[i]); 00391 if ((i%16) == 15) { 00392 debug("\n"); 00393 } 00394 } 00395 debug("\n"); 00396 } 00397 00398 void WIZnet_Chip::scmd(int socket, Command cmd) 00399 { 00400 sreg<uint8_t>(socket, Sn_CR, cmd); 00401 while(sreg<uint8_t>(socket, Sn_CR)); 00402 } 00403 00404 00405 void mdio_init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_MDC, uint16_t GPIO_Pin_MDIO) 00406 { 00407 /* Set GPIOs for MDIO and MDC */ 00408 GPIO_InitTypeDef MDIO_InitDef; 00409 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDIO, PAD_AF1); 00410 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDC, PAD_AF1); 00411 MDIO_InitDef.GPIO_Pin = GPIO_Pin_MDC | GPIO_Pin_MDIO; 00412 MDIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; 00413 HAL_GPIO_Init(GPIOx, &MDIO_InitDef); 00414 } 00415 00416 void output_MDIO(GPIO_TypeDef* GPIOx, uint32_t val, uint32_t n) 00417 { 00418 for(val <<= (32-n); n; val<<=1, n--) 00419 { 00420 if(val & 0x80000000) 00421 HAL_GPIO_SetBits(GPIOx, MDIO); 00422 else 00423 HAL_GPIO_ResetBits(GPIOx, MDIO); 00424 00425 wait_ms(MDC_WAIT); 00426 HAL_GPIO_SetBits(GPIOx, MDC); 00427 wait_ms(MDC_WAIT); 00428 HAL_GPIO_ResetBits(GPIOx, MDC); 00429 } 00430 } 00431 00432 uint32_t input_MDIO( GPIO_TypeDef* GPIOx ) 00433 { 00434 uint32_t i, val=0; 00435 for(i=0; i<16; i++) 00436 { 00437 val <<=1; 00438 HAL_GPIO_SetBits(GPIOx, MDC); 00439 wait_ms(MDC_WAIT); 00440 HAL_GPIO_ResetBits(GPIOx, MDC); 00441 wait_ms(MDC_WAIT); 00442 val |= HAL_GPIO_ReadInputDataBit(GPIOx, MDIO); 00443 } 00444 return (val); 00445 } 00446 00447 void turnaround_MDIO( GPIO_TypeDef* GPIOx) 00448 { 00449 GPIOx->OUTENCLR = MDIO ; 00450 HAL_GPIO_SetBits(GPIOx, MDC); 00451 wait_ms(MDC_WAIT); 00452 HAL_GPIO_ResetBits(GPIOx, MDC); 00453 wait_ms(MDC_WAIT); 00454 } 00455 00456 void idle_MDIO( GPIO_TypeDef* GPIOx ) 00457 { 00458 GPIOx->OUTENSET = MDIO ; 00459 HAL_GPIO_SetBits(GPIOx,MDC); 00460 wait_ms(MDC_WAIT); 00461 HAL_GPIO_ResetBits(GPIOx, MDC); 00462 wait_ms(MDC_WAIT); 00463 } 00464 00465 uint32_t mdio_read(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr) 00466 { 00467 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00468 output_MDIO(GPIOx, 0x06, 4); 00469 output_MDIO(GPIOx, PHY_ADDR, 5); 00470 output_MDIO(GPIOx, PhyRegAddr, 5); 00471 turnaround_MDIO(GPIOx); 00472 uint32_t val = input_MDIO(GPIOx ); 00473 idle_MDIO(GPIOx); 00474 return val; 00475 } 00476 00477 void mdio_write(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr, uint32_t val) 00478 { 00479 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00480 output_MDIO(GPIOx, 0x05, 4); 00481 output_MDIO(GPIOx, PHY_ADDR, 5); 00482 output_MDIO(GPIOx, PhyRegAddr, 5); 00483 output_MDIO(GPIOx, 0x02, 2); 00484 output_MDIO(GPIOx, val, 16); 00485 idle_MDIO(GPIOx); 00486 } 00487 00488 int WIZnet_Chip::ethernet_link(void) { 00489 return ((mdio_read(GPIO_MDC, PHYREG_STATUS)>>SVAL)&0x01); 00490 } 00491 00492 void WIZnet_Chip::ethernet_set_link(int speed, int duplex) { 00493 uint32_t val=0; 00494 if((speed < 0) || (speed > 1)) { 00495 val = CNTL_AUTONEGO; 00496 } else { 00497 val = ((CNTL_SPEED&(speed<<11))|(CNTL_DUPLEX&(duplex<<7))); 00498 } 00499 mdio_write(GPIO_MDC, PHYREG_CONTROL, val); 00500 } 00501 00502 void WIZnet_Chip::reg_rd_mac(uint16_t addr, uint8_t* data) 00503 { 00504 data[0] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+3)); 00505 data[1] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+2)); 00506 data[2] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+1)); 00507 data[3] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+0)); 00508 data[4] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+7)); 00509 data[5] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+6)); 00510 } 00511 00512 void WIZnet_Chip::reg_wr_ip(uint16_t addr, uint8_t cb, const char* ip) 00513 { 00514 uint8_t buf[4]={0,}; 00515 uint32_t wr_ip = 0; 00516 char* p = (char*)ip; 00517 00518 for(int i = 0; i < 4; i++) { 00519 wr_ip = (wr_ip<<8); 00520 buf[i] = atoi(p); 00521 wr_ip |= buf[i]; 00522 p = strchr(p, '.'); 00523 if (p == NULL) break; 00524 p++; 00525 } 00526 *(volatile uint32_t *)(W7500x_WZTOE_BASE + (uint32_t)((cb<<16)+addr)) = wr_ip; 00527 } 00528 00529 void WIZnet_Chip::sreg_ip(int socket, uint16_t addr, const char* ip) { 00530 reg_wr_ip(addr, (uint8_t)(0x01+(socket<<2)), ip); 00531 } 00532 00533 #endif 00534
Generated on Thu Jul 14 2022 05:42:13 by 1.7.2