SMSC LAN91C111 32/16/8-Bit Three-In-One Fast Ethernet Controller
SMSC AN 9.6 41 Revision 1.0 (08-14-08)
APPLICATION NOTE
This example has extra stuff for defining the different architectures, but the key example is the byte
swapping part at the bottom:
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>
/*
* 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];
}