This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Header File Problem | MSP430F552X

Problem description:

All my files will compile correctly, my error comes during runtime.  If I try to set register TA0R with a value it will not load the value correctly.

Example:

TA0R = 0x1234 

It seems to store the High byte of the argument into the Low byte of the register.  So if I use IAR to look into the register after this command, then TA0R = 0x0012

 

I’m positive it has something to do with how it is mapped in the header file “msp430x552x.h”

I know this because when I remove the declaration of this register in that file and replace it with the one given in the file “io430x552x.h”, it works correctly. 

 

Now my question is who creates these header files?  Is it TI or someone else?  Is there an update for these files?  If so, how do I get them?

  • I am using KickStart from SLAC050v.zip = FET_R521.exe. It works in this respect.

    (I think the later and current version SLAC050w.zip = FET_R522.exe works too.)

    The register TA0R is defined in the header file with:

    DEFCW(   TA0R              , TA0R_)

    where DEFCW is defined by:

    #define DEFCW(name, address) __no_init union \
    { \
      struct \
      { \
        volatile unsigned char  name##_L; \
        volatile unsigned char  name##_H; \
      }; \
      volatile unsigned short   name; \
    } @ address;

    and TA0R_ is defined by:

    #define  TA0R_               (0x0350)  /* Timer0_A5 */

    Thus, as a result, we have the equivalent of:

    volatile short TA0R @ 0x350;

    This is correct.

  • Sorry. I need to change the last three line in my previous reply to the following five lines:

    Thus, as a result, we have the equivalent of:

    __no_init volatile short TA0R @ 0x350;

    __no_init volatile char TA0R_L @ 0x350;

    __no_init volatile char TA0R_H @ 0x351;

    This is correct.

     

  • I discovered a similar behaviour with the DMA controller.

    While the documentation describes byte access for the registers and defines byte aliases, they sometimes seem to be word access only. So you'll have to modify TA0R with word access and not use TA0R_x at all. The observation that your high-byte is read back in the low byte is exactly what happened on the DMA registers too. Atomic word access solved the problem.

    In addition, the documentation states that you should halt the timer before modifying it. This sounds reasonable when writing the register with byte access (TA0 might increment between the writes, causing an unexpected over/underflow) but should not be a problem when word-accessing it (simultaneous write of all 16 bits).

    Since you're already using the TA0R, the compiler should generate word access. But it seems that it doesn't. Take a look at the generated assembly code for both header variations.

    With MSPGCC I discovered that the compiler will generate byte access to word variables if it isn't clear that the destination will be word-aligned (as misaligned word access results into a write to an address with cleared LSB, one byte below). It happens e.g. when you use the address as parameter to a function. HTen the function does not know whether the address is aligned and will use byte access. Also, maybe the alignment information is lost due to the struct usage instead of a direct declaration. It depends on the 'smartness' of the compiler.

    p.s.: IMHO the __no_init is not necessary as the register is placed neither in initialized nor zeroed or non-initialized data segment but at a fixed address (outside any segment).

     

    But to answer your final question: the header files are usually created by the compiler manufacturer, based on TIs documentation. For the MSPGCC I wrote a lot of them myself (for the 54xx family) and forwarded them to the community. And I discovered several errors in the documentation. Most of them have already been addressed in later revisions of the docs.

    Keep in mind that the compiler manufacturer might write the header files, but besides ensuring that the compiler will generate proper binary code from the C code, there will be no checking whether the hardware will work as expected or the headers will meet reality. Only header vs. docs at the moment of writing the headers will be verified. (so often even changes in the docs aren't reflected in the headers). So if something does not work and you're sure you code should work, first check the assembly code generated (listing or debugger), then try to get newer versions of the docs and compare with your headers.

**Attention** This is a public forum