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.

problem with :DMA activation by SW REQ (DMAREQ bit)

Other Parts Discussed in Thread: MSP430F5438A

hello,

i'm working with the msp430F5438A.
and my IDE is CCs 5.3.

the problem is with the DMA.

I try to send data  to the terminal by the DMA
with the following features:
the data is : block.
the triger is by the SW: DMAREQ bit.


the result is that only one character is send and then
the DMAEN is reset and the transmition is stop.

is there anyone any hint how to solve the problem?

thanks.

the code is
=====================
#include <msp430.h>

typedef unsigned int Uint16;

const char String[60] = "word1 word2 word3 word4 word5 word6 word7 word8\r\n";
Uint16 SrtingSize = 0;

void ClockCnfg ( void);// 16Mhz clock (MCLK).
void TimerA1Cnfg (void);// blink led, period of 100ms;
void PortCnfg (void) ; // config the uart and the led port.
void CommCnfg (void);// config uart 1 : 57600 BR, SMCLK
void DmaCnfg ( void) ; //DMA  block transmision.

void main (void)
{
    __bic_SR_register (GIE);
    PortCnfg();
    ClockCnfg();
    TimerCnfg();
    CommCnfg();
    DmaCnfg ();
    __bis_SR_register (GIE);
    while (1)
    {
        __delay (65000);
        __delay (65000);
        __delay (65000);
        DMA0CTL |= DMAREQ;
    }
}

void DmaCnfg (void)
{
    DMA0CTL &= DMAEN;/* DMAxTSEL should by modified only when
                        the DMACTLx DMAEN bit is 0 */
    DMACTL0 = DMA0TSEL_0; // DMA REQ by sw.
    __data16_write_addr ( ( unsigned short )&DMA0SA , ( unsigned long )&String);
    __data16_write_addr ( ( unsigned short )&DMA0DA , ( unsigned long )&UCA0TXBUF);
    DMA0SZ = StringSize = sizeof (String);
    DMA0CTL |= DMADT_1 + // block transfer.
        DMASRINcR_3 + // source address is incremented.
        DMASBDB // DMA source byte.
        ;
    DMA0CTL |= DMAEN; // Dma enable.
}

  • I’m not sure whether sizeof(String) is what you want. “String” is an unsigned char * and its size is 2 (or 4 in large data model). If you want to know the size of the array it points to, then use strlen(String) to determine the real size of a 0-terminated string.
    I also wouldn’t use an size parameter when defining a constant array that is initialized with a string. Best case you waste space as the array is longer than the string, worst case the sting is longer and you’ll get errors.
    Just use const unsigned char String[]=”xxx”;
    BTW: did you compile the code? You define “SrtingSize” and use “StringSize”,
    J

  • Hello,

    Thanks for all comments. I implemented them.
    i made some change in the code and now the code is work.

    the code is
    =====================
    #include <msp430.h>
    #include <string.h>// for strlen();

    const char String[] = "Hello World\r\n";

    void ClockCnfg ( void);// 16Mhz clock (MCLK).
    void TimerA1Cnfg (void);// blink led, period of 100ms;
    void PortCnfg (void) ; // config the uart and the led port.
    void CommCnfg (void);// config uart 1 : 57600 BR, SMCLK
    void DmaCnfg ( void) ; //DMA  block transmision.

    void main (void)
    {
        __bic_SR_register (GIE);
        PortCnfg();
        ClockCnfg();
        TimerCnfg();
        CommCnfg();
        DmaCnfg ();
        __bis_SR_register (GIE);
        while (1)
        {

            while ((DMA0CTL & DMAEN )!=0)
            {
                __no_operation(); // wait here for the end of the transmission..
            }
            DMA0CTL |= DMAEN; // start new block transmission.
        }
    }

    void DmaCnfg (void)
    {
        DMA0CTL &= DMAEN;/* DMAxTSEL should by modified only when
                            the DMACTLx DMAEN bit is 0 */
        DMACTL0 = DMA0TSEL_17; // USCI_A0 TXIFG tirgger.
        __data16_write_addr ( ( unsigned short )&DMA0SA , ( unsigned long )&String);
        __data16_write_addr ( ( unsigned short )&DMA0DA , ( unsigned long )&UCA0TXBUF);
        DMA0SZ = strlen (String);
        DMA0CTL |= DMADT_1 + // block transfer.
            DMASRINCR_3 + // source address is incremented.
            DMASBDB // DMA source byte.
            ;
        DMA0CTL |= DMAEN; // Dma enable.
    }

  • Hi,

     The same code i used but for me first character only sent, even i hard coded the size.

     Can anyone help.

  • The code has a still unhandled bug: block mode is wrong. In block mode, after the trigger, the whole block is sent with maximum speed. So TXBUF is stuffed over and over again before it has even started sending the first byte.
    Single transfer has to be used with TXBUF. So each transfer needs its own trigger from TXBUF.

  • Thanks Jens,

     Now i got a better clarification

**Attention** This is a public forum