what?
Dependents: w7500-paho-mqtt openHAB_mqtt_W7500 kakaoIoTchatbot w7500-RFID-mqtt
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) 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 Timer t; 00200 t.reset(); 00201 t.start(); 00202 while(1) { 00203 int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00204 if (size > req_size) { 00205 return size; 00206 } 00207 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00208 break; 00209 } 00210 } 00211 return -1; 00212 } 00213 00214 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size) 00215 { 00216 if (socket < 0) { 00217 return -1; 00218 } 00219 Timer t; 00220 t.reset(); 00221 t.start(); 00222 while(1) { 00223 int size = sreg<uint16_t>(socket, Sn_TX_FSR); 00224 if (size > req_size) { 00225 return size; 00226 } 00227 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00228 break; 00229 } 00230 } 00231 return -1; 00232 } 00233 00234 int WIZnet_Chip::send(int socket, const char * str, int len) 00235 { 00236 if (socket < 0) { 00237 return -1; 00238 } 00239 00240 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00241 uint32_t sn_tx_base = W7500x_TXMEM_BASE + (uint32_t)(socket<<18); 00242 00243 for(int i=0; i<len; i++) 00244 *(volatile uint8_t *)(sn_tx_base + ((ptr+i)&0xFFFF)) = str[i]; 00245 00246 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00247 scmd(socket, SEND); 00248 00249 uint8_t tmp_Sn_IR; 00250 while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) { 00251 // @Jul.10, 2014 fix contant name, and udp sendto function. 00252 switch (sreg<uint8_t>(socket, Sn_SR)) { 00253 case SOCK_CLOSED : 00254 close(socket); 00255 return 0; 00256 //break; 00257 case SOCK_UDP : 00258 // ARP timeout is possible. 00259 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) { 00260 sreg<uint8_t>(socket, Sn_ICR, INT_TIMEOUT); 00261 return 0; 00262 } 00263 break; 00264 default : 00265 break; 00266 } 00267 } 00268 00269 sreg<uint8_t>(socket, Sn_ICR, INT_SEND_OK); 00270 00271 return len; 00272 } 00273 00274 int WIZnet_Chip::recv(int socket, char* buf, int len) 00275 { 00276 if (socket < 0) { 00277 return -1; 00278 } 00279 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00280 uint32_t sn_rx_base = W7500x_RXMEM_BASE + (uint32_t)(socket<<18); 00281 00282 for(int i=0; i<len; i++) 00283 buf[i] = *(volatile uint8_t *)(sn_rx_base + ((ptr+i)&0xFFFF)); 00284 00285 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00286 scmd(socket, RECV); 00287 00288 return len; 00289 } 00290 00291 int WIZnet_Chip::new_socket() 00292 { 00293 for(int s = 0; s < MAX_SOCK_NUM; s++) { 00294 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00295 return s; 00296 } 00297 } 00298 return -1; 00299 } 00300 00301 uint16_t WIZnet_Chip::new_port() 00302 { 00303 uint16_t port = rand(); 00304 port |= 49152; 00305 return port; 00306 } 00307 00308 bool WIZnet_Chip::link(int wait_time_ms) 00309 { 00310 Timer t; 00311 t.reset(); 00312 t.start(); 00313 while(1) { 00314 int is_link = ethernet_link(); 00315 00316 if (is_link) { 00317 return true; 00318 } 00319 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00320 break; 00321 } 00322 } 00323 return 0; 00324 } 00325 00326 void WIZnet_Chip::set_link(PHYMode phymode) 00327 { 00328 int speed = -1; 00329 int duplex = 0; 00330 00331 switch(phymode) { 00332 case AutoNegotiate : speed = -1; duplex = 0; break; 00333 case HalfDuplex10 : speed = 0; duplex = 0; break; 00334 case FullDuplex10 : speed = 0; duplex = 1; break; 00335 case HalfDuplex100 : speed = 1; duplex = 0; break; 00336 case FullDuplex100 : speed = 1; duplex = 1; break; 00337 } 00338 00339 ethernet_set_link(speed, duplex); 00340 } 00341 00342 uint32_t str_to_ip(const char* str) 00343 { 00344 uint32_t ip = 0; 00345 char* p = (char*)str; 00346 for(int i = 0; i < 4; i++) { 00347 ip |= atoi(p); 00348 p = strchr(p, '.'); 00349 if (p == NULL) { 00350 break; 00351 } 00352 ip <<= 8; 00353 p++; 00354 } 00355 return ip; 00356 } 00357 00358 void printfBytes(char* str, uint8_t* buf, int len) 00359 { 00360 printf("%s %d:", str, len); 00361 for(int i = 0; i < len; i++) { 00362 printf(" %02x", buf[i]); 00363 } 00364 printf("\n"); 00365 } 00366 00367 void printHex(uint8_t* buf, int len) 00368 { 00369 for(int i = 0; i < len; i++) { 00370 if ((i%16) == 0) { 00371 printf("%p", buf+i); 00372 } 00373 printf(" %02x", buf[i]); 00374 if ((i%16) == 15) { 00375 printf("\n"); 00376 } 00377 } 00378 printf("\n"); 00379 } 00380 00381 void debug_hex(uint8_t* buf, int len) 00382 { 00383 for(int i = 0; i < len; i++) { 00384 if ((i%16) == 0) { 00385 debug("%p", buf+i); 00386 } 00387 debug(" %02x", buf[i]); 00388 if ((i%16) == 15) { 00389 debug("\n"); 00390 } 00391 } 00392 debug("\n"); 00393 } 00394 00395 void WIZnet_Chip::scmd(int socket, Command cmd) 00396 { 00397 sreg<uint8_t>(socket, Sn_CR, cmd); 00398 while(sreg<uint8_t>(socket, Sn_CR)); 00399 } 00400 00401 00402 void mdio_init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_MDC, uint16_t GPIO_Pin_MDIO) 00403 { 00404 /* Set GPIOs for MDIO and MDC */ 00405 GPIO_InitTypeDef MDIO_InitDef; 00406 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDIO, PAD_AF1); 00407 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDC, PAD_AF1); 00408 MDIO_InitDef.GPIO_Pin = GPIO_Pin_MDC | GPIO_Pin_MDIO; 00409 MDIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; 00410 HAL_GPIO_Init(GPIOx, &MDIO_InitDef); 00411 } 00412 00413 void output_MDIO(GPIO_TypeDef* GPIOx, uint32_t val, uint32_t n) 00414 { 00415 for(val <<= (32-n); n; val<<=1, n--) 00416 { 00417 if(val & 0x80000000) 00418 HAL_GPIO_SetBits(GPIOx, MDIO); 00419 else 00420 HAL_GPIO_ResetBits(GPIOx, MDIO); 00421 00422 wait_ms(MDC_WAIT); 00423 HAL_GPIO_SetBits(GPIOx, MDC); 00424 wait_ms(MDC_WAIT); 00425 HAL_GPIO_ResetBits(GPIOx, MDC); 00426 } 00427 } 00428 00429 uint32_t input_MDIO( GPIO_TypeDef* GPIOx ) 00430 { 00431 uint32_t i, val=0; 00432 for(i=0; i<16; i++) 00433 { 00434 val <<=1; 00435 HAL_GPIO_SetBits(GPIOx, MDC); 00436 wait_ms(MDC_WAIT); 00437 HAL_GPIO_ResetBits(GPIOx, MDC); 00438 wait_ms(MDC_WAIT); 00439 val |= HAL_GPIO_ReadInputDataBit(GPIOx, MDIO); 00440 } 00441 return (val); 00442 } 00443 00444 void turnaround_MDIO( GPIO_TypeDef* GPIOx) 00445 { 00446 GPIOx->OUTENCLR = MDIO ; 00447 HAL_GPIO_SetBits(GPIOx, MDC); 00448 wait_ms(MDC_WAIT); 00449 HAL_GPIO_ResetBits(GPIOx, MDC); 00450 wait_ms(MDC_WAIT); 00451 } 00452 00453 void idle_MDIO( GPIO_TypeDef* GPIOx ) 00454 { 00455 GPIOx->OUTENSET = MDIO ; 00456 HAL_GPIO_SetBits(GPIOx,MDC); 00457 wait_ms(MDC_WAIT); 00458 HAL_GPIO_ResetBits(GPIOx, MDC); 00459 wait_ms(MDC_WAIT); 00460 } 00461 00462 uint32_t mdio_read(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr) 00463 { 00464 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00465 output_MDIO(GPIOx, 0x06, 4); 00466 output_MDIO(GPIOx, PHY_ADDR, 5); 00467 output_MDIO(GPIOx, PhyRegAddr, 5); 00468 turnaround_MDIO(GPIOx); 00469 uint32_t val = input_MDIO(GPIOx ); 00470 idle_MDIO(GPIOx); 00471 return val; 00472 } 00473 00474 void mdio_write(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr, uint32_t val) 00475 { 00476 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00477 output_MDIO(GPIOx, 0x05, 4); 00478 output_MDIO(GPIOx, PHY_ADDR, 5); 00479 output_MDIO(GPIOx, PhyRegAddr, 5); 00480 output_MDIO(GPIOx, 0x02, 2); 00481 output_MDIO(GPIOx, val, 16); 00482 idle_MDIO(GPIOx); 00483 } 00484 00485 int WIZnet_Chip::ethernet_link(void) { 00486 return ((mdio_read(GPIO_MDC, PHYREG_STATUS)>>SVAL)&0x01); 00487 } 00488 00489 void WIZnet_Chip::ethernet_set_link(int speed, int duplex) { 00490 uint32_t val=0; 00491 if((speed < 0) || (speed > 1)) { 00492 val = CNTL_AUTONEGO; 00493 } else { 00494 val = ((CNTL_SPEED&(speed<<11))|(CNTL_DUPLEX&(duplex<<7))); 00495 } 00496 mdio_write(GPIO_MDC, PHYREG_CONTROL, val); 00497 } 00498 00499 void WIZnet_Chip::reg_rd_mac(uint16_t addr, uint8_t* data) 00500 { 00501 data[0] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+3)); 00502 data[1] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+2)); 00503 data[2] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+1)); 00504 data[3] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+0)); 00505 data[4] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+7)); 00506 data[5] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+6)); 00507 } 00508 00509 void WIZnet_Chip::reg_wr_ip(uint16_t addr, uint8_t cb, const char* ip) 00510 { 00511 uint8_t buf[4]={0,}; 00512 uint32_t wr_ip = 0; 00513 char* p = (char*)ip; 00514 00515 for(int i = 0; i < 4; i++) { 00516 wr_ip = (wr_ip<<8); 00517 buf[i] = atoi(p); 00518 wr_ip |= buf[i]; 00519 p = strchr(p, '.'); 00520 if (p == NULL) break; 00521 p++; 00522 } 00523 *(volatile uint32_t *)(W7500x_WZTOE_BASE + (uint32_t)((cb<<16)+addr)) = wr_ip; 00524 } 00525 00526 void WIZnet_Chip::sreg_ip(int socket, uint16_t addr, const char* ip) { 00527 reg_wr_ip(addr, (uint8_t)(0x01+(socket<<2)), ip); 00528 } 00529 00530 #endif 00531
Generated on Tue Jul 12 2022 20:27:29 by 1.7.2