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.

MSP430F67791A: DMA9 workaround in MSP430Ware

Part Number: MSP430F67791A

Hello,

we are going to design an E-Meter on MSP430F67791A device.

We have to send a big amount of data by UART, but the presence of DMA9 issue makes this process not so simple in terms of CPU overhead.

The workaround of DMA9 provided in SLAZ598U is not completely clear.

We tried to find some software examples on how to implement data transfer avoiding this issue in MSPWare, but find no information on this case.

Does MSPWare contain any examples of workaround on DMA9 issue on MSP430F67791A?

Could you please provide any code examples on how to handle this error?

Thank you.

  • Hi Slava,

    we are going to design an E-Meter on MSP430F67791A device.

    Great. Glad you're using the A version, not the non-A version. For more details about those differences, refer to Differences Between MSP430F67xx and MSP430F67xxA Devices. Also, consider using the Energy Measurement Design Center (EMDC) for your E-meter design.

    We have to send a big amount of data by UART, but the presence of DMA9 issue makes this process not so simple in terms of CPU overhead.

    The workaround of DMA9 provided in SLAZ598U is not completely clear.

    The workaround describes using two DMA channels to mitigate the errata issue. Refer to the following threads for more details.

    MSP430FR5739: The workaround for DMA9 errata of EXP430FR5739

    MSP430F67xx errata DMA9

    We tried to find some software examples on how to implement data transfer avoiding this issue in MSPWare, but find no information on this case.

    Does MSPWare contain any examples of workaround on DMA9 issue on MSP430F67791A?

    Could you please provide any code examples on how to handle this error?

    I couldn't find any code examples demonstrating the DMA9 workaround in TI Resource Explorer. You may be able to find the workaround in some of the F6779A-based TI reference design code if they use DMA (not sure if any do or not).

    It sounds like the DMA9 workaround is feasible, but since you're early in the design, perhaps you can work around this by using a different interface such as SPI or I2C that wouldn't be affected.

    Another important set of errata that designers sometimes miss are the AUXPMM1 and AUXPMM2 errata. Those require careful consideration when using auxiliary power supplies and backup batteries. I wanted to highlight these.

    Regards,

    James

  • Hello James,

    I can't find any code sources on how to fix DMA9. Does this mean that no software example is provided as solution for this issue and customer has to implement and test this part of code by himself?

  • Hi Slava,

    That's correct. I did find a DMA UART DriverLib example that they could start with and modify. There may be other F5xx/F6xx code examples that may help too. It sounds like the errata is just duplicating one DMA channel with another at lower priority. Once they configure the first channel, the second shouldn't be too hard.

    Regards,

    James

  • Hi James,

    thank yo for provided source code example. But this example doesn't show us how :

    - to setup two different DMA channels for the same data transfer

    - to use a 2nd dummy DMA transmission (according to recommendation from this thread MSP430FR5739: The workaround for DMA9 errata of EXP430FR5739).

    I provide the initial DMA source code from customer below.

    Could you please modify this to  add a required code, that can make DMA work without DMA9 issue?

    Thank you in advance.

    include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include <msp430.h>
    
    //third party
    #include "dma.h"
    #include "usci_a_uart.h"
    
    /*
    
    CHANNEL DMA0                DMA1                DMA2
    0       DMAREQ              DMAREQ              DMAREQ
    1       TA0CCR0 CCIFG       TA0CCR0 CCIFG       TA0CCR0 CCIFG
    2       TA0CCR2 CCIFG       TA0CCR2 CCIFG       TA0CCR2 CCIFG
    3       TA1CCR0 CCIFG       TA1CCR0 CCIFG       TA1CCR0 CCIFG
    4       Reserved            Reserved            Reserved
    5       TA2CCR0 CCIFG       TA2CCR0 CCIFG       TA2CCR0 CCIFG
    6       Reserved            Reserved            Reserved
    7       TA3CCR0 CCIFG       TA3CCR0 CCIFG       TA3CCR0 CCIFG
    8       Reserved            Reserved            Reserved
    9       Reserved            Reserved            Reserved
    10      Reserved            Reserved            Reserved
    11      Reserved            Reserved            Reserved
    12      Reserved            Reserved            Reserved
    13      SD24IFG             SD24IFG             SD24IFG
    14      Reserved            Reserved            Reserved
    15      Reserved            Reserved            Reserved
    16      UCA0RXIFG           UCA0RXIFG           UCA0RXIFG
    17      UCA0TXIFG           UCA0TXIFG           UCA0TXIFG
    18      UCA1RXIFG           UCA1RXIFG           UCA1RXIFG
    19      UCA1TXIFG           UCA1TXIFG           UCA1TXIFG
    20      UCA2RXIFG           UCA2RXIFG           UCA2RXIFG
    21      UCA2TXIFG           UCA2TXIFG           UCA2TXIFG
    22      UCB0RXIFG0          UCB0RXIFG0          UCB0RXIFG0
    23      UCB0TXIFG0          UCB0TXIFG0          UCB0TXIFG0
    24      ADC10IFG0           ADC10IFG0           ADC10IFG0
    25      UCA3RXIFG           UCA3RXIFG           UCA3RXIFG
    26      UCA3TXIFG           UCA3TXIFG           UCA3TXIFG		*****
    27      UCB1RXIFG0          UCB1RXIFG0          UCB1RXIFG0
    28      UCB1TXIFG0          UCB1TXIFG0          UCB1TXIFG0
    29      MPY ready           MPY ready           MPY ready
    30      DMA2IFG             DMA0IFG             DMA1IFG
    31      Reserved            Reserved            Reserved
    */
    
    
    static uint8_t tx_buf[1072];
    
    void SendDataToUCA3(uint8_t *buf, uint16_t count)
    {
        DMA_initParam param;
    //Initialize and Setup DMA Channel 0
        memset(&param, 0, sizeof(DMA_initParam));
        param.channelSelect = DMA_CHANNEL_0;
        param.transferModeSelect = DMA_TRANSFER_BLOCK;
        param.transferSize = count - 1;
        param.triggerSourceSelect = DMA_TRIGGERSOURCE_26;
        param.transferUnitSelect = DMA_SIZE_SRCBYTE_DSTBYTE;
        param.triggerTypeSelect = DMA_TRIGGER_RISINGEDGE;
        DMA_init(&param);
    //
        memcpy(tx_buf, buf, count);
    //
        DMA_setSrcAddress(DMA_CHANNEL_0, (uint32_t)(&tx_buf[1]), DMA_DIRECTION_INCREMENT);
        DMA_setDstAddress(DMA_CHANNEL_0, (uint32_t)(&UCA3TXBUF),  DMA_DIRECTION_UNCHANGED);
    //    
        DMA_enableInterrupt(DMA_CHANNEL_0);
        DMA_enableTransfers(DMA_CHANNEL_0);
        DMA_startTransfer(DMA_CHANNEL_0);   
        
        UCA3TXBUF = tx_buf[0];
    };
    
    #pragma vector=DMA_VECTOR
    __interrupt void DMA_ISR(void)
    {
      
      switch(__even_in_range(DMAIV, 16))
      {
        case DMAIV_DMA0IFG:
          DMA0CTL = 0;
          break;
        case DMAIV_DMA1IFG:
          DMA1CTL = 0;
          break;
        case DMAIV_DMA2IFG:
          DMA2CTL = 0;
          break;
      };
    };
    

  • Hi Slava,

    This is a good start. Based on the DMA9 workaround described in the erratasheet, they should be able to just copy/paste their DMA Channel 0 configuration code and then tweak it to configure DMA Channel 2 to use the same interrupt flag (e.g. DMA_TRIGGERSOURCE_26) as the trigger source. That should prevent any missing bytes during transmission.

  • Hello James, there is another question on the same topic.

    Customer revealed, that he uses MSP430F67791A rev.C on his board.

     The document SLAZ598U – MSP430F67791A Device Erratasheet claims, that rev.C does not contain a DMA9 error.

    Could you please confirm, that there is no typo in Errata document and rev.C does not contain DMA9 error?

    If there is no any typos in ERRATA document, could you please check the source code provided above for any mistakes?

  • Could you please confirm, that there is no typo in Errata document and rev.C does not contain DMA9 error?

    That's correct.

    If there is no any typos in ERRATA document, could you please check the source code provided above for any mistakes?

    Here's my feedback about the code:

    • Add DMA_clearInterrupt(DMA_CHANNEL_0); before DMA_enableInterrupt(DMA_CHANNEL_0);
    • Remove DMA_startTransfer(DMA_CHANNEL_0); Writing the first byte to TXBUF should start the transfer because the DMA is configured to use TXIFG as the trigger. They are manually sending the first byte at index [0], so it makes sense they start at index [1] in DMA_setSrcAddress.

**Attention** This is a public forum