void WS2812B_Send_Buffer(void) { WS2812B_TC = 0; DMA_ClearFlag(DMA1_FLAG_TC2 | DMA1_FLAG_HT2 | DMA1_FLAG_GL2 | DMA1_FLAG_TE2); DMA_ClearFlag(DMA1_FLAG_TC3 | DMA1_FLAG_HT3 | DMA1_FLAG_GL3 | DMA1_FLAG_TE3); DMA_ClearFlag(DMA1_FLAG_TC4 | DMA1_FLAG_HT4 | DMA1_FLAG_GL4 | DMA1_FLAG_TE4); DMA_SetCurrDataCounter(DMA1_Channel2, WS2812B_BUFFER_SIZE); DMA_SetCurrDataCounter(DMA1_Channel3, WS2812B_BUFFER_SIZE); DMA_SetCurrDataCounter(DMA1_Channel4, WS2812B_BUFFER_SIZE); TIM3->SR = 0; DMA_Cmd(DMA1_Channel2, ENABLE); DMA_Cmd(DMA1_Channel3, ENABLE); DMA_Cmd(DMA1_Channel4, ENABLE); TIM_DMACmd(TIM3, TIM_DMA_CC1, ENABLE); TIM_DMACmd(TIM3, TIM_DMA_CC3, ENABLE); TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE); TIM_SetCounter(TIM3, 10); TIM_Cmd(TIM3, ENABLE); }
void DMA1_Channel2_3_IRQHandler(void) { DMA_ClearITPendingBit(DMA1_IT_TC2); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); DMA_Cmd(DMA1_Channel2, DISABLE); DMA_Cmd(DMA1_Channel3, DISABLE); DMA_Cmd(DMA1_Channel4, DISABLE); TIM_DMACmd(TIM3, TIM_DMA_CC1, DISABLE); TIM_DMACmd(TIM3, TIM_DMA_CC3, DISABLE); TIM_DMACmd(TIM3, TIM_DMA_Update, DISABLE); }
void pixelclock_setup ( void ) { /* turn up the pixelclock timer * --> really should slave this off the hsync timer, or perhaps be a subchannel? */ //#define TIM8_PERIOD (500-1) /* Timer 8 PWM period 2 KHz */ #define TIM8_PERIOD (5) /* Timer 8 PWM period 2 KHz */ //#define TIM8_PRESCALER (168-1) /* Timer 8 prescaler 1 MHz */ #define TIM8_PRESCALER (1-1) /* Timer 8 prescaler 1 MHz */ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); /* TIM8 clock enable */ TIM_TimeBaseStructure.TIM_Period = TIM8_PERIOD; /* ARR end counter to trigger interupt */ TIM_TimeBaseStructure.TIM_Prescaler = TIM8_PRESCALER; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // TIM_CKD_DIV1 TIM_CKD_DIV2 TIM_CKD_DIV14 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); /* Time base configuration */ TIM_ARRPreloadConfig(TIM8, ENABLE); /* Enable the time autoreload register */ TIM_Cmd(TIM8, ENABLE); /* TIM enable counter */ TIM_DMACmd(TIM8, TIM_DMA_Update, ENABLE); /* Enable TIM8_UP DMA Requests */ // enable timer for pixel clock //nvic_enable_irq(NVIC_TIM8_UP_TIM13_IRQ); }
void ws2812_init() { wiced_pwm_init(WICED_PWM_2, 800000, 0); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); DMA_Init(DMA1_Stream7, &dma); TIM_DMACmd(TIM4, TIM_DMA_CC3, ENABLE); DMA_Cmd(DMA1_Stream7, ENABLE); wiced_pwm_start(WICED_PWM_2); }
static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) { if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) { motorDmaOutput_t * const motor = &dmaMotors[descriptor->userParam]; DMA_Cmd(descriptor->channel, DISABLE); TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, DISABLE); DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF); } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* DMA Configuration */ DMA_Configuration(); /* TIM1 DMA Transfer example ------------------------------------------------- TIM1CLK = 72 MHz, Prescaler = 0, TIM1 counter clock = 72 MHz The TIM1 Channel3 is configured to generate a complementary PWM signal with a frequency equal to: TIM1 counter clock / (TIM1_Period + 1) = 17.57 KHz and a variable duty cycle that is changed by the DMA after a specific number of Update DMA request. The number of this repetitive requests is defined by the TIM1 Repetion counter, each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new value defined by the SRC_Buffer . -----------------------------------------------------------------------------*/ /* TIM1 Peripheral Configuration --------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 4095; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 2; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 127; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* TIM1 Update DMA Request enable */ TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }
void pwmCompleteDigitalMotorUpdate(uint8_t motorCount) { UNUSED(motorCount); if (!pwmMotorsEnabled) { return; } for (int i = 0; i < dmaMotorTimerCount; i++) { TIM_SetCounter(dmaMotorTimers[i].timer, 0); TIM_DMACmd(dmaMotorTimers[i].timer, dmaMotorTimers[i].timerDmaSources, ENABLE); } }
void TIM8_Init(void){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8 ,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC,&GPIO_InitStructure); GPIO_PinAFConfig(GPIOC, GPIO_PinSource6 ,GPIO_AF_TIM8); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8 ,GPIO_AF_TIM8); GPIO_PinAFConfig(GPIOC, GPIO_PinSource9 ,GPIO_AF_TIM8); /* Time base configuration Frequency of 18Mhz */ TIM_TimeBaseStructure.TIM_Period = 8- 1; // 8 -1 ou 16- 1 TIM_TimeBaseStructure.TIM_Prescaler = 0; //Not sure if 144Mhz timer TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //Channel 1 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; TIM_OCInitStructure.TIM_Pulse = 50; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC1Init(TIM8, &TIM_OCInitStructure); TIM_OC2Init(TIM8, &TIM_OCInitStructure); TIM_OC3Init(TIM8, &TIM_OCInitStructure); TIM_OC4Init(TIM8, &TIM_OCInitStructure); TIM_DMACmd(TIM8, TIM_DMA_Update, ENABLE ); /* Enable TIM8_Updates DMA Requests */ //SET COUNTER }
/******************************************************************************* * Function Name : Timer8 configurations * Description : Configure Timer8 in such a way that it can initiate data transfer using DMA * Input : None * Output : None * Return : None *******************************************************************************/ void TIM8_Configuration(void) { #define TIM8_PERIOD (500-1) /* Timer 8 PWM period 2 KHz */ //#define TIM8_PRESCALER (168-1) /* Timer 8 prescaler 1 MHz */ #define TIM8_PRESCALER (16-1) /* Timer 8 prescaler 1 MHz */ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); /* TIM8 clock enable */ TIM_TimeBaseStructure.TIM_Period = TIM8_PERIOD; TIM_TimeBaseStructure.TIM_Prescaler = TIM8_PRESCALER; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); /* Time base configuration */ TIM_ARRPreloadConfig(TIM8, ENABLE); /* Enable the time autoreload register */ TIM_Cmd(TIM8, ENABLE); /* TIM enable counter */ TIM_DMACmd(TIM8, TIM_DMA_Update, ENABLE); /* Enable TIM8_UP DMA Requests */ }
void DMA_Config(void) { DMA_InitTypeDef DMA_InitStruct; DMA_DeInit(DMA1_Channel1); // Deinitialize DAM1 Channel 1 to their default reset values. DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&TIM2->CCR3; // Specifies Physical address of the peripheral in this case Timer 2 CCR1 DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&ledBuff; // Specifies the buffer memory address DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST; // Data transfered from memory to peripheral DMA_InitStruct.DMA_BufferSize = LED_BUFFER_SIZE; // Specifies the buffer size DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // Do not incrament the peripheral address DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; // Incrament the buffer index DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; // Specifies the peripheral data width DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; // Specifies the memory data width DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; // Specifies the operation mode. Normal or Circular DMA_InitStruct.DMA_Priority = DMA_Priority_High; // Specifies the software priority DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; // DMA_Init(DMA1_Channel1, &DMA_InitStruct); // Initialize DAM1 Channel 1 to values specified in the DMA_InitStruct structure. TIM_DMACmd(TIM2, TIM_DMA_CC3, ENABLE); // Enables TIM2's DMA request. TIM_DMA_CC1 : TIM Capture Compare 1 DMA source }
void ADC_Conf(){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; // GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2; GPIO_Init(GPIOC, &GPIO_InitStructure); // ADCの設定 ADC_CommonInitTypeDef ADC_CommonInitStructure; ADC_CommonStructInit(&ADC_CommonInitStructure); ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_2; ADC_CommonInit(&ADC_CommonInitStructure); ADC_MultiModeDMARequestAfterLastTransferCmd(ENABLE); // ADC1の設定 ADC_InitTypeDef ADC_InitStructure; ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC3; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = nADC; // 変換回数 ADC_Init(ADC1, &ADC_InitStructure); // ADC2の設定 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_Init(ADC2, &ADC_InitStructure); ADC_DiscModeChannelCountConfig(ADC1, 1); ADC_DiscModeCmd(ADC1, ENABLE); ADC_DiscModeChannelCountConfig(ADC2, 1); ADC_DiscModeCmd(ADC2, ENABLE); // AD変換チャネルなどの設定 ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_144Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_144Cycles); ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_144Cycles); ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_144Cycles); ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 2, ADC_SampleTime_144Cycles); ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 3, ADC_SampleTime_144Cycles); // タイマのカウンタの設定値を計算する uint32_t clock; RCC_ClocksTypeDef RCC_Clocks; RCC_GetClocksFreq(&RCC_Clocks); if(RCC_Clocks.HCLK_Frequency == RCC_Clocks.PCLKx_Frequency_autoADC) clock = RCC_Clocks.PCLKx_Frequency_autoADC; else clock = RCC_Clocks.PCLKx_Frequency_autoADC * 2; uint16_t preDMAC_trig = 2; uint16_t ADC_trig = dt_preADC * clock + preDMAC_trig; uint16_t postDMAC_trig = dt_postADC * clock + ADC_trig; uint16_t ADC_period = dt_int * clock / nDMAC_ADC; // エラーチェック if(ADC_trig > ADC_period || postDMAC_trig > ADC_period) while(1); // AD変換とポート出力制御用タイマの設定 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = ADC_period - 1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // AD変換タイミング (CC3) TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = ADC_trig - 1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC3Init(TIM1, &TIM_OCInitStructure); TIM_CtrlPWMOutputs(TIM1, ENABLE); // AD変換前DMA転送タイミング (CC1) TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable; TIM_OCInitStructure.TIM_Pulse = preDMAC_trig - 1; TIM_OC1Init(TIM1, &TIM_OCInitStructure); // AD変換後DMA転送タイミング (CC2) TIM_OCInitStructure.TIM_Pulse = postDMAC_trig - 1; TIM_OC2Init(TIM1, &TIM_OCInitStructure); // DMAC起動許可 TIM_DMACmd(TIM1, TIM_DMA_CC1, ENABLE); TIM_DMACmd(TIM1, TIM_DMA_CC2, ENABLE); // regular group変換後データ転送用DMACの設定 DMA_InitTypeDef DMA_InitStructure; DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_Channel = DMA_Channel_x_endADC_autoADC; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC->CDR)); DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADC_result; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = nDMAC_ADC; // 転送回数 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMAx_StreamY_endADC_autoADC, &DMA_InitStructure); // ADCの有効化 ADC_Cmd(ADC1, ENABLE); ADC_Cmd(ADC2, ENABLE); // Enable DMA DMA_Cmd(DMAx_StreamY_endADC_autoADC, ENABLE); DMA_Cmd(DMAx_StreamY_preADC_OUT_autoADC, ENABLE); DMA_Cmd(DMAx_StreamY_postADC_OUT_autoADC, ENABLE); // タイマ動作開始 TIM_Cmd(TIM1, ENABLE); }
void _wsOutput_State(FunctionalState State) { /* WS_OUTPUT_TIM enable/disable DMA Req */ TIM_DMACmd(WS_OUTPUT_TIM, WS_OUTPUT_TIM_DMA_CH, State); }
void Timer3_init(void) { uint16_t PrescalerValue; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); /* GPIOB Configuration: PWM_TIMER Channel 1 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_TIM3); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Compute the prescaler value */ RCC_ClocksTypeDef clocks; RCC_GetClocksFreq(&clocks); PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 20000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = TIM_PERIOD; // 800kHz TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_RepetitionCounter = 1; TIM_TimeBaseInit(PWM_TIMER, &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_COMPARE_LOGIC_1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(PWM_TIMER, &TIM_OCInitStructure); /*** * Must enable reload for PWM (STMicroelectronicd RM0090 section 18.3.9 * "PWM mode": * * You must enable the corresponding preload register by setting the * OCxPE bit in the TIMx_CCMRx register. * * This is part of the fix for the pulse corruption (the runt pulse at * the start and the extra pulse at the end). */ TIM_OC1PreloadConfig(PWM_TIMER, TIM_OCPreload_Enable); /* configure DMA */ /* DMA clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); /* DMA1 Channel6 Config */ DMA_DeInit(DMA_STREAM); DMA_InitStructure.DMA_BufferSize = 24*24;//42; DMA_InitStructure.DMA_Channel = DMA_CHANNEL; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; // data shifted from memory to peripheral DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&LED_BYTE_Buffer; // this is the buffer memory DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // automatically increase buffer index DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // stop DMA feed after buffer size is reached DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&PWM_TIMER->CCR1; // physical address of Timer 3 CCR1 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_Init(DMA_STREAM, &DMA_InitStructure); /* PWM_TIMER CC1 DMA Request enable */ TIM_DMACmd(PWM_TIMER, DMA_SOURCE, ENABLE); DMA_Cmd(DMA_STREAM, ENABLE); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* TIM1 and GPIOA clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA, ENABLE); /* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* GPIOA Configuration: Channel 1 as alternate function push-pull */ 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); /* TIM1 DeInit */ TIM_DeInit(TIM1); /* DMA1 Channel5 Config */ DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_DMAR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SRC_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); /* Time base configuration */ /* ----------------------------------------------------------------------- TIM1 Configuration: generate 1 PWM signal using the DMA burst mode: The TIM1CLK frequency is set to SystemCoreClock (Hz), to get TIM1 counter clock at 24 MHz the Prescaler is computed as following: - Prescaler = (TIM1CLK / TIM1 counter clock) - 1 SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density and Connectivity line devices and to 24 MHz for Low-Density Value line and Medium-Density Value line devices The TIM1 period is 5.8 KHz: TIM1 Frequency = TIM1 counter clock/(ARR + 1) = 24 MHz / 4096 = 5.8KHz KHz TIM1 Channel1 duty cycle = (TIM1_CCR1/ TIM1_ARR)* 100 = 33.33% ----------------------------------------------------------------------- */ 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 Configuration in PWM Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0xFFF; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* TIM1 DMAR Base register and DMA Burst Length Config */ TIM_DMAConfig(TIM1, TIM_DMABase_ARR, TIM_DMABurstLength_3Transfers); /* TIM1 DMA Update enable */ TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE); /* TIM1 enable */ TIM_Cmd(TIM1, ENABLE); /* TIM1 PWM Outputs Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* DMA1 Channel5 enable */ DMA_Cmd(DMA1_Channel5, ENABLE); /* Wait until DMA1 Channel5 end of Transfer */ while (!DMA_GetFlagStatus(DMA1_FLAG_TC5)) { } /* Infinite loop */ while(1) { } }
/** * @brief Main program * @param None * @retval None */ int main(void) { __IO uint16_t i; __IO uint16_t *ptr; __IO uint16_t tmp1; __IO uint16_t tmp2; uint32_t scpcnt; uint32_t scpwait; uint32_t scptpos; /* RCC Configuration */ RCC_Config(); /* GPIO Configuration */ GPIO_Config(); /* TIM Configuration */ TIM_Config(); /* NVIC Configuration */ NVIC_Config(); /* DAC Configuration */ DAC_Config(); /* SPI Configuration */ SPI_Config(); /* USART Configuration */ USART_Config(115200); /* Calibrate LC Meter */ LCM_Calibrate(); // /* Update bluetooth baudrate */ // STM32_CMD.Cmd = STM32_CMD.TickCount; // while (STM32_CMD.Cmd == STM32_CMD.TickCount); // STM32_CMD.Cmd = STM32_CMD.TickCount; // while (STM32_CMD.Cmd == STM32_CMD.TickCount); // USART3_puts("AT\0"); // STM32_CMD.Cmd = STM32_CMD.TickCount; // while (STM32_CMD.Cmd == STM32_CMD.TickCount) // { // if ((USART3->SR & USART_FLAG_RXNE) != 0) // { // STM32_CMD.BTBuff[i] = USART3->DR; // i++; // } // } // STM32_CMD.Cmd = STM32_CMD.TickCount; // while (STM32_CMD.Cmd == STM32_CMD.TickCount); // STM32_CMD.Cmd = STM32_CMD.TickCount; // while (STM32_CMD.Cmd == STM32_CMD.TickCount); // USART3_puts("AT+BAUD8\0"); // STM32_CMD.Cmd = STM32_CMD.TickCount; // while (STM32_CMD.Cmd == STM32_CMD.TickCount) // { // if ((USART3->SR & USART_FLAG_RXNE) != 0) // { // STM32_CMD.BTBuff[i] = USART3->DR; // i++; // } // } // while (1) // { // } while (1) { USART3_getdata((uint8_t *)&STM32_CMD.Cmd,4); switch (STM32_CMD.Cmd) { case CMD_LCMCAL: LCM_Calibrate(); USART3_putdata((uint8_t *)&STM32_CMD.STM32_LCM.FrequencyCal0,sizeof(STM32_LCMTypeDef)); break; case CMD_LCMCAP: GPIO_ResetBits(GPIOD, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_6 | GPIO_Pin_7); USART3_putdata((uint8_t *)&STM32_CMD.STM32_FRQ.Frequency,sizeof(STM32_FRQTypeDef)); USART3_putdata((uint8_t *)&STM32_CMD.STM32_LCM.FrequencyCal0,sizeof(STM32_LCMTypeDef)); break; case CMD_LCMIND: GPIO_ResetBits(GPIOD, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_7); GPIO_SetBits(GPIOD, GPIO_Pin_6); USART3_putdata((uint8_t *)&STM32_CMD.STM32_FRQ.Frequency,sizeof(STM32_FRQTypeDef)); USART3_putdata((uint8_t *)&STM32_CMD.STM32_LCM.FrequencyCal0,sizeof(STM32_LCMTypeDef)); break; case CMD_FRQCH1: GPIO_ResetBits(GPIOD, GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_6 | GPIO_Pin_7); GPIO_SetBits(GPIOD, GPIO_Pin_0); USART3_putdata((uint8_t *)&STM32_CMD.STM32_FRQ.Frequency,sizeof(STM32_FRQTypeDef)); break; case CMD_FRQCH2: GPIO_ResetBits(GPIOD, GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_6 | GPIO_Pin_7); GPIO_SetBits(GPIOD, GPIO_Pin_1); USART3_putdata((uint8_t *)&STM32_CMD.STM32_FRQ.Frequency,sizeof(STM32_FRQTypeDef)); break; case CMD_FRQCH3: GPIO_ResetBits(GPIOD, GPIO_Pin_2 | GPIO_Pin_6 | GPIO_Pin_7); GPIO_SetBits(GPIOD, GPIO_Pin_0 | GPIO_Pin_1); USART3_putdata((uint8_t *)&STM32_CMD.STM32_FRQ.Frequency,sizeof(STM32_FRQTypeDef)); break; case CMD_SCPSET: USART3_putdata((uint8_t *)&STM32_CMD.STM32_FRQ.Frequency,sizeof(STM32_FRQTypeDef)); USART3_getdata((uint8_t *)&STM32_CMD.STM32_SCP.ADC_Prescaler,sizeof(STM32_SCPTypeDef)); /* Scope magnify */ i = (STM32_CMD.STM32_SCP.ScopeMag & 0x07) << 3; GPIO_SetBits(GPIOE,(i ^ 0x38)); GPIO_ResetBits(GPIOE,i); /* Set V-Pos */ DAC_SetChannel1Data(DAC_Align_12b_R, STM32_CMD.STM32_SCP.ScopeVPos); /* Set Trigger level */ DAC_SetChannel2Data(DAC_Align_12b_R, STM32_CMD.STM32_SCP.ScopeTriggerLevel); if (STM32_CMD.STM32_SCP.ADC_TripleMode) { /* DMA Configuration */ DMA_TripleConfig(STM32_CMD.STM32_SCP.ADC_SampleSize); /* ADC Configuration */ ADC_TripleConfig(STM32_CMD.STM32_SCP.ADC_Prescaler, STM32_CMD.STM32_SCP.ADC_TwoSamplingDelay); } else { /* DMA Configuration */ DMA_SingleConfig(STM32_CMD.STM32_SCP.ADC_SampleSize); /* ADC Configuration */ ADC_SingleConfig(STM32_CMD.STM32_SCP.ADC_Prescaler,STM32_CMD.STM32_SCP.ADC_SampleTime); } if (STM32_CMD.STM32_SCP.ScopeTrigger == 2) { /* Rising edge */ TIM5->CCER &= ~0x2; } else { /* Falling edge */ TIM5->CCER |= 0x2; } if (STM32_CMD.STM32_SCP.ScopeTrigger) { /* Wait for trigger */ scpcnt = TIM5->CNT; scpwait = STM32_CMD.TickCount + 2; while (scpcnt == TIM5->CNT && scpwait != STM32_CMD.TickCount); } /* Start ADC1 Software Conversion */ ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART; i = 0; while (i < 30000) { i++; } /* Since BlueTooth is slower than the lowest sampling rate there is no need to wait */ SendCompressedBuffer((uint32_t *)SCOPE_DATAPTR, STM32_CMD.STM32_SCP.ADC_SampleSize / 4); /* Done */ ADC->CCR=0; ADC1->CR2=0; ADC2->CR2=0; ADC3->CR2=0; break; case CMD_SCP2SET: STM_EVAL_LEDToggle(LED4); USART3_putdata((uint8_t *)&STM32_CMD.STM32_FRQ.Frequency,sizeof(STM32_FRQTypeDef)); USART3_getdata((uint8_t *)&STM32_CMD.STM32_SCP2.SampleRateSet,sizeof(STM32_SCP2TypeDef)); /* Scope magnify */ i = ((uint32_t)STM32_CMD.STM32_SCP2.Mag & 0x07) << 3; GPIO_SetBits(GPIOE,(i ^ 0x38)); GPIO_ResetBits(GPIOE,i); /* Set V-Pos */ DAC_SetChannel1Data(DAC_Align_12b_R, STM32_CMD.STM32_SCP2.VPos); /* Set Trigger level */ DAC_SetChannel2Data(DAC_Align_12b_R, STM32_CMD.STM32_SCP2.TriggerLevel); /* Get number of samples needed */ SampleSize = GetScopeSampleSize(); if (STM32_CMD.STM32_SCP2.Triple) { /* DMA Configuration */ DMA_TripleConfig(SampleSize); /* ADC Configuration */ ADC_TripleConfig((uint32_t)STM32_CMD.STM32_SCP2.SampleRateSet >> 4,(uint32_t)STM32_CMD.STM32_SCP2.SampleRateSet & 0xF); } else { /* DMA Configuration */ DMA_SingleConfig(SampleSize); /* ADC Configuration */ ADC_SingleConfig(((uint32_t)STM32_CMD.STM32_SCP2.SampleRateSet >> 3) & 0x3,(uint32_t)STM32_CMD.STM32_SCP2.SampleRateSet & 0x7); } /* Trigger configuration */ if (STM32_CMD.STM32_SCP2.Trigger == 2) { /* Rising edge */ TIM5->CCER &= ~0x2; } else { /* Falling edge */ TIM5->CCER |= 0x2; } if (STM32_CMD.STM32_SCP2.Trigger) { /* Wait for trigger */ scpcnt = TIM5->CNT; scpwait = STM32_CMD.TickCount + 2; while (scpcnt == TIM5->CNT && scpwait != STM32_CMD.TickCount); } /* Start ADC1 Software Conversion */ ADC1->CR2 |= (uint32_t)ADC_CR2_SWSTART; /* Reset wavedata */ ScopeResetWave((uint32_t *)SCOPE_WAVEPTR,SCOPE_MAXWAVESIZE); ScopeResetWave((uint32_t *)SCOPE_COUNTPTR,SCOPE_MAXWAVESIZE); /* Wait until DMA transfer complete */ while (DMA_GetFlagStatus(DMA2_Stream0, DMA_FLAG_TCIF0) == RESET); /* Done sampling */ ADC->CCR=0; ADC1->CR2=0; ADC2->CR2=0; ADC3->CR2=0; ScopeSetWaveData((uint32_t *)SCOPE_WAVEPTR, (uint32_t *)SCOPE_COUNTPTR, (uint16_t *)SCOPE_DATAPTR); scptpos = 0; if (STM32_CMD.STM32_SCP2.Trigger) { scptpos = ScopeFindTrigger((uint16_t *)SCOPE_DATAPTR); } /* Send wave data */ SendCompressedBuffer((uint32_t *)(SCOPE_DATAPTR + scptpos * 2), (uint32_t)STM32_CMD.STM32_SCP2.PixDiv * (uint32_t)STM32_CMD.STM32_SCP2.nDiv * 2 / 4); STM_EVAL_LEDToggle(LED4); break; case CMD_HSCSET: GPIO_ResetBits(GPIOD, GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_6 | GPIO_Pin_7); GPIO_SetBits(GPIOD, GPIO_Pin_0); USART3_getdata((uint8_t *)&STM32_CMD.STM32_HSC.HSCSet,sizeof(STM32_HSCTypeDef)); TIM4->ARR = STM32_CMD.STM32_HSC.HSCSet; TIM4->CCR2 = (STM32_CMD.STM32_HSC.HSCSet+1) / 2; TIM4->PSC = STM32_CMD.STM32_HSC.HSCDiv; USART3_putdata((uint8_t *)&STM32_CMD.STM32_FRQ.Frequency,sizeof(STM32_FRQTypeDef)); break; case CMD_DDSSET: USART3_getdata((uint8_t *)&STM32_CMD.STM32_DDS.DDS_Cmd,sizeof(STM32_DDSTypeDef)); if (STM32_CMD.STM32_DDS.DDS_Cmd == DDS_PHASESET) { SPISendData(DDS_PHASESET); SPISendData32(STM32_CMD.STM32_DDS.DDS__PhaseAdd); } else if (STM32_CMD.STM32_DDS.DDS_Cmd == DDS_WAVESET) { SPISendData(DDS_WAVESET); SPISendData(STM32_CMD.STM32_DDS.DDS_Wave); SPISendData(STM32_CMD.STM32_DDS.DDS_Amplitude); SPISendData(STM32_CMD.STM32_DDS.DDS_DCOffset); } else if (STM32_CMD.STM32_DDS.DDS_Cmd == DDS_SWEEPSET) { SPISendData(DDS_SWEEPSET); SPISendData(STM32_CMD.STM32_DDS.SWEEP_Mode); SPISendData(STM32_CMD.STM32_DDS.SWEEP_Time); SPISendData32(STM32_CMD.STM32_DDS.SWEEP_Step); SPISendData32(STM32_CMD.STM32_DDS.SWEEP_Min); SPISendData32(STM32_CMD.STM32_DDS.SWEEP_Max); } break; case CMD_LGASET: USART3_getdata((uint8_t *)&STM32_CMD.STM32_LGA.DataBlocks,sizeof(STM32_LGATypeDef)); /* Set the Prescaler value */ TIM8->PSC = STM32_CMD.STM32_LGA.LGASampleRateDiv; /* Set the Autoreload value */ TIM8->ARR = STM32_CMD.STM32_LGA.LGASampleRate; TIM8->CNT = STM32_CMD.STM32_LGA.LGASampleRate-1; DMA_LGAConfig(); TIM_DMACmd(TIM8, TIM_DMA_Update, ENABLE); /* DMA2_Stream1 enable */ DMA_Cmd(DMA2_Stream1, ENABLE); /* Enable timer */ TIM8->CR1 |= TIM_CR1_CEN; while (DMA_GetFlagStatus(DMA2_Stream1,DMA_FLAG_HTIF1) == RESET); /* Half done */ USART3_putdata((uint8_t *)LGA_DATAPTR, STM32_CMD.STM32_LGA.DataBlocks * 1024 / 2); while (DMA_GetFlagStatus(DMA2_Stream1,DMA_FLAG_TCIF1) == RESET); /* Done */ USART3_putdata((uint8_t *)(LGA_DATAPTR + STM32_CMD.STM32_LGA.DataBlocks * 1024 / 2), STM32_CMD.STM32_LGA.DataBlocks * 1024 / 2); TIM_Cmd(TIM8, DISABLE); DMA_DeInit(DMA2_Stream1); break; case CMD_WAVEUPLOAD: USART3_getdata((uint8_t *)WAVE_DATAPTR,4096); SPISendData(DDS_WAVEUPLOAD); ptr = (uint16_t *)WAVE_DATAPTR; i = 2048; while (i--) { SPISendData(*ptr); ptr++; } STM_EVAL_LEDToggle(LED4); break; }
/** * @brief Main program * @param None * @retval : None */ int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* Configure the GPIO ports */ GPIO_Configuration(); /* DMA1 Channel5 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM1_CCR1_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC1_DR_Address; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); /* Enable DMA1 Channel5 */ DMA_Cmd(DMA1_Channel5, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 RegularChannelConfig Test */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); /* TIM1 configuration ------------------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 0xFF0; TIM_TimeBaseStructure.TIM_Prescaler = 0x0; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel1 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Enable TIM1 */ TIM_Cmd(TIM1, ENABLE); /* Enable TIM1 outputs */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Enable TIM1 DMA interface */ TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Start ADC1 conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); while (1) { } }
/************************************************************* * TIM4 Initialization **************************************************************/ void TIM4_Init() { #if (STRCMP($tim4IntEn$, 0) == 0) NVIC_InitTypeDef NVIC_InitStructure; #endif #if (STRCMP($ch1_0Pin$, DISABLE) == 0 || STRCMP($ch1_1Pin$, DISABLE) == 0 || \ STRCMP($ch2_0Pin$, DISABLE) == 0 || STRCMP($ch2_1Pin$, DISABLE) == 0 || \ STRCMP($ch3_0Pin$, DISABLE) == 0 || STRCMP($ch3_1Pin$, DISABLE) == 0 || \ STRCMP($ch4_0Pin$, DISABLE) == 0 || STRCMP($ch4_1Pin$, DISABLE) == 0) GPIO_InitTypeDef GPIO_InitStructure; #endif TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; #if ( (STRCMP($ch1En$, DISABLE) == 0 && STRCMP($ch1sel$, CAPTURE_ENABLE) == 0) || \ (STRCMP($ch2En$, DISABLE) == 0 && STRCMP($ch2sel$, CAPTURE_ENABLE) == 0) || \ (STRCMP($ch3En$, DISABLE) == 0 && STRCMP($ch3sel$, CAPTURE_ENABLE) == 0) || \ (STRCMP($ch4En$, DISABLE) == 0 && STRCMP($ch4sel$, CAPTURE_ENABLE) == 0) ) TIM_OCInitTypeDef TIM_OCInitStructure; #endif #if ( (STRCMP($ch1En$, DISABLE) == 0 && STRCMP($ch1sel$, COMPARE_ENABLE) == 0) || \ (STRCMP($ch2En$, DISABLE) == 0 && STRCMP($ch2sel$, COMPARE_ENABLE) == 0) || \ (STRCMP($ch3En$, DISABLE) == 0 && STRCMP($ch3sel$, COMPARE_ENABLE) == 0) || \ (STRCMP($ch4En$, DISABLE) == 0 && STRCMP($ch4sel$, COMPARE_ENABLE) == 0) ) TIM_ICInitTypeDef TIM_ICInitStructure; #endif //PUT_A_NEW_LINE_HERE // // Enable TIM4 clock // RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); #if (STRCMP($tim4PinRemap$, DEFAULT) == 0 ) //PUT_A_NEW_LINE_HERE // // Enable TIM4's GPIOD, GPIOE, AFIO clock // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE); #else //PUT_A_NEW_LINE_HERE // // Enable TIM4's GPIOB , GPIOE, AFIO clock // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE); #endif #if (STRCMP($tim4PinRemap$, DEFAULT) == 1) #if (STRCMP($ch1_0Pin$, DISABLE) == 0 || STRCMP($ch2_0Pin$, DISABLE) == 0 || STRCMP($ch3_0Pin$, DISABLE) == 0 || STRCMP($ch4_0Pin$, DISABLE) == 0) // // Configure TIM4 pins: ETR, CH1, CH2, CH3, CH4, when Pin Remap is Default // #endif #if (STRCMP($etrPin$, DISABLE) == 0) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); #endif #if (STRCMP($ch1_0Pin$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; #if (STRCMP($ch1sel$, CAPTURE_ENABLE) == 1) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; #else GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; #endif GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); #endif #if (STRCMP($ch2_0Pin$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; #if (STRCMP($ch2sel$, CAPTURE_ENABLE) == 1) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; #else GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; #endif GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); #endif #if (STRCMP($ch3_0Pin$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; #if (STRCMP($ch3sel$, CAPTURE_ENABLE) == 1) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; #else GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; #endif GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); #endif #if (STRCMP($ch4_0Pin$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; #if (STRCMP($ch4sel$, CAPTURE_ENABLE) == 1) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; #else GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; #endif GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); #endif #endif #if (STRCMP($tim4PinRemap$, GPIO_Remap_TIM4) == 1) // // Configure TIM4 pins: ETR, CH1, CH2, CH3, CH4, when Pin Remap is PartialRemap1 // GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); #if (STRCMP($etrPin$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); #endif #if (STRCMP($ch1_1Pin$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; #if (STRCMP($ch1sel$, CAPTURE_ENABLE) == 1) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; #else GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; #endif GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); #endif #if (STRCMP($ch2_1Pin$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; #if (STRCMP($ch2sel$, CAPTURE_ENABLE) == 1) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; #else GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; #endif GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); #endif #if (STRCMP($ch3_0Pin$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; #if (STRCMP($ch3sel$, CAPTURE_ENABLE) == 1) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; #else GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; #endif GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); #endif #if (STRCMP($ch4_0Pin$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; #if (STRCMP($ch4sel$, CAPTURE_ENABLE) == 1) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; #else GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; #endif GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &GPIO_InitStructure); #endif #endif //PUT_A_NEW_LINE_HERE // // Initializes the TIM4 Time Base Unit // TIM_TimeBaseStructure.TIM_Period = $tim4Period$; TIM_TimeBaseStructure.TIM_Prescaler = $tim4Psclr$; TIM_TimeBaseStructure.TIM_ClockDivision = $tim4ClkDiv$; TIM_TimeBaseStructure.TIM_CounterMode = $tim4CntMode$; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); #if (STRCMP($tim4ARRMode$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE // // Enables Preload register on ARR // TIM_ARRPreloadConfig(TIM3, ENABLE); #endif #if (STRCMP($ch1En$, DISABLE) == 0) #if (STRCMP($ch1sel$, CAPTURE_ENABLE) == 0) //PUT_A_NEW_LINE_HERE // // Initializes Output Compare Channel1 of the TIM4 // TIM_OCInitStructure.TIM_OCMode = $oc1Mode$; TIM_OCInitStructure.TIM_OutputState = $oc1State$; TIM_OCInitStructure.TIM_Pulse = $oc1Pluse$; TIM_OCInitStructure.TIM_OCPolarity = $oc1Polar$; TIM_OC1Init(TIM4, &TIM_OCInitStructure); #if (STRCMP($oc1Preload$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE // // Enables Preload register on CCR1 // TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); #endif #if (STRCMP($oc1Preload$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE // // Clears or safeguards the OCREF1 signal on an external event // TIM_ClearOC1Ref(TIM4, TIM_OCClear_Enable); #endif #if ( STRCMP($oc1FastEn$, DISABLE) == 0 && (STRCMP($oc1Mode$, TIM_OCMode_PWM1) == 1 || STRCMP($oc1Mode$, TIM_OCMode_PWM2) == 1) ) //PUT_A_NEW_LINE_HERE // // Configures the TIM4 Output Compare Channel1 Fast feature // TIM_OC1FastConfig(TIM4, TIM_OCClear_Enable); #endif #endif #if (STRCMP($ch1sel$, COMPARE_ENABLE) == 0) //PUT_A_NEW_LINE_HERE // // Initializes Input Capture Channel1 of the TIM4 // TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; TIM_ICInitStructure.TIM_ICPolarity = $ic1Polar$; TIM_ICInitStructure.TIM_ICSelection = $ic1Sel$; TIM_ICInitStructure.TIM_ICPrescaler = $ic1Psc$; TIM_ICInitStructure.TIM_ICFilter = $ic1Filter$; TIM_ICInit(TIM4, &TIM_ICInitStructure); #endif #endif #if (STRCMP($ch2En$, DISABLE) == 0) #if (STRCMP($ch2sel$, CAPTURE_ENABLE) == 0) //PUT_A_NEW_LINE_HERE // // Initializes Output Compare Channel2 of the TIM4 // TIM_OCInitStructure.TIM_OCMode = $oc2Mode$; TIM_OCInitStructure.TIM_OutputState = $oc2State$; TIM_OCInitStructure.TIM_Pulse = $oc2Pluse$; TIM_OCInitStructure.TIM_OCPolarity = $oc2Polar$; TIM_OC2Init(TIM4, &TIM_OCInitStructure); #if (STRCMP($oc2Preload$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE // // Enables Preload register on CCR2 // TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); #endif #if (STRCMP($oc2Preload$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE // // Clears or safeguards the OCREF2 signal on an external event // TIM_ClearOC2Ref(TIM4, TIM_OCClear_Enable); #endif #if ( STRCMP($oc2FastEn$, DISABLE) == 0 && (STRCMP($oc2Mode$, TIM_OCMode_PWM1) == 1 || STRCMP($oc2Mode$, TIM_OCMode_PWM2) == 1) ) //PUT_A_NEW_LINE_HERE // // Configures the TIM4 Output Compare Channel2 Fast feature // TIM_OC2FastConfig(TIM4, TIM_OCClear_Enable); #endif #endif #if (STRCMP($ch2sel$, COMPARE_ENABLE) == 0) //PUT_A_NEW_LINE_HERE // // Initializes Input Capture Channel2 of the TIM4 // TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; TIM_ICInitStructure.TIM_ICPolarity = $ic2Polar$; TIM_ICInitStructure.TIM_ICSelection = $ic2Sel$; TIM_ICInitStructure.TIM_ICPrescaler = $ic2Psc$; TIM_ICInitStructure.TIM_ICFilter = $ic2Filter$; TIM_ICInit(TIM4, &TIM_ICInitStructure); #endif #endif #if (STRCMP($ch3En$, DISABLE) == 0) #if (STRCMP($ch3sel$, CAPTURE_ENABLE) == 0) //PUT_A_NEW_LINE_HERE // // Initializes Output Compare Channel3 of the TIM4 // TIM_OCInitStructure.TIM_OCMode = $oc3Mode$; TIM_OCInitStructure.TIM_OutputState = $oc3State$; TIM_OCInitStructure.TIM_Pulse = $oc3Pluse$; TIM_OCInitStructure.TIM_OCPolarity = $oc3Polar$; TIM_OC3Init(TIM4, &TIM_OCInitStructure); #if (STRCMP($oc3Preload$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE // // Enables Preload register on CCR3 // TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); #endif #if (STRCMP($oc3Preload$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE // // Clears or safeguards the OCREF3 signal on an external event // TIM_ClearOC3Ref(TIM4, TIM_OCClear_Enable); #endif #if ( STRCMP($oc3FastEn$, DISABLE) == 0 && (STRCMP($oc3Mode$, TIM_OCMode_PWM1) == 1 || STRCMP($oc3Mode$, TIM_OCMode_PWM2) == 1) ) //PUT_A_NEW_LINE_HERE // // Configures the TIM4 Output Compare Channel3 Fast feature // TIM_OC3FastConfig(TIM4, TIM_OCClear_Enable); #endif #endif #if (STRCMP($ch3sel$, COMPARE_ENABLE) == 0) //PUT_A_NEW_LINE_HERE // // Initializes Input Capture Channel3 of the TIM4 // TIM_ICInitStructure.TIM_Channel = TIM_Channel_3; TIM_ICInitStructure.TIM_ICPolarity = $ic3Polar$; TIM_ICInitStructure.TIM_ICSelection = $ic3Sel$; TIM_ICInitStructure.TIM_ICPrescaler = $ic3Psc$; TIM_ICInitStructure.TIM_ICFilter = $ic3Filter$; TIM_ICInit(TIM4, &TIM_ICInitStructure); #endif #endif #if (STRCMP($ch4En$, DISABLE) == 0) #if (STRCMP($ch4sel$, CAPTURE_ENABLE) == 0) //PUT_A_NEW_LINE_HERE // // Initializes Output Compare Channel4 of the TIM4 // TIM_OCInitStructure.TIM_OCMode = $oc4Mode$; TIM_OCInitStructure.TIM_OutputState = $oc4State$; TIM_OCInitStructure.TIM_Pulse = $oc4Pluse$; TIM_OCInitStructure.TIM_OCPolarity = $oc4Polar$; TIM_OC4Init(TIM4, &TIM_OCInitStructure); #if (STRCMP($oc4Preload$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE // // Enables Preload register on CCR4 // TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); #endif #if (STRCMP($oc4Preload$, DISABLE) == 0) //PUT_A_NEW_LINE_HERE // // Clears or safeguards the OCREF4 signal on an external event // TIM_ClearOC4Ref(TIM4, TIM_OCClear_Enable); #endif #if ( STRCMP($oc4FastEn$, DISABLE) == 0 && (STRCMP($oc4Mode$, TIM_OCMode_PWM1) == 1 || STRCMP($oc4Mode$, TIM_OCMode_PWM2) == 1) ) //PUT_A_NEW_LINE_HERE // // Configures the TIM4 Output Compare Channel4 Fast feature // TIM_OC4FastConfig(TIM4, TIM_OCClear_Enable); #endif #endif #if (STRCMP($ch4sel$, COMPARE_ENABLE) == 0) //PUT_A_NEW_LINE_HERE // // Initializes Input Capture Channel4 of the TIM4 // TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; TIM_ICInitStructure.TIM_ICPolarity = $ic4Polar$; TIM_ICInitStructure.TIM_ICSelection = $ic4Sel$; TIM_ICInitStructure.TIM_ICPrescaler = $ic4Psc$; TIM_ICInitStructure.TIM_ICFilter = $ic4Filter$; TIM_ICInit(TIM4, &TIM_ICInitStructure); #endif #endif //PUT_A_NEW_LINE_HERE // // Enables TIM4 peripheral // TIM_Cmd(TIM4, ENABLE); #if (STRCMP($masterEn$, DISABLE) == 0 && STRCMP($masterTRGOSrc$, None) == 0) //PUT_A_NEW_LINE_HERE // // Selects the TIM4 Trigger Output Mode // TIM_SelectOutputTrigger(TIM4, $masterTRGOSrc$); #endif #if (STRCMP($slaveEn$, DISABLE) == 0 ) //PUT_A_NEW_LINE_HERE // // Sets the TIM4 Master/Slave Mode // TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable); #endif #if (STRCMP($slaveEn$, DISABLE) == 0 && STRCMP($slaveModeSet$, Disable(Internal Clock)) == 0) //PUT_A_NEW_LINE_HERE // // Selects the TIM4 Slave Mode // TIM_SelectSlaveMode(TIM4, $slaveModeSet$); #endif #if (STRCMP($onePulseEn$, TIM_OPMode_Repetitive) == 0 ) //PUT_A_NEW_LINE_HERE // // Selects the TIM4's One Pulse Mode // TIM_SelectOnePulseMode(TIM4, TIM_OPMode_Single); #endif #if (STRCMP($hallSensorEn$, DISABLE) == 0 ) //PUT_A_NEW_LINE_HERE // // Enables the TIM4's Hall sensor interface // TIM_SelectHallSensor(TIM4, ENABLE); #endif #if (STRCMP($encoderEn$, DISABLE) == 0 ) //PUT_A_NEW_LINE_HERE // // Configures the TIM4 Encoder Interface // TIM_EncoderInterfaceConfig(TIM4, $extiCh1OutputPin$, $EncodeIC1Polar$, $EncodeIC2Polar$); #endif #if (STRCMP($interClkEn$, ENABLE) == 0 ) #if (STRCMP($interTrigr$, DISABLE) == 0 ) //PUT_A_NEW_LINE_HERE // // Configures the TIM4 Internal Trigger as External Clock // TIM_ITRxExternalClockConfig(TIM4, $interTrigr$); #endif #if (STRCMP($timxTrigr$, DISABLE) == 0 ) //PUT_A_NEW_LINE_HERE // // Configures the TIM4 Trigger as External Clock // TIM_TIxExternalClockConfig(TIM4, $timxTrigr$, TIM_ICPolarity_Rising, 0x0); #endif #if (STRCMP($extTrigr$, DISABLE) == 0 ) #if (STRCMP($extTrigr$, ExternalTriggerMode1) == 1 ) //PUT_A_NEW_LINE_HERE // // Configures the External clock Mode1 // TIM_ETRClockMode1Config(TIM4, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted, 0x0); #endif #if (STRCMP($extTrigr$, ExternalTriggerMode2) == 1 ) //PUT_A_NEW_LINE_HERE // // Configures the External clock Mode2 // TIM_ETRClockMode2Config(TIM4, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_Inverted, 0x0); #endif #endif #endif #if (STRCMP($evtUpdate$, DISABLE) == 0 ) //PUT_A_NEW_LINE_HERE // // Enables the TIM4 Update event // TIM_UpdateRequestConfig(TIM4, $updateRqstSrc$); TIM_UpdateDisableConfig(TIM4, DISABLE); #endif #if (STRCMP($tim4IntEn$, 0) == 0 ) //PUT_A_NEW_LINE_HERE // // Enables TIM4 interrupts // TIM_ITConfig(TIM4, $tim4IntEn$, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif #if (STRCMP($tim4dmaEn$, DISABLE) == 0 ) //PUT_A_NEW_LINE_HERE // // Enables the TIM4's DMA Requests // TIM_DMAConfig(TIM4, $dmaBaseAddr$, $dmaBurstLen$); #if (STRCMP($tim4dmaRqstSrc$, 0) == 0 ) TIM_DMACmd(TIM4, $tim4dmaRqstSrc$, ENABLE); #endif TIM_SelectCCDMA(TIM4, ENABLE); #endif }
/** * @brief Configure the TIM1 Pins. * @param None * @retval None */ static void TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* GPIOA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* DMA2 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* GPIOA Configuration: PA8(TIM1 CH1) as alternate function push-pull ------*/ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Connect TIM pins to AF2 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2); /* Time base configuration */ /* ----------------------------------------------------------------------- TIM1 Configuration: generate 1 PWM signal using the DMA burst mode: TIM1 input clock (TIM1CLK) is set to APB2 clock (PCLK2) TIM1CLK = PCLK2 PCLK2 = HCLK => TIM1CLK = HCLK = SystemCoreClock To get TIM1 counter clock at 24 MHz, the prescaler is computed as follows: Prescaler = (TIM1CLK / TIM1 counter clock) - 1 Prescaler = (SystemCoreClock /24 MHz) - 1 TIM1 Frequency = TIM1 counter clock/(ARR + 1) = 24 MHz / 4096 = 5.85 KHz TIM1 Channel1 duty cycle = (TIM1_CCR1/ TIM1_ARR)* 100 = 33.33% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f0xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ 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 Configuration in PWM Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0xFFF; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* TIM1 DMAR Base register and DMA Burst Length Config */ TIM_DMAConfig(TIM1, TIM_DMABase_ARR, TIM_DMABurstLength_3Transfers); /* TIM1 DMA Update enable */ TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE); /* TIM1 enable */ TIM_Cmd(TIM1, ENABLE); /* TIM1 PWM Outputs Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); }
void ws2811LedStripHardwareInit(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; uint16_t prescalerValue; #ifdef CC3D RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); #else RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* GPIOA Configuration: TIM3 Channel 1 as alternate function push-pull */ GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); #endif RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Compute the prescaler value */ prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 29; // 800kHz TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCStructInit(&TIM_OCInitStructure); 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_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_CtrlPWMOutputs(TIM3, ENABLE); /* configure DMA */ /* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA1 Channel6 Config */ DMA_DeInit(DMA1_Channel6); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM3->CCR1; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE; 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_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel6, &DMA_InitStructure); /* TIM3 CC1 DMA Request enable */ TIM_DMACmd(TIM3, TIM_DMA_CC1, ENABLE); DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA); NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); const hsvColor_t hsv_white = { 0, 255, 255}; setStripColor(&hsv_white); ws2811UpdateStrip(); }
void transponderIrHardwareInit(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(TRANSPONDER_GPIO_AHB_PERIPHERAL, ENABLE); GPIO_PinAFConfig(TRANSPONDER_GPIO, TRANSPONDER_PIN_SOURCE, TRANSPONDER_GPIO_AF); /* Configuration alternate function push-pull */ GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = TRANSPONDER_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(TRANSPONDER_GPIO, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(TRANSPONDER_TIMER_APB2_PERIPHERAL, ENABLE); /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 156; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TRANSPONDER_TIMER, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; #ifdef TRANSPONDER_INVERTED TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; #else TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; #endif TIM_OC1Init(TRANSPONDER_TIMER, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TRANSPONDER_TIMER, TIM_OCPreload_Enable); TIM_CtrlPWMOutputs(TRANSPONDER_TIMER, ENABLE); /* configure DMA */ /* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA1 Channel6 Config */ DMA_DeInit(TRANSPONDER_DMA_CHANNEL); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TRANSPONDER_TIMER->CCR1; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)transponderIrDMABuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = TRANSPONDER_DMA_BUFFER_SIZE; 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_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(TRANSPONDER_DMA_CHANNEL, &DMA_InitStructure); TIM_DMACmd(TRANSPONDER_TIMER, TIM_DMA_CC1, ENABLE); DMA_ITConfig(TRANSPONDER_DMA_CHANNEL, DMA_IT_TC, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TRANSPONDER_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_TRANSPONDER_DMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_TRANSPONDER_DMA); NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* DMA Configuration */ DMA_Configuration(); /* TIM1 DMA Transfer example ------------------------------------------------- TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density and Connectivity line devices and to 24 MHz for Low-Density Value line and Medium-Density Value line devices. The objective is to configure TIM1 channel 3 to generate complementary PWM signal with a frequency equal to 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 and a variable duty cycle that is changed by the DMA after a specific number of Update DMA request. The number of this repetitive requests is defined by the TIM1 Repetition counter, each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new value defined by the SRC_Buffer . -----------------------------------------------------------------------------*/ /* Compute the value to be set in ARR register to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570 ) - 1; /* Compute CCR1 value to generate a duty cycle at 50% */ SRC_Buffer[0] = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR1 value to generate a duty cycle at 37.5% */ SRC_Buffer[1] = (uint16_t) (((uint32_t) 375 * (TimerPeriod - 1)) / 1000); /* Compute CCR1 value to generate a duty cycle at 25% */ SRC_Buffer[2] = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* TIM1 Peripheral Configuration --------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 2; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = SRC_Buffer[0]; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* TIM1 Update DMA Request enable */ TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }
/** ** sinusPeriod in SystemCoreClock quants **/ void DacSetPeriod(uint32_t sinusPeriod, uint16_t amplitude) { uint32_t prescaler = 1; uint32_t period = 24; DMA_InitTypeDef DMA_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; g_dac_amplitude = amplitude; if (sinusPeriod < MIN_SINUS_PERIOD) sinusPeriod = MIN_SINUS_PERIOD; // assert_param(frequency >= 100 && frequency <= 200000); DMA_Cmd(DMA1_Channel2, DISABLE); TIM_Cmd(GENERATOR_TIMER, DISABLE); DAC_SetChannel1Data(DAC_Align_12b_R, DAC_ZERO); // SinusBufferSize must be multiply by 4 sinusPeriod = (sinusPeriod / (period * 4)) * period * 4; // Пусть будет не кратным 4, попробуем частоту 100 КГц // sinusPeriod = (sinusPeriod / period) * period; SinusBufferSize = sinusPeriod / period; if (SinusBufferSize > SINUS_BUFFER_SIZE) { uint32_t p4; // period = 72; prescaler = sinusPeriod / period / SINUS_BUFFER_SIZE; while (SINUS_BUFFER_SIZE * prescaler * period < sinusPeriod) { prescaler++; } p4 = period * prescaler * 4; sinusPeriod = (sinusPeriod / p4) * p4; SinusBufferSize = sinusPeriod / period / prescaler; } DacSinusCalculate(); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DAC->DHR12R1; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&g_sinusBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = SinusBufferSize; 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_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel2, &DMA_InitStructure); DMA_Cmd(DMA1_Channel2, ENABLE); // 72 MHz / TIM_Prescaler / TIM_Period TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = period - 1; TIM_TimeBaseStructure.TIM_Prescaler = prescaler - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(GENERATOR_TIMER, &TIM_TimeBaseStructure); TIM_SetCounter(GENERATOR_TIMER, 0); TIM_DMACmd(GENERATOR_TIMER, TIM_DMA_Update, ENABLE); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; #ifdef USE_ADC12 TIM_OC2Init(GENERATOR_TIMER, &TIM_OCInitStructure); // ADC1 EXT3 #else TIM_OC3Init(GENERATOR_TIMER, &TIM_OCInitStructure); // ADC3 EXT1 #endif g_dac_period = period * prescaler * SinusBufferSize; }
void ws2811LedStripHardwareInit(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; DMA_InitTypeDef DMA_InitStructure; uint16_t prescalerValue; dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0); ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN)); /* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */ IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0); IOConfigGPIO(ws2811IO, IO_CONFIG(GPIO_Speed_50MHz, GPIO_Mode_AF_PP)); RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE); /* Compute the prescaler value */ prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 29; // 800kHz TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCStructInit(&TIM_OCInitStructure); 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_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_CtrlPWMOutputs(TIM3, ENABLE); /* configure DMA */ /* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA1 Channel6 Config */ DMA_DeInit(DMA1_Channel6); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM3->CCR1; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE; 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_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel6, &DMA_InitStructure); /* TIM3 CC1 DMA Request enable */ TIM_DMACmd(TIM3, TIM_DMA_CC1, ENABLE); DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE); const hsvColor_t hsv_white = { 0, 255, 255}; ws2811Initialised = true; setStripColor(&hsv_white); ws2811UpdateStrip(); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM1 Configuration */ TIM_Config(); /* Time base configuration */ /* ----------------------------------------------------------------------- TIM1 Configuration: generate 1 PWM signal using the DMA burst mode: TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock To get TIM1 counter clock at 24 MHz, the prescaler is computed as follows: Prescaler = (TIM1CLK / TIM1 counter clock) - 1 Prescaler = (SystemCoreClock /24 MHz) - 1 The TIM1 period is 5.8 KHz: TIM1 Frequency = TIM1 counter clock/(ARR + 1) = 24 MHz / 4096 = 5.85 KHz TIM1 Channel1 duty cycle = (TIM1_CCR1/ TIM1_ARR)* 100 = 33.33% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ 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 Configuration in PWM Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0xFFF; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* TIM1 DMAR Base register and DMA Burst Length Config */ TIM_DMAConfig(TIM1, TIM_DMABase_ARR, TIM_DMABurstLength_3Transfers); /* TIM1 DMA Update enable */ TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE); /* TIM1 enable */ TIM_Cmd(TIM1, ENABLE); /* TIM1 PWM Outputs Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Enable DMA2 Stream5 */ DMA_Cmd(DMA2_Stream5, ENABLE); /* Wait until DMA2 Stream5 end of Transfer */ while (!DMA_GetFlagStatus(DMA2_Stream5, DMA_FLAG_TCIF5)) { } /* Infinite loop */ while(1) { } }
void ws2811_init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; // Default LED values int i, bit; for (i = 0;i < LED_BUFFER_LEN;i++) { RGBdata[i] = 0; } for (i = 0;i < LED_BUFFER_LEN;i++) { uint32_t tmp_color = rgb_to_local(RGBdata[i]); for (bit = 0;bit < 24;bit++) { if(tmp_color & (1 << 23)) { bitbuffer[bit + i * 24] = WS2811_ONE; } else { bitbuffer[bit + i * 24] = WS2811_ZERO; } tmp_color <<= 1; } } // Fill the rest of the buffer with zeros to give the LEDs a chance to update // after sending all bits for (i = 0;i < BITBUFFER_PAD;i++) { bitbuffer[BITBUFFER_LEN - BITBUFFER_PAD - 1 + i] = 0; } // GPIOB clock enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // GPIOB Configuration: Channel 3 as alternate function push-pull GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM4); // DMA clock enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE); DMA_DeInit(DMA1_Stream7); DMA_InitStructure.DMA_Channel = DMA_Channel_2; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM4->CCR3; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)bitbuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = BITBUFFER_LEN; 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_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA1_Stream7, &DMA_InitStructure); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // Time Base configuration TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TIM_PERIOD; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); // Channel 3 Configuration in PWM mode TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = bitbuffer[0]; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); // TIM4 counter enable TIM_Cmd(TIM4, ENABLE); // DMA enable DMA_Cmd(DMA1_Stream7, ENABLE); // TIM4 Update DMA Request enable TIM_DMACmd(TIM4, TIM_DMA_CC3, ENABLE); // Main Output Enable TIM_CtrlPWMOutputs(TIM4, ENABLE); }
void ws2811LedStripHardwareInit(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; uint16_t prescalerValue; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_1); /* GPIOA Configuration: TIM16 Channel 1 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = WS2811_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(WS2811_GPIO, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE); /* Compute the prescaler value */ prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 29; // 800kHz TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM16, &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_High; TIM_OC1Init(TIM16, &TIM_OCInitStructure); TIM_CtrlPWMOutputs(TIM16, ENABLE); /* configure DMA */ /* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA1 Channel Config */ DMA_DeInit(DMA1_Channel3); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM16->CCR1; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE; 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_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel3, &DMA_InitStructure); /* TIM16 CC1 DMA Request enable */ TIM_DMACmd(TIM16, TIM_DMA_CC1, ENABLE); DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); setStripColor(&white); ws2811UpdateStrip(); }
void ws2812Init(void) { uint16_t PrescalerValue; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* GPIOB Configuration: TIM3 Channel 1 as alternate function push-pull */ // Configure the GPIO PB4 for the timer output 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_25MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_Init(GPIOB, &GPIO_InitStructure); //Map timer to alternate functions GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_TIM3); /* Compute the prescaler value */ PrescalerValue = 0; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = (105 - 1); // 800kHz TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; 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_High; TIM_OC2Init(TIM3, &TIM_OCInitStructure); // TIM_Cmd(TIM3, ENABLE); // Go!!! TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_CtrlPWMOutputs(TIM3, ENABLE); // enable Timer 3 /* configure DMA */ /* DMA clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); /* DMA1 Channel2 Config */ DMA_DeInit(DMA1_Stream5); // USART TX DMA Channel Config DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM3->CCR2; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)led_dma.buffer; // this is the buffer memory DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_BufferSize = 0; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull ; DMA_InitStructure.DMA_Channel = DMA_Channel_5; DMA_Init(DMA1_Stream5, &DMA_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 11; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(DMA1_Stream5, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA1_Stream5, DMA_IT_HT, ENABLE); /* TIM3 CC2 DMA Request enable */ TIM_DMACmd(TIM3, TIM_DMA_CC2, ENABLE); vSemaphoreCreateBinary(allLedDone); }
/** * @brief Main program. * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f0xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f0xx.c file */ /* SPI configuration ------------------------------------------------------*/ SPI_Config(); /* SysTick configuration ---------------------------------------------------*/ SysTickConfig(); /* Initialize LEDs mounted on STM320518-EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED4); /* Master board configuration ------------------------------------------------*/ #ifdef SPI_MASTER /* Initialize push-buttons mounted on STM320518-EVAL board */ STM_EVAL_PBInit(BUTTON_RIGHT, BUTTON_MODE_GPIO); STM_EVAL_PBInit(BUTTON_LEFT, BUTTON_MODE_GPIO); STM_EVAL_PBInit(BUTTON_UP, BUTTON_MODE_GPIO); STM_EVAL_PBInit(BUTTON_DOWN, BUTTON_MODE_GPIO); STM_EVAL_PBInit(BUTTON_SEL, BUTTON_MODE_GPIO); /* Initializes the SPI communication */ SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_Init(SPIx, &SPI_InitStructure); /* Initialize the FIFO threshold */ SPI_RxFIFOThresholdConfig(SPIx, SPI_RxFIFOThreshold_QF); /* TIM configuration ------------------------------------------------------*/ TIM_Config(); /* Enable the SPI peripheral */ SPI_Cmd(SPIx, ENABLE); /* Enable NSS output for master mode */ SPI_SSOutputCmd(SPIx, ENABLE); /* TIM Capture Compare DMA Request enable */ TIM_DMACmd(TIMx, TIMx_DMA_CHANNEL, ENABLE); while (1) { /* DMA channel Rx of SPI Configuration */ DMA_InitStructure.DMA_BufferSize = (uint16_t)1; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CommandReceived; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_Init(SPIx_RX_DMA_CHANNEL, &DMA_InitStructure); /* DMA TIM trigger channel Configuration */ DMA_InitStructure.DMA_BufferSize = (uint16_t)1; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CommandTransmitted; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_Init(TIMx_CHANNEL_DMA_CHANNEL, &DMA_InitStructure); /* Enable the SPI Rx DMA request */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); CommandTransmitted = 0x00; CommandReceived = 0x00; /* Clear the RxBuffer */ Fill_Buffer(RxBuffer, TXBUFFERSIZE); PressedButton = Read_Joystick(); while (PressedButton == JOY_NONE) { PressedButton = Read_Joystick(); } switch (PressedButton) { /* JOY_RIGHT button pressed */ case JOY_RIGHT: CommandTransmitted = CMD_RIGHT; NumberOfByte = CMD_RIGHT_SIZE; break; /* JOY_LEFT button pressed */ case JOY_LEFT: CommandTransmitted = CMD_LEFT; NumberOfByte = CMD_LEFT_SIZE; break; /* JOY_UP button pressed */ case JOY_UP: CommandTransmitted = CMD_UP; NumberOfByte = CMD_UP_SIZE; break; /* JOY_DOWN button pressed */ case JOY_DOWN: CommandTransmitted = CMD_DOWN; NumberOfByte = CMD_DOWN_SIZE; break; /* JOY_SEL button pressed */ case JOY_SEL: CommandTransmitted = CMD_SEL; NumberOfByte = CMD_SEL_SIZE; break; default: break; } /* Enable the DMA channel */ DMA_Cmd(SPIx_RX_DMA_CHANNEL, ENABLE); /* Enable DMA1 TIM Trigger Channel */ DMA_Cmd(TIMx_CHANNEL_DMA_CHANNEL, ENABLE); /* TIM enable counter */ TIM_Cmd(TIMx, ENABLE); /* Wait the SPI DMA Rx transfer complete or time out*/ TimeOut = USER_TIMEOUT; while ((DMA_GetFlagStatus(SPIx_RX_DMA_FLAG_TC) == RESET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } /* The BSY flag can be monitored to ensure that the SPI communication is complete. This is required to avoid corrupting the last transmission before disabling the SPI or entering the Stop mode. The software must first wait until TXE=1 and then until BSY=0.*/ TimeOut = USER_TIMEOUT; while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } TimeOut = USER_TIMEOUT; while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } /* Clear DMA1 global flags*/ DMA_ClearFlag(TIMx_CHANNEL_DMA_FLAG_GL); DMA_ClearFlag(SPIx_RX_DMA_FLAG_GL); /* disable the DMA channels */ DMA_Cmd(SPIx_RX_DMA_CHANNEL, DISABLE); DMA_Cmd(TIMx_CHANNEL_DMA_CHANNEL, DISABLE); /* disable the SPI Rx DMA request */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, DISABLE); /* TIM disable counter */ TIM_Cmd(TIMx, DISABLE); if (CommandReceived == CMD_ACK) { /* DMA channel Rx of SPI Configuration */ DMA_InitStructure.DMA_BufferSize = (uint16_t)NumberOfByte; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_Init(SPIx_RX_DMA_CHANNEL, &DMA_InitStructure); /* DMA channel Tx of SPI Configuration */ DMA_InitStructure.DMA_BufferSize = (uint16_t)NumberOfByte; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_Init(TIMx_CHANNEL_DMA_CHANNEL, &DMA_InitStructure); /* Enable the SPI Rx DMA request */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); /* Enable the DMA channel */ DMA_Cmd(SPIx_RX_DMA_CHANNEL, ENABLE); /* Enable DMA1 TIM Trigger Channel */ DMA_Cmd(TIMx_CHANNEL_DMA_CHANNEL, ENABLE); /* TIM enable counter */ TIM_Cmd(TIMx, ENABLE); /* Wait the SPI Rx DMA transfer complete or time out */ TimeOut = USER_TIMEOUT; while ((DMA_GetFlagStatus(SPIx_RX_DMA_FLAG_TC) == RESET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } /* The BSY flag can be monitored to ensure that the SPI communication is complete. This is required to avoid corrupting the last transmission before disabling the SPI or entering the Stop mode. The software must first wait until TXE=1 and then until BSY=0.*/ TimeOut = USER_TIMEOUT; while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } TimeOut = USER_TIMEOUT; while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } /* Clear DMA1 global flags */ DMA_ClearFlag(TIMx_CHANNEL_DMA_FLAG_GL); DMA_ClearFlag(SPIx_RX_DMA_FLAG_GL); /* Disable the DMA channels */ DMA_Cmd(SPIx_RX_DMA_CHANNEL, DISABLE); DMA_Cmd(TIMx_CHANNEL_DMA_CHANNEL, DISABLE); /* Disable the SPI Rx and Tx DMA requests */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, DISABLE); /* TIM disable counter */ TIM_Cmd(TIMx, DISABLE); switch (NumberOfByte) { /* CMD_RIGHT command received */ case CMD_RIGHT_SIZE: if ((Buffercmp(TxBuffer, RxBuffer, CMD_RIGHT_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) { /* Turn ON LED2 and LED3 */ STM_EVAL_LEDOn(LED2); STM_EVAL_LEDOn(LED3); /* Turn OFF LED4 */ STM_EVAL_LEDOff(LED4); } break; /* CMD_LEFT command received */ case CMD_LEFT_SIZE: if ((Buffercmp(TxBuffer, RxBuffer, CMD_LEFT_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) { /* Turn ON LED4 */ STM_EVAL_LEDOn(LED4); /* Turn OFF LED2 and LED3 */ STM_EVAL_LEDOff(LED2); STM_EVAL_LEDOff(LED3); } break; /* CMD_UP command received */ case CMD_UP_SIZE: if ((Buffercmp(TxBuffer, RxBuffer, CMD_UP_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) { /* Turn ON LED2 */ STM_EVAL_LEDOn(LED2); /* Turn OFF LED3 and LED4 */ STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED4); } break; /* CMD_DOWN command received */ case CMD_DOWN_SIZE: if ((Buffercmp(TxBuffer, RxBuffer, CMD_DOWN_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) { /* Turn ON LED3 */ STM_EVAL_LEDOn(LED3); /* Turn OFF LED2 and LED4 */ STM_EVAL_LEDOff(LED2); STM_EVAL_LEDOff(LED4); } break; /* CMD_SEL command received */ case CMD_SEL_SIZE: if ((Buffercmp(TxBuffer, RxBuffer, CMD_SEL_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) { /* Turn ON LED2, LED3 and LED4 */ STM_EVAL_LEDOn(LED2); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOn(LED4); } break; default: break; } } } #endif /* SPI_MASTER */ /* Slave board configuration -----------------------------------------------*/ #ifdef SPI_SLAVE /* Initializes the SPI communication */ SPI_I2S_DeInit(SPIx); SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; SPI_Init(SPIx, &SPI_InitStructure); /* Initialize the FIFO threshold */ SPI_RxFIFOThresholdConfig(SPIx, SPI_RxFIFOThreshold_QF); CommandTransmitted = CMD_ACK; /* Infinite Loop */ while (1) { /* DMA channel Rx of SPI Configuration */ DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CommandReceived; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_Init(SPIx_RX_DMA_CHANNEL, &DMA_InitStructure); /* DMA channel Tx of SPI Configuration */ DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CommandTransmitted; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_Init(SPIx_TX_DMA_CHANNEL, &DMA_InitStructure); /* Enable the SPI Rx and Tx DMA requests */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE); /* Enable the SPI peripheral */ SPI_Cmd(SPIx, ENABLE); CommandReceived = 0x00; /* Enable the DMA channels */ DMA_Cmd(SPIx_RX_DMA_CHANNEL, ENABLE); DMA_Cmd(SPIx_TX_DMA_CHANNEL, ENABLE); /* Wait the SPI DMA transfers complete or time out */ while (DMA_GetFlagStatus(SPIx_RX_DMA_FLAG_TC) == RESET) {} TimeOut = USER_TIMEOUT; while ((DMA_GetFlagStatus(SPIx_TX_DMA_FLAG_TC) == RESET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } /* The BSY flag can be monitored to ensure that the SPI communication is complete. This is required to avoid corrupting the last transmission before disabling the SPI or entering the Stop mode. The software must first wait until TXE=1 and then until BSY=0.*/ TimeOut = USER_TIMEOUT; while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } TimeOut = USER_TIMEOUT; while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } /* Clear DMA1 global flags */ DMA_ClearFlag(SPIx_TX_DMA_FLAG_GL); DMA_ClearFlag(SPIx_RX_DMA_FLAG_GL); /* Disable the DMA channels */ DMA_Cmd(SPIx_RX_DMA_CHANNEL, DISABLE); DMA_Cmd(SPIx_TX_DMA_CHANNEL, DISABLE); /* Disable the SPI peripheral */ SPI_Cmd(SPIx, DISABLE); /* Disable the SPI Rx and Tx DMA requests */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, DISABLE); SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, DISABLE); switch (CommandReceived) { /* CMD_RIGHT command received */ case CMD_RIGHT: NumberOfByte = CMD_RIGHT_SIZE; break; /* CMD_LEFT command received */ case CMD_LEFT: NumberOfByte = CMD_LEFT_SIZE; break; /* CMD_UP command received */ case CMD_UP: NumberOfByte = CMD_UP_SIZE; break; /* CMD_DOWN command received */ case CMD_DOWN: NumberOfByte = CMD_DOWN_SIZE; break; /* CMD_SEL command received */ case CMD_SEL: NumberOfByte = CMD_SEL_SIZE; break; default: break; } /* DMA channel Rx of SPI Configuration */ DMA_InitStructure.DMA_BufferSize = NumberOfByte; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_Init(SPIx_RX_DMA_CHANNEL, &DMA_InitStructure); /* DMA channel Tx of SPI Configuration */ DMA_InitStructure.DMA_BufferSize = NumberOfByte; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_Init(SPIx_TX_DMA_CHANNEL, &DMA_InitStructure); /* Enable the SPI Rx and Tx DMA requests */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE); /* Enable the SPI peripheral */ SPI_Cmd(SPIx, ENABLE); /* Enable the DMA channels */ DMA_Cmd(SPIx_RX_DMA_CHANNEL, ENABLE); DMA_Cmd(SPIx_TX_DMA_CHANNEL, ENABLE); /* Wait the SPI DMA transfers complete or time out */ while (DMA_GetFlagStatus(SPIx_RX_DMA_FLAG_TC) == RESET) {} TimeOut = USER_TIMEOUT; while ((DMA_GetFlagStatus(SPIx_TX_DMA_FLAG_TC) == RESET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } /* The BSY flag can be monitored to ensure that the SPI communication is complete. This is required to avoid corrupting the last transmission before disabling the SPI or entering the Stop mode. The software must first wait until TXE=1 and then until BSY=0.*/ TimeOut = USER_TIMEOUT; while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } TimeOut = USER_TIMEOUT; while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET)&&(TimeOut != 0x00)) {} if(TimeOut == 0) { TimeOut_UserCallback(); } switch (NumberOfByte) { /* CMD_RIGHT command received */ case CMD_RIGHT_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_RIGHT_SIZE, SPI_DATAMASK) != FAILED) { /* Turn ON LED2 and LED3 */ STM_EVAL_LEDOn(LED2); STM_EVAL_LEDOn(LED3); /* Turn OFF LED4 */ STM_EVAL_LEDOff(LED4); } break; /* CMD_LEFT command received */ case CMD_LEFT_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_LEFT_SIZE, SPI_DATAMASK) != FAILED) { /* Turn ON LED4 */ STM_EVAL_LEDOn(LED4); /* Turn OFF LED2 and LED3 */ STM_EVAL_LEDOff(LED2); STM_EVAL_LEDOff(LED3); } break; /* CMD_UP command received */ case CMD_UP_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_UP_SIZE, SPI_DATAMASK) != FAILED) { /* Turn ON LED2 */ STM_EVAL_LEDOn(LED2); /* Turn OFF LED3 and LED4 */ STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED4); } break; /* CMD_DOWN command received */ case CMD_DOWN_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_DOWN_SIZE, SPI_DATAMASK) != FAILED) { /* Turn ON LED3 */ STM_EVAL_LEDOn(LED3); /* Turn OFF LED2 and LED4 */ STM_EVAL_LEDOff(LED2); STM_EVAL_LEDOff(LED4); } break; /* CMD_SEL command received */ case CMD_SEL_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_SEL_SIZE, SPI_DATAMASK) != FAILED) { /* Turn ON LED2, LED3 and LED4 */ STM_EVAL_LEDOn(LED2); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOn(LED4); } break; default: break; } /* Clear DMA1 global flags */ DMA_ClearFlag(SPIx_TX_DMA_FLAG_GL); DMA_ClearFlag(SPIx_RX_DMA_FLAG_GL); /* Disable the DMA channels */ DMA_Cmd(SPIx_RX_DMA_CHANNEL, DISABLE); DMA_Cmd(SPIx_TX_DMA_CHANNEL, DISABLE); /* Disable the SPI peripheral */ SPI_Cmd(SPIx, DISABLE); /* Disable the SPI Rx and Tx DMA requests */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, DISABLE); SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, DISABLE); } #endif /* SPI_SLAVE */ }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM Configuration */ TIM_Config(); /* TIM1 DMA Transfer example ------------------------------------------------- TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock SystemCoreClock is set to 168 MHz for STM32F4xx devices. The objective is to configure TIM1 channel 3 to generate complementary PWM signal with a frequency equal to 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 and a variable duty cycle that is changed by the DMA after a specific number of Update DMA request. The number of this repetitive requests is defined by the TIM1 Repetion counter, each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new value defined by the aSRC_Buffer. Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. -----------------------------------------------------------------------------*/ /* Compute the value to be set in ARR regiter to generate signal frequency at 17.57 Khz */ uhTimerPeriod = (SystemCoreClock / 17570 ) - 1; /* Compute CCR1 value to generate a duty cycle at 50% */ aSRC_Buffer[0] = (uint16_t) (((uint32_t) 5 * (uhTimerPeriod - 1)) / 10); /* Compute CCR1 value to generate a duty cycle at 37.5% */ aSRC_Buffer[1] = (uint16_t) (((uint32_t) 375 * (uhTimerPeriod - 1)) / 1000); /* Compute CCR1 value to generate a duty cycle at 25% */ aSRC_Buffer[2] = (uint16_t) (((uint32_t) 25 * (uhTimerPeriod - 1)) / 100); /* TIM1 Peripheral Configuration -------------------------------------------*/ /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = uhTimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 3; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = aSRC_Buffer[0]; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Enable preload feature */ TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* DMA enable*/ DMA_Cmd(DMA2_Stream6, ENABLE); /* TIM1 Update DMA Request enable */ TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) { } }