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.

DMA setting problem.

Other Parts Discussed in Thread: MSP430F5438, MSP430F47177, MSP430WARE

Hello!

I have a problem setting the DMA with CCE.

When using IAR, I can write for instance:

char * buffer;

Then when sending this buffer somewhere else with the DMA0:

(A) DMA0SA = buffer;

(B) DMA0DA = (void *)&UCB1TXBUF;

NB: I don't know if the cast is right, but it does not produce any error or warning in IAR.

Now when porting to CCE, I get the following errors:

error at line (A):

a value of type "unsigned char *" cannot be assigned to type "__SFR_FARPTR"

warning at line (B):

a value of type "void *" cannot be assigned to type "__SFR_FARPTR"

So I tried to cast as __SFR_FARPTR, whatever it is.

The result is better in the sense that the error in A disappeard, but I still get 2 warnings:

nonstandard conversion between pointer to function and pointer to data.

Can anybody tell me what is the right way to cast when setting the DMA parameters?

By the way, I am using a MSP430F5438

Thanks,

Pascal

 

  • I was able to replicate the errors and warnings you mention with CCE v3.1.

    Although I get similar warnings from CCE such as "nonstandard conversion between pointer to function and pointer to data", the following generates what I believe appropriate assembly to configure DMA0SA and DMA0DA.

    char array[8] ;

    int main(void)
    {
        char * buffer ;
       
        buffer = &array[0] ;
       
        DMA0SA = (__SFR_FARPTR)buffer ;
        DMA0DA = (__SFR_FARPTR)&UCB1TXBUF ;
       
        return 0 ;
    }

    I enabled the following Project Build options to generate the assembly listing file to verify this.

    Project -> Properties
    C/C++ Build -> Tool Settings -> MSP430 Compiler v3.1 -> Assembly Options: -> Generate listing file (--asm_listing)

    It seems to generate the appropriate assembly, but not the means (ie. with warnings).

     

  • FYI - TI example code on their website shows the suggested syntax to workaround this compiler peculiarity:

     

    DMA0SA = (__SFR_FARPTR) (unsigned long) &EEPROMImage;  // Source is virtual EEPROM

    DMA0DA = (__SFR_FARPTR) (unsigned long) &UCB0TXBUF;    // Dest is USCI_B0 TX buffer

     

    Hope that helps... __SFR_FARPTR is a function pointer in my Code Composer environment.  A better choice than (unsigned long) is the C99 addition, (uintptr_t).  As it happens, Code Composer typedefs these two types to be equivalent, so either will work in this situation:

    DMA0SA = (__SFR_FARPTR) (uintptr_t) &EEPROMImage;  // Source is virtual EEPROM


  • Hi,

    I am using CCS Studio 5.2

    Integrated the USB CDC code for MSP430.

    When build I get warnings of "invalid type conversion" for various places that reference "__DMA_ACCESS_REG__" type

    DMA0DA = __DMA_ACCESS_REG__ dest;                       //set destination for DMAx

    in dma.c I also see this define:

    /* for CCS */
    #define __DMA_ACCESS_REG__ (__SFR_FARPTR)(unsigned long)
    #endif

    I have seen other odd behavior when "__SFR_FARPTR" was used.

    Should I worry about this warning? 

    Thanks,

    Ed

  • Hi,

    In CCS Studio 5.2 and using (__SFR_FARPTR)(unsigned long) per TI recommendations I get warnings (Invalid type conversion). 

    invalid type conversion "../USB/USB_API/USB_Common/dma.c" ==> memcpyV "../USB/USB_API/USB_Common/dma.c" ==> USB_initMemcpy "../USB/USB_API/USB_Common/dma.c" ==> memcpyDMA0 "../USB/USB_API/USB_Common/dma.c"
     ==> memcpyDMA1 "../USB/USB_API/USB_Common/dma.c" ==> memcpyDMA2

    How do I resolve this Invalid type conversion?

    Regards,

    Ed

  • gifford scott said:
    __SFR_FARPTR is a function pointer in my Code Composer environment.  A better choice than (unsigned long) is the C99 addition, (uintptr_t).  As it happens, Code Composer typedefs these two types to be equivalent, so either will work in this situation:


    Well, __SFR_FARPTR is not jsut a function pointer. It' sprimary purpose is to represent a monolithic 20 bit value, as opposed to a long int value that is represented as 2*16 bit on assembly level. When stored to 'normal' memory, both are 4 byte size. But a normal long int will be put into 2*16 bit registers while an __SFR_FARPTR will be stored in a single register in a special 20 bit mode. Only this way, a 20 bit address can be properly written to DMA0SA.

    DMAxSA and DMAxDA are the only registers on any MSP that get a 20 bit value. It seems that the header files for CCS have defined them in a way that is not backwards compatible to a 16 bit address created by a normal reference, becasue they have to be written at in a special manner (with a 20-bit write instruction) to gain access to >64k address range.

    However, this requires an MSP with MSP430X 20-bit CPU core and perhaps even large data model or large code model active. It's also possible that the converison problems only arise when large code model (which is default) or large data model is active and for small code/data model, it simply resolves to a 16bit pointer as usual. i had to look through the GCC headers to check this, but I don't have it installed.

  • Hi,

    I made the change to dma.c as you suggested:

    /* #define __DMA_ACCESS_REG__ (__SFR_FARPTR)(unsigned long) */
    #define __DMA_ACCESS_REG__ (__SFR_FARPTR)(uintptr_t)

    And I get the same warning.  All references to where __DMA_ACCESS_REG__ is used are marked as "invalid type conversion"

        DMA0DA = __DMA_ACCESS_REG__ dest;

    Do I need to change the CCS settings?

    Regards,

    Ed

  • Ed Lombardo said:
    And I get the same warning.  All references to where __DMA_ACCESS_REG__ is used are marked as "invalid type conversion"

    It seems there is some quirk in the CSS handling of the 20bit datatype. How to fix it?

    DMA0DA is definitely defined as __SFR_FARPTR. However, casting to this datatype fails where it shouldn't. One thing you can try is to disable large code/data model in the project settings (large cod emeodel is AFAIK the default for processors with 20bit address range). It may be that you then can just assign a 16bit pointer as you did in IAR. You might need to do a project clean, to ensure that no old information is surviving without being updated to the project change.

    I had to analyze the header files for further suggesitons. Which I can't do becasue I don't have CCS installed nor do I have the time to do it. Personally, I used handwritten assembly instructions to write a 20bit value to DAM0DA and SA, so it is independent of used code or data model and 20bit pointer support.

  • This problem has resurfaced with compiler 4.3.1 in CCSv6. A program I compile for MSP430F47177 without warnings in CCSv5.5 using compiler 4.2.3 contains the line:

    DMA0SA = (__SFR_FARPTR)(unsigned long)(gTxPIC.Address);

    However importing this project into CCSv6 with the same relevant build settings (large data model, restricted code model, none as near variables) using compiler 4.3.1 does generate an invalid type conversion warning when converting from (unsigned long) to (__SFR_FARPTR).

    "173-D invalid type conversion" 

    I submitted a support request to TI about this, but they have just sent me a link to this forum. Now I have searched the forum and did not find the solution. This is the closest thread. Any help would be appreciated.

  • You could try writing a request in the CCS compiler forum, as this is clearly a compiler-related problem.

  • Yes, I tried posting to the compiler forum but the moderator moved the post back to here. Then I put a service request to TI on their website after which TI Europe called and they said to go through the distributor for technical support and emailed me a list. I asked if that was also for compiler issues (as I buy the compiler direct) and they said if it is a technical issue, yes.

    TI used to have direct support. Silicon Labs still has direct support in Europe. Perhaps I am not large enough for them to worry about, but I do buy about XX,XXXX USD in TI products a year and the compilers and CCS are direct from them so it is disappointing. It is affecting my ability to upgrade to CCSv6 and more broadly my choice of vendor for cortex M3 solutions at the moment.

    Today I will find time to call the distributor and walk them through this problem. No-one likes change, I will how well the distributor route works.

  • Bradford Backus said:
    Yes, I tried posting to the compiler forum but the moderator moved the post back to here.


    Wow, the compiler guys are really quick in moving questions to other forums. If they read 'MSP', it is moved here instantly even though it has nothing to do with the processor.
    Well, they know that MSP questions are usually handled quickly and sufficiently here, but this one is nothing we can help with.

    I've filed a request to move this thread back.

  • Bradford Backus said:

    using compiler 4.3.1 does generate an invalid type conversion warning when converting from (unsigned long) to (__SFR_FARPTR).

    "173-D invalid type conversion" 

    Please submit a test case, preprocessed like this, and include the exact build options you use (copy-n-paste from the build console window).

    Thanks and regards,

    -George

  • Hi George,

    I have never submitted a test case before. Where do I submit this? 

    Best Wishes,

    Bradford

  • You attach it to your post.  Use the icon that looks like a paper clip.  Here is a video on the whole process.

    Thanks and regards,

    -George

  • Hi George,

    It would be great if you could take a look at this (5873.System.pp.txt preprocessed file as instructed) and suggest where it is going wrong. One example of the identical type of warnings I am dealing with is: 

    "../System.c", line 808: warning #173-D invalid type conversion

    When typecasting from (unsigned long) to (__SFR_FARPTR) in compiler 4.3.1 - 4.3.3 for setting DMA registers as described in TI documentation.

    this typecast used to work in 4.2.4

    The build settings are:

    -vmspx --abi=coffabi --data_model=restricted --near_data=globals -O1 --include_path="c:/ti/ccsv6/ccs_base/msp430/include" --include_path="c:/ti/ccsv6/tools/compiler/msp430_4.3.3/include" -g --preproc_with_compile --preproc_with_comment --define=__MSP430F47177__ --diag_warning=225 --display_error_number --printf_support=minimal

  • There are a couple of things going on here.

    Main thing first is that it is invalid to cast a data pointer to a function pointer or vice versa (even an explicit cast).  Hence the warning about “invalid type conversion”.

    For DMA setup on an mspx device, we need to get a 20-bit address.  This requires using the intrinsic:

                    __data16_write_addr(unsigned short addr, unsigned long src)

    The intrinsic generates the desired sequence including MOVA instruction:

                    MOV.W addr, Rx

                    MOVA src, 0(Rx)

     Please see msp430 dma example code for details: http://www.ti.com/lsds/ti/microcontrollers_16-bit_32-bit/msp/tools_software.page#code

    Or if you have MSP430Ware installed, you can browse through MSP430Ware content inside TI Resource Explorer to find the code examples.

    Regards,
    Greg

  • This worked for me in CCS 6.1, without any warnings:

    __data20_write_long((uintptr_t) DMA0SA, (uintptr_t) &source);

    Steve.
  • Correction: was missing an '&':

    __data20_write_long((uintptr_t) &DMA0SA, (uintptr_t) &source);

    Steve.
  • Thank you very much Steve even after so much time from the original post. I can verify that this also worked for me.

    I used for example:

    __data20_write_long((unsigned long)&DMA2DA, (unsigned long)&source);

    -B