안녕하세요 w5500 chip을 사용해서 SPI를 사용해 ethernet을 porting하던 중 아래와 같은 사항으로 진도가 나가지 않아 문의 드립니다.
init을 할 때 아래와 같이 처리했습니다.
if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1) {
DEBUG((EFI_D_INFO, “WIZCHIP Initialized fail.\n”));
return WIZCHIP_INIT_FAIL;
}
do {
if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1) {
DEBUG((EFI_D_INFO, “Unknown PHY Link status.\n”));
return WIZCHIP_PHYLINK_FAIL;
}
res = tmp;
if (retry_count < link_wait_sec_time){
msleep(1500);
retry_count++;
} else {
res = PHY_LINK_OFF;
break;
}
} while (tmp == PHY_LINK_OFF);
PHY link가 정상적으로 된 것 까지 확인한 뒤 아래 code로 ethernet을 설정했습니다.
void WIZCHIP_NetConf(UINT8* mac_addr, UINT8* ip_addr, UINT8* gateway, UINT8* net_mask)
{
//default setting
wiz_NetInfo gWIZNETINFO = {
{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35 }, // Mac address
{ 192, 168, 0, 100 }, // IP address
{ 192, 168, 0, 1}, // Gateway
{ 255, 255, 255, 0}, // net mask
{ 8, 8, 8, 0}, // DNS Server
};
DEBUG((EFI_D_INFO, "[YKCHO] WIZCHIP_NetConf into\n"));
DEBUG((EFI_D_INFO, "mac_addr : %02x:%02x:%02x:%02x:%02x:%02x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]));
DEBUG((EFI_D_INFO, "ip_addr : %u:%u:%u:%u\n", ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3]));
DEBUG((EFI_D_INFO, "gateway : %u:%u:%u:%u\n", gateway[0], gateway[1], gateway[2], gateway[3]));
DEBUG((EFI_D_INFO, "gateway : %u:%u:%u:%u\n", net_mask[0], net_mask[1], net_mask[2], net_mask[3]));
gWIZNETINFO.mac[0] = mac_addr[0];
gWIZNETINFO.mac[1] = mac_addr[1];
gWIZNETINFO.mac[2] = mac_addr[2];
gWIZNETINFO.mac[3] = mac_addr[3];
gWIZNETINFO.mac[4] = mac_addr[4];
gWIZNETINFO.mac[5] = mac_addr[5];
gWIZNETINFO.gw[0] = gateway[0];
gWIZNETINFO.gw[1] = gateway[1];
gWIZNETINFO.gw[2] = gateway[2];
gWIZNETINFO.gw[3] = gateway[3];
gWIZNETINFO.ip[0] = ip_addr[0];
gWIZNETINFO.ip[1] = ip_addr[1];
gWIZNETINFO.ip[2] = ip_addr[2];
gWIZNETINFO.ip[3] = ip_addr[3];
gWIZNETINFO.sn[0] = net_mask[0];
gWIZNETINFO.sn[1] = net_mask[1];
gWIZNETINFO.sn[2] = net_mask[2];
gWIZNETINFO.sn[3] = net_mask[3];
gWIZNETINFO.dhcp = NETINFO_STATIC;
ctlnetwork(CN_SET_NETINFO, (void*) &gWIZNETINFO);
ctlnetwork(CN_GET_NETINFO, (void*) &gWIZNETINFO);
DEBUG((EFI_D_INFO, "[YKCHO] WIZCHIP_NetConf get\n"));
DEBUG((EFI_D_INFO, "mac_addr : %02x:%02x:%02x:%02x:%02x:%02x\n", gWIZNETINFO.mac[0], gWIZNETINFO.mac[1], gWIZNETINFO.mac[2], gWIZNETINFO.mac[3], gWIZNETINFO.mac[4], gWIZNETINFO.mac[5]));
DEBUG((EFI_D_INFO, "ip_addr : %u:%u:%u:%u\n", gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3]));
DEBUG((EFI_D_INFO, "gateway : %u:%u:%u:%u\n", gWIZNETINFO.gw[0], gWIZNETINFO.gw[1], gWIZNETINFO.gw[2], gWIZNETINFO.gw[3]));
DEBUG((EFI_D_INFO, "net_mask : %u:%u:%u:%u\n", gWIZNETINFO.sn[0], gWIZNETINFO.sn[1], gWIZNETINFO.sn[2], gWIZNETINFO.sn[3]));
}
위 처럼 해서 정상적으로 설정된 것 까지 확인한 뒤 ping을 날렸을 때 정상적으로 응답하는 것을 확인했습니다.
위 상태에서 무한루프를 돌리는 부분에 아래와 같이 loopback_tcps()를 사용해서 루프백을 테스트하는 code를 추가하였습니다.
while (1)
{
UINT8 s_buf[2048];
…
#if 1//ykcho test
loopback_tcps(1, s_buf, 61290);
#endif
}
위처럼 했을 때 loopback_tcps()의 case SOCK_CLOSED 부분을 진입하면서 socket()을 실행하고 socket()에서 taddr을 확인 후 close()를 타게 되는데
close()에서 setSn_CR(sn,Sn_CR_CLOSE); 이후 while( getSn_CR(sn) ); 부분에서 0x0으로 clear이 되지 않아 무한루프를 돌고 있습니다.
혹시 초기화를 하는 부분에서 빠진게 있는지, 아니면 무엇을 더 해야하는게 있는 것인지 문의 드립니다.
혹시 몰라 write, read할 때 레지스터 주소가 잘못되었는지, 값은 정확한지 다 확인은 해 봤으나 모두 정상적으로 기록되고 있습니다.
ioLibrary는 V3.1.1을 다운받았습니다.
문제가 발생하는 source는 아래와 같습니다.
int8_t close(uint8_t sn)
{
CHECK_SOCKNUM();
//A20160426 : Applied the erratum 1 of W5300
#if (WIZCHIP == 5300)
//M20160503 : Wrong socket parameter. s → sn
//if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != getSn_TxMAX(s)) )
if( ((getSn_MR(sn)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(sn) != getSn_TxMAX(sn)) )
{
uint8 destip[4] = {0, 0, 0, 1};
// TODO
// You can wait for completing to sending data;
// wait about 1 second;
// if you have completed to send data, skip the code of erratum 1
// ex> wait_1s();
// if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue;
//
//M20160503 : The socket() of close() calls close() itself again. It occures a infinite loop - close()->socket()->close()->socket()-> ~
//socket(s,Sn_MR_UDP,0x3000,0);
//sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
setSn_MR(sn,Sn_MR_UDP);
setSn_PORTR(sn, 0x3000);
setSn_CR(sn,Sn_CR_OPEN);
while(getSn_CR(sn) != 0);
while(getSn_SR(sn) != SOCK_UDP);
sendto(sn,destip,1,destip,0x3000); // send the dummy data to an unknown destination(0.0.0.1).
};
#endif
setSn_CR(sn,Sn_CR_CLOSE);
/* wait to process the command… */
while( getSn_CR(sn) ); ← 이 부분…