Let's update the last example adding DMA interruption. We are going to use the same buffers and DMA configuration, to configure the interrupt we use NVIC function to enable interruption of DMA1_Channel1_IRQn
, using function HAL_DMA_RegisterCallback()
, the user must register a function callback and the DMA Callback ID that define when the interrupt is triggered, this is a parameter of enum HAL_DMA_CallbackIDTypeDef
.
#include "bsp.h"
#include <stdio.h>
extern void initialise_monitor_handles(void);
#define BUFFER_SIZE 32
/*flag to indicate interrupt of DMA*/
uint32_t Flag;
/*handler of DMA*/
DMA_HandleTypeDef DMAHandler;
/*this variable stored in RAM will be used as detinations*/
static uint32_t Buffer[BUFFER_SIZE];
/*this variable stored in FLASH will be used as source*/
static const uint32_t DataSource[BUFFER_SIZE] =
{
0x01020304, 0x05060708, 0x090A0B0C, 0x0D0E0F10,
0x11121314, 0x15161718, 0x191A1B1C, 0x1D1E1F20,
0x21222324, 0x25262728, 0x292A2B2C, 0x2D2E2F30,
0x31323334, 0x35363738, 0x393A3B3C, 0x3D3E3F40,
0x41424344, 0x45464748, 0x494A4B4C, 0x4D4E4F50,
0x51525354, 0x55565758, 0x595A5B5C, 0x5D5E5F60,
0x61626364, 0x65666768, 0x696A6B6C, 0x6D6E6F70,
0x71727374, 0x75767778, 0x797A7B7C, 0x7D7E7F80
};
void TransferCallback(DMA_HandleTypeDef *hdma);
int main(void)
{
/*Initialize HAL library*/
HAL_Init();
/*Activation of semihosting*/
initialise_monitor_handles();
printf("Hola semihosting\n\r");
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* Configure DMA request hdma_memtomem_dma1_channel1 on DMA1_Channel1 */
DMAHandler.Instance = DMA1_Channel1; /*DMA1 channel 1*/
DMAHandler.Init.Request = DMA_REQUEST_MEM2MEM; /*memory to memory transfer*/
DMAHandler.Init.Direction = DMA_MEMORY_TO_MEMORY; /*memory to memory transfer direction (flash to ram)*/
DMAHandler.Init.PeriphInc = DMA_PINC_ENABLE; /*increment source address (flash memory)*/
DMAHandler.Init.MemInc = DMA_MINC_ENABLE; /*increment destination address (ram memory)*/
DMAHandler.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; /*source transfers (flash) is peroformed in 32 bits values*/
DMAHandler.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; /*destination transfers (ram) will be performed in 32 bits values*/
DMAHandler.Init.Mode = DMA_NORMAL; /*Single transfer mode*/
DMAHandler.Init.Priority = DMA_PRIORITY_LOW; /*transfer in low priority*/
HAL_DMA_Init( &DMAHandler );
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority( DMA1_Channel1_IRQn, 2, 0 );
HAL_NVIC_EnableIRQ( DMA1_Channel1_IRQn );
/*Register of the callback function to call on interrupt and indicate the activation of IT when the transfer is complete*/
HAL_DMA_RegisterCallback( &DMAHandler, HAL_DMA_XFER_CPLT_CB_ID, TransferCallback );
/*Init the transfer*/
HAL_DMA_Start_IT( &DMAHandler, (uint32_t)&DataSource, (uint32_t)&Buffer, BUFFER_SIZE );
while(1)
{
/*Ask if transfer is done*/
if(Flag == 1u)
{
Flag = 0u;
printf("-------Buffer Content-------------\r\n");
for(uint32_t i=0 ; i<BUFFER_SIZE/4u ;i++)
{
printf("0x%08lX, 0x%08lX, 0x%08lX, 0x%08lX\n\r", Buffer[(i*4)+0u], Buffer[(i*4)+1u], Buffer[(i*4)+2u], Buffer[(i*4)+3u]);
}
}
}
}
/*Program will call this function from DMA interrupt*/
void TransferCallback(DMA_HandleTypeDef *hdma)
{
Flag = 1u;
}
ints.c
extern DMA_HandleTypeDef DMAHandler;
void DMA1_Channel1_IRQHandler(void)
{
HAL_DMA_IRQHandler( &DMAHandler );
}