/* DMA Stream parameters definitions. You can modify these parameters to select a different DMA Stream and/or channel. But note that only DMA2 Streams are capable of Memory to Memory transfers. */
#define DMA_STREAM DMA2_Stream0 #define DMA_CHANNEL DMA_Channel_0 #define DMA_STREAM_CLOCK RCC_AHB1Periph_DMA2 #define DMA_STREAM_IRQ DMA2_Stream0_IRQn #define DMA_IT_TCIF DMA_IT_TCIF0 #define DMA_FLAG_TCIF DMA_FLAG_TCIF0 #define DAM_STREAM_IRQHANDLER DMA2_Stream0_IRQHandler
#define BUFFER_SIZE 32 #define TIMEOUT_MAX 10000 /* Maximum timeout value */ // const uint32_t SRC_Const_Buffer[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 }; // uint32_t DST_Buffer[BUFFER_SIZE];
/* Private typedef ---------------------------------------------*/ typedef enum { FAILED = 0, PASSED = !FAILED } TestStatus; /* Private variables --------------------------------------------*/ __IO TestStatus TransferStatus = FAILED;
/** * @brief Compares two buffers. * @param pBuffer, pBuffer1: buffers to be compared. * @param BufferLength: buffer's length * @retval PASSED: pBuffer identical to pBuffer1 * FAILED: pBuffer differs from pBuffer1 */ TestStatus Buffercmp(const uint32_t* pBuffer, uint32_t* pBuffer1, uint16_t BufferLength) { while (BufferLength--) { if (*pBuffer != *pBuffer1) { return FAILED; } pBuffer++; pBuffer1++; } return PASSED; }
/** * @brief Configure the DMA controller according to the Stream parameters * defined in main.h file * @param None * @retval None */
void DMA_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; DMA_InitTypeDef DMA_InitStructure; __IO uint32_t Timeout = TIMEOUT_MAX;
/* Enable DMA clock */ RCC_AHB1PeriphClockCmd(DMA_STREAM_CLOCK, ENABLE);
/* Reset DMA Stream registers (for debug purpose) */ DMA_DeInit(DMA2_Stream0);
/* Check if the DMA Stream is disabled before enabling it. Note that this step is useful when the same Stream is used multiple times: enabled, then disabled then re-enabled... In this case, the DMA Stream disable will be effective only at the end of the ongoing data transfer and it will not be possible to re-configure it before making sure that the Enable bit has been cleared by hardware. If the Stream is used only once, this step might be bypassed. */ while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE) { }
/* Configure DMA Stream */ DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SRC_Const_Buffer; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)DST_Buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; DMA_InitStructure.DMA_BufferSize = (uint32_t)BUFFER_SIZE; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure);
/* Enable DMA Stream Transfer Complete interrupt */ DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
/* DMA Stream enable */ DMA_Cmd(DMA2_Stream0, ENABLE);
/* Check if the DMA Stream has been effectively enabled. The DMA Stream Enable bit is cleared immediately by hardware if there is an error in the configuration parameters and the transfer is no started (ie. When wrong FIFO threshold is configured ...) */ Timeout = TIMEOUT_MAX; while ((DMA_GetCmdStatus(DMA2_Stream0) != ENABLE) && (Timeout--> 0)) { } /* Check if a timeout condition occurred */ if (Timeout == 0) { /* Manage the error: to simplify the code enter an infinite loop */ while (1) { } } /* Enable the DMA Stream IRQ Channel */ NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } // volatile uint8_t i; // void DMA2_Stream0_IRQHandler(void) { /* Test on DMA Stream Transfer Complete interrupt */ if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) { /* Clear DMA Stream Transfer Complete interrupt pending bit */ DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); i = 1; } }
/*---------------------START OF BOOT---------------------------------*/ int main(void) { //First of all, we need to setup proper interrupt priority NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //Only preemption priority //group (4 bits) uint32_t counter=0; while (1) { counter++; /* Configure and enable the DMA Stream for Memory to Memory transfer */ i = 0; DMA_Config(); /* Wait the end of transmission (the DMA Stream is disabled by Hardware at the end of the transfer) . There is also another way to check on end of transfer by monitoring the number of remaining data to be transferred. */ // while (DMA_GetCurrentMemoryTarget(DMA_STREAM) != 0) *//* First method */\
while (DMA_GetCmdStatus(DMA2_Stream0) != DISABLE) /* Second method */ { /* Since this code present a simple example of how to use DMA, it is just waiting on the end of transfer. But, while DMA Stream is transferring data, the CPU is free to perform other tasks in parallel to the DMA transfer. */ } // /*Check if the transmitted and received data are equal */ TransferStatus = Buffercmp(SRC_Const_Buffer, DST_Buffer, BUFFER_SIZE); /*TransferStatus = PASSED, if the transmitted and received data are the same */ /*TransferStatus = FAILED, if the transmitted and received data are different */
if (TransferStatus != PASSED) { /* Turn LED4 on: Transfer correct */ while (1) ; } } while (1) ; }