2 ******************************************************************************
\r
3 * @file discover_functions.c
\r
4 * @author Microcontroller Division
\r
7 * @brief Discover demo functions
\r
8 ******************************************************************************
\r
11 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
\r
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
\r
13 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
\r
14 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
\r
15 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
\r
16 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
\r
18 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
\r
21 /* Includes ------------------------------------------------------------------*/
\r
23 /* stm32l1xxx std peripheral drivers headers*/
\r
24 #include "stm32l1xx_exti.h"
\r
27 /* touch sensing library headers*/
\r
28 //#include "stm32_tsl_api.h" -- superseded
\r
29 //#include "stm32l15x_tsl_ct_acquisition.h" -- superseded
\r
31 #include "tsl_user.h"
\r
32 /* discover application headers*/
\r
33 #include "discover_board.h"
\r
34 #include "discover_functions.h"
\r
35 #include "stm32l_discovery_lcd.h"
\r
36 #include "icc_measure.h"
\r
38 /*Variables placed in DataFlash */
\r
40 /* ADC converter value for Bias current value*/
\r
41 #if (defined ( __CC_ARM ))
\r
42 uint8_t Bias_Current __attribute__((at(0x08080000)));
\r
43 #elif (defined (__ICCARM__))
\r
44 uint8_t Bias_Current @ ".DataFlash" ;
\r
45 #elif (defined (__GNUC__))
\r
46 /* ADC converter value for Bias current value*/
\r
47 uint8_t Bias_Current __attribute__((section(".DataFlash")));
\r
50 /* Flag for autotest placed in Data Flash for return from RESET after STANDBY */
\r
51 #if (defined ( __CC_ARM ))
\r
52 bool self_test __attribute__((at(0x08080004)));
\r
53 #elif (defined (__ICCARM__))
\r
54 bool self_test @ ".DataFlash" ;
\r
55 #elif (defined (__GNUC__))
\r
56 /* Flag for autotest placed in Data Flash for return from RESET after STANDBY */
\r
57 bool self_test __attribute__((section(".DataFlash")));
\r
60 extern float Current_STBY;
\r
61 extern uint8_t t_bar[2];
\r
62 extern uint16_t Int_CurrentSTBY;
\r
64 /* Used for indicate that the automatic test is ON (set in interrupt handler).*/
\r
66 /* To indicate if user button function is actived*/
\r
68 /* Used for detect keypressed*/
\r
69 extern volatile bool KeyPressed;
\r
73 * @brief automatic test for VDD
\r
81 uint16_t Message[6];
\r
83 /* Display test name*/
\r
84 LCD_GLASS_DisplayString(" VDD ");
\r
86 /* get VDD voltage value */
\r
87 vdd_test = (int)Vref_measure();
\r
89 /* Check if value is correct */
\r
90 if ((vdd_test>VCC_MAX) || (vdd_test<VCC_MIN))
\r
92 /* if not correct stay in following infinit loop -- Press reset for exit */
\r
95 /* Display VDD ERROR message*/
\r
96 LCD_GLASS_ScrollSentence("VDD ERROR ",1,SCROLL_SPEED);
\r
98 /*convert vdd_test value in char and stor it into Message */
\r
99 convert_into_char (vdd_test, Message);
\r
100 /* Add unit and decimal point to Message */
\r
103 Message[1] |= DOT;
\r
105 /*Display Message*/
\r
106 LCD_GLASS_DisplayStrDeci(Message);
\r
111 /* Display VDD OK message*/
\r
112 LCD_GLASS_DisplayString("VDD OK");
\r
117 * @brief Automatic test current in Run Mode
\r
118 * @caller auto_test
\r
122 void test_icc_Run(void)
\r
125 uint16_t Message[6];
\r
127 /* Display test name*/
\r
128 LCD_GLASS_DisplayString("RUN ");
\r
131 /* get ICC current value in RUN mode*/
\r
132 icc_test = (int)Icc_RUN();
\r
134 /* Check if value is correct */
\r
135 if ((icc_test>ICC_RUN_MAX) || (icc_test<ICC_RUN_MIN))
\r
137 /* if not correct stay in following infinit loop -- Press reset for exit */
\r
140 KeyPressed = FALSE;
\r
141 /* Display RUN ERROR message*/
\r
142 LCD_GLASS_ScrollSentence("RUN ERROR ",1,SCROLL_SPEED);
\r
144 /*convert icc_test value in char and stor it into tab */
\r
145 convert_into_char((uint32_t)(icc_test), Message);
\r
146 /* Add unit and decimal point to Message */
\r
151 /*Display Message*/
\r
152 LCD_GLASS_DisplayStrDeci(Message);
\r
157 /* Display RUN OK message*/
\r
158 LCD_GLASS_DisplayString("RUN OK");
\r
163 * @brief Automatic test bias value
\r
164 * @caller auto_test
\r
168 void test_Bias(void)
\r
171 /* Display test name*/
\r
172 LCD_GLASS_DisplayString("BIAS ");
\r
174 /* Get operational amplifier BIAS current value*/
\r
175 Current = Bias_Current * Vdd_appli()/ADC_CONV;
\r
177 display_MuAmp((uint32_t)Current);
\r
179 /* Check if value is correct */
\r
180 if ((Bias_Current > ICC_BIAS_MAX) || (Bias_Current == 0 ))
\r
182 /* if not correct stay in following infinit loop */
\r
185 KeyPressed = FALSE;
\r
186 /* Display BIAS ERROR message and BIAS current*/
\r
187 LCD_GLASS_ScrollSentence("BIAS ERROR ",1,SCROLL_SPEED);
\r
189 display_MuAmp((uint32_t)Current);
\r
194 /* Display BIAS OK message*/
\r
195 LCD_GLASS_DisplayString("BIASOK");
\r
200 * @brief Automatic test current in STOP Mode
\r
201 * @caller auto_test
\r
205 void test_icc_STOP(void)
\r
208 /* Display test name*/
\r
209 LCD_GLASS_DisplayString("STOP ");
\r
212 /* Get operational Icc current value in Stop mode no RTC*/
\r
213 icc_test = (int)Icc_Stop_NoRTC();
\r
215 /* Test if value is correct */
\r
216 if ((icc_test>ICC_STOP_MAX) || (icc_test<ICC_STOP_MIN))
\r
218 /* if not correct stay in following infinite loop */
\r
221 KeyPressed = FALSE;
\r
222 /* Display ICC STOP ERROR message*/
\r
223 LCD_GLASS_ScrollSentence("ICC STOP ERROR ",1,SCROLL_SPEED);
\r
225 /* Display ICC STOPvalue*/
\r
226 display_MuAmp((uint32_t)icc_test);
\r
231 /* Display STOP OK message*/
\r
232 LCD_GLASS_DisplayString("STOPOK");
\r
238 * @brief Automatic test current in STBY Mode
\r
239 * @caller auto_test
\r
243 void test_icc_STBY(void)
\r
245 /* Display test name*/
\r
246 LCD_GLASS_DisplayString("STBY ");
\r
248 /* Current value measured in Standby mode*/
\r
249 ADC_Icc_Test(MCU_STBY);
\r
250 /* No Return software reset performed in ADC_Icc_Test function */
\r
254 * @brief Run auto test
\r
259 void auto_test(void)
\r
261 uint16_t tab[6]={0x20,0x20,0x20,0x20,0x20,0x20};
\r
265 /* Switch off leds*/
\r
266 GPIO_LOW(LD_GPIO_PORT,LD_GREEN_GPIO_PIN);
\r
267 GPIO_LOW(LD_GPIO_PORT,LD_BLUE_GPIO_PIN);
\r
269 /* reset LCD bar indicator*/
\r
275 /* To display version */
\r
276 LCD_GLASS_DisplayString(" TEST ");
\r
279 LCD_GLASS_DisplayStrDeci(tab);
\r
283 /* And launch the tests*/
\r
290 /* Infinite loop: Press reset button at the end of test for exit*/
\r
293 LCD_GLASS_ScrollSentence("TEST OK ",1,SCROLL_SPEED);
\r
294 KeyPressed = FALSE;
\r
299 * @brief Second part of Run auto test (run after sw reset)
\r
300 * @caller main after RESET
\r
304 void auto_test_part2(void)
\r
306 float Current_STBY;
\r
308 /* Substract operational amplifier bias current from mesured standby current*/
\r
309 if ( Int_CurrentSTBY > Bias_Current )
\r
310 Int_CurrentSTBY -= Bias_Current;
\r
311 /* convert value in uA */
\r
312 Current_STBY = Int_CurrentSTBY * Vdd_appli()/ADC_CONV;
\r
313 Current_STBY *= 20L;
\r
314 /*Display Standby Icc current value*/
\r
315 display_MuAmp((uint32_t)Current_STBY);
\r
317 /* Test if value is correct */
\r
318 if ((Current_STBY > ICC_STBY_MAX) || (Current_STBY < ICC_STBY_MIN))
\r
320 /* if not correct stay in following infinite loop */
\r
323 KeyPressed = FALSE;
\r
324 /* Display ICC STBY error message */
\r
325 LCD_GLASS_ScrollSentence("ICC STBY ERROR ",1,SCROLL_SPEED);
\r
327 /* Display ICC STBY current */
\r
328 display_MuAmp((uint32_t)Current_STBY);
\r
333 /* Display ICC STBY test OK*/
\r
334 LCD_GLASS_DisplayString("STBYOK");
\r
337 /* Infinite loop: Press reset button at the end of autotest to restart application*/
\r
340 LCD_GLASS_ScrollSentence("TEST OK ",1,SCROLL_SPEED);
\r
341 KeyPressed = FALSE;
\r
345 * @brief Measures the BIAS current PJ1 Must be on OFF position
\r
350 void Bias_measurement(void)
\r
353 uint16_t MeasurINT;
\r
354 /* indicate that applicartion run in ** BIAS CURRENT ** mode */
\r
355 LCD_GLASS_ScrollSentence(" ** BIAS CURRENT ** JP1 OFF **",1,SCROLL_SPEED);
\r
357 /* Get operational amplifier Bias current value */
\r
358 MeasurINT = ADC_Icc_Test(MCU_STOP_NoRTC);
\r
360 /* convert mesured value in uA*/
\r
361 Current = MeasurINT * Vdd_appli()/ADC_CONV;
\r
364 /*display bias current value */
\r
365 display_MuAmp((uint32_t)Current);
\r
367 /* unlock E²Prom write access*/
\r
368 DATA_EEPROM_Unlock();
\r
370 /* Store the value in E²Prom for application needs*/
\r
371 DATA_EEPROM_FastProgramByte((uint32_t)&Bias_Current, MeasurINT) ;
\r
373 /* Lock back E²PROM write access */
\r
374 DATA_EEPROM_Lock();
\r
376 /* Infinite loop: BIAS current display -- Press reset button in order to restart application*/
\r
379 /* Get operational amplifier Bias current value */
\r
380 MeasurINT = ADC_Icc_Test(MCU_STOP_NoRTC);
\r
381 /* convert mesured value in uA*/
\r
382 Current = MeasurINT * Vdd_appli()/ADC_CONV;
\r
384 /*display bias current value */
\r
385 display_MuAmp((uint32_t)Current);
\r
391 * @brief converts a 32bit unsined int into ASCII
\r
392 * @caller several callers for display values
\r
393 * @param Number digit to displays
\r
394 * p_tab values in array in ASCII
\r
397 void convert_into_char(uint32_t number, uint16_t *p_tab)
\r
399 uint16_t units=0, tens=0, hundreds=0, thousands=0, misc=0;
\r
401 units = (((number%10000)%1000)%100)%10;
\r
402 tens = ((((number-units)/10)%1000)%100)%10;
\r
403 hundreds = (((number-tens-units)/100))%100%10;
\r
404 thousands = ((number-hundreds-tens-units)/1000)%10;
\r
405 misc = ((number-thousands-hundreds-tens-units)/10000);
\r
407 *(p_tab+4) = units + 0x30;
\r
408 *(p_tab+3) = tens + 0x30;
\r
409 *(p_tab+2) = hundreds + 0x30;
\r
410 *(p_tab+1) = thousands + 0x30;
\r
411 *(p_tab) = misc + 0x30;
\r
416 * @brief Function to return the VDD measurement
\r
417 * @caller All measurements: VDD display or Current
\r
419 * Method for VDD measurement:
\r
420 * The VREFINT is not stored in memory.
\r
422 * Vdd_appli = (Theorical_Vref/Vref mesure) * ADC_Converter
\r
423 * Theorical_Vref = 1.224V
\r
424 * ADC_Converter 4096
\r
425 * ---> LSBIdeal = VREF/4096 or VDA/4096
\r
427 * @retval VDD measurements
\r
429 float Vdd_appli(void)
\r
431 uint16_t MeasurINT ;
\r
433 float f_Vdd_appli ;
\r
435 /*Read the BandGap value on ADC converter*/
\r
436 MeasurINT = ADC_Supply();
\r
438 /* We use the theorical value */
\r
439 f_Vdd_appli = (VREF/MeasurINT) * ADC_CONV;
\r
441 /* convert Vdd_appli into mV */
\r
442 f_Vdd_appli *= 1000L;
\r
444 return f_Vdd_appli;
\r
448 * @brief Function to measure VDD
\r
451 * @retval Vdd value in mV
\r
453 uint16_t Vref_measure(void)
\r
458 Vdd_mV = (uint16_t)Vdd_appli();
\r
460 convert_into_char (Vdd_mV, tab);
\r
462 /* To add unit and decimal point */
\r
465 tab[1] |= DOT; /* To add decimal point for display in volt */
\r
468 LCD_GLASS_DisplayStrDeci(tab);
\r
474 * @brief funtion to display the current in µA
\r
475 * @caller several funcions
\r
476 * @param Current value.
\r
479 void display_MuAmp (uint32_t Current)
\r
483 convert_into_char(Current, tab);
\r
487 /* Test the significant digit for displays 3 or 4 digits*/
\r
488 if ( tab[0] != '0')
\r
490 tab[1] |= DOT; /* To add decimal point */
\r
492 /* To shift for suppress '0' before decimal */
\r
500 LCD_GLASS_DisplayStrDeci(tab);
\r
504 * @brief funtion Current measurement in RUN mode
\r
505 * @caller main and test_icc_RUN
\r
507 * @retval Current (mA)
\r
509 float Icc_RUN(void)
\r
512 uint16_t MeasurINT;
\r
514 /* Get Icc current value in Run mode*/
\r
515 MeasurINT = ADC_Icc_Test(MCU_RUN);
\r
516 /* Convert value in mA*/
\r
517 Current = MeasurINT * Vdd_appli()/ADC_CONV;
\r
519 /* Convert value in ASCII and store it into tab*/
\r
520 convert_into_char((uint32_t)(Current), tab);
\r
521 /* Add unit and decimal point */
\r
526 /* Display mesured value */
\r
527 LCD_GLASS_DisplayStrDeci(tab);
\r
533 * @brief funtion Current measurement in SLEEP mode
\r
536 * @retval Current (mA)
\r
538 float Icc_SLEEP(void)
\r
541 uint16_t MeasurINT;
\r
544 /* Get Icc current value in Sleep mode*/
\r
545 MeasurINT = ADC_Icc_Test(MCU_SLEEP);
\r
546 /* Substract operational amplifier bias current from value*/
\r
547 Current = MeasurINT * Vdd_appli()/ADC_CONV;
\r
548 /* Convert value in mA*/
\r
550 /* Convert value in ASCII and store it into tab*/
\r
551 convert_into_char((uint32_t)(Current), tab);
\r
552 /* Add unit and decimal point */
\r
557 /*Display mesured value */
\r
558 LCD_GLASS_DisplayStrDeci(tab);
\r
559 /* Return value in mA*/
\r
564 * @brief funtion Current measurement in Low power
\r
567 * @retval Current (uA)
\r
569 float Icc_LPRUN(void)
\r
572 uint16_t MeasurINT;
\r
574 /* Get Icc current value in Low power mode*/
\r
575 MeasurINT = ADC_Icc_Test(MCU_LP_RUN);
\r
576 /* Substract operational amplifier bias current from value*/
\r
577 if ( MeasurINT > Bias_Current )
\r
578 MeasurINT -= Bias_Current;
\r
579 /* Convert value in uA*/
\r
580 Current = MeasurINT * Vdd_appli()/ADC_CONV;
\r
582 /* Display mesured value */
\r
583 display_MuAmp((uint32_t)Current);
\r
584 /* Return value in uA*/
\r
589 * @brief funtion Current measurement in Low power
\r
592 * @retval Current (µA)
\r
594 float Icc_LPSLEEP(void)
\r
597 uint16_t MeasurINT;
\r
598 /* Get Icc current value in Low power sleep mode*/
\r
599 MeasurINT = ADC_Icc_Test(MCU_LP_SLEEP);
\r
600 /* Substract operational amplifier bias current from value*/
\r
601 if ( MeasurINT > Bias_Current )
\r
602 MeasurINT -= Bias_Current;
\r
603 /* Convert value in uA*/
\r
604 Current = MeasurINT * Vdd_appli()/ADC_CONV;
\r
606 /* Test if value is correct */
\r
607 if ((int) Current<MAX_CURRENT)
\r
609 /* if correct : Display mesured value */
\r
610 display_MuAmp((uint32_t)Current);
\r
612 /* if not correct : Display ERROR */
\r
614 LCD_GLASS_DisplayString("Error");
\r
616 /* Return value in uA*/
\r
621 * @brief funtion Current measurement in Stop mode with LCD ON
\r
622 * @caller main and test_icc_LCD
\r
624 * @retval Current (µA)
\r
626 float Icc_STOP(void)
\r
629 uint16_t MeasurINT;
\r
631 /* Get Icc current value in STOP mode*/
\r
632 MeasurINT = ADC_Icc_Test(MCU_STOP_RTC);
\r
633 /* Substract operational amplifier bias current from value*/
\r
634 if ( MeasurINT > Bias_Current )
\r
635 MeasurINT -= Bias_Current;
\r
636 /* Convert value in uA*/
\r
637 Current = MeasurINT * Vdd_appli()/ADC_CONV;
\r
639 /* test if value is correct */
\r
640 if ((int) Current<MAX_CURRENT)
\r
642 /* if correct : Display mesured value */
\r
643 display_MuAmp((uint32_t)Current);
\r
647 /* if not correct : Display error if not in autotest */
\r
651 LCD_GLASS_DisplayString("Error");
\r
654 /* Return value in uA*/
\r
659 * @brief funtion Current measurement in Stop mode with LCD OFF
\r
664 float Icc_Stop_NoRTC(void)
\r
667 uint16_t MeasurINT;
\r
669 /* Get Icc current value in STOP mode with no RTC */
\r
670 MeasurINT = ADC_Icc_Test(MCU_STOP_NoRTC);
\r
671 /* Substract operational amplifier bias current from value*/
\r
672 if ( MeasurINT > Bias_Current )
\r
673 MeasurINT -= Bias_Current;
\r
674 /* Convert value in uA*/
\r
675 Current = MeasurINT * Vdd_appli()/ADC_CONV;
\r
677 /* Display mesured value */
\r
678 display_MuAmp((uint32_t)Current);
\r
679 /* Return value in uA*/
\r
683 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
\r