WIZnet Developer Forum

W5500 SPI 통신을 이용한 TCP/IP 통신 에러

안녕하세요.

W5500에 SPI 통신을 사용하는 장비에서 TCP/IP로 통신을 합니다.

임베디드 장비는 TCP 서버 모드로 동작을 하구요.
PC에서 Data를 전송하면 임베디드 장비(이하 장비)에서 Data를 잘 받습니다.
하지만 장비에서 PC로 send 명령으로 자료를 보내면 한번보낸이후에는 항상 전송이 안됩니다.

이런 경우에도 PC에서 자료를 보내면 장비에서는 잘 받습니다.

다시 정리하면…

장비에서 보내는 Packet은 한번만 전송되고 그 이후에는 항상 send 결과값이 0입니다.

이유가 뭘까요?

감사합니다.

환경
PC -----(TCP/IP)----- W5500 -----(SPI)----- 임베디드 장비

정상동작
PC ----->(TCP/IP)-----> W5500 ----->(SPI)-----> 임베디드 장비

비정상 동작(1회만 성공)
PC <-----(TCP/IP)<----- W5500 <-----(SPI)<----- 임베디드 장비

어느 부분에서 문제가 생겼는지(화살표 구간별) 디버깅이 필요합니다.

임베디드 장비의 socket.c 파일에 있는 send( ) 함수에서 에러?가 발생하네요.

int32_t send(uint8_t sn, uint8_t * buf, uint16_t len)
{
uint8_t tmp=0;
uint16_t freesize=0;

CHECK_SOCKNUM();
CHECK_SOCKMODE(Sn_MR_TCP);
CHECK_SOCKDATA();
tmp = getSn_SR(sn);
if(tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) return SOCKERR_SOCKSTATUS;
if( sock_is_sending & (1<<sn) )
{
tmp = getSn_IR(sn);
if(tmp & Sn_IR_SENDOK)
{
setSn_IR(sn, Sn_IR_SENDOK);
//M20150401 : Typing Error
//#if WZICHIP == 5200
#if WIZCHIP == 5200
if(getSn_TX_RD(sn) != sock_next_rd[sn])
{
setSn_CR(sn,Sn_CR_SEND);
while(getSn_CR(sn));
return SOCK_BUSY;
}
#endif
sock_is_sending &= ~(1<<sn);
}
else if(tmp & Sn_IR_TIMEOUT)
{
close(sn);
return SOCKERR_TIMEOUT;
}
else return SOCK_BUSY;
}
freesize = getSn_TxMAX(sn);
if (len > freesize) len = freesize; // check size not to exceed MAX size.
while(1)
{
freesize = getSn_TX_FSR(sn);
tmp = getSn_SR(sn);
if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT))
{
close(sn);
return SOCKERR_SOCKSTATUS;
}
if( (sock_io_mode & (1<<sn)) && (len > freesize) ) return SOCK_BUSY;
if(len <= freesize) break;
}
wiz_send_data(sn, buf, len);
#if WIZCHIP == 5200
sock_next_rd[sn] = getSn_TX_RD(sn) + len;
#endif

#if WIZCHIP == 5300
setSn_TX_WRSR(sn,len);
#endif

setSn_CR(sn,Sn_CR_SEND);
/* wait to process the command… */
while(getSn_CR(sn));
sock_is_sending |= (1 << sn);
//M20150409 : Explicit Type Casting
//return len;
return (int32_t)len;
}

첫 packet을 전송한 후에 다음 send를 수행하는 경우 위에 Bold로 표시된 부분인 SOCK_BUSY값이 반환됩니다.

이런경우 어떤 부분을 살펴봐야 할까요?

send 후에 sock_is_sending 에 설정된 bit를 Clear하지 않아서 발생하는 문제입니다.

send 후 인터럽트 처리루틴에서 Sn_IR_SENDOK 가 발생하면 socket.c 파일에 static으로 선언된 sock_is_sending 변수의 해당 flag를 clear해주면 다음 전송이 정상적으로 이루어 지기는 합니다.

인터럽트와 send 함수사이에 sock_is_sending 처리부분을 좀더 살펴보면 해결이될것 같습니다.

감사합니다.

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.