W7500 raw socket

Hi, I am looking for an example of sending and receiving RAW sockets running on the W7500. I am using the evaluation board and all of the examples are around UDP and TCP.



W7500 supports IPRAW and MACRAW socket. But there is no RAW socket example running on W7500.
You can use it by modifying the W5500 document Since W7500 contains W5500 core.
W5500 document has an ipraw application note PPPoE communication application note running on macraw socket.


I managed to get this working by modifying the driver send function, adding a RAW constant to the enum protocol definition and creating a Raw socket class. Details of changes below.

W7500x_toe.cpp - Added sendRaw function. This is identical to send except it uses SEND_MAC instead of SEND as the command. Could modify send to check the protocol and use the appropriate command. For now I have two functions.

int WIZnet_Chip::sendRaw(int socket, const char * str, int len)
	if (socket < 0) {
		return -1;

	uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR);
	uint32_t sn_tx_base = W7500x_TXMEM_BASE + (uint32_t)(socket<<18); 

	for(int i=0; i<len; i++)
		*(volatile uint8_t *)(sn_tx_base + ((ptr+i)&0xFFFF)) = str[i];

	sreg<uint16_t>(socket, Sn_TX_WR, ptr + len);
	scmd(socket, SEND_MAC);

	uint8_t tmp_Sn_IR;
	while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) {
		// @Jul.10, 2014 fix contant name, and udp sendto function.
		switch (sreg<uint8_t>(socket, Sn_SR)) {
			case SOCK_CLOSED :
				return 0;
			case SOCK_UDP :
				// ARP timeout is possible.
				if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) {
					sreg<uint8_t>(socket, Sn_ICR, INT_TIMEOUT);
					return 0;
			default :

	sreg<uint8_t>(socket, Sn_ICR, INT_SEND_OK);

	return len;

W7500x_toe.h - Added RAW to the protocol enum:

enum Protocol {
    CLOSED = 0,
    TCP    = 1,
    UDP    = 2,
    RAW    = 4

SocketRaw.cpp - New class derived from Socket, that uses the above:

class TSocketRaw: public Socket
        void Init();
        void Open();
        int Send( char *BufferPtr,
                  int   Length);


    if (_sock_fd < 0) {
        _sock_fd = eth->new_socket();
    // Has to be socket 0 as this is the only socket that can opperate in raw mode.
    if( _sock_fd != 0)
        printf( "ERROR:- Raw Socket %d (should be socket 0, try connecting before using any other sockets.)\r\n", _sock_fd);

    eth->setProtocol( _sock_fd, WIZnet_Chip::RAW);
    eth->scmd( _sock_fd, WIZnet_Chip::OPEN);

TSocketRaw::Send( char *BufferPtr,
                     int   Length)
    int Size;
    Size= eth->wait_writeable( _sock_fd, _blocking ? -1 : _timeout, Length - 1);
    if( Size < 0)
        return -1;
    Size = eth->sendRaw( _sock_fd, BufferPtr, Length);
    return Size;

Thanks Becky. I managed to get it working well. I have posted my solution onto the thread for others to use.


We are using W7500 as Serial to Ethernet Converter. Where we need multiple sockets too. from the W7500X libraries, We found Socket.c and socket.h files , but these are some what confusing. Can you please share your code for Serial to Ethernet if you done it.

it will be helpful to us.