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_Ricky 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 Tue Jul 12 2022 18:45:24 by
1.7.2
