Added key direction awarness to t3, t5 and t6 views:
In case of big font views the handling of motion events were not considered, As results all events caused a menu change in th same direction.
line source
///////////////////////////////////////////////////////////////////////////////+ −
/// -*- coding: UTF-8 -*-+ −
///+ −
/// \file Discovery/Src/base.c+ −
/// \brief main(): init hardware, IRQs and start sub-systems+ −
/// \author heinrichs weikamp gmbh+ −
/// \date 26-February-2014+ −
///+ −
/// $Id$+ −
///////////////////////////////////////////////////////////////////////////////+ −
/// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh+ −
///+ −
/// This program is free software: you can redistribute it and/or modify+ −
/// it under the terms of the GNU General Public License as published by+ −
/// the Free Software Foundation, either version 3 of the License, or+ −
/// (at your option) any later version.+ −
///+ −
/// This program is distributed in the hope that it will be useful,+ −
/// but WITHOUT ANY WARRANTY; without even the implied warranty of+ −
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ −
/// GNU General Public License for more details.+ −
///+ −
/// You should have received a copy of the GNU General Public License+ −
/// along with this program. If not, see <http://www.gnu.org/licenses/>.+ −
//////////////////////////////////////////////////////////////////////////////+ −
+ −
/**+ −
@verbatim+ −
==============================================================================+ −
##### Firmware Info #####+ −
==============================================================================+ −
[..] In settings.c including text and magic stuff+ −
==============================================================================+ −
##### IRQs #####+ −
==============================================================================+ −
[..] The IRQs are very important and most functions should only run there.+ −
+ −
PreemptPriority are as follows+ −
(#) 2 (low) sprintf _only_ here. Don't use in maintask or anywhere else.+ −
Called by Buttons und Timer3+ −
Timer3 is 1/10 second+ −
(#) 1 (mid) anything that should work while in IRQ2 like HalDelay(), VSYNC+ −
and DMA2D Transfer Complete for housekeepingFrame();+ −
(#) 0 (high) _very very short_ interrupts like The HAL hardware part for+ −
spi, uart, i2c.+ −
+ −
SubPriority within PreemptPriority give the order to execute.+ −
Introduced 30.Oct.14 as it used by several HAL examples.+ −
Three levelAmbients are available (2 low,1 mid,0 high)+ −
+ −
The STM32F4 has 4bits for IRQ levelAmbients, divided 2/2 in this code+ −
with the NVIC_PRIORITYGROUP_2 setting.+ −
+ −
==============================================================================+ −
##### MainTask #####+ −
==============================================================================+ −
[..] For everthing slow without importance to be 'in time'.+ −
Like VPM and Buehlmann.+ −
No sprintf and probably no GFX_SetFramesTopBottom() stuff neither.+ −
If sprintf is called while sprintf is executed it blows up everything.+ −
+ −
==============================================================================+ −
##### Frames / the external SDRAM #####+ −
==============================================================================+ −
[..] The SDRAM is handled by getFrame() and releaseFrame().+ −
Each frame with 800*480*2 Bytes.+ −
Be carefull to release every frame+ −
otherwise there will be a memory leakage over time.+ −
housekeepingFrame() in the MainTask takes care of cleaning the frames.+ −
All frames are filled with 0x00. This will be transparent with color of+ −
CLUT_Font020 (is CLUT 0) if the alpha is set for a 16bit pair.+ −
housekeepingFrame() delays the cleaning of frames still used as screen+ −
buffer to prevent flickering.+ −
+ −
[..] use global variable frameCounter[] in gfxengine.c to control memory+ −
all but the last three are identical to caller_id+ −
for example 0x05 are the menu frames+ −
the last but one is a sum for higher numbers (shouldn't be any)+ −
the last but one are those in status RELEASED+ −
the last are those CLEAR (as of 151202 down to 4 in logbook mode)+ −
+ −
[..] 4 pages are used for two double memories for screenshots (since Nov. 15)+ −
+ −
==============================================================================+ −
##### Display #####+ −
==============================================================================+ −
[..] There is a Top layer, Bottom layer and background color.+ −
All are perfectly alpha-blended by hardware.+ −
+ −
(#) top layer has 800x480 option function calls only+ −
as it is not used for cursors here+ −
(#) bottom layer has free size and start option to be used+ −
for cursors (or sprites in the future ;-)+ −
(#) background only black in the moment.+ −
ToDo: Could be anything else for warnings etc.+ −
if needed+ −
+ −
[..] Frame updates, switching and cursors is done with+ −
+ −
(#) GFX_SetFramesTopBottom() and the subset+ −
GFX_SetFrameTop() + GFX_SetFrameBottom()+ −
Those do not change anything on the display but give commands to..+ −
(#) GFX_change_LTDC() The only place that changes the pointer.+ −
This prevents erratic behaviour if several changes+ −
are made within one refresh rate of the screen.+ −
Is called in IRQ by PD4 and HAL_GPIO_EXTI_IRQHandler+ −
from VSYNC signal.+ −
+ −
[..] Content+ −
+ −
(#) Colors by LookupTable only. This could be modified by+ −
system settings in the future. (gfx_color.h/.c)+ −
+ −
(#) Text by text_multilinguage.h/.c with one char+ −
necessary only starting from '\x80'+ −
with automatic language switch by+ −
selected_language in SSettings+ −
see openEdit_Language() in tMenuEditSystem.c+ −
Therefore there are differnent functions+ −
for example:+ −
write_label_fix() for single char multilanguage+ −
write_label_var() for strings that could include+ −
multilanguage as well+ −
see GFX_write_string() to get an overview of the controls+ −
as well as the command list in gfx_engine.h+ −
There is no clear before writing, text overlay is always on.+ −
Many options to have LargeFont.SmallFont for numbers etc.+ −
+ −
==============================================================================+ −
##### Update, DualBoot and build-in FLASH memory usage #####+ −
==============================================================================+ −
[..] Boot0 pin, Boot1/PB2 pin and BFB2 software bit control the behaviour.+ −
PB2 should be tied to GND.+ −
Boot0 == VDD -> bootloader on start, otherwise boot from Bank1 or Bank2+ −
depending on BFB2.+ −
Bank2 contains the Fonts and should contain a proper test code in future+ −
Bank1 is the main code (Bank1 is 1 MB too, usage as of Oct. 14 is 200 KB)+ −
[..] Bootloader should be either UART or USB (on FS pins _only_)+ −
USB HS to FS like on the Eval board does not work.+ −
[..] Bootloader for the smaller CPU2 is implemented via the SPI used for DMA copy.+ −
+ −
==============================================================================+ −
##### Connection to CPU2 (STM32F411 as of Oct.14 #####+ −
==============================================================================+ −
[..] Connected via SPI and DMA for every purpose.+ −
two entire arrays are transfered for data security reasons+ −
with respect to master (STM32F429) might interrupt internal+ −
data copy in CPU2 (like hi byte, low byte, etc.).+ −
[..] The entire life data is calculated in CPU2. Like tissues, CNS,...+ −
Therefore the main unit is _not_ necessarily a Real Time system.+ −
Simulation on the main unit can be executed without disrupting life data.+ −
[..] SPI is triggered and timed by calling DataEX_call() in data_exchange_main.c+ −
DataEX_copy_to_LifeData() does the transfer from buffer to variables used.+ −
+ −
==============================================================================+ −
##### Menu, MenuEdit, Info #####+ −
==============================================================================+ −
[..] tMenu.c, tMenuEdit.c and tInfo.c is the system used.+ −
logbook is part of Info not Menu.+ −
The Info Menu is accessed by button 'Back'+ −
The regular Menu is accessed by button 'Enter'+ −
[..] Menu content is kept in frame memory for fast access.+ −
There is no need to build pages if the 'Enter' button is pressed.+ −
This is in contrast to MenuEdit pages.+ −
[..] Button control for new pages (and pages in general) have to implemented+ −
in tMenu.c, tMenuEdit.c or tInfo.c+ −
+ −
[..] ToDo (Oct. 14) Timeout for menus via Timer3 / IRQ 2+ −
+ −
==============================================================================+ −
##### settings #####+ −
==============================================================================+ −
[..] files: settings.c, settings.h+ −
1. adjust struct SSettings in settings.h+ −
2. adjust const SSettings SettingsStandard in settings.c+ −
3. adjust set_new_settings_missing_in_ext_flash()+ −
4. adjust check_and_correct_settings() IMPORTANT as it changes values!+ −
+ −
==============================================================================+ −
##### specials #####+ −
==============================================================================+ −
[..] There was code for vector graphics from great demos+ −
(peridiummmm and jupiter) that can be fitted again+ −
+ −
==============================================================================+ −
##### ppO2 sensors #####+ −
==============================================================================+ −
[..] in tCCR.c is function get_ppO2SensorWeightedResult_cbar();+ −
+ −
@endverbatim+ −
******************************************************************************+ −
* @attention+ −
*+ −
* <h2><center>© COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>+ −
*+ −
******************************************************************************+ −
*/+ −
+ −
/* Includes ------------------------------------------------------------------*/+ −
#include "stdio.h"+ −
#include <string.h> // for memcopy+ −
+ −
#include "stm32f4xx_hal.h"+ −
#include "ostc.h"+ −
#include "base.h"+ −
#include "display.h"+ −
#include "gfx_engine.h"+ −
#include "show_logbook.h"+ −
#include "text_multilanguage.h"+ −
#include "tHome.h"+ −
#include "tInfo.h"+ −
#include "tInfoLog.h"+ −
#include "tMenu.h"+ −
#include "tMenuEdit.h"+ −
#include "tMenuEditGasOC.h"+ −
#include "tStructure.h"+ −
#include "externLogbookFlash.h"+ −
#include "tComm.h"+ −
#include "tCCR.h"+ −
#include "data_exchange.h"+ −
#include "data_exchange_main.h"+ −
#include "vpm.h"+ −
#include "buehlmann.h"+ −
#include "logbook.h"+ −
#include "check_warning.h"+ −
#include "simulation.h"+ −
#include "decom.h"+ −
#include "timer.h"+ −
#include "logbook_miniLive.h"+ −
#include "test_vpm.h"+ −
#include "tDebug.h"+ −
#include "motion.h"+ −
+ −
#ifdef DEMOMODE+ −
#include "demo.h"+ −
static void TIM_DEMO_init(void);+ −
#endif+ −
+ −
+ −
//#include "lodepng.h"+ −
//#include <stdlib.h> // for malloc and free+ −
+ −
/** @addtogroup OSTC 4+ −
* @{+ −
*/+ −
+ −
/* Private typedef -----------------------------------------------------------*/+ −
+ −
//#define NO_TIMEOUT+ −
//#define QUICK_SLEEP+ −
+ −
/* Private define ------------------------------------------------------------*/+ −
#define REFRESH_COUNT ((uint32_t)0x0569) /**< for SDRAM refresh counter (90Mhz SD clock) */+ −
#define INVALID_BUTTON ((uint8_t) 0xFF)+ −
/* Private macro -------------------------------------------------------------*/+ −
/* Private variables ---------------------------------------------------------*/+ −
+ −
static RTC_HandleTypeDef RtcHandle; /* used to change time and date, no RTC is running on this MCU */+ −
TIM_HandleTypeDef TimHandle; /* used in stm32f4xx_it.c too */+ −
static TIM_HandleTypeDef TimBacklightHandle;+ −
#ifdef DEMOMODE+ −
TIM_HandleTypeDef TimDemoHandle; /* used in stm32f4xx_it.c too */+ −
#endif+ −
+ −
static uint8_t LastButtonPressed;+ −
static uint32_t LastButtonPressedTick;+ −
static uint32_t BaseTick100ms; /* Tick at last 100ms cycle */+ −
+ −
/* SDRAM handler declaration */+ −
static SDRAM_HandleTypeDef hsdram;+ −
static FMC_SDRAM_TimingTypeDef SDRAM_Timing;+ −
static FMC_SDRAM_CommandTypeDef command;+ −
+ −
/* This was used for Dual Boot */+ −
//FLASH_OBProgramInitTypeDef OBInit;+ −
//FLASH_AdvOBProgramInitTypeDef AdvOBInit;+ −
+ −
/* Private variables with external access ------------------------------------*/+ −
+ −
static uint32_t globalStateID = 0;+ −
static uint32_t time_without_button_pressed_deciseconds = 0; /**< langbeschreibung (eigenes Feld) warum diese variable verwendet wird um den sleepmode zu aktivieren */+ −
uint8_t bootToBootloader = 0; ///< set in tComm.c to install firmware updates, calls resetToFirmwareUpdate()+ −
static uint8_t returnFromCommCleanUpRequest = 0; ///< use this to exit bluetooth mode and call tComm_exit()+ −
uint32_t base_tempLightLevel = 0;+ −
static uint8_t wasFirmwareUpdateCheckBattery = 0;+ −
static uint8_t DoDisplayRefresh = 0; /* trigger to refresh display data */+ −
+ −
/* Private function prototypes -----------------------------------------------*/+ −
static void SystemClock_Config(void);+ −
static void Error_Handler(void);+ −
static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command);+ −
static void SDRAM_Config(void);+ −
static void EXTILine_Buttons_Config(void);+ −
static void TIM_init(void);+ −
static void TIM_BACKLIGHT_init(void);+ −
static uint32_t TIM_BACKLIGHT_adjust(void);+ −
static void gotoSleep(void);+ −
static void deco_loop(void);+ −
static void resetToFirmwareUpdate(void);+ −
static void TriggerButtonAction(void);+ −
static void EvaluateButton(void);+ −
static void RefreshDisplay(void);+ −
+ −
/* ITM Trace-------- ---------------------------------------------------------*/+ −
/*+ −
#define ITM_Port8(n) (*((volatile unsigned char *)(0xE0000000+4*n)))+ −
#define ITM_Port16(n) (*((volatile unsigned short*)(0xE0000000+4*n)))+ −
#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))+ −
+ −
#define DEMCR (*((volatile unsigned long *)(0xE000EDFC)))+ −
#define TRCENA 0x01000000+ −
+ −
struct __FILE { int handle; };+ −
FILE __stdout;+ −
FILE __stdin;+ −
+ −
int fputc(int ch, FILE *f) {+ −
if (DEMCR & TRCENA) {+ −
while (ITM_Port32(0) == 0);+ −
ITM_Port8(0) = ch;+ −
}+ −
return(ch);+ −
}+ −
*/+ −
/* #define DEBUG_RUNTIME TRUE */+ −
#ifdef DEBUG_RUNTIME+ −
#define MEASURECNT 60 /* number of measuremets to be stored */+ −
static uint32_t loopcnt[MEASURECNT];+ −
#endif+ −
+ −
static uint8_t ButtonAction = ACTION_END;+ −
+ −
static void StoreButtonAction(uint8_t action)+ −
{+ −
ButtonAction = action;+ −
}+ −
+ −
// ===============================================================================+ −
// main+ −
/// @brief This function makes initializations and has the nonIRQ endless loop+ −
/// for bluetooth and deco calculations+ −
///+ −
// ===============================================================================+ −
int main(void)+ −
{+ −
uint32_t pLayerInvisible;+ −
uint16_t totalDiveCounterFound;+ −
#ifdef DEBUG_RUNTIME+ −
RTC_TimeTypeDef Stime;+ −
uint8_t measurementindex = 0;+ −
uint8_t lastsecond = 0xFF;+ −
#endif+ −
+ −
detectionState_t pitchstate;+ −
set_globalState( StBoot0 );+ −
LastButtonPressed = 0;+ −
+ −
HAL_Init();+ −
HAL_NVIC_SetPriorityGrouping( NVIC_PRIORITYGROUP_2 );+ −
+ −
SystemClock_Config();+ −
+ −
MX_GPIO_Init();+ −
// MX_SmallCPU_NO_Reset_Helper(); //161116 hw+ −
MX_SPI_Init();+ −
MX_UART_Init();+ −
SDRAM_Config();+ −
HAL_Delay( 100 );+ −
+ −
stateRealGetPointerWrite()->lastKnownBatteryPercentage = 0; // damit das nicht in settings kopiert wird.+ −
set_settings_to_Standard();+ −
mod_settings_for_first_start_with_empty_ext_flash();+ −
ext_flash_read_settings();+ −
if( newFirmwareVersionCheckViaSettings() ) // test for old firmware version in loaded settings+ −
{+ −
wasFirmwareUpdateCheckBattery = 1;+ −
set_settings_button_to_standard_with_individual_buttonBalance(); // will adapt individual values+ −
}+ −
//settingsGetPointer()->bluetoothActive = 0; /* MX_Bluetooth_PowerOff(); unnecessary as part of MX_GPIO_Init() */+ −
//settingsGetPointer()->compassBearing = 0;+ −
set_new_settings_missing_in_ext_flash(); // includes update of firmware version 161121+ −
+ −
GFX_init( &pLayerInvisible );+ −
TIM_BACKLIGHT_init();+ −
+ −
// new 170508: bluetooth on at start+ −
settingsGetPointer()->bluetoothActive = 1;+ −
MX_Bluetooth_PowerOn();+ −
+ −
// Haase Geburtstag:+ −
// settingsGetPointer()->serialHigh = (3012 / 256);+ −
// settingsGetPointer()->serialLow = (3012 & 0xFF);+ −
+ −
// settingsGetPointer()->showDebugInfo = 1;+ −
+ −
/*+ −
if( (hardwareDataGetPointer()->primarySerial == 20+18)+ −
|| (hardwareDataGetPointer()->primarySerial == 20+25)+ −
|| (hardwareDataGetPointer()->primarySerial == 20+27))+ −
{+ −
MX_Bluetooth_PowerOn();+ −
tComm_Set_Bluetooth_Name(1);+ −
}+ −
*/+ −
errorsInSettings = check_and_correct_settings();+ −
createDiveSettings();+ −
+ −
#ifdef QUICK_SLEEP+ −
settingsGetPointer()->timeoutSurfacemode = 20;+ −
#else+ −
settingsGetPointer()->timeoutSurfacemode = 120;+ −
#endif+ −
+ −
#ifdef DEMOMODE+ −
demoConfigureSettings();+ −
TIM_DEMO_init();+ −
#endif+ −
+ −
// -----------------------------+ −
+ −
display_power_on__1_of_2__pre_RGB();+ −
GFX_LTDC_Init();+ −
GFX_LTDC_LayerDefaultInit( TOP_LAYER, pLayerInvisible );+ −
GFX_LTDC_LayerDefaultInit( BACKGRD_LAYER, pLayerInvisible );+ −
GFX_SetFramesTopBottom( pLayerInvisible, pLayerInvisible, 480 );+ −
HAL_Delay( 20 );+ −
display_power_on__2_of_2__post_RGB();+ −
GFX_use_colorscheme( settingsGetPointer()->tX_colorscheme );+ −
+ −
tHome_init();+ −
tI_init();+ −
tM_init();+ −
tMenuEdit_init();+ −
tInfoLog_init();+ −
tComm_init();+ −
DataEX_init();+ −
setButtonResponsiveness( settingsGetPointer()->ButtonResponsiveness );+ −
set_globalState_tHome();+ −
+ −
GFX_start_VSYNC_IRQ();+ −
tCCR_init();+ −
+ −
GFX_logoAutoOff();+ −
EXTILine_Buttons_Config();+ −
+ −
ext_flash_repair_dive_log();+ −
//ext_flash_repair_SPECIAL_dive_numbers_starting_count_with(1);+ −
+ −
totalDiveCounterFound = logbook_lastDive_diveNumber();+ −
if( settingsGetPointer()->totalDiveCounter < totalDiveCounterFound )+ −
settingsGetPointer()->totalDiveCounter = totalDiveCounterFound;+ −
+ −
if( settingsGetPointer()->debugModeOnStart )+ −
{+ −
settingsGetPointer()->debugModeOnStart = 0;+ −
ext_flash_write_settings();+ −
setDebugMode();+ −
openInfo( StIDEBUG );+ −
}+ −
InitMotionDetection();+ −
+ −
TIM_init(); /* start cylic 100ms task */+ −
+ −
/* @brief main LOOP+ −
*+ −
* this is executed while no IRQ interrupts it+ −
* - deco calculation+ −
* - bluetooth+ −
* and resetToFirmwareUpdate()+ −
* because tComm_control() does not exit before disconnection+ −
*/+ −
while( 1 )+ −
{+ −
if( bootToBootloader )+ −
resetToFirmwareUpdate();+ −
+ −
tCCR_control();+ −
if( tComm_control() )// will stop while loop if tComm Mode started until exit from UART+ −
{+ −
createDiveSettings();+ −
updateMenu();+ −
ext_flash_write_settings();+ −
}+ −
deco_loop();+ −
TriggerButtonAction();+ −
if(DoDisplayRefresh)+ −
{+ −
DoDisplayRefresh = 0;+ −
RefreshDisplay();+ −
+ −
if(stateUsed->mode == MODE_DIVE) /* handle motion events in divemode only */+ −
{+ −
switch(settingsGetPointer()->MotionDetection)+ −
{+ −
case MOTION_DETECT_MOVE: pitchstate = detectPitch(stateRealGetPointer()->lifeData.compass_pitch);+ −
break;+ −
case MOTION_DETECT_SECTOR: pitchstate = detectSectorButtonEvent(stateRealGetPointer()->lifeData.compass_pitch);+ −
break;+ −
case MOTION_DETECT_SCROLL: pitchstate = detectScrollButtonEvent(stateRealGetPointer()->lifeData.compass_pitch);+ −
break;+ −
default:+ −
pitchstate = DETECT_NOTHING;+ −
break;+ −
}+ −
if(DETECT_NEG_PITCH == pitchstate)+ −
{+ −
StoreButtonAction((uint8_t)ACTION_PITCH_NEG);+ −
}+ −
if(DETECT_POS_PITCH == pitchstate)+ −
{+ −
StoreButtonAction((uint8_t)ACTION_PITCH_POS);+ −
}+ −
}+ −
+ −
+ −
// Enable this to make the simulator write a logbook entry+ −
// #define SIM_WRITES_LOGBOOK 1+ −
+ −
#ifdef SIM_WRITES_LOGBOOK+ −
if(stateUsed == stateSimGetPointer())+ −
logbook_InitAndWrite(stateUsed);+ −
#endif+ −
if(stateUsed == stateRealGetPointer()) /* Handle log entries while in dive mode*/+ −
logbook_InitAndWrite(stateUsed);+ −
}+ −
+ −
#ifdef DEBUG_RUNTIME+ −
translateTime(stateUsed->lifeData.timeBinaryFormat, &Stime);+ −
if(lastsecond == 0xFF)+ −
{+ −
measurementindex = 0;+ −
loopcnt[measurementindex] = 0;+ −
lastsecond = Stime.Seconds;+ −
}+ −
loopcnt[measurementindex]++;+ −
+ −
if(lastsecond != Stime.Seconds)+ −
{+ −
measurementindex++;+ −
if (measurementindex == MEASURECNT) measurementindex = 0;+ −
loopcnt[measurementindex] = 0;+ −
lastsecond = Stime.Seconds;+ −
if(measurementindex +1 < MEASURECNT) loopcnt[measurementindex +1] = 0xffff; /* helps to identify the latest value */+ −
}+ −
#endif+ −
+ −
}+ −
}+ −
+ −
+ −
+ −
+ −
// ===============================================================================+ −
// timer IRQ+ −
/// @brief this is called periodically+ −
///+ −
/// - refresh screen (the actual change is done in the VSYNC IRQ)+ −
/// - start data transfer with RTE / small CPU (DateEX....)+ −
/// - update logbook+ −
/// - timeouts+ −
/// ....+ −
///+ −
/// all this in three steps / switch() routines in a given order+ −
/// as the previous switch() might influence the next functions+ −
/// to be called+ −
///+ −
// ===============================================================================+ −
+ −
//#define NO_TIMEOUT+ −
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)+ −
{+ −
#ifdef DEMOMODE+ −
if(htim->Instance==TIM7)+ −
{+ −
HAL_GPIO_EXTI_Callback(demoGetCommand());+ −
return;+ −
}+ −
#endif+ −
static uint8_t last_base;+ −
+ −
SStateList status;+ −
uint32_t timeout_in_seconds;+ −
uint32_t timeout_limit_Surface_in_seconds;+ −
+ −
+ −
BaseTick100ms = HAL_GetTick(); /* store start of 100ms cycle */+ −
+ −
_Bool InDiveMode = 0;+ −
_Bool modeChange = 0; // to exit from menu and logbook+ −
+ −
if(stateUsed->mode == MODE_DIVE)+ −
InDiveMode = 1;+ −
else+ −
InDiveMode = 0;+ −
+ −
EvaluateButton();+ −
+ −
if(returnFromCommCleanUpRequest)+ −
{+ −
tComm_exit();+ −
returnFromCommCleanUpRequest = 0;+ −
}+ −
+ −
get_globalStateList(&status);+ −
+ −
switch(status.base)+ −
{+ −
case BaseHome:+ −
case BaseMenu:+ −
case BaseInfo:+ −
updateSetpointStateUsed();+ −
+ −
DateEx_copy_to_dataOut();+ −
DataEX_copy_to_LifeData(&modeChange);+ −
//foto session :-) stateRealGetPointerWrite()->lifeData.battery_charge = 99;+ −
//foto session :-) stateSimGetPointerWrite()->lifeData.battery_charge = 99;+ −
DataEX_copy_to_deco();+ −
DataEX_call();+ −
+ −
if(stateUsed == stateSimGetPointer())+ −
{+ −
simulation_UpdateLifeData(1);+ −
}+ −
+ −
check_warning();+ −
updateMiniLiveLogbook(1);+ −
timer_UpdateSecond(1);+ −
base_tempLightLevel = TIM_BACKLIGHT_adjust();+ −
tCCR_tick();+ −
tHome_tick();+ −
if(status.base == BaseHome)+ −
tMenuEdit_writeSettingsToFlash(); // takes 900 ms!!+ −
break;+ −
case BaseStop:+ −
DateEx_copy_to_dataOut();+ −
DataEX_call();+ −
DataEX_control_connection_while_asking_for_sleep();+ −
break;+ −
default:+ −
case BaseComm:+ −
if(get_globalState() == StUART_RTECONNECT)+ −
{+ −
DateEx_copy_to_dataOut();+ −
DataEX_call();+ −
DataEX_copy_to_LifeData(0);+ −
}+ −
break;+ −
}+ −
+ −
/* timeout control */+ −
if(modeChange) ///< from RTE, set in data_exchange_main.c+ −
time_without_button_pressed_deciseconds = (settingsGetPointer()->timeoutSurfacemode / 4) * 3;+ −
if(status.base != last_base)+ −
time_without_button_pressed_deciseconds = 0;+ −
last_base = status.base;+ −
timeout_in_seconds = time_without_button_pressed_deciseconds / 10;+ −
time_without_button_pressed_deciseconds += 1;+ −
if(modeChange || (timeout_in_seconds != time_without_button_pressed_deciseconds / 10))+ −
{+ −
#ifdef NO_TIMEOUT+ −
timeout_in_seconds = 0;+ −
#else+ −
timeout_in_seconds += 1;+ −
#endif+ −
+ −
if(InDiveMode)+ −
{+ −
switch(status.base)+ −
{+ −
case BaseHome:+ −
if((status.line != 0) && (timeout_in_seconds >= settingsGetPointer()->timeoutEnterButtonSelectDive))+ −
{+ −
set_globalState(StD);+ −
timeout_in_seconds = 0;+ −
}+ −
break;+ −
+ −
case BaseMenu:+ −
if((status.line == 0) && ((timeout_in_seconds >= settingsGetPointer()->timeoutMenuDive) || modeChange))+ −
{+ −
exitMenu();+ −
timeout_in_seconds = 0;+ −
}+ −
if((status.line != 0) && ((timeout_in_seconds >= settingsGetPointer()->timeoutMenuEdit) || modeChange))+ −
{+ −
exitMenuEdit_to_Home();+ −
timeout_in_seconds = 0;+ −
}+ −
break;+ −
default:+ −
break;+ −
}+ −
}+ −
else /* surface mode */+ −
{+ −
switch(status.base)+ −
{+ −
case BaseHome:+ −
// added hw 161027+ −
if(!(stateRealGetPointer()->warnings.lowBattery) && (stateRealGetPointer()->lifeData.battery_charge > 9))+ −
{+ −
stateRealGetPointerWrite()->lastKnownBatteryPercentage = stateRealGetPointer()->lifeData.battery_charge;+ −
}+ −
else if((wasFirmwareUpdateCheckBattery) && (timeout_in_seconds > 3))+ −
{+ −
wasFirmwareUpdateCheckBattery = 0;+ −
setButtonResponsiveness(settingsGetPointer()->ButtonResponsiveness); // added 170306+ −
if( (settingsGetPointer()->lastKnownBatteryPercentage > 0)+ −
&& (settingsGetPointer()->lastKnownBatteryPercentage <= 100)+ −
&& (stateRealGetPointer()->warnings.lowBattery))+ −
{+ −
setBatteryPercentage(settingsGetPointer()->lastKnownBatteryPercentage);+ −
}+ −
}+ −
// stuff before and new @161121 CCR-sensor limit 10 minutes+ −
if((settingsGetPointer()->dive_mode == DIVEMODE_CCR) && (settingsGetPointer()->CCR_Mode == CCRMODE_Sensors))+ −
{+ −
timeout_limit_Surface_in_seconds = settingsGetPointer()->timeoutSurfacemodeWithSensors;+ −
}+ −
else+ −
{+ −
timeout_limit_Surface_in_seconds = settingsGetPointer()->timeoutSurfacemode;+ −
}+ −
if(timeout_in_seconds >= timeout_limit_Surface_in_seconds)+ −
{+ −
gotoSleep();+ −
}+ −
break;+ −
case BaseMenu:+ −
if((status.line == 0) && ((timeout_in_seconds >= settingsGetPointer()->timeoutMenuSurface) || modeChange))+ −
{+ −
exitMenu();+ −
timeout_in_seconds = 0;+ −
}+ −
if((status.line != 0) && ((timeout_in_seconds >= settingsGetPointer()->timeoutMenuEdit) || modeChange))+ −
{+ −
if((status.page != (uint8_t)((StMPLAN >> 24) & 0x0F)) || (timeout_in_seconds >= 10*(settingsGetPointer()->timeoutMenuEdit)))+ −
{+ −
exitMenuEdit_to_Home();+ −
timeout_in_seconds = 0;+ −
}+ −
}+ −
break;+ −
+ −
case BaseInfo:+ −
if((timeout_in_seconds >= settingsGetPointer()->timeoutInfo) || modeChange)+ −
{+ −
if(status.page == InfoPageLogList)+ −
{+ −
exitLog();+ −
timeout_in_seconds = 0;+ −
}+ −
else+ −
if(status.page == InfoPageLogShow)+ −
{+ −
show_logbook_exit();+ −
exitLog();+ −
timeout_in_seconds = 0;+ −
}+ −
else+ −
if(status.page != InfoPageCompass)+ −
{+ −
exitInfo();+ −
timeout_in_seconds = 0;+ −
}+ −
}+ −
break;+ −
default:+ −
break;+ −
}+ −
}+ −
}+ −
+ −
get_globalStateList(&status);+ −
+ −
if(status.base == BaseComm) /* main loop not serviced in com mode */+ −
{+ −
tComm_refresh();+ −
}+ −
else+ −
{+ −
DoDisplayRefresh = 1;+ −
}+ −
}+ −
+ −
+ −
/* button and VSYNC IRQ+ −
*+ −
* VSYNC will switch foreground and background picture+ −
* if demanded. see GFX_change_LTDC()+ −
*+ −
*/+ −
// ===============================================================================+ −
// HAL_GPIO_EXTI_Callback+ −
/// @brief button and VSYNC IRQ+ −
///+ −
/// VSYNC will switch foreground and background picture if demanded -+ −
/// see GFX_change_LTDC()+ −
///+ −
// ===============================================================================+ −
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {+ −
if (!GPIO_Pin)+ −
return;+ −
+ −
if (GPIO_Pin == VSYNC_IRQ_PIN) // rechts, unten+ −
{+ −
GFX_change_LTDC();+ −
housekeepingFrame();+ −
/*+ −
#ifdef DEMOMODE+ −
static uint8_t countCall = 0;+ −
if(countCall++ < 10)+ −
return;+ −
countCall = 0;+ −
uint8_t buttonAction = demoGetCommand();+ −
if(buttonAction)+ −
GPIO_Pin = buttonAction;+ −
else+ −
#endif+ −
*/+ −
return;+ −
}+ −
+ −
LastButtonPressed = GPIO_Pin;+ −
LastButtonPressedTick = HAL_GetTick();+ −
+ −
#ifdef DEMOMODE+ −
uint8_t demoMachineCall = 0;+ −
if(GPIO_Pin & 0x80)+ −
{+ −
demoMachineCall = 1;+ −
GPIO_Pin &= 0x7F;+ −
}+ −
#endif+ −
}+ −
+ −
static void RefreshDisplay()+ −
{+ −
SStateList status;+ −
get_globalStateList(&status);+ −
switch(status.base)+ −
{+ −
case BaseHome:+ −
tHome_refresh();+ −
tM_check_content();+ −
break;+ −
case BaseMenu:+ −
tM_refresh_live_content();+ −
tMenuEdit_refresh_live_content();+ −
break;+ −
case BaseInfo:+ −
tInfo_refresh(); ///< only compass at the moment 23.Feb.2015 hw+ −
break;+ −
case BaseComm: /* refresh already done in tim callback */+ −
break;+ −
default:+ −
if(get_globalState() == StStop)+ −
tHome_sleepmode_fun();+ −
break;+ −
}+ −
}+ −
+ −
+ −
static void TriggerButtonAction()+ −
{+ −
uint8_t action = ButtonAction;+ −
SStateList status;+ −
+ −
if(ButtonAction != ACTION_END)+ −
{+ −
get_globalStateList(&status);+ −
+ −
if (action == ACTION_BUTTON_CUSTOM) {+ −
GFX_screenshot();+ −
}+ −
+ −
switch (status.base) {+ −
case BaseStop:+ −
if (action == ACTION_BUTTON_BACK)+ −
resetToFirmwareUpdate();+ −
break;+ −
case BaseComm: /* already handled in tim callback */+ −
break;+ −
case BaseHome:+ −
if (action == ACTION_BUTTON_NEXT) {+ −
if (status.page == PageSurface)+ −
openMenu(1);+ −
else+ −
tHomeDiveMenuControl(action);+ −
} else if (action == ACTION_BUTTON_BACK) {+ −
if (get_globalState() == StS)+ −
openInfo(StILOGLIST);+ −
else if ((status.page == PageDive)+ −
&& (settingsGetPointer()->design < 7)) {+ −
settingsGetPointer()->design = 7; // auto switch to 9 if necessary+ −
} else if ((status.page == PageDive) && (status.line != 0)) {+ −
if (settingsGetPointer()->extraDisplay == EXTRADISPLAY_BIGFONT)+ −
{+ −
settingsGetPointer()->design = 3;+ −
if(settingsGetPointer()->MotionDetection == MOTION_DETECT_SECTOR)+ −
{+ −
DefinePitchSectors(stateRealGetPointer()->lifeData.compass_pitch,CUSTOMER_DEFINED_VIEWS);+ −
}+ −
}+ −
else if (settingsGetPointer()->extraDisplay+ −
== EXTRADISPLAY_DECOGAME)+ −
settingsGetPointer()->design = 4;+ −
+ −
set_globalState(StD);+ −
} else+ −
tHome_change_field_button_pressed();+ −
} else if ((action == ACTION_BUTTON_ENTER) || (action == ACTION_PITCH_NEG) || (action == ACTION_PITCH_POS))+ −
{+ −
+ −
if ((status.page == PageDive) && (status.line == 0))+ −
{+ −
tHome_change_customview_button_pressed(action);+ −
if((settingsGetPointer()->MotionDetection != MOTION_DETECT_OFF) && (action == ACTION_BUTTON_ENTER)) /* Button pressed while motion detection is active => calibrate to current pitch value */+ −
{+ −
DefinePitchSectors(stateRealGetPointer()->lifeData.compass_pitch,CUSTOMER_KEEP_LAST_SECTORS);+ −
}+ −
}+ −
else if (status.page == PageSurface)+ −
tHome_change_customview_button_pressed(action);+ −
else+ −
tHomeDiveMenuControl(action);+ −
}+ −
break;+ −
+ −
case BaseMenu:+ −
if (status.line == 0)+ −
sendActionToMenu(action);+ −
else+ −
sendActionToMenuEdit(action);+ −
break;+ −
+ −
case BaseInfo:+ −
if (status.page == InfoPageLogList)+ −
sendActionToInfoLogList(action);+ −
else if (status.page == InfoPageLogShow)+ −
sendActionToInfoLogShow(action);+ −
else+ −
sendActionToInfo(action);+ −
break;+ −
+ −
default:+ −
break;+ −
}+ −
ButtonAction = ACTION_END;+ −
}+ −
}+ −
+ −
+ −
static void EvaluateButton()+ −
{+ −
uint8_t action = 0;+ −
SStateList status;+ −
SSettings* pSettings;+ −
pSettings = settingsGetPointer();+ −
+ −
if (GFX_logoStatus() != 0)+ −
return;+ −
+ −
if ((LastButtonPressed != INVALID_BUTTON) && (time_elapsed_ms(LastButtonPressedTick, HAL_GetTick())) > 50)+ −
{+ −
if (LastButtonPressed == BUTTON_BACK_PIN) { // links+ −
if (HAL_GPIO_ReadPin(BUTTON_BACK_GPIO_PORT, BUTTON_BACK_PIN) == 1) {+ −
action = ACTION_BUTTON_BACK;+ −
}+ −
}+ −
+ −
else if (LastButtonPressed == BUTTON_ENTER_PIN) { // mitte+ −
if (HAL_GPIO_ReadPin(BUTTON_ENTER_GPIO_PORT, BUTTON_ENTER_PIN) == 1) {+ −
action = ACTION_BUTTON_ENTER;+ −
}+ −
}+ −
+ −
else if (LastButtonPressed == BUTTON_NEXT_PIN) { // rechts+ −
if (HAL_GPIO_ReadPin(BUTTON_NEXT_GPIO_PORT, BUTTON_NEXT_PIN) == 1) {+ −
action = ACTION_BUTTON_NEXT;+ −
}+ −
}+ −
+ −
if(action != 0)+ −
{+ −
time_without_button_pressed_deciseconds = 0;+ −
if(pSettings->FlipDisplay) /* switch action resulting from pressed button */+ −
{+ −
if (action == ACTION_BUTTON_BACK)+ −
{+ −
action = ACTION_BUTTON_NEXT;+ −
}+ −
else+ −
{+ −
if (action == ACTION_BUTTON_NEXT)+ −
{+ −
action = ACTION_BUTTON_BACK;+ −
}+ −
}+ −
}+ −
}+ −
+ −
#ifdef BUTTON_CUSTOM_PIN+ −
else+ −
if(LastButtonPressed == BUTTON_CUSTOM_PIN) // extra+ −
action = ACTION_BUTTON_CUSTOM;+ −
#endif+ −
+ −
#ifdef DEMOMODE // user pressed button ?+ −
if((!demoMachineCall) && demoModeActive())+ −
{+ −
demoSendCommand(action);+ −
return;+ −
}+ −
#endif+ −
+ −
get_globalStateList(&status);+ −
if(status.base == BaseComm) /* main loop is not serviced in comm mode => react immediately */+ −
{+ −
if (action == ACTION_BUTTON_BACK) {+ −
settingsGetPointer()->bluetoothActive = 0;+ −
MX_Bluetooth_PowerOff();+ −
tComm_exit();+ −
}+ −
}+ −
else+ −
{+ −
StoreButtonAction(action); /* Handle action in main loop */+ −
}+ −
LastButtonPressed = INVALID_BUTTON;+ −
}+ −
}+ −
+ −
static void gotoSleep(void)+ −
{+ −
/* not at the moment of testing */+ −
// ext_flash_erase_firmware_if_not_empty();+ −
GFX_logoAutoOff();+ −
set_globalState(StStop);+ −
}+ −
+ −
+ −
// -----------------------------+ −
+ −
uint32_t get_globalState(void)+ −
{+ −
return globalStateID;+ −
}+ −
+ −
+ −
void get_globalStateList(SStateList *output)+ −
{+ −
output->base = (uint8_t)((globalStateID >> 28) & 0x0F);+ −
output->page = (uint8_t)((globalStateID >> 24) & 0x0F);+ −
output->line = (uint8_t)((globalStateID >> 16) & 0xFF);+ −
output->field = (uint8_t)((globalStateID >> 8) & 0xFF);+ −
output->mode = (uint8_t)((globalStateID ) & 0xFF);+ −
}+ −
+ −
+ −
void get_idSpecificStateList(uint32_t id, SStateList *output)+ −
{+ −
output->base = (uint8_t)((id >> 28) & 0x0F);+ −
output->page = (uint8_t)((id >> 24) & 0x0F);+ −
output->line = (uint8_t)((id >> 16) & 0xFF);+ −
output->field = (uint8_t)((id >> 8) & 0xFF);+ −
output->mode = (uint8_t)((id ) & 0xFF);+ −
}+ −
+ −
+ −
void set_globalState_Menu_Page(uint8_t page)+ −
{+ −
globalStateID = ((BaseMenu << 28) + (page << 24));+ −
}+ −
+ −
void set_globalState_Log_Page(uint8_t pageIsLine)+ −
{+ −
globalStateID = StILOGLIST + (pageIsLine << 16);+ −
}+ −
+ −
+ −
void set_globalState_Menu_Line(uint8_t line)+ −
{+ −
globalStateID = ((globalStateID & MaskLineFieldDigit) + (line << 16));+ −
}+ −
+ −
+ −
void set_globalState(uint32_t newID)+ −
{+ −
globalStateID = newID;+ −
}+ −
+ −
void set_returnFromComm(void)+ −
{+ −
returnFromCommCleanUpRequest = 1;+ −
}+ −
+ −
uint8_t font_update_required(void)+ −
{+ −
uint8_t *fontVersionHigh;+ −
uint8_t *fontVersionLow;+ −
+ −
fontVersionHigh = (uint8_t *)0x08132000;+ −
fontVersionLow = (uint8_t *)0x08132001;+ −
+ −
if(FONTminimum_required_high() < *fontVersionHigh)+ −
return 0;+ −
+ −
if((FONTminimum_required_high() == *fontVersionHigh) && (FONTminimum_required_low() <= *fontVersionLow))+ −
return 0;+ −
+ −
return 1;+ −
}+ −
+ −
+ −
__attribute__((optimize("O0"))) void delayMicros(uint32_t micros)+ −
{+ −
micros = micros * (168/4) - 10;+ −
while(micros--);+ −
}+ −
+ −
+ −
void get_RTC_DateTime(RTC_DateTypeDef * sdatestructureget, RTC_TimeTypeDef * stimestructureget)+ −
{+ −
/* Get the RTC current Time */+ −
if(sdatestructureget)+ −
HAL_RTC_GetTime(&RtcHandle, stimestructureget, FORMAT_BIN);+ −
/* Get the RTC current Date */+ −
if(stimestructureget)+ −
HAL_RTC_GetDate(&RtcHandle, sdatestructureget, FORMAT_BIN);+ −
}+ −
+ −
+ −
void set_RTC_DateTime(RTC_DateTypeDef * sdatestructure, RTC_TimeTypeDef * stimestructure)+ −
{+ −
if(sdatestructure)+ −
if(HAL_RTC_SetDate(&RtcHandle,sdatestructure,FORMAT_BCD) != HAL_OK)+ −
{+ −
/* Initialization Error */+ −
Error_Handler();+ −
}+ −
+ −
if(stimestructure)+ −
if(HAL_RTC_SetTime(&RtcHandle,stimestructure,FORMAT_BCD) != HAL_OK)+ −
{+ −
/* Initialization Error */+ −
Error_Handler();+ −
}+ −
}+ −
+ −
static void TIM_init(void)+ −
{+ −
uint16_t uwPrescalerValue = 0;+ −
+ −
uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) - 1;+ −
+ −
/* Set TIMx instance */+ −
TimHandle.Instance = TIMx;+ −
+ −
/* Initialize TIM3 peripheral as follows:+ −
+ Period = 10000 - 1+ −
+ Prescaler = ((SystemCoreClock/2)/10000) - 1+ −
+ ClockDivision = 0+ −
+ Counter direction = Up+ −
*/+ −
TimHandle.Init.Period = 1000 - 1;+ −
TimHandle.Init.Prescaler = uwPrescalerValue;+ −
TimHandle.Init.ClockDivision = 0;+ −
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;+ −
if(HAL_TIM_Base_Init(&TimHandle) != HAL_OK)+ −
{+ −
/* Initialization Error */+ −
Error_Handler();+ −
}+ −
+ −
/*##-2- Start the TIM Base generation in interrupt mode ####################*/+ −
/* Start Channel1 */+ −
if(HAL_TIM_Base_Start_IT(&TimHandle) != HAL_OK)+ −
{+ −
/* Starting Error */+ −
Error_Handler();+ −
}+ −
}+ −
+ −
#ifdef DEMOMODE+ −
static void TIM_DEMO_init(void)+ −
{+ −
uint16_t uwPrescalerValue = 0;+ −
+ −
uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) - 1;+ −
+ −
/* Set TIMx instance */+ −
TimDemoHandle.Instance = TIM7;+ −
+ −
/* Initialize TIM3 peripheral as follows:+ −
+ Period = 10000 - 1+ −
+ Prescaler = ((SystemCoreClock/2)/10000) - 1+ −
+ ClockDivision = 0+ −
+ Counter direction = Up+ −
*/+ −
TimDemoHandle.Init.Period = 1000 - 1;+ −
TimDemoHandle.Init.Prescaler = uwPrescalerValue;+ −
TimDemoHandle.Init.ClockDivision = 0;+ −
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;+ −
if(HAL_TIM_Base_Init(&TimDemoHandle) != HAL_OK)+ −
{+ −
/* Initialization Error */+ −
Error_Handler();+ −
}+ −
+ −
/*##-2- Start the TIM Base generation in interrupt mode ####################*/+ −
/* Start Channel1 */+ −
if(HAL_TIM_Base_Start_IT(&TimDemoHandle) != HAL_OK)+ −
{+ −
/* Starting Error */+ −
Error_Handler();+ −
}+ −
}+ −
#endif+ −
+ −
+ −
+ −
#ifndef TIM_BACKLIGHT+ −
+ −
static uint32_t TIM_BACKLIGHT_adjust(void)+ −
{+ −
return 0;+ −
}+ −
+ −
static void TIM_BACKLIGHT_init(void)+ −
{+ −
}+ −
#else+ −
static uint32_t TIM_BACKLIGHT_adjust(void)+ −
{+ −
static uint32_t levelActual = 12000;+ −
static uint8_t brightnessModeLast = 0;+ −
// static _Bool wasLostConnection = 0;+ −
+ −
uint32_t levelAmbient;+ −
uint32_t levelMax;+ −
uint32_t levelMin;+ −
uint32_t levelUpStep_100ms = 200;+ −
uint32_t levelDnStep_100ms = 20;+ −
+ −
TIM_OC_InitTypeDef sConfig;+ −
sConfig.OCMode = TIM_OCMODE_PWM1;+ −
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;+ −
sConfig.OCFastMode = TIM_OCFAST_DISABLE;+ −
+ −
const SDiveState * pStateReal = stateRealGetPointer();+ −
+ −
+ −
// if(pStateReal->data_old__lost_connection_to_slave)+ −
// {+ −
// changed 160613 from 6000 to 12000+ −
// removed hw 161209+ −
// levelAmbient = 12000;+ −
// levelActual = 12000;+ −
// wasLostConnection = 1;+ −
// }+ −
// else+ −
// {+ −
SSettings *pSettings = settingsGetPointer();+ −
/* 300 - 4000 */+ −
/* important levelAmbient 300 - 1200 */+ −
levelAmbient = 10 * pStateReal->lifeData.ambient_light_level;+ −
+ −
switch( pSettings->brightness)+ −
{+ −
case 0: /* Cave */+ −
levelMax = 3000;/* max 25 % (x2) */+ −
levelMin = 1500;+ −
break;+ −
case 1: /* Eco */+ −
levelMax = 6000;/* max 50 % (x2) */+ −
levelMin = 3000;+ −
break;+ −
case 2: /* Std */+ −
levelAmbient += 1000;+ −
levelMax = 9000;+ −
levelMin = 4500;+ −
levelUpStep_100ms += levelUpStep_100ms/2; // 4500 instead of 3000+ −
levelDnStep_100ms += levelDnStep_100ms/2;+ −
break;+ −
case 3: /* High */+ −
default:+ −
levelAmbient += 3000;+ −
levelMax = 12000; /* max 100% (x2) */+ −
levelMin = 6000;+ −
levelUpStep_100ms += levelUpStep_100ms; // 6000 instead of 3000+ −
levelDnStep_100ms += levelDnStep_100ms;+ −
break;+ −
case 4: /* New Max */+ −
levelAmbient = 12000;+ −
levelMax = 12000; /* max 100% (x2) */+ −
levelMin = 12000;+ −
levelUpStep_100ms += 12000;+ −
levelDnStep_100ms += 0;+ −
break;+ −
}+ −
+ −
if((pSettings->brightness != brightnessModeLast))// || wasLostConnection)+ −
{+ −
levelActual = levelAmbient;+ −
brightnessModeLast = pSettings->brightness;+ −
// wasLostConnection = 0;+ −
}+ −
// }+ −
+ −
if(levelAmbient > levelActual)+ −
levelActual += levelUpStep_100ms;+ −
else+ −
if((levelAmbient < levelActual) && (levelActual > levelMin) && (levelActual > levelDnStep_100ms))+ −
levelActual -= levelDnStep_100ms;+ −
+ −
if(levelActual > levelMax)+ −
levelActual = levelMax;+ −
else+ −
if(levelActual < levelMin)+ −
levelActual = levelMin;+ −
+ −
// sConfig.Pulse = levelActual / 20;+ −
sConfig.Pulse = (levelMin + ((levelMax - levelMin)/2)) / 20; // added 170306+ −
+ −
/* xx - 600 */+ −
if(sConfig.Pulse > 600)+ −
sConfig.Pulse = 600;+ −
else+ −
if(sConfig.Pulse < 100)+ −
sConfig.Pulse = 100;+ −
+ −
HAL_TIM_PWM_ConfigChannel(&TimBacklightHandle, &sConfig, TIM_BACKLIGHT_CHANNEL);+ −
HAL_TIM_PWM_Start(&TimBacklightHandle, TIM_BACKLIGHT_CHANNEL);+ −
+ −
return levelActual;+ −
}+ −
+ −
static void TIM_BACKLIGHT_init(void)+ −
{+ −
uint32_t uwPrescalerValue = 0;+ −
TIM_OC_InitTypeDef sConfig;+ −
+ −
uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 18000000) - 1;+ −
+ −
TimBacklightHandle.Instance = TIM_BACKLIGHT;+ −
+ −
/* Initialize TIM3 peripheral as follows:+ −
30 kHz+ −
*/+ −
TimBacklightHandle.Init.Period = 600 - 1;+ −
TimBacklightHandle.Init.Prescaler = uwPrescalerValue;+ −
TimBacklightHandle.Init.ClockDivision = 0;+ −
TimBacklightHandle.Init.CounterMode = TIM_COUNTERMODE_UP;+ −
HAL_TIM_PWM_Init(&TimBacklightHandle);+ −
+ −
sConfig.OCMode = TIM_OCMODE_PWM1;+ −
sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;+ −
sConfig.OCFastMode = TIM_OCFAST_DISABLE;+ −
sConfig.Pulse = 100; /* Initial brigthness of display */+ −
+ −
HAL_TIM_PWM_ConfigChannel(&TimBacklightHandle, &sConfig, TIM_BACKLIGHT_CHANNEL);+ −
HAL_TIM_PWM_Start(&TimBacklightHandle, TIM_BACKLIGHT_CHANNEL);+ −
}+ −
#endif+ −
+ −
+ −
static void EXTILine_Buttons_Config(void)+ −
{+ −
GPIO_InitTypeDef GPIO_InitStructure;+ −
+ −
BUTTON_ENTER_GPIO_ENABLE();+ −
BUTTON_NEXT_GPIO_ENABLE();+ −
BUTTON_BACK_GPIO_ENABLE();+ −
+ −
/* Configure pin as weak PULLUP input */+ −
/* buttons */+ −
GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;+ −
GPIO_InitStructure.Pull = GPIO_NOPULL;+ −
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;+ −
+ −
GPIO_InitStructure.Pin = BUTTON_ENTER_PIN;+ −
HAL_GPIO_Init(BUTTON_ENTER_GPIO_PORT, &GPIO_InitStructure);+ −
+ −
GPIO_InitStructure.Pin = BUTTON_NEXT_PIN;+ −
HAL_GPIO_Init(BUTTON_NEXT_GPIO_PORT, &GPIO_InitStructure);+ −
+ −
GPIO_InitStructure.Pin = BUTTON_BACK_PIN;+ −
HAL_GPIO_Init(BUTTON_BACK_GPIO_PORT, &GPIO_InitStructure);+ −
+ −
/* Enable and set EXTI Line0 Interrupt to the lowest priority */+ −
HAL_NVIC_SetPriority(BUTTON_ENTER_EXTI_IRQn, 2, 0);+ −
HAL_NVIC_SetPriority(BUTTON_NEXT_EXTI_IRQn, 2, 0);+ −
HAL_NVIC_SetPriority(BUTTON_BACK_EXTI_IRQn, 2, 0);+ −
HAL_NVIC_EnableIRQ(BUTTON_ENTER_EXTI_IRQn);+ −
HAL_NVIC_EnableIRQ(BUTTON_NEXT_EXTI_IRQn);+ −
HAL_NVIC_EnableIRQ(BUTTON_BACK_EXTI_IRQn);+ −
+ −
#ifdef BUTTON_CUSTOM_PIN+ −
BUTTON_CUSTOM_GPIO_ENABLE();+ −
GPIO_InitStructure.Pin = BUTTON_CUSTOM_PIN;+ −
HAL_GPIO_Init(BUTTON_CUSTOM_GPIO_PORT, &GPIO_InitStructure);+ −
HAL_NVIC_SetPriority(BUTTON_CUSTOM_EXTI_IRQn, 2, 0);+ −
HAL_NVIC_EnableIRQ(BUTTON_CUSTOM_EXTI_IRQn);+ −
#endif+ −
}+ −
+ −
+ −
/**+ −
* @brief System Clock Configuration+ −
* The system Clock is configured as follow :+ −
* System Clock source = PLL (HSE)+ −
* SYSCLK(Hz) = 180000000+ −
* HCLK(Hz) = 180000000+ −
* AHB Prescaler = 1+ −
* APB1 Prescaler = 4+ −
* APB2 Prescaler = 2+ −
* HSE Frequency(Hz) = 8000000+ −
* PLL_M = 8+ −
* PLL_N = 360+ −
* PLL_P = 2+ −
* PLL_Q = 7+ −
* VDD(V) = 3.3+ −
* Main regulator output voltage = Scale1 mode+ −
* Flash Latency(WS) = 5+ −
* The LTDC Clock is configured as follow :+ −
* PLLSAIN = 192+ −
* PLLSAIR = 4+ −
* PLLSAIDivR = 8+ −
* @param None+ −
* @retval None+ −
*/+ −
static void SystemClock_Config(void)+ −
{+ −
+ −
/* Enable Power Control clock */+ −
__PWR_CLK_ENABLE();+ −
+ −
/* The voltage scaling allows optimizing the power consumption when the device is+ −
clocked below the maximum system frequency, to update the voltage scaling value+ −
regarding system frequency refer to product datasheet. */+ −
__HAL_PWR_VOLTAGESCALING_CONFIG( PWR_REGULATOR_VOLTAGE_SCALE1 );+ −
+ −
/*##-1- System Clock Configuration #########################################*/+ −
/* Enable HighSpeed Oscillator and activate PLL with HSE/HSI as source */+ −
RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };+ −
#ifdef DISC1_BOARD+ −
// Use High Speed Internal (HSI) oscillator, running at 16MHz.+ −
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;+ −
RCC_OscInitStruct.HSIState = RCC_HSI_ON;+ −
RCC_OscInitStruct.HSICalibrationValue = 0x10;+ −
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;+ −
RCC_OscInitStruct.PLL.PLLM = 16; // HSI/16 is 1Mhz.+ −
#else+ −
// Use High Speed External oscillator, running at 8MHz+ −
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;+ −
RCC_OscInitStruct.HSEState = RCC_HSE_ON;+ −
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;+ −
RCC_OscInitStruct.PLL.PLLM = 8; // HSE/8 is 1Mhz.+ −
#endif+ −
// System clock = PLL (1MHz) * N/p = 180 MHz.+ −
RCC_OscInitStruct.PLL.PLLN = 360;+ −
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;+ −
RCC_OscInitStruct.PLL.PLLQ = 7;+ −
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;+ −
HAL_RCC_OscConfig( &RCC_OscInitStruct );+ −
+ −
// HAL_PWREx_ActivateOverDrive();+ −
HAL_PWREx_DeactivateOverDrive();+ −
+ −
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */+ −
RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 };+ −
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK+ −
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;+ −
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;+ −
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;+ −
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;+ −
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;+ −
HAL_RCC_ClockConfig( &RCC_ClkInitStruct, FLASH_LATENCY_8 ); //FLASH_LATENCY_5);+ −
+ −
/*##-2- LTDC Clock Configuration ###########################################*/+ −
/* LCD clock configuration */+ −
/* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */+ −
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */+ −
/* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/4 = 48 Mhz */+ −
/* LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDIVR_8 = 48/8 = 6 Mhz */+ −
+ −
/* neu: 8MHz/8*300/5/8 = 7,5 MHz = 19,5 Hz bei 800 x 480 */+ −
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};+ −
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;+ −
PeriphClkInitStruct.PLLSAI.PLLSAIN = 300; //192;+ −
PeriphClkInitStruct.PLLSAI.PLLSAIR = 5; //4;+ −
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;//RCC_PLLSAIDIVR_4;// RCC_PLLSAIDIVR_2; // RCC_PLLSAIDIVR_8+ −
HAL_RCCEx_PeriphCLKConfig( &PeriphClkInitStruct );+ −
}+ −
+ −
+ −
/**+ −
* @brief This function is executed in case of error occurrence.+ −
* @param None+ −
* @retval None+ −
*/+ −
static void Error_Handler(void)+ −
{+ −
/* Turn LED3 on */+ −
// BSP_LED_On(LED3);+ −
while(1)+ −
{+ −
}+ −
}+ −
+ −
/**+ −
* @brief Perform the SDRAM exernal memory inialization sequence+ −
* @param hsdram: SDRAM handle+ −
* @param Command: Pointer to SDRAM command structure+ −
* @retval None+ −
*/+ −
static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)+ −
{+ −
__IO uint32_t tmpmrd =0;+ −
/* Step 3: Configure a clock configuration enable command */+ −
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;+ −
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;+ −
Command->AutoRefreshNumber = 1;+ −
Command->ModeRegisterDefinition = 0;+ −
+ −
/* Send the command */+ −
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);+ −
+ −
/* Step 4: Insert 100 ms delay */+ −
HAL_Delay(100);+ −
+ −
/* Step 5: Configure a PALL (precharge all) command */+ −
Command->CommandMode = FMC_SDRAM_CMD_PALL;+ −
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;+ −
Command->AutoRefreshNumber = 1;+ −
Command->ModeRegisterDefinition = 0;+ −
+ −
/* Send the command */+ −
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);+ −
+ −
/* Step 6 : Configure a Auto-Refresh command */+ −
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;+ −
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;+ −
Command->AutoRefreshNumber = 4;+ −
Command->ModeRegisterDefinition = 0;+ −
+ −
/* Send the command */+ −
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);+ −
+ −
/* Step 7: Program the external memory mode register */+ −
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |+ −
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |+ −
SDRAM_MODEREG_CAS_LATENCY_3 |+ −
SDRAM_MODEREG_OPERATING_MODE_STANDARD |+ −
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;+ −
+ −
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;+ −
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;+ −
Command->AutoRefreshNumber = 1;+ −
Command->ModeRegisterDefinition = tmpmrd;+ −
+ −
/* Send the command */+ −
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);+ −
+ −
/* Step 8: Set the refresh rate counter */+ −
/* (15.62 us x Freq) - 20 */+ −
/* neu: (8 us x Freq) - 20 */+ −
/* Set the device refresh counter */+ −
HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);+ −
}+ −
+ −
+ −
/**+ −
******************************************************************************+ −
******************************************************************************+ −
******************************************************************************+ −
*/+ −
+ −
+ −
/**+ −
* @brief DMA2D configuration.+ −
* @note This function Configure tha DMA2D peripheral :+ −
* 1) Configure the transfer mode : memory to memory W/ pixel format conversion+ −
* 2) Configure the output color mode as ARGB4444+ −
* 3) Configure the output memory address at SRAM memory+ −
* 4) Configure the data size : 320x120 (pixels)+ −
* 5) Configure the input color mode as ARGB8888+ −
* 6) Configure the input memory address at FLASH memory+ −
* @retval+ −
* None+ −
*/+ −
+ −
static void SDRAM_Config(void)+ −
{+ −
/*##-1- Configure the SDRAM device #########################################*/+ −
/* SDRAM device configuration */+ −
hsdram.Instance = FMC_SDRAM_DEVICE;+ −
+ −
/* Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2) */+ −
/* TMRD: 2 Clock cycles */+ −
SDRAM_Timing.LoadToActiveDelay = 2;+ −
/* TXSR: min=70ns (6x11.90ns) */+ −
SDRAM_Timing.ExitSelfRefreshDelay = 7;+ −
/* TRAS: min=42ns (4x11.90ns) max=120k (ns) */+ −
SDRAM_Timing.SelfRefreshTime = 4;+ −
/* TRC: min=63 (6x11.90ns) */+ −
SDRAM_Timing.RowCycleDelay = 7;+ −
/* TWR: 2 Clock cycles */+ −
SDRAM_Timing.WriteRecoveryTime = 2;+ −
/* TRP: 15ns => 2x11.90ns */+ −
SDRAM_Timing.RPDelay = 2;+ −
/* TRCD: 15ns => 2x11.90ns */+ −
SDRAM_Timing.RCDDelay = 2;+ −
+ −
hsdram.Init.SDBank = FMC_SDRAM_BANK2;+ −
hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9;+ −
hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13;+ −
hsdram.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;+ −
hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;+ −
hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;+ −
hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;+ −
hsdram.Init.SDClockPeriod = SDCLOCK_PERIOD;+ −
hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;+ −
hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1;+ −
+ −
/* Initialize the SDRAM controller */+ −
if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK)+ −
{+ −
/* Initialization Error */+ −
Error_Handler();+ −
}+ −
+ −
/* Program the SDRAM external device */+ −
SDRAM_Initialization_Sequence(&hsdram, &command);+ −
}+ −
+ −
+ −
#ifdef USE_FULL_ASSERT+ −
+ −
/**+ −
* @brief Reports the name of the source file and the source line number+ −
* where the assert_param error has occurred.+ −
* @param file: pointer to the source file name+ −
* @param line: assert_param error line source number+ −
* @retval None+ −
*/+ −
void assert_failed(uint8_t* file, uint32_t line)+ −
{+ −
/* User can add his own implementation to report the file name and line number,+ −
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */+ −
+ −
/* Infinite loop */+ −
while (1)+ −
{+ −
}+ −
}+ −
#endif+ −
+ −
+ −
static void deco_loop(void)+ −
{+ −
typedef enum+ −
{+ −
CALC_VPM,+ −
CALC_VPM_FUTURE,+ −
CALC_BUEHLMANN,+ −
CALC_BUEHLMANN_FUTURE,+ −
CALC_INVALID+ −
} CALC_WHAT;+ −
+ −
static CALC_WHAT what = CALC_INVALID;+ −
static int counter = 0;+ −
if((stateUsed->mode != MODE_DIVE) || (stateUsed->diveSettings.diveMode == DIVEMODE_Apnea) || (decoLock != DECO_CALC_ready ))+ −
return;+ −
+ −
decoLock = DECO_CALC_running;+ −
+ −
if(stateDeco.diveSettings.deco_type.ub.standard == GF_MODE)+ −
{+ −
// 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))+ −
if(what == CALC_BUEHLMANN)+ −
{+ −
//Calc future+ −
what = CALC_BUEHLMANN_FUTURE;+ −
}+ −
else+ −
what = CALC_BUEHLMANN;+ −
+ −
}+ −
else+ −
{+ −
// hw 151110 mh wants future TTS even in deco zone if((what == CALC_VPM) && (!stateDeco.vpm.deco_zone_reached))+ −
if(what == CALC_VPM)+ −
{+ −
//Calc future+ −
what = CALC_VPM_FUTURE;+ −
}+ −
else+ −
what = CALC_VPM;+ −
}+ −
+ −
//In one of ten calc the other option+ −
if(counter == 10)+ −
{+ −
if(what == CALC_VPM)+ −
what = CALC_BUEHLMANN;+ −
if(what == CALC_BUEHLMANN)+ −
what = CALC_VPM;+ −
counter = 0;+ −
}+ −
+ −
decom_CreateGasChangeList(&stateDeco.diveSettings, &stateDeco.lifeData);+ −
+ −
switch(what)+ −
{+ −
case CALC_VPM:+ −
vpm_calc(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.vpm,&stateDeco.decolistVPM, DECOSTOPS);+ −
decoLock = DECO_CALC_FINSHED_vpm;+ −
return;+ −
case CALC_VPM_FUTURE:+ −
decom_tissues_exposure(stateDeco.diveSettings.future_TTS_minutes * 60,&stateDeco.lifeData);+ −
vpm_calc(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.vpm,&stateDeco.decolistFutureVPM, FUTURESTOPS);+ −
decoLock = DECO_CALC_FINSHED_Futurevpm;+ −
return;+ −
case CALC_BUEHLMANN:+ −
buehlmann_calc_deco(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.decolistBuehlmann);+ −
buehlmann_ceiling_calculator(&stateDeco.lifeData, &stateDeco.decolistBuehlmann);+ −
buehlmann_super_saturation_calculator(&stateDeco.lifeData,&stateDeco.decolistBuehlmann);+ −
decoLock = DECO_CALC_FINSHED_Buehlmann;+ −
return;+ −
case CALC_BUEHLMANN_FUTURE:+ −
decom_tissues_exposure(stateDeco.diveSettings.future_TTS_minutes * 60,&stateDeco.lifeData);+ −
buehlmann_calc_deco(&stateDeco.lifeData,&stateDeco.diveSettings,&stateDeco.decolistFutureBuehlmann);+ −
decoLock = DECO_CALC_FINSHED_FutureBuehlmann;+ −
return;+ −
default: break;+ −
}+ −
counter++;+ −
}+ −
+ −
static void resetToFirmwareUpdate(void)+ −
{+ −
__HAL_RCC_CLEAR_RESET_FLAGS();+ −
HAL_NVIC_SystemReset();+ −
}+ −
+ −
// debugging by https://blog.feabhas.com/2013/02/developing-a-generic-hard-fault-handler-for-arm-cortex-m3cortex-m4/+ −
+ −
/*+ −
void printErrorMsg(const char * errMsg)+ −
{+ −
+ −
// printf(errMsg);+ −
// return;+ −
+ −
while(*errMsg != 0){+ −
ITM_SendChar(*errMsg);+ −
++errMsg;+ −
}+ −
}+ −
+ −
enum { r0, r1, r2, r3, r12, lr, pc, psr};+ −
+ −
void stackDump(uint32_t stack[])+ −
{+ −
static char msg[80];+ −
sprintf(msg, "r0 = 0x%08x\n", stack[r0]); printErrorMsg(msg);+ −
sprintf(msg, "r1 = 0x%08x\n", stack[r1]); printErrorMsg(msg);+ −
sprintf(msg, "r2 = 0x%08x\n", stack[r2]); printErrorMsg(msg);+ −
sprintf(msg, "r3 = 0x%08x\n", stack[r3]); printErrorMsg(msg);+ −
sprintf(msg, "r12 = 0x%08x\n", stack[r12]); printErrorMsg(msg);+ −
sprintf(msg, "lr = 0x%08x\n", stack[lr]); printErrorMsg(msg);+ −
sprintf(msg, "pc = 0x%08x\n", stack[pc]); printErrorMsg(msg);+ −
sprintf(msg, "psr = 0x%08x\n", stack[psr]); printErrorMsg(msg);+ −
}+ −
+ −
void printUsageErrorMsg(uint32_t CFSRValue)+ −
{+ −
printErrorMsg("Usage fault: ");+ −
CFSRValue >>= 16; // right shift to lsb+ −
if((CFSRValue & (1 << 9)) != 0) {+ −
printErrorMsg("Divide by zero\n");+ −
}+ −
}+ −
+ −
void Hard_Fault_Handler()//uint32_t stack[])+ −
{+ −
static char msg[80];+ −
printErrorMsg("In Hard Fault Handler\n");+ −
sprintf(msg, "SCB->HFSR = 0x%08x\n", SCB->HFSR);+ −
printErrorMsg(msg);+ −
if ((SCB->HFSR & (1 << 30)) != 0) {+ −
printErrorMsg("Forced Hard Fault\n");+ −
sprintf(msg, "SCB->CFSR = 0x%08x\n", SCB->CFSR );+ −
printErrorMsg(msg);+ −
if((SCB->CFSR & 0xFFFF0000) != 0) {+ −
printUsageErrorMsg(SCB->CFSR);+ −
}+ −
}+ −
__ASM volatile("BKPT #01");+ −
while(1);+ −
}+ −
+ −
int my_store_of_MSP;+ −
+ −
void HardFault_Handler(void)+ −
{+ −
__asm ("MRS my_store_of_MSP, MSP");+ −
Hard_Fault_Handler();+ −
}+ −
*/+ −
+ −
/*+ −
__asm void HardFault_Handler(void)+ −
{+ −
TST lr, #4 // Test for MSP or PSP+ −
ITE EQ+ −
MRSEQ r0, MSP+ −
MRSNE r0, PSP+ −
B __cpp(Hard_Fault_Handler)+ −
}+ −
*/+ −
/*+ −
HardFault_Handler\+ −
PROC+ −
EXPORT HardFault_Handler+ −
B .+ −
ENDP+ −
*/+ −
+ −
/*+ −
__asm int f(int i)+ −
{+ −
ADD i, i, #1 // error+ −
}+ −
+ −
EXPORT HardFault_Handler+ −
HardFault_Handler FUNCTION+ −
MRS r0, MSP+ −
B __cpp(Hard_Fault_Handler)+ −
ENDFUNC+ −
*/+ −