761e761a331c64e3f4a1ec75e6b91cd309e8d6bf
[fw/stlink] / example / stm32f4 / Projects / discovery_demo / main.c
1 /**
2   ******************************************************************************
3   * @file    main.c 
4   * @author  MCD Application Team
5   * @version V1.0.0
6   * @date    19-September-2011
7   * @brief   Main program body
8   ******************************************************************************
9   * @attention
10   *
11   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17   *
18   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
19   ******************************************************************************
20   */ 
21 /* Includes ------------------------------------------------------------------*/
22 #include "main.h"
23 #include "usbd_hid_core.h"
24 #include "usbd_usr.h"
25 #include "usbd_desc.h"
26
27 //Library config for this project!!!!!!!!!!!
28 #include "stm32f4xx_conf.h"
29
30 /** @addtogroup STM32F4-Discovery_Demo
31   * @{
32   */
33
34 /* Private typedef -----------------------------------------------------------*/
35 /* Private define ------------------------------------------------------------*/
36
37 #define TESTRESULT_ADDRESS         0x080FFFFC
38 #define ALLTEST_PASS               0x00000000
39 #define ALLTEST_FAIL               0x55555555
40
41 /* Private macro -------------------------------------------------------------*/
42 /* Private variables ---------------------------------------------------------*/
43 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
44   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
45     #pragma data_alignment = 4   
46   #endif
47 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
48 __ALIGN_BEGIN USB_OTG_CORE_HANDLE  USB_OTG_dev __ALIGN_END;
49   
50 uint16_t PrescalerValue = 0;
51
52 __IO uint32_t TimingDelay;
53 __IO uint8_t DemoEnterCondition = 0x00;
54 __IO uint8_t UserButtonPressed = 0x00;
55 LIS302DL_InitTypeDef  LIS302DL_InitStruct;
56 LIS302DL_FilterConfigTypeDef LIS302DL_FilterStruct;  
57 __IO int8_t X_Offset, Y_Offset, Z_Offset  = 0x00;
58 uint8_t Buffer[6];
59
60 /* Private function prototypes -----------------------------------------------*/
61 static uint32_t Demo_USBConfig(void);
62 static void TIM4_Config(void);
63 static void Demo_Exec(void);
64
65 /* Private functions ---------------------------------------------------------*/
66
67 /**
68   * @brief  Main program.
69   * @param  None
70   * @retval None
71   */
72 int main(void)
73 {
74   RCC_ClocksTypeDef RCC_Clocks;
75   
76   /* Initialize LEDs and User_Button on STM32F4-Discovery --------------------*/
77   STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI); 
78   
79   STM_EVAL_LEDInit(LED4);
80   STM_EVAL_LEDInit(LED3);
81   STM_EVAL_LEDInit(LED5);
82   STM_EVAL_LEDInit(LED6);
83   
84   /* SysTick end of count event each 10ms */
85   RCC_GetClocksFreq(&RCC_Clocks);
86   SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
87   
88   if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)
89   {
90     /* Turn on LEDs available on STM32F4-Discovery ---------------------------*/
91     STM_EVAL_LEDOn(LED4);
92     STM_EVAL_LEDOn(LED3);
93     STM_EVAL_LEDOn(LED5);
94     STM_EVAL_LEDOn(LED6); 
95
96     if ((*(__IO uint32_t*) TESTRESULT_ADDRESS) == ALLTEST_PASS)
97     {
98       TimingDelay = 300;
99       /* Waiting User Button is pressed or Test Program condition verified */
100       while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00))
101       {}
102     }
103     else
104     {
105       /* Waiting User Button is Released  or TimeOut*/
106       TimingDelay = 300;
107       while ((STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)&&(TimingDelay != 0x00))
108       {}
109       if (STM_EVAL_PBGetState(BUTTON_USER) == Bit_RESET)
110       {
111         TimingDelay = 0x00;
112       }
113     }
114     if (TimingDelay == 0x00)
115     {
116       /* Turn off LEDs available on STM32F4-Discovery ------------------------*/
117       STM_EVAL_LEDOff(LED4);
118       STM_EVAL_LEDOff(LED3);
119       STM_EVAL_LEDOff(LED5);
120       STM_EVAL_LEDOff(LED6); 
121       
122       /* Waiting User Button is released */
123       while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)
124       {}
125       
126       /* Unlocks the FLASH control register access */
127       FLASH_Unlock();
128       
129       /* Move discovery kit to detect negative and positive acceleration values 
130       on X, Y and Z axis */
131       Accelerometer_MEMS_Test();
132       
133       /* USB Hardware connection */
134       USB_Test();
135       
136       /* Audio Hardware connection */
137       Audio_Test();
138       
139       /* Microphone MEMS Hardware connection */
140       Microphone_MEMS_Test();
141       
142       /* Write PASS code at last word in the flash memory */
143       FLASH_ProgramWord(TESTRESULT_ADDRESS, ALLTEST_PASS);
144       
145       while(1)
146       {
147         /* Toggle Green LED: signaling the End of the Test program */
148         STM_EVAL_LEDToggle(LED4);
149         Delay(10);
150       }
151     }
152     else
153     {
154       Demo_Exec();
155     }
156   }
157   else
158   {    
159     Demo_Exec();
160   }
161 }
162
163 /**
164   * @brief  Execute the demo application.
165   * @param  None
166   * @retval None
167   */
168 static void Demo_Exec(void)
169 {
170   RCC_ClocksTypeDef RCC_Clocks;
171   uint8_t togglecounter = 0x00;
172   
173   while(1)
174   {
175     DemoEnterCondition = 0x00;
176     
177     /* Reset UserButton_Pressed variable */
178     UserButtonPressed = 0x00;
179     
180     /* Initialize LEDs to be managed by GPIO */
181     STM_EVAL_LEDInit(LED4);
182     STM_EVAL_LEDInit(LED3);
183     STM_EVAL_LEDInit(LED5);
184     STM_EVAL_LEDInit(LED6);
185     
186     /* SysTick end of count event each 10ms */
187     RCC_GetClocksFreq(&RCC_Clocks);
188     SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);  
189     
190     /* Turn OFF all LEDs */
191     STM_EVAL_LEDOff(LED4);
192     STM_EVAL_LEDOff(LED3);
193     STM_EVAL_LEDOff(LED5);
194     STM_EVAL_LEDOff(LED6);
195     
196     /* Waiting User Button is pressed */
197     while (UserButtonPressed == 0x00)
198     {
199       /* Toggle LED4 */
200       STM_EVAL_LEDToggle(LED4);
201       Delay(10);
202       /* Toggle LED4 */
203       STM_EVAL_LEDToggle(LED3);
204       Delay(10);
205       /* Toggle LED4 */
206       STM_EVAL_LEDToggle(LED5);
207       Delay(10);
208       /* Toggle LED4 */
209       STM_EVAL_LEDToggle(LED6);
210       Delay(10);
211       togglecounter ++;
212       if (togglecounter == 0x10)
213       {
214         togglecounter = 0x00;
215         while (togglecounter < 0x10)
216         {
217           STM_EVAL_LEDToggle(LED4);
218           STM_EVAL_LEDToggle(LED3);
219           STM_EVAL_LEDToggle(LED5);
220           STM_EVAL_LEDToggle(LED6);
221           Delay(10);
222           togglecounter ++;
223         }
224        togglecounter = 0x00;
225       }
226     }
227     
228     /* Waiting User Button is Released */
229     while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)
230     {}
231     UserButtonPressed = 0x00;
232     
233     /* TIM4 channels configuration */
234     TIM4_Config();
235     
236     /* Disable all Timer4 channels */
237     TIM_CCxCmd(TIM4, TIM_Channel_1, DISABLE);
238     TIM_CCxCmd(TIM4, TIM_Channel_2, DISABLE);
239     TIM_CCxCmd(TIM4, TIM_Channel_3, DISABLE);
240     TIM_CCxCmd(TIM4, TIM_Channel_4, DISABLE);
241
242     /* MEMS configuration */
243     LIS302DL_InitStruct.Power_Mode = LIS302DL_LOWPOWERMODE_ACTIVE;
244     LIS302DL_InitStruct.Output_DataRate = LIS302DL_DATARATE_100;
245     LIS302DL_InitStruct.Axes_Enable = LIS302DL_XYZ_ENABLE;
246     LIS302DL_InitStruct.Full_Scale = LIS302DL_FULLSCALE_2_3;
247     LIS302DL_InitStruct.Self_Test = LIS302DL_SELFTEST_NORMAL;
248     LIS302DL_Init(&LIS302DL_InitStruct);
249     
250     /* Required delay for the MEMS Accelerometre: Turn-on time = 3/Output data Rate 
251     = 3/100 = 30ms */
252     Delay(30);
253     
254     DemoEnterCondition = 0x01;
255     /* MEMS High Pass Filter configuration */
256     LIS302DL_FilterStruct.HighPassFilter_Data_Selection = LIS302DL_FILTEREDDATASELECTION_OUTPUTREGISTER;
257     LIS302DL_FilterStruct.HighPassFilter_CutOff_Frequency = LIS302DL_HIGHPASSFILTER_LEVEL_1;
258     LIS302DL_FilterStruct.HighPassFilter_Interrupt = LIS302DL_HIGHPASSFILTERINTERRUPT_1_2;
259     LIS302DL_FilterConfig(&LIS302DL_FilterStruct);
260     
261     LIS302DL_Read(Buffer, LIS302DL_OUT_X_ADDR, 6);
262     X_Offset = Buffer[0];
263     Y_Offset = Buffer[2];
264     Z_Offset = Buffer[4];
265     
266     /* USB configuration */
267     Demo_USBConfig();
268     
269     /* Waiting User Button is pressed */
270     while (UserButtonPressed == 0x00)
271     {}
272     
273     /* Waiting User Button is Released */
274     while (STM_EVAL_PBGetState(BUTTON_USER) == Bit_SET)
275     {}
276     
277     /* Disable SPI1 used to drive the MEMS accelerometre */
278     SPI_Cmd(LIS302DL_SPI, DISABLE);
279     
280     /* Disconnect the USB device */
281     DCD_DevDisconnect(&USB_OTG_dev);
282     USB_OTG_StopDevice(&USB_OTG_dev);
283   }
284 }
285
286 /**
287   * @brief  Initializes the USB for the demonstration application.
288   * @param  None
289   * @retval None
290   */
291 static uint32_t Demo_USBConfig(void)
292 {
293   USBD_Init(&USB_OTG_dev,
294             USB_OTG_FS_CORE_ID,
295             &USR_desc, 
296             &USBD_HID_cb, 
297             &USR_cb);
298   
299   return 0;
300 }
301
302 /**
303   * @brief  Configures the TIM Peripheral.
304   * @param  None
305   * @retval None
306   */
307 static void TIM4_Config(void)
308 {
309   GPIO_InitTypeDef GPIO_InitStructure;
310   TIM_OCInitTypeDef  TIM_OCInitStructure;
311   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
312   
313   /* --------------------------- System Clocks Configuration -----------------*/
314   /* TIM4 clock enable */
315   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
316   
317   /* GPIOD clock enable */
318   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
319
320   /*-------------------------- GPIO Configuration ----------------------------*/
321   /* GPIOD Configuration: Pins 12, 13, 14 and 15 in output push-pull */
322   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
323   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
324   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
325   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
326   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
327   GPIO_Init(GPIOD, &GPIO_InitStructure);
328
329   /* Connect TIM4 pins to AF2 */  
330   GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
331   GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); 
332   GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4);
333   GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4); 
334   
335     /* -----------------------------------------------------------------------
336     TIM4 Configuration: Output Compare Timing Mode:
337     
338     In this example TIM4 input clock (TIM4CLK) is set to 2 * APB1 clock (PCLK1), 
339     since APB1 prescaler is different from 1 (APB1 Prescaler = 4, see system_stm32f4xx.c file).
340       TIM4CLK = 2 * PCLK1  
341       PCLK1 = HCLK / 4 
342       => TIM4CLK = 2*(HCLK / 4) = HCLK/2 = SystemCoreClock/2
343          
344     To get TIM4 counter clock at 2 KHz, the prescaler is computed as follows:
345        Prescaler = (TIM4CLK / TIM1 counter clock) - 1
346        Prescaler = (168 MHz/(2 * 2 KHz)) - 1 = 41999
347                                         
348     To get TIM4 output clock at 1 Hz, the period (ARR)) is computed as follows:
349        ARR = (TIM4 counter clock / TIM4 output clock) - 1
350            = 1999
351                     
352     TIM4 Channel1 duty cycle = (TIM4_CCR1/ TIM4_ARR)* 100 = 50%
353     TIM4 Channel2 duty cycle = (TIM4_CCR2/ TIM4_ARR)* 100 = 50%
354     TIM4 Channel3 duty cycle = (TIM4_CCR3/ TIM4_ARR)* 100 = 50%
355     TIM4 Channel4 duty cycle = (TIM4_CCR4/ TIM4_ARR)* 100 = 50%
356     
357     ==> TIM4_CCRx = TIM4_ARR/2 = 1000  (where x = 1, 2, 3 and 4).
358   
359     Note: 
360      SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
361      Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
362      function to update SystemCoreClock variable value. Otherwise, any configuration
363      based on this variable will be incorrect.    
364   ----------------------------------------------------------------------- */ 
365   
366   
367   /* Compute the prescaler value */
368   PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 2000) - 1;
369   
370   /* Time base configuration */
371   TIM_TimeBaseStructure.TIM_Period = TIM_ARR;
372   TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
373   TIM_TimeBaseStructure.TIM_ClockDivision = 0;
374   TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
375   TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
376   
377   /* Enable TIM4 Preload register on ARR */
378   TIM_ARRPreloadConfig(TIM4, ENABLE);
379   
380   /* TIM PWM1 Mode configuration: Channel */
381   TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
382   TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
383   TIM_OCInitStructure.TIM_Pulse = TIM_CCR;
384   TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
385   
386   /* Output Compare PWM1 Mode configuration: Channel1 */
387   TIM_OC1Init(TIM4, &TIM_OCInitStructure);
388   TIM_CCxCmd(TIM4, TIM_Channel_1, DISABLE);
389   
390   TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
391   
392   /* Output Compare PWM1 Mode configuration: Channel2 */
393   TIM_OC2Init(TIM4, &TIM_OCInitStructure);
394   TIM_CCxCmd(TIM4, TIM_Channel_2, DISABLE);
395   
396   TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
397     
398   /* Output Compare PWM1 Mode configuration: Channel3 */
399   TIM_OC3Init(TIM4, &TIM_OCInitStructure);
400   TIM_CCxCmd(TIM4, TIM_Channel_3, DISABLE);
401   
402   TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
403   
404   /* Output Compare PWM1 Mode configuration: Channel4 */
405   TIM_OC4Init(TIM4, &TIM_OCInitStructure);
406   TIM_CCxCmd(TIM4, TIM_Channel_4, DISABLE);
407   
408   TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
409   
410   /* TIM4 enable counter */
411   TIM_Cmd(TIM4, ENABLE);
412 }
413
414 /**
415   * @brief  Inserts a delay time.
416   * @param  nTime: specifies the delay time length, in 10 ms.
417   * @retval None
418   */
419 void Delay(__IO uint32_t nTime)
420 {
421   TimingDelay = nTime;
422
423   while(TimingDelay != 0);
424 }
425
426 /**
427   * @brief  Decrements the TimingDelay variable.
428   * @param  None
429   * @retval None
430   */
431 void TimingDelay_Decrement(void)
432 {
433   if (TimingDelay != 0x00)
434   { 
435     TimingDelay--;
436   }
437 }
438
439 /**
440   * @brief  This function handles the test program fail.
441   * @param  None
442   * @retval None
443   */
444 void Fail_Handler(void)
445 {
446   /* Erase last sector */ 
447   FLASH_EraseSector(FLASH_Sector_11, VoltageRange_3);
448   /* Write FAIL code at last word in the flash memory */
449   FLASH_ProgramWord(TESTRESULT_ADDRESS, ALLTEST_FAIL);
450   
451   while(1)
452   {
453     /* Toggle Red LED */
454     STM_EVAL_LEDToggle(LED5);
455     Delay(5);
456   }
457 }
458
459 /**
460   * @brief  MEMS accelerometre management of the timeout situation.
461   * @param  None.
462   * @retval None.
463   */
464 uint32_t LIS302DL_TIMEOUT_UserCallback(void)
465 {
466   /* MEMS Accelerometer Timeout error occured during Test program execution */
467   if (DemoEnterCondition == 0x00)
468   {
469     /* Timeout error occured for SPI TXE/RXNE flags waiting loops.*/
470     Fail_Handler();    
471   }
472   /* MEMS Accelerometer Timeout error occured during Demo execution */
473   else
474   {
475     while (1)
476     {   
477     }
478   }
479   return 0;  
480 }
481
482 #ifdef  USE_FULL_ASSERT
483
484 /**
485   * @brief  Reports the name of the source file and the source line number
486   *   where the assert_param error has occurred.
487   * @param  file: pointer to the source file name
488   * @param  line: assert_param error line source number
489   * @retval None
490   */
491 void assert_failed(uint8_t* file, uint32_t line)
492
493   /* User can add his own implementation to report the file name and line number,
494      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
495
496   /* Infinite loop */
497   while (1)
498   {
499   }
500 }
501 #endif
502
503 /**
504   * @}
505   */
506
507
508 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/