Home › Forums › Mastering STM32 book support forum › tim3 encoder mode + dma: can't have any readdings
Tagged: dma tim encoder
- This topic has 2 replies, 2 voices, and was last updated 7 years, 9 months ago by jano.
-
AuthorPosts
-
February 23, 2017 at 10:59 am #6279janoParticipant
hi!
Programming the tim3 in encoder mode is pretty straightforward, I make a program to modify the width of the pwm of tim2 from the encoder I have plugged in tim3, everything works here.
But when I try it in dma mode I can’t make the same.
I tried several combinations of the commented lines without any interesting results, except when I try to use the polling mode and in this case the polling routine gets stuck forever in a loop (probably because inside of stm32f4xx_hal_tim.h the HAL_TIM_Encoder_Start_DMA calls to HAL_DMA_Start_IT)here is the relevant part of main.c: (why we can’t attach a .c?)
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_SPI1_Init();
MX_TIM2_Init();
MX_TIM3_Init();
MX_TIM4_Init();
MX_USART2_UART_Init();/* USER CODE BEGIN 2 */
uint32_t data = 3, data2 = 1;
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
HAL_TIM_Encoder_MspInit(&htim3);
// HAL_TIM_Base_Start(&htim3);
// HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);// __HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
HAL_TIM_Encoder_Start_DMA(&htim3, TIM_CHANNEL_ALL, (uint32_t *)data, (uint32_t *)data2, 2);/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
// HAL_DMA_Start(&hdma_tim3_ch4_up, __HAL_TIM_GET_COUNTER(&htim3), data, 2);
// HAL_DMA_PollForTransfer(&hdma_tim3_ch4_up, HAL_DMA_HALF_TRANSFER, HAL_MAX_DELAY);
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, data); //__HAL_TIM_GET_COUNTER(&htim3));/* USER CODE BEGIN 3 */
}
.
.
.
.
./* TIM3 init function */
static void MX_TIM3_Init(void)
{TIM_Encoder_InitTypeDef sConfig;
TIM_MasterConfigTypeDef sMasterConfig;htim3.Instance = TIM3;
htim3.Init.Prescaler = 0;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 10000;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
sConfig.IC1Filter = 0;
sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
sConfig.IC2Filter = 0;
if (HAL_TIM_Encoder_Init(&htim3, &sConfig) != HAL_OK)
{
Error_Handler();
}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}}
and from stm32f4xx_hal_msp.c :
void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef* htim_encoder)
{GPIO_InitTypeDef GPIO_InitStruct;
if(htim_encoder->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspInit 0 *//* USER CODE END TIM3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM3_CLK_ENABLE();/**TIM3 GPIO Configuration
PB4 ——> TIM3_CH1
PB5 ——> TIM3_CH2
*/
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);/* Peripheral DMA init*/
hdma_tim3_ch4_up.Instance = DMA1_Stream2;
hdma_tim3_ch4_up.Init.Channel = DMA_CHANNEL_5;
hdma_tim3_ch4_up.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_tim3_ch4_up.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim3_ch4_up.Init.MemInc = DMA_MINC_DISABLE;
hdma_tim3_ch4_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tim3_ch4_up.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tim3_ch4_up.Init.Mode = DMA_NORMAL;
hdma_tim3_ch4_up.Init.Priority = DMA_PRIORITY_LOW;
hdma_tim3_ch4_up.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_tim3_ch4_up) != HAL_OK)
{
Error_Handler();
}/* Several peripheral DMA handle pointers point to the same DMA handle.
Be aware that there is only one stream to perform all the requested DMAs. */
__HAL_LINKDMA(htim_encoder,hdma[TIM_DMA_ID_CC4],hdma_tim3_ch4_up);
__HAL_LINKDMA(htim_encoder,hdma[TIM_DMA_ID_UPDATE],hdma_tim3_ch4_up);/* USER CODE BEGIN TIM3_MspInit 1 */
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);/* USER CODE END TIM3_MspInit 1 */
}}
and from stm32f4xx_it.c :/**
* @brief This function handles DMA1 stream2 global interrupt.
*/
void DMA1_Stream2_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream2_IRQn 0 *//* USER CODE END DMA1_Stream2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_tim3_ch4_up);
/* USER CODE BEGIN DMA1_Stream2_IRQn 1 *//* USER CODE END DMA1_Stream2_IRQn 1 */
}Comparing this with ch9 ex2 the HAL_DMA_Start_IT is called inside the HAL_TIM_Encoder_Start_DMA, but I can’t see any place where the register TIMx DMA/Interrupt enable register (TIMx_DIER) is modified (like the huart2.Instance->CR3 |= USART_CR3_DMAT; for the UART), should I modify this register? if yes: how I can find the ‘huart.Instance’ equivalent (how this is called?)
or I’m losing something else?
Thanks.- This topic was modified 7 years, 9 months ago by jano.
February 27, 2017 at 6:59 am #6325Carmine NovielloKeymasterCan you post the whole project somewhere?
February 27, 2017 at 10:10 am #6327janoParticipanthi Carmine!
just uploaded now in https://github.com/jano2358/env_0_1
-
AuthorPosts
- You must be logged in to reply to this topic.