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.

MSP430FR5969: GCC and 32 bit special function registers

Part Number: MSP430FR5969


Writing to certain special function registers requires the use of mova instructions in some cases. For example, the DMA address registers. I was looking at the code generated for a simple example and it looks bad:

  DMA0SA = &ADC12MEM0;
    443e:       8c 00 60 08     mova    #2144,  r12     ;0x00860
    4442:       00 18 4d 4c     movx.a  r12,    r13     ;
    4446:       0c 4c           mov     r12,    r12     ;
    4448:       0f 18 4d 11     rpt #16 { rrax.a        r13             ;
    444c:       82 4c 12 05     mov     r12,    &0x0512 ;
    4450:       82 4d 14 05     mov     r13,    &0x0514 ;

This was compiled with "-mlarge" but that made little difference. Both do similar mucking about with the address of ADC12MEM0 (0x860) to make it into two 16 bit values in two registers. The correct value is in r12 after the first instruction and a simple mov would finish the job. (This operation requires only a single instruction: "movx.a #0x860,&0x512".)

Writing the address in two 16 bit word writes is wrong. As the user guide clearly states "Reading or writing bits 19-16 requires the use of extended instructions. When writing to DMAxSA with word instructions, bits 19-16 are cleared." Testing verified that writing a non-zero word to 0x514 resulted in it being zero. 0x512 was unchanged.

I compiled this using the 9.2 distribution of GCC with "-O2". I tried to upgrade to the latest distribution but that failed. It is in something resembling a 7z archive but it appears empty:

Scanning the drive for archives:
1 file, 41050906 bytes (40 MiB)

Listing archive: msp430-gcc-full-linux-x64-installer-9.3.1.2.7z

--
Path = msp430-gcc-full-linux-x64-installer-9.3.1.2.7z
Type = 7z
Physical Size = 41050906
Headers Size = 266
Method = LZMA2:48m LZMA:20 BCJ2
Solid = -
Blocks = 1

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
------------------- ----- ------------ ------------  ------------------------
                                     0            0  0 files

  • Hi David

    I don't have much experience on GCC compilar environment.

    I can see "-O2"Optimize more (O2) is set. May I know if the same issue will happen if we set the Optimization level to 0 "None (O0): Disable optimizations"

     

    Thanks!

  • It will not matter because the header file (iomacros.h) defines a sfr_l as an unsigned integer. To a C compiler an unsigned integer is 32 bits.

    So it promotes the 20 bit pointer into a 32 bit integer (slowly) and then stores it as it would any other 32 bit integer. Using two 16 bit stores.

    Not a huge problem, I guess, since it only results in an error when writing to the DMA address registers and the address is in upper FRAM. Otherwise it is just wildly inefficient code.

**Attention** This is a public forum