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.

MSP430FR5994: Compiler Warning assigning UART register to DMA register (CCS12 with TO v21.6.0 on MSP430FR59xx)

Part Number: MSP430FR5994


Dear all,

I think its an easy question with a quick answer... but I already searched for quite some time without any changes. So I hope someone can help me out.

What I want:

Set the address of a register as the value of an other register. To be more precise e.g. set the destination register of the DMA to the UART output buffer register. This “should” look like this:

DMA0DA = &UCA1TXBUF;

What I get:

Compiler warning, which could very well be real errors, like “a value of type xxxx cannot be assigned to an entity of type “__SFR_FARPRT” “.

What I already tried:

I get that this might be because I try to write a 16bit adress (the UART buffer adress) into a 32bit (real 20bit) register… so I tried all kind of different cast like:

DMA0DA = (uintptr_t *) &UCA1TXBUF;

Also the compiler guide suggest "ptrdiff_t" or "data pointer" which both are unknown to the compiler...

I hope someone can help me out and resolve my misunderstanding.

Best wishes,

Tobias

  • The compiler has trouble with that assignment. It writes a 32 bit value to memory as two 16 bit writes which mangles the DMA address.Two options:

    Helper functions are provided to write a long address: __data20_write_long

    Use the 16 bit version of the register: DMA0DA_L.

    The UART register is going to be fine with this since its upper bits are zero.

  • Dear David,

    thank you very much for your reply! Sadly it didn't help... ill try to supply a bit more code and the exact warning - perhaps it helps.


    volatile unsigned char uart_tx_buffer[20]="Test";
    
    DMA0DAL = &UCA1TXBUF;     //DMA channel 0 destination address is TX-Output-Buffer   - write 16bit address into low 16 bits of 32bit address
    DMA0SA =  (uart_tx_buffer + 1);     //DMA channel 0 source address is address of second element and up (buffer[1])

    Firs of all the code is running ok, but im concerned about the warning and would like to code it properly. I have a global array of chars which may get altered by an interrupt soooo this array should be volatile, right?

    I tried your suggestion writing in the low two bytes of the DMA0DA register and get the warning: a value of type "volatile unsigned int *" cannot be assigned to an entity of type "unsigned int"

    I think the problem might be that the UCA1TXBUF uses the default #define "SFR_16BIT(address)"... any other suggestions?

    In the third line i get a similar warning: a value of type "volatile unsigned char *" cannot be assigned to an entity of type "__SFR_FARPTR"

    Here i cant use your suggestion to only write the low 16bits. Am i right to assume this would be the suggested code:

    __data20_write_long(DMA0SA, uart_tx_buffer + 1);

    With this i now also get the warning: argument of type "__SFR_FARPTR" is incompatible with parameter of type "unsigned long".

    Thanks for your help!

    Best wishes Tobias

  • The DMA address registers are an odd duck since if you don't use the mova (or mov.a) instruction, the upper 16 bits of the DMA address gets set to zero. Which causes trouble when the compiler uses two 16 bit writes like it does for any 32 bit write. The functions (data20*) are the only way to do this but they are clunky. (Look at the code generated.) If you want to eliminate the warnings you will have to fiddle around to find what makes the compiler happy. Casting to whatever type shuts it up.

  • This is how example msp430fr599x_dma_01.c does it:

    > __data20_write_long((uintptr_t) &DMA0SA,(uintptr_t) 0x1C20);

    I'm not sure why the author felt the need for the "magic constant" -- there's no reason that couldn't be "(uintptr_t)(uart_tx_buffer+1)".

    https://dev.ti.com/tirex/explore/node?node=ACXdYpuLv5865Z2qDAo.Dw__IOGqZri__LATEST

  • Dear David,

    thank you for the clarification.

    "Casting to whatever type shuts it up."

    Uff that's a bit disturbing or unfulfilling... but it seems its a solution -> so thanks anyway.

    Best wishes

    Tobias

  • Dear Bruce,

    thank you fore the attached link. It indeed helped and now the compiler is happy...

    Concerning the "clunky" part from David: I suppose I shouldn't use the __data20 functions too frequently. But in the case of an address which could be 20bit there isn't a better way, or?

    How bad is it to use this function - since my assembler skills are nearly nonexistent? Interestingly the compiler is also not happy when im using 32bit... Would assigning a register a 20bit address which got casted to 32bit even work, or did i understand David correctly and it will get mixed up and truncated?

    Thanks for the help and at least one "happy compiler" solution!

    Best wishes

    Tobias

**Attention** This is a public forum