cancel
Showing results for 
Search instead for 
Did you mean: 

STM32f446RE Timer6 DMA problem

n.serina
Associate III
Posted on April 13, 2017 at 18:08

Hello All, 

I have some serious issue which i am not able to figure it out, i really dont know what i am missing, 

basically what i am doing is simple, 

i m using TIM6 (BASIC TIMER) dma to toggle the led. 

The problem is , the moment i trigger the dma it goes to 'Transfer Error' block of the DMA isr, 

i have no clue why this is happening , below is my code, i must be doing something silly, but i spent 2 days , i have no clue 

&sharpinclude<stdio.h>

&sharpinclude 'stm32f446xx.h'

/* Private variables ---------------------------------------------------------*/

TIM_HandleTypeDef htim6;

DMA_HandleTypeDef hdma_tim6_up;

uint8_t data[2]={0xff,0x00};

/* Private function prototypes -----------------------------------------------*/

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_TIM6_Init(void);

static void MX_DMA_init(void);

int main()

{

SystemClock_Config();

MX_GPIO_Init();

MX_TIM6_Init();

/* DMA controller clock enable */

__HAL_RCC_DMA1_CLK_ENABLE();

/* DMA interrupt init */

/* DMA1_Stream1_IRQn interrupt configuration */

HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);

MX_DMA_init();

__HAL_TIM_ENABLE_DMA(&htim6, TIM_DMA_UPDATE);

HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);

HAL_DMA_Start_IT(htim6.hdma[TIM_DMA_ID_UPDATE], (uint32_t)&data, (uint32_t)&GPIOA->ODR, 2);

HAL_TIM_Base_Start(&htim6); //trigger the timer.

while(1);

}

void MX_DMA_init(void)

{

/* Peripheral DMA init*/

hdma_tim6_up.Instance = DMA1_Stream1;

hdma_tim6_up.Init.Channel = DMA_CHANNEL_7;

hdma_tim6_up.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_tim6_up.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_tim6_up.Init.MemInc = DMA_MINC_ENABLE;

hdma_tim6_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_tim6_up.Init.MemDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_tim6_up.Init.Mode = DMA_CIRCULAR;

hdma_tim6_up.Init.Priority = DMA_PRIORITY_HIGH;

hdma_tim6_up.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

if (HAL_DMA_Init(&hdma_tim6_up) != HAL_OK)

{

while(1);

}

__HAL_LINKDMA(&htim6,hdma[TIM_DMA_ID_UPDATE],hdma_tim6_up);

}

/** System Clock Configuration

*/

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

/**Configure the main internal regulator output voltage

*/

__HAL_RCC_PWR_CLK_ENABLE();

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);

/**Initializes the CPU, AHB and APB busses clocks

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = 16;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

RCC_OscInitStruct.PLL.PLLM = 8;

RCC_OscInitStruct.PLL.PLLN = 96;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 2;

RCC_OscInitStruct.PLL.PLLR = 2;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

while(1);

}

/**Initializes the CPU, AHB and APB busses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)

{

while(1);

}

}

/* TIM6 init function */

static void MX_TIM6_Init(void)

{

TIM_MasterConfigTypeDef sMasterConfig;

__HAL_RCC_TIM6_CLK_ENABLE();

htim6.Instance = TIM6;

htim6.Init.Prescaler = 47999;

htim6.Init.CounterMode = TIM_COUNTERMODE_UP;

htim6.Init.Period = 500;

if (HAL_TIM_Base_Init(&htim6) != HAL_OK)

{

while(1);

}

&sharpif 1

sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)

{

while(1);

}

&sharpendif

}

/** Configure pins as

* Analog

* Input

* Output

* EVENT_OUT

* EXTI

PA2 ------> USART2_TX

PA3 ------> USART2_RX

*/

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOH_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

/*Configure GPIO pin : LD2_Pin */

GPIO_InitStruct.Pin = GPIO_PIN_5;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

/**

* @brief This function handles TIM6 global interrupt and DAC1, DAC2 underrun error interrupts.

*/

void TIM6_DAC_IRQHandler(void)

{

/* USER CODE BEGIN TIM6_DAC_IRQn 0 */

/* USER CODE END TIM6_DAC_IRQn 0 */

HAL_TIM_IRQHandler(&htim6);

/* USER CODE BEGIN TIM6_DAC_IRQn 1 */

/* USER CODE END TIM6_DAC_IRQn 1 */

}

/**

* @brief This function handles DMA1 stream1 global interrupt.

*/

void DMA1_Stream1_IRQHandler(void)

{

/* USER CODE BEGIN DMA1_Stream1_IRQn 0 */

/* USER CODE END DMA1_Stream1_IRQn 0 */

HAL_DMA_IRQHandler(&hdma_tim6_up);

/* USER CODE BEGIN DMA1_Stream1_IRQn 1 */

/* USER CODE END DMA1_Stream1_IRQn 1 */

}

#smt32f4-cubemx #dma-stm32
2 REPLIES 2
Posted on April 13, 2017 at 18:38

You'd need to use DMA2 and a timer on APB2 for your copy from memory to memory to succeed.

GPIOA->ODR is classed as a memory transaction as it is on the AHB, not APB1 or APB2

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on April 14, 2017 at 02:24

Many Thanks

turvey.clive

‌ , somehow i ignored this, i am going to try this today . Thanks again.