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