comparison Discovery/Src/base.c @ 38:5f11787b4f42

include in ostc4 repository
author heinrichsweikamp
date Sat, 28 Apr 2018 11:52:34 +0200
parents
children ff7775cc34c4 f561c79b0546
comparison
equal deleted inserted replaced
37:ccc45c0e1ea2 38:5f11787b4f42
1 ///////////////////////////////////////////////////////////////////////////////
2 /// -*- coding: UTF-8 -*-
3 ///
4 /// \file Discovery/Src/base.c
5 /// \brief main(): init hardware, IRQs and start sub-systems
6 /// \author heinrichs weikamp gmbh
7 /// \date 26-February-2014
8 ///
9 /// $Id$
10 ///////////////////////////////////////////////////////////////////////////////
11 /// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh
12 ///
13 /// This program is free software: you can redistribute it and/or modify
14 /// it under the terms of the GNU General Public License as published by
15 /// the Free Software Foundation, either version 3 of the License, or
16 /// (at your option) any later version.
17 ///
18 /// This program is distributed in the hope that it will be useful,
19 /// but WITHOUT ANY WARRANTY; without even the implied warranty of
20 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 /// GNU General Public License for more details.
22 ///
23 /// You should have received a copy of the GNU General Public License
24 /// along with this program. If not, see <http://www.gnu.org/licenses/>.
25 //////////////////////////////////////////////////////////////////////////////
26
27 /**
28 @verbatim
29 ==============================================================================
30 ##### Firmware Info #####
31 ==============================================================================
32 [..] In settings.c including text and magic stuff
33 ==============================================================================
34 ##### IRQs #####
35 ==============================================================================
36 [..] The IRQs are very important and most functions should only run there.
37
38 PreemptPriority are as follows
39 (#) 2 (low) sprintf _only_ here. Don't use in maintask or anywhere else.
40 Called by Buttons und Timer3
41 Timer3 is 1/10 second
42 (#) 1 (mid) anything that should work while in IRQ2 like HalDelay(), VSYNC
43 and DMA2D Transfer Complete for housekeepingFrame();
44 (#) 0 (high) _very very short_ interrupts like The HAL hardware part for
45 spi, uart, i2c.
46
47 SubPriority within PreemptPriority give the order to execute.
48 Introduced 30.Oct.14 as it used by several HAL examples.
49 Three levelAmbients are available (2 low,1 mid,0 high)
50
51 The STM32F4 has 4bits for IRQ levelAmbients, divided 2/2 in this code
52 with the NVIC_PRIORITYGROUP_2 setting.
53
54 ==============================================================================
55 ##### MainTask #####
56 ==============================================================================
57 [..] For everthing slow without importance to be 'in time'.
58 Like VPM and Buehlmann.
59 No sprintf and probably no GFX_SetFramesTopBottom() stuff neither.
60 If sprintf is called while sprintf is executed it blows up everything.
61
62 ==============================================================================
63 ##### Frames / the external SDRAM #####
64 ==============================================================================
65 [..] The SDRAM is handled by getFrame() and releaseFrame().
66 Each frame with 800*480*2 Bytes.
67 Be carefull to release every frame
68 otherwise there will be a memory leakage over time.
69 housekeepingFrame() in the MainTask takes care of cleaning the frames.
70 All frames are filled with 0x00. This will be transparent with color of
71 CLUT_Font020 (is CLUT 0) if the alpha is set for a 16bit pair.
72 housekeepingFrame() delays the cleaning of frames still used as screen
73 buffer to prevent flickering.
74
75 [..] use global variable frameCounter[] in gfxengine.c to control memory
76 all but the last three are identical to caller_id
77 for example 0x05 are the menu frames
78 the last but one is a sum for higher numbers (shouldn't be any)
79 the last but one are those in status RELEASED
80 the last are those CLEAR (as of 151202 down to 4 in logbook mode)
81
82 [..] 4 pages are used for two double memories for screenshots (since Nov. 15)
83
84 ==============================================================================
85 ##### Display #####
86 ==============================================================================
87 [..] There is a Top layer, Bottom layer and background color.
88 All are perfectly alpha-blended by hardware.
89
90 (#) top layer has 800x480 option function calls only
91 as it is not used for cursors here
92 (#) bottom layer has free size and start option to be used
93 for cursors (or sprites in the future ;-)
94 (#) background only black in the moment.
95 ToDo: Could be anything else for warnings etc.
96 if needed
97
98 [..] Frame updates, switching and cursors is done with
99
100 (#) GFX_SetFramesTopBottom() and the subset
101 GFX_SetFrameTop() + GFX_SetFrameBottom()
102 Those do not change anything on the display but give commands to..
103 (#) GFX_change_LTDC() The only place that changes the pointer.
104 This prevents erratic behaviour if several changes
105 are made within one refresh rate of the screen.
106 Is called in IRQ by PD4 and HAL_GPIO_EXTI_IRQHandler
107 from VSYNC signal.
108
109 [..] Content
110
111 (#) Colors by LookupTable only. This could be modified by
112 system settings in the future. (gfx_color.h/.c)
113
114 (#) Text by text_multilinguage.h/.c with one char
115 necessary only starting from '\x80'
116 with automatic language switch by
117 selected_language in SSettings
118 see openEdit_Language() in tMenuEditSystem.c
119 Therefore there are differnent functions
120 for example:
121 write_label_fix() for single char multilanguage
122 write_label_var() for strings that could include
123 multilanguage as well
124 see GFX_write_string() to get an overview of the controls
125 as well as the command list in gfx_engine.h
126 There is no clear before writing, text overlay is always on.
127 Many options to have LargeFont.SmallFont for numbers etc.
128
129 ==============================================================================
130 ##### Update, DualBoot and build-in FLASH memory usage #####
131 ==============================================================================
132 [..] Boot0 pin, Boot1/PB2 pin and BFB2 software bit control the behaviour.
133 PB2 should be tied to GND.
134 Boot0 == VDD -> bootloader on start, otherwise boot from Bank1 or Bank2
135 depending on BFB2.
136 Bank2 contains the Fonts and should contain a proper test code in future
137 Bank1 is the main code (Bank1 is 1 MB too, usage as of Oct. 14 is 200 KB)
138 [..] Bootloader should be either UART or USB (on FS pins _only_)
139 USB HS to FS like on the Eval board does not work.
140 [..] Bootloader for the smaller CPU2 is implemented via the SPI used for DMA copy.
141
142 ==============================================================================
143 ##### Connection to CPU2 (STM32F411 as of Oct.14 #####
144 ==============================================================================
145 [..] Connected via SPI and DMA for every purpose.
146 two entire arrays are transfered for data security reasons
147 with respect to master (STM32F429) might interrupt internal
148 data copy in CPU2 (like hi byte, low byte, etc.).
149 [..] The entire life data is calculated in CPU2. Like tissues, CNS,...
150 Therefore the main unit is _not_ necessarily a Real Time system.
151 Simulation on the main unit can be executed without disrupting life data.
152 [..] SPI is triggered and timed by calling DataEX_call() in data_exchange_main.c
153 DataEX_copy_to_LifeData() does the transfer from buffer to variables used.
154
155 ==============================================================================
156 ##### Menu, MenuEdit, Info #####
157 ==============================================================================
158 [..] tMenu.c, tMenuEdit.c and tInfo.c is the system used.
159 logbook is part of Info not Menu.
160 The Info Menu is accessed by button 'Back'
161 The regular Menu is accessed by button 'Enter'
162 [..] Menu content is kept in frame memory for fast access.
163 There is no need to build pages if the 'Enter' button is pressed.
164 This is in contrast to MenuEdit pages.
165 [..] Button control for new pages (and pages in general) have to implemented
166 in tMenu.c, tMenuEdit.c or tInfo.c
167
168 [..] ToDo (Oct. 14) Timeout for menus via Timer3 / IRQ 2
169
170 ==============================================================================
171 ##### settings #####
172 ==============================================================================
173 [..] files: settings.c, settings.h
174 1. adjust struct SSettings in settings.h
175 2. adjust const SSettings SettingsStandard in settings.c
176 3. adjust set_new_settings_missing_in_ext_flash()
177 4. adjust check_and_correct_settings() IMPORTANT as it changes values!
178
179 ==============================================================================
180 ##### specials #####
181 ==============================================================================
182 [..] There was code for vector graphics from great demos
183 (peridiummmm and jupiter) that can be fitted again
184
185 ==============================================================================
186 ##### ppO2 sensors #####
187 ==============================================================================
188 [..] in tCCR.c is function get_ppO2SensorWeightedResult_cbar();
189
190 @endverbatim
191 ******************************************************************************
192 * @attention
193 *
194 * <h2><center>&copy; COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
195 *
196 ******************************************************************************
197 */
198
199 /* Includes ------------------------------------------------------------------*/
200 #include "stdio.h"
201 #include <string.h> // for memcopy
202
203 #include "stm32f4xx_hal.h"
204 #include "ostc.h"
205 #include "base.h"
206 #include "display.h"
207 #include "gfx_engine.h"
208 #include "show_logbook.h"
209 //#include "test_vpm.h"
210 #include "text_multilanguage.h"
211 #include "tHome.h"
212 #include "tInfo.h"
213 #include "tInfoLog.h"
214 #include "tMenu.h"
215 #include "tMenuEdit.h"
216 #include "tMenuEditGasOC.h"
217 #include "tStructure.h"
218 //#include "gfx_specialeffects.h"
219 #include "externLogbookFlash.h"
220 #include "tComm.h"
221 #include "tCCR.h"
222 #include "data_exchange.h"
223 #include "data_exchange_main.h"
224 #include "vpm.h"
225 #include "buehlmann.h"
226 #include "logbook.h"
227 #include "check_warning.h"
228 #include "simulation.h"
229 #include "decom.h"
230 #include "timer.h"
231 #include "logbook_miniLive.h"
232 #include "test_vpm.h"
233 //#include "bonexConnect.h"
234 #include "tDebug.h"
235
236 #ifdef DEMOMODE
237 #include "demo.h"
238 static void TIM_DEMO_init(void);
239 #endif
240
241 //#include "lodepng.h"
242 //#include <stdlib.h> // for malloc and free
243
244 /** @addtogroup OSTC 4
245 * @{
246 */
247
248 /* Private typedef -----------------------------------------------------------*/
249
250 //#define NO_TIMEOUT
251 //#define QUICK_SLEEP
252
253 /* Private define ------------------------------------------------------------*/
254 //#define BUFFER_SIZE ((uint32_t)0x00177000)
255 //#define WRITE_READ_ADDR ((uint32_t)0x0000)
256 #define REFRESH_COUNT ((uint32_t)0x0569) /**< for SDRAM refresh counter (90Mhz SD clock) */
257
258 /* Private macro -------------------------------------------------------------*/
259 /* Private variables ---------------------------------------------------------*/
260
261 RTC_HandleTypeDef RtcHandle; /* used to change time and date, no RTC is running on this MCU */
262 TIM_HandleTypeDef TimHandle; /* used in stm32f4xx_it.c too */
263 TIM_HandleTypeDef TimBacklightHandle; /* used in stm32f4xx_it.c too */
264 TIM_HandleTypeDef TimDemoHandle; /* used in stm32f4xx_it.c too */
265
266 /*
267 uint32_t time_before;
268 uint32_t time_between;
269 uint32_t time_after;
270 */
271
272 /* SDRAM handler declaration */
273 SDRAM_HandleTypeDef hsdram;
274 FMC_SDRAM_TimingTypeDef SDRAM_Timing;
275 FMC_SDRAM_CommandTypeDef command;
276
277 /* This was used for Dual Boot */
278 //FLASH_OBProgramInitTypeDef OBInit;
279 //FLASH_AdvOBProgramInitTypeDef AdvOBInit;
280
281 /* Private variables with external access ------------------------------------*/
282
283 uint32_t globalStateID = 0;
284 uint8_t globalModeID = SURFMODE;
285 uint32_t time_without_button_pressed_deciseconds = 0; /**< langbeschreibung (eigenes Feld) warum diese variable verwendet wird um den sleepmode zu aktivieren */
286 uint8_t bootToBootloader = 0; ///< set in tComm.c to install firmware updates, calls resetToFirmwareUpdate()
287 //uint8_t dataEx_VPM_call = 0;
288 uint8_t returnFromCommCleanUpRequest = 0; ///< use this to exit bluetooth mode and call tComm_exit()
289 uint32_t base_tempLightLevel = 0;
290 uint8_t updateButtonsToDefault = 0;
291 uint8_t wasFirmwareUpdateCheckBattery = 0;
292
293 /* Private function prototypes -----------------------------------------------*/
294
295 static void SystemClock_Config(void);
296 static void Error_Handler(void);
297 static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command);
298 static void SDRAM_Config(void);
299 static void EXTILine_Buttons_Config(void);
300 static void TIM_init(void);
301 static void TIM_BACKLIGHT_init(void);
302 static uint32_t TIM_BACKLIGHT_adjust(void);
303 static void gotoSleep(void);
304 static void deco_loop(void);
305 static void resetToFirmwareUpdate(void);
306
307 /* ITM Trace-------- ---------------------------------------------------------*/
308 /*
309 #define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n)))
310 #define ITM_Port16(n) (*((volatile unsigned short*)(0xE0000000+4*n)))
311 #define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))
312
313 #define DEMCR (*((volatile unsigned long *)(0xE000EDFC)))
314 #define TRCENA 0x01000000
315
316 struct __FILE { int handle; };
317 FILE __stdout;
318 FILE __stdin;
319
320 int fputc(int ch, FILE *f) {
321 if (DEMCR & TRCENA) {
322 while (ITM_Port32(0) == 0);
323 ITM_Port8(0) = ch;
324 }
325 return(ch);
326 }
327 */
328
329 // ===============================================================================
330 // main
331 /// @brief This function makes initializations and has the nonIRQ endless loop
332 /// for bluetooth and deco calculations
333 ///
334 // ===============================================================================
335 int main(void)
336 {
337 uint32_t pLayerInvisible;
338 uint16_t totalDiveCounterFound;
339
340 set_globalState( StBoot0 );
341
342 HAL_Init();
343 HAL_NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_2 );
344
345 SystemClock_Config();
346
347 MX_GPIO_Init();
348 // MX_SmallCPU_NO_Reset_Helper(); //161116 hw
349 MX_SPI_Init();
350 MX_UART_Init();
351 SDRAM_Config();
352 HAL_Delay( 100 );
353 GFX_init( &pLayerInvisible );
354
355 TIM_init();
356 TIM_BACKLIGHT_init();
357
358 /*
359 GFX_helper_font_memory_list(&FontT24);
360 GFX_helper_font_memory_list(&FontT42);
361 GFX_helper_font_memory_list(&FontT48);
362 GFX_helper_font_memory_list(&FontT54);
363 GFX_helper_font_memory_list(&FontT84);
364 GFX_helper_font_memory_list(&FontT105);
365 GFX_helper_font_memory_list(&FontT144);
366 */
367
368 stateRealGetPointerWrite()->lastKnownBatteryPercentage = 0; // damit das nicht in settings kopiert wird.
369 set_settings_to_Standard();
370 mod_settings_for_first_start_with_empty_ext_flash();
371 ext_flash_read_settings();
372 if( newFirmwareVersionCheckViaSettings() ) // test for old firmware version in loaded settings
373 {
374 wasFirmwareUpdateCheckBattery = 1;
375 set_settings_button_to_standard_with_individual_buttonBalance(); // will adapt individual values
376 }
377 //settingsGetPointer()->bluetoothActive = 0; /* MX_Bluetooth_PowerOff(); unnecessary as part of MX_GPIO_Init() */
378 //settingsGetPointer()->compassBearing = 0;
379 set_new_settings_missing_in_ext_flash(); // inlcudes update of firmware version 161121
380
381 // new 170508: bluetooth on at start
382 settingsGetPointer()->bluetoothActive = 1;
383 MX_Bluetooth_PowerOn();
384
385 // Haase Geburtstag:
386 // settingsGetPointer()->serialHigh = (3012 / 256);
387 // settingsGetPointer()->serialLow = (3012 & 0xFF);
388
389 // settingsGetPointer()->showDebugInfo = 1;
390
391 /*
392 if(settingsGetPointer()->scooterControl)
393 {
394 settingsGetPointer()->bluetoothActive = 1;
395 MX_Bluetooth_PowerOn();
396 if(settingsGetPointer()->scooterDeviceAddress[0] != 0)
397 bC_setConnectRequest();
398 }
399 */
400 /*
401 if( (hardwareDataGetPointer()->primarySerial == 20+18)
402 || (hardwareDataGetPointer()->primarySerial == 20+25)
403 || (hardwareDataGetPointer()->primarySerial == 20+27))
404 {
405 MX_Bluetooth_PowerOn();
406 tComm_Set_Bluetooth_Name(1);
407 }
408 */
409 errorsInSettings = check_and_correct_settings();
410 createDiveSettings();
411
412 #ifdef QUICK_SLEEP
413 settingsGetPointer()->timeoutSurfacemode = 20;
414 #else
415 settingsGetPointer()->timeoutSurfacemode = 120;
416 #endif
417
418 #ifdef DEMOMODE
419 demoConfigureSettings();
420 TIM_DEMO_init();
421 #endif
422
423 // -----------------------------
424
425 display_power_on__1_of_2__pre_RGB();
426 GFX_LTDC_Init();
427 GFX_LTDC_LayerDefaultInit( TOP_LAYER, pLayerInvisible );
428 GFX_LTDC_LayerDefaultInit( BACKGRD_LAYER, pLayerInvisible );
429 GFX_SetFramesTopBottom( pLayerInvisible, pLayerInvisible, 480 );
430 HAL_Delay( 20 );
431 display_power_on__2_of_2__post_RGB();
432 GFX_use_colorscheme( settingsGetPointer()->tX_colorscheme );
433
434 // -----------------------------
435 tHome_init();
436 tI_init();
437 tM_init();
438 tMenuEdit_init();
439 tInfoLog_init();
440 tComm_init();
441 DataEX_init();
442 setButtonResponsiveness( settingsGetPointer()->ButtonResponsiveness );
443 set_globalState_tHome();
444
445 GFX_start_VSYNC_IRQ();
446 tCCR_init();
447
448 GFX_logoAutoOff();
449 EXTILine_Buttons_Config();
450
451 ext_flash_repair_dive_log();
452 //ext_flash_repair_SPECIAL_dive_numbers_starting_count_with(1);
453
454 totalDiveCounterFound = logbook_lastDive_diveNumber();
455 if( settingsGetPointer()->totalDiveCounter < totalDiveCounterFound )
456 settingsGetPointer()->totalDiveCounter = totalDiveCounterFound;
457
458 if( settingsGetPointer()->debugModeOnStart )
459 {
460 settingsGetPointer()->debugModeOnStart = 0;
461 ext_flash_write_settings();
462 setDebugMode();
463 openInfo( StIDEBUG );
464 }
465
466 /* @brief main LOOP
467 *
468 * this is executed while no IRQ interrupts it
469 * - deco calculation
470 * - bluetooth
471 * and resetToFirmwareUpdate()
472 * because tComm_control() does not exit before disconnection
473 */
474 while( 1 )
475 {
476 if( bootToBootloader )
477 resetToFirmwareUpdate();
478
479 // this will allways reset after RTE reset -> no good!
480 // if(DataEX_was_power_on()) // new to allow for update after RTE update
481 // resetToFirmwareUpdate();
482
483 tCCR_control();
484 if( tComm_control() )// will stop while loop if tComm Mode started until exit from UART
485 {
486 createDiveSettings();
487 updateMenu();
488 ext_flash_write_settings();
489 }
490 deco_loop();
491 /*
492 bonexControl();
493 if(bC_getStatus() == BC_DISCONNECTED)
494 {
495 if(tComm_control()) // will stop while loop if tComm Mode started until exit from UART
496 {
497 createDiveSettings();
498 updateMenu();
499 ext_flash_write_settings();
500 }
501 }
502 */
503 }
504 }
505
506 // ===============================================================================
507 // timer IRQ
508 /// @brief this is called periodically
509 ///
510 /// - refresh screen (the actual change is done in the VSYNC IRQ)
511 /// - start data transfer with RTE / small CPU (DateEX....)
512 /// - update logbook
513 /// - timeouts
514 /// ....
515 ///
516 /// all this in three steps / switch() routines in a given order
517 /// as the previous switch() might influence the next functions
518 /// to be called
519 ///
520 // ===============================================================================
521 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
522 {
523 #ifdef DEMOMODE
524 if(htim->Instance==TIM7)
525 {
526 HAL_GPIO_EXTI_Callback(demoGetCommand());
527 return;
528 }
529 #endif
530 static uint8_t last_base;
531
532 SStateList status;
533 uint32_t timeout_in_seconds;
534 uint32_t timeout_limit_Surface_in_seconds;
535
536 _Bool InDiveMode = 0;
537 _Bool modeChange = 0; // to exit from menu and logbook
538
539 if(stateUsed->mode == MODE_DIVE)
540 InDiveMode = 1;
541 else
542 InDiveMode = 0;
543
544 if(returnFromCommCleanUpRequest)
545 {
546 tComm_exit();
547 returnFromCommCleanUpRequest = 0;
548 }
549
550 get_globalStateList(&status);
551
552 switch(status.base)
553 {
554 case BaseHome:
555 case BaseMenu:
556 case BaseInfo:
557 updateSetpointStateUsed();
558 DateEx_copy_to_dataOut();
559 DataEX_call();
560 DataEX_copy_to_LifeData(&modeChange);
561 //foto session :-) stateRealGetPointerWrite()->lifeData.battery_charge = 99;
562 //foto session :-) stateSimGetPointerWrite()->lifeData.battery_charge = 99;
563 DataEX_copy_to_deco();
564 if(stateUsed == stateSimGetPointer())
565 simulation_UpdateLifeData(1);
566 check_warning();
567 if(stateUsed == stateRealGetPointer())
568 logbook_InitAndWrite();
569 updateMiniLiveLogbook(1);
570 timer_UpdateSecond(1);
571 base_tempLightLevel = TIM_BACKLIGHT_adjust();
572 tCCR_tick();
573 tHome_tick();
574 if(status.base == BaseHome)
575 tMenuEdit_writeSettingsToFlash(); // takes 900 ms!!
576 break;
577 case BaseStop:
578 DateEx_copy_to_dataOut();
579 DataEX_call();
580 DataEX_control_connection_while_asking_for_sleep();
581 break;
582 default:
583 case BaseComm:
584 if(get_globalState() == StUART_RTECONNECT)
585 {
586 DateEx_copy_to_dataOut();
587 DataEX_call();
588 DataEX_copy_to_LifeData(0);
589 }
590 break;
591 }
592
593 /* timeout control */
594 if(modeChange) ///< from RTE, set in data_exchange_main.c
595 time_without_button_pressed_deciseconds = (settingsGetPointer()->timeoutSurfacemode / 4) * 3;
596 if(status.base != last_base)
597 time_without_button_pressed_deciseconds = 0;
598 last_base = status.base;
599 timeout_in_seconds = time_without_button_pressed_deciseconds / 10;
600 time_without_button_pressed_deciseconds += 1;
601 if(modeChange || (timeout_in_seconds != time_without_button_pressed_deciseconds / 10))
602 {
603 #ifdef NO_TIMEOUT
604 timeout_in_seconds = 0;
605 #else
606 timeout_in_seconds += 1;
607 #endif
608
609 if(InDiveMode)
610 {
611 switch(status.base)
612 {
613 case BaseHome:
614 if((status.line != 0) && (timeout_in_seconds >= settingsGetPointer()->timeoutEnterButtonSelectDive))
615 {
616 set_globalState(StD);
617 timeout_in_seconds = 0;
618 }
619 break;
620
621 case BaseMenu:
622 if((status.line == 0) && ((timeout_in_seconds >= settingsGetPointer()->timeoutMenuDive) || modeChange))
623 {
624 exitMenu();
625 timeout_in_seconds = 0;
626 }
627 if((status.line != 0) && ((timeout_in_seconds >= settingsGetPointer()->timeoutMenuEdit) || modeChange))
628 {
629 exitMenuEdit_to_Home();
630 timeout_in_seconds = 0;
631 }
632 break;
633 /* why was this here? 160317 hw
634 case BaseInfo:
635 if(status.page == InfoPageLogList)
636 {
637 exitLog();
638 }
639 else
640 if(status.page == InfoPageLogShow)
641 {
642 show_logbook_exit();
643 exitLog();
644 }
645 else
646 if(status.page != InfoPageCompass)
647 {
648 exitInfo();
649 }
650 timeout_in_seconds = 0;
651 break;
652 */
653 default:
654 break;
655 }
656 }
657 else /* surface mode */
658 {
659 switch(status.base)
660 {
661 case BaseHome:
662 // added hw 161027
663 if(!(stateRealGetPointer()->warnings.lowBattery) && (stateRealGetPointer()->lifeData.battery_charge > 9))
664 {
665 stateRealGetPointerWrite()->lastKnownBatteryPercentage = stateRealGetPointer()->lifeData.battery_charge;
666 }
667 else if((wasFirmwareUpdateCheckBattery) && (timeout_in_seconds > 3))
668 {
669 wasFirmwareUpdateCheckBattery = 0;
670 setButtonResponsiveness(settingsGetPointer()->ButtonResponsiveness); // added 170306
671 if( (settingsGetPointer()->lastKnownBatteryPercentage > 0)
672 && (settingsGetPointer()->lastKnownBatteryPercentage <= 100)
673 && (stateRealGetPointer()->warnings.lowBattery))
674 {
675 setBatteryPercentage(settingsGetPointer()->lastKnownBatteryPercentage);
676 }
677 }
678 // stuff before and new @161121 CCR-sensor limit 10 minutes
679 if((settingsGetPointer()->dive_mode == DIVEMODE_CCR) && (settingsGetPointer()->CCR_Mode == CCRMODE_Sensors))
680 {
681 timeout_limit_Surface_in_seconds = settingsGetPointer()->timeoutSurfacemodeWithSensors;
682 }
683 else
684 {
685 timeout_limit_Surface_in_seconds = settingsGetPointer()->timeoutSurfacemode;
686 }
687 if(timeout_in_seconds >= timeout_limit_Surface_in_seconds)
688 {
689 gotoSleep();
690 }
691 break;
692 case BaseMenu:
693 if((status.line == 0) && ((timeout_in_seconds >= settingsGetPointer()->timeoutMenuSurface) || modeChange))
694 {
695 exitMenu();
696 timeout_in_seconds = 0;
697 }
698 if((status.line != 0) && ((timeout_in_seconds >= settingsGetPointer()->timeoutMenuEdit) || modeChange))
699 {
700 if((status.page != (uint8_t)((StMPLAN >> 24) & 0x0F)) || (timeout_in_seconds >= 10*(settingsGetPointer()->timeoutMenuEdit)))
701 {
702 exitMenuEdit_to_Home();
703 timeout_in_seconds = 0;
704 }
705 }
706 break;
707
708 case BaseInfo:
709 if((timeout_in_seconds >= settingsGetPointer()->timeoutInfo) || modeChange)
710 {
711 if(status.page == InfoPageLogList)
712 {
713 exitLog();
714 timeout_in_seconds = 0;
715 }
716 else
717 if(status.page == InfoPageLogShow)
718 {
719 show_logbook_exit();
720 exitLog();
721 timeout_in_seconds = 0;
722 }
723 else
724 if(status.page != InfoPageCompass)
725 {
726 exitInfo();
727 timeout_in_seconds = 0;
728 }
729 }
730 break;
731 default:
732 break;
733 }
734 }
735 }
736
737 get_globalStateList(&status);
738
739 switch(status.base)
740 {
741 case BaseHome:
742 tHome_refresh();
743 tM_check_content();
744 break;
745 case BaseMenu:
746 tM_refresh_live_content();
747 tMenuEdit_refresh_live_content();
748 break;
749 case BaseInfo:
750 tInfo_refresh(); ///< only compass at the moment 23.Feb.2015 hw
751 break;
752 case BaseComm:
753 tComm_refresh();
754 break;
755 default:
756 if(get_globalState() == StStop)
757 tHome_sleepmode_fun();
758 break;
759 }
760 }
761
762
763 /* button and VSYNC IRQ
764 *
765 * VSYNC will switch foreground and background picture
766 * if demanded. see GFX_change_LTDC()
767 *
768 */
769 // ===============================================================================
770 // HAL_GPIO_EXTI_Callback
771 /// @brief button and VSYNC IRQ
772 ///
773 /// VSYNC will switch foreground and background picture if demanded -
774 /// see GFX_change_LTDC()
775 ///
776 // ===============================================================================
777 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
778 {
779 if(!GPIO_Pin)
780 return;
781
782 uint8_t action = 0;
783 SStateList status;
784
785 if(GPIO_Pin == VSYNC_IRQ_PIN) // rechts, unten
786 {
787 GFX_change_LTDC();
788 housekeepingFrame();
789 /*
790 #ifdef DEMOMODE
791 static uint8_t countCall = 0;
792 if(countCall++ < 10)
793 return;
794 countCall = 0;
795 uint8_t buttonAction = demoGetCommand();
796 if(buttonAction)
797 GPIO_Pin = buttonAction;
798 else
799 #endif
800 */
801 return;
802 }
803
804 #ifdef DEMOMODE
805 uint8_t demoMachineCall = 0;
806 if(GPIO_Pin & 0x80)
807 {
808 demoMachineCall = 1;
809 GPIO_Pin &= 0x7F;
810 }
811 #endif
812
813 time_without_button_pressed_deciseconds = 0;
814
815 if(GFX_logoStatus() != 0)
816 return;
817
818 if(GPIO_Pin == BUTTON_BACK_PIN) // links
819 action = ACTION_BUTTON_BACK;
820 else
821 if(GPIO_Pin == BUTTON_ENTER_PIN) // mitte
822 action = ACTION_BUTTON_ENTER;
823 else
824 if(GPIO_Pin == BUTTON_NEXT_PIN) // rechts
825 action = ACTION_BUTTON_NEXT;
826 #ifdef BUTTON_CUSTOM_PIN
827 else
828 if(GPIO_Pin == BUTTON_CUSTOM_PIN) // extra
829 action = ACTION_BUTTON_CUSTOM;
830 #endif
831
832 #ifdef DEMOMODE // user pressed button ?
833 if((!demoMachineCall) && demoModeActive())
834 {
835 demoSendCommand(action);
836 return;
837 }
838 #endif
839
840 get_globalStateList(&status);
841
842 if(action == ACTION_BUTTON_CUSTOM)
843 {
844 GFX_screenshot();
845 }
846
847 switch(status.base)
848 {
849 case BaseStop:
850 if(action == ACTION_BUTTON_BACK)
851 resetToFirmwareUpdate();
852 break;
853 case BaseComm:
854 if(action == ACTION_BUTTON_BACK)
855 {
856 settingsGetPointer()->bluetoothActive = 0;
857 MX_Bluetooth_PowerOff();
858 tComm_exit();
859 }
860 break;
861 case BaseHome:
862 if(action == ACTION_BUTTON_NEXT)
863 {
864 if(status.page == PageSurface)
865 openMenu(1);
866 else
867 tHomeDiveMenuControl(action);
868 }
869 else
870 if(action == ACTION_BUTTON_BACK)
871 {
872 if(get_globalState() == StS)
873 openInfo(StILOGLIST);
874 else
875 if((status.page == PageDive) && (settingsGetPointer()->design < 7))
876 {
877 settingsGetPointer()->design = 7; // auto switch to 9 if necessary
878 }
879 else
880 if((status.page == PageDive) && (status.line != 0))
881 {
882 if(settingsGetPointer()->extraDisplay == EXTRADISPLAY_BIGFONT)
883 settingsGetPointer()->design = 3;
884 else
885 if(settingsGetPointer()->extraDisplay == EXTRADISPLAY_DECOGAME)
886 settingsGetPointer()->design = 4;
887
888 set_globalState(StD);
889 }
890 else
891 tHome_change_field_button_pressed();
892 }
893 else
894 if(action == ACTION_BUTTON_ENTER)
895 {
896 if((status.page == PageDive) && (status.line == 0))
897 tHome_change_customview_button_pressed();
898 else
899 if(status.page == PageSurface)
900 tHome_change_customview_button_pressed();
901 else
902 tHomeDiveMenuControl(action);
903 }
904 break;
905
906 case BaseMenu:
907 if(status.line == 0)
908 sendActionToMenu(action);
909 else
910 sendActionToMenuEdit(action);
911 break;
912
913 case BaseInfo:
914 if(status.page == InfoPageLogList)
915 sendActionToInfoLogList(action);
916 else
917 if(status.page == InfoPageLogShow)
918 sendActionToInfoLogShow(action);
919 else
920 sendActionToInfo(action);
921 break;
922
923 default:
924 break;
925 }
926 }
927
928
929 void gotoSleep(void)
930 {
931 /* not at the moment of testing */
932 // ext_flash_erase_firmware_if_not_empty();
933 GFX_logoAutoOff();
934 set_globalState(StStop);
935 }
936
937
938 // -----------------------------
939
940 uint8_t get_globalMode(void)
941 {
942 return globalModeID;
943 }
944
945
946 void set_globalMode(uint8_t newMode)
947 {
948 if((newMode != DIVEMODE) && (newMode != SURFMODE))
949 return;
950
951 globalModeID = newMode;
952 }
953
954
955 uint32_t get_globalState(void)
956 {
957 return globalStateID;
958 }
959
960
961 void get_globalStateList(SStateList *output)
962 {
963 output->base = (uint8_t)((globalStateID >> 28) & 0x0F);
964 output->page = (uint8_t)((globalStateID >> 24) & 0x0F);
965 output->line = (uint8_t)((globalStateID >> 16) & 0xFF);
966 output->field = (uint8_t)((globalStateID >> 8) & 0xFF);
967 output->mode = (uint8_t)((globalStateID ) & 0xFF);
968 }
969
970
971 void get_idSpecificStateList(uint32_t id, SStateList *output)
972 {
973 output->base = (uint8_t)((id >> 28) & 0x0F);
974 output->page = (uint8_t)((id >> 24) & 0x0F);
975 output->line = (uint8_t)((id >> 16) & 0xFF);
976 output->field = (uint8_t)((id >> 8) & 0xFF);
977 output->mode = (uint8_t)((id ) & 0xFF);
978 }
979
980
981 void set_globalState_Menu_Page(uint8_t page)
982 {
983 globalStateID = ((BaseMenu << 28) + (page << 24));
984 }
985
986 void set_globalState_Log_Page(uint8_t pageIsLine)
987 {
988 globalStateID = StILOGLIST + (pageIsLine << 16);
989 }
990
991
992 void set_globalState_Menu_Line(uint8_t line)
993 {
994 globalStateID = ((globalStateID & MaskLineFieldDigit) + (line << 16));
995 }
996
997
998 void set_globalState(uint32_t newID)
999 {
1000 globalStateID = newID;
1001 }
1002
1003 void set_returnFromComm(void)
1004 {
1005 returnFromCommCleanUpRequest = 1;
1006 }
1007
1008 uint8_t font_update_required(void)
1009 {
1010 uint8_t *fontVersionHigh;
1011 uint8_t *fontVersionLow;
1012
1013 fontVersionHigh = (uint8_t *)0x08132000;
1014 fontVersionLow = (uint8_t *)0x08132001;
1015
1016 if(FONTminimum_required_high() < *fontVersionHigh)
1017 return 0;
1018
1019 if((FONTminimum_required_high() == *fontVersionHigh) && (FONTminimum_required_low() <= *fontVersionLow))
1020 return 0;
1021
1022 return 1;
1023 }
1024
1025
1026 void delayMicros(uint32_t micros)
1027 {
1028 micros = micros * (168/4) - 10;
1029 while(micros--);
1030 }
1031
1032
1033 void get_RTC_DateTime(RTC_DateTypeDef * sdatestructureget, RTC_TimeTypeDef * stimestructureget)
1034 {
1035 /* Get the RTC current Time */
1036 if(sdatestructureget)
1037 HAL_RTC_GetTime(&RtcHandle, stimestructureget, FORMAT_BIN);
1038 /* Get the RTC current Date */
1039 if(stimestructureget)
1040 HAL_RTC_GetDate(&RtcHandle, sdatestructureget, FORMAT_BIN);
1041 }
1042
1043
1044 void set_RTC_DateTime(RTC_DateTypeDef * sdatestructure, RTC_TimeTypeDef * stimestructure)
1045 {
1046 if(sdatestructure)
1047 if(HAL_RTC_SetDate(&RtcHandle,sdatestructure,FORMAT_BCD) != HAL_OK)
1048 {
1049 /* Initialization Error */
1050 Error_Handler();
1051 }
1052
1053 if(stimestructure)
1054 if(HAL_RTC_SetTime(&RtcHandle,stimestructure,FORMAT_BCD) != HAL_OK)
1055 {
1056 /* Initialization Error */
1057 Error_Handler();
1058 }
1059 }
1060
1061 static void TIM_init(void)
1062 {
1063 uint16_t uwPrescalerValue = 0;
1064
1065 uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) - 1;
1066
1067 /* Set TIMx instance */
1068 TimHandle.Instance = TIMx;
1069
1070 /* Initialize TIM3 peripheral as follows:
1071 + Period = 10000 - 1
1072 + Prescaler = ((SystemCoreClock/2)/10000) - 1
1073 + ClockDivision = 0
1074 + Counter direction = Up
1075 */
1076 TimHandle.Init.Period = 1000 - 1;
1077 TimHandle.Init.Prescaler = uwPrescalerValue;
1078 TimHandle.Init.ClockDivision = 0;
1079 TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
1080 if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK)
1081 {
1082 /* Initialization Error */
1083 Error_Handler();
1084 }
1085
1086 /*##-2- Start the TIM Base generation in interrupt mode ####################*/
1087 /* Start Channel1 */
1088 if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)
1089 {
1090 /* Starting Error */
1091 Error_Handler();
1092 }
1093 }
1094
1095 #ifdef DEMOMODE
1096 static void TIM_DEMO_init(void)
1097 {
1098 uint16_t uwPrescalerValue = 0;
1099
1100 uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) - 1;
1101
1102 /* Set TIMx instance */
1103 TimDemoHandle.Instance = TIM7;
1104
1105 /* Initialize TIM3 peripheral as follows:
1106 + Period = 10000 - 1
1107 + Prescaler = ((SystemCoreClock/2)/10000) - 1
1108 + ClockDivision = 0
1109 + Counter direction = Up
1110 */
1111 TimDemoHandle.Init.Period = 1000 - 1;
1112 TimDemoHandle.Init.Prescaler = uwPrescalerValue;
1113 TimDemoHandle.Init.ClockDivision = 0;
1114 TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
1115 if(HAL_TIM_Base_Init(&TimDemoHandle) != HAL_OK)
1116 {
1117 /* Initialization Error */
1118 Error_Handler();
1119 }
1120
1121 /*##-2- Start the TIM Base generation in interrupt mode ####################*/
1122 /* Start Channel1 */
1123 if(HAL_TIM_Base_Start_IT(&TimDemoHandle) != HAL_OK)
1124 {
1125 /* Starting Error */
1126 Error_Handler();
1127 }
1128 }
1129 #endif
1130
1131
1132
1133 #ifndef TIM_BACKLIGHT
1134
1135 static uint32_t TIM_BACKLIGHT_adjust(void)
1136 {
1137 return 0;
1138 }
1139
1140 static void TIM_BACKLIGHT_init(void)
1141 {
1142 }
1143 #else
1144 static uint32_t TIM_BACKLIGHT_adjust(void)
1145 {
1146 static uint32_t levelActual = 12000;
1147 static uint8_t brightnessModeLast = 0;
1148 // static _Bool wasLostConnection = 0;
1149
1150 uint32_t levelAmbient;
1151 uint32_t levelMax;
1152 uint32_t levelMin;
1153 uint32_t levelUpStep_100ms = 200;
1154 uint32_t levelDnStep_100ms = 20;
1155
1156 TIM_OC_InitTypeDef sConfig;
1157 sConfig.OCMode = TIM_OCMODE_PWM1;
1158 sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
1159 sConfig.OCFastMode = TIM_OCFAST_DISABLE;
1160
1161 const SDiveState * pStateReal = stateRealGetPointer();
1162
1163
1164 // if(pStateReal->data_old__lost_connection_to_slave)
1165 // {
1166 // changed 160613 from 6000 to 12000
1167 // removed hw 161209
1168 // levelAmbient = 12000;
1169 // levelActual = 12000;
1170 // wasLostConnection = 1;
1171 // }
1172 // else
1173 // {
1174 SSettings *pSettings = settingsGetPointer();
1175 /* 300 - 4000 */
1176 /* important levelAmbient 300 - 1200 */
1177 levelAmbient = 10 * pStateReal->lifeData.ambient_light_level;
1178
1179 switch( pSettings->brightness)
1180 {
1181 case 0: /* Cave */
1182 levelMax = 3000;/* max 25 % (x2) */
1183 levelMin = 1500;
1184 break;
1185 case 1: /* Eco */
1186 levelMax = 6000;/* max 50 % (x2) */
1187 levelMin = 3000;
1188 break;
1189 case 2: /* Std */
1190 levelAmbient += 1000;
1191 levelMax = 9000;
1192 levelMin = 4500;
1193 levelUpStep_100ms += levelUpStep_100ms/2; // 4500 instead of 3000
1194 levelDnStep_100ms += levelDnStep_100ms/2;
1195 break;
1196 case 3: /* High */
1197 default:
1198 levelAmbient += 3000;
1199 levelMax = 12000; /* max 100% (x2) */
1200 levelMin = 6000;
1201 levelUpStep_100ms += levelUpStep_100ms; // 6000 instead of 3000
1202 levelDnStep_100ms += levelDnStep_100ms;
1203 break;
1204 case 4: /* New Max */
1205 levelAmbient = 12000;
1206 levelMax = 12000; /* max 100% (x2) */
1207 levelMin = 12000;
1208 levelUpStep_100ms += 12000;
1209 levelDnStep_100ms += 0;
1210 break;
1211 }
1212
1213 if((pSettings->brightness != brightnessModeLast))// || wasLostConnection)
1214 {
1215 levelActual = levelAmbient;
1216 brightnessModeLast = pSettings->brightness;
1217 // wasLostConnection = 0;
1218 }
1219 // }
1220
1221 if(levelAmbient > levelActual)
1222 levelActual += levelUpStep_100ms;
1223 else
1224 if((levelAmbient < levelActual) && (levelActual > levelMin) && (levelActual > levelDnStep_100ms))
1225 levelActual -= levelDnStep_100ms;
1226
1227 if(levelActual > levelMax)
1228 levelActual = levelMax;
1229 else
1230 if(levelActual < levelMin)
1231 levelActual = levelMin;
1232
1233 // sConfig.Pulse = levelActual / 20;
1234 sConfig.Pulse = (levelMin + ((levelMax - levelMin)/2)) / 20; // added 170306
1235
1236 /* xx - 600 */
1237 if(sConfig.Pulse > 600)
1238 sConfig.Pulse = 600;
1239 else
1240 if(sConfig.Pulse < 100)
1241 sConfig.Pulse = 100;
1242
1243 HAL_TIM_PWM_ConfigChannel(&TimBacklightHandle, &sConfig, TIM_BACKLIGHT_CHANNEL);
1244 HAL_TIM_PWM_Start(&TimBacklightHandle, TIM_BACKLIGHT_CHANNEL);
1245
1246 return levelActual;
1247 }
1248
1249 static void TIM_BACKLIGHT_init(void)
1250 {
1251 uint32_t uwPrescalerValue = 0;
1252 TIM_OC_InitTypeDef sConfig;
1253
1254 uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 18000000) - 1;
1255
1256 TimBacklightHandle.Instance = TIM_BACKLIGHT;
1257
1258 /* Initialize TIM3 peripheral as follows:
1259 30 kHz
1260 */
1261 TimBacklightHandle.Init.Period = 600 - 1;
1262 TimBacklightHandle.Init.Prescaler = uwPrescalerValue;
1263 TimBacklightHandle.Init.ClockDivision = 0;
1264 TimBacklightHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
1265 HAL_TIM_PWM_Init(&TimBacklightHandle);
1266
1267 sConfig.OCMode = TIM_OCMODE_PWM1;
1268 sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
1269 sConfig.OCFastMode = TIM_OCFAST_DISABLE;
1270 sConfig.Pulse = 50 * 6;
1271
1272 HAL_TIM_PWM_ConfigChannel(&TimBacklightHandle, &sConfig, TIM_BACKLIGHT_CHANNEL);
1273 HAL_TIM_PWM_Start(&TimBacklightHandle, TIM_BACKLIGHT_CHANNEL);
1274 }
1275 #endif
1276
1277
1278 static void EXTILine_Buttons_Config(void)
1279 {
1280 GPIO_InitTypeDef GPIO_InitStructure;
1281
1282 BUTTON_ENTER_GPIO_ENABLE();
1283 BUTTON_NEXT_GPIO_ENABLE();
1284 BUTTON_BACK_GPIO_ENABLE();
1285
1286 /* Configure pin as weak PULLUP input */
1287 /* buttons */
1288 GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
1289 GPIO_InitStructure.Pull = GPIO_NOPULL;
1290 GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
1291
1292 GPIO_InitStructure.Pin = BUTTON_ENTER_PIN;
1293 HAL_GPIO_Init(BUTTON_ENTER_GPIO_PORT, &GPIO_InitStructure);
1294
1295 GPIO_InitStructure.Pin = BUTTON_NEXT_PIN;
1296 HAL_GPIO_Init(BUTTON_NEXT_GPIO_PORT, &GPIO_InitStructure);
1297
1298 GPIO_InitStructure.Pin = BUTTON_BACK_PIN;
1299 HAL_GPIO_Init(BUTTON_BACK_GPIO_PORT, &GPIO_InitStructure);
1300
1301 /* Enable and set EXTI Line0 Interrupt to the lowest priority */
1302 HAL_NVIC_SetPriority(BUTTON_ENTER_EXTI_IRQn, 2, 0);
1303 HAL_NVIC_SetPriority(BUTTON_NEXT_EXTI_IRQn, 2, 0);
1304 HAL_NVIC_SetPriority(BUTTON_BACK_EXTI_IRQn, 2, 0);
1305 HAL_NVIC_EnableIRQ(BUTTON_ENTER_EXTI_IRQn);
1306 HAL_NVIC_EnableIRQ(BUTTON_NEXT_EXTI_IRQn);
1307 HAL_NVIC_EnableIRQ(BUTTON_BACK_EXTI_IRQn);
1308
1309 #ifdef BUTTON_CUSTOM_PIN
1310 BUTTON_CUSTOM_GPIO_ENABLE();
1311 GPIO_InitStructure.Pin = BUTTON_CUSTOM_PIN;
1312 HAL_GPIO_Init(BUTTON_CUSTOM_GPIO_PORT, &GPIO_InitStructure);
1313 HAL_NVIC_SetPriority(BUTTON_CUSTOM_EXTI_IRQn, 2, 0);
1314 HAL_NVIC_EnableIRQ(BUTTON_CUSTOM_EXTI_IRQn);
1315 #endif
1316 }
1317
1318
1319 /**
1320 * @brief System Clock Configuration
1321 * The system Clock is configured as follow :
1322 * System Clock source = PLL (HSE)
1323 * SYSCLK(Hz) = 180000000
1324 * HCLK(Hz) = 180000000
1325 * AHB Prescaler = 1
1326 * APB1 Prescaler = 4
1327 * APB2 Prescaler = 2
1328 * HSE Frequency(Hz) = 8000000
1329 * PLL_M = 8
1330 * PLL_N = 360
1331 * PLL_P = 2
1332 * PLL_Q = 7
1333 * VDD(V) = 3.3
1334 * Main regulator output voltage = Scale1 mode
1335 * Flash Latency(WS) = 5
1336 * The LTDC Clock is configured as follow :
1337 * PLLSAIN = 192
1338 * PLLSAIR = 4
1339 * PLLSAIDivR = 8
1340 * @param None
1341 * @retval None
1342 */
1343 static void SystemClock_Config(void)
1344 {
1345
1346 /* Enable Power Control clock */
1347 __PWR_CLK_ENABLE();
1348
1349 /* The voltage scaling allows optimizing the power consumption when the device is
1350 clocked below the maximum system frequency, to update the voltage scaling value
1351 regarding system frequency refer to product datasheet. */
1352 __HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );
1353
1354 /*##-1- System Clock Configuration #########################################*/
1355 /* Enable HighSpeed Oscillator and activate PLL with HSE/HSI as source */
1356 RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };
1357 #ifdef DISC1_BOARD
1358 // Use High Speed Internal (HSI) oscillator, running at 16MHz.
1359 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
1360 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
1361 RCC_OscInitStruct.HSICalibrationValue = 0x10;
1362 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
1363 RCC_OscInitStruct.PLL.PLLM = 16; // HSI/16 is 1Mhz.
1364 #else
1365 // Use High Speed External oscillator, running at 8MHz
1366 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
1367 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
1368 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
1369 RCC_OscInitStruct.PLL.PLLM = 8; // HSE/8 is 1Mhz.
1370 #endif
1371 // System clock = PLL (1MHz) * N/p = 180 MHz.
1372 RCC_OscInitStruct.PLL.PLLN = 360;
1373 RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
1374 RCC_OscInitStruct.PLL.PLLQ = 7;
1375 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
1376 HAL_RCC_OscConfig( &RCC_OscInitStruct );
1377
1378 // HAL_PWREx_ActivateOverDrive();
1379 HAL_PWREx_DeactivateOverDrive();
1380
1381 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
1382 RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };
1383 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK
1384 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
1385 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
1386 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
1387 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
1388 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
1389 HAL_RCC_ClockConfig( &RCC_ClkInitStruct, FLASH_LATENCY_8 ); //FLASH_LATENCY_5);
1390
1391 /*##-2- LTDC Clock Configuration ###########################################*/
1392 /* LCD clock configuration */
1393 /* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
1394 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */
1395 /* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/4 = 48 Mhz */
1396 /* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDIVR_8 = 48/8 = 6 Mhz */
1397
1398 /* neu: 8MHz/8*300/5/8 = 7,5 MHz = 19,5 Hz bei 800 x 480 */
1399 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
1400 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
1401 PeriphClkInitStruct.PLLSAI.PLLSAIN = 300; //192;
1402 PeriphClkInitStruct.PLLSAI.PLLSAIR = 5; //4;
1403 PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;//RCC_PLLSAIDIVR_4;// RCC_PLLSAIDIVR_2; // RCC_PLLSAIDIVR_8
1404 HAL_RCCEx_PeriphCLKConfig( &PeriphClkInitStruct );
1405 }
1406
1407
1408 /**
1409 * @brief This function is executed in case of error occurrence.
1410 * @param None
1411 * @retval None
1412 */
1413 static void Error_Handler(void)
1414 {
1415 /* Turn LED3 on */
1416 // BSP_LED_On(LED3);
1417 while(1)
1418 {
1419 }
1420 }
1421
1422 /**
1423 * @brief Perform the SDRAM exernal memory inialization sequence
1424 * @param hsdram: SDRAM handle
1425 * @param Command: Pointer to SDRAM command structure
1426 * @retval None
1427 */
1428 static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
1429 {
1430 __IO uint32_t tmpmrd =0;
1431 /* Step 3: Configure a clock configuration enable command */
1432 Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
1433 Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
1434 Command->AutoRefreshNumber = 1;
1435 Command->ModeRegisterDefinition = 0;
1436
1437 /* Send the command */
1438 HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
1439
1440 /* Step 4: Insert 100 ms delay */
1441 HAL_Delay(100);
1442
1443 /* Step 5: Configure a PALL (precharge all) command */
1444 Command->CommandMode = FMC_SDRAM_CMD_PALL;
1445 Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
1446 Command->AutoRefreshNumber = 1;
1447 Command->ModeRegisterDefinition = 0;
1448
1449 /* Send the command */
1450 HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
1451
1452 /* Step 6 : Configure a Auto-Refresh command */
1453 Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
1454 Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
1455 Command->AutoRefreshNumber = 4;
1456 Command->ModeRegisterDefinition = 0;
1457
1458 /* Send the command */
1459 HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
1460
1461 /* Step 7: Program the external memory mode register */
1462 tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
1463 SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
1464 SDRAM_MODEREG_CAS_LATENCY_3 |
1465 SDRAM_MODEREG_OPERATING_MODE_STANDARD |
1466 SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
1467
1468 Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
1469 Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
1470 Command->AutoRefreshNumber = 1;
1471 Command->ModeRegisterDefinition = tmpmrd;
1472
1473 /* Send the command */
1474 HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
1475
1476 /* Step 8: Set the refresh rate counter */
1477 /* (15.62 us x Freq) - 20 */
1478 /* neu: (8 us x Freq) - 20 */
1479 /* Set the device refresh counter */
1480 HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);
1481 }
1482
1483
1484 /**
1485 ******************************************************************************
1486 ******************************************************************************
1487 ******************************************************************************
1488 */
1489
1490
1491 /**
1492 * @brief DMA2D configuration.
1493 * @note This function Configure tha DMA2D peripheral :
1494 * 1) Configure the transfer mode : memory to memory W/ pixel format conversion
1495 * 2) Configure the output color mode as ARGB4444
1496 * 3) Configure the output memory address at SRAM memory
1497 * 4) Configure the data size : 320x120 (pixels)
1498 * 5) Configure the input color mode as ARGB8888
1499 * 6) Configure the input memory address at FLASH memory
1500 * @retval
1501 * None
1502 */
1503
1504 static void SDRAM_Config(void)
1505 {
1506 /*##-1- Configure the SDRAM device #########################################*/
1507 /* SDRAM device configuration */
1508 hsdram.Instance = FMC_SDRAM_DEVICE;
1509
1510 /* Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2) */
1511 /* TMRD: 2 Clock cycles */
1512 SDRAM_Timing.LoadToActiveDelay = 2;
1513 /* TXSR: min=70ns (6x11.90ns) */
1514 SDRAM_Timing.ExitSelfRefreshDelay = 7;
1515 /* TRAS: min=42ns (4x11.90ns) max=120k (ns) */
1516 SDRAM_Timing.SelfRefreshTime = 4;
1517 /* TRC: min=63 (6x11.90ns) */
1518 SDRAM_Timing.RowCycleDelay = 7;
1519 /* TWR: 2 Clock cycles */
1520 SDRAM_Timing.WriteRecoveryTime = 2;
1521 /* TRP: 15ns => 2x11.90ns */
1522 SDRAM_Timing.RPDelay = 2;
1523 /* TRCD: 15ns => 2x11.90ns */
1524 SDRAM_Timing.RCDDelay = 2;
1525
1526 hsdram.Init.SDBank = FMC_SDRAM_BANK2;
1527 hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;
1528 hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;
1529 hsdram.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;
1530 hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
1531 hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
1532 hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
1533 hsdram.Init.SDClockPeriod = SDCLOCK_PERIOD;
1534 hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
1535 hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;
1536
1537 /* Initialize the SDRAM controller */
1538 if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK)
1539 {
1540 /* Initialization Error */
1541 Error_Handler();
1542 }
1543
1544 /* Program the SDRAM external device */
1545 SDRAM_Initialization_Sequence(&hsdram, &command);
1546 }
1547
1548
1549 #ifdef USE_FULL_ASSERT
1550
1551 /**
1552 * @brief Reports the name of the source file and the source line number
1553 * where the assert_param error has occurred.
1554 * @param file: pointer to the source file name
1555 * @param line: assert_param error line source number
1556 * @retval None
1557 */
1558 void assert_failed(uint8_t* file, uint32_t line)
1559 {
1560 /* User can add his own implementation to report the file name and line number,
1561 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
1562
1563 /* Infinite loop */
1564 while (1)
1565 {
1566 }
1567 }
1568 #endif
1569
1570
1571 void deco_loop(void)
1572 {
1573 typedef enum
1574 {
1575 CALC_VPM,
1576 CALC_VPM_FUTURE,
1577 CALC_BUEHLMANN,
1578 CALC_BUEHLMANN_FUTURE,
1579 } CALC_WHAT;
1580
1581 static int what = -1;
1582 int counter = 0;
1583 if((stateUsed->mode != MODE_DIVE) || (stateUsed->diveSettings.diveMode == DIVEMODE_Apnea) || (decoLock != DECO_CALC_ready ))
1584 return;
1585
1586 decoLock = DECO_CALC_running;
1587
1588 if(stateDeco.diveSettings.deco_type.ub.standard == GF_MODE)
1589 {
1590 // hw 151110 mh wants future TTS even in deco zone if((what == CALC_BUEHLMANN) && (stateDeco.lifeData.pressure_ambient_bar > stateDeco.diveSettings.internal__pressure_first_stop_ambient_bar_as_upper_limit_for_gf_low_otherwise_zero))
1591 if(what == CALC_BUEHLMANN)
1592 {
1593 //Calc future
1594 what = CALC_BUEHLMANN_FUTURE;
1595 }
1596 else
1597 what = CALC_BUEHLMANN;
1598
1599 }
1600 else
1601 {
1602 // hw 151110 mh wants future TTS even in deco zone if((what == CALC_VPM) && (!stateDeco.vpm.deco_zone_reached))
1603 if(what == CALC_VPM)
1604 {
1605 //Calc future
1606 what = CALC_VPM_FUTURE;
1607 }
1608 else
1609 what = CALC_VPM;
1610 }
1611
1612 //In one of ten calc the other option
1613 if(counter == 10)
1614 {
1615 if(what == CALC_VPM)
1616 what = CALC_BUEHLMANN;
1617 if(what == CALC_BUEHLMANN)
1618 what = CALC_VPM;
1619 counter = 0;
1620 }
1621
1622 decom_CreateGasChangeList(&stateDeco.diveSettings, &stateDeco.lifeData);
1623
1624 switch(what)
1625 {
1626 case CALC_VPM:
1627 vpm_calc(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.vpm,&stateDeco.decolistVPM, DECOSTOPS);
1628 decoLock = DECO_CALC_FINSHED_vpm;
1629 return;
1630 case CALC_VPM_FUTURE:
1631 decom_tissues_exposure(stateDeco.diveSettings.future_TTS_minutes * 60,&stateDeco.lifeData);
1632 vpm_calc(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.vpm,&stateDeco.decolistFutureVPM, FUTURESTOPS);
1633 decoLock = DECO_CALC_FINSHED_Futurevpm;
1634 return;
1635 case CALC_BUEHLMANN:
1636 buehlmann_calc_deco(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.decolistBuehlmann);
1637 buehlmann_ceiling_calculator(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.decolistBuehlmann);
1638 buehlmann_relative_gradient_calculator(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.decolistBuehlmann);
1639 decoLock = DECO_CALC_FINSHED_Buehlmann;
1640 return;
1641 case CALC_BUEHLMANN_FUTURE:
1642 decom_tissues_exposure(stateDeco.diveSettings.future_TTS_minutes * 60,&stateDeco.lifeData);
1643 buehlmann_calc_deco(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.decolistFutureBuehlmann);
1644 //buehlmann_ceiling_calculator(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.decolistBuehlmann);
1645 decoLock = DECO_CALC_FINSHED_FutureBuehlmann;
1646 return;
1647 }
1648 counter++;
1649 }
1650
1651 void resetToFirmwareUpdate(void)
1652 {
1653 __HAL_RCC_CLEAR_RESET_FLAGS();
1654 HAL_NVIC_SystemReset();
1655 }
1656
1657 // debugging by https://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/
1658
1659 /*
1660 void printErrorMsg(const char * errMsg)
1661 {
1662
1663 // printf(errMsg);
1664 // return;
1665
1666 while(*errMsg != 0){
1667 ITM_SendChar(*errMsg);
1668 ++errMsg;
1669 }
1670 }
1671
1672 enum { r0, r1, r2, r3, r12, lr, pc, psr};
1673
1674 void stackDump(uint32_t stack[])
1675 {
1676 static char msg[80];
1677 sprintf(msg, "r0 = 0x%08x\n", stack[r0]); printErrorMsg(msg);
1678 sprintf(msg, "r1 = 0x%08x\n", stack[r1]); printErrorMsg(msg);
1679 sprintf(msg, "r2 = 0x%08x\n", stack[r2]); printErrorMsg(msg);
1680 sprintf(msg, "r3 = 0x%08x\n", stack[r3]); printErrorMsg(msg);
1681 sprintf(msg, "r12 = 0x%08x\n", stack[r12]); printErrorMsg(msg);
1682 sprintf(msg, "lr = 0x%08x\n", stack[lr]); printErrorMsg(msg);
1683 sprintf(msg, "pc = 0x%08x\n", stack[pc]); printErrorMsg(msg);
1684 sprintf(msg, "psr = 0x%08x\n", stack[psr]); printErrorMsg(msg);
1685 }
1686
1687 void printUsageErrorMsg(uint32_t CFSRValue)
1688 {
1689 printErrorMsg("Usage fault: ");
1690 CFSRValue >>= 16; // right shift to lsb
1691 if((CFSRValue & (1 << 9)) != 0) {
1692 printErrorMsg("Divide by zero\n");
1693 }
1694 }
1695
1696 void Hard_Fault_Handler()//uint32_t stack[])
1697 {
1698 static char msg[80];
1699 printErrorMsg("In Hard Fault Handler\n");
1700 sprintf(msg, "SCB->HFSR = 0x%08x\n", SCB->HFSR);
1701 printErrorMsg(msg);
1702 if ((SCB->HFSR & (1 << 30)) != 0) {
1703 printErrorMsg("Forced Hard Fault\n");
1704 sprintf(msg, "SCB->CFSR = 0x%08x\n", SCB->CFSR );
1705 printErrorMsg(msg);
1706 if((SCB->CFSR & 0xFFFF0000) != 0) {
1707 printUsageErrorMsg(SCB->CFSR);
1708 }
1709 }
1710 __ASM volatile("BKPT #01");
1711 while(1);
1712 }
1713
1714 int my_store_of_MSP;
1715
1716 void HardFault_Handler(void)
1717 {
1718 __asm ("MRS my_store_of_MSP, MSP");
1719 Hard_Fault_Handler();
1720 }
1721 */
1722
1723 /*
1724 __asm void HardFault_Handler(void)
1725 {
1726 TST lr, #4 // Test for MSP or PSP
1727 ITE EQ
1728 MRSEQ r0, MSP
1729 MRSNE r0, PSP
1730 B __cpp(Hard_Fault_Handler)
1731 }
1732 */
1733 /*
1734 HardFault_Handler\
1735 PROC
1736 EXPORT HardFault_Handler
1737 B .
1738 ENDP
1739 */
1740
1741 /*
1742 __asm int f(int i)
1743 {
1744 ADD i, i, #1 // error
1745 }
1746
1747 EXPORT HardFault_Handler
1748 HardFault_Handler FUNCTION
1749 MRS r0, MSP
1750 B __cpp(Hard_Fault_Handler)
1751 ENDFUNC
1752 */