Welcome to MSPM0G3519 Development Board repository
9. DMA Transfer
DMA Transfer
DMA Transfer1. Learning ObjectivesDMA Principle2. Hardware Setup3. Experiment Steps1. Open SYSCONFIG Configuration Tool2. ADC Parameter Configuration3. DMA Parameter Configuration4. Write Program5. Compile4. Program Analysis5. Experimental Phenomena
1. Learning Objectives
Understand basic DMA knowledge.
Learn the basic use of DMA and display the transferred ADC data on the serial assistant.
DMA Principle
DMA (Direct Memory Access) is a technology used in computer systems that allows peripherals to directly access memory without CPU involvement to complete data transfer. It enables efficient data exchange between peripherals (such as ADC, DAC, memory, etc.) and memory, reducing CPU burden and improving overall system performance.
Principle:
Trigger Data Transfer: DMA operations are usually triggered by external devices (such as ADC, sensors) or internal events (such as timer overflow).
Initialize DMA Controller: CPU configures parameters for DMA controller including source address, destination address, transfer data size, transfer direction, etc.
Direct Data Transfer: Once the DMA controller is activated, it can directly transfer data from the source address (peripheral output buffer or memory) to the destination address (memory or peripheral) without CPU intervention.
Notify CPU After Transfer Complete: After DMA completes data transfer, it can send an interrupt request to the CPU, telling the CPU that data is ready or transfer completed successfully.
2. Hardware Setup
The DMA in these devices supports the following important features:
12 independent DMA transfer channels
12 independent DMA transfer channels
6 full-featured channels (DMA0-DMA5), supporting repeated transfer mode
6 basic channels (DMA6-DMA11), supporting single transfer mode
Configurable DMA channel priority
Byte (8-bit), short word (16-bit), word (32-bit), long word (64-bit), and ultra-long word (128-bit) or mixed byte and word transfer capability
Transfer counter block size supports transferring any type of data up to 64k
Configurable DMA transfer trigger selection
Active channel interrupt providing service for other channels
Early interrupt generation for ping-pong buffer architecture
Cascade channel when activity on another channel completes
Stride mode supporting data reorganization, such as three-phase metering applications
Collection mode

By consulting the data manual, only full-featured DMA channels support repeated transfer, early interrupt, and extended mode. Basic DMA channels support basic data transfer and interrupts, but are sufficient for simple data transfer requirements.
MSPM0G3519's DMA supports four transfer modes, each channel can be configured separately for its transfer mode. For example, channel 0 can be configured for single-word or single-byte transfer mode, channel 1 for block transfer mode, and channel 2 for repeated block transfer mode. Transfer modes are configured independently of addressing modes. Any addressing mode can be used with any transfer mode. Three types of data can be transferred, selected through .srcWidth and .destWidth control bits. Source and destination locations can be byte, short word, or word data. Transfers are also supported in byte-to-byte, short-word-to-short-word, word-to-word, or any combination. As follows:
Single-word or single-byte transfer: Each transfer requires a separate trigger. DMA is automatically disabled when DMAxSZ transfer has been generated.
Block transfer: An entire block will be transferred after one trigger. DMA is automatically disabled at the end of block transfer.
Repeated single-word or single-byte transfer: Each transfer requires a separate trigger, DMA remains enabled.
Repeated block transfer: An entire block will be transferred after one trigger, DMA remains enabled.
Based on these modes, MSPM0G3519 provides 6 addressing modes:
Fixed address to fixed address:

Fixed address to block address:

Block address to fixed address:

Block address to block address:

Fill data to block address:

Data table to specified address:

3. Experiment Steps
This case uses ADC to acquire PA27 pin voltage, and DMA transfers the ADC acquired data directly to a specified address.
1. Open SYSCONFIG Configuration Tool
This case uses the ADC Acquisition course as a template. Open the ADC project and open the .syscfg file.

2. ADC Parameter Configuration
The ADC configuration here is the same as in the ADC Acquisition case.
Configure ADC resolution and interrupts. This case does not use interrupts, so nothing is selected here.

3. DMA Parameter Configuration

Save the configuration in the .syscfg file using the shortcut key Ctrl+S.
4. Write Program
In the empty.c file, write the following code
x#include "ti_msp_dl_config.h"#include "stdio.h"
volatile uint16_t ADC_VALUE[20];//The data collected by ADC is saved in the address
unsigned int adc_getValue(unsigned int number); //Read ADC datavoid uart0_send_string(char* str); //Send string via serial port
int main(void){ char output_buff[50] = {0}; unsigned int adc_value = 0; float voltage_value = 0;
SYSCFG_DL_init();
// Set the starting address of DMA transfer DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) &ADC0->ULLMEM.MEMRES[0]); // Set the destination address of DMA transfer DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t) &ADC_VALUE[0]); // Enable DMA DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID); // Start ADC conversion DL_ADC12_startConversion(ADC_VOLTAGE_INST);
uart0_send_string("adc+dma Demo start\r\n"); while (1) { // Get ADC data adc_value = adc_getValue(10); sprintf(output_buff, "adc value:%d\r\n", adc_value); uart0_send_string(output_buff);
// Convert the data collected by ADC into voltage voltage_value = adc_value/4095.0*3.3; sprintf(output_buff, "voltage value:%.2f\r\n", voltage_value); uart0_send_string(output_buff);
delay_cycles(32000000); }}
// Read ADC dataunsigned int adc_getValue(unsigned int number){ unsigned int gAdcResult = 0; unsigned char i = 0;
// Collect multiple times and accumulate for( i = 0; i < number; i++ ) { gAdcResult += ADC_VALUE[i]; } // Mean Filter gAdcResult /= number;
return gAdcResult;}
// Send string via serial portvoid uart0_send_string(char* str){ //The current string address is not at the end and the string first address is not empty while(*str!=0&&str!=0) { // Wait when serial port 0 is busy, and send the incoming characters when it is not busy while( DL_UART_isBusy(UART_0_INST) == true ); // Send the characters in the first address of the string, and increment the first address after sending. DL_UART_Main_transmitData(UART_0_INST, *str++); }}5. Compile

Compilation was successful. You can now download the program to the development board.
4. Program Analysis
empty.c

The uart0_send_string function sends a string through UART serial port. It iterates through each character with while (*str != 0) until the string ends (*str == 0). Before sending each character, it checks if UART is busy via DL_UART_isBusy(UART_0_INST). Data can only be sent when UART is idle. It sends the current character via DL_UART_Main_transmitData(UART_0_INST, *str++) and increments str to point to the next character.

This code reads ADC (analog-to-digital converter) data. It triggers ADC conversion and waits for conversion to complete, then gets the ADC sample result and returns it.

This code's functionality is to use ADC (analog-to-digital converter) and DMA (Direct Memory Access) combined to acquire analog signals and output results through serial port. DMA transfers ADC data directly to memory without manual reading each time, and periodically outputs ADC sample values and calculated voltage values through serial port.
5. Experimental Phenomena
After the program is downloaded, after configuring the serial assistant as shown in the figure below, adjust the potentiometer knob to output voltage to the PA27 pin. After ADC collects and loads data into ADC result register 0, DMA is triggered. DMA will transfer data to the memory variable ADC_VALUE. You can get data by directly calling ADC_VALUE.
