This code example demonstrates the transmission of data from memory to memory by Memory DMA (M-DMA), shows its operation, initial setting, and interrupt handling.
The device used in this code example (CE) is:
The board used for testing is:
- TRAVEO™ T2G Cluster 6M Lite Kit (KIT_T2G_C-2D-6M_LITE)
This code example demonstrates the transmission of data from Code Flash to SRAM by M-DMA. M-DMA transfer is initiated using software triggers.
M-DMA
The TRAVEO™ T2G device supports two kinds of DMA controllers: Peripheral DMA (P-DMA) and Memory DMA (M-DMA). The main difference between the M-DMA and P-DMA controllers is that the M-DMA controller has dedicated channel logic (with channel state) for each channel, whereas the P-DMA reuses the channel logic for all channels. The M-DMA controller is used to transfer data between memory and memory without CPU involvement. The following shows the functionality of M-DMA.
- Focuses on achieving high memory bandwidth for a small number of channels.
- Focuses on memory-to-memory data transfers (but it can also perform peripheral-to-memory and memory-to-peripheral data transfers).
- Uses a dedicated data transfer engine for each channel.
- A descriptor specifies the following data transfer specifications:
- The source and destination address locations and the size of the transfer.
- The actions of a channel; for example, generation of output triggers and interrupts.
- Data transfer types can be single, 1D, or 2D as defined in the descriptor structure. These types essentially define the address sequences generated for source and destination. 1D and 2D transfers are used for “scatter gather” and other useful transfer operations.
More details can be found in:
- TRAVEO™ T2G CYT4DN
This CE has been developed for:
- TRAVEO™ T2G Cluster 6M Lite Kit (KIT_T2G_C-2D-6M_LITE)
Figure 1. KIT_T2G_C-2D-6M_LITE (Top View)
This design consists of M-DMA and a user button. The M-DMA is designed to initiate transfers by software triggers. Pressing the User Button1 generates an interrupt. When interrupt occurs, M-DMA transfer is triggered by software. Then, M-DMA transfers 36 bytes data from a specified source address (Code Flash) to a destination address (SRAM). M-DMA will generate an interrupt when the transfer is complete.
STDOUT setting
Initialization of the GPIO for UART is done in the cy_retarget_io_init() function.
- Initialize the pin specified by CYBSP_DEBUG_UART_TX as UART TX, the pin specified by CYBSP_DEBUG_UART_RX as UART RX (these pins are connected to KitProg3 COM port)
- The serial port parameters become to 8N1 and 115200 baud
GPIO port pin initialization
Initialization of the GPIO port pin is done once in the Cy_GPIO_Pin_Init() function.
- Initialize the pin specified by User Button1 as input
Configuration of the GPIO interrupt is done once.
- Register a interrupt handler for User Button1 by Cy_SysInt_Init() function.
M-DMA initialization
The M-DMA initialization is done in following steps.
-
To disable M-DMA and channel, Cy_DMAC_Disable() and Cy_DMAC_Channel_DeInit() is called.
-
Source and destination addresses are specified the DMAC_Descriptor_0_config.srcAddress and DMAC_Descriptor_0_config.dstAddress.
-
To initialize DMA Descriptor, Cy_DMAC_Descriptor_Init() is called with using structure cy_stc_dmac_descriptor_config_t and cy_stc_dmac_descriptor_t which are auto-coded by Device Configurator as argument.
-
To initialize DMA channel, Cy_DMAC_Channel_Init() is called with using structure cy_stc_dmac_channel_config_t which are auto-coded by Device Configurator as argument.
Note: This code example needs to set the source and destination address. Therefore, the Store Config in Flash
checkbox in Advanced
does not set.
Configuration of the M-DMA interrupt is done once.
-
To set a priority for the M-DMA channel, Cy_DMAC_Channel_SetPriority() is called, and interrupt is enabled by Cy_DMAC_Channel_SetInterruptMask().
-
To enable the M-DMA, Cy_DMAC_Enable() is called.
-
Next, register a handler for M-DMA channel by Cy_SysInt_Init().
-
Last, NVIC_EnableIRQ() is called to enable IRQ.
M-DMA Transfer
-
When pressing the user button is detected, the HandleGPIOIntr() is called and set the g_isInterrupt.
-
When set the g_isInterrupt, Cy_DMAC_Channel_SetDescriptor() is called with using structure cy_stc_dmac_descriptor_t which are auto-coded by Device Configurator as argument to sets a descriptor as current for the specified M-DMA channel.
-
Then, M-DMA channel is enabled by Cy_DMAC_Channel_Enable(), and initiate M-DMA transfer by Cy_TrigMux_SwTrigger().
-
The HandleDMACIntr() is called by DMA transfer completion, and set the g_isComplete.
-
When the g_isComplete is set, memcmp() is called to check if the source data and destination data match.
ISR of DMA transfer completion
The ISR funtion for DMA transfer completion is HandleDMACIntr().
-
At first, checking if the intended interrupt has occurred by Cy_DMAC_Channel_GetInterruptStatusMasked() before start ISR proces.
-
Then, set the g_isComplete after clearing the interrupt by Cy_DMAC_Channel_ClearInterrupt().
Before testing this code example:
- Power the board through the dedicated power connector
- Connect the board to the PC through the USB interface
- Build the project using the dedicated Build button
or by right-clicking the project name and selecting "Build Project"
- To program the board, in the Quick Panel, scroll down, and click [Project Name] Program (KitProg3_MiniProg4)
For this example, a terminal emulator is required for displaying outputs. Install a terminal emulator if you do not have one. Instructions in this document use Tera Term.
After code compilation, perform the following steps to flashing the device:
- Connect the board to your PC using the provided USB cable through the KitProg3 USB connector.
- Open a terminal program and select the KitProg3 COM port. Set the serial port parameters to 8N1 and 115200 baud.
- Program the board using one of the following:
- Select the code example project in the Project Explorer.
- In the Quick Panel, scroll down, and click [Project Name] Program (KitProg3_MiniProg4).
- After programming, the code example starts automatically. Confirm that the messages are displayed on the UART terminal.
Figure 3. Terminal output on program startup
Figure 4. Print out the result
- You also can debug the example to step through the code. In the IDE, use the [Project Name] Debug (KitProg3_MiniProg4) configuration in the Quick Panel. For details, see the "Program and debug" section in the Eclipse IDE for ModusToolbox™ software user guide.
Note: (Only while debugging) On the CM7 CPU, some code in main() may execute before the debugger halts at the beginning of main(). This means that some code executes twice: once before the debugger stops execution, and again after the debugger resets the program counter to the beginning of main(). See KBA231071 to learn about this and for the workaround.
Relevant Application notes are:
- AN235305 - Getting started with TRAVEO™ T2G family MCUs in ModusToolbox™
- AN220191 - How To Use Direct Memory Access (DMA) Controller In TRAVEO™ T2G FAMILY
- AN219842 - How to use interrupt in TRAVEO™ II
ModusToolbox™ is available online:
Associated TRAVEO™ T2G MCUs can be found on:
More code examples can be found on the GIT repository:
For additional trainings, visit our webpage:
For questions and support, use the TRAVEO™ T2G Forum: