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