/**
******************************************************************************
* @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****/