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