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.

Using breakpoints during a DMA transfer with TI FET firmware 2.4.2.0 problem

Other Parts Discussed in Thread: MSP430F5437

I'm running my program on a MSP430F5347 processor with the TI FET430UIF, and IAR Embedded Workbench

The version of msp430.dll found inside the IAR folder is 2.4.2.0, the version of hil.dll is 1.2.6.0

 

The problem I'm experience is that when a breakpoint is used during a DMA transfer the processor simply resets.

 

If I load the msp430.dll version 2.4.1.0, I don't see this issue. 

 

Below is the code i was running and the setup I have.

- One SPI port is configured to always run as master (UCA0), and one SPI port is configured to always run as slave (UCA1).

- DMA channel 0 is used to send messages out UCA0, and DMA channel 1 is used to read messages from UCA1.

- The hardware on the other end of the SPI is configured similarly (1 master SPI port, and 1 slave SPI port).  That hardwares master is connected to the MSP slave, and slave is connected to the MSP master.  When that hardware gets data from the MSP430, it will then send back data to the MSP430.

 

If I place a breakpoint at the while (1) {} code in main, and single step, the whole thing just resets.

 

 

 

#include "msp430f5437.h"

//==== Port Data======
#define PIN_OUTPUT_DIRECTION (0xff)
#define PIN_INPUT_DIRECTION (0x00)

//Port 3 bit locations
#define UCx_SPIX_SCK    BIT0 //output pin
#define UCx_SPIX_CS_N   BIT3 //output pin, active low
#define UCx_SPIX_MOSI   BIT4 //output pin
#define UCx_SPIX_MISO   BIT5 //not used

#define UCx_SPIS_SCK    BIT6

//Port 5 bit locations
#define UCx_XT2IN       BIT2
#define UCx_XT2OUt      BIT3
#define UCx_SPIS_CS_N   BIT5 //active low
#define UCx_SPIS_MOSI   BIT6
#define UCx_SPIS_MISO   BIT7 //un-used

// Port 7 bit locations
#define UCx_XIN         BIT0
#define UCx_XOUT        BIT1

// global variable flags used to see if a transfer was finished
unsigned int dma0done;
unsigned int dma1done;

#pragma vector = DMA_VECTOR
__interrupt void dmaIntHdlr (void)
{
    unsigned int interrReg = DMAIV;
   
    switch (interrReg)
    {
        case DMAIV_DMA0IFG: //if master finished, turn off chip select
        {
            dma0done ++;
           
            //clear chip select
            P3OUT |= UCx_SPIX_CS_N;
           
            //clear interrupt and disable channel
            DMA0CTL &= (~DMAEN | ~DMAIFG);
            break;
        }
        case DMAIV_DMA1IFG:
        {
            dma1done ++;

            //clear interrupt and disable channel
            DMA1CTL &= (~DMAEN | ~DMAIFG);
            break;
        }
    };
}

static void setupClock ()
{
    //configure port 5 (16 MHz) and port 7 (32kHz)
    //set as peripherals
    P5SEL |= UCx_XT2IN | UCx_XT2OUT;
    P7SEL |= UCx_XIN | UCx_XOUT;
   
    //ACLK src = XT1, sclk src = XT2, mclk src = XT2
    UCSCTL4 = SELA__XT1CLK + SELS__XT2CLK + SELM_XT2CLK;
   
    //turn on the oscillators
    UCSCTL6 &= ~(XT1OFF + XT2OFF);
   
    //load cap 12 pF
    UCSCTL6 |= XCAP_3;
    UCSCTL6 &= ~SMCLKOFF;
   
    //clear oscillator faults
    while (SFPIFG1 & OFIFG)
    {
        UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HOFFG + DCOFFI);
        //attempt to clear fault flag
        SFRIFG1 &= ~OFIFG;
    }
    //assign the clocks
    UCSCTL6 &= ~(XT1DRIVE_0);
    UCSCTL6 &= ~(XT2DRIVE_2);
}

static void configDma ()
{
    DMA0CTL &= ~DMAEN;
    DMA1CTL &= ~DMAEN;
   
    //DMA 0 is for TX, so set trigger to master SPI TX buffer empty
    //DMA 1 is for RX, so set trigger to salve SPI RX buffer full
    DMACTL0 = DMA0TSEL__USCIA0TX | DMA1TSEL__USCIA1RX;
   
    //single xfer, dest const, src incremening, byte, interrupt enable, edge
    DMA0CTL = DMADT_0 | DMADSTINCR_0 | DMASRCINCR_3 | DMASBDB | DMAIE;
    //single xfer, dest incremening, src const, byte, interrupt enable, edge
    DMA1CTL = DMADT_0 | DMADSTINCR_3 | DMASRCINCR_0 | DMASBDB | DMAIE;
   
    DMACTL4 |= DMARMWDIS_L; //I have tried both setting this and not setting this
}

