Location>code7788 >text

MSPM0G3507 Peripheral DMA Learning Notes

Popularity:281 ℃/2024-07-28 14:31:21

summarize

Storage of variables


Normally, the variable is stored in SRAM, and to send the value of that variable to the peripheral, you need to call a kernel operation to make the data in SRAM go to the peripheral.
Too much of this type of operation can lead to high CPU usage and overall lag.

DMA Control Overview


  • DMA:Direct Memory Access
  • Dedicated to data transfer, freeing up the CPU
  • For DMA, the CPU first initiates the transfer, then performs other operations during the transfer, and finally receives an interrupt from the DMA controller when the operation is complete.
  • ----> CPU starts and ends with DMA interrupt flag transfer complete.
  • DMA transfers are bidirectional, either from the peripheral to the SRAM or from the SRAM to the peripheral.
  • Typically, the data transferred by DMA, in the peripheral/SRAM, is addressedprogressionThe ----> can be sequentially shifted for addressing to achieve the effect of transferring data sequentially.

DMA register related (general purpose)

PerAddr (transmit peripheral address)

SramAddr (transfer SRAM address)

Direction (set the transmission direction)

DataSize (size of transmitted data)

Sram+ (whether SRAM address is moved or not)

Peri+ (whether the peripheral address is moved or not)

--> Generally peripheral addresses are fixed and immobile

G3507 DMA Setup

Setting the Addressing Method

  1. Fixed address to fixed address
    Fixed Address to Fixed Address

  2. Fixed address to block of addresses
    Fixed Address to Address Block

  3. Block of addresses to fixed address
    Address Block to Address Block

  4. Block of addresses to block of addresses
    Address Block to Address Block

  5. Fill data to block of addresses
    Fill data to address block

  6. Data table to specific address
    Data table to a specific address

Channel Settings

  • consist ofbase channelcap (a poem)full-featured channel
  • Basic channels support only single or block transfers
  • FULL channel support for repeated single and repeated block transfers
  • The highest priority DMA channel (starting with DMAo) is the FULL channel; the remaining priority channels are base channels.

Transmission Mode Setting

  • single transmission
  • block transfer
  • Repeat Single Transmission (supported by full-featured channels only)
  • Repeat Block Transfer (supported on full-featured channels only)

Mode 1: Single transmission

  • Definable number of transfers
  • Can define whether two addresses are additive or subtractive
  • You can set the incremental or decremental step size.
  • There are three registers that are incremented or decremented after each transfer --> when one of these registers decrements to 0, a flag register is set. At the same time the DMA enable is cleared (even if the DMA is not working - > it needs to be set again).

Mode 2: Block Transfer

  • Define the size of the block
  • The values of three registers are stored in temporary registers, two of which are decremented or incremented after each transfer. The presence register indicates the address to the step.
  • The presence register shows the number of blocks remaining after decrementing.

Mode 3: Repeat single transmission

  • Characteristics Same as single transmission, but will always be enabled to repeat the single transmission.

Mode 4: Repeated block transfer

  • Characteristic Same block transfer, will always enable and repeat the block transfer.

Submode: stride transfer

  • Each time the pointer is not incremented by one, customize the incremental step ----> i.e., skip part of the data read or written.

Expansion modes: four

  • normal mode
  • fill mode
  • table mode

utilization

External DMA Channel

  • Trigger type selects the external DMA channel
  • Then select the trigger method
  • Select Addressing Mode

  • Source Length and Destination Length determine the number of bytes read/written by the DMA.
    -> How many bytes of data the DMA reads from the source address each time and how many bytes of data it sends to the destination address each time.
    --> The addressing mode determines whether the next read/write address is incremental/decremental/unchanging after the DMA completes each read/write operation --> This refers to block internal addressing incremental/decremental/unchanging.

  • Check Configure Transfer Size to configure the size of the data to be transferred each time (only relevant for block transfers)
    --> Distinguish between read/write size and transfer size. You can read more and write slowly.
    --> Transfer Size determines how large a block of data is transferred at a time.

  • Addressing of source and destination addresses is incremental/decremental/unchanging after each transmission is completed
  • Note: Source address --->DMA --->Destination address, in case of block transfer mode.


  • How DMA interrupts are triggered

DMA_block_transfer routine details

see note



#include "ti_msp_dl_config.h"

#define DMA_TRANSFER_SIZE_WORDS (16)

// Source data
const uint32_t gSrcData[DMA_TRANSFER_SIZE_WORDS] = {0x00000000, 0x10101010,
                                                    0x20202020, 0x30303030, 0x40404040, 0x50505050, 0x60606060, 0x7070707070,
                                                    0x80808080, 0x9090909090, 0xA0A0A0A0, 0xB0B0B0B0, 0xC0C0C0C0, 0xD0D0D0D0D0,
                                                    0xE0E0E0E0, 0xF0F0F0F0}.

//Target address
uint32_t gDstData[DMA_TRANSFER_SIZE_WORDS];; //Target address.


//DMA trigger interrupt flag
volatile bool gChannel0InterruptTaken = false;

//Verify result flag
volatile bool gVerifyResult = false;; //Verify result flag bit; //DMA trigger interrupt flag.


int main(void)
{
    SYSCFG_DL_init().

    /* Setup interrupts on device */
    DL_SYSCTL_disableSleepOnExit(); /* Setup interrupts on device */.
    NVIC_EnableIRQ(DMA_INT_IRQn);

    /* Configure DMA source, destination and size */
    // Set source address
    DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) &gSrcData[0]);
    //set destination address
    DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) &gDstData[0]);
    //set transfer size -->how many uint32 data
        DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, sizeof(gSrcData) / sizeof(uint32_t));;

    // Enable to open the DMA channel
    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);

    //Start transmission
    gChannel0InterruptTaken = false;; //start transfer.
    DL_DMA_startTransfer(DMA, DMA_CH0_CHAN_ID);

    /* Wait for block transfer to complete */
    while (gChannel0InterruptTaken == false)
    {
        __WFE();
    }

    // At this point the transfer is complete and you can verify that the data is correct
    gVerifyResult = true;
    for (int i = 0; i < DMA_TRANSFER_SIZE_WORDS; i++)
    {
        /* First compare the source and destination data to see if they are the same - > compare true or false
         /* then compare the result with gVerifyResult -->false with any value results in false
         * This is for the purpose of verifying that all values in the array are the same */.

        gVerifyResult &= gSrcData[i] == gDstData[i];
    }


    /* Completes the transfer and causes the LED to light up */
    DL_GPIO_clearPins(
        GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN);

    /* Breakpoint detection result */
    __BKPT(0);

    while (1) {
        __WFI(); }
    }
}

void DMA_IRQHandler(void)
{

    switch (DL_DMA_getPendingInterrupt(DMA))
    {
            // Determine which DMA channel is generating the interrupt
        case DL_DMA_EVENT_IIDX_DMACH0.
            gChannel0InterruptTaken = true;
            gChannel0InterruptTaken = true; break;
        break; default.
            break; default.
    }
}

DMA is used in the SPI communication previously posted, which can be found in the collection.