cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with the implementation of an interface using the timer and DMA

nikoradist
Associate
Posted on May 31, 2015 at 17:32

Hello!

I am developing an interface for touch panel control light (RGB leds). I configured the timer 3, DMA, and the correct port. The logical zero and one coded pulse width. Request update DMA is not working. On the other hand DMA request CC1 works great. I understand that the update event happens once in the timer period. Why update event to the DMA event does not reach? My mcu is stm32f051k8u6. Could anybody help me with this?

uint16_t const buffersize = 8;
static __IO uint16_t LED_BYTE_Buffer[9];
/**
* @}
*/ 
/**
* @brief Initializes interface.
* @param None 
* @retval None
*/
void Init2WireInterface(void)
{
RCC_Configuration();
Interface_GPIOInit();
Timer3_Init();
InitDMA();
}
/**
* @brief Transmit 9 Bit.
* @param IntensityColor, 
* 
@arg Intensity
@arg Color
* coordinate.
* @retval None
*/
void Transmit9Bit(IntensityColor_TypeDef IntensityColor, uint16_t coordinate)
{
while (memaddr <= buffersize)
{
if ( (coordinate<<
memaddr
) & 0x80 )
{
LED_BYTE_Buffer[memaddr] = 96-1; // compare value for logical 1
}
else
{
LED_BYTE_Buffer[memaddr] = 48-1; // compare value for logical 0
}
memaddr++;
}
//TIM_GenerateEvent(TIM3, TIM_EventSource_Update);
TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE);
DMA_SetCurrDataCounter(DMA1_Channel4, buffersize); // load number of bytes to be transferred
DMA_Cmd(DMA1_Channel4, ENABLE); // enable DMA channel 4
TIM_Cmd(TIM3, ENABLE); // enable Timer 3
//TIM_CtrlPWMOutputs(TIM3, ENABLE);
while(!DMA_GetFlagStatus(DMA1_FLAG_TC4)); // wait until transfer complete
TIM_Cmd(TIM3, DISABLE); // disable Timer 3
TIM_DMACmd(TIM3, TIM_DMA_Update, DISABLE);
DMA_Cmd(DMA1_Channel4, DISABLE); // disable DMA channel 4
DMA_ClearFlag(DMA1_FLAG_TC4); // clear DMA1 Channel 4 transfer complete flag
}
/**
* @brief Enables the AHB peripheral clock.
* @param None 
* @retval None
*/
static void RCC_Configuration(void)
{
/* Enable the GPIO_Interface Clock */
RCC_AHBPeriphClockCmd(DATA_GPIO_CLK, ENABLE);
/* Enable the TIM3_Interface Clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Enable the DMA_Interface Clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}
/**
* @brief Initializes the GPIOx peripheral.
* @param None 
* @retval None
*/
static void Interface_GPIOInit(void) 
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure the GPIO_Interface pin */
GPIO_PinAFConfig(DATA_GPIO_PORT, GPIO_PinSource4, GPIO_AF_1);
GPIO_InitStructure.GPIO_Pin
= 
DATA_PIN
;
GPIO_InitStructure.GPIO_Mode
= 
GPIO_Mode_AF
;
GPIO_InitStructure.GPIO_OType
= 
GPIO_OType_PP
;
GPIO_InitStructure.GPIO_PuPd
= 
GPIO_PuPd_NOPULL
;
GPIO_InitStructure.GPIO_Speed
= 
GPIO_Speed_50MHz
;
GPIO_Init(DATA_GPIO_PORT, &GPIO_InitStructure);
}
/**
* @brief Initializes the TIM3 peripheral.
* @param None 
* @retval None
*/
static void Timer3_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period
= 
192
-1;
TIM_TimeBaseStructure.TIM_Prescaler
= 
1
;
TIM_TimeBaseStructure.TIM_ClockDivision
= 
TIM_CKD_DIV1
;
TIM_TimeBaseStructure.TIM_CounterMode
= 
TIM_CounterMode_Up
;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode
= 
TIM_OCMode_PWM1
;
TIM_OCInitStructure.TIM_OutputState
= 
TIM_OutputState_Enable
;
TIM_OCInitStructure.TIM_Pulse
= 
50
;
TIM_OCInitStructure.TIM_OCPolarity
= 
TIM_OCPolarity_Low
;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
} 
/**
* @brief Initializes the DMA Channel4.
* @param None 
* @retval None
*/
static void InitDMA(void)
{
/* DMA1 Channel4 Config */
DMA_DeInit(DMA1_Channel4);
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TIM3->CCR1); // physical address of Timer 3 CCR1
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&(LED_BYTE_Buffer[0]); // this is the buffer memory 
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // data shifted from memory to peripheral
DMA_InitStructure.DMA_BufferSize = buffersize;;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // automatically increase buffer index
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // stop DMA feed after buffer size is reached
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
/* TIM3 Update DMA Request enable */
TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE);
}
/**
* @}
*/
/*****END OF FILE****/

