AnsweredAssumed Answered

STM32F407 DMA

Question asked by AlexSmart on Dec 27, 2012
Hello! Currently having trouble with DMA on STM32F407. Memory to Peripheral mode (from location in flash memory to GPIO), triggered by Timer. Trigger condition is occurs (timer interrupt), but DMA transaction is not occurs...

Source code:

#include "stm32f4xx.h"
#include "main.h"

#define F_TMR_INT                            (1000)
#define VIDEO_BUF_LINE_SIZE                    4
#define VIDEO_BUF_LINE_NUM                    4
#define DMA_VIDEO_DATA_STREAM                DMA1_Stream0
#define DMA_VIDEO_DATA_CHANNEL                 DMA_Channel_6
#define DMA_VIDEO_DATA_STREAM_CLOCK         RCC_AHB1Periph_DMA1
#define DMA_VIDEO_DATA_STREAM_IRQ           DMA1_Stream0_IRQn
#define DMA_VIDEO_DATA_IT_TCIF              DMA_IT_TCIF0
#define DAM_VIDEO_DATA_STREAM_IRQHANDLER    DMA1_Stream0_IRQHandler

DMA_InitTypeDef DMA_Video_Data_InitStructure;

unsigned char     Video_Buffer[VIDEO_BUF_LINE_NUM][VIDEO_BUF_LINE_SIZE] =
{
    {0x55,0xAA,0x55,0xAA},
    {0x01,0x02,0x01,0x02},
    {0x10,0x20,0x10,0x20},
    {0x40,0x04,0x40,0x04}
};
int main(void)
{            
    RCC_Configuration();
    GPIO_Configuration();
    DMA_Configuration();
    TMR_Configuration();
    NVIC_Configuration();
    
    DMA_Cmd(DMA_VIDEO_DATA_STREAM, ENABLE);
    TIM_Cmd(TIM5, ENABLE);

    while (1);
}
void RCC_Configuration(void)
{
    RCC_PCLK1Config(RCC_HCLK_Div1);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,     ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,     ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,     ENABLE);
}
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin         = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3 | GPIO_Pin_2 | GPIO_Pin_1 | GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable the TIM2 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel                         = TIM5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority     = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority             = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                    = ENABLE;
    
    NVIC_Init(&NVIC_InitStructure);
    
    NVIC_InitStructure.NVIC_IRQChannel                         = DMA_VIDEO_DATA_STREAM_IRQ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority     = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority             = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                     = ENABLE;
    
    NVIC_Init(&NVIC_InitStructure);   
}
void TMR_Configuration(void)
{
    TIM_TimeBaseInitTypeDef                      TIM_TimeBaseStructure;

    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period             = SystemCoreClock/F_TMR_INT-1;
    TIM_TimeBaseStructure.TIM_Prescaler         = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision     = 0;
    TIM_TimeBaseStructure.TIM_CounterMode         = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);

    TIM_DMACmd (TIM5, TIM_DMA_Update, ENABLE);
    TIM_PrescalerConfig(TIM5, 0x0000, TIM_PSCReloadMode_Immediate);
    TIM_ITConfig(TIM5, TIM_IT_Update, ENABLE);
}
    
void DMA_Configuration(void)
{
    DMA_DeInit(DMA_VIDEO_DATA_STREAM);
    while (DMA_GetCmdStatus(DMA_VIDEO_DATA_STREAM) != DISABLE)
    {
    }
    DMA_Video_Data_InitStructure.DMA_Channel                 = DMA_VIDEO_DATA_CHANNEL;  
    DMA_Video_Data_InitStructure.DMA_PeripheralBaseAddr     = (uint32_t)&(GPIOA->ODR);
    DMA_Video_Data_InitStructure.DMA_Memory0BaseAddr         = (uint32_t)Video_Buffer;
    DMA_Video_Data_InitStructure.DMA_DIR                     = DMA_DIR_MemoryToPeripheral;
    DMA_Video_Data_InitStructure.DMA_BufferSize             = (uint32_t)VIDEO_BUF_LINE_SIZE;
    DMA_Video_Data_InitStructure.DMA_PeripheralInc             = DMA_PeripheralInc_Disable;
    DMA_Video_Data_InitStructure.DMA_MemoryInc                 = DMA_MemoryInc_Enable;
    DMA_Video_Data_InitStructure.DMA_PeripheralDataSize     = DMA_PeripheralDataSize_HalfWord;
    DMA_Video_Data_InitStructure.DMA_MemoryDataSize         = DMA_MemoryDataSize_Byte;
    DMA_Video_Data_InitStructure.DMA_Mode                     = DMA_Mode_Circular;
    DMA_Video_Data_InitStructure.DMA_Priority                 = DMA_Priority_VeryHigh;
    DMA_Video_Data_InitStructure.DMA_FIFOMode                 = DMA_FIFOMode_Enable;         
    DMA_Video_Data_InitStructure.DMA_FIFOThreshold             = DMA_FIFOThreshold_Full;
    DMA_Video_Data_InitStructure.DMA_MemoryBurst             = DMA_MemoryBurst_Single;
    DMA_Video_Data_InitStructure.DMA_PeripheralBurst         = DMA_PeripheralBurst_Single;
    DMA_Init(DMA_VIDEO_DATA_STREAM, &DMA_Video_Data_InitStructure);
    
    /* Enable DMA Stream Transfer Complete interrupt */
    DMA_ITConfig(DMA_VIDEO_DATA_STREAM, DMA_IT_TC, ENABLE);
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 
  /* Infinite loop */
  while (1)
  {
  }
}
#endif


UPD:
On first timer interrupt (DMA trigger) NDTR register decrements and in LISR register is set to 0x00000009 (FIFO error and transfer error)...

Outcomes