W5100 SPI Packet Format Error

#1

I use W5100 as tcp server. I can open socket and listen it besides i can connect it from pc as client there is no problem in that. But When i call sysinit(0x55, 0x55) parameter. I can not read Tx_WR and TX_RD pointer addresses because of SPI packet format error. Here is a photo from my logic analyzer.

Here is my main.c code:

uint8_t ip_addr[4] = {192, 168, 1, 100};
uint8_t gw_ip_addr[4] = {0, 0, 0, 0};
uint8_t subnet_mask[4] = {255, 0, 0, 0};
uint8_t mac_addr[6] = {80, 23, 100, 233, 211, 112};
uint8_t dest_ip[4] = {192, 168, 1, 1};
uint8_t sample[257] = {0x11,0x22,0x33,0x44};
uint16_t    debug;

/*Our MCU initialize code*/
processing_wiznet_init_scenario();
processing_led_management_init_scenario();
make_address_and_data_pins_internally_pulldown();

WIZNET_HW_RESET;

iinchip_init();

debug =  IINCHIP_READ(Sn_TX_WR0(0));
debug =  IINCHIP_READ(Sn_TX_WR0(0) + 1);
debug =   IINCHIP_READ(Sn_TX_RD0(0));
debug =   IINCHIP_READ(Sn_TX_RD0(0) + 1);/*Perfectly normal SPI sequence*/
setSIPR(ip_addr);
setGAR(gw_ip_addr);
setSUBR(subnet_mask);
setSHAR(mac_addr);

debug =  IINCHIP_READ(Sn_TX_WR0(0));
debug =  IINCHIP_READ(Sn_TX_WR0(0) + 1);
debug =   IINCHIP_READ(Sn_TX_RD0(0));
debug =   IINCHIP_READ(Sn_TX_RD0(0) + 1);/*This sequence is perfect too.*/

sysinit(0x55, 0x55);

debug =  IINCHIP_READ(Sn_TX_WR0(0));
debug =  IINCHIP_READ(Sn_TX_WR0(0) + 1);
debug =   IINCHIP_READ(Sn_TX_RD0(0));
debug =   IINCHIP_READ(Sn_TX_RD0(0) + 1);/*Sometimes that sequence might be failed.*/

disconnect(0);
close(0);

if(socket(0,Sn_MR_TCP,32100,0x00) == 0)
    return;

listen(0) ;

debug =  IINCHIP_READ(Sn_TX_WR0(0));/* I stop my code via breakpoint i connect from pc as client no problem.*/
debug =  IINCHIP_READ(Sn_TX_WR0(0) + 1);
debug =   IINCHIP_READ(Sn_TX_RD0(0));
debug =   IINCHIP_READ(Sn_TX_RD0(0) + 1);

IINCHIP_WRITE(Sn_TX_WR0(0), IINCHIP_READ(Sn_TX_RD0(0)));
IINCHIP_WRITE(Sn_TX_WR0(0) + 1, IINCHIP_READ(Sn_TX_RD0(0) + 1));

debug = send(0,sample,4);/*In send library function TX_Wr pointer value exceeds limits such as 2303 besides SPI packet sequence is broken you can see in attachment.*/

I totally stuck because of this SPI packet error. Is this normal or is there any errata about it ?


#2

Hi,

I don’t understand your question.
What is the wrong format??
When you read the TX write pointer, the value is 0x0000.

#3

Hi, i think the photo is confusing i put it because the packet format error is clear to see in that (response: 0x03 0xFF 0xFF 0xFF). I often see the packet format error when i read Tx_WR or RD pointer. So the chip go crazy because that looks 0xFF (my IINCHIP_Read implementation return last byte of packet)and when i send the data with send function the chip bombing TCP line via sending multiple 1460 bytes packages (i send 4 byte only.).

#4

You mean that when 0x001A(RMSR) is written, MISO responses is 0x03 0xFF 0xFF 0xFF ???

When MCU writes to W5100, you should ignore response.
The value is nothing.

You just care about last byte 0x01. It is written data.

#5

[quote=“hjjeon0608”]You mean that when 0x001A(RMSR) is written, MISO responses is 0x03 0xFF 0xFF 0xFF ???

When MCU writes to W5100, you should ignore response.
The value is nothing.

