안녕하세요.
DSP28335 와 WIZ811MJ 모듈을 가지고 개발하는 개발자입니다.
소켓 0 를 통해 2048byte를 dSP28335 에서 PC로 데이터를 송신하는 펌웨어를 구성하였습니다.
보내고자 하는 데이터가 16bit 데이터를 송신하는데 간헐적으로 데이터가 송신이 안되는 경우가 발생을 합니다.
데이터 패킷 상위 8bit 하위 8bit 이렇게 송신을 합니다.
예를 들면
DSP 송신 :
0x01 0xAB 0x01 0xAB 0x01 0xAB 0x01 0xAB 0x01 0xAB 0x01 0xAB 0x01 0xAB : 2048 바이트
PC 수신 :
0x01 0xAB 0x01 0xAB 0x01 0xAB 0x01 0xAB 0xAB 0xAB 0x01 0xAB 0x01 0xAB : 2048 바이트
PC 측 수신에서 0x01 0xAB 값이 수신이 되다가 0xAB 0XAB 이값이 수신이 됩니다.
매번 생기는 증상은 아니고, 간헐적으로 생기고, 한번 생기기 시작하면 2048 중에서 특정한 위치에서 동일하게 발생 합니다.
PC 수신측은 작성한 프로그램으로 받아도 동일한 증상이고, wire shark 프로그램으로 받아도 동일한 증상입니다.
제가 구현한 소스는 W5100_ATMega_WEBSERV-master 프로그램을 수정하였습니다.
하드웨어 환경은 SPI 클럭 10Mhz 입니다.
TCP sever 함수는 아래와 같습니다.
void W5100_TCP_SOCKET_Flow(void)
{
mysocketstate = W51_read(sockaddr+W5100_SR_OFFSET);
switch (mysocketstate) // based on current status of socket...
{
case W5100_SKT_SR_CLOSED: // if socket is closed...
if (OpenSocket(mysocket, W5100_SKT_MR_TCP, HTTP_PORT) == mysocket) // if successful opening a socket...
{
socketreconnectcounter++;
Listen(mysocket);
DELAY_US(1000);
}
break;
case W5100_SKT_SR_ESTABLISHED: // if socket connection is established...
if(RECT.DMADataSendFlag)
{
if(DMAFlagCount > 4)
{
DMAFlagCountdisplay = DMAFlagCount;
DMAFlagCount = 0;
switch(DMASendFlag)
{
case SENDPING:
DMASendFlag = SENDSTOP;
datasendstate = Send16(mysocket, ADC_RESULT, sizeof(ADC_RESULT));
break;
case SENDPONG:
DMASendFlag = SENDSTOP;
datasendstate = Send16(mysocket, ADC_RESULT_BUFF, sizeof(ADC_RESULT_BUFF));
break;
case SENDSTOP:
break;
default :
break;
}
}
}
else
{
DMASendFlag = SENDSTOP;
}
break;
case W5100_SKT_SR_FIN_WAIT:
case W5100_SKT_SR_CLOSING:
case W5100_SKT_SR_TIME_WAIT:
case W5100_SKT_SR_CLOSE_WAIT:
case W5100_SKT_SR_LAST_ACK:
DisconnectSocket(mysocket);
CloseSocket(mysocket);
break;
}
}
send 구현 함수는 아래와 같습니다.
Uint8 Send16(Uint8 sock, const Uint16 *buf, Uint16 buflen)
{
Uint16 ptr;
Uint16 offaddr;
Uint16 realaddr;
Uint16 txsize;
Uint16 timeout;
Uint16 sockaddr;
// GPIO0_ON;
// Uint16 DMASendFlagState;
// ----------------------(1) 1msec -------------------------------------------------------------------
if (buflen == 0 || sock >= W5100_NUM_SOCKETS) return W5100_FAIL; // ignore illegal requests
sockaddr = W5100_SKT_BASE(sock); // calc base addr for this socket
// Make sure the TX Free Size Register is available
txsize = W51_read(sockaddr+W5100_TX_FSR_OFFSET); // make sure the TX free-size reg is available
txsize = (((txsize & 0x00FF) << 8 ) + W51_read(sockaddr+W5100_TX_FSR_OFFSET + 1));
timeout = 0;
while (txsize < buflen)
{
// DELAY_US(10);
txsize = W51_read(sockaddr+W5100_TX_FSR_OFFSET); // make sure the TX free-size reg is available
txsize = (((txsize & 0x00FF) << 8 ) + W51_read(sockaddr+W5100_TX_FSR_OFFSET + 1));
if (timeout++ > 1000) // if max delay has passed...
{
DisconnectSocket(sock); // can't connect, close it down
return W5100_FAIL; // show failure
}
}
// Read the Tx Write Pointer
ptr = W51_read(sockaddr+W5100_TX_WR_OFFSET);
offaddr = (((ptr & 0x00FF) << 8 ) + W51_read(sockaddr+W5100_TX_WR_OFFSET + 1));
//------------------(1) 1msec end ------------------------------------------------------------------------
while (buflen)
{
buflen--;
realaddr = W5100_TXBUFADDR + (offaddr & W5100_TX_BUF_MASK); // calc W5100 physical buffer addr for this socket
static Uint8 tmp;
tmp = *buf & 0x00FF;
W51_write(realaddr, tmp); // send a upper byte of application data to TX buffer
offaddr++; // next TX buffer addr
tmp = ((*buf) >> 8)&0x00FF;
W51_write(realaddr+1, tmp); // send a lower byte of application data to TX buffer
offaddr++; // next TX buffer addr
buf++; // next input buffer addr
if(DMASendFlag)
{
// return DMA_OVERFLOW;
}
}
W51_write(sockaddr+W5100_TX_WR_OFFSET, (offaddr & 0xFF00) >> 8); // send MSB of new write-pointer addr
W51_write(sockaddr+W5100_TX_WR_OFFSET + 1, (offaddr & 0x00FF)); // send LSB
W51_write(sockaddr+W5100_CR_OFFSET, W5100_SKT_CR_SEND); // start the send on its way
while (W51_read(sockaddr+W5100_CR_OFFSET)) ; // loop until socket starts the send (blocks!!)
// GPIO0_OFF;
return W5100_OK;
}
검토 의견 부탁드립니다.