• Resolved

Newbie question: HWREG and HWREGBITW, what they do?

I know it's a very newbie question and I know the #define for them is in hw_types.h

But I must admit my newbie level on C and say: I don't get it! It is a pointer, to a cast of a unsigned long pointer that masks the pointer to some bit of this long?

Sorry, I was already lost on the casting to another pointer, I guess too much Java made me weak towards real low level programming languages and I bow down to the experts for help.

I've been carelessly allowing all of those macros live in my code just copying them from the example, but until know I've been only setting up the stuff that is mostly API commands based. No registers.

But the IPC is full of those and I have some issues to iron out on the uDMA (http://e2e.ti.com/support/microcontrollers/tms320c2000_32-bit_real-time_mcus/f/171/t/180339.aspx) too and a better understanding of those Macros will be very useful.

Please (light)darkness;



maybe I should elaborate a bit further:


stuff like this:


    // Allow writes to protected registers.

I get it, there's a register named SYSCTL_MWRALLOW that you can find at address 0x400FB980 and I'm writting on it 0xA5A5A5A5. And it means that now I can write the protected registers, which I can see which ones are in the datasheet.

but sometimes there's some HWREG(RAM_CONFIG_BASE + RAM_O_MSXRTESTINIT1) |= 0x1; which I barely pretend I understand, something about masking the first bit of RAM_O_MSXRTESTINIT1 into RAM_CONFIG_BASE  register, but then I see a HWREGBITW(&g_ulFlags, FLAG_SYSTICK) that doesn't seem to be much to do with any of the hardware registers or almost randomly in some examples there's a

    // Tells M3 Core the vector table is at the beginning of C0 now.
    HWREG(NVIC_VTABLE) = 0x20005000;

why can't you leave the NVIC_VTABLE where it was? Was it doing any harm on the default place?

again, any help will be appreciate to (light)darkness;  <- cast light into darkness.

  • Rondaldo,

    Hardware registers are just addresses in memory. Instead of having the actual address for each register as a #define, the base address for each peripheral is defined, along with the offsets from that base address for each register.

    For example, RAM_CONFIG_BASE is equal to address 0x400FB200. RAM_O_MSXRTESTINIT1 is located at 0x400FB250, but instead of storing that address, the offset of 0x50 from the RAM_CONFIG_BASE is used. HWREG(RAM_CONFIG_BASE + RAM_O_MSXRTESTINIT1) is just adding the offset for that specific register to the ram config base address.

    The |=0x1 is just 'setting' the first bit. (Get the contents of RAM_O_MSXRTESTINIT1 and OR them with 0x01)

    The HWREG macro is used to actually work with the addresses. It casts the address value to a volatile(it's a register, so it could change at any time) pointer that is then dereferenced (*) so it can be read/written to as a variable in c.

    HWREGBITW is used to manipulate individual bits on a register using 'bit banding'. This allows you to modify individual bits without having to read-modify-write the register. You can find more information on bit banding here: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0179b/CHDJHIDF.html and http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/Behcjiic.html

    I hope this helps,


  • In reply to Alvaro Tarazona:

    hi Alvaro,

    thanks for the reply, I had to re-read a few times and sleep on it to absorb the data but I guess my brain is starting to make sense of it.

    But two specific questions arise from it:

    1) On the enet_uip example it's used A LOT  the following the definition:

    #define FLAG_SYSTICK            0
    #define FLAG_RXPKT 1
    #define FLAG_TXPKT 2
    #define FLAG_RXPKTPEND 3
    static volatile unsigned long g_ulFlags;

    and then the macro HWREGBITW(&g_ulFlags, FLAG_SYSTICK) = 1 or while((HWREGBITW(&g_ulFlags, FLAG_TXPKT) == 1) .... is that just the programmer re-using the MACRO for his own needs with no real hardware register association?? Just using the MACRO to test the bits of his own status long?

    2) in some examples we see:

        // Tells M3 Core the vector table is at the beginning of C0 now.
        HWREG(NVIC_VTABLE) = 0x20005000;

    why moving the interrupts around? I noticed that it does on all DUAL core examples except blinky and flash and it's always moving to C0 (M3 core secure RAM) so I don't see the connection between C0 and the C28 core.


  • In reply to Ronaldo Pace:


    1) Yes, the HWREGBITW is being used to manipulate individual bits on the g_ulFlags with a single instruction.  These macros don't have to be used only for registers. You could use any voltatile unsigned long address as the argument.

    2)  If you look at the linker command file, you will see that the INTVECS section is located at address 0x20005000. The  g_pfnVectors array, declared in startup_ccs.c is stored there. In the past, we would put in the ISR functions directly in this array. Now you can use the IntRegister() driverlib function in  driverlib/interrupt.c to do it. The first time this function is called, it copies the entire vector table to RAM and changes the NVIC_VTABLE to point to it. 

    As long as you use IntRegister before you enable interrupts, you shouldn't have to worry about setting NVIC_VTABLE in your code.


  • In reply to Alvaro Tarazona:

    Now I have a question:

    Is while((HWREGBITW(&g_ulFlags, FLAG_TXPKT) == 1) the same as while((HWREGBITW(&g_ulFlags, FLAG_TXPKT) )?

    I seem to be having some trouble with the latter format in an 'if' statement.

    thanks George

  • In reply to george dorian:


    Think of '0' as FALSE and '1' as TRUE.  So yes.

    Thank you,