You just care about last byte 0x01. It is written data.[/quote]
Okay, we can ignore writing’s sequence response.
My problem is when i read Tx_WR and Tx_RD pointer values the spi package error happens occasionally. So send function manage Tx pointer in a wrong way after that i see multiple 1460 byte data packages on wireshark and my tcp test tool even if i send 4 bytes data package.

I will post some pictures about it at the end of the day.

#6

You can see TX_Wr read error in first picture

When i read 0x0424 it’s perfectly normal.

Second picture’s code piece :

[code]

sysinit(0x55, 0x55);

close(0);

if(socket(0,Sn_MR_TCP,32100,0x00) == 0)
return;

listen(0) ;
/You can see all data flow in second picture of these debug areas/
debug = IINCHIP_READ(Sn_TX_WR0(0));
debug = IINCHIP_READ(Sn_TX_WR0(0) + 1);
debug = IINCHIP_READ(Sn_TX_RD0(0));
debug = IINCHIP_READ(Sn_TX_RD0(0) + 1);[/code]




#7

Plz, post your send function and iinchip_read, iinchip_write.

#8

send function is library’s function i used as is .

[code]uint16 send(
SOCKET s, /< the socket index */
const uint8 * buf, /
< a pointer to data */
uint16 len /**< the data size to be send */
)
{
uint8 status=0;
uint16 ret=0;
uint16 freesize=0;
#ifdef DEF_IINCHIP_DBG
printf(“send()\r\n”);
#endif
ret = getIINCHIP_TxMAX(s);

if (len > getIINCHIP_TxMAX(s))
ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else
ret = len;

// if freebuf is available, start.
do
{
freesize = getSn_TX_FSR(s);
status = IINCHIP_READ(Sn_SR(s));
if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
{
ret = 0;
break;
}
#ifdef DEF_IINCHIP_DBG
printf(“socket %d freesize(%d) empty or error\r\n”, s, freesize);
#endif
} while (freesize < ret);

  // copy data

send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);

/* +20071122[chungs]:wait to process the command… /
while( IINCHIP_READ(Sn_CR(s)) )
;
/
------- */

/* +2008.01 bj /
//#ifdef DEF_IINCHIP_INT
// while ( (getISR(s) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
//#else
while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
//#endif
{
/
m2008.01 [bj] : reduce code /
if ( IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED )
{
#ifdef DEF_IINCHIP_DBG
printf(“SOCK_CLOSED.\r\n”);
#endif
close(s);
return 0;
}
}
/
+2008.01 bj */
#ifdef DEF_IINCHIP_INT
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
#else
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
#endif
return ret;
}[/code]

IINCHIP read and write functions. In w5100.c I use like this : return user_IINCHIP_READ(…) and return user_IINCHIP_WRITE(…)

uint32_t byte_merger(uint8_t opcode, uint16_t addr, uint8_t data)
{
    uint32_t merged_stream;

    merged_stream = ((uint32_t)(opcode))<<24;
    merged_stream |= (((uint32_t)addr)<<8);
    merged_stream |= data;

    return merged_stream;
}

/**
@brief	This function writes the value to W5100 registers.
*/
uint8_t user_IINCHIP_WRITE(uint16_t addr,uint8_t data){
uint8_t spi_counter = 0;
uint32_t temp_value;
uint32_t received_temp_val;
uint32_t received_temp_val1;

wiznet_MOSI_data = byte_merger(0xF0, addr, data);
temp_value = wiznet_MOSI_data;
wiznet_MISO_data = 0;
    WIZNET_SEN_ENABLE;
    Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();

    for(spi_counter = 0;spi_counter<32;spi_counter++){
        wiznet_MOSI_data = temp_value;
        wiznet_MOSI_data = (wiznet_MOSI_data << spi_counter)&0x80000000;
        wiznet_MOSI_data = (wiznet_MOSI_data >>31);
        if(wiznet_MOSI_data == 1) GPIO_SetBits(GPIOB,WIZNET_MOSI);
        if(wiznet_MOSI_data == 0) GPIO_ResetBits(GPIOB,WIZNET_MOSI);

        Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();
        GPIO_SetBits(GPIOB,WIZNET_SCLK);
        Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();

        GPIO_ResetBits(GPIOB,WIZNET_SCLK);
        Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();


}

    received_temp_val = wiznet_MISO_data;
    received_temp_val1 = received_temp_val & 0x000000FF;
    received_current_data = received_temp_val1;

    WIZNET_SEN_DISABLE;

    Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();
	return 1;
}

