W5100의 통신이 끊어지는 현상

안녕하십니까?

저는 DSP28335와 WIZ811MJ 이더넷 모듈을 이용하여 TCP 통신을 구현하고 있는 사람있습니다.

실시간 전송이라는 어려운 문제를 풀려고 하는데 문제가 생겨 글을 올립니다.

DSP28335 : 서버
PC : 클라이언트

SPI 통신 방식

으로 통신을 하는데 소켓0 에 2k 데이터를 서버에서 클라이언트로 데이터를 보내는 프로그램을 작성하고 있습니다.

근데, 2K 데이터를 3msec 정도의 주기로 WIZ811MJ 에 데이터를 send 하는데

불규칙적으로 소켓이 닫히는 현상이 발생합니다. 2K 데이터 에서 4K 데이터로 늘이면 소켓이 바로 닫혀버리네요.

1K 데이터로 보내면 1분 정도 보내다가 소켓이 닫히고요 ㅜ ㅜ

포럼에서 찾아보니 W5100에는 소켓이 4개 있고, 각각 기본적으로 2K 메모리가 할당되어 있다고 그래서 기본 메모리를 확장하면 된다고 확인하였습니다.

여기서 질문이 있습니다.

저는 소켓 0 만 사용을 하고 다른 채널은 사용을 안하고자 합니다.

질문 1 : 소켓0에 TX 최대 메모리인 8K 바이트를 할당할 수 있는지요?
질문 2 : 소켓0에 8K 메모리를 할당할 때 그외 소켓 설정을 따로 해야 하는지요? 소켓 diable 이라든지 , 소켓 2,3,4 0K 메모리 할당 설정이라든지
질문 3 : 이더넷 통신을 RX 을 쓰지 않고 TX만 쓴다면 RX 메모리도 활용이 가능한지요?

5usec ADC 샘플링 데이터를 3msec안에 2K 데이터를 보내야 하거든요 ㅜ ㅜ
확인을 해보니 2K 를 보내든 1K를 보내든 시간을 거의 동일해서 한번 보낼 때 최대한 많이 보낼려고 합니다.

검토 의견 부탁드립니다.

두서없는 글을 읽어 주셔서 감사합니다. ^^

안녕하세요.

질문에 답변드리기 이전에, 전송 중에 소켓이 close된다고 하셨는데, 먼저 왜 socket이 close가되는원인 분석이 우선되어야 합니다. socket close 문제와 socket tx buffer 크기와는 전혀 상관없음을 알려드립니다.

답변 1 : socket 최대 tx buffer 사이즈는 8K를 사용할 수 있습니다.
답변 2 : tx memory 설정 register TMSR 값을 0x03으로 설정하셔야 합니다.
사용하지 않는 socket들은 close 상테를 유지하셔야 합니다.
답변 3: socket의 TX, RX memory는 물리적으로 분리되어 있어,
RX memory 영역을 socket RX buffer로 할당할 수 없습니다.

참고로 말씀하신 전송 Bandwidth는 (1000ms/3ms) X 2048 X 8 = 약 5.5Mbps 로 계산됩니다.
DSP칩을 사용하시는 것으로 2KB socket TX buffer로도 충분히 5.5Mbps 가능할 것으로 판단됩니다.

감사합니다.

감사합니다.

제가 DSP28335 의 SPI 클럭을 10MHZ 이상으로 해서 W5100과 IP 주소를 쓰고 다시 읽으니 쓰레기 값이 들어오더라구요.

SPI 클럭을 10MHZ 이상 올리지를 못하겠네요.

10MHz 클럭으로 전송 시 이더넷 통신속도가 1.5Mbps가 나오던데요.

전송속도를 올리는 스킬이 있는지요?

저는 wiznet git에 있는 W5100_ATMega_WEBSERV-master 소스를 수정하여 사용하고 있습니다.

send 함수를 수정하여 다음과 같이 수정하였습니다.

DSP 28335의 메모리 특성상 16bit 메모리로 고정이 되어 기존의 send()함수를 사용하지 못하고 수정하였습니다.

Uint8 Send16(Uint8 sock, const Uint16 *buf, Uint16 buflen)
{
Uint16 ptr;
Uint16 offaddr;
Uint16 realaddr;
Uint16 txsize;
Uint16 timeout;
Uint16 sockaddr;
// Uint16 DMASendFlagState;

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));
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;
    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!!)

return  W5100_OK;

}

위와 같이 수정하여 전송하면 전송속도가 1.5Mbps가 최고이더라구요. ㅠ ㅠ

전송 속도를 올릴 수 있는 방법이 있는지요?

안녕하세요.
W5100의 SPI 경우 속도가 나오지 않을 수 있습니다.
Logic 설계적으로 SPI clock을 sampling하여 처리하도록 구현되어 있어 속도 향상에는 한계가 있습니다.

Bus I/F를 사용하시거나, W5500이나 W6100으로 변경할 것을 권장합니다.

16bit mode라 할 지라도 8bit bus로 사용할 수 있는 것으로 알고 있습니다.

DSP가 16bit Address Space를 사용할 것으로 예상이 되므로, W5100의 Register Map를 2배로 증가시켜서 정의하시고 8bit를 마치 16bit 인것처럼 처리하시면 될 것 같습니다.

예로)
기존 8bit 정의가 아래와 같다면

#define IR 0x0008
#define IMR 0x0009

이를 16bit 정의로 변경하시어 access하시면 될 것 같습니다.
#define IR (0x0008 << 2)
#define IMR (0x0009 <<2)

감사합니다.