--- /dev/null
+/**
+ ******************************************************************************
+ * @file main.c
+ * @author MCD Application Team
+ * @version V1.0.0
+ * @date 19-September-2011
+ * @brief Main program body
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "usbd_hid_core.h"
+#include "usbd_usr.h"
+#include "usbd_desc.h"
+
+//Library config for this project!!!!!!!!!!!
+#include "stm32f4xx_conf.h"
+
+/** @addtogroup STM32F4-Discovery_Demo
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+
+#define TESTRESULT_ADDRESS 0x080FFFFC
+#define ALLTEST_PASS 0x00000000
+#define ALLTEST_FAIL 0x55555555
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+ #pragma data_alignment = 4
+ #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END;
+
+uint16_t PrescalerValue = 0;
+
+__IO uint32_t TimingDelay;
+__IO uint8_t DemoEnterCondition = 0x00;
+__IO uint8_t UserButtonPressed = 0x00;
+LIS302DL_InitTypeDef LIS302DL_InitStruct;
+LIS302DL_FilterConfigTypeDef LIS302DL_FilterStruct;
+__IO int8_t X_Offset, Y_Offset, Z_Offset = 0x00;
+uint8_t Buffer[6];
+
+/* Private function prototypes -----------------------------------------------*/
+static uint32_t Demo_USBConfig(void);
+static void TIM4_Config(void);
+static void Demo_Exec(void);
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @brief Main program.
+ * @param None
+ * @retval None
+ */
+int main(void)
+{
+ RCC_ClocksTypeDef RCC_Clocks;
+
+ /* Initialize LEDs and User_Button on STM32F4-Discovery --------------------*/
+ STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI);
+
+ STM_EVAL_LEDInit(LED4);
+ STM_EVAL_LEDInit(LED3);
+ STM_EVAL_LEDInit(LED5);
+ STM_EVAL_LEDInit(LED6);
+
+ /* SysTick end of count event each 10ms */
+ RCC_GetClocksFreq(&RCC_Clocks);
+ SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
+
+ if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)
+ {
+ /* Turn on LEDs available on STM32F4-Discovery ---------------------------*/
+ STM_EVAL_LEDOn(LED4);
+ STM_EVAL_LEDOn(LED3);
+ STM_EVAL_LEDOn(LED5);
+ STM_EVAL_LEDOn(LED6);
+
+ if ((*(__IO uint32_t*) TESTRESULT_ADDRESS) == ALLTEST_PASS)
+ {
+ TimingDelay = 300;
+ /* Waiting User Button is pressed or Test Program condition verified */
+ while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00))
+ {}
+ }
+ else
+ {
+ /* Waiting User Button is Released or TimeOut*/
+ TimingDelay = 300;
+ while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00))
+ {}
+ if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET)
+ {
+ TimingDelay = 0x00;
+ }
+ }
+ if (TimingDelay == 0x00)
+ {
+ /* Turn off LEDs available on STM32F4-Discovery ------------------------*/
+ STM_EVAL_LEDOff(LED4);
+ STM_EVAL_LEDOff(LED3);
+ STM_EVAL_LEDOff(LED5);
+ STM_EVAL_LEDOff(LED6);
+
+ /* Waiting User Button is released */
+ while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)
+ {}
+
+ /* Unlocks the FLASH control register access */
+ FLASH_Unlock();
+
+ /* Move discovery kit to detect negative and positive acceleration values
+ on X, Y and Z axis */
+ Accelerometer_MEMS_Test();
+
+ /* USB Hardware connection */
+ USB_Test();
+
+ /* Audio Hardware connection */
+ Audio_Test();
+
+ /* Microphone MEMS Hardware connection */
+ Microphone_MEMS_Test();
+
+ /* Write PASS code at last word in the flash memory */
+ FLASH_ProgramWord(TESTRESULT_ADDRESS, ALLTEST_PASS);
+
+ while(1)
+ {
+ /* Toggle Green LED: signaling the End of the Test program */
+ STM_EVAL_LEDToggle(LED4);
+ Delay(10);
+ }
+ }
+ else
+ {
+ Demo_Exec();
+ }
+ }
+ else
+ {
+ Demo_Exec();
+ }
+}
+
+/**
+ * @brief Execute the demo application.
+ * @param None
+ * @retval None
+ */
+static void Demo_Exec(void)
+{
+ RCC_ClocksTypeDef RCC_Clocks;
+ uint8_t togglecounter = 0x00;
+
+ while(1)
+ {
+ DemoEnterCondition = 0x00;
+
+ /* Reset UserButton_Pressed variable */
+ UserButtonPressed = 0x00;
+
+ /* Initialize LEDs to be managed by GPIO */
+ STM_EVAL_LEDInit(LED4);
+ STM_EVAL_LEDInit(LED3);
+ STM_EVAL_LEDInit(LED5);
+ STM_EVAL_LEDInit(LED6);
+
+ /* SysTick end of count event each 10ms */
+ RCC_GetClocksFreq(&RCC_Clocks);
+ SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
+
+ /* Turn OFF all LEDs */
+ STM_EVAL_LEDOff(LED4);
+ STM_EVAL_LEDOff(LED3);
+ STM_EVAL_LEDOff(LED5);
+ STM_EVAL_LEDOff(LED6);
+
+ /* Waiting User Button is pressed */
+ while (UserButtonPressed == 0x00)
+ {
+ /* Toggle LED4 */
+ STM_EVAL_LEDToggle(LED4);
+ Delay(10);
+ /* Toggle LED4 */
+ STM_EVAL_LEDToggle(LED3);
+ Delay(10);
+ /* Toggle LED4 */
+ STM_EVAL_LEDToggle(LED5);
+ Delay(10);
+ /* Toggle LED4 */
+ STM_EVAL_LEDToggle(LED6);
+ Delay(10);
+ togglecounter ++;
+ if (togglecounter == 0x10)
+ {
+ togglecounter = 0x00;
+ while (togglecounter < 0x10)
+ {
+ STM_EVAL_LEDToggle(LED4);
+ STM_EVAL_LEDToggle(LED3);
+ STM_EVAL_LEDToggle(LED5);
+ STM_EVAL_LEDToggle(LED6);
+ Delay(10);
+ togglecounter ++;
+ }
+ togglecounter = 0x00;
+ }
+ }
+
+ /* Waiting User Button is Released */
+ while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)
+ {}
+ UserButtonPressed = 0x00;
+
+ /* TIM4 channels configuration */
+ TIM4_Config();
+
+ /* Disable all Timer4 channels */
+ TIM_CCxCmd(TIM4, TIM_Channel_1, DISABLE);
+ TIM_CCxCmd(TIM4, TIM_Channel_2, DISABLE);
+ TIM_CCxCmd(TIM4, TIM_Channel_3, DISABLE);
+ TIM_CCxCmd(TIM4, TIM_Channel_4, DISABLE);
+
+ /* MEMS configuration */
+ LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE;
+ LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_100;
+ LIS302DL_InitStruct.Axes_Enable = LIS302DL_XYZ_ENABLE;
+ LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3;
+ LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL;
+ LIS302DL_Init(&LIS302DL_InitStruct);
+
+ /* Required delay for the MEMS Accelerometre: Turn-on time = 3/Output data Rate
+ = 3/100 = 30ms */
+ Delay(30);
+
+ DemoEnterCondition = 0x01;
+ /* MEMS High Pass Filter configuration */
+ LIS302DL_FilterStruct.HighPassFilter_Data_Selection = LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER;
+ LIS302DL_FilterStruct.HighPassFilter_CutOff_Frequency = LIS302DL_HIGHPASSFILTER_LEVEL_1;
+ LIS302DL_FilterStruct.HighPassFilter_Interrupt = LIS302DL_HIGHPASSFILTERINTERRUPT_1_2;
+ LIS302DL_FilterConfig(&LIS302DL_FilterStruct);
+
+ LIS302DL_Read(Buffer, LIS302DL_OUT_X_ADDR, 6);
+ X_Offset = Buffer[0];
+ Y_Offset = Buffer[2];
+ Z_Offset = Buffer[4];
+
+ /* USB configuration */
+ Demo_USBConfig();
+
+ /* Waiting User Button is pressed */
+ while (UserButtonPressed == 0x00)
+ {}
+
+ /* Waiting User Button is Released */
+ while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)
+ {}
+
+ /* Disable SPI1 used to drive the MEMS accelerometre */
+ SPI_Cmd(LIS302DL_SPI, DISABLE);
+
+ /* Disconnect the USB device */
+ DCD_DevDisconnect(&USB_OTG_dev);
+ USB_OTG_StopDevice(&USB_OTG_dev);
+ }
+}
+
+/**
+ * @brief Initializes the USB for the demonstration application.
+ * @param None
+ * @retval None
+ */
+static uint32_t Demo_USBConfig(void)
+{
+ USBD_Init(&USB_OTG_dev,
+ USB_OTG_FS_CORE_ID,
+ &USR_desc,
+ &USBD_HID_cb,
+ &USR_cb);
+
+ return 0;
+}
+
+/**
+ * @brief Configures the TIM Peripheral.
+ * @param None
+ * @retval None
+ */
+static void TIM4_Config(void)
+{
+ GPIO_InitTypeDef GPIO_InitStructure;
+ TIM_OCInitTypeDef TIM_OCInitStructure;
+ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
+
+ /* --------------------------- System Clocks Configuration -----------------*/
+ /* TIM4 clock enable */
+ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
+
+ /* GPIOD clock enable */
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
+
+ /*-------------------------- GPIO Configuration ----------------------------*/
+ /* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */
+ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
+ 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_100MHz;
+ GPIO_Init(GPIOD, &GPIO_InitStructure);
+
+ /* Connect TIM4 pins to AF2 */
+ GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
+ GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
+ GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4);
+ GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4);
+
+ /* -----------------------------------------------------------------------
+ TIM4 Configuration: Output Compare Timing Mode:
+
+ In this example TIM4 input clock (TIM4CLK) is set to 2 * APB1 clock (PCLK1),
+ since APB1 prescaler is different from 1 (APB1 Prescaler = 4, see system_stm32f4xx.c file).
+ TIM4CLK = 2 * PCLK1
+ PCLK1 = HCLK / 4
+ => TIM4CLK = 2*(HCLK / 4) = HCLK/2 = SystemCoreClock/2
+
+ To get TIM4 counter clock at 2 KHz, the prescaler is computed as follows:
+ Prescaler = (TIM4CLK / TIM1 counter clock) - 1
+ Prescaler = (168 MHz/(2 * 2 KHz)) - 1 = 41999
+
+ To get TIM4 output clock at 1 Hz, the period (ARR)) is computed as follows:
+ ARR = (TIM4 counter clock / TIM4 output clock) - 1
+ = 1999
+
+ TIM4 Channel1 duty cycle = (TIM4_CCR1/ TIM4_ARR)* 100 = 50%
+ TIM4 Channel2 duty cycle = (TIM4_CCR2/ TIM4_ARR)* 100 = 50%
+ TIM4 Channel3 duty cycle = (TIM4_CCR3/ TIM4_ARR)* 100 = 50%
+ TIM4 Channel4 duty cycle = (TIM4_CCR4/ TIM4_ARR)* 100 = 50%
+
+ ==> TIM4_CCRx = TIM4_ARR/2 = 1000 (where x = 1, 2, 3 and 4).
+
+ 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 prescaler value */
+ PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 2000) - 1;
+
+ /* Time base configuration */
+ TIM_TimeBaseStructure.TIM_Period = TIM_ARR;
+ TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
+ TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+ TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+ TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
+
+ /* Enable TIM4 Preload register on ARR */
+ TIM_ARRPreloadConfig(TIM4, ENABLE);
+
+ /* TIM PWM1 Mode configuration: Channel */
+ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
+ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
+ TIM_OCInitStructure.TIM_Pulse = TIM_CCR;
+ TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
+
+ /* Output Compare PWM1 Mode configuration: Channel1 */
+ TIM_OC1Init(TIM4, &TIM_OCInitStructure);
+ TIM_CCxCmd(TIM4, TIM_Channel_1, DISABLE);
+
+ TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
+
+ /* Output Compare PWM1 Mode configuration: Channel2 */
+ TIM_OC2Init(TIM4, &TIM_OCInitStructure);
+ TIM_CCxCmd(TIM4, TIM_Channel_2, DISABLE);
+
+ TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
+
+ /* Output Compare PWM1 Mode configuration: Channel3 */
+ TIM_OC3Init(TIM4, &TIM_OCInitStructure);
+ TIM_CCxCmd(TIM4, TIM_Channel_3, DISABLE);
+
+ TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
+
+ /* Output Compare PWM1 Mode configuration: Channel4 */
+ TIM_OC4Init(TIM4, &TIM_OCInitStructure);
+ TIM_CCxCmd(TIM4, TIM_Channel_4, DISABLE);
+
+ TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
+
+ /* TIM4 enable counter */
+ TIM_Cmd(TIM4, ENABLE);
+}
+
+/**
+ * @brief Inserts a delay time.
+ * @param nTime: specifies the delay time length, in 10 ms.
+ * @retval None
+ */
+void Delay(__IO uint32_t nTime)
+{
+ TimingDelay = nTime;
+
+ while(TimingDelay != 0);
+}
+
+/**
+ * @brief Decrements the TimingDelay variable.
+ * @param None
+ * @retval None
+ */
+void TimingDelay_Decrement(void)
+{
+ if (TimingDelay != 0x00)
+ {
+ TimingDelay--;
+ }
+}
+
+/**
+ * @brief This function handles the test program fail.
+ * @param None
+ * @retval None
+ */
+void Fail_Handler(void)
+{
+ /* Erase last sector */
+ FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3);
+ /* Write FAIL code at last word in the flash memory */
+ FLASH_ProgramWord(TESTRESULT_ADDRESS, ALLTEST_FAIL);
+
+ while(1)
+ {
+ /* Toggle Red LED */
+ STM_EVAL_LEDToggle(LED5);
+ Delay(5);
+ }
+}
+
+/**
+ * @brief MEMS accelerometre management of the timeout situation.
+ * @param None.
+ * @retval None.
+ */
+uint32_t LIS302DL_TIMEOUT_UserCallback(void)
+{
+ /* MEMS Accelerometer Timeout error occured during Test program execution */
+ if (DemoEnterCondition == 0x00)
+ {
+ /* Timeout error occured for SPI TXE/RXNE flags waiting loops.*/
+ Fail_Handler();
+ }
+ /* MEMS Accelerometer Timeout error occured during Demo execution */
+ else
+ {
+ while (1)
+ {
+ }
+ }
+ return 0;
+}
+
+#ifdef USE_FULL_ASSERT
+
+/**
+ * @brief Reports the name of the source file and the source line number
+ * where the assert_param error has occurred.
+ * @param file: pointer to the source file name
+ * @param line: assert_param error line source number
+ * @retval None
+ */
+void assert_failed(uint8_t* file, uint32_t line)
+{
+ /* User can add his own implementation to report the file name and line number,
+ ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+
+ /* Infinite loop */
+ while (1)
+ {
+ }
+}
+#endif
+
+/**
+ * @}
+ */
+
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/