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 in block transfer mode not sending block

Other Parts Discussed in Thread: MSP430F5637

I've been working on this for a few days and just can't seem to see the problem here.  I'm just trying to send a block of data out of a UART as a starting point and have run into this.  I've configured the DMA channel 0 based on what I read in the data sheet and some examples.  The code interrupts in the correct DMA vector, but I don't ever get the block of data out.  I only get 1 byte and it isn't ever the first by of my array.

I load a 256 byte array with a for loop at the top and then use that array as my source address and the UCA0TXBUF as my destination address.  When I check the registers in the debugger these addresses seem to be loaded correctly.  The value in the size register is also correct.  I've tried larger and smaller values as well.

I set this to send out a single by in the array on repeated single transfer and it works.  If I pick the 5'th byte in the array it repeatedly sends out 5, array element 6 is 6 etc... 

/*  
 * ======== main ========
 */
VOID main (VOID)
{

	char data_buff[256];
	char i;
	for(i=0; i<255; i++){
		data_buff[i] = i;
	}



	WDTCTL = WDTPW + WDTHOLD;	// Stop watch dog timer

    SetVCore(3);	// Max voltage on core

    /*
     * Setup Clock System UCS
     * ----------------------
     * DCO -> 20Mhz
     * MCLK -> DCO
     * SMCLK -> DCO/4
     * ACLK -> REFO (32.768Hz)
     */
    UCSCTL3 = SELREF__REFOCLK;			// Select REFO CLK for FLL reference (FLL_refclk)
    UCSCTL4 = (UCSCTL4 & ~(SELA_7)) | (SELA__REFOCLK);		// Select REFO for ACLK
    Init_FLL_Settle(USB_MCLK_FREQ / 1000, USB_MCLK_FREQ / 32768);   // DCO will be driven by the FLL which is referenced from REFO
    																// FLLN = /305, FLLD = /2, FLL_refdiv = /1
    																// Using USB_MCLK_FREQ, but could be standard desired MCLK frequency/1000
    																// Divide by 1000 b/c function requires it
    																// Ratio is always the ratio of the desired clock / reference clock
    P7SEL |= (BIT2 + BIT3);		// Enable pins to function as oscillator inputs (XT2IN, XT2OUT)
    XT2_Start(XT2DRIVE_0);      // Start XT2 Oscillator
    UCSCTL5 |= 0x20;			// SMCLK/4

    ConfigSubMainCLKout();


    /*
     * Configure UART
     * ---------------
     * P2.0 -> USCI_A0 UART RXD
     * P2.1 -> USCI_A0 UART TXD
     */
    P2SEL |= BIT4 + BIT5;
    P2DIR |= BIT4;

    PMAPKEYID = 0x2D52;		// Unlock port map controller
    PMAPCTL |= BIT1;
    P2MAP5 = PM_UCA0RXD;	// Map UCA0 RXD to P2.5
    P2MAP4 = PM_UCA0TXD;	// Map UCA0 TXD to P2.4

    // Configure UART
    UCA0CTL1 |= UCSWRST;	// Hold USCI in reset
    UCA0CTL0 = 0x00;		// No parity, LSB first, 8bit data, 1 stop bit, UART mode, Asynchronus
    UCA0CTL1 |= UCSSEL_1;	// use ACLK (32768), leave in reset for configuration
    UCA0BR0 = 3;			// Baud clock settings from table
    UCA0MCTL = UCBRS_3;		// ""
    UCA0CTL1 &= ~UCSWRST;			// Enable USCI logic
    //UCA0IE |= UCRXIE;				// Enalbe RX interrupts
    UCA0IFG = 0x00;					// Clear pending inetrrupt flags



    /*
     * Setup DMA controller
     */
    DMACTL0 |= DMA0TSEL_17;
    DMACTL4 = DMARMWDIS;
    DMA0CTL &= ~DMAIFG;
    DMA0CTL |= DMADT_2 + DMASRCINCR_3 + DMADSTBYTE + DMASRCBYTE + DMAIE + DMAEN;
    DMA0SZ = 256;
    //__data16_write_addr((unsigned short) &DMA3SA, (unsigned long) &data_buff);
    //__data16_write_addr((unsigned short) &DMA3DA, (unsigned long) UCA0TXBUF);
    DMA0SA = (__SFR_FARPTR) (unsigned int) &data_buff[0];
    DMA0DA = (__SFR_FARPTR) (0x05C0 + 0x0E);	// UCA0TXBUF;


    UCA0TXBUF = 0x55;




    __enable_interrupt();                           //Enable interrupts globally







    while (1)
    {

    }  //while(1)
} //main()



