yangyang
Fork of WIZnetInterface by
Embed:
(wiki syntax)
Show/hide line numbers
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