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 00158 uint8_t tmpSn_SR; 00159 tmpSn_SR = sreg<uint8_t>(socket, Sn_SR); 00160 // packet sending is possible, when state is SOCK_CLOSE_WAIT. 00161 if ((tmpSn_SR == SOCK_ESTABLISHED) || (tmpSn_SR == SOCK_CLOSE_WAIT)) { 00162 return true; 00163 } 00164 00165 return false; 00166 } 00167 // Reset the chip & set the buffer 00168 void WIZnet_Chip::reset() 00169 { 00170 /* S/W Reset PHY */ 00171 mdio_write(GPIO_MDC, PHYREG_CONTROL, 0x8000); 00172 wait_ms(10);//for S/W reset 00173 wait_ms(10);//for MDC I/F RDY 00174 00175 mdio_init(GPIO_MDC, MDC, MDIO); 00176 00177 /* S/W Reset WZTOE */ 00178 reg_wr<uint8_t>(MR, MR_RST); 00179 // set PAD strengh and pull-up for TXD[3:0] and TXE 00180 #ifdef __DEF_USED_IC101AG__ //For using IC+101AG 00181 00182 #if defined(TARGET_WIZwiki_W7500) || defined(TARGET_WIZwiki_W7500ECO) 00183 00184 *(volatile uint32_t *)(0x41003068) = 0x64; //TXD0 00185 *(volatile uint32_t *)(0x4100306C) = 0x64; //TXD1 00186 *(volatile uint32_t *)(0x41003070) = 0x64; //TXD2 00187 *(volatile uint32_t *)(0x41003074) = 0x64; //TXD3 00188 *(volatile uint32_t *)(0x41003050) = 0x64; //TXE 00189 #endif 00190 00191 #endif 00192 00193 // set ticker counter 00194 reg_wr<uint32_t>(TIC100US, (SystemCoreClock/10000)); 00195 // write MAC address inside the WZTOE MAC address register 00196 reg_wr_mac(SHAR, mac); 00197 /* 00198 * set RX and TX buffer size 00199 * for (int socket = 0; socket < MAX_SOCK_NUM; socket++) { 00200 * sreg<uint8_t>(socket, Sn_RXBUF_SIZE, 2); 00201 * sreg<uint8_t>(socket, Sn_TXBUF_SIZE, 2); 00202 * } 00203 */ 00204 } 00205 00206 00207 bool WIZnet_Chip::close(int socket) 00208 { 00209 //pc2.printf("-----------------------------------2222-------------------------------------***\r\n"); 00210 if (socket < 0) { 00211 //pc2.printf("---------------return false1--------***\r\n"); 00212 return false; 00213 } 00214 // if SOCK_CLOSED, return 00215 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) { 00216 //pc2.printf("---------------return true1--------***\r\n"); 00217 return true; 00218 } 00219 // if SOCK_ESTABLISHED, send FIN-Packet to peer 00220 if (sreg<uint8_t>(socket, Sn_MR) == TCP) { 00221 scmd(socket, DISCON); 00222 } 00223 // close socket 00224 scmd(socket, CLOSE); 00225 // clear Socket Interrupt Register 00226 sreg<uint8_t>(socket, Sn_ICR, 0xff); 00227 //pc2.printf("---------------return true2--------***\r\n"); 00228 return true; 00229 } 00230 00231 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size) 00232 { 00233 if (socket < 0) { 00234 return -1; 00235 } 00236 Timer t; 00237 t.reset(); 00238 t.start(); 00239 while(1) { 00240 int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00241 if (size > req_size) { 00242 return size; 00243 } 00244 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00245 break; 00246 } 00247 } 00248 return -1; 00249 } 00250 00251 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size) 00252 { 00253 if (socket < 0) { 00254 return -1; 00255 } 00256 Timer t; 00257 t.reset(); 00258 t.start(); 00259 while(1) { 00260 int size = sreg<uint16_t>(socket, Sn_TX_FSR); 00261 if (size > req_size) { 00262 return size; 00263 } 00264 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00265 break; 00266 } 00267 } 00268 return -1; 00269 } 00270 00271 int WIZnet_Chip::send(int socket, const char * str, int len) 00272 { 00273 if (socket < 0) { 00274 return -1; 00275 } 00276 00277 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00278 uint32_t sn_tx_base = W7500x_TXMEM_BASE + (uint32_t)(socket<<18); 00279 00280 for(int i=0; i<len; i++) 00281 *(volatile uint8_t *)(sn_tx_base + ((ptr+i)&0xFFFF)) = str[i]; 00282 00283 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00284 scmd(socket, SEND); 00285 00286 uint8_t tmp_Sn_IR; 00287 while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) { 00288 // @Jul.10, 2014 fix contant name, and udp sendto function. 00289 switch (sreg<uint8_t>(socket, Sn_SR)) { 00290 case SOCK_CLOSED : 00291 close(socket); 00292 return 0; 00293 //break; 00294 case SOCK_UDP : 00295 // ARP timeout is possible. 00296 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) { 00297 sreg<uint8_t>(socket, Sn_ICR, INT_TIMEOUT); 00298 return 0; 00299 } 00300 break; 00301 default : 00302 break; 00303 } 00304 } 00305 00306 sreg<uint8_t>(socket, Sn_ICR, INT_SEND_OK); 00307 00308 return len; 00309 } 00310 00311 int WIZnet_Chip::recv(int socket, char* buf, int len) 00312 { 00313 if (socket < 0) { 00314 return -1; 00315 } 00316 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00317 uint32_t sn_rx_base = W7500x_RXMEM_BASE + (uint32_t)(socket<<18); 00318 00319 for(int i=0; i<len; i++) 00320 buf[i] = *(volatile uint8_t *)(sn_rx_base + ((ptr+i)&0xFFFF)); 00321 00322 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00323 scmd(socket, RECV); 00324 00325 return len; 00326 } 00327 00328 int WIZnet_Chip::new_socket() 00329 { 00330 for(int s = 0; s < MAX_SOCK_NUM; s++) { 00331 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00332 return s; 00333 } 00334 } 00335 return -1; 00336 } 00337 00338 uint16_t WIZnet_Chip::new_port() 00339 { 00340 uint16_t port = rand(); 00341 port |= 49152; 00342 return port; 00343 } 00344 00345 bool WIZnet_Chip::link(int wait_time_ms) 00346 { 00347 Timer t; 00348 t.reset(); 00349 t.start(); 00350 while(1) { 00351 int is_link = ethernet_link(); 00352 00353 if (is_link) { 00354 return true; 00355 } 00356 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00357 break; 00358 } 00359 } 00360 return 0; 00361 } 00362 00363 void WIZnet_Chip::set_link(PHYMode phymode) 00364 { 00365 int speed = -1; 00366 int duplex = 0; 00367 00368 switch(phymode) { 00369 case AutoNegotiate : speed = -1; duplex = 0; break; 00370 case HalfDuplex10 : speed = 0; duplex = 0; break; 00371 case FullDuplex10 : speed = 0; duplex = 1; break; 00372 case HalfDuplex100 : speed = 1; duplex = 0; break; 00373 case FullDuplex100 : speed = 1; duplex = 1; break; 00374 } 00375 00376 ethernet_set_link(speed, duplex); 00377 } 00378 00379 uint32_t str_to_ip(const char* str) 00380 { 00381 uint32_t ip = 0; 00382 char* p = (char*)str; 00383 for(int i = 0; i < 4; i++) { 00384 ip |= atoi(p); 00385 p = strchr(p, '.'); 00386 if (p == NULL) { 00387 break; 00388 } 00389 ip <<= 8; 00390 p++; 00391 } 00392 return ip; 00393 } 00394 00395 void printfBytes(char* str, uint8_t* buf, int len) 00396 { 00397 printf("%s %d:", str, len); 00398 for(int i = 0; i < len; i++) { 00399 printf(" %02x", buf[i]); 00400 } 00401 printf("\n"); 00402 } 00403 00404 void printHex(uint8_t* buf, int len) 00405 { 00406 for(int i = 0; i < len; i++) { 00407 if ((i%16) == 0) { 00408 printf("%p", buf+i); 00409 } 00410 printf(" %02x", buf[i]); 00411 if ((i%16) == 15) { 00412 printf("\n"); 00413 } 00414 } 00415 printf("\n"); 00416 } 00417 00418 void debug_hex(uint8_t* buf, int len) 00419 { 00420 for(int i = 0; i < len; i++) { 00421 if ((i%16) == 0) { 00422 debug("%p", buf+i); 00423 } 00424 debug(" %02x", buf[i]); 00425 if ((i%16) == 15) { 00426 debug("\n"); 00427 } 00428 } 00429 debug("\n"); 00430 } 00431 00432 void WIZnet_Chip::scmd(int socket, Command cmd) 00433 { 00434 sreg<uint8_t>(socket, Sn_CR, cmd); 00435 while(sreg<uint8_t>(socket, Sn_CR)); 00436 } 00437 00438 00439 void mdio_init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_MDC, uint16_t GPIO_Pin_MDIO) 00440 { 00441 /* Set GPIOs for MDIO and MDC */ 00442 GPIO_InitTypeDef MDIO_InitDef; 00443 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDIO, PAD_AF1); 00444 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDC, PAD_AF1); 00445 MDIO_InitDef.GPIO_Pin = GPIO_Pin_MDC | GPIO_Pin_MDIO; 00446 MDIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; 00447 HAL_GPIO_Init(GPIOx, &MDIO_InitDef); 00448 } 00449 00450 void output_MDIO(GPIO_TypeDef* GPIOx, uint32_t val, uint32_t n) 00451 { 00452 for(val <<= (32-n); n; val<<=1, n--) 00453 { 00454 if(val & 0x80000000) 00455 HAL_GPIO_SetBits(GPIOx, MDIO); 00456 else 00457 HAL_GPIO_ResetBits(GPIOx, MDIO); 00458 00459 wait_ms(MDC_WAIT); 00460 HAL_GPIO_SetBits(GPIOx, MDC); 00461 wait_ms(MDC_WAIT); 00462 HAL_GPIO_ResetBits(GPIOx, MDC); 00463 } 00464 } 00465 00466 uint32_t input_MDIO( GPIO_TypeDef* GPIOx ) 00467 { 00468 uint32_t i, val=0; 00469 for(i=0; i<16; i++) 00470 { 00471 val <<=1; 00472 HAL_GPIO_SetBits(GPIOx, MDC); 00473 wait_ms(MDC_WAIT); 00474 HAL_GPIO_ResetBits(GPIOx, MDC); 00475 wait_ms(MDC_WAIT); 00476 val |= HAL_GPIO_ReadInputDataBit(GPIOx, MDIO); 00477 } 00478 return (val); 00479 } 00480 00481 void turnaround_MDIO( GPIO_TypeDef* GPIOx) 00482 { 00483 GPIOx->OUTENCLR = MDIO ; 00484 HAL_GPIO_SetBits(GPIOx, MDC); 00485 wait_ms(MDC_WAIT); 00486 HAL_GPIO_ResetBits(GPIOx, MDC); 00487 wait_ms(MDC_WAIT); 00488 } 00489 00490 void idle_MDIO( GPIO_TypeDef* GPIOx ) 00491 { 00492 GPIOx->OUTENSET = MDIO ; 00493 HAL_GPIO_SetBits(GPIOx,MDC); 00494 wait_ms(MDC_WAIT); 00495 HAL_GPIO_ResetBits(GPIOx, MDC); 00496 wait_ms(MDC_WAIT); 00497 } 00498 00499 uint32_t mdio_read(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr) 00500 { 00501 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00502 output_MDIO(GPIOx, 0x06, 4); 00503 output_MDIO(GPIOx, PHY_ADDR, 5); 00504 output_MDIO(GPIOx, PhyRegAddr, 5); 00505 turnaround_MDIO(GPIOx); 00506 uint32_t val = input_MDIO(GPIOx ); 00507 idle_MDIO(GPIOx); 00508 return val; 00509 } 00510 00511 void mdio_write(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr, uint32_t val) 00512 { 00513 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00514 output_MDIO(GPIOx, 0x05, 4); 00515 output_MDIO(GPIOx, PHY_ADDR, 5); 00516 output_MDIO(GPIOx, PhyRegAddr, 5); 00517 output_MDIO(GPIOx, 0x02, 2); 00518 output_MDIO(GPIOx, val, 16); 00519 idle_MDIO(GPIOx); 00520 } 00521 00522 int WIZnet_Chip::ethernet_link(void) { 00523 return ((mdio_read(GPIO_MDC, PHYREG_STATUS)>>SVAL)&0x01); 00524 } 00525 00526 void WIZnet_Chip::ethernet_set_link(int speed, int duplex) { 00527 uint32_t val=0; 00528 if((speed < 0) || (speed > 1)) { 00529 val = CNTL_AUTONEGO; 00530 } else { 00531 val = ((CNTL_SPEED&(speed<<11))|(CNTL_DUPLEX&(duplex<<7))); 00532 } 00533 mdio_write(GPIO_MDC, PHYREG_CONTROL, val); 00534 } 00535 00536 void WIZnet_Chip::reg_rd_mac(uint16_t addr, uint8_t* data) 00537 { 00538 data[0] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+3)); 00539 data[1] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+2)); 00540 data[2] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+1)); 00541 data[3] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+0)); 00542 data[4] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+7)); 00543 data[5] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+6)); 00544 } 00545 00546 void WIZnet_Chip::reg_wr_ip(uint16_t addr, uint8_t cb, const char* ip) 00547 { 00548 uint8_t buf[4]={0,}; 00549 uint32_t wr_ip = 0; 00550 char* p = (char*)ip; 00551 00552 for(int i = 0; i < 4; i++) { 00553 wr_ip = (wr_ip<<8); 00554 buf[i] = atoi(p); 00555 wr_ip |= buf[i]; 00556 p = strchr(p, '.'); 00557 if (p == NULL) break; 00558 p++; 00559 } 00560 *(volatile uint32_t *)(W7500x_WZTOE_BASE + (uint32_t)((cb<<16)+addr)) = wr_ip; 00561 } 00562 00563 void WIZnet_Chip::sreg_ip(int socket, uint16_t addr, const char* ip) { 00564 reg_wr_ip(addr, (uint8_t)(0x01+(socket<<2)), ip); 00565 } 00566 00567 #endif 00568 00569
Generated on Thu Jul 14 2022 10:00:04 by
1.7.2
