2022-12-07 04:38 AM
Looking at this post
It does indeed look like the PWM pulse callback is used rather than the HAL_DMA_XFER_CPLT_CB_ID Calllback
I have set up DMA to transfer to PWM. It is a circular buffer so I am just changing the pointer "audio_channel[AY_CHAN].ptr" reference in the call-back.
I wish to update the DMA values after the sequence is completed (length of "AUDIO_CHUNKS") - (moving the pointer )
The PWM event fires as expected but the DMA Call-back is not firing. It also seems that the PWM call-back fires after the DMA streams completed - in "static void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma)" there is only a callback to htim->PWM_PulseFinishedCallback(htim); So that seems to reflect what I'm seeing. Does this make the DMA call-back redundant? In addition it seems that HAL_TIM_PWM_PULSE_FINISHED_CB_ID fires after the last PWM value is written. Is this correct?
In addition how does the "tim5.Init.RepetitionCounter" affect both the PWM and DMA callbacks?
All the flags have been set in "stm32h7xx_hal_conf.h"
..
void PWM_PulseFinishedCallback() //Works
{
audio_channel[AY_CHAN].ptr = *(audio->buff + audio->ptr_cnt);
audio_channel[AY_CHAN].ptrptr_cnt += AUDIO_CHUNKS;
}
void DMA_AudioCallback //Not Working
{
audio_channel[AY_CHAN].ptr = *(audio->buff + audio->ptr_cnt);
audio_channel[AY_CHAN].ptrptr_cnt += AUDIO_CHUNKS;
}
void start_audio()
{
HAL_TIM_RegisterCallback(&htim5, HAL_TIM_PWM_PULSE_FINISHED_CB_ID, &PWM_PulseFinishedCallback);
HAL_DMA_RegisterCallback(&hdma_tim5_ch1, HAL_DMA_XFER_CPLT_CB_ID, &DMA_Callback);.
HAL_TIM_PWM_Start_DMA(&htim5, TIM_CHANNEL_1, (uint32_t*) &audio_channel[AY_CHAN].ptr, AUDIO_CHUNKS);
//__HAL_DMA_ENABLE_IT(&hdma_tim5_ch1, DMA_IT_TC); // Is this wrong?
//HAL_TIM_Base_Start(&htim5); //Not needed
}
void MX_TIM5_Init(void)
{
/* USER CODE BEGIN TIM5_Init 0 */
/* USER CODE END TIM5_Init 0 */
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
/* USER CODE BEGIN TIM5_Init 1 */
/* USER CODE END TIM5_Init 1 */
htim5.Instance = TIM5;
htim5.Init.Prescaler = AUDIO_PRESCALER;
htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
htim5.Init.Period = AUDIO_PERIOD;
htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
// htim5.Init.RepetitionCounter = AUDIO_CHUNKS ; ? Is this required?
if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Init(&htim5) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
//sConfigOC.Pulse= FRAME_SIZE;
sConfigOC.OCMode = TIM_OCMODE_PWM2;
sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_SET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_SET;
if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM5_Init 2 */
/* USER CODE END TIM5_Init 2 */
HAL_TIM_MspPostInit(&htim5);
}
...
if(tim_baseHandle->Instance==TIM5)
{
/* USER CODE BEGIN TIM5_MspInit 0 */
/* USER CODE END TIM5_MspInit 0 */
/* TIM5 clock enable */
__HAL_RCC_TIM5_CLK_ENABLE();
/* TIM5 DMA Init */
/* TIM5_CH1 Init */
hdma_tim5_ch1.Instance = DMA1_Stream1;
hdma_tim5_ch1.Init.Request = DMA_REQUEST_TIM5_CH1;
hdma_tim5_ch1.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tim5_ch1.Init.PeriphInc = DMA_PINC_ENABLE;
hdma_tim5_ch1.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim5_ch1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim5_ch1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_tim5_ch1.Init.Mode = DMA_CIRCULAR;
hdma_tim5_ch1.Init.Priority = DMA_PRIORITY_HIGH;
hdma_tim5_ch1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_tim5_ch1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(tim_baseHandle,hdma[TIM_DMA_ID_CC1],hdma_tim5_ch1);
/* TIM5 interrupt Init */
HAL_NVIC_SetPriority(TIM5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM5_IRQn);
/* USER CODE BEGIN TIM5_MspInit 1 */
/* USER CODE END TIM5_MspInit 1 */
}
..void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}