/** ****************************************************************************** * @file hw_config.c * @author MCD Application Team * @version V4.0.0 * @date 21-January-2013 * @brief Hardware Configuration & Setup ****************************************************************************** * @attention * *

© COPYRIGHT 2013 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "hw_config.h" #include "stm32_it.h" #include "usb_lib.h" #include "usb_desc.h" #include "usb_pwr.h" #include "usb_prop.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ #define TIM2ARRValue 3273 /* 22KHz = 72MHz / 3273 */ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ ErrorStatus HSEStartUpStatus; EXTI_InitTypeDef EXTI_InitStructure; /* Extern variables ----------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len); /* Private functions ---------------------------------------------------------*/ /******************************************************************************* * Function Name : Set_System * Description : Configures Main system clocks & power * Input : None. * Return : None. *******************************************************************************/ void Set_System(void) { #if !defined(STM32L1XX_MD) GPIO_InitTypeDef GPIO_InitStructure; #endif /* STM32L1XX_MD */ #if defined(USB_USE_EXTERNAL_PULLUP) GPIO_InitTypeDef GPIO_InitStructure; #endif /* USB_USE_EXTERNAL_PULLUP */ /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32xxx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32xxx.c file */ #ifdef STM32L1XX_MD /* Enable the SYSCFG module clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); #endif /* STM32L1XX_MD */ #ifdef USE_STM3210B_EVAL /* Enable GPIOB, TIM2 & TIM4 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM4 , ENABLE); #endif /* USE_STM3210B_EVAL */ #if !defined(STM32L1XX_MD) /* Configure USB pull-up */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_DISCONNECT, ENABLE); /* Configure USB pull-up */ GPIO_InitStructure.GPIO_Pin = USB_DISCONNECT_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; GPIO_Init(USB_DISCONNECT, &GPIO_InitStructure); #endif /* STM32L1XX_MD */ #if defined(USB_USE_EXTERNAL_PULLUP) /* Enable the USB disconnect GPIO clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIO_DISCONNECT, ENABLE); /* USB_DISCONNECT used as USB pull-up */ GPIO_InitStructure.GPIO_Pin = USB_DISCONNECT_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(USB_DISCONNECT, &GPIO_InitStructure); #endif /* USB_USE_EXTERNAL_PULLUP */ USB_Cable_Config(DISABLE); USB_Cable_Config(ENABLE); /* Configure the EXTI line 18 connected internally to the USB IP */ EXTI_ClearITPendingBit(EXTI_Line18); EXTI_InitStructure.EXTI_Line = EXTI_Line18; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); } /******************************************************************************* * Function Name : Set_USBClock * Description : Configures USB Clock input (48MHz) * Input : None. * Return : None. *******************************************************************************/ void Set_USBClock(void) { #ifdef STM32L1XX_MD /* Enable USB clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); #else /* Select USBCLK source */ RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5); /* Enable the USB clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); #endif /* STM32L1XX_MD */ } /******************************************************************************* * Function Name : Enter_LowPowerMode * Description : Power-off system clocks and power while entering suspend mode * Input : None. * Return : None. *******************************************************************************/ void Enter_LowPowerMode(void) { /* Set the device state to suspend */ bDeviceState = SUSPENDED; } /******************************************************************************* * Function Name : Leave_LowPowerMode * Description : Restores system clocks and power while exiting suspend mode * Input : None. * Return : None. *******************************************************************************/ void Leave_LowPowerMode(void) { DEVICE_INFO *pInfo = &Device_Info; /* Set the device state to the correct state */ if (pInfo->Current_Configuration != 0) { /* Device configured */ bDeviceState = CONFIGURED; } else { bDeviceState = ATTACHED; } /*Enable SystemCoreClock*/ SystemInit(); } /******************************************************************************* * Function Name : USB_Interrupts_Config * Description : Configures the USB interrupts * Input : None. * Return : None. *******************************************************************************/ void USB_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); #ifdef STM32L1XX_MD NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable and configure the priority of the USB_HP IRQ Channel*/ NVIC_InitStructure.NVIC_IRQChannel = USB_HP_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStructure); /* Enable the USB Wake-up interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USB_FS_WKUP_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #else /* USE_STM3210B_EVAL or USE_STM3210E_EVAL */ /* Enable and configure the priority of the USB_LP IRQ Channel*/ NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable and configure the priority of the USB_HP IRQ Channel*/ NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* Enable the USB Wake-up interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USBWakeUp_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_Init(&NVIC_InitStructure); #endif /* STM32L1XX_MD */ /* Audio Components Interrupt configuration */ Audio_Config(); } /******************************************************************************* * Function Name : USB_Interrupts_Config * Description : Configures the USB interrupts * Input : None. * Return : None. *******************************************************************************/ void Audio_Config(void) { NVIC_InitTypeDef NVIC_InitStructure; #if defined(USE_STM32L152_EVAL) /* Enable the TIM2 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #elif defined(USE_STM3210B_EVAL) /* Enable the TIM2 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #elif defined(USE_STM3210E_EVAL) /* SPI2 IRQ Channel configuration */ NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); #endif /* USE_STM3210B_EVAL */ } /******************************************************************************* * Function Name : USB_Cable_Config * Description : Software Connection/Disconnection of USB Cable * Input : None. * Return : Status *******************************************************************************/ void USB_Cable_Config (FunctionalState NewState) { #ifdef STM32L1XX_MD if (NewState != DISABLE) { STM32L15_USB_CONNECT; } else { STM32L15_USB_DISCONNECT; } #else if (NewState != DISABLE) { GPIO_ResetBits(USB_DISCONNECT, USB_DISCONNECT_PIN); } else { GPIO_SetBits(USB_DISCONNECT, USB_DISCONNECT_PIN); } #endif /* STM32L1XX_MD */ } /******************************************************************************* * Function Name : Speaker_Timer_Config * Description : Configure and enable the timer * Input : None. * Return : None. *******************************************************************************/ void Speaker_Config(void) { #ifdef USE_STM32L152_EVAL DAC_InitTypeDef DAC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; uint16_t TIM6ARRValue = 4000; /* TIM6 and DAC clocks enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 | RCC_APB1Periph_DAC, ENABLE); /* Enable GPIOA clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* Configure DAC Channel1 and Channel2 as output */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); /* TIM6 Configuration */ TIM_DeInit(TIM6); TIM6ARRValue = (uint32_t)(SystemCoreClock/22000); /* Audio Sample Rate = 22KHz */ /* Set the timer auto reload value dependent on the audio frequency */ TIM_SetAutoreload(TIM6, TIM6ARRValue); /* 22.KHz = 32MHz / 1454 */ /* TIM6 TRGO selection */ TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); /* Enable TIM6 update interrupt */ TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE); /* DAC deinitialize */ DAC_DeInit(); DAC_StructInit(&DAC_InitStructure); /* Fill DAC InitStructure */ DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; /* DAC Channel1: 8bit right---------------------------------------------------*/ /* DAC Channel1 Init */ DAC_Init(DAC_Channel_1, &DAC_InitStructure); /* Enable DAC Channel1 */ DAC_Cmd(DAC_Channel_1, ENABLE); /* Start TIM6 */ TIM_Cmd(TIM6, ENABLE); #elif defined(USE_STM3210B_EVAL) GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* Configure PB.08 as alternate function (TIM4_OC3) */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* TIM4 configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0x00; /* TIM4CLK = 72 MHz */ TIM_TimeBaseStructure.TIM_Period = 0xFF; /* PWM frequency : 281.250KHz*/ TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* TIM4's Channel3 in PWM1 mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_Pulse = 0x7F; /* Duty cycle: 50%*/ TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; /* set high polarity */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); /* TIM2 configuration */ TIM_TimeBaseStructure.TIM_Period = TIM2ARRValue; TIM_TimeBaseStructure.TIM_Prescaler = 0x00; /* TIM2CLK = 72 MHz */ TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Output Compare Inactive Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_Pulse = 0x0; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Start TIM4 */ TIM_Cmd(TIM4, ENABLE); /* Start TIM2 */ TIM_Cmd(TIM2, ENABLE); /* Enable TIM2 update interrupt */ TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); #else /* Configure the initialization parameters */ I2S_GPIO_Config(); I2S_Config(I2S_Standard_Phillips, I2S_MCLKOutput_Enable, I2S_AudioFreq_22k); CODEC_Config(OutputDevice_SPEAKER, I2S_Standard_Phillips, I2S_MCLKOutput_Enable, 0x08); SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, ENABLE); #endif } /******************************************************************************* * Function Name : Get_SerialNum. * Description : Create the serial number string descriptor. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Get_SerialNum(void) { uint32_t Device_Serial0, Device_Serial1, Device_Serial2; Device_Serial0 = *(uint32_t*)ID1; Device_Serial1 = *(uint32_t*)ID2; Device_Serial2 = *(uint32_t*)ID3; Device_Serial0 += Device_Serial2; if (Device_Serial0 != 0) { IntToUnicode (Device_Serial0, &Speaker_StringSerial[2] , 8); IntToUnicode (Device_Serial1, &Speaker_StringSerial[18], 4); } } /******************************************************************************* * Function Name : HexToChar. * Description : Convert Hex 32Bits value into char. * Input : None. * Output : None. * Return : None. *******************************************************************************/ static void IntToUnicode (uint32_t value , uint8_t *pbuf , uint8_t len) { uint8_t idx = 0; for( idx = 0 ; idx < len ; idx ++) { if( ((value >> 28)) < 0xA ) { pbuf[ 2* idx] = (value >> 28) + '0'; } else { pbuf[2* idx] = (value >> 28) + 'A' - 10; } value = value << 4; pbuf[ 2* idx + 1] = 0; } } /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/