changeset 5:e65d01b6a17e

MOVE files for other applications
author JeanDo
date Fri, 15 Dec 2017 01:45:20 +0100
parents 89a87ddc2e47
children b355f462c952
files .hgsubstate BootLoader/Inc/base_bootloader.h BootLoader/Inc/tInfoBootloader.h BootLoader/Src/base_bootlader.c BootLoader/Src/settings_bootloader.c BootLoader/Src/tInfoBootloader.c OtherSources/base_upperRegion.c OtherSources/data_central_mini.c OtherSources/data_exchange_main_mini.c OtherSources/firmwareEraseProgram.c OtherSources/stm32f4xx_hal_msp.c OtherSources/stm32f4xx_hal_msp_hw2.c
diffstat 12 files changed, 3816 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/.hgsubstate	Wed Dec 13 18:23:00 2017 +0100
+++ b/.hgsubstate	Fri Dec 15 01:45:20 2017 +0100
@@ -1,3 +1,3 @@
-ecedf94caf7ee0aa654b7675dfca4c2047ef4331 Common
-1a59cc1a9674ef64f9ca32c5691727def66f9c83 Discovery
+e501ab2a9b3c9c17be7ede397fbfc6904fc09be0 Common
+3a82df4793fe804f6b2891441e2a0bea30a9c336 Discovery
 14a446c4e560520adf6261cb68411284a3a964ab Small_CPU
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BootLoader/Inc/base_bootloader.h	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,101 @@
+/**
+  ******************************************************************************
+  * @file    LTDC/LTDC_Display_2Layers/Inc/main.h 
+  * @author  MCD Application Team
+  * @version V1.0.1
+  * @date    26-February-2014
+  * @brief   Header for main.c module
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+  
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef BASE_BOOTLOADER_H
+#define BASE_BOOTLOADER_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+#include "tStructure.h"
+#include "settings.h"
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* Exported macro ------------------------------------------------------------*/
+
+#define TOP_LAYER 1
+#define BACKGRD_LAYER 0
+
+#define SURFMODE 1
+#define DIVEMODE 2
+
+typedef enum 
+{
+  ST_Boot = 0,
+	ST_Surface,
+	ST_Dive,
+	ST_Menu,
+	ST_END
+} SState;
+
+typedef enum 
+{
+  ACTION_IDLE_TICK = 0,
+	ACTION_IDLE_SECOND,
+	ACTION_MODE_CHANGE,
+	ACTION_TIMEOUT,
+	ACTION_BUTTON_CUSTOM,
+	ACTION_BUTTON_BACK,
+	ACTION_BUTTON_NEXT,
+	ACTION_BUTTON_ENTER,
+	ACTION_BUTTON_ENTER_FINAL,
+	ACTION_END
+} SAction;
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+uint32_t get_globalState(void);
+void set_globalState(uint32_t newID);
+void get_globalStateList(SStateList *output);
+void set_globalState_Menu_Page(uint8_t page);
+void set_globalState_Menu_Line(uint8_t line);
+void get_idSpecificStateList(uint32_t id, SStateList *output);
+void delayMicros(uint32_t micros);
+void get_RTC_DateTime(RTC_DateTypeDef * sdatestructureget, RTC_TimeTypeDef * stimestructureget);
+void set_RTC_DateTime(RTC_DateTypeDef * sdatestructure, RTC_TimeTypeDef * stimestructure);
+uint8_t get_globalMode(void);
+void set_globalMode(uint8_t newMode);
+void set_globalState_Log_Page(uint8_t pageIsLine);
+void	set_globalState_Base(void);
+
+void set_returnFromComm(void);
+
+#endif /* BASE_BOOTLOADER_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BootLoader/Inc/tInfoBootloader.h	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,46 @@
+/**
+  ******************************************************************************
+  * @file    tInfoBootloader.h  - bootloader only -
+  * @author  heinrichs/weikamp, Christian Weikamp
+  * @version V0.0.1
+  * @date    08-Aug-2014
+  * @brief   Header file communication with PC
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
+  *
+  ******************************************************************************
+  */ 
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef TINFO_BOOTLOADER_H
+#define TINFO_BOOTLOADER_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include <stdint.h>
+/** @addtogroup Base
+  * @{
+  */
+
+/* Exported variables --------------------------------------------------------*/  
+
+
+/* Exported functions --------------------------------------------------------*/  
+
+void tInfoBootloader_init(void);
+void tInfo_newpage(const char * text);
+void tInfo_write(const char * text);
+void tInfo_button_text(const char *text_left, const char *text_mid, const char *text_right);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TINFO_BOOTLOADER_H */
+
+/************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BootLoader/Src/base_bootlader.c	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,1507 @@
+/**
+  ******************************************************************************
+	* @copyright heinrichs weikamp
+  * @file   		base_bootlader.c
+  * @author 		heinrichs/weikamp, Christian Weikamp
+  * @date   		26-February-2014
+  * @version		V1.0.4
+  * @since			09-Jan-2016
+  * @brief			The beginning of it all. main() is part of this.
+	*							 + Do the inits for hardware
+	*							 + check for button press or update process reset trigger
+	*							 + Do the inits for sub-systems like menu, dive screen etc.
+	*							 + Start IRQs
+	*							 + Start MainTasks not in IRQs
+	* @bug
+	* @warning
+  @verbatim
+	
+  ==============================================================================
+              ##### bootloader specific #####
+  ==============================================================================
+
+	151130	chsw	sleep on button3 
+								(MX_tell_reset_logik_alles_ok() + DataEX_call() in endlos loop)
+	
+	==============================================================================
+              ##### bootloader specific #####
+  ==============================================================================
+
+	Bootloader info is set right here in this file.
+	The location is 0x0800A000 instead of 0x08050000 (firmware)
+	
+	on system reset (Menu Start Bootloader in firmware) the update process
+	is started automatically if no button is pressed
+
+	if the right button is pressed the bootloader menu is started
+	
+	after update process (with update or empty) cleaning of EEPROM is started
+	afterwards the watchdog reset starts without activating the update process
+
+	bluetooth chip is started in tComm on start of the mini bootloader firmware
+	
+	SMALLCPU_CSB_PIN must be re-set to 0 to communicate with small CPU / CPU2 / RTE 
+	
+	for RealTerm to send file / firmware, Delays has to be increased to 0
+	
+	RTE update / SPI1 with DMA gave IBUSERR, now it is working fine :-) 150828
+	==============================================================================
+	from standard firmware, parts might be invalid here:
+	==============================================================================
+              ##### 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.
+
+  ==============================================================================
+              ##### 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
+
+  ==============================================================================
+              ##### specials #####
+  ==============================================================================
+  [..] There was code for vector graphics from great demos
+				(peridiummmm and jupiter) that can be fitted again
+
+	 @endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stdio.h"
+#include <string.h> // for memcopy
+
+#include "stm32f4xx_hal.h"
+#include "stm32f4xx_hal_rcc.h"
+#include "stm32f4xx_hal_flash_ex.h"
+#include "stm32f4xx_hal_wwdg.h"
+
+#include "ostc.h"
+#include "base_bootloader.h"
+#include "display.h"
+#include "gfx_engine.h"
+#include "externLogbookFlash.h"
+#include "tComm.h"
+#include "tStructure.h"
+#include "tInfoBootloader.h"
+
+#include "firmwareEraseProgram.h"
+#include "firmwareJumpToApplication.h"
+
+#include "data_exchange_main.h"
+
+/** @addtogroup OSTC 4
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+#define BUFFER_SIZE         ((uint32_t)0x00177000)
+#define WRITE_READ_ADDR     ((uint32_t)0x0000)
+#define REFRESH_COUNT       ((uint32_t)0x0569)   /* SDRAM refresh counter (90Mhz SD clock) */
+
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+	uint8_t returnFromCommCleanUpRequest = 0;
+
+const SFirmwareData FirmwareData __attribute__((at(0x08000000 + 0x0000A000))) = {
+	.firmwareVersion16to32bit.ub.first 		= 1,
+	.firmwareVersion16to32bit.ub.second 	= 0,
+	.firmwareVersion16to32bit.ub.third 		= 1,
+	.firmwareVersion16to32bit.ub.betaFlag = 1,
+
+	/* 4 bytes with trailing 0 */
+	.signature = "cw",
+	
+	.release_year = 16,
+	.release_month = 4,
+	.release_day = 8,
+	.release_sub = 0,
+	
+	/* max 48 with trailing 0 */
+	//release_info ="12345678901234567890123456789012345678901"
+	.release_info ="tComm with all",
+	
+	/* for safety reasons and coming functions*/
+	.dummy[0] = 0,
+	.dummy[1] = 0,
+	.dummy[2] = 0xEE, /* the magic byte */
+	.dummy[3] = 0xFF
+};
+
+
+const SHardwareData HardwareData __attribute__((at(HARDWAREDATA_ADDRESS))) = {
+
+	// first 52 bytes
+	.primarySerial = 0xFFFF,
+	.primaryLicence	= 0xFF,
+	.revision8bit = 0xFF,
+	.production_year = 0xFF,
+	.production_month = 0xFF,
+	.production_day = 0xFF,
+	.production_bluetooth_name_set = 0xFF,
+
+	.production_info = {
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+
+	// other 12 bytes (64 in total)
+	.secondarySerial = 0xFFFF,
+	.secondaryLicence = 0xFF,
+	.secondaryReason8bit = 0xFF,
+	.secondary_year = 0xFF,
+	.secondary_month = 0xFF,
+	.secondary_day = 0xFF,
+	.secondary_bluetooth_name_set = 0xFF,
+	.secondary_info = {0xFF,0xFF,0xFF,0xFF}
+};
+
+
+RTC_HandleTypeDef		RtcHandle;
+TIM_HandleTypeDef   TimHandle; /* used in stm32f4xx_it.c too */
+TIM_HandleTypeDef   TimBacklightHandle; /* used in stm32f4xx_it.c too */
+
+uint32_t time_before;
+uint32_t time_between;
+uint32_t time_after;
+
+/* SDRAM handler declaration */
+SDRAM_HandleTypeDef hsdram;
+FMC_SDRAM_TimingTypeDef SDRAM_Timing;
+FMC_SDRAM_CommandTypeDef command;
+
+FLASH_OBProgramInitTypeDef    OBInit;
+FLASH_AdvOBProgramInitTypeDef AdvOBInit;
+
+
+/* Private variables with external access ------------------------------------*/
+
+uint32_t globalStateID = 0;
+uint8_t globalModeID = SURFMODE;
+uint32_t time_without_button_pressed_deciseconds = 0;
+uint8_t bootToBootloader = 0;
+
+/* Private function prototypes -----------------------------------------------*/
+
+//static void LCD_ToggleFramebuffer(GFX_DrawCfgTypeDef *hconfig);
+//static void LCD_Config(GFX_DrawCfgTypeDef *hconfig);
+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 DualBoot(void);
+static void EXTILine_Buttons_Config(void);
+//static void RTC_init(void);
+static void TIM_init(void);
+static void TIM_BACKLIGHT_init(void);
+//static void TIM_BACKLIGHT_adjust(void);
+static void gotoSleep(void);
+uint8_t checkResetForFirmwareUpdate(void);
+void DeleteResetToFirmwareUpdateRegister(void);
+void reset_to_firmware_using_Watchdog(void);
+void reset_to_update_using_system_reset(void);
+
+//static void DualBootToBootloader(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);
+}
+*/
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+  * @brief   Main program
+  * @param  None
+  * @retval None
+  */
+
+void GPIO_test_I2C_lines(void)
+{
+  GPIO_InitTypeDef   GPIO_InitStructure;
+  __GPIOA_CLK_ENABLE();
+  __GPIOG_CLK_ENABLE();
+  GPIO_InitStructure.Pin = GPIO_PIN_7;
+  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStructure.Pull = GPIO_PULLUP;
+  GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
+  HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); 
+  GPIO_InitStructure.Pin = GPIO_PIN_3;
+  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); 
+
+	while(1)
+	{
+	HAL_GPIO_WritePin(GPIOG,GPIO_PIN_7,GPIO_PIN_SET);	
+	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);	
+	HAL_Delay(10);
+	HAL_GPIO_WritePin(GPIOG,GPIO_PIN_7,GPIO_PIN_RESET);	
+	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);	
+	HAL_Delay(10);
+	}
+}
+
+
+int main(void)
+{
+	
+/*
+	HAL_Init();
+  SystemClock_Config();
+GPIO_test_I2C_lines();
+*/
+	uint32_t pLayerInvisible;
+	uint32_t firmware_load_result;
+	uint8_t magicbyte = 0;
+	uint8_t callForUpdate;
+	uint8_t status = 0;
+	char textVersion[32];
+	uint8_t ptr;
+	uint32_t pOffset;
+	
+	set_globalState(StBoot0);
+
+  HAL_Init();
+  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
+
+	/* feedback for the user
+	 * aber sehr unsch�n beim Warmstart
+	 * da das letzte Bild noch lange nachleuchtet */
+//	MX_GPIO_Backlight_max_static_only_Init();
+
+
+	/* button press is only 40 to 50 us low */
+	MX_GPIO_One_Button_only_Init();
+
+	uint32_t i = 500000;
+
+	callForUpdate = __HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST);
+
+	if(callForUpdate)
+	{
+		i = 0;
+	}
+	else
+	if(			(firmware_MainCodeIsProgammed() == 0)
+			||	(hardwareDataGetPointer()->primarySerial == 0xFFFF)
+			||	(hardwareDataGetPointer()->production_bluetooth_name_set == 0xFF))
+	{
+		i = 1;
+	}
+	else
+	{
+		while(MX_GPIO_Read_The_One_Button() && i)
+		{
+			i--;
+			__NOP();
+		}
+		if(i)
+		{
+			i = 200000;
+			while(!MX_GPIO_Read_The_One_Button() && i)
+			{
+				i--;
+				__NOP();
+			}
+			if(i)
+			{
+				i = 200000;
+				while(MX_GPIO_Read_The_One_Button() && i)
+				{
+					i--;
+					__NOP();
+				}
+				if(i)
+				{
+					i = 200000;
+					while(!MX_GPIO_Read_The_One_Button() && i)
+					{
+						i--;
+						__NOP();
+					}
+					if(i)
+					{
+						i = 200000;
+						while(MX_GPIO_Read_The_One_Button() && i)
+						{
+							i--;
+							__NOP();
+						}
+					}
+				}
+			}
+		}
+	}
+	
+	if((i == 0) && (callForUpdate == 0))
+		firmware_JumpTo_Application();
+
+  SystemClock_Config();
+
+  MX_GPIO_Init();
+	MX_Bluetooth_PowerOn();
+	MX_SPI_Init();
+	SDRAM_Config();
+	HAL_Delay(100);
+
+	GFX_init1_no_DMA(&pLayerInvisible, 2);
+
+	TIM_BACKLIGHT_init();
+
+// -----------------------------
+
+	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_change_LTDC();
+	GFX_hwBackgroundOn();
+	GFX_change_LTDC();
+// -----------------------------
+	tInfoBootloader_init();
+// -----------------------------
+	if(i == 0)
+	{
+		tInfo_newpage("load firmware data");
+		uint8_t* pBuffer = (uint8_t*)((uint32_t)0xD0000000); /* blocked via  GFX_init1_no_DMA */
+		firmware_load_result = ext_flash_read_firmware(pBuffer,768000, &magicbyte);
+
+		if((firmware_load_result > 0) && (firmware_load_result < 768000) && (magicbyte == 0xEE))
+		{
+			ptr = ext_flash_read_firmware_version(textVersion);
+			textVersion[ptr++] = 'f';
+			textVersion[ptr++] = 'o';
+			textVersion[ptr++] = 'u';
+			textVersion[ptr++] = 'n';
+			textVersion[ptr++] = 'd';
+			textVersion[ptr] = 0;
+
+			tInfo_newpage(textVersion);
+			tInfo_write("erase flash");
+			status = firmware_eraseFlashMemory();
+			if(status != HAL_OK)
+			{
+				tInfo_newpage("error. try again.");
+				status = firmware_eraseFlashMemory();
+				if(status != HAL_OK)
+				{
+					tInfo_newpage("error. skip update.");
+					HAL_Delay(1000);
+				}
+			}
+			if(status == HAL_OK)
+			{
+				tInfo_write("programm flash");
+				status = firmware_programFlashMemory(pBuffer,firmware_load_result);
+				if(status != HAL_OK)
+				{
+					tInfo_newpage("error. try again.");
+					status = firmware_programFlashMemory(pBuffer,firmware_load_result);
+					if(status != HAL_OK)
+					{
+						tInfo_newpage("error. skip update.");
+						HAL_Delay(1000);
+					}
+				}
+			}
+		}
+	}
+
+	/* here comes the variable upper firmware loader */
+	if((i == 0) && (status == HAL_OK))
+	{
+		tInfo_newpage("load firmware2 data");
+		uint8_t* pBuffer = (uint8_t*)((uint32_t)0xD0000000); /* blocked via  GFX_init1_no_DMA */
+		firmware_load_result = ext_flash_read_firmware2(&pOffset, pBuffer,768000*2,0,0);
+
+		if((firmware_load_result > 0) && (firmware_load_result + pOffset <= 1024000))
+		{
+			ptr = 0;
+			ptr += gfx_number_to_string(7,0,&textVersion[ptr],firmware_load_result);
+			textVersion[ptr++] = ' ';
+			textVersion[ptr++] = 'b';
+			textVersion[ptr++] = 'y';
+			textVersion[ptr++] = 't';
+			textVersion[ptr++] = 'e';
+			textVersion[ptr++] = 's';
+			textVersion[ptr++] = ' ';
+			textVersion[ptr++] = 'w';
+			textVersion[ptr++] = 'i';
+			textVersion[ptr++] = 't';
+			textVersion[ptr++] = 'h';
+			textVersion[ptr++] = ' ';
+			ptr += gfx_number_to_string(7,0,&textVersion[ptr],pOffset);
+			textVersion[ptr++] = ' ';
+			textVersion[ptr++] = 'o';
+			textVersion[ptr++] = 'f';
+			textVersion[ptr++] = 'f';
+			textVersion[ptr++] = 's';
+			textVersion[ptr++] = 'e';
+			textVersion[ptr++] = 't';
+			textVersion[ptr] = 0;
+			tInfo_newpage(textVersion);
+
+			ptr = 0;
+			textVersion[ptr++] = 'f';
+			textVersion[ptr++] = 'o';
+			textVersion[ptr++] = 'u';
+			textVersion[ptr++] = 'n';
+			textVersion[ptr++] = 'd';
+			textVersion[ptr] = 0;
+
+			tInfo_write(textVersion);
+			tInfo_write("erase flash");
+			status = firmware2_variable_upperpart_eraseFlashMemory(firmware_load_result,pOffset);
+			if(status != HAL_OK)
+			{
+				tInfo_newpage("error. try again.");
+				status = firmware2_variable_upperpart_eraseFlashMemory(firmware_load_result,pOffset);
+				if(status != HAL_OK)
+				{
+					tInfo_newpage("error. skip update.");
+					HAL_Delay(1000);
+				}
+			}
+			if(status == HAL_OK)
+			{
+				tInfo_write("programm flash");
+				status = firmware2_variable_upperpart_programFlashMemory(firmware_load_result,pOffset,pBuffer,firmware_load_result,0);
+				if(status != HAL_OK)
+				{
+					tInfo_newpage("error. try again.");
+					status = firmware2_variable_upperpart_programFlashMemory(firmware_load_result,pOffset,pBuffer,firmware_load_result,0);
+					if(status != HAL_OK)
+					{
+						tInfo_newpage("error. skip update.");
+						HAL_Delay(1000);
+					}
+				}
+			}
+		}
+	}
+
+	if((i == 0) && (status == HAL_OK))
+	{
+		tInfo_newpage("Done.");
+		tInfo_write("Cleaning.");
+		ext_flash_erase_firmware_if_not_empty();
+		ext_flash_erase_firmware2_if_not_empty();
+		tInfo_write("Reset device.");
+		reset_to_firmware_using_Watchdog();
+	}
+
+	ptr = 0;
+	textVersion[ptr++] = '\021';
+	textVersion[ptr++] = 's';
+	textVersion[ptr++] = 'e';
+	textVersion[ptr++] = 'r';
+	textVersion[ptr++] = 'i';
+	textVersion[ptr++] = 'a';
+	textVersion[ptr++] = 'l';
+	textVersion[ptr++] = ' ';
+	if(HardwareData.primarySerial == 0xFFFF)
+	{
+		textVersion[ptr++] = 'n';
+		textVersion[ptr++] = 'o';
+		textVersion[ptr++] = 't';
+		textVersion[ptr++] = ' ';
+		textVersion[ptr++] = 's';
+		textVersion[ptr++] = 'e';
+		textVersion[ptr++] = 't';
+	}
+	else if(HardwareData.secondarySerial == 0xFFFF)
+	{
+		textVersion[ptr++] = '#';
+		ptr += gfx_number_to_string(5,1,&textVersion[ptr],HardwareData.primarySerial);
+	}
+	else
+	{
+		textVersion[ptr++] = '#';
+		ptr += gfx_number_to_string(5,1,&textVersion[ptr],HardwareData.secondarySerial);
+		textVersion[ptr++] = ' ';
+		textVersion[ptr++] = '(';
+		ptr += gfx_number_to_string(5,1,&textVersion[ptr],HardwareData.primarySerial);
+		textVersion[ptr++] = ')';
+	}
+	textVersion[ptr++] = '\020';
+	textVersion[ptr] = 0;
+
+	tInfo_button_text("Exit","","Sleep");
+	tInfo_newpage("Bootloader 160602");
+	tInfo_write("start bluetooth");
+	tInfo_write("");
+	tInfo_write(textVersion);
+	tInfo_write("");
+	
+	TIM_init();
+	MX_UART_Init();
+	MX_Bluetooth_PowerOn();
+	tComm_Set_Bluetooth_Name(0);
+	
+	tComm_init();
+	set_globalState_Base();
+
+	GFX_start_VSYNC_IRQ();
+
+	EXTILine_Buttons_Config();
+/*	
+  uint8_t* pBuffer1 = (uint8_t*)getFrame(20);
+	firmware_load_result = ext_flash_read_firmware(pBuffer1,768000);
+	
+	if((firmware_load_result > 0) && (firmware_load_result < 768000))
+	{
+		firmware_eraseFlashMemory();
+		firmware_programFlashMemory(pBuffer1,firmware_load_result);
+		// not for testing
+		//ext_flash_erase_firmware_if_not_empty();
+    reset_to_firmware_using_Watchdog();  
+	}
+*/
+	while(1)
+	{
+//		if(bootToBootloader)
+//			DualBootToBootloader();
+
+		if(bootToBootloader)
+			reset_to_update_using_system_reset();
+				
+		tComm_control(); // will stop while loop if tComm Mode started until exit from UART
+	};
+}
+
+
+void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
+{
+
+	SStateList status;
+
+	get_globalStateList(&status);
+
+	switch(status.base)
+	{
+		default:
+//			TIM_BACKLIGHT_adjust();
+			break;
+	}
+
+	if(returnFromCommCleanUpRequest)
+	{
+		tComm_exit();
+		returnFromCommCleanUpRequest = 0;
+		GFX_hwBackgroundOn();
+		tInfo_button_text("Exit","","Sleep");
+		tInfo_newpage("bluetooth disonnected");
+		tInfo_write("");
+		tInfo_write("");
+		tInfo_write("");
+		tInfo_write("");
+	}
+	
+	get_globalStateList(&status);
+
+	switch(status.base)
+	{
+		case BaseComm:
+			if(get_globalState() == StUART_STANDARD)
+			 tComm_refresh();
+			break;
+		default:
+			break;
+	}
+}
+
+void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+	uint8_t action;
+	SStateList status;
+	static uint8_t counterToPreventSleep = 0;
+  if(GPIO_Pin == VSYNC_IRQ_PIN) // rechts, unten
+	{
+		GFX_change_LTDC();
+		housekeepingFrame();
+		if(counterToPreventSleep < 250)
+			counterToPreventSleep++;
+		else
+		if(counterToPreventSleep != 255)
+		{
+			counterToPreventSleep = 255;
+		}
+		
+		return;
+	}
+
+	time_without_button_pressed_deciseconds	= 0;
+
+	if(GFX_logoStatus() != 0)
+		return;
+
+  if(GPIO_Pin == BUTTON_BACK_PIN) // links
+		action = ACTION_BUTTON_BACK;
+	else
+  if(GPIO_Pin == BUTTON_ENTER_PIN) // mitte
+		action = ACTION_BUTTON_ENTER;
+	else
+  if(GPIO_Pin == BUTTON_NEXT_PIN) // rechts
+		action = ACTION_BUTTON_NEXT;
+#ifdef BUTTON_CUSTOM_PIN
+	else
+  if(GPIO_Pin == BUTTON_CUSTOM_PIN) // extra
+		action = ACTION_BUTTON_CUSTOM;
+#endif
+	else
+		action = 0;
+	get_globalStateList(&status);
+
+	switch(status.base)
+	{
+		case BaseComm:
+			if(action == ACTION_BUTTON_BACK)
+			{
+				reset_to_firmware_using_Watchdog();
+			}
+		 break;
+			
+		default:
+			if((action == ACTION_BUTTON_NEXT) && (counterToPreventSleep == 255) && (get_globalState() == StS))
+			{
+				while(1)
+				{
+					MX_tell_reset_logik_alles_ok();
+					DataEX_call();
+					HAL_Delay(100);
+				}
+			}
+			else
+			if(action == ACTION_BUTTON_BACK)
+			{
+				reset_to_firmware_using_Watchdog();
+			}
+			else
+			if(action == ACTION_BUTTON_CUSTOM)
+			{
+				if(get_globalState() == StS)
+					gotoSleep();
+			}
+			else
+			if(action == ACTION_BUTTON_ENTER)
+			{
+				reset_to_update_using_system_reset();
+			}
+			break;
+	}
+}
+
+
+void gotoSleep(void)
+{
+	ext_flash_erase_firmware_if_not_empty();
+	set_globalState(StStop);
+}
+
+// -----------------------------
+
+
+void MainBootLoaderInit(void)
+{
+	void (*SysMemBootJump)(void);
+	SysMemBootJump=(void (*)(void)) (*((uint32_t *) 0x1fff0004));
+
+	// DMA, SPI, UART, TIM, ExtIRQ, graphics DMA, LTDC
+
+	HAL_RCC_DeInit();
+	SysTick->CTRL = 0;
+	SysTick->LOAD = 0;
+	SysTick->VAL = 0;
+
+	__set_PRIMASK(1);
+
+	__set_MSP(0x20002318);
+	SysMemBootJump();
+}
+
+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_Base(void)
+{
+	set_globalState(StS);
+}
+
+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 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();
+  }
+}
+
+#ifndef TIM_BACKLIGHT
+/*
+static void TIM_BACKLIGHT_adjust(void)
+{
+}
+*/
+static void TIM_BACKLIGHT_init(void)
+{
+}
+#else
+/*
+static void TIM_BACKLIGHT_adjust(void)
+{
+
+	TIM_OC_InitTypeDef sConfig;
+	sConfig.OCMode     = TIM_OCMODE_PWM1;
+  sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
+  sConfig.OCFastMode = TIM_OCFAST_DISABLE;
+	sConfig.Pulse = 600;
+
+	HAL_TIM_PWM_ConfigChannel(&TimBacklightHandle, &sConfig, TIM_BACKLIGHT_CHANNEL);
+	HAL_TIM_PWM_Start(&TimBacklightHandle, TIM_BACKLIGHT_CHANNEL);
+}
+*/
+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 = 50 * 6;
+
+	HAL_TIM_PWM_ConfigChannel(&TimBacklightHandle, &sConfig, TIM_BACKLIGHT_CHANNEL);
+	HAL_TIM_PWM_Start(&TimBacklightHandle, TIM_BACKLIGHT_CHANNEL);
+}
+#endif
+
+  /* Configure RTC prescaler and RTC data registers */
+  /* RTC configured as follow:
+      - Hour Format    = Format 24
+      - Asynch Prediv  = Value according to source clock
+      - Synch Prediv   = Value according to source clock
+      - OutPut         = Output Disable
+      - OutPutPolarity = High Polarity
+      - OutPutType     = Open Drain */
+	/*#define RTC_ASYNCH_PREDIV  0x7F    LSE as RTC clock */
+	/*LSE: #define RTC_SYNCH_PREDIV   0x00FF  LSE as RTC clock */
+	/*LSI: #define RTC_SYNCH_PREDIV   0x0130  LSI as RTC clock */
+/*
+static void RTC_init(void)
+{
+  RtcHandle.Instance = RTC;
+
+
+  RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
+  RtcHandle.Init.AsynchPrediv = 0x7F;
+  RtcHandle.Init.SynchPrediv = 0x0130;
+  RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
+  RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
+  RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
+
+  if(HAL_RTC_Init(&RtcHandle) != HAL_OK)
+  {
+    Error_Handler();
+  }
+}
+*/
+
+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)
+{
+  RCC_ClkInitTypeDef RCC_ClkInitStruct;
+  RCC_OscInitTypeDef RCC_OscInitStruct;
+  RCC_PeriphCLKInitTypeDef  PeriphClkInitStruct;
+
+  /* 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 HSE Oscillator and activate PLL with HSE as source */
+  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+  RCC_OscInitStruct.PLL.PLLM = 8;
+  RCC_OscInitStruct.PLL.PLLN = 336;//360;
+  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
+  RCC_OscInitStruct.PLL.PLLQ = 7;
+  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_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 */ 
+  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);
+}
+
+/*
+static void DualBoot(void)
+{
+    // Set BFB2 bit to enable boot from Flash Bank2
+    // Allow Access to Flash control registers and user Falsh
+    HAL_FLASH_Unlock();
+
+    // Allow Access to option bytes sector
+    HAL_FLASH_OB_Unlock();
+
+    // Get the Dual boot configuration status
+    AdvOBInit.OptionType = OBEX_BOOTCONFIG;
+    HAL_FLASHEx_AdvOBGetConfig(&AdvOBInit);
+
+    // Enable/Disable dual boot feature
+    if (((AdvOBInit.BootConfig) & (FLASH_OPTCR_BFB2)) == FLASH_OPTCR_BFB2)
+    {
+      AdvOBInit.BootConfig = OB_DUAL_BOOT_DISABLE;
+      HAL_FLASHEx_AdvOBProgram (&AdvOBInit);
+    }
+    else
+    {
+      AdvOBInit.BootConfig = OB_DUAL_BOOT_ENABLE;
+      HAL_FLASHEx_AdvOBProgram (&AdvOBInit);
+    }
+
+    // Start the Option Bytes programming process
+    if (HAL_FLASH_OB_Launch() != HAL_OK)
+    {
+      // User can add here some code to deal with this error
+      while (1)
+      {
+      }
+    }
+    // Prevent Access to option bytes sector
+    HAL_FLASH_OB_Lock();
+
+    // Disable the Flash option control register access (recommended to protect
+    // the option Bytes against possible unwanted operations)
+    HAL_FLASH_Lock();
+
+    // Initiates a system reset request to reset the MCU
+    reset_to_firmware_using_Watchdog();
+}
+*/
+/**
+  ******************************************************************************
+  ******************************************************************************
+  ******************************************************************************
+  */
+
+
+/**
+  * @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);
+}
+
+
+uint8_t checkResetForFirmwareUpdate(void)
+{
+	uint32_t backupRegisterContent;
+	
+	RTC_HandleTypeDef RtcHandle;
+	RtcHandle.Instance = RTC;
+	backupRegisterContent = HAL_RTCEx_BKUPRead(&RtcHandle,RTC_BKP_DR0);
+	
+	if(backupRegisterContent == 0x12345678)
+		return 1;
+	else
+		return 0;
+}
+
+void DeleteResetToFirmwareUpdateRegister(void)
+{
+	RTC_HandleTypeDef RtcHandle;
+	RtcHandle.Instance = RTC;
+  __HAL_RTC_WRITEPROTECTION_DISABLE(&RtcHandle);
+	HAL_RTCEx_BKUPWrite(&RtcHandle,RTC_BKP_DR0,0x00);
+  __HAL_RTC_WRITEPROTECTION_ENABLE(&RtcHandle);
+}
+
+#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 DualBootToBootloader(void)
+{
+    // Set BFB2 bit to enable boot from Flash Bank2
+    // Allow Access to Flash control registers and user Falsh
+    HAL_FLASH_Unlock();
+  
+    // Allow Access to option bytes sector
+    HAL_FLASH_OB_Unlock();
+    
+    // Get the Dual boot configuration status
+    AdvOBInit.OptionType = OPTIONBYTE_BOOTCONFIG;
+    HAL_FLASHEx_AdvOBGetConfig(&AdvOBInit);
+
+    // Enable/Disable dual boot feature
+		if (((AdvOBInit.BootConfig) & (FLASH_OPTCR_BFB2)) == FLASH_OPTCR_BFB2)
+    {
+      AdvOBInit.BootConfig = OB_DUAL_BOOT_DISABLE;
+      HAL_FLASHEx_AdvOBProgram (&AdvOBInit);
+			if (HAL_FLASH_OB_Launch() != HAL_OK)
+			{
+				while (1)
+				{
+				}
+			}
+    }
+    else
+    {
+
+      AdvOBInit.BootConfig = OB_DUAL_BOOT_ENABLE;
+      HAL_FLASHEx_AdvOBProgram (&AdvOBInit);
+			if (HAL_FLASH_OB_Launch() != HAL_OK)
+			{
+				while (1)
+				{
+				}
+			}
+		}
+    
+    // Prevent Access to option bytes sector
+    HAL_FLASH_OB_Lock();
+    
+    / Disable the Flash option control register access (recommended to protect 
+    // the option Bytes against possible unwanted operations)
+    HAL_FLASH_Lock();    
+    
+    // Initiates a system reset request to reset the MCU
+    reset_to_firmware_using_Watchdog();  
+}
+*/
+
+void reset_to_update_using_system_reset(void)
+{
+	__HAL_RCC_CLEAR_RESET_FLAGS();
+	HAL_NVIC_SystemReset();
+}
+
+void reset_to_firmware_using_Watchdog(void)
+{
+	__HAL_RCC_CLEAR_RESET_FLAGS();
+  __HAL_RCC_WWDG_CLK_ENABLE();
+
+	WWDG_HandleTypeDef   WwdgHandle;
+	WwdgHandle.Instance = WWDG;
+
+  WwdgHandle.Init.Prescaler = WWDG_PRESCALER_8;
+  WwdgHandle.Init.Window    = 80;
+  WwdgHandle.Init.Counter   = 127;
+  
+  HAL_WWDG_Init(&WwdgHandle);
+	HAL_WWDG_Start(&WwdgHandle);
+	while(1);
+}
+
+
+void set_returnFromComm(void)
+{
+	returnFromCommCleanUpRequest = 1;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BootLoader/Src/settings_bootloader.c	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,47 @@
+/**
+  ******************************************************************************
+	* @copyright	heinrichs weikamp
+  * @file   		settings_bootloader.c
+  * @author 		heinrichs/weikamp, Christian Weikamp
+  * @date				21-March-2016
+  * @version		V1.0.1
+  * @since			24-Oct-2016
+  * @brief			mini version for firmwareDataGetPointer() etc.
+	*							1.0.1 getLicence() included
+  ******************************************************************************
+  */
+
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "settings.h"
+
+
+/* always at 0x8080000, do not move -> bootloader access */
+const SFirmwareData* firmwareDataGetPointer(void)
+{
+	return (const SFirmwareData*)(0x08040000 + 0x00010000);
+}	
+
+
+void getActualRTEandFONTversion(uint8_t *RTEhigh, uint8_t *RTElow, uint8_t *FONThigh, uint8_t *FONTlow)
+{
+	if(RTEhigh && RTElow)
+	{
+		*RTEhigh = 0;
+		*RTElow = 0;
+	}
+	if(FONThigh && FONTlow)
+	{
+		*FONThigh = *(uint8_t *)0x08132000;
+		*FONTlow = *(uint8_t *)0x08132001;
+	}
+}
+
+
+uint8_t getLicence(void)
+{
+//return 0xFF;
+//return LICENCEBONEX;
+	return hardwareDataGetPointer()->primaryLicence;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BootLoader/Src/tInfoBootloader.c	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,123 @@
+/**
+  ******************************************************************************
+  * @file    tInfoBootloader.c
+  * @author  heinrichs/weikamp, Christian Weikamp
+  * @version V0.0.1
+  * @date    08-May-2015
+  * @brief   Write something on the screen in between steps
+  *
+  @verbatim
+  ==============================================================================
+                        ##### How to use #####
+  ==============================================================================
+	* a little bit of text (DMA is not running for fast clean)
+	@endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 heinrichs weikamp</center></h2>
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "base_bootloader.h"
+#include "ostc.h"
+#include "tInfoBootloader.h"
+#include "gfx_engine.h"
+#include "gfx_colors.h"
+/* Exported variables --------------------------------------------------------*/
+
+/* Private variables ---------------------------------------------------------*/
+
+	GFX_DrawCfgScreen	tIBscreen;
+	GFX_DrawCfgWindow	tIBwindow;
+	uint8_t line = 1;
+	
+	char textButtonLeft[30] = { 0 };
+	char textButtonMid[31] = { 0 };
+	char textButtonRight[31] = { 0 };
+
+/* Private types -------------------------------------------------------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+
+void tInfoBootloader_init(void)
+{
+	tIBscreen.FBStartAdress = 0;
+	tIBscreen.ImageHeight = 480;
+	tIBscreen.ImageWidth = 800;
+	tIBscreen.LayerIndex = 1;
+
+	tIBwindow.Image = &tIBscreen;
+	tIBwindow.WindowNumberOfTextLines = 6;
+	tIBwindow.WindowLineSpacing = 65;
+	tIBwindow.WindowTab = 400;
+	tIBwindow.WindowX0 = 20;
+	tIBwindow.WindowX1 = 779;
+	tIBwindow.WindowY0 = 0;
+	tIBwindow.WindowY1 = 799;
+	
+	line = 1;
+}
+
+
+void tInfo_button_text(const char *text_left, const char *text_mid, const char *text_right)
+{
+	if(text_left)
+		strncpy(textButtonLeft,text_left,30);
+	if(text_mid)
+	{
+		textButtonMid[0] = '\001';
+		strncpy(&textButtonMid[1],text_mid,30);
+	}
+	if(text_right)
+	{
+		textButtonRight[0] = '\002';
+		strncpy(&textButtonRight[1],text_right,30);
+	}
+}
+
+
+void tInfo_newpage(const char *text)
+{
+	uint32_t backup  = tIBscreen.FBStartAdress;
+	
+	tIBscreen.FBStartAdress = getFrame(18);
+	line = 1;
+	if(text)
+		GFX_write_string(&FontT48, &tIBwindow, text,line);
+	line++;
+
+	if(*textButtonLeft)
+		write_content_simple(&tIBscreen, 0, 800, 480-24, &FontT24,textButtonLeft,CLUT_ButtonSurfaceScreen);
+	if(*textButtonMid)
+		write_content_simple(&tIBscreen, 0, 800, 480-24, &FontT24,textButtonMid,CLUT_ButtonSurfaceScreen);
+	if(*textButtonRight)
+		write_content_simple(&tIBscreen, 0, 800, 480-24, &FontT24,textButtonRight,CLUT_ButtonSurfaceScreen);
+	
+	GFX_SetFrameTop(tIBscreen.FBStartAdress);
+	GFX_change_LTDC();
+	
+	if(backup != 0)
+			releaseFrame(18,backup);
+}
+
+
+void tInfo_write(const char *text)
+{
+	if((line > 6) || (tIBscreen.FBStartAdress == 0))
+		tInfo_newpage(text);
+	else
+	{
+		if(text)
+			GFX_write_string(&FontT48, &tIBwindow, text,line);
+		line++;
+
+	}	
+}
+
+/* Private functions ---------------------------------------------------------*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OtherSources/base_upperRegion.c	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,129 @@
+/**
+  ******************************************************************************
+	* @copyright heinrichs weikamp
+  * @file   		base_upperRegion.c
+  * @author 		heinrichs/weikamp, Christian Weikamp
+  * @date   		31-August-2015
+  * @version		V0.0.3
+  * @since			03-Dez-2016
+  * @brief			The beginning of it all. main() is part of this.
+	* @bug
+	* @warning
+  @verbatim
+  ==============================================================================
+              ##### New characters in fonts #####
+  ==============================================================================
+  [..] Use font_tmore.c and add line to corresponding font like font_t54c
+			 Don't forget to adjust the length of the font in the last line starting
+			 const tFont .....
+
+	[..] last char vor der großen Lücke, Stand 160217 
+			 image_data_FontT24_0x002b[364]
+			 __attribute__((at( START_T24_FONT + (1647 * 28) ))), START_T24_FONT  (0x08142F00 - MINUS_BANK)
+
+			 -> frei ab 0x0814E490
+			 geht dann weiter mit image_data_ostc_fuer_Tauchcomputer_240px
+			 sind ca. 120 kByte frei!
+			 
+	 @endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stdio.h"
+#include <string.h> // for memcopy
+
+#include "stm32f4xx_hal.h"
+#include "gfx_engine.h"
+
+/* HINT chsw 160114
+ * using Jef Driesen dctool.exe I found out that from 150K to 230K there is only '0's!!!
+ */
+ 
+#define VARIABLE_UPPER_REGION
+//#define FIXED_UPPER_REGION
+
+#ifdef VARIABLE_UPPER_REGION
+//static const uint8_t image_data_HelloWorld[] __attribute__((at(0x08132000 )))  = "Hello World    ";
+
+typedef struct
+{
+	uint8_t versionFirst;
+	uint8_t versionSecond;
+	uint8_t versionNOTUSED;
+	uint8_t versionBeta;
+	uint8_t signature[4];
+	uint8_t release_year;
+	uint8_t release_month;
+	uint8_t release_day;
+	uint8_t release_sub;
+	char release_info[48];
+	char dummy[4];
+} SHelloWorldData;
+
+static const SHelloWorldData FirmwareData __attribute__((at(0x08132000))) = {
+
+	.versionFirst		= 0,
+	.versionSecond	= 9,
+	.versionNOTUSED	= 0,
+	.versionBeta		= 0,
+
+	/* 4 bytes with trailing 0 */
+	.signature = "cw",
+	
+	.release_year = 16,
+	.release_month = 1,
+	.release_day = 13,
+	.release_sub = 0,
+	
+	/* max 48 with trailing 0 */
+	//release_info ="12345678901234567890123456789012345678901"
+	.release_info  ="",
+	
+	/* for safety reasons and coming functions */
+	.dummy[0] = 0,
+	.dummy[1] = 0,
+	.dummy[2] = 0xF0, /* the magic byte for fonts*/
+	.dummy[3] = 0xFF
+};
+static const uint8_t image_data_end_of_header[] __attribute__((at(0x0813217e - 5 )))  = "chsw";
+
+
+// at the moment 09. Sept. 2015, font_T144_plus is the first code starting at 0x0813217e
+#include "font_T144_plus.c"			// 0x0813217e, max. 69 kB
+#include "font_T24.c"						// 0x08142F00  max. 47 kB
+// grosse Lücke von 120 kB
+#include "image_ostc.c"					// 0x0816BAD2
+#include "font_T84.c" 					// 0x08170000
+#include "font_T54.c"						// 0x081762EE
+#include "font_T105.c"					// 0x0817bd00
+// der letzte Font ist T42, dahinter ist Platz von 0x081aa5a0 (Stand 151214) bis 0x081DFFFF
+#include "font_T42.c"						// 0x0818f9c0
+// starts at BASE_TMORE = 0x081aa5a0, defined in fontT_config.h
+#include "font_Tmore.c"					// 0x081aa5a0
+
+
+// im regulären unteren Speicher
+// for checked / unchecked only at the moment
+//#include "font_awe48.c"
+//#include "battery2_complete.c"
+#endif
+
+// starts at 0x081E0000
+#ifdef FIXED_UPPER_REGION
+#include "font_T48_plus.c"
+#include "image_heinrichs_weikamp.c" /* with no fixed region color lookup table */
+#endif
+
+
+int main(void) //__attribute__((at(0x08000000)))
+{
+}
+	
+
+/************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OtherSources/data_central_mini.c	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,224 @@
+/**
+  ******************************************************************************
+	* @copyright heinrichs weikamp
+  * @file   		data_central_mini.c   - bootloader only -
+  * @author 		heinrichs/weikamp, Christian Weikamp
+  * @date   		10-November-2014
+  * @version		V1.0.3
+  * @since			10-Nov-2014
+  * @brief	
+	* @bug
+	* @warning
+  @verbatim
+  
+	 @endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 heinrichs weikamp</center></h2>
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h>
+#include "data_central.h"
+#include "stm32f4xx_hal.h"
+#include "crcmodel.h"
+
+void translateDate(uint32_t datetmpreg, RTC_DateTypeDef *sDate)
+{
+  datetmpreg = (uint32_t)(datetmpreg & RTC_DR_RESERVED_MASK);
+
+  /* Fill the structure fields with the read parameters */
+  sDate->Year = (uint8_t)((datetmpreg & (RTC_DR_YT | RTC_DR_YU)) >> 16);
+  sDate->Month = (uint8_t)((datetmpreg & (RTC_DR_MT | RTC_DR_MU)) >> 8);
+  sDate->Date = (uint8_t)(datetmpreg & (RTC_DR_DT | RTC_DR_DU));
+  sDate->WeekDay = (uint8_t)((datetmpreg & (RTC_DR_WDU)) >> 13);
+
+	/* Convert the date structure parameters to Binary format */
+	sDate->Year = (uint8_t)RTC_Bcd2ToByte(sDate->Year);
+	sDate->Month = (uint8_t)RTC_Bcd2ToByte(sDate->Month);
+	sDate->Date = (uint8_t)RTC_Bcd2ToByte(sDate->Date);
+}
+
+void translateTime(uint32_t tmpreg, RTC_TimeTypeDef *sTime)
+{
+  tmpreg = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK);
+
+  /* Fill the structure fields with the read parameters */
+  sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16);
+  sTime->Minutes = (uint8_t)((tmpreg & (RTC_TR_MNT | RTC_TR_MNU)) >>8);
+  sTime->Seconds = (uint8_t)(tmpreg & (RTC_TR_ST | RTC_TR_SU));
+  sTime->TimeFormat = (uint8_t)((tmpreg & (RTC_TR_PM)) >> 16);
+
+	/* Convert the time structure parameters to Binary format */
+	sTime->Hours = (uint8_t)RTC_Bcd2ToByte(sTime->Hours);
+	sTime->Minutes = (uint8_t)RTC_Bcd2ToByte(sTime->Minutes);
+	sTime->Seconds = (uint8_t)RTC_Bcd2ToByte(sTime->Seconds);
+  sTime->SubSeconds = 0;
+}
+
+
+/* This is derived from crc32b but does table lookup. First the table
+itself is calculated, if it has not yet been set up.
+Not counting the table setup (which would probably be a separate
+function), when compiled to Cyclops with GCC, this function executes in
+7 + 13n instructions, where n is the number of bytes in the input
+message. It should be doable in 4 + 9n instructions. In any case, two
+of the 13 or 9 instrucions are load byte.
+   This is Figure 14-7 in the text. */
+
+/* http://www.hackersdelight.org/ i guess ;-)  *chsw */
+
+uint32_t crc32c_checksum(uint8_t* message, uint16_t length, uint8_t* message2, uint16_t length2) {
+	int i, j;
+	uint32_t byte, crc, mask;
+	static unsigned int table[256] = {0};
+
+	/* Set up the table, if necessary. */
+	if (table[1] == 0) {
+		for (byte = 0; byte <= 255; byte++) {
+			 crc = byte;
+			 for (j = 7; j >= 0; j--) {    // Do eight times.
+					mask = -(crc & 1);
+					crc = (crc >> 1) ^ (0xEDB88320 & mask);
+			 }
+			 table[byte] = crc;
+		}
+	}
+
+	/* Through with table setup, now calculate the CRC. */
+	i = 0;
+	crc = 0xFFFFFFFF;
+	while (length--) {
+		byte = message[i];
+		crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF];
+		i = i + 1;
+	}
+	if(length2)
+	{
+	 i = 0;
+	 while (length2--) {
+			byte = message2[i];
+			crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF];
+			i = i + 1;
+	 }
+	}
+	return ~crc;
+}
+
+
+uint32_t	CRC_CalcBlockCRC_moreThan768000(uint32_t *buffer1, uint32_t *buffer2, uint32_t words)
+{
+ cm_t        crc_model;
+ uint32_t      word_to_do;
+ uint8_t       byte_to_do;
+ int         i;
+ 
+     // Values for the STM32F generator.
+ 
+     crc_model.cm_width = 32;            // 32-bit CRC
+     crc_model.cm_poly  = 0x04C11DB7;    // CRC-32 polynomial
+     crc_model.cm_init  = 0xFFFFFFFF;    // CRC initialized to 1's
+     crc_model.cm_refin = FALSE;         // CRC calculated MSB first
+     crc_model.cm_refot = FALSE;         // Final result is not bit-reversed
+     crc_model.cm_xorot = 0x00000000;    // Final result XOR'ed with this
+ 
+     cm_ini(&crc_model);
+ 
+     while (words--)
+     {
+         // The STM32F10x hardware does 32-bit words at a time!!!
+				if(words > (768000/4))
+					word_to_do = *buffer2++;
+				else
+					word_to_do = *buffer1++;
+ 
+         // Do all bytes in the 32-bit word.
+ 
+         for (i = 0; i < sizeof(word_to_do); i++)
+         {
+             // We calculate a *byte* at a time. If the CRC is MSB first we
+             // do the next MS byte and vica-versa.
+ 
+             if (crc_model.cm_refin == FALSE)
+             {
+                 // MSB first. Do the next MS byte.
+ 
+                 byte_to_do = (uint8_t) ((word_to_do & 0xFF000000) >> 24);
+                 word_to_do <<= 8;
+             }
+             else
+             {
+                 // LSB first. Do the next LS byte.
+ 
+                 byte_to_do = (uint8_t) (word_to_do & 0x000000FF);
+                 word_to_do >>= 8;
+             }
+ 
+             cm_nxt(&crc_model, byte_to_do);
+         }
+     }
+ 
+     // Return the final result.
+ 
+     return (cm_crc(&crc_model));
+}
+ 
+
+uint32_t	CRC_CalcBlockCRC(uint32_t *buffer, uint32_t words)
+{
+ cm_t        crc_model;
+ uint32_t      word_to_do;
+ uint8_t       byte_to_do;
+ int         i;
+ 
+     // Values for the STM32F generator.
+ 
+     crc_model.cm_width = 32;            // 32-bit CRC
+     crc_model.cm_poly  = 0x04C11DB7;    // CRC-32 polynomial
+     crc_model.cm_init  = 0xFFFFFFFF;    // CRC initialized to 1's
+     crc_model.cm_refin = FALSE;         // CRC calculated MSB first
+     crc_model.cm_refot = FALSE;         // Final result is not bit-reversed
+     crc_model.cm_xorot = 0x00000000;    // Final result XOR'ed with this
+ 
+     cm_ini(&crc_model);
+ 
+     while (words--)
+     {
+         // The STM32F10x hardware does 32-bit words at a time!!!
+ 
+         word_to_do = *buffer++;
+ 
+         // Do all bytes in the 32-bit word.
+ 
+         for (i = 0; i < sizeof(word_to_do); i++)
+         {
+             // We calculate a *byte* at a time. If the CRC is MSB first we
+             // do the next MS byte and vica-versa.
+ 
+             if (crc_model.cm_refin == FALSE)
+             {
+                 // MSB first. Do the next MS byte.
+ 
+                 byte_to_do = (uint8_t) ((word_to_do & 0xFF000000) >> 24);
+                 word_to_do <<= 8;
+             }
+             else
+             {
+                 // LSB first. Do the next LS byte.
+ 
+                 byte_to_do = (uint8_t) (word_to_do & 0x000000FF);
+                 word_to_do >>= 8;
+             }
+ 
+             cm_nxt(&crc_model, byte_to_do);
+         }
+     }
+ 
+     // Return the final result.
+ 
+     return (cm_crc(&crc_model));
+}
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OtherSources/data_exchange_main_mini.c	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,130 @@
+/**
+  ******************************************************************************
+  * @file    data_exchange_main.c
+  * @author  heinrichs/weikamp, Christian Weikamp
+  * @date    13-Oct-2014
+  * @version V0.0.2
+  * @since   27-May-2015
+
+	* @brief   Communication with the second CPU == RTE system
+  *
+  @verbatim
+  ==============================================================================
+                        ##### How to use #####
+  ==============================================================================
+
+  ==============================================================================
+                        ##### Device Data #####
+  ==============================================================================
+	
+	main CPU always sends the device data info that it has at the moment
+
+		on start it is INT32_MIN, INT32_MAX and 0 
+		as initialized  in data_central.c variable declaration
+	
+	second small CPU gets request to send its device data
+		
+		on receiption the data is merged with the data in externLogbookFlash,
+		stored on the externLogbookFlash and from now on send to small CPU
+
+	@endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include <string.h> // for memcopy
+#include "stm32f4xx_hal.h"
+#include "stdio.h"
+#include "ostc.h"
+#include "data_central.h"
+#include "data_exchange_main.h"
+#include "base.h"
+#include "externLogbookFlash.h"
+
+
+/* Expoted variables --------------------------------------------------------*/
+
+/* Private variables ---------------------------------------------------------*/
+
+SDataReceiveFromMaster dataOut;
+SDataExchangeSlaveToMaster dataIn;
+
+uint8_t data_old__lost_connection_to_slave_counter_temp = 0;
+/* Private types -------------------------------------------------------------*/
+
+uint8_t DataEX_check_header_and_footer_ok(void);
+void DataEX_control_connection_while_asking_for_sleep(void);
+
+/* Exported functions --------------------------------------------------------*/
+
+uint8_t DataEX_call(void)
+{
+	DataEX_control_connection_while_asking_for_sleep();
+	
+	for(int i=0;i<EXCHANGE_BUFFERSIZE;i++)
+		*(uint8_t *)(((uint32_t)&dataOut) + i)  = 0;
+
+	dataOut.mode = MODE_SHUTDOWN;
+
+	dataOut.header.checkCode[0] = 0xBB;
+	dataOut.header.checkCode[1] = 0x01;
+	dataOut.header.checkCode[2] = 0x01;
+	dataOut.header.checkCode[3] = 0xBB;
+
+	dataOut.footer.checkCode[0] = 0xF4;
+	dataOut.footer.checkCode[1] = 0xF3;
+	dataOut.footer.checkCode[2] = 0xF2;
+	dataOut.footer.checkCode[3] = 0xF1;
+
+	HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_SET);
+	delayMicros(10);
+
+	if(data_old__lost_connection_to_slave_counter_temp >= 3)
+	{
+		data_old__lost_connection_to_slave_counter_temp = 0;
+	}
+	else
+	{
+		HAL_GPIO_WritePin(SMALLCPU_CSB_GPIO_PORT,SMALLCPU_CSB_PIN,GPIO_PIN_RESET);
+	}
+
+	HAL_SPI_TransmitReceive_DMA(&cpu2DmaSpi, (uint8_t *)&dataOut, (uint8_t *)&dataIn, EXCHANGE_BUFFERSIZE+1);
+	return 1;
+}
+
+
+void DataEX_control_connection_while_asking_for_sleep(void)
+{
+ 	if(!DataEX_check_header_and_footer_ok())
+	{
+		data_old__lost_connection_to_slave_counter_temp += 1;
+	}
+}
+
+uint8_t DataEX_check_header_and_footer_ok(void)
+{
+	if(dataIn.header.checkCode[0] != 0xA1)
+		return 0;
+	if(dataIn.header.checkCode[1] != 0xA2)
+		return 0;
+	if(dataIn.header.checkCode[2] != 0xA3)
+		return 0;
+	if(dataIn.header.checkCode[3] != 0xA4)
+		return 0;
+	if(dataIn.footer.checkCode[0] != 0xE1)
+		return 0;
+	if(dataIn.footer.checkCode[1] != 0xE2)
+		return 0;
+	if(dataIn.footer.checkCode[2] != 0xE3)
+		return 0;
+	if(dataIn.footer.checkCode[3] != 0xE4)
+		return 0;
+
+	return 1;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OtherSources/firmwareEraseProgram.c	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,571 @@
+/**
+  ******************************************************************************
+  * @file    firmwareEraseProgram.c
+  * @author  heinrichs/weikamp, Christian Weikamp
+  * @version V0.0.1
+  * @date    05-May-2015
+  * @version V0.0.1
+  * @since   05-May-2015
+  * @brief   erase and program the STM32F4xx internal FLASH memory
+  *
+  @verbatim
+  ==============================================================================
+                        ##### How to use #####
+  ==============================================================================
+	ADDR_FLASH_SECTOR_0 to/with ADDR_FLASH_SECTOR_5 (256KB) is used for this bootloader
+
+	ADDR_FLASH_SECTOR_23 is blocked and used for Font T48 and image_heinrichs_weikamp
+	Font T24 for button text is not blocked / protected
+	other fonts should not be used here
+
+
+  ==============================================================================
+                        ##### From  AN2557 #####
+							STM32F10xxx In-Application programming CD00161640.pdf   2010
+  ==============================================================================
+User program conditions
+The user application to be loaded into the Flash memory using IAP should be built with
+these configuration settings:
+1. Set the program load address at 0x08003000, using your toolchain linker file
+2. Relocate the vector table at address 0x08003000, using the
+"NVIC_SetVectorTable"function or the VECT_TAB_OFFSET definition inside the
+"system_stm32f10x.c"
+
+can be found here system_stm32f4xx.c
+
+
+	@endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2015 heinrichs weikamp</center></h2>
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+#include "stdio.h"
+#include "firmwareEraseProgram.h"
+#include "settings.h" // to access SHardwareData
+
+/* Exported variables --------------------------------------------------------*/
+
+/* Private types -------------------------------------------------------------*/
+
+/* Base address of the Flash sectors Bank 1 */
+#define ADDR_FLASH_SECTOR_0     ((uint32_t)0x08000000) /* Base @ of Sector 0, 16 Kbytes */
+#define ADDR_FLASH_SECTOR_1     ((uint32_t)0x08004000) /* Base @ of Sector 1, 16 Kbytes */
+#define ADDR_FLASH_SECTOR_2     ((uint32_t)0x08008000) /* Base @ of Sector 2, 16 Kbytes */
+#define ADDR_FLASH_SECTOR_3     ((uint32_t)0x0800C000) /* Base @ of Sector 3, 16 Kbytes */
+#define ADDR_FLASH_SECTOR_4     ((uint32_t)0x08010000) /* Base @ of Sector 4, 64 Kbytes */
+#define ADDR_FLASH_SECTOR_5     ((uint32_t)0x08020000) /* Base @ of Sector 5, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_6     ((uint32_t)0x08040000) /* Base @ of Sector 6, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_7     ((uint32_t)0x08060000) /* Base @ of Sector 7, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_8     ((uint32_t)0x08080000) /* Base @ of Sector 8, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_9     ((uint32_t)0x080A0000) /* Base @ of Sector 9, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_10    ((uint32_t)0x080C0000) /* Base @ of Sector 10, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_11    ((uint32_t)0x080E0000) /* Base @ of Sector 11, 128 Kbytes */
+
+/* Base address of the Flash sectors Bank 2 */
+#define ADDR_FLASH_SECTOR_12     ((uint32_t)0x08100000) /* Base @ of Sector 0, 16 Kbytes */
+#define ADDR_FLASH_SECTOR_13     ((uint32_t)0x08104000) /* Base @ of Sector 1, 16 Kbytes */
+#define ADDR_FLASH_SECTOR_14     ((uint32_t)0x08108000) /* Base @ of Sector 2, 16 Kbytes */
+#define ADDR_FLASH_SECTOR_15     ((uint32_t)0x0810C000) /* Base @ of Sector 3, 16 Kbytes */
+#define ADDR_FLASH_SECTOR_16     ((uint32_t)0x08110000) /* Base @ of Sector 4, 64 Kbytes */
+#define ADDR_FLASH_SECTOR_17     ((uint32_t)0x08120000) /* Base @ of Sector 5, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_18     ((uint32_t)0x08140000) /* Base @ of Sector 6, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_19     ((uint32_t)0x08160000) /* Base @ of Sector 7, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_20     ((uint32_t)0x08180000) /* Base @ of Sector 8, 128 Kbytes  */
+#define ADDR_FLASH_SECTOR_21     ((uint32_t)0x081A0000) /* Base @ of Sector 9, 128 Kbytes  */
+#define ADDR_FLASH_SECTOR_22     ((uint32_t)0x081C0000) /* Base @ of Sector 10, 128 Kbytes */
+#define ADDR_FLASH_SECTOR_23     ((uint32_t)0x081E0000) /* Base @ of Sector 11, 128 Kbytes */
+
+#define SECTOR_SIZE_128KB     ((uint32_t)0x00020000) 
+
+#define FLASH_FW_START_ADDR   ADDR_FLASH_SECTOR_6
+#define FLASH_FW_END_ADDR     (ADDR_FLASH_SECTOR_12 - 1)
+
+#define FLASH_FW2_START_ADDR   ADDR_FLASH_SECTOR_12
+#define FLASH_FW2_END_ADDR     (ADDR_FLASH_SECTOR_22 + SECTOR_SIZE_128KB - 1)
+
+/* Private variables ---------------------------------------------------------*/
+
+static FLASH_EraseInitTypeDef EraseInitStruct; /*Variable used for Erase procedure*/
+
+uint32_t FirstSector = 0, NbOfSectors = 0, Address = 0;
+uint32_t SectorError = 0;
+__IO uint32_t data32 = 0 , MemoryProgramStatus = 0;
+
+
+
+/* Private function prototypes -----------------------------------------------*/
+//static void firmware_Error_Handler(HAL_StatusTypeDef reason);
+static uint32_t GetSector(uint32_t Address);
+uint8_t hardware_programm_sub(uint8_t *buffer64, uint8_t length, uint32_t startAddress);
+
+/* Exported functions --------------------------------------------------------*/
+
+const SHardwareData* hardwareDataGetPointer(void)
+{
+	return (SHardwareData*)HARDWAREDATA_ADDRESS;
+}
+
+uint8_t hardware_programmPrimaryBluetoothNameSet(void)
+{
+	uint8_t data = 0xF0;
+	return hardware_programm_sub(&data, 1, HARDWAREDATA_ADDRESS + 7);
+}
+
+
+uint8_t hardware_programmSecondaryBluetoothNameSet(void)
+{
+	uint8_t data = 0xF0;
+	return hardware_programm_sub(&data, 1, HARDWAREDATA_ADDRESS + 52 + 7);
+}
+
+
+uint8_t hardware_programmProductionData(uint8_t *buffer52)
+{
+	buffer52[7] = 0xFF;// production_bluetooth_name_set
+	return hardware_programm_sub(buffer52, 52, HARDWAREDATA_ADDRESS);// check base_bootloader.c of OSTC4bootloader code and settings.h
+}
+
+
+uint8_t hardware_programmSecondarySerial(uint8_t *buffer12)
+{
+	buffer12[7] = 0xFF;// secondary_bluetooth_name_set
+	return hardware_programm_sub(buffer12, 12, HARDWAREDATA_ADDRESS + 52);
+}
+
+
+uint8_t hardware_programm_sub(uint8_t *buffer, uint8_t length, uint32_t startAddress)
+{
+	HAL_StatusTypeDef answer;
+
+	uint32_t ptr = 0;
+	uint8_t data8;
+
+	// test empty
+	Address = startAddress; 
+	for(int i=0;i<length;i++)
+	{
+		if((*(uint8_t *)Address != 0xFF) && (buffer[i] != 0xFF))
+			return 0xE0;
+		Address = Address + 1;
+	}
+	
+	// start programming
+	HAL_FLASH_Unlock();
+	
+	Address = startAddress; 
+	ptr = 0;
+	answer = HAL_OK;
+  while (ptr < length)
+  {
+		if(buffer[ptr] != 0xFF)
+		{
+			answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, buffer[ptr]);
+		}
+    if (answer == HAL_OK)
+    {
+      Address = Address + 1;
+			ptr++;
+    }
+    else
+    { 
+			HAL_FLASH_Lock(); 
+			return answer;
+    }
+  }
+	HAL_FLASH_Lock(); 
+
+  /* Check if the programmed data is OK 
+      MemoryProgramStatus = 0: data programmed correctly
+      MemoryProgramStatus != 0: number of words not programmed correctly ******/
+	Address = startAddress; // check base_bootloader.c of OSTC4bootloader code
+  MemoryProgramStatus = 0x0;
+  
+	ptr = 0;
+  while(ptr < length)
+  {
+    data8 = *(__IO uint8_t*)Address;
+
+    if((buffer[ptr] != 0xFF) && (data8 !=  buffer[ptr]))
+    {
+      MemoryProgramStatus++;  
+    }
+
+    Address = Address + 1;
+		ptr++;
+  }  
+
+  /* Check if there is an issue to program data */
+  if (MemoryProgramStatus == 0)
+  {
+		return HAL_OK;
+  }
+  else
+  {
+		return 0xEE;
+  }
+}
+
+
+uint8_t firmware2_variable_upperpart_eraseFlashMemory(uint32_t length, uint32_t offset)
+{
+	uint32_t startAddress, endAddress;
+
+//	HAL_StatusTypeDef answer;
+	HAL_FLASH_Unlock();
+  
+	startAddress = FLASH_FW2_START_ADDR + offset;
+	endAddress = startAddress + length;
+	
+	if(endAddress > FLASH_FW2_END_ADDR)
+		endAddress = FLASH_FW2_END_ADDR;
+	
+  FirstSector = GetSector(startAddress);
+  NbOfSectors = GetSector(endAddress) - FirstSector + 1;
+
+  EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
+  EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_1;
+  EraseInitStruct.Sector = FirstSector;
+  EraseInitStruct.NbSectors = NbOfSectors;
+  
+	return HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
+}
+
+
+uint8_t firmware2_variable_upperpart_programFlashMemory(uint32_t length, uint32_t offset, uint8_t *pBuffer1, uint32_t pBuffer1Size, uint8_t *pBuffer2)
+{
+	HAL_StatusTypeDef answer;
+	uint32_t ptr = 0;
+	uint32_t length1, length2;
+	
+	if((pBuffer2) && (length > pBuffer1Size))
+	{
+		length1 = pBuffer1Size;
+		length2 = length - length1;
+	}
+	else
+	{
+		length1 = length;
+		length2 = 0;
+	}
+		
+	Address = FLASH_FW2_START_ADDR + offset;
+
+	ptr = 0;
+  while ((Address <= FLASH_FW2_END_ADDR) && (ptr < length1))
+  {
+		answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer1[ptr]);
+    if (answer == HAL_OK)
+    {
+      Address = Address + 1;
+			ptr++;
+    }
+    else
+    { 
+			return answer;
+    }
+  }
+	ptr = 0;
+  while ((Address <= FLASH_FW2_END_ADDR) && (ptr < length2))
+  {
+		answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer2[ptr]);
+    if (answer == HAL_OK)
+    {
+      Address = Address + 1;
+			ptr++;
+    }
+    else
+    { 
+			return answer;
+    }
+  }
+  HAL_FLASH_Lock(); 
+
+	Address = FLASH_FW2_START_ADDR + offset;;
+  MemoryProgramStatus = 0x0;
+  
+	ptr = 0;
+  while ((Address <= FLASH_FW2_END_ADDR) && (ptr < length1))
+  {
+    data32 = *(__IO uint8_t*)Address;
+
+    if (data32 !=  pBuffer1[ptr])
+    {
+      MemoryProgramStatus++;  
+    }
+
+    Address = Address + 1;
+		ptr++;
+  }  
+	ptr = 0;
+  while ((Address <= FLASH_FW2_END_ADDR) && (ptr < length2))
+  {
+    data32 = *(__IO uint8_t*)Address;
+
+    if (data32 !=  pBuffer2[ptr])
+    {
+      MemoryProgramStatus++;  
+    }
+
+    Address = Address + 1;
+		ptr++;
+  }  
+
+  if (MemoryProgramStatus == 0)
+  {
+		return HAL_OK;
+  }
+  else
+  {
+		return 0xEE;
+  }
+}
+
+uint8_t firmware_eraseFlashMemory(void)
+{
+//	HAL_StatusTypeDef answer;
+  /* Unlock the Flash to enable the flash control register access *************/ 
+  HAL_FLASH_Unlock();
+
+  /* Erase the user Flash area
+    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
+
+  /* Get the 1st sector to erase */
+  FirstSector = GetSector(FLASH_FW_START_ADDR);
+  /* Get the number of sector to erase from 1st sector*/
+  NbOfSectors = GetSector(FLASH_FW_END_ADDR) - FirstSector + 1;
+
+  /* Fill EraseInit structure*/
+  EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
+  EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_1;
+  EraseInitStruct.Sector = FirstSector;
+  EraseInitStruct.NbSectors = NbOfSectors;
+  
+  /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
+     you have to make sure that these data are rewritten before they are accessed during code
+     execution. If this cannot be done safely, it is recommended to flush the caches by setting the
+     DCRST and ICRST bits in the FLASH_CR register. */
+	return HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
+}
+
+uint8_t firmware_programFlashMemory(uint8_t *pBuffer1, uint32_t length1)//, uint8_t *pBuffer2, uint32_t length2)
+{
+	HAL_StatusTypeDef answer;
+	
+  /* Program the user Flash area word by word
+    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
+
+	uint32_t ptr = 0;
+	
+	Address = FLASH_FW_START_ADDR;
+
+	ptr = 0;
+  while ((Address <= FLASH_FW_END_ADDR) && (ptr < length1))
+  {
+		answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer1[ptr]);
+    if (answer == HAL_OK)
+//    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32) == HAL_OK)
+    {
+      Address = Address + 1;//4;
+			ptr++;
+    }
+    else
+    { 
+			return answer;
+    }
+  }
+	/* same for pBuffer2
+	ptr = 0;
+  while ((Address < FLASH_FW_END_ADDR) && (ptr < length2))
+  {
+		
+    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer2[ptr]) == HAL_OK)
+    {
+      Address = Address + 1;
+			ptr++;
+    }
+    else
+    { 
+      firmware_Error_Handler();
+    }
+  }
+*/
+  /* Lock the Flash to disable the flash control register access (recommended
+     to protect the FLASH memory against possible unwanted operation) *********/
+  HAL_FLASH_Lock(); 
+
+  /* Check if the programmed data is OK 
+      MemoryProgramStatus = 0: data programmed correctly
+      MemoryProgramStatus != 0: number of words not programmed correctly ******/
+  Address = FLASH_FW_START_ADDR;
+  MemoryProgramStatus = 0x0;
+  
+	ptr = 0;
+  while ((Address <= FLASH_FW_END_ADDR) && (ptr < length1))
+  {
+    data32 = *(__IO uint8_t*)Address;
+
+    if (data32 !=  pBuffer1[ptr])
+    {
+      MemoryProgramStatus++;  
+    }
+
+    Address = Address + 1;//4;
+		ptr++;
+  }  
+	/* same for pBuffer2 
+	ptr = 0;
+  while ((Address < FLASH_FW_END_ADDR) && (ptr < length2))
+  {
+    data32 = *(__IO uint32_t*)Address;
+
+    if (data32 !=  pBuffer2[ptr])
+    {
+      MemoryProgramStatus++;  
+    }
+
+    Address = Address + 1;//4;
+		ptr++;
+  }  
+*/
+  /* Check if there is an issue to program data */
+  if (MemoryProgramStatus == 0)
+  {
+		return HAL_OK;
+    /* No error detected. Switch on LED3 */
+  }
+  else
+  {
+		return 0xEE;
+  }
+
+	
+}
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+  * @brief  Gets the sector of a given address
+  * @param  None
+  * @retval The sector of a given address
+  */
+static uint32_t GetSector(uint32_t Address)
+{
+  uint32_t sector = 0;
+  
+  if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
+  {
+    sector = FLASH_SECTOR_0;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
+  {
+    sector = FLASH_SECTOR_1;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
+  {
+    sector = FLASH_SECTOR_2;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
+  {
+    sector = FLASH_SECTOR_3;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
+  {
+    sector = FLASH_SECTOR_4;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
+  {
+    sector = FLASH_SECTOR_5;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
+  {
+    sector = FLASH_SECTOR_6;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
+  {
+    sector = FLASH_SECTOR_7;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
+  {
+    sector = FLASH_SECTOR_8;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
+  {
+    sector = FLASH_SECTOR_9;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
+  {
+    sector = FLASH_SECTOR_10;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_12) && (Address >= ADDR_FLASH_SECTOR_11))
+  {
+    sector = FLASH_SECTOR_11;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_13) && (Address >= ADDR_FLASH_SECTOR_12))
+  {
+    sector = FLASH_SECTOR_12;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_14) && (Address >= ADDR_FLASH_SECTOR_13))
+  {
+    sector = FLASH_SECTOR_13;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_15) && (Address >= ADDR_FLASH_SECTOR_14))
+  {
+    sector = FLASH_SECTOR_14;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_16) && (Address >= ADDR_FLASH_SECTOR_15))
+  {
+    sector = FLASH_SECTOR_15;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_17) && (Address >= ADDR_FLASH_SECTOR_16))
+  {
+    sector = FLASH_SECTOR_16;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_18) && (Address >= ADDR_FLASH_SECTOR_17))
+  {
+    sector = FLASH_SECTOR_17;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_19) && (Address >= ADDR_FLASH_SECTOR_18))
+  {
+    sector = FLASH_SECTOR_18;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_20) && (Address >= ADDR_FLASH_SECTOR_19))
+  {
+    sector = FLASH_SECTOR_19;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_21) && (Address >= ADDR_FLASH_SECTOR_20))
+  {
+    sector = FLASH_SECTOR_20;  
+  } 
+  else if((Address < ADDR_FLASH_SECTOR_22) && (Address >= ADDR_FLASH_SECTOR_21))
+  {
+    sector = FLASH_SECTOR_21;  
+  }
+  else if((Address < ADDR_FLASH_SECTOR_23) && (Address >= ADDR_FLASH_SECTOR_22))
+  {
+    sector = FLASH_SECTOR_22;  
+  }
+  else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_23))*/
+  {
+    sector = FLASH_SECTOR_23;  
+  }
+
+  return sector;
+}
+
+/*
+static void firmware_Error_Handler(HAL_StatusTypeDef reason)
+{
+	static HAL_StatusTypeDef last_reason = HAL_OK;
+	
+	last_reason = reason;
+  while(1)
+  {
+  }
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OtherSources/stm32f4xx_hal_msp.c	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,47 @@
+/**
+  ******************************************************************************
+  * @file    stm32f4xx_hal_msp.c 
+  * @author  heinrichs/weikamp, Christian Weikamp
+  * @date    05-Dec-2014
+  * @version V0.0.1
+  * @since   05-Dec-2014
+  * @brief   loader for the hardware specific stm32f4xx_hal_msp.c 
+  *           
+  @verbatim                 
+  ============================================================================== 
+              ##### How to use #####
+  ============================================================================== 
+  @endverbatim
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
+  *
+  ******************************************************************************
+  */ 
+
+/* Includes ------------------------------------------------------------------*/
+
+#include "ostc.h"
+
+#ifdef OSTC_ON_DISCOVERY_HARDWARE
+ #include "stm32f4xx_hal_msp_discovery.c"
+#else
+ #include "stm32f4xx_hal_msp_hw1.c"
+#endif
+
+/* Exported variables --------------------------------------------------------*/  
+
+/* Private types -------------------------------------------------------------*/
+
+/* Private variables ---------------------------------------------------------*/
+
+/* Private variables with external access via get_xxx() function -------------*/
+
+/* Private function prototypes -----------------------------------------------*/
+
+/* Exported functions --------------------------------------------------------*/
+
+/* Private functions ---------------------------------------------------------*/
+
+/************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OtherSources/stm32f4xx_hal_msp_hw2.c	Fri Dec 15 01:45:20 2017 +0100
@@ -0,0 +1,889 @@
+/**
+  ******************************************************************************
+  * File Name          : stm32f4xx_hal_msp.c
+  * Date               : 04/12/2014 15:39:26
+  * Description        : This file provides code for the MSP Initialization 
+  *                      and de-Initialization codes.
+  ******************************************************************************
+  *
+  * COPYRIGHT(c) 2014 STMicroelectronics
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+#include "ostc.h"
+
+
+DMA_HandleTypeDef hdma_spi1_tx;
+
+DMA_HandleTypeDef hdma_spi1_rx;
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/**
+  * Initializes the Global MSP.
+  */
+void HAL_MspInit(void)
+{
+  /* USER CODE BEGIN MspInit 0 */
+  /* USER CODE END MspInit 0 */
+
+  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
+
+  /* System interrupt init*/
+	/** SysTick_IRQn interrupt configuration
+		* use 1  by Christian 
+		*/
+  HAL_NVIC_SetPriority(SysTick_IRQn, 1, 0);
+
+  /* USER CODE BEGIN MspInit 1 */
+	/* always set priority right */
+	HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
+  /* USER CODE END MspInit 1 */
+}
+
+void HAL_DMA2D_MspInit(DMA2D_HandleTypeDef* hdma2d)
+{
+
+  if(hdma2d->Instance==DMA2D)
+  {
+  /* USER CODE BEGIN DMA2D_MspInit 0 */
+
+  /* USER CODE END DMA2D_MspInit 0 */
+    /* Peripheral clock enable */
+    __DMA2D_CLK_ENABLE();
+  /* USER CODE BEGIN DMA2D_MspInit 1 */
+		HAL_NVIC_SetPriority(DMA2D_IRQn, 1, 2);
+		HAL_NVIC_EnableIRQ(DMA2D_IRQn);  
+  /* USER CODE END DMA2D_MspInit 1 */
+  }
+
+}
+
+void HAL_DMA2D_MspDeInit(DMA2D_HandleTypeDef* hdma2d)
+{
+
+  if(hdma2d->Instance==DMA2D)
+  {
+  /* USER CODE BEGIN DMA2D_MspDeInit 0 */
+
+  /* USER CODE END DMA2D_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __DMA2D_CLK_DISABLE();
+  /* USER CODE BEGIN DMA2D_MspDeInit 1 */
+  __DMA2D_RELEASE_RESET();
+  /* USER CODE END DMA2D_MspDeInit 1 */
+  }
+
+}
+
+void HAL_LTDC_MspInit(LTDC_HandleTypeDef* hltdc)
+{
+
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(hltdc->Instance==LTDC)
+  {
+  /* USER CODE BEGIN LTDC_MspInit 0 */
+		__GPIOE_CLK_ENABLE();
+		__GPIOF_CLK_ENABLE();
+		__GPIOG_CLK_ENABLE();
+		__GPIOH_CLK_ENABLE();
+		__GPIOI_CLK_ENABLE();
+
+  /* USER CODE END LTDC_MspInit 0 */
+    /* Peripheral clock enable */
+    __LTDC_CLK_ENABLE();
+  
+    /**LTDC GPIO Configuration    
+    PE4     ------> LTDC_B0
+    PE5     ------> LTDC_G0
+    PE6     ------> LTDC_G1
+    PI9     ------> LTDC_VSYNC
+    PI10     ------> LTDC_HSYNC
+    PF10     ------> LTDC_DE
+    PH2     ------> LTDC_R0
+    PH3     ------> LTDC_R1
+    PH8     ------> LTDC_R2
+    PH9     ------> LTDC_R3
+    PH10     ------> LTDC_R4
+    PH11     ------> LTDC_R5
+    PH12     ------> LTDC_R6
+    PG6     ------> LTDC_R7
+    PG7     ------> LTDC_CLK
+    PH13     ------> LTDC_G2
+    PH14     ------> LTDC_G3
+    PH15     ------> LTDC_G4
+    PI0     ------> LTDC_G5
+    PI1     ------> LTDC_G6
+    PI2     ------> LTDC_G7
+    PG10     ------> LTDC_B2
+    PG11     ------> LTDC_B3
+    PG12     ------> LTDC_B1
+    PI4     ------> LTDC_B4
+    PI5     ------> LTDC_B5
+    PI6     ------> LTDC_B6
+    PI7     ------> LTDC_B7 
+    */
+    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
+    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_0|GPIO_PIN_1 
+                          |GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6 
+                          |GPIO_PIN_7;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
+    HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
+
+    GPIO_InitStruct.Pin = GPIO_PIN_10;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
+    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_8|GPIO_PIN_9 
+                          |GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13 
+                          |GPIO_PIN_14|GPIO_PIN_15;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
+    HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
+
+    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_11 
+                          |GPIO_PIN_12;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
+    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+  /* USER CODE BEGIN LTDC_MspInit 1 */
+
+  /* USER CODE END LTDC_MspInit 1 */
+  }
+
+}
+
+void HAL_LTDC_MspDeInit(LTDC_HandleTypeDef* hltdc)
+{
+
+  if(hltdc->Instance==LTDC)
+  {
+  /* USER CODE BEGIN LTDC_MspDeInit 0 */
+
+  /* USER CODE END LTDC_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __LTDC_CLK_DISABLE();
+  
+    /**LTDC GPIO Configuration    
+    PE4     ------> LTDC_B0
+    PE5     ------> LTDC_G0
+    PE6     ------> LTDC_G1
+    PI9     ------> LTDC_VSYNC
+    PI10     ------> LTDC_HSYNC
+    PF10     ------> LTDC_DE
+    PH2     ------> LTDC_R0
+    PH3     ------> LTDC_R1
+    PH8     ------> LTDC_R2
+    PH9     ------> LTDC_R3
+    PH10     ------> LTDC_R4
+    PH11     ------> LTDC_R5
+    PH12     ------> LTDC_R6
+    PG6     ------> LTDC_R7
+    PG7     ------> LTDC_CLK
+    PH13     ------> LTDC_G2
+    PH14     ------> LTDC_G3
+    PH15     ------> LTDC_G4
+    PI0     ------> LTDC_G5
+    PI1     ------> LTDC_G6
+    PI2     ------> LTDC_G7
+    PG10     ------> LTDC_B2
+    PG11     ------> LTDC_B3
+    PG12     ------> LTDC_B1
+    PI4     ------> LTDC_B4
+    PI5     ------> LTDC_B5
+    PI6     ------> LTDC_B6
+    PI7     ------> LTDC_B7 
+    */
+    HAL_GPIO_DeInit(GPIOE, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6);
+
+    HAL_GPIO_DeInit(GPIOI, GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_0|GPIO_PIN_1 
+                          |GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6 
+                          |GPIO_PIN_7);
+
+    HAL_GPIO_DeInit(GPIOF, GPIO_PIN_10);
+
+    HAL_GPIO_DeInit(GPIOH, GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_8|GPIO_PIN_9 
+                          |GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13 
+                          |GPIO_PIN_14|GPIO_PIN_15);
+
+    HAL_GPIO_DeInit(GPIOG, GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_10|GPIO_PIN_11 
+                          |GPIO_PIN_12);
+
+  /* USER CODE BEGIN LTDC_MspDeInit 1 */
+		__LTDC_RELEASE_RESET();
+
+  /* USER CODE END LTDC_MspDeInit 1 */
+  }
+
+}
+
+void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
+{
+
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(hspi->Instance==SPI1)
+  {
+  /* USER CODE BEGIN SPI1_MspInit 0 */
+		__GPIOA_CLK_ENABLE();
+		__GPIOB_CLK_ENABLE();
+		__DMA2_CLK_ENABLE();
+
+  /* USER CODE END SPI1_MspInit 0 */
+    /* Peripheral clock enable */
+    __SPI1_CLK_ENABLE();
+  
+    /**SPI1 GPIO Configuration    
+    alt: PA4     ------> SPI1_NSS, jetzt soft
+    PA5     ------> SPI1_SCK
+		alt:    PA6     ------> SPI1_MISO
+    neu: PB4     ------> SPI1_MISO
+    PA7     ------> SPI1_MOSI 
+    */
+//    GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
+    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;//GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
+    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+    GPIO_InitStruct.Pin = GPIO_PIN_4;
+    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+    /* Peripheral DMA init*/
+  
+    hdma_spi1_tx.Instance = DMA2_Stream3;
+    hdma_spi1_tx.Init.Channel = DMA_CHANNEL_3;
+    hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
+    hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
+    hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
+    hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+    hdma_spi1_tx.Init.Mode = DMA_NORMAL;
+    hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
+    hdma_spi1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+/* by christian */		
+hdma_spi1_tx.Init.MemBurst            = DMA_MBURST_INC4;
+hdma_spi1_tx.Init.PeriphBurst         = DMA_PBURST_INC4;
+    HAL_DMA_Init(&hdma_spi1_tx);
+
+    __HAL_LINKDMA(hspi,hdmatx,hdma_spi1_tx);
+
+    hdma_spi1_rx.Instance = DMA2_Stream0;
+    hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3;
+    hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
+    hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
+    hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
+    hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+    hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+    hdma_spi1_rx.Init.Mode = DMA_NORMAL;
+    hdma_spi1_rx.Init.Priority = DMA_PRIORITY_HIGH;
+    hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+/* by christian */	
+hdma_spi1_rx.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
+
+hdma_spi1_rx.Init.MemBurst            = DMA_MBURST_INC4;
+hdma_spi1_rx.Init.PeriphBurst         = DMA_PBURST_INC4;
+    HAL_DMA_Init(&hdma_spi1_rx);
+
+    __HAL_LINKDMA(hspi, hdmarx, hdma_spi1_rx);
+
+		/*##-4- Configure the NVIC for DMA #########################################*/ 
+		/* NVIC configuration for DMA transfer complete interrupt (SPI1_TX) */
+		HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 1);
+		HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
+		
+			
+		/* NVIC configuration for DMA transfer complete interrupt (SPI1_RX) */
+		HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);   
+		HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
+
+  }
+  else if(hspi->Instance==SPI2)
+  {
+  /* USER CODE BEGIN SPI2_MspInit 0 */
+		__GPIOB_CLK_ENABLE();
+
+  /* USER CODE END SPI2_MspInit 0 */
+    /* Peripheral clock enable */
+    __SPI2_CLK_ENABLE();
+  
+    /**SPI2 GPIO Configuration    
+    PB13     ------> SPI2_SCK
+    PB14     ------> SPI2_MISO
+    PB15     ------> SPI2_MOSI 
+    */
+    GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
+    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+  /* USER CODE BEGIN SPI2_MspInit 1 */
+
+  /* USER CODE END SPI2_MspInit 1 */
+  }
+  else if(hspi->Instance==SPI5)
+  {
+  /* USER CODE BEGIN SPI5_MspInit 0 */
+		__GPIOF_CLK_ENABLE();
+
+  /* USER CODE END SPI5_MspInit 0 */
+    /* Peripheral clock enable */
+    __SPI5_CLK_ENABLE();
+  
+    /**SPI5 GPIO Configuration    
+    PF7     ------> SPI5_SCK
+    PF8     ------> SPI5_MISO
+    PF9     ------> SPI5_MOSI 
+    */
+    GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;//GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
+    HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+  /* USER CODE BEGIN SPI5_MspInit 1 */
+
+  /* USER CODE END SPI5_MspInit 1 */
+  }
+
+}
+
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
+{
+
+  if(hspi->Instance==SPI1)
+  {
+  /* USER CODE BEGIN SPI1_MspDeInit 0 */
+		__SPI1_FORCE_RESET();
+		__SPI1_RELEASE_RESET();
+
+  /* USER CODE END SPI1_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __SPI1_CLK_DISABLE();
+  
+    /**SPI1 GPIO Configuration    
+    PA4     ------> SPI1_NSS
+    PA5     ------> SPI1_SCK
+    PA6     ------> SPI1_MISO
+    PA7     ------> SPI1_MOSI 
+    */
+    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
+
+    /* Peripheral DMA DeInit*/
+    HAL_DMA_DeInit(hspi->hdmatx);
+    HAL_DMA_DeInit(hspi->hdmarx);
+  /* USER CODE BEGIN SPI1_MspDeInit 1 */
+
+  /* USER CODE END SPI1_MspDeInit 1 */
+  }
+  else if(hspi->Instance==SPI2)
+  {
+  /* USER CODE BEGIN SPI2_MspDeInit 0 */
+
+  /* USER CODE END SPI2_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __SPI2_CLK_DISABLE();
+  
+    /**SPI2 GPIO Configuration    
+    PB13     ------> SPI2_SCK
+    PB14     ------> SPI2_MISO
+    PB15     ------> SPI2_MOSI 
+    */
+    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);
+
+  /* USER CODE BEGIN SPI2_MspDeInit 1 */
+
+  /* USER CODE END SPI2_MspDeInit 1 */
+  }
+  else if(hspi->Instance==SPI5)
+  {
+  /* USER CODE BEGIN SPI5_MspDeInit 0 */
+		__SPI5_FORCE_RESET();
+		__SPI5_RELEASE_RESET();
+
+  /* USER CODE END SPI5_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __SPI5_CLK_DISABLE();
+  
+    /**SPI5 GPIO Configuration    
+    PF7     ------> SPI5_SCK
+    PF8     ------> SPI5_MISO
+    PF9     ------> SPI5_MOSI 
+    */
+    HAL_GPIO_DeInit(GPIOF, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9);
+
+  /* USER CODE BEGIN SPI5_MspDeInit 1 */
+
+  /* USER CODE END SPI5_MspDeInit 1 */
+  }
+
+}
+
+void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* htim_pwm)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(htim_pwm->Instance==TIM_BACKLIGHT)
+  {
+		TIM_BACKLIGHT_GPIO_ENABLE();
+    TIM_BACKLIGHT_CLK_ENABLE();
+  
+    GPIO_InitStruct.Pin = TIM_BACKLIGHT_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
+    HAL_GPIO_Init(TIM_BACKLIGHT_GPIO_PORT, &GPIO_InitStruct);
+  }
+
+}
+
+void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
+{
+  if(htim_base->Instance==TIMx)
+  {
+    TIMx_CLK_ENABLE();
+
+		HAL_NVIC_SetPriority(TIMx_IRQn, 2, 1);
+		HAL_NVIC_EnableIRQ(TIMx_IRQn);
+	}
+  if(htim_base->Instance==TIM7)
+  {
+    __TIM7_CLK_ENABLE();
+
+		HAL_NVIC_SetPriority(TIM7_IRQn, 2, 0);
+		HAL_NVIC_EnableIRQ(TIM7_IRQn);
+	}
+}
+
+void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* htim_pwm)
+{
+
+  if(htim_pwm->Instance==TIM2)
+  {
+  /* USER CODE BEGIN TIM2_MspDeInit 0 */
+
+  /* USER CODE END TIM2_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __TIM2_CLK_DISABLE();
+  
+    /**TIM2 GPIO Configuration    
+    PA15     ------> TIM2_CH1 
+    */
+    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_15);
+
+  /* USER CODE BEGIN TIM2_MspDeInit 1 */
+
+  /* USER CODE END TIM2_MspDeInit 1 */
+  }
+
+}
+
+void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
+{
+
+  if(htim_base->Instance==TIM3)
+  {
+  /* USER CODE BEGIN TIM3_MspDeInit 0 */
+
+  /* USER CODE END TIM3_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __TIM3_CLK_DISABLE();
+  
+    /**TIM3 GPIO Configuration    
+    PC7     ------> TIM3_CH2 
+    */
+    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_7);
+
+  /* USER CODE BEGIN TIM3_MspDeInit 1 */
+
+  /* USER CODE END TIM3_MspDeInit 1 */
+  }
+
+}
+
+void HAL_UART_MspInit(UART_HandleTypeDef* huart)
+{
+
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if(huart->Instance==USART1)
+  {
+  /* USER CODE BEGIN USART1_MspInit 0 */
+		__GPIOA_CLK_ENABLE();
+
+  /* USER CODE END USART1_MspInit 0 */
+    /* Peripheral clock enable */
+    __USART1_CLK_ENABLE();
+  
+    /**USART1 GPIO Configuration    
+    PA9     ------> USART1_TX
+    PA10     ------> USART1_RX 
+    PA11     ------> USART1_CTS
+    PA12     ------> USART1_RTS
+    */
+#ifdef USARTx_CTS_PIN	
+    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
+#else
+    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
+#endif		
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;//GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
+    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+		HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
+		HAL_NVIC_EnableIRQ(USART1_IRQn);
+  }
+#ifdef USART_IR_HUD	
+  else if(huart->Instance==USART_IR_HUD) /* USART2 */
+  {
+    USART_IR_HUD_CLK_ENABLE();
+		USART_IR_HUD_TX_GPIO_CLK_ENABLE();
+		USART_IR_HUD_RX_GPIO_CLK_ENABLE();
+
+    /**USART2 GPIO Configuration    
+    PD5     ------> USART2_TX
+    PD6     ------> USART2_RX 
+    */
+
+    GPIO_InitStruct.Pin = USART_IR_HUD_TX_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = USART_IR_HUD_TX_AF;
+    HAL_GPIO_Init(USART_IR_HUD_TX_GPIO_PORT, &GPIO_InitStruct);
+
+    GPIO_InitStruct.Pin = USART_IR_HUD_RX_PIN;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = USART_IR_HUD_RX_AF;
+    HAL_GPIO_Init(USART_IR_HUD_RX_GPIO_PORT, &GPIO_InitStruct);
+
+		HAL_NVIC_SetPriority(USART_IR_HUD_IRQn, 0, 1);
+		HAL_NVIC_EnableIRQ(USART_IR_HUD_IRQn);
+  }
+#endif	
+  else if(huart->Instance==USART3)
+  {
+  /* USER CODE BEGIN USART3_MspInit 0 */
+
+  /* USER CODE END USART3_MspInit 0 */
+    /* Peripheral clock enable */
+    __USART3_CLK_ENABLE();
+  
+    /**USART3 GPIO Configuration    
+    PC10     ------> USART3_TX
+    PC11     ------> USART3_RX 
+    */
+    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
+    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
+    GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
+    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+  /* USER CODE BEGIN USART3_MspInit 1 */
+
+  /* USER CODE END USART3_MspInit 1 */
+  }
+
+}
+
+void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
+{
+
+  if(huart->Instance==USART1)
+  {
+  /* USER CODE BEGIN USART1_MspDeInit 0 */
+
+  /* USER CODE END USART1_MspDeInit 0 */
+    /* Peripheral clock disable */
+			HAL_NVIC_DisableIRQ(USART1_IRQn);
+    __USART1_CLK_DISABLE();
+  
+    /**USART1 GPIO Configuration    
+    PA9     ------> USART1_TX
+    PA10     ------> USART1_RX 
+    */
+#ifdef USARTx_CTS_PIN	
+    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12);
+#else
+    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
+#endif		
+
+  /* USER CODE BEGIN USART1_MspDeInit 1 */
+
+  /* USER CODE END USART1_MspDeInit 1 */
+  }
+  else if(huart->Instance==USART2)
+  {
+  /* USER CODE BEGIN USART2_MspDeInit 0 */
+
+  /* USER CODE END USART2_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __USART2_CLK_DISABLE();
+  
+    /**USART2 GPIO Configuration    
+    PD5     ------> USART2_TX
+    PD6     ------> USART2_RX 
+    */
+    HAL_GPIO_DeInit(GPIOD, GPIO_PIN_5|GPIO_PIN_6);
+
+  /* USER CODE BEGIN USART2_MspDeInit 1 */
+
+  /* USER CODE END USART2_MspDeInit 1 */
+  }
+  else if(huart->Instance==USART3)
+  {
+  /* USER CODE BEGIN USART3_MspDeInit 0 */
+
+  /* USER CODE END USART3_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __USART3_CLK_DISABLE();
+  
+    /**USART3 GPIO Configuration    
+    PC10     ------> USART3_TX
+    PC11     ------> USART3_RX 
+    */
+    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_10|GPIO_PIN_11);
+
+  /* USER CODE BEGIN USART3_MspDeInit 1 */
+
+  /* USER CODE END USART3_MspDeInit 1 */
+  }
+
+}
+
+static int FMC_Initialized = 0;
+
+static void HAL_FMC_MspInit(void){
+  GPIO_InitTypeDef GPIO_InitStruct;
+  if (FMC_Initialized) {
+    return;
+  }
+  FMC_Initialized = 1;
+  /* Peripheral clock enable */
+	/* by christian */
+  __GPIOC_CLK_ENABLE();
+  __GPIOD_CLK_ENABLE();
+  __GPIOE_CLK_ENABLE();
+  __GPIOF_CLK_ENABLE();
+  __GPIOG_CLK_ENABLE();
+  __GPIOH_CLK_ENABLE();
+
+  __FMC_CLK_ENABLE();
+  
+  /** FMC GPIO Configuration  
+  PF0   ------> FMC_A0
+  PF1   ------> FMC_A1
+  PF2   ------> FMC_A2
+  PF3   ------> FMC_A3
+  PF4   ------> FMC_A4
+  PF5   ------> FMC_A5
+  PC0   ------> FMC_SDNWE
+  PF11   ------> FMC_SDNRAS
+  PF12   ------> FMC_A6
+  PF13   ------> FMC_A7
+  PF14   ------> FMC_A8
+  PF15   ------> FMC_A9
+  PG0   ------> FMC_A10
+  PG1   ------> FMC_A11
+  PE7   ------> FMC_D4
+  PE8   ------> FMC_D5
+  PE9   ------> FMC_D6
+  PE10   ------> FMC_D7
+  PE11   ------> FMC_D8
+  PE12   ------> FMC_D9
+  PE13   ------> FMC_D10
+  PE14   ------> FMC_D11
+  PE15   ------> FMC_D12
+  PH6   ------> FMC_SDNE1 neu
+  PH7   ------> FMC_SDCKE1  neu 
+  PD8   ------> FMC_D13
+  PD9   ------> FMC_D14
+  PD10   ------> FMC_D15
+  PD14   ------> FMC_D0
+  PD15   ------> FMC_D1
+  PG2   ------> FMC_A12
+  PG4   ------> FMC_BA0
+  PG5   ------> FMC_BA1
+  PG8   ------> FMC_SDCLK
+  PD0   ------> FMC_D2
+  PD1   ------> FMC_D3
+  PG15   ------> FMC_SDNCAS
+  PE0   ------> FMC_NBL0
+  PE1   ------> FMC_NBL1
+  */
+	
+  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
+  GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
+
+
+  GPIO_InitStruct.Pin = GPIO_PIN_0;
+  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14 
+                          |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
+  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 
+                          |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 
+                          |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
+  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
+
+  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 
+                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12 
+                          |GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
+  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
+
+  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4 
+                          |GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15;
+  HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
+
+  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
+  HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
+
+
+}
+
+void HAL_SDRAM_MspInit(SDRAM_HandleTypeDef* hsdram){
+  HAL_FMC_MspInit();
+}
+
+static int FMC_DeInitialized = 0;
+
+static void HAL_FMC_MspDeInit(void){
+  if (FMC_DeInitialized) {
+    return;
+  }
+  FMC_DeInitialized = 1;
+  /* Peripheral clock enable */
+  __FMC_CLK_DISABLE();
+  
+  /** FMC GPIO Configuration  
+  PF0   ------> FMC_A0
+  PF1   ------> FMC_A1
+  PF2   ------> FMC_A2
+  PF3   ------> FMC_A3
+  PF4   ------> FMC_A4
+  PF5   ------> FMC_A5
+  PC0   ------> FMC_SDNWE
+  PF11   ------> FMC_SDNRAS
+  PF12   ------> FMC_A6
+  PF13   ------> FMC_A7
+  PF14   ------> FMC_A8
+  PF15   ------> FMC_A9
+  PG0   ------> FMC_A10
+  PG1   ------> FMC_A11
+  PE7   ------> FMC_D4
+  PE8   ------> FMC_D5
+  PE9   ------> FMC_D6
+  PE10   ------> FMC_D7
+  PE11   ------> FMC_D8
+  PE12   ------> FMC_D9
+  PE13   ------> FMC_D10
+  PE14   ------> FMC_D11
+  PE15   ------> FMC_D12
+  PH6   ------> FMC_SDNE1
+  PH7   ------> FMC_SDCKE1
+  PD8   ------> FMC_D13
+  PD9   ------> FMC_D14
+  PD10   ------> FMC_D15
+  PD14   ------> FMC_D0
+  PD15   ------> FMC_D1
+  PG2   ------> FMC_A12
+  PG4   ------> FMC_BA0
+  PG5   ------> FMC_BA1
+  PG8   ------> FMC_SDCLK
+  PD0   ------> FMC_D2
+  PD1   ------> FMC_D3
+  PG15   ------> FMC_SDNCAS
+  PE0   ------> FMC_NBL0
+  PE1   ------> FMC_NBL1
+  */
+  HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 
+                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_11|GPIO_PIN_12 
+                          |GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);
+
+  HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0);
+
+  HAL_GPIO_DeInit(GPIOG, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4 
+                          |GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15);
+
+  HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 
+                          |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 
+                          |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1);
+
+  HAL_GPIO_DeInit(GPIOH, GPIO_PIN_6|GPIO_PIN_7);
+
+  HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14 
+                          |GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1);
+
+}
+
+void HAL_SDRAM_MspDeInit(SDRAM_HandleTypeDef* hsdram){
+  HAL_FMC_MspDeInit();
+}
+
+/* USER CODE BEGIN 1 */
+
+/* USER CODE END 1 */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/