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.

MSP430FR5994: Repeated Burst-block DMA

Part Number: MSP430FR5994

I use repeated burst-block to DMA Rx into memory.

The documentation says: "In repeated burst-block mode the CPU executes at 20% capacity continuously until the repeated burst-block transfer is stopped."

Does stop mean:

1) - until the rx byte is transferred

2) - until the dma controller is stopped

(If 2) very poor performance hit at low baud rates :-)

  • If you are only wanting to move data from a serial (or I2C/SPI) receive port, it is more likely you need to be using mode 000 - the single transfer mode. This will trigger the transfer of a single piece of data from the source to the destination *per trigger*, and halt after N transfers. Otherwise you will be transferring a block-length number of repeated reads of the *same register* with every trigger.
  • I set up a ring buffer in memory with the tail following DMAxSZ.  Very simple.

    The question remains, what will hapen at low baud rates, 80 % performance hit?

  • Burst block mode is really for transferring large amounts of memory as fast as possible. The 80% amount is to allow the CPU to respond to external interrupts, otherwise there would be no CPU bandwidth to respond while the transfer was in process. But it is not intended for use with single-byte/word transfers initiated with a trigger at every data event. I include some live code for driving the SPI ports as a backplane comms channel, perhaps you might find something useful there. This code flips between using the same DMA channel for either transmit or receive - slave-mode is receive.

    // DMA.
    // ----

    // WARN there are DMA errata (DMA4) affecting the operation of this module.
    // modifying the DMA registers while a DMA operation takes place causes corruption.

    // WARN !!! the DMA implementation in the MSP430 nukes the CPU quite easily.
    // =========================================================================
    // if changes are made to the DMA setup while it is active,
    // it mangles the internal state of the CPU quite badly.
    // so far it has been seen to affect at least the SPI and the CRC blocks.
    // there seems to be no recovery for this condition other than reset.
    // Erratum DMA4 indicates that this only applies to 20-bit DMA register accesses,
    // but it seems to apply to 16-bit as well, and the workarounds don't seem to work.

    // MISO has a problem that it pulls low if enabled while SPI disabled.
    // therefore we disable the peripheral pin function to let it float.

    // NOTE that there is a bit of an issue with DMA timing.
    // because the SPI hardware buffers the outgoing data, the DMA completes before it.
    // in fact, the DMA completes before the last two bytes have gone out,
    // since the DMA completes with the last write to the buffer.
    // so we send two extra bytes (nominally), and know that when the DMA completes,
    // it is because there are now two dummy bytes in the buffers.
    // these bytes will either be chopped off by the sender,
    // or received and ignored by the receiver.

    // BP DMA.
    // -------
    
    inline void bp_dma_mst_enable( void ) {
    	DMA1CTL |= DMAEN;
    }
    inline void bp_dma_slv_enable( void ) {
    	DMA1CTL |= DMAEN;
    }
    inline void bp_dma_disable( void ) {
    	DMA1CTL &= ~DMAEN;
    }
    inline void bp_dma_slv_reload_data( void * a_dst_p ) {
    	DMA1CTL = DMADT_0 + DMASRCINCR_0 + DMADSTINCR_3 + DMASBDB + DMAIE;
    	DMA1SA = (__SFR_FARPTR ) ((void *) &UCB1RXBUF);
    	DMA1DA = (__SFR_FARPTR ) ((void *) a_dst_p);
    	// maximum allowed data receive.
    	DMA1SZ = frm__max_size();
    	DMACTL0 = (DMACTL0 & 0xFF) | DMA1TSEL__USCIB1RX;
    }
    inline void bp_dma_mst_reload_data( void * a_src_p, int a_size ) {
    	DMA1CTL = DMADT_0 + DMASRCINCR_3 + DMADSTINCR_0 + DMASBDB + DMAIE;
    	DMA1SA = (__SFR_FARPTR ) ((void *) a_src_p);
    	DMA1DA = (__SFR_FARPTR ) ((void *) &UCB1TXBUF);
    	DMA1SZ = a_size + 2;
    	DMACTL0 = (DMACTL0 & 0xFF) | DMA1TSEL__USCIB1TX;
    }
    
    
    void bp_spi__init( void ) {
    
    	bp_dma_disable();

    ... // initial setup for SPI DMA (DMA0/1=RX/TX). // ----------------------------------------- // no NMI-can-abort, disable DMA during R/M/W CPU ops. DMACTL4 = DMARMWDIS; // set up DMA for master/slave usage. DMA1CTL = DMADT_0 + DMASBDB + DMAIE; ...
    }

**Attention** This is a public forum