This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Little Endian in C51?

Is it somehow possible to generate little-endian code using C51?

We are using a 8051 variant as a controller for an ASIC with a little endian interface. I would like to be able to do something like:

*((DWORD*)0x4000) = 0x12345678;

And have the bytes written to the bus in "reversed" or Intel order, least significant byte first.

Is this possible?

  • It's not a standard compiler option.

    I also have a project that uses an 8051 to control an ASIC with a 32-bit, little-endian interface. I wrote assembler routines that do the register access and endian inversion all at once.

    That is, a U32 will be passed in R4-R7. The 8051 core has only an 8-bit data bus, so your particular device has to have some means for building up a 32-bit data path from several 8-bit writes. It doesn't make any difference to the efficiency of your assembly code whether you MOV R4, R5, R6, R7, or MOV R7, R6, R5, R4 to your 32-bit interface.

    I also added routines to do common bit operations, as they can also be efficiently folded into the access.

    So, I have C prototypes along these lines:

    U32 RegRead (U32* addr); // *addr
    U32 RegWrite (U32* addr, U32 val); // *addr = val;
    
    U32 RegAnd (U32* addr, U32 val); // val & *addr
    
    U32 RegOrEq (U32* addr, U32 val); // *addr |= val;
    U32 RegAndEqNot (U32* addr, U32 val); // *addr &= ~val;
    

    It turns out you don't need to directly dereference pointers at all.

    Note that the addr pointers into those prototypes are generic addresses. This is a trick to get the compiler to pass them in R1..R3, while the U32 parameter is passed in R4..R7. My registers happen to be in xdata space, but it turns out it's better to stuff a useless byte in the procedure call than to spill a parameter by declaring a 16-bit xdata*, which would then conflict with the U32 in terms of register assignment.