//------------------------------------------------------------------------------
// DMA Interrupt Service Routine
//------------------------------------------------------------------------------
#pragma vector=DMA_VECTOR
__interrupt void DMA_ISR(void)
{
  switch(__even_in_range(DMAIV,16))
  {
    case 0: break;
    case 2:                                 // DMA0IFG = DMA Channel 0
    	_nop();
      break;
    case 4: break;                          // DMA1IFG = DMA Channel 1
    case 6: break;                          // DMA2IFG = DMA Channel 2
    case 8: 		                        // DMA3IFG = DMA Channel 3

    _nop();
    break;
    case 10: break;                         // DMA4IFG = DMA Channel 4
    case 12: break;                         // DMA5IFG = DMA Channel 5
    case 14: break;                         // DMA6IFG = DMA Channel 6
    case 16: break;                         // DMA7IFG = DMA Channel 7
    default: break;
  }
}

My code is above. I also have no problem entering the interrupt when in burst block mode. I hit case 2 every time but nothing comes out of the uart. I've also tried different DMA channels, but still no go. Any help is appreciated!


I'm using a 100pin MSP430F5637

Thanks,

Rob

  • Don't know about FET break point debugging engine, but in general until device is under JTAG control DMA is disabled.

    http://forum.43oh.com/topic/2843-msp430-dma/?p=35770

    You can also read another posts from linked topic. There is DMA > UART example for MSP430F55xx in open source TI USB stack.

  • Hmmm....

    After reading the post you linked me to I tried just powering up the MSP430 and pushing the reset button I've got which reset the device, but the output is still wrong.  So far I'm still not sure whats up, but thanks for the input and I'll post up the solution when I figure it out :)


    Quick question.  In reading the data sheet over and over I'm now wondering if I miss-read/understood how the DMA block and burst/block transfers actually work.  I've changed this over to, specifically, "block" transfer mode and notice that I always get the last byte of my array out of the UART.  So if I set my counter to 10 for the array I made (data array) I get a 0x0A out of the serial port.  I'm thinking that the DMA just unloads the data into the TX buffer so fast it overwrites itself until the dma transfer ends leaving the last byte (in the case of setting the DMASZ value to 10) which would be 0x0A.  What I'm getting at is this:  In block mode it looks like the DMA moves the data as fast as it can overwriting older values in this situation does this apply to burst block?  I'm wondering if the TX interrupt flag triggers the block or burst/block transfer making the DMA unload as fast as possible the entire block into the TXBUFF rather than load data into the TXBUFF as it is sent out the serial port. 

    It seems like this functionality of having the DMA work through the block of data AS the peripheral sends it out successfully would have to be there, but from what I've seen from further testing specifically "Block" transfer mode doesn't seem to support this.  Thoughts?

  • Robbie Valentine said:

    It seems like this functionality of having the DMA work through the block of data AS the peripheral sends it out successfully would have to be there, but from what I've seen from further testing specifically "Block" transfer mode doesn't seem to support this.  Thoughts?

    Maybe you have wrong picture related to DMA modes.
    Here is example how it is (DMA > UART) done in TI USB Stack (case nTmp1 > 5) using single transfer mode (DMADT_0) ...

**Attention** This is a public forum