static void configSpi ()
{
    //mast port
    UCA0CTL1 = UCSWRST;
    UCA0CTL0 = UCCKPH | UCMSB | UCMST | UCSYNC;
    UCA0CTL1 = UCSSEL__SMCLK | UCSWRST;
    UCB0BRW = 0x0010;
   
    P3SEL |= UCx_SPIX_SCK | UCx_SPIX_MOSI;
    P3SEL &= ~(UCx_SPIX_CS_N | UCx_SPIX_MISO);
    P3DIR |= UCx_SPIX_SCK | UCx_SPIX_CS_N | UCx_SPIX_MOSI | UCx_SPIX_MISO;
    //turn off chip select, pin is active low
    P3OUT |= UCx_SPIX_CS_N;
   
    UCA0IE = 0x00;
    UCA0CTL1 &= ~UCSWRST
   
    //slave port
    UCA1CTL1 = UCSWRST;
    UCA1CTL0 = UCCKPH | UCMSB | UCSYNC;
   
    P3SEL |= UCx_SPIS_SCK;
    P3DIR &= ~UCx_SPIS_SCK;
    P5SEL |= UCx_SPIS_MOSI;
    P5SEL &= ~(UCx_SPIS_CS_N | UCx_SPIS_MISO);
    P5DIR &= ~(UCx_SPIS_CS_N | UCx_SPIS_MOSI);
    P5DIR |= UCx_SPIS_MISO;
   
    UCA1IE = 0x00;
    UCA1CTL &= ~UCSWRST;
}

static void appStartup ()
{
    P1DIR = PIN_OUTPUT_DIRECTION;
    P2DIR = PIN_OUTPUT_DIRECTION;
    P3DIR = PIN_OUTPUT_DIRECTION;
    P4DIR = PIN_OUTPUT_DIRECTION;
    P5DIR = PIN_OUTPUT_DIRECTION;
    P6DIR = PIN_OUTPUT_DIRECTION;
    P7DIR = PIN_OUTPUT_DIRECTION;
   
    P1OUT = 0xff;
    P2OUT = 0xff;
    P3OUT = 0xff;
    P4OUT = 0xff;
    P5OUT = 0xff;
    P6OUT = 0xff;
    P7OUT = 0xff;

    setupClock();
    configSpi ();
    configDma ();
   
    P1IFG = 0;
    P2IFG = 0;
}

//just some data to send to the hardware, once hardware receives this, it should send back some other data
unsigned char outMessage [] = {0xaa, 0x00, 0x00, 0xaa, 0x00, 0xaa};

//hardware sends back 12 bytes of data on receiving the first message
unsigned char inMessage [12] = {0};

void main ()
{

    WDTCTL = WDTPW + WDTHOLD;
   
    __enable_interrupt ();
   
    dma0done = 0;
    dma1done = 0;
   
    appStartup ();
   
    //toggle the reset
    UCA0CTL1 |= UCSWRST;
    UCA0CTL1 &= ~UCSWRST;
   
    UCA1CTL1 |= UCSWRST;
    UCA1CTL1 &= ~UCSWRST;
   
    //ready the receive dma channel first
    DMA1SA = (__data20 unsigned int *)&UCA1RXBUF;
    DMA1DA = inMessage;
    DMA1SZ = 12;
    DMA1CTL |= DMAEN;
   
    //set the chip select and ready the master/tx dma channel
    P3OUT &= ~UCx_SPIX_CS_N;
   
    DMA0SA = outMessage;
    DMA0DA = (__data20 unsigned int *)&UCA0TXBUF;
    DMA0SZ = sizeof(outMessage);
    DMA0CTL |= DMAEN;
   
    //trigger the transfer buffer empty to initiate transfer
    UCA0IFG &= ~UCTXIFG;
    UCA0IFG |= UCTXIFG;
   
    while (1) {}
   
}

  • Normal 0 false false false EN-US X-NONE X-NONE MicrosoftInternetExplorer4

    Hi Li,

     I noticed you are using an old version of the MSP430.DLL. Could you please upgrade it  to the latest one B2.4.6.1.

     

    The issue you noticed should be fixed in this one.

    The processor won’t reset.  But it’s possible that transferred data might be corrupted.

     

    I would recommend to not set breakpoints during an active DMA transfer.

     

    Regards Florian

  • Hi Florian,

      Could you please kindly point me to where I may download the newest version?

    I found the wiki link http://processors.wiki.ti.com/index.php/MSP430_JTAG_Interface_USB_Driver but the version there is 2.4.4.0

    Thanks,

    Ying

  • Normal 0 false false false EN-US X-NONE X-NONE MicrosoftInternetExplorer4

    Hi Ying,

    Ok i see. Just download the latest version of IAR Kickstart from the TI Web. In this Version the DLL V2.4.6.1 is included.

    http://dl-www.ti.com/lit/sw/slac050z/slac050z.zip

    Regards Florian

**Attention** This is a public forum