WIZnet Developer Forum

Is it possible to send TCP via MACRAW socket?


I have some sockets of the wiznet 5500 configured as TCP sockets and one as MACRAW. When all of my TCP sockets are in use, and a new device tries to send a TCP packet to my device the TCP message comes in on the MACRAW socket. When this happens I want to close the new TCP session since I don’t have space for it, so I want to send it a TCP FIN packet.

I can send a message via the MACRAW socket if it has an etherType of 0x7777, but when I use EtherType 0x0800 (IP) and send an IP packet containing a TCP packet it does not seem to go out the wire.

Am I using the chip wrong? Can I not send a TCP messages out a MACRAW socket?

I have been able to send and receive UDP on a UDP socket, send and receive TCP on TCP socket, and send and recieve ICMP on an IPRAW/ICMP socket. I can receive all kinds of traffic on the MACRAW socket but have been unable to send TCP or ICMP. I am thinking maybe this is a chip restriction?

Thanks in advance for any help.



As you know, MACRAW can handle the Ethernet frame.
Hence, you can send any Ethernet packet in MACRAW mode.
Please, check your codes and refer to below pseudo code.

  1. Pseudo code for sending in MACRAW mode
// macraw_send
uint16 macraw_send( const uint8 * buf, uint16 len )
    uint16 ret=0;
    uint16 ptr = 0;
    uint32 addrbsb = 0;

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

    ptr = IINCHIP_READ( Sn_TX_WR0(0) );
    ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_TX_WR1(0));

    addrbsb = (uint32)(ptr<<8) + 0x10;
    wiz_write_buf(addrbsb, (uint8*)(buf), len);
    ptr += len;

    IINCHIP_WRITE( Sn_TX_WR0(0),(uint8)((ptr & 0xff00) >> 8));
    IINCHIP_WRITE( Sn_TX_WR1(0),(uint8)(ptr & 0x00ff));

    while( IINCHIP_READ(Sn_CR(0)) );
    while ( (IINCHIP_READ(Sn_IR(0)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK );


uint16 wiz_write_buf(uint32 addrbsb,uint8* buf,uint16 len)
    uint16 idx = 0;
    IINCHIP_CSoff();                                 // CS=0, SPI start
    IINCHIP_SpiSendData( (addrbsb & 0x00FF0000)>>16);// Address byte 1
    IINCHIP_SpiSendData( (addrbsb & 0x0000FF00)>> 8);// Address byte 2
    IINCHIP_SpiSendData( (addrbsb & 0x000000F8) + 4);// Data write command and Write data length 1
    for(idx = 0; idx < len; idx++)                   // Write data in loop
    IINCHIP_CSon();                                  // CS=1, SPI end
    IINCHIP_ISR_ENABLE();                            // Interrupt Service Routine Enable    

    return len;  
  1. Check packet frame.
  • As you know, you make full Ethernet frame for sending in MACRAW mode as follows,
    | Ethernet header | IP header | TCP (or UDP) header | payload |
  • Please, check each field values in headers, as like checksum.


Hi Suhwan,

Thank you for the reply. In looking at your source code I am not checking the command register or interrupt register after the send and not clearing the send ok bit, so I will try that.

When I send a MACRAW packet, if it is an IP packet (ether type 0x0800) do I need to have the checksums correct for it to be sent out? Does it do any checking on the accuracy of the packet I send or does it allow me to just send any stream of bytes even if it is an incorrectly formatted packet? Do I need to at least a correct ethernet header?


Hi Matt,

We recommend the clear checking of the command register and ‘send ok’ bit.

Yes. In MACRAW mode, you should be calculate the checksum of IP header and TCP (or UDP) header.

The incorrectly formatted packet is send out.
I’m not sure but Packet capture program, as like WireShark, does not display/capture the incorrectly formatted packet.

Yes. W5500 generates preamble and FCS. Therefore, you make Ethernet Frame expect FCS and preamble.
– Ethernet Frame Types –
| preamble | Destination MAC address | Source MAC Address | Lengh/Etheret type | …DATA… | FCS |

[quote]// ****************************************************************************
// send a message using MACRAW socket
// ****************************************************************************
int8s wiznetTxRaw(int8u* ipAddr, int16u dataLen, int8u* data)

// Socket 0 command register = SEND = 0x20
sc1SpiReadOrWrite6BytesOrLess(SPI_WRITE, BLOCK_SOCKET0_REGISTER, 0x0001, 1, 0x20, 0,0,0,0,0);

[color=#BF0040]/bug: the Sn_TX_WR should be incremented before Send Command/
// increment Sn_TX_WR
currentPosition = currentPosition + dataLen;
emberSerialPrintf(gAppSerial, “Write Sn_TXWR = %d\r\n”, currentPosition);
sc1SpiReadOrWrite6BytesOrLess(SPI_WRITE, BLOCK_SOCKET0_REGISTER, 0x0024, 2, HIGH_BYTE(currentPosition), LOW_BYTE(currentPosition), 0,0,0,0);
/bug: the Sn_TX_WR should be incremented before Send Command/[/color]

return 0;

We get a bug on your codes.
In your code, the Sn_TX_WR is incremented after Send command in wiznetTxRaw().
But, the Sn_TX_WR should be incremented before Send Command.


[quote=“suhwan”]Hi Matt,

We recommend the clear checking of the command register and ‘send ok’ bit.

Checking Sn_IR I always get 0x20 instead of 0x10.
According to DS this is a reserved bit. So I (and probably other MACRAW-users) still don’t know whether the frame was transmitted on wire or not.

At least my W5500 chip transmitted frames even if the header was wrong. E.g. I sent a frame with type=0 and length=0 and it arrived at the other side (using a direct connection, no switch in between)

Hi, Matt

You can see the packet with wireshark although the packet is wrong format, I know.

So if you can’t see packet is sent in Wireshark, check preamble header.
As I know, preamble must be correct.


I have recently succeeded in sending/receiving raw frames, but still wonder if the chip (w5500) has undocumented ability to forge FCS field (also the way to receive packets with non-standard FCS regarded). Is there any chance?

I’m asking because read in datasheet for older chip that it is possible to at least receive CRC value.


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