cancel
Showing results for 
Search instead for 
Did you mean: 

update values for DMA

Bogdan
Senior
Posted on June 22, 2016 at 23:09

Hello,

i am modulating the ARR and CCR registers of a timer to get a stream of ppm pulses, and squeeze them togheather. To be honest i am not very familiar with DMA's . What i want to achive, is to squeze a sum of radio pulses, into one single ppm stream, and not using a fixed period which is dependent by the dutycycle, therefore at Clive's sugestion from another post to use the dma to modulate the timer registers from a ''wave buffer'' Right now, i am using a example value of 1000 for the ppm pulse, and do the math to extract the ARR values and CCR in order to achive trough the timer a signal of 1000us On Time and 300us rest time, total period 1300us... With the calculated values in the buffer the timer works as expected But if i want to update the values in loop, how should i proceed? I tryied to use the ''Transfer Complete'' IRQ handler from the dma channel, and update the buufer values there ( Buffer[0] and Buffer[2]) is there a way to update this values ? I am asking this, because in the future i will read the ppm channel values from a receiver, and i am planing to update the dma buffer and the dma will modulate acording the timer register

#define TIM1_DMAR_ADDRESS ((uint32_t)0x40012C4C) /* TIM ARR (Auto Reload Register) address */
uint16_t Buffer[6] = {0x79E9, 0x0000, 0x5CA7};
uint32_t mARR, mCCR;
uint16_t dutcycle;
uint16_t my_value;
uint16_t deadtime;
float fr;
int main()
{ 
my_value = 1000; // this is my pwm value from a unknow source, and bellow i calculate the desired ARR and CCR values to get 1000us Ton, and 300us Off
deadtime = 300; // fixed microseconds Toff 
fr=(float)1.0f/((float)(my_value+0f))*1000000.0f;
mARR=24000000/((uint16_t)(fr-1)); // Get the desired ARR value for loading into DMA buffer
dutcycle = (float)(my_value /(float)(my_value + deadtime) )* 100; //Compute dutycycle from 0 to 100%
mCCR =(uint32_t)(dutcycle*(mARR+1));
mCCR = (uint32_t)(mCCR/100);
SRC_Buffer[0] = mARR;
SRC_Buffer[2] =mCCR;
RCC_ClocksTypeDef ClksFreq;
RCC_GetClocksFreq(&ClksFreq); // clock view for debug
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // this pin is used just to toggle in the dma irg handler for logic analyzer view
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); 
TIM_DeInit(TIM1);
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_DMAR_ADDRESS; 
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 3;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF; 
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) (SystemCoreClock / 24000000) - 1; 
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
TIM_OCInitStructure.TIM_Pulse = 0xFFF; 
TIM_OC1Init(TIM1, &TIM_OCInitStructure); 
TIM_DMAConfig(TIM1, TIM_DMABase_ARR, TIM_DMABurstLength_3Transfers);
TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
TIM_Cmd(TIM1, ENABLE);
TIM_CtrlPWMOutputs(TIM1, ENABLE);
DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); 
DMA_Cmd(DMA1_Channel5, ENABLE);
while(1){
}
}
void DMA1_Channel5_IRQHandler(void)
{
DMA_ClearITPendingBit( DMA1_IT_TC5);
Buffer[0] = 333; // here i update the new values for the DMA?
Buffer[2] = 222; // here i update the new values for the DMA?
}

0 REPLIES 0