SMSC LAN91C111 32/16/8-Bit Three-In-One Fast Ethernet Controller

This example has extra stuff for defining the different architectures, but the key example is the byte swapping part at the bottom:

/*

*Little endian <==> big endian 32-bit swap macros.

*M_32_SWAP swap a memory location

*P_32_SWAP swap a referenced memory location

*P_32_COPY swap from one location to another

*/

#define M_32_SWAP(a) { uint32 _tmp = a;

((char *)&a)[0] = ((char *)&_tmp)[3]; ((char *)&a)[1] = ((char *)&_tmp)[2]; ((char *)&a)[2] = ((char *)&_tmp)[1]; ((char *)&a)[3] = ((char *)&_tmp)[0];

}

#define P_32_SWAP(a) { uint32 _tmp = *(uint32 *)a; ((char *)a)[0] = ((char *)&_tmp)[3]; ((char *)a)[1] = ((char *)&_tmp)[2];

((char *)a)[2] = ((char *)&_tmp)[1]; ((char *)a)[3] = ((char *)&_tmp)[0];

}

#define P_32_COPY(a, b) { ((char *)&(b))[0] = ((char *)&(a))[3]; ((char *)&(b))[1] = ((char *)&(a))[2]; ((char *)&(b))[2] = ((char *)&(a))[1]; ((char *)&(b))[3] = ((char *)&(a))[0];

}

/*

*Little endian <==> big endian 16-bit swap macros.

*M_16_SWAP swap a memory location

*P_16_SWAP swap a referenced memory location

*P_16_COPY swap from one location to another

*/

#define M_16_SWAP(a) {

uint16 _tmp = a;

((char *)&a)[0] = ((char *)&_tmp)[1]; ((char *)&a)[1] = ((char *)&_tmp)[0];

}

#define P_16_SWAP(a) { uint16 _tmp = *(uint16 *)a;

((char *)a)[0] = ((char *)&_tmp)[1];

((char *)a)[1] = ((char *)&_tmp)[0];

}

#define P_16_COPY(a, b) { ((char *)&(b))[0] = ((char *)&(a))[1]; ((char *)&(b))[1] = ((char *)&(a))[0];

}

This example is nothing more than swapping bytes. Most Unix machines include routines to do this, and they are generally called: hton, htons, htonl, ntohs, ntohl, and are generally found in the header <net/hton.h>

SMSC AN 9.6

41

Revision 1.0 (08-14-08)

APPLICATION NOTE