/**
@brief	This function reads the value from W5100 registers.
*/
uint8_t user_IINCHIP_READ(uint16_t addr)
{
uint8_t spi_counter = 0;
uint32_t temp_value;
uint32_t received_temp_val;
uint32_t received_temp_val1;

wiznet_MOSI_data = byte_merger(0x0F, addr, 0x00);
temp_value = wiznet_MOSI_data;
wiznet_MISO_data = 0;
    WIZNET_SEN_ENABLE;
    Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();

    for(spi_counter = 0;spi_counter<32;spi_counter++){
        wiznet_MOSI_data = temp_value;
        wiznet_MOSI_data = (wiznet_MOSI_data << spi_counter)&0x80000000;
        wiznet_MOSI_data = (wiznet_MOSI_data >>31);
        if(wiznet_MOSI_data == 1) GPIO_SetBits(GPIOB,WIZNET_MOSI);
        if(wiznet_MOSI_data == 0) GPIO_ResetBits(GPIOB,WIZNET_MOSI);

        Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();
        GPIO_SetBits(GPIOB,WIZNET_SCLK);
        Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();

        if(GPIO_ReadInputDataBit(GPIOB,WIZNET_MISO ) == 1){
        wiznet_MISO_data = (wiznet_MISO_data >> (31-spi_counter))|0x00000001;
        wiznet_MISO_data = (wiznet_MISO_data << (31-spi_counter));
        }
        if(GPIO_ReadInputDataBit(GPIOB,WIZNET_MISO ) == 0){
        wiznet_MISO_data = (wiznet_MISO_data >> (31-spi_counter))&0xFFFFFFFE;
        wiznet_MISO_data = (wiznet_MISO_data << (31-spi_counter));
        }
        GPIO_ResetBits(GPIOB,WIZNET_SCLK);
        Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();


}

    received_temp_val = wiznet_MISO_data;
    received_temp_val1 = received_temp_val & 0x000000FF;
    received_current_data = received_temp_val1;

    WIZNET_SEN_DISABLE;

    Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS(); Delay_1uS();

    return received_current_data;
}

#9

I add retransmission property in IINCHIP_Read function but the things get worst. Once the communication is blown up, the chip never returns a valid packet.

My modifications:
1-) If the data package is not valid which is
first byte not equal 0x00,
second byte not equal 0x01,
third byte not equal 0x02

if any of these conditions happen, i read MR (address 0x0000) register. Here is the logic analyzer log


#10

Hi,

I read your question through.
And I have some question.

  1. What value you write to Tx wr pointer register??
    Can you read the same value that you write?? I cannot see write value. So I cannot judge what is wrong value.

  2. You read Tx rd pointer and then add length of data you want to send and then write to the tx wr pointer???

  3. When you read Tx wr pointer register or Tx rd pointer register several times, the value are different??

#11

[quote=“hjjeon0608”]Hi,

I read your question through.
And I have some question.

  1. What value you write to Tx wr pointer register??
    Can you read the same value that you write?? I cannot see write value. So I cannot judge what is wrong value.

  2. You read Tx rd pointer and then add length of data you want to send and then write to the tx wr pointer???

  3. When you read Tx wr pointer register or Tx rd pointer register several times, the value are different??[/quote]

1-)I think the attachment will answer your question(at right side of photo you see the retransmission mechanism is worked and get the right value of S0_TX_WR but it works 1-2 times after that it can’t help anymore to us)
2-) This question’s answer is in wiznet library, i modify only IINCHIP_Read function with retransmission. (Here is the link:
wiznet.co.kr/Admin_Root/UpLo … _DV_V180(0.zip)
3-)When I can read a valid spi package from w5100, there is no problem with tx_wr, tx_rd pointer values. But the library gets the broken pointer value(by broken spi package) add my data length to tx_wr pointer and boom whole communication is blown up because the pointer value has been damaged because of non-valid spi package. But as i said if the packages are solid, pointer values are solid.