#timer #timer #dma #dma #stm32f0 #stm32f0
2 REPLIES 2
Posted on May 31, 2015 at 18:06

Not sure I understand the failure mode you're trying to describe.

Are you able to see the PWM signal on the pin? Which pin specifically? Your code lacks defines.

Are you able to modulate the PWM with the DMA buffer?

You probably need to initialize memaddr to zero. Nine or Eight bits?

Is it stuck in the DMA TC while() loop?

Do you need to turn this on/off, or can you send a continuously modulated stream of bits?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
nikoradist
Associate
Posted on June 01, 2015 at 12:07

>Are you able to see the PWM signal on the pin? Which pin specifically? Your code lacks defines.

>Are you able to modulate the PWM with the DMA buffer? >Is it stuck in the DMA TC while() loop? Here my defines: #define DATA_PIN GPIO_Pin_4 #define DATA_GPIO_PORT GPIOB #define DATA_GPIO_CLK RCC_AHBENR_GPIOBEN When I set request event CC1 I see PWM (attached pictures). I modulate PWM form DMA buffer, but I have one troble with this (see marked osciloscope diagram). Timer get 2 pulses for one period and two signals is sticking (I think that happen 'couse I set CC1). I want to initialize request event update but then I lacks in while() loop. while(!DMA_GetFlagStatus(DMA1_FLAG_TC4)); I >You probably need to initialize memaddr to zero. Nine or Eight bits? Yes, I set 8 bits to zero. >Do you need to turn this on/off, or can you send a continuously modulated stream of bits? If you call Transmit9Bit() it send 8 bit (pay no attention to the function name).

#include ''2WireInterface.h''
#define buffersize 8 
/** @defgroup 2WireInterface_Private_Variables
* @{
*/ 
static __IO uint16_t LED_BYTE_Buffer[buffersize+1];
/**
* @}
*/ 
/**
* @brief Initializes interface.
* @param None 
* @retval None
*/
void Init2WireInterface(void)
{
RCC_Configuration();
Interface_GPIOInit();
Timer3_Init();
InitDMA();
}
/**
* @brief Transmit 9 Bit.
* @param IntensityColor, 
* 
@arg Intensity
@arg Color
* coordinate.
* @retval None
*/
void Transmit9Bit(IntensityColor_TypeDef IntensityColor, uint8_t coordinate)
{
/*coordinate = coordinate << 
2
;
if (IntensityColor)
{
coordinate = (coordinate) || 0x001;
}
else
{
coordinate = (coordinate) || 0x003;
}*/
uint16_t 
memaddr
= 
0
; // reset buffer memory index
while (memaddr < buffersize)
{
if ( (coordinate<<memaddr) & 0x80 )//0x100
{
LED_BYTE_Buffer[memaddr] = 96-1; // compare value for logical 1
}
else
{
LED_BYTE_Buffer[memaddr] = 48-1; // compare value for logical 0
}
memaddr++;
}
LED_BYTE_Buffer[buffersize] = 0;
//TIM_GenerateEvent(TIM3, TIM_EventSource_Update);
//TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE);
DMA_SetCurrDataCounter(DMA1_Channel4, buffersize); // load number of bytes to be transferred
DMA_Cmd(DMA1_Channel4, ENABLE); // enable DMA channel 4
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_Cmd(TIM3, ENABLE); // enable Timer 3
//TIM_CtrlPWMOutputs(TIM3, ENABLE);
while(!DMA_GetFlagStatus(DMA1_FLAG_TC4)); // wait until transfer complete
TIM_Cmd(TIM3, DISABLE); // disable Timer 3
//TIM_DMACmd(TIM3, TIM_DMA_Update, DISABLE);
//DMA_Cmd(DMA1_Channel4, DISABLE); // disable DMA channel 4
DMA_ClearFlag(DMA1_FLAG_TC4); // clear DMA1 Channel 4 transfer complete flag
}
/**
* @brief Enables the AHB peripheral clock.
* @param None 
* @retval None
*/
static void RCC_Configuration(void)
{
/* Enable the GPIO_Interface Clock */
RCC_AHBPeriphClockCmd(DATA_GPIO_CLK, ENABLE);
/* Enable the TIM3_Interface Clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Enable the DMA_Interface Clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}
/**
* @brief Initializes the GPIOx peripheral.
* @param None 
* @retval None
*/
static void Interface_GPIOInit(void) 
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure the GPIO_Interface pin */
GPIO_PinAFConfig(DATA_GPIO_PORT, GPIO_PinSource4, GPIO_AF_1);
GPIO_InitStructure.GPIO_Pin
= 
DATA_PIN
;
GPIO_InitStructure.GPIO_Mode
= 
GPIO_Mode_AF
;
GPIO_InitStructure.GPIO_OType
= 
GPIO_OType_PP
;
GPIO_InitStructure.GPIO_PuPd
= 
GPIO_PuPd_NOPULL
;
GPIO_InitStructure.GPIO_Speed
= 
GPIO_Speed_50MHz
;
GPIO_Init(DATA_GPIO_PORT, &GPIO_InitStructure);
}
/**
* @brief Initializes the TIM3 peripheral.
* @param None 
* @retval None
*/
static void Timer3_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period
= 
192
-1;
TIM_TimeBaseStructure.TIM_Prescaler
= 
1
;
TIM_TimeBaseStructure.TIM_ClockDivision
= 
TIM_CKD_DIV1
;
TIM_TimeBaseStructure.TIM_CounterMode
= 
TIM_CounterMode_Up
;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode
= 
TIM_OCMode_PWM1
;
TIM_OCInitStructure.TIM_OutputState
= 
TIM_OutputState_Enable
;
TIM_OCInitStructure.TIM_Pulse
= 
0
;
TIM_OCInitStructure.TIM_OCPolarity
= 
TIM_OCPolarity_Low
;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
} 
/**
* @brief Initializes the DMA Channel4.
* @param None 
* @retval None
*/
static void InitDMA(void)
{
/* DMA1 Channel4 Config */
DMA_DeInit(DMA1_Channel4);
DMA_InitTypeDef DMA_InitStructure;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(TIM3->CCR1); // physical address of Timer 3 CCR1
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&(LED_BYTE_Buffer[0]); // this is the buffer memory 
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // data shifted from memory to peripheral
DMA_InitStructure.DMA_BufferSize = buffersize;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // automatically increase buffer index
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // stop DMA feed after buffer size is reached
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
//DMA_Cmd(DMA1_Channel4, ENABLE);
/* TIM3 Update DMA Request enable */
TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE);
}
/**
* @}
*/
/*****END OF FILE****/

0690X00000605HaQAI.png