TM_PWM_Result_t TM_PWM_InitTimer(TIM_TypeDef* TIMx, TM_PWM_TIM_t* TIM_Data, double PWMFrequency) { TIM_TimeBaseInitTypeDef TIM_BaseStruct; TM_TIMER_PROPERTIES_t Timer_Data; /* Check valid timer */ if (TIMx == TIM6 || TIMx == TIM7) { /* Timers TIM6 and TIM7 can not provide PWM feature */ return TM_PWM_Result_TimerNotValid; } /* Save timer */ TIM_Data->TIM = TIMx; /* Get timer properties */ TM_TIMER_PROPERTIES_GetTimerProperties(TIMx, &Timer_Data); /* Check for maximum timer frequency */ if (PWMFrequency > Timer_Data.TimerFrequency) { /* Frequency too high */ return TM_PWM_Result_FrequencyTooHigh; } else if (PWMFrequency == 0) { /* Not valid frequency */ return TM_PWM_Result_FrequencyTooLow; } /* Generate settings */ TM_TIMER_PROPERTIES_GenerateDataForWorkingFrequency(&Timer_Data, PWMFrequency); /* Check valid data */ if (Timer_Data.Period == 0) { /* Too high frequency */ return TM_PWM_Result_FrequencyTooHigh; } /* Tests are OK */ TIM_Data->Frequency = PWMFrequency; TIM_Data->Micros = 1000000 / PWMFrequency; TIM_Data->Period = Timer_Data.Period; TIM_Data->Prescaler = Timer_Data.Prescaler; /* Enable clock for Timer */ TM_TIMER_PROPERTIES_EnableClock(TIMx); /* Set timer options */ TIM_BaseStruct.TIM_Prescaler = Timer_Data.Prescaler - 1; TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_BaseStruct.TIM_Period = Timer_Data.Period - 1; TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_BaseStruct.TIM_RepetitionCounter = 0; /* Initialize timer */ TIM_TimeBaseInit(TIMx, &TIM_BaseStruct); /* Start timer */ TIM_Cmd(TIMx, ENABLE); /* Return OK */ return TM_PWM_Result_Ok; }
void TM_DELAY_INT_InitTIM(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; NVIC_InitTypeDef NVIC_InitStruct; TM_TIMER_PROPERTIES_t TIM_Data; /* Get timer properties */ TM_TIMER_PROPERTIES_GetTimerProperties(TM_DELAY_TIM, &TIM_Data); /* Generate timer properties, 1us ticks */ TM_TIMER_PROPERTIES_GenerateDataForWorkingFrequency(&TIM_Data, 1000000); /* Enable clock for TIMx */ TM_TIMER_PROPERTIES_EnableClock(TM_DELAY_TIM); /* Set timer settings */ TIM_TimeBaseStruct.TIM_ClockDivision = 0; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStruct.TIM_Period = 999; /* 1 millisecond */ TIM_TimeBaseStruct.TIM_Prescaler = SystemCoreClock / (1000000 * (SystemCoreClock / TIM_Data.TimerFrequency)) - 1; /* With prescaler for 1 microsecond tick */ TIM_TimeBaseStruct.TIM_RepetitionCounter = 0; /* Initialize timer */ TIM_TimeBaseInit(TM_DELAY_TIM, &TIM_TimeBaseStruct); /* Enable interrupt each update cycle */ TIMx->DIER |= TIM_IT_Update; /* Set NVIC parameters */ NVIC_InitStruct.NVIC_IRQChannel = TM_DELAY_TIM_IRQ; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; /* Add to NVIC */ NVIC_Init(&NVIC_InitStruct); /* Start timer */ TM_DELAY_TIM->CR1 |= TIM_CR1_CEN; }
TM_DAC_SIGNAL_Result_t TM_DAC_SIGNAL_SetCustomSignal(TM_DAC_SIGNAL_Channel_t DACx, uint16_t* Signal_Data, uint16_t Signal_Length, double frequency) { DAC_InitTypeDef DAC_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; DMA_InitTypeDef DMA_InitStruct; TM_TIMER_PROPERTIES_t Timer_Data; /* Check if timer is set */ if (!dac_timer_set[DACx]) { return TM_DAC_SIGNAL_Result_Error; } /* Check used timer */ /* Set proper trigger */ if (DAC_TIM[DACx] == TIM2) { DAC_InitStruct.DAC_Trigger = DAC_Trigger_T2_TRGO; } else if (DAC_TIM[DACx] == TIM4) { DAC_InitStruct.DAC_Trigger = DAC_Trigger_T4_TRGO; } else if (DAC_TIM[DACx] == TIM5) { DAC_InitStruct.DAC_Trigger = DAC_Trigger_T5_TRGO; } else if (DAC_TIM[DACx] == TIM6) { DAC_InitStruct.DAC_Trigger = DAC_Trigger_T6_TRGO; } else if (DAC_TIM[DACx] == TIM7) { DAC_InitStruct.DAC_Trigger = DAC_Trigger_T7_TRGO; } else if (DAC_TIM[DACx] == TIM8) { DAC_InitStruct.DAC_Trigger = DAC_Trigger_T8_TRGO; } else { /* Timer is not valid */ return TM_DAC_SIGNAL_Result_TimerNotValid; } /* Get timer data */ TM_TIMER_PROPERTIES_GetTimerProperties(DAC_TIM[DACx], &Timer_Data); /* Get period and prescaler values */ TM_TIMER_PROPERTIES_GenerateDataForWorkingFrequency(&Timer_Data, frequency * Signal_Length); /* Check valid frequency */ if (Timer_Data.Frequency == 0) { return TM_DAC_SIGNAL_Result_Error; } /* Enable DAC clock */ RCC->APB1ENR |= RCC_APB1ENR_DACEN; /* Enable DMA1 clock */ RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; /* Initialize DAC */ DAC_InitStruct.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStruct.DAC_OutputBuffer = DAC_OutputBuffer_Enable; /* Disable DMA */ if (DACx == TM_DAC1) { /* Init DAC channel 1 */ DAC_Init(DAC_Channel_1, &DAC_InitStruct); } else if (DACx == TM_DAC2) { /* Init DAC channel 2 */ DAC_Init(DAC_Channel_2, &DAC_InitStruct); } /* Enable timer clock */ TM_TIMER_PROPERTIES_EnableClock(DAC_TIM[DACx]); /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStruct); TIM_TimeBaseStruct.TIM_Period = Timer_Data.Period - 1; TIM_TimeBaseStruct.TIM_Prescaler = Timer_Data.Prescaler - 1; TIM_TimeBaseStruct.TIM_ClockDivision = 0; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; /* Initialize timer */ TIM_TimeBaseInit(DAC_TIM[DACx], &TIM_TimeBaseStruct); /* Enable TIM selection */ TIM_SelectOutputTrigger(DAC_TIM[DACx], TIM_TRGOSource_Update); /* Set DMA options */ DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)Signal_Data; DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStruct.DMA_BufferSize = Signal_Length; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; DMA_InitStruct.DMA_Priority = DMA_Priority_High; DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; switch (DACx) { case TM_DAC1: /* Set peripheral location = 12bit right aligned for channel 1 */ DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR12R1; /* Disable DMA */ DMA_DeInit(DAC_SIGNAL_DMA_DAC1_STREAM); /* Set channel used */ DMA_InitStruct.DMA_Channel = DAC_SIGNAL_DMA_DAC1_CHANNEL; /* Initialize DMA */ DMA_Init(DAC_SIGNAL_DMA_DAC1_STREAM, &DMA_InitStruct); /* Enable DMA Stream for DAC Channel 1 */ DMA_Cmd(DAC_SIGNAL_DMA_DAC1_STREAM, ENABLE); /* Enable DAC Channel 1 */ DAC_Cmd(DAC_Channel_1, ENABLE); /* Enable DMA for DAC Channel 1 */ DAC_DMACmd(DAC_Channel_1, ENABLE); break; case TM_DAC2: /* Disable DMA */ DMA_DeInit(DAC_SIGNAL_DMA_DAC2_STREAM); /* Set channel used */ DMA_InitStruct.DMA_Channel = DAC_SIGNAL_DMA_DAC2_CHANNEL; /* Set peripheral location = 12bit right aligned for channel 2 */ DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR12R2; /* Initialize DMA */ DMA_Init(DAC_SIGNAL_DMA_DAC2_STREAM, &DMA_InitStruct); /* Enable DMA Stream for DAC Channel 2 */ DMA_Cmd(DAC_SIGNAL_DMA_DAC2_STREAM, ENABLE); /* Enable DAC Channel 2 */ DAC_Cmd(DAC_Channel_2, ENABLE); /* Enable DMA for DAC Channel 2 */ DAC_DMACmd(DAC_Channel_2, ENABLE); break; default: break; } /* Enable timer */ DAC_TIM[DACx]->CR1 |= TIM_CR1_CEN; /* Return OK */ return TM_DAC_SIGNAL_Result_Ok; }