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.

MSP430FR5969: Using FRAM above 0x10000 with MSPGCC 4.6.3

Part Number: MSP430FR5969
Other Parts Discussed in Thread: ENERGIA

In case it is helpful for anyone else using Energia/MSPGCC 4.6.3 with the MSP430FR5969 we have used the following routines to copy blocks of memory to and from FRAM above 0x10000.  For some reason we have found we get errors if the watchdog timer is not disabled during the transfer.  If anyone can explain why that is it would be useful to know.

void highmem_read(uint32_t srcaddr, void *dstaddr, uint16_t len) {

disableWatchDog(); //ensure no watchdog interrupt during DMA

DMA2CTL &= ~(DMAEN | DMAIFG);
DMACTL1 = (DMACTL1 & 0xFF00) | DMA2TSEL_0;
DMA2SZ = len;

asm volatile(
"rlam.a #4, %B[srcaddr] \n\t" // Upper 16 bits need shifting
"rlam.a #4, %B[srcaddr] \n\t"// Upper 16 bits need shifting
"rlam.a #4, %B[srcaddr] \n\t"// Upper 16 bits need shifting
"rlam.a #4, %B[srcaddr] \n\t"// Upper 16 bits need shifting

"adda %B[srcaddr], %A[srcaddr] \n\t"// Combine with lower 16 bits
" \n\t"
"movx.a %A[srcaddr], &__DMA2SA \n\t"
"movx.a %[dstaddr], &__DMA2DA \n\t"
: [srcaddr] "+r" (srcaddr)
: [dstaddr] "r" (dstaddr)
: );


DMA2CTL = DMAEN | DMADT_1 | DMASRCINCR_3 | DMADSTINCR_3 | DMASBDB ;
DMACTL4 = DMARMWDIS;
DMA2CTL |= DMAREQ;
while (!(DMA2CTL & DMAIFG))
;


// Done
DMA2CTL &= ~DMAIFG;

//interrupts();
enableWatchDog();

}


void highmem_write(uint32_t dstaddr, void *srcaddr, uint16_t len) {
// Copy <len> bytes in units of 1-byte per transfer from srcaddr[] to dstaddr[]
if (!len) return;

disableWatchDog(); //ensure no watchdog interrupt during DMA


DMA2CTL &= ~(DMAEN | DMAIFG);
DMACTL1 = (DMACTL1 & 0xFF00) | DMA2TSEL_0;
DMA2SZ = len;
asm volatile(
"rlam.a #4, %B[dstaddr] \n\t" // Upper 16 bits need shifting
"rlam.a #4, %B[dstaddr] \n\t"// Upper 16 bits need shifting
"rlam.a #4, %B[dstaddr] \n\t"// Upper 16 bits need shifting
"rlam.a #4, %B[dstaddr] \n\t"// Upper 16 bits need shifting
"adda %B[dstaddr], %A[dstaddr] \n\t"// Combine with lower 16 bits
" \n\t"
"movx.a %[srcaddr], &__DMA2SA \n\t"
"movx.a %A[dstaddr], &__DMA2DA \n\t"
: [dstaddr] "+r" (dstaddr)
: [srcaddr] "r" (srcaddr)
: );
DMA2CTL = DMAEN | DMADT_1 | DMASRCINCR_3 | DMADSTINCR_3 | DMASBDB
| DMALEVEL_L;
DMA2CTL |= DMAREQ;
while (!(DMA2CTL & DMAIFG))
;
// Done
DMA2CTL &= ~DMAIFG;
enableWatchDog();
}

  • Hello David,

    after quick look at your code, I see that you do not use WDT.
    Of course, my statement is relevant to the code above, not to your entire project.

    Rule of thumb: if you do not use it, disable it.

    About WDT:
    The primary function of the watchdog timer (WDT_A) module is to perform a controlled system restart after
    a software problem occurs. If the selected time interval expires, a system reset is generated. If the watchdog function
    is not needed in an application, the module can be configured as an interval timer and can generate interrupts
    at selected time intervals.

    About DMA:
    During a block transfer, the CPU is halted until the complete block has been transferred. The block transfer takes
    (2 × MCLK × DMAxSZ) clock cycles to complete. CPU execution resumes with its previous state after the block
    transfer is complete.

    As I remember, also a DMA block transfer would be interrupted by WDT.
    Could you check it and reply?
  • Thanks Tomasz.

    As I understand it, Energia always uses the watchdog timer as an interval timer to count milliseconds. I think you must be right that the watchdog timer interrupts DMA transfers even when it is configured as an interval timer but I am not sure where this is covered in the documentation. A side effect of my code is it introduces some inaccuracy into the Energia milliseconds count returned by millis().

    Regards

    David
  • David,

    Saying: As I remember, also a DMA block transfer would be interrupted by WDT,
    I was thinking about WDT working as watchdog, not a timer.
    WDT working as watchdog generates system breaks when in case of timer function, WDT generates just interrupt.
    Sorry for a misleading statement.

    I do not know Energia. Energia is not TI product and, on this portal, it is sometimes hard to find answer quickly.
    As I remember, the best place for Energia support is a forum on www.43oh.com

    This pdf covers all details you may need: WDT, DMA, Interrupts.
    www.ti.com/.../slau367o.pdf

**Attention** This is a public forum