diff Discovery/Src/gfx_engine.c @ 38:5f11787b4f42

include in ostc4 repository
author heinrichsweikamp
date Sat, 28 Apr 2018 11:52:34 +0200
parents
children e97deb6e2705
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Discovery/Src/gfx_engine.c	Sat Apr 28 11:52:34 2018 +0200
@@ -0,0 +1,4074 @@
+/**
+  ******************************************************************************
+  * @file    gfx_engine.c
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.2
+  * @date    30-April-2014
+  * @brief   Main source file of GFX Graphic Engine
+  *          This file provides firmware functions to manage the following
+  *          functions to draw on the screen:
+  *           + write string to display
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 heinrichs weikamp</center></h2>
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "stm32f4xx_hal.h"
+
+#include "gfx.h"
+#include "gfx_engine.h"
+#include "gfx_fonts.h"
+#include "gfx_colors.h"
+#include "ostc.h"
+#include "settings.h"
+#include "text_multilanguage.h"
+
+/* Exported variables --------------------------------------------------------*/
+
+/* Private types -------------------------------------------------------------*/
+
+typedef struct
+{
+	uint32_t Xdelta;
+	uint32_t Ydelta;
+	uint8_t	 invert;
+	uint8_t  color;
+	uint8_t  dualFont;
+	uint8_t  resize;
+	uint32_t font;
+	uint8_t  spaceMode;
+	uint8_t  singleSpaceWithSizeOfNextChar;
+	uint8_t	useTinyFont;
+	uint32_t TinyFont;
+	int8_t TinyFontExtraYdelta;
+	tFont *actualFont;
+	uint8_t doubleSize;
+} GFX_CfgWriteString;
+
+typedef struct
+{
+	uint32_t  pBuffer;
+	uint32_t  height;
+	uint32_t  width;
+	uint32_t 	leftStart;
+	uint32_t 	bottomStart;
+} GFX_layerSingle;
+/*
+typedef struct
+{
+	GFX_layerSingle top;
+	GFX_layerSingle bottom;
+} GFX_layersTopBottom;
+*/
+typedef struct
+{
+	uint32_t pActualTopBuffer;
+	uint32_t pNextTopBuffer[2];
+	GFX_layerSingle actualBottom;
+	GFX_layerSingle nextBottom[2];
+	uint8_t boolNextTop;
+	uint8_t boolNextBottom;
+} GFX_layerControl;
+
+typedef struct
+{
+	uint32_t 	StartAddress;
+	int8_t 		status;
+	uint8_t		caller;
+} SFrameList;
+
+enum FRAMESTATE
+{
+	CLEAR = 0,
+	BLOCKED,
+	RELEASED
+};
+
+enum LOGOSTATE
+{
+	LOGOOFF = 0,
+	LOGOSTART = 1,
+	LOGOSTOP = 255
+};
+
+// should be 43
+#define MAXFRAMES 39
+
+#define SDRAM_BANK_ADDR    	((uint32_t)0xD0000000)
+#define	FBGlobalStart				SDRAM_BANK_ADDR
+#define	FBOffsetEachIndex		(800*480*2)
+
+#define SDRAM_DOUBLE_BUFFER_ONE ((uint32_t)(FBGlobalStart + (MAXFRAMES * FBOffsetEachIndex)))
+#define SDRAM_DOUBLE_BUFFER_TWO ((uint32_t)(SDRAM_DOUBLE_BUFFER_ONE + (2 * FBOffsetEachIndex)))
+#define SDRAM_DOUBLE_BUFFER_END ((uint32_t)(SDRAM_DOUBLE_BUFFER_TWO + (2 * FBOffsetEachIndex)))
+
+/* Semi Private variables ---------------------------------------------------------*/
+
+DMA2D_HandleTypeDef	Dma2dHandle;
+LTDC_HandleTypeDef	LtdcHandle;
+
+/* Private variables ---------------------------------------------------------*/
+
+uint8_t DMA2D_at_work = 0;
+
+GFX_layerControl FrameHandler = { 0 };
+
+uint32_t pInvisibleFrame = 0;
+uint32_t pLogoFrame = 0;
+uint8_t logoStatus;
+uint32_t pBackgroundHwFrame = 0;
+uint8_t backgroundHwStatus;
+
+SFrameList frame[MAXFRAMES];
+
+#define MAXFRAMECOUNTER (28)
+uint8_t frameCounter[MAXFRAMECOUNTER] = { 0 };
+
+_Bool lock_changeLTDC	= 0;
+
+/* ITM Trace-----------------------------------------------------------------*/
+
+#include "stdio.h"
+
+#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; /* Add whatever needed */ };
+FILE __stdout;
+FILE __stdin;
+
+int fputc(int ch, FILE *f) {
+  if (DEMCR & TRCENA) {
+    while (ITM_Port32(0) == 0);
+    ITM_Port8(0) = ch;
+  }
+  return(ch);
+}
+
+uint32_t MinU32GFX(uint32_t a, uint32_t b)
+{
+	return ((a<b)?a:b);
+}
+
+
+uint32_t MaxU32GFX(uint32_t a, uint32_t b)
+{
+	return((a>b)?a:b);
+}
+
+/* Private function prototypes -----------------------------------------------*/
+
+static uint32_t GFX_write_char(GFX_DrawCfgWindow* hgfx, GFX_CfgWriteString* cfg, uint8_t character, tFont *Font);
+static uint32_t GFX_write_substring(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, uint8_t textId, int8_t nextCharFor2Byte);
+uint32_t GFX_write__Modify_Xdelta__Centered(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, const char *pText);
+uint32_t GFX_write__Modify_Xdelta__RightAlign(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, const char *pTextInput);
+static void GFX_Error_Handler(void);
+static void GFX_Dma2d_TransferComplete(DMA2D_HandleTypeDef* Dma2dHandle);
+static void GFX_Dma2d_TransferError(DMA2D_HandleTypeDef* Dma2dHandle);
+void  GFX_clear_frame_dma2d(uint8_t frameId);
+
+uint32_t GFX_doubleBufferOne(void);
+uint32_t GFX_doubleBufferTwo(void);
+
+
+/* Exported functions --------------------------------------------------------*/
+
+uint8_t GFX_logoStatus(void)
+{
+	return logoStatus;
+}
+
+
+void GFX_helper_font_memory_list(const tFont *Font)
+{
+	int i;
+	uint8_t character;
+
+	// -----------------------------
+
+	for(character = 0x20; character < 0xFF; character++)
+	{
+		for(i=0;i<Font->length;i++)
+		{
+			if(Font->chars[i].code == character)
+			{
+				printf("%02x: 0x%0lx  0x%0lx\n\r",(uint8_t)character, (uint32_t)(Font->chars[i].image->data),((uint32_t)(Font->chars[i+1].image->data)-(uint32_t)(Font->chars[i].image->data)));
+				break;
+			}
+		}
+	}
+}
+
+
+
+void GFX_SetWindowLayer0(uint32_t pDestination, int16_t XleftGimpStyle, int16_t XrightGimpStyle, int16_t YtopGimpStyle, int16_t YbottomGimpStyle)
+{
+	int16_t XSize, YSize, X0, Y0;
+
+	if(XleftGimpStyle 	< 0) 		XleftGimpStyle = 0;
+	if(XrightGimpStyle 	< 0) 		XrightGimpStyle = 0;
+	if(XleftGimpStyle 	> 799)	XleftGimpStyle = 800;
+	if(XrightGimpStyle 	> 799)	XrightGimpStyle = 800;
+
+	if(YtopGimpStyle 		< 0) 		YtopGimpStyle = 0;
+	if(YbottomGimpStyle < 0) 		YbottomGimpStyle = 0;
+	if(YtopGimpStyle 		> 479)	YtopGimpStyle = 480;
+	if(YbottomGimpStyle > 479)	YbottomGimpStyle = 480;
+
+/*
+	XSize = YbottomGimpStyle 	- YtopGimpStyle;
+	YSize = XrightGimpStyle		- XleftGimpStyle;
+	if((XSize <= 0) || (YSize <= 0))
+		return;
+	X0 = 479 - YbottomGimpStyle;
+	Y0 = XleftGimpStyle;
+	while((LTDC->CPSR & LTDC_CPSR_CYPOS) <= (uint32_t)800);
+	HAL_LTDC_SetWindowSize(&LtdcHandle, XSize, YSize, LayerIdx);
+	HAL_LTDC_SetWindowPosition(&LtdcHandle, X0, Y0,LayerIdx);
+	HAL_LTDC_SetAddress(&LtdcHandle, pDestination, LayerIdx);
+*/
+
+	XSize = XrightGimpStyle		- XleftGimpStyle;
+	YSize = YbottomGimpStyle 	- YtopGimpStyle;
+	if((XSize <= 0) || (YSize <= 0))
+		return;
+	Y0 = 479 - YbottomGimpStyle;
+	X0 = XleftGimpStyle;
+
+	GFX_SetFrameBottom(pDestination, X0, Y0, XSize, YSize);
+}
+
+
+void GFX_logoAutoOff(void)
+{
+	if(logoStatus == LOGOOFF)
+		logoStatus = LOGOSTART;
+}
+
+/*
+uint8_t	GFX_printf_firmware(char *text)
+{	
+	uint8_t zahl, ptr;
+	
+	ptr = 0;
+	zahl = settingsGetPointer()->firmwareVersion16to32bit.ub.first;
+	if(zahl >= 10)
+	{
+		text[ptr++] = '0' + (zahl / 10);
+		zahl = zahl - ((zahl / 10 ) * 10);
+	}
+	text[ptr++] = '0' + zahl;
+	text[ptr++] = '.';
+	
+	zahl = settingsGetPointer()->firmwareVersion16to32bit.ub.second;
+	if(zahl >= 10)
+	{
+		text[ptr++] = '0' + (zahl / 10);
+		zahl = zahl - ((zahl / 10 ) * 10);
+	}
+	text[ptr++] = '0' + zahl;
+	text[ptr++] = '.';
+
+	zahl = settingsGetPointer()->firmwareVersion16to32bit.ub.third;
+	if(zahl >= 10)
+	{
+		text[ptr++] = '0' + (zahl / 10);
+		zahl = zahl - ((zahl / 10 ) * 10);
+	}
+	text[ptr++] = '0' + zahl;
+	
+	if(settingsGetPointer()->firmwareVersion16to32bit.ub.betaFlag)
+	{
+		text[ptr++] = ' ';
+		text[ptr++] = 'b';
+		text[ptr++] = 'e';
+		text[ptr++] = 't';
+		text[ptr++] = 'a';
+	}
+	text[ptr] = 0;
+
+	return ptr;
+}
+*/
+
+void GFX_hwBackgroundOn(void)
+{
+	backgroundHwStatus = LOGOSTART;
+}
+
+
+void GFX_hwBackgroundOff(void)
+{
+	backgroundHwStatus = LOGOSTOP;
+}
+
+
+void GFX_build_hw_background_frame(void)
+{
+	GFX_DrawCfgScreen	tLogoTemp;
+	SWindowGimpStyle windowGimp;
+	
+	pBackgroundHwFrame = getFrame(1);
+	backgroundHwStatus = 0;
+
+	tLogoTemp.FBStartAdress = pBackgroundHwFrame;
+	tLogoTemp.ImageHeight = 480;
+	tLogoTemp.ImageWidth = 800;
+	tLogoTemp.LayerIndex = 1;
+
+	windowGimp.left = (800 - 400) / 2;
+	windowGimp.top =  0;//(480 -  46) / 2;
+	
+	GFX_draw_image_color(&tLogoTemp, windowGimp, &ImgHWcolor);
+/*	
+	char localtext[256];
+	uint8_t ptr = 0;
+	
+	localtext[ptr++] = ' ';
+	localtext[ptr++] = ' ';
+	localtext[ptr++] = 'O';
+	localtext[ptr++] = 'S';
+	localtext[ptr++] = ' ';
+	ptr += GFX_printf_firmware(&localtext[ptr]);
+	localtext[ptr] = 0;
+
+	write_content_simple(&tLogoTemp, 0, 800, 240-24, &FontT24,localtext,CLUT_Font020);
+*/	
+}
+
+
+
+
+void GFX_build_logo_frame(void)
+{
+	GFX_DrawCfgScreen	tLogoTemp;
+	SWindowGimpStyle windowGimp;
+	
+	pLogoFrame = getFrame(1);
+	logoStatus = LOGOOFF;
+
+	tLogoTemp.FBStartAdress = pLogoFrame;
+	tLogoTemp.ImageHeight = 480;
+	tLogoTemp.ImageWidth = 800;
+	tLogoTemp.LayerIndex = 1;
+
+	windowGimp.left = (800 - 400) / 2;
+	windowGimp.top =  (480 -  46) / 2;
+	
+	GFX_draw_image_color(&tLogoTemp, windowGimp, &ImgHWcolor);
+/*	
+	char localtext[256];
+	uint8_t ptr = 0;
+	
+	localtext[ptr++] = ' ';
+	localtext[ptr++] = ' ';
+	localtext[ptr++] = 'O';
+	localtext[ptr++] = 'S';
+	localtext[ptr++] = ' ';
+	ptr += GFX_printf_firmware(&localtext[ptr]);
+	localtext[ptr] = 0;
+
+	write_content_simple(&tLogoTemp, 0, 800, 240-24, &FontT24,localtext,CLUT_Font020);
+*/	
+}
+
+
+void GFX_init(uint32_t  * pDestinationOut)
+{
+	frame[0].StartAddress = FBGlobalStart;
+	GFX_clear_frame_immediately(frame[0].StartAddress);
+	frame[0].status = CLEAR;
+	frame[0].caller = 0;
+
+	for(int i=1;i<MAXFRAMES;i++)
+	{
+		frame[i].StartAddress = frame[i-1].StartAddress + FBOffsetEachIndex;
+		GFX_clear_frame_immediately(frame[i].StartAddress);
+		frame[i].status = CLEAR;
+		frame[i].caller = 0;
+	}
+	
+	for(int i=1;i<MAXFRAMECOUNTER;i++)
+	{
+		frameCounter[i] = 0;
+	}
+
+	pInvisibleFrame = getFrame(2);
+	*pDestinationOut = pInvisibleFrame;
+
+	GFX_build_logo_frame();
+	GFX_build_hw_background_frame();
+	
+  /* Register to memory mode with ARGB8888 as color Mode */
+  Dma2dHandle.Init.Mode         = DMA2D_R2M;
+  Dma2dHandle.Init.ColorMode    = DMA2D_ARGB4444;//to fake AL88,  before: DMA2D_ARGB8888;
+  Dma2dHandle.Init.OutputOffset = 0;
+
+  /* DMA2D Callbacks Configuration */
+  Dma2dHandle.XferCpltCallback  = GFX_Dma2d_TransferComplete;
+  Dma2dHandle.XferErrorCallback = GFX_Dma2d_TransferError;
+
+  Dma2dHandle.Instance  = DMA2D;
+
+  /* DMA2D Initialisation */
+	if(HAL_DMA2D_Init(&Dma2dHandle) != HAL_OK)
+		GFX_Error_Handler();
+
+  if(HAL_DMA2D_ConfigLayer(&Dma2dHandle, 1) != HAL_OK)
+		GFX_Error_Handler();
+
+	DMA2D_at_work = 255;
+}
+
+
+void GFX_init1_no_DMA(uint32_t  * pDestinationOut, uint8_t blockFrames)
+{
+	frame[0].StartAddress = FBGlobalStart;
+	GFX_clear_frame_immediately(frame[0].StartAddress);
+	frame[0].status = CLEAR;
+	frame[0].caller = 0;
+
+	for(int i=1;i<MAXFRAMES;i++)
+	{
+		frame[i].StartAddress = frame[i-1].StartAddress + FBOffsetEachIndex;
+		GFX_clear_frame_immediately(frame[i].StartAddress);
+		frame[i].status = CLEAR;
+		frame[i].caller = 0;
+	}
+
+	for(int i=0;i<blockFrames;i++)
+	{
+		frame[i].status = BLOCKED;
+		frame[i].caller = 1;
+	}
+	
+	pInvisibleFrame = getFrame(2);
+	*pDestinationOut = pInvisibleFrame;
+
+	GFX_build_logo_frame();
+	GFX_build_hw_background_frame();
+}
+
+
+void GFX_init2_DMA(void)
+{
+  /* Register to memory mode with ARGB8888 as color Mode */
+  Dma2dHandle.Init.Mode         = DMA2D_R2M;
+  Dma2dHandle.Init.ColorMode    = DMA2D_ARGB4444;//to fake AL88,  before: DMA2D_ARGB8888;
+  Dma2dHandle.Init.OutputOffset = 0;
+
+  /* DMA2D Callbacks Configuration */
+  Dma2dHandle.XferCpltCallback  = GFX_Dma2d_TransferComplete;
+  Dma2dHandle.XferErrorCallback = GFX_Dma2d_TransferError;
+
+  Dma2dHandle.Instance  = DMA2D;
+
+  /* DMA2D Initialisation */
+	if(HAL_DMA2D_Init(&Dma2dHandle) != HAL_OK)
+		GFX_Error_Handler();
+
+  if(HAL_DMA2D_ConfigLayer(&Dma2dHandle, 1) != HAL_OK)
+		GFX_Error_Handler();
+
+	DMA2D_at_work = 255;
+}
+
+
+
+void GFX_SetFrameTop(uint32_t pDestination)
+{
+	lock_changeLTDC	= 1;
+	uint8_t boolNextTop = !FrameHandler.boolNextTop;
+
+	if(pDestination == 0)
+		pDestination = pInvisibleFrame;
+
+	FrameHandler.pNextTopBuffer[boolNextTop] = pDestination;
+	FrameHandler.boolNextTop = boolNextTop;
+	lock_changeLTDC	= 0;
+}
+
+
+void GFX_SetFrameBottom(uint32_t pDestination, uint32_t x0, uint32_t y0, uint32_t width, uint32_t height)
+{
+	lock_changeLTDC	= 1;
+	uint8_t boolNextBottom = !FrameHandler.boolNextBottom;
+
+	if(pDestination == 0)
+		pDestination = pInvisibleFrame;
+
+	FrameHandler.nextBottom[boolNextBottom].pBuffer = pDestination;
+	FrameHandler.nextBottom[boolNextBottom].height = height;
+	FrameHandler.nextBottom[boolNextBottom].width = width;
+	FrameHandler.nextBottom[boolNextBottom].leftStart = x0;
+	FrameHandler.nextBottom[boolNextBottom].bottomStart = y0;
+	FrameHandler.boolNextBottom = boolNextBottom;
+	lock_changeLTDC	= 0;
+}
+
+
+void GFX_SetFramesTopBottom(uint32_t pTop, uint32_t pBottom, uint32_t heightBottom)
+{
+	GFX_SetFrameTop(pTop);
+	GFX_SetFrameBottom(pBottom, 0, 0, 800, heightBottom);
+}
+
+
+uint32_t GFX_get_pActualFrameTop(void)
+{
+	return FrameHandler.pActualTopBuffer;
+}
+
+
+uint32_t GFX_get_pActualFrameBottom(void)
+{
+	return FrameHandler.actualBottom.pBuffer;
+}
+
+
+void GFX_start_VSYNC_IRQ(void)
+{
+  GPIO_InitTypeDef   GPIO_InitStructure;
+
+  GPIO_InitStructure.Mode = GPIO_MODE_IT_FALLING;
+  GPIO_InitStructure.Pull = GPIO_NOPULL;
+	GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
+  GPIO_InitStructure.Pin = VSYNC_IRQ_PIN;
+  HAL_GPIO_Init(VSYNC_IRQ_GPIO_PORT, &GPIO_InitStructure);
+
+  HAL_NVIC_SetPriority(VSYNC_IRQ_EXTI_IRQn, 1, 0);
+  HAL_NVIC_EnableIRQ(VSYNC_IRQ_EXTI_IRQn);
+}
+
+
+void GFX_change_LTDC(void)
+{
+	if(lock_changeLTDC	== 1)
+		return;
+
+	uint32_t pTop = 0;
+	uint32_t pBot = 0;
+	uint32_t heightBot = 0;
+	uint32_t widthBot = 0;
+	uint32_t leftStartBot = 0;
+	uint32_t bottomStartBot = 0;
+	uint8_t change_position = 0;
+	uint8_t change_size = 0;
+
+	// Top Frame
+	pTop = FrameHandler.pNextTopBuffer[FrameHandler.boolNextTop];
+	if(FrameHandler.pActualTopBuffer != pTop)
+	{
+		HAL_LTDC_SetAddress(&LtdcHandle, pTop, 1);
+		FrameHandler.pActualTopBuffer = pTop;
+	}	
+	
+	// Bottom Frame
+	if(logoStatus != LOGOOFF)
+	{
+		switch(logoStatus)
+			{
+			case LOGOSTART:
+				HAL_LTDC_SetAlpha(&LtdcHandle, 0, 1);
+				HAL_LTDC_SetAlpha(&LtdcHandle, 34, 0);
+				HAL_LTDC_ConfigCLUT(&LtdcHandle, (uint32_t *)indexHWcolor, indexHWcolorSIZE, 0);
+				HAL_LTDC_SetAddress(&LtdcHandle, pLogoFrame, 0);
+				HAL_LTDC_SetWindowSize(&LtdcHandle, 480, 800, 0);
+				HAL_LTDC_SetWindowPosition(&LtdcHandle, 0, 0, 0);
+				logoStatus = 2;
+				break;
+
+			case LOGOSTOP:
+				HAL_LTDC_SetAlpha(&LtdcHandle, 255, 1);
+				HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, 0);
+
+				pBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].pBuffer;
+				heightBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].height;
+				widthBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].width;
+				leftStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].leftStart;
+				bottomStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].bottomStart;
+				HAL_LTDC_SetWindowSize(&LtdcHandle, heightBot, widthBot, 0);
+				HAL_LTDC_SetWindowPosition(&LtdcHandle, bottomStartBot, leftStartBot, 0);
+				HAL_LTDC_SetAddress(&LtdcHandle, pBot, 0);
+				HAL_LTDC_SetAlpha(&LtdcHandle, 255, 0);
+				FrameHandler.actualBottom.height = heightBot;
+				FrameHandler.actualBottom.width = widthBot;
+				FrameHandler.actualBottom.leftStart = leftStartBot;
+				FrameHandler.actualBottom.bottomStart = bottomStartBot;
+				FrameHandler.actualBottom.pBuffer = pBot;
+
+				logoStatus = LOGOOFF;
+				if(backgroundHwStatus == 2)
+				{
+					backgroundHwStatus = LOGOSTART;
+				}
+				break;
+			default:
+				if(logoStatus < 35)
+				{
+					logoStatus++;
+					if(logoStatus <= 15)
+						HAL_LTDC_SetAlpha(&LtdcHandle, 17*logoStatus, 0);
+				}
+				else
+				{
+					logoStatus +=20;
+					HAL_LTDC_SetAlpha(&LtdcHandle, logoStatus-55, 1);
+					HAL_LTDC_SetAlpha(&LtdcHandle, 255+55-logoStatus, 0);
+				}
+				break;
+			}
+		return;
+	}
+	else if (backgroundHwStatus != LOGOOFF)
+	{
+		switch(backgroundHwStatus)
+			{
+			case LOGOSTART:
+				HAL_LTDC_ConfigCLUT(&LtdcHandle, (uint32_t *)indexHWcolor, indexHWcolorSIZE, 0);
+				HAL_LTDC_SetAddress(&LtdcHandle, pBackgroundHwFrame, 0);
+				HAL_LTDC_SetWindowSize(&LtdcHandle, 480, 800, 0);
+				HAL_LTDC_SetWindowPosition(&LtdcHandle, 0, 0, 0);
+				backgroundHwStatus = 2;
+				break;
+
+			case LOGOSTOP:
+				HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, 0);
+				pBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].pBuffer;
+				heightBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].height;
+				widthBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].width;
+				leftStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].leftStart;
+				bottomStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].bottomStart;
+				HAL_LTDC_SetWindowSize(&LtdcHandle, heightBot, widthBot, 0);
+				HAL_LTDC_SetWindowPosition(&LtdcHandle, bottomStartBot, leftStartBot, 0);
+				HAL_LTDC_SetAddress(&LtdcHandle, pBot, 0);
+				HAL_LTDC_SetAlpha(&LtdcHandle, 255, 0);
+				FrameHandler.actualBottom.height = heightBot;
+				FrameHandler.actualBottom.width = widthBot;
+				FrameHandler.actualBottom.leftStart = leftStartBot;
+				FrameHandler.actualBottom.bottomStart = bottomStartBot;
+				FrameHandler.actualBottom.pBuffer = pBot;
+				backgroundHwStatus = LOGOOFF;
+				break;
+
+			default:
+				break;
+			}
+		return;
+	}
+	else
+	{
+		pBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].pBuffer;
+		heightBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].height;
+		widthBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].width;
+		leftStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].leftStart;
+		bottomStartBot = FrameHandler.nextBottom[FrameHandler.boolNextBottom].bottomStart;
+
+		if(FrameHandler.actualBottom.pBuffer == pBot)
+			pBot = 0;
+		
+		if((FrameHandler.actualBottom.height != heightBot) || (FrameHandler.actualBottom.width != widthBot))
+			change_size = 1;
+
+		if((FrameHandler.actualBottom.leftStart != leftStartBot) || (FrameHandler.actualBottom.bottomStart != bottomStartBot))
+			change_position = 1;
+
+		if(pBot || change_size || change_position)
+		{
+			if(heightBot && widthBot)
+				HAL_LTDC_SetWindowSize(&LtdcHandle, heightBot, widthBot, 0);
+
+			if(change_position || leftStartBot || bottomStartBot)
+				HAL_LTDC_SetWindowPosition(&LtdcHandle, bottomStartBot, leftStartBot, 0);
+
+			if(pBot)
+				HAL_LTDC_SetAddress(&LtdcHandle, pBot, 0);
+
+			if(change_size)
+			{
+				FrameHandler.actualBottom.height = heightBot;
+				FrameHandler.actualBottom.width = widthBot;
+			}
+			if(change_position)
+			{
+				FrameHandler.actualBottom.leftStart = leftStartBot;
+				FrameHandler.actualBottom.bottomStart = bottomStartBot;
+			}
+			if(pBot)
+				FrameHandler.actualBottom.pBuffer = pBot;
+		}		
+	}
+}
+
+uint8_t GFX_is_colorschemeDiveStandard(void)
+{
+	return (ColorLUT[CLUT_Font027] == 0x00FFFFFF);
+}
+
+
+void change_CLUT_entry(uint8_t entryToChange, uint8_t entryUsedForChange)
+{
+/* bug fix
+	static uint8_t counter = 0;
+	
+	if(entryToChange == 0x1C)
+		counter++;
+*/	
+	ColorLUT[entryToChange] = ColorLUT[entryUsedForChange];
+	HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, 1);
+	if(logoStatus == LOGOOFF)
+		HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, 0);
+}
+
+
+void GFX_use_colorscheme(uint8_t colorscheme)
+{
+	uint8_t ColorSchemeStart;
+
+	if(colorscheme > 3)
+		colorscheme = 0;
+
+	ColorSchemeStart = CLUT_Colorscheme0 + (8 * colorscheme);
+	for(int i=1; i<8; i++)
+	{
+		ColorLUT[CLUT_Font027 + i] = ColorLUT[ColorSchemeStart + i];
+	}
+	change_CLUT_entry(CLUT_Font027, ColorSchemeStart);
+}
+
+
+void GFX_VGA_transform(uint32_t pSource, uint32_t pDestination)
+{
+	int h, v;
+	uint32_t offsetSource, offsetSourceStartOfLine;
+
+	offsetSourceStartOfLine = 480 + 480 - 2;
+	for(v=0;v<480;v++)
+	{
+		offsetSource = offsetSourceStartOfLine;
+		for(h=0;h<640;h++)
+		{
+			*(__IO uint8_t*)pDestination = *(uint8_t*)(pSource + offsetSource);
+			pDestination++;
+			offsetSource += 1;
+			*(__IO uint8_t*)pDestination = *(uint8_t*)(pSource + offsetSource);
+			pDestination++;
+			offsetSource += 480 + 479;
+		}
+		offsetSourceStartOfLine -= 2;
+	}
+}
+
+HAL_StatusTypeDef GFX_SetBackgroundColor(uint32_t LayerIdx, uint8_t red, uint8_t green, uint8_t blue)
+{
+  uint32_t tmp = 0;
+  uint32_t tmp1 = 0;
+
+  /* Process locked */
+  __HAL_LOCK(&LtdcHandle);
+
+  /* Change LTDC peripheral state */
+  LtdcHandle.State = HAL_LTDC_STATE_BUSY;
+
+  /* Check the parameters */
+  assert_param(IS_LTDC_LAYER(LayerIdx));
+
+  /* Copy new layer configuration into handle structure */
+  LtdcHandle.LayerCfg[LayerIdx].Backcolor.Red    = red;
+  LtdcHandle.LayerCfg[LayerIdx].Backcolor.Green  = green;
+  LtdcHandle.LayerCfg[LayerIdx].Backcolor.Blue   = blue;
+
+  /* Configure the LTDC Layer */
+  tmp = ((uint32_t)(green) << 8);
+  tmp1 = ((uint32_t)(red) << 16);
+  __HAL_LTDC_LAYER(&LtdcHandle, LayerIdx)->DCCR &= ~(LTDC_LxDCCR_DCBLUE | LTDC_LxDCCR_DCGREEN | LTDC_LxDCCR_DCRED | LTDC_LxDCCR_DCALPHA);
+  __HAL_LTDC_LAYER(&LtdcHandle, LayerIdx)->DCCR = (blue | tmp | tmp1 | 0xFF);
+
+  /* Sets the Reload type */
+  LtdcHandle.Instance->SRCR = LTDC_SRCR_IMR;
+
+  /* Initialize the LTDC state*/
+  LtdcHandle.State  = HAL_LTDC_STATE_READY;
+
+  /* Process unlocked */
+  __HAL_UNLOCK(&LtdcHandle);
+
+return HAL_OK;
+}
+
+
+void GFX_clear_frame_immediately(uint32_t pDestination)
+{
+	uint32_t i;
+
+	for(i = 200*480; i > 0; i--)
+	{
+		*(__IO uint16_t*)pDestination = 0;
+		pDestination += 2;
+		*(__IO uint16_t*)pDestination = 0;
+		pDestination += 2;
+		*(__IO uint16_t*)pDestination = 0;
+		pDestination += 2;
+		*(__IO uint16_t*)pDestination = 0;
+		pDestination += 2;
+	}
+}
+
+
+void GFX_clear_window_immediately(GFX_DrawCfgWindow* hgfx)
+{
+	uint32_t pDestination, i, j;
+	uint16_t left, width, bottom, height, nextlineStep;
+
+	pDestination = (uint32_t)hgfx->Image->FBStartAdress;
+
+	left 		= hgfx->WindowX0;
+	width 	= 1 + hgfx->WindowX1 - left;
+	bottom 	= hgfx->WindowY0;
+	height 	= 1 + hgfx->WindowY1 - bottom;
+	nextlineStep = hgfx->Image->ImageHeight - height;
+	nextlineStep *= 2;
+
+	pDestination += 2 * bottom;
+	pDestination += 2 * hgfx->Image->ImageHeight * left;
+
+	for(j = width; j > 0; j--)
+	{
+		for(i = height; i > 0; i--)
+		{
+			*(__IO uint16_t*)pDestination = 0;
+			pDestination += 2;
+		}
+		pDestination += nextlineStep;
+	}
+}
+
+
+void  GFX_clear_frame_dma2d(uint8_t frameId)
+{
+	if(frameId >= MAXFRAMES)
+		return;
+
+	DMA2D_at_work = frameId;
+
+	if (HAL_DMA2D_Start_IT(&Dma2dHandle, 0x0000000000, frame[frameId].StartAddress, 480, 800) != HAL_OK)
+		GFX_Error_Handler();
+}
+
+
+void GFX_fill_buffer(uint32_t pDestination, uint8_t alpha, uint8_t color)
+{
+
+		union al88_u
+	{
+		uint8_t al8[2];
+		uint16_t al88;
+	};
+
+	union al88_u colorcombination;
+	uint32_t i;
+
+	colorcombination.al8[0] = color;
+	colorcombination.al8[1] = alpha;
+
+	for(i = 800*480; i > 0; i--)
+	{
+		*(__IO uint16_t*)pDestination = colorcombination.al88;
+		pDestination += 2;
+	}
+}
+
+
+void gfx_flip(point_t *p1, point_t *p2)
+{
+	point_t temp;
+	
+	temp = *p1;
+	*p1 = *p2;
+	*p2 = temp;
+}
+
+
+static inline void gfx_brush(uint8_t thickness, GFX_DrawCfgScreen *hgfx, uint16_t x0, uint16_t y0, uint8_t color)
+{
+	uint32_t pDestination;
+	uint8_t offset = thickness/2;
+
+	pDestination = hgfx->FBStartAdress + 2*(x0 - offset)*hgfx->ImageHeight + 2*(y0-offset);
+	for(int x=thickness;x>0;x--)
+	{
+		for(int y=thickness;y>0;y--)
+		{
+			*(__IO uint16_t*)pDestination = 0xFF00 + color;
+			pDestination +=2;
+		}
+		pDestination += 2*(hgfx->ImageHeight - thickness);
+	}
+}
+
+
+void GFX_draw_thick_line(uint8_t thickness, GFX_DrawCfgScreen *hgfx, point_t start, point_t stop, uint8_t color)
+{
+	if(thickness < 2)
+		GFX_draw_line(hgfx,  start,  stop,  color);
+	
+	int x0 = start.x;
+	int y0 = start.y;
+	int x1 = stop.x;
+	int y1 = stop.y;
+	int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
+	int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; 
+	int err = (dx>dy ? dx : -dy)/2, e2;
+
+	
+	if(start.x == stop.x)
+	{
+		if(start.y > stop.y) gfx_flip(&start,&stop);
+		for (int j = stop.y - start.y; j > 0; j--)
+		{
+			gfx_brush(thickness,hgfx,start.x,start.y++,color);
+		}
+	}
+	else
+	if(start.y == stop.y)
+	{
+		if(start.x > stop.x) gfx_flip(&start,&stop);
+		
+		for (int j = stop.x - start.x; j > 0; j--)
+		{
+			gfx_brush(thickness,hgfx,start.x++,start.y,color);
+		}
+	}
+	else // diagonal
+	{
+		for(;;)
+		{
+			gfx_brush(thickness,hgfx,x0,y0,color);
+			if (x0==x1 && y0==y1) break;
+			e2 = err;
+			if (e2 >-dx) { err -= dy; x0 += sx; }
+			if (e2 < dy) { err += dx; y0 += sy; }
+		}
+	}	
+}
+
+
+void GFX_draw_line(GFX_DrawCfgScreen *hgfx, point_t start, point_t stop, uint8_t color)
+{
+	uint32_t pDestination;
+	uint32_t j;
+
+	if(start.x == stop.x)
+	{
+		if(start.y > stop.y) gfx_flip(&start,&stop);
+		pDestination = (uint32_t)hgfx->FBStartAdress;
+		pDestination += start.x * hgfx->ImageHeight * 2;
+		pDestination += start.y * 2;
+		for (j = stop.y - start.y; j > 0; j--)
+		{
+			*(__IO uint16_t*)pDestination = 0xFF00 + color;
+			pDestination += 2;
+		}
+	}
+	else
+	if(start.y == stop.y)
+	{
+		if(start.x > stop.x) gfx_flip(&start,&stop);
+		pDestination = (uint32_t)hgfx->FBStartAdress;
+		pDestination += start.x * hgfx->ImageHeight * 2;
+		pDestination += start.y * 2;
+		for (j = stop.x - start.x; j > 0; j--)
+		{
+			*(__IO uint16_t*)pDestination = 0xFF00 + color;
+			pDestination += hgfx->ImageHeight * 2;
+		}
+	}
+	else // diagonal
+	{
+		int x0 = start.x;
+		int y0 = start.y;
+		int x1 = stop.x;
+		int y1 = stop.y;
+		int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
+		int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; 
+		int err = (dx>dy ? dx : -dy)/2, e2;
+	 
+		for(;;)
+		{
+			pDestination = (uint32_t)hgfx->FBStartAdress;
+			pDestination += ((x0 * hgfx->ImageHeight) + y0) * 2;
+			*(__IO uint16_t*)pDestination = 0xFF00 + color;
+			if (x0==x1 && y0==y1) break;
+			e2 = err;
+			if (e2 >-dx) { err -= dy; x0 += sx; }
+			if (e2 < dy) { err += dx; y0 += sy; }
+		}
+	}
+}
+
+
+void GFX_draw_image_monochrome(GFX_DrawCfgScreen *hgfx, SWindowGimpStyle window, const tImage *image, uint8_t color)
+{
+	uint32_t pDestination;
+	uint32_t j;
+	point_t start, stop;
+
+	start.x = window.left;
+	start.y = (hgfx->ImageHeight - image->height - window.top);
+	stop.y = start.y + image->height;
+	stop.x = start.x + image->width;
+	j = 0;
+	
+	for(int xx = start.x; xx < stop.x; xx++)
+	{
+		pDestination = (uint32_t)hgfx->FBStartAdress;
+		pDestination += xx * hgfx->ImageHeight * 2;
+		pDestination += start.y * 2;
+		for(int yy = start.y; yy < stop.y; yy++)
+		{
+			*(__IO uint8_t*)pDestination = color;
+			pDestination += 1;
+			*(__IO uint8_t*)pDestination = image->data[j++];
+			pDestination += 1;
+		}
+	}	
+}
+	
+
+void GFX_draw_image_color(GFX_DrawCfgScreen *hgfx, SWindowGimpStyle window, const tImage *image)
+{
+	uint32_t pDestination;
+	uint32_t j;
+	point_t start, stop;
+
+	start.x = window.left;
+	start.y = (hgfx->ImageHeight - image->height - window.top);
+	stop.y = start.y + image->height;
+	stop.x = start.x + image->width;
+	j = 0;
+	
+	for(int xx = start.x; xx < stop.x; xx++)
+	{
+		pDestination = (uint32_t)hgfx->FBStartAdress;
+		pDestination += xx * hgfx->ImageHeight * 2;
+		pDestination += start.y * 2;
+		for(int yy = start.y; yy < stop.y; yy++)
+		{
+			*(__IO uint8_t*)pDestination = image->data[j++];
+			pDestination += 1;
+			*(__IO uint8_t*)pDestination = 0xFF;
+			pDestination += 1;
+		}
+	}	
+}
+
+
+int16_Point_t switchToOctantZeroFrom(uint8_t octant, int16_t x, int16_t y) 
+{
+	int16_Point_t answer;
+   switch(octant)
+	 {		 
+		case 0:// return (x,y);
+			answer.x = x;
+			answer.y = y;
+			break;
+		case 1:// return (y,x);
+			answer.x = y;
+			answer.y = x;
+			break;
+		case 2:// return (y, -x);
+			answer.x = y;
+			answer.y = -x;
+			break;
+		case 3:// return (-x, y);
+			answer.x = -x;
+			answer.y = y;
+			break;
+		case 4:// return (-x, -y);
+			answer.x = -x;
+			answer.y = -y;
+			break;
+		case 5:// return (-y, -x);
+			answer.x = -y;
+			answer.y = -x;
+			break;
+		case 6:// return (-y, x);
+			answer.x = -y;
+			answer.y = x;
+			break;
+		case 7:// return (x, -y);
+			answer.x = x;
+			answer.y = -y;
+			break;
+	 }
+	return answer;
+}
+
+/* this is NOT fast nor optimized */
+void GFX_draw_pixel(GFX_DrawCfgScreen *hgfx, int16_t x, int16_t y, uint8_t color)
+{
+	uint32_t pDestination;
+	
+	pDestination = (uint32_t)hgfx->FBStartAdress;
+	pDestination += x * hgfx->ImageHeight * 2;
+	pDestination += y * 2;
+	
+	*(__IO uint8_t*)pDestination = color;
+	pDestination += 1;
+	*(__IO uint8_t*)pDestination = 0xFF;
+}
+
+
+/* store the quarter circle for given radius */
+void GFX_draw_circle_with_MEMORY(uint8_t use_memory, GFX_DrawCfgScreen *hgfx, point_t center, uint8_t radius, int8_t color)
+{
+}
+
+/* this is NOT fast nor optimized */
+void GFX_draw_circle(GFX_DrawCfgScreen *hgfx, point_t center, uint8_t radius, int8_t color)
+{
+  int x, y;
+  int l;
+  int r2, y2;
+  int y2_new;
+  int ty;
+
+  /* cos pi/4 = 185363 / 2^18 (approx) */
+  l = (radius * 185363) >> 18;
+
+	/* hw */
+	l += 1;
+	
+  /* At x=0, y=radius */
+  y = radius;
+
+  r2 = y2 = y * y;
+  ty = (2 * y) - 1;
+  y2_new = r2 + 3;
+
+  for (x = 0; x <= l; x++) {
+    y2_new -= (2 * x) - 3;
+
+    if ((y2 - y2_new) >= ty) {
+      y2 -= ty;
+      y -= 1;
+      ty -= 2;
+    }
+
+    GFX_draw_pixel (hgfx,  x + center.x,  y + center.y, color);
+    GFX_draw_pixel (hgfx,  x + center.x, -y + center.y, color);
+    GFX_draw_pixel (hgfx, -x + center.x,  y + center.y, color);
+    GFX_draw_pixel (hgfx, -x + center.x, -y + center.y, color);
+
+    GFX_draw_pixel (hgfx,  y + center.x,  x + center.y, color);
+    GFX_draw_pixel (hgfx,  y + center.x, -x + center.y, color);
+    GFX_draw_pixel (hgfx, -y + center.x,  x + center.y, color);
+    GFX_draw_pixel (hgfx, -y + center.x, -x + center.y, color);
+  }
+}
+
+
+void GFX_draw_colorline(GFX_DrawCfgScreen *hgfx, point_t start, point_t stop, uint8_t color)
+{
+	uint32_t pDestination;
+	uint32_t j;
+	uint32_t temp;
+
+	if(start.x == stop.x)
+	{
+		if(stop.y < start.y)
+		{
+			temp = stop.y;
+			stop.y = start.y;
+			start.y = temp;
+		}
+		pDestination = (uint32_t)hgfx->FBStartAdress;
+		pDestination += start.x * hgfx->ImageHeight * 2;
+		pDestination += start.y * 2;
+		for (j = stop.y - start.y; j > 0; j--)
+		{
+			*(__IO uint8_t*)pDestination = color;
+			pDestination += 1;
+			*(__IO uint8_t*)pDestination = 0xFF;
+			pDestination += 1;
+		}
+	}
+	else
+	if(start.y == stop.y)
+	{
+		if(stop.x < start.x)
+		{
+			temp = stop.x;
+			stop.x = start.x;
+			start.x = temp;
+		}
+		pDestination = (uint32_t)hgfx->FBStartAdress;
+		pDestination += start.x * hgfx->ImageHeight * 2;
+		pDestination += start.y * 2;
+		for (j = stop.x - start.x; j > 0; j--)
+		{
+			*(__IO uint8_t*)pDestination = color;
+			pDestination += 1;
+			*(__IO uint8_t*)pDestination = 0xFF;
+			pDestination -= 1;
+			pDestination += hgfx->ImageHeight * 2;
+		}
+	}
+	else // diagonal Bresenham's_line_algorithm
+	{
+		int x0 = start.x;
+		int y0 = start.y;
+		int x1 = stop.x;
+		int y1 = stop.y;
+		int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
+		int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; 
+		int err = (dx>dy ? dx : -dy)/2, e2;
+	 
+		for(;;)
+		{
+			pDestination = (uint32_t)hgfx->FBStartAdress;
+			pDestination += ((x0 * hgfx->ImageHeight) + y0) * 2;
+			*(__IO uint8_t*)pDestination = color;
+			pDestination += 1;
+			*(__IO uint8_t*)pDestination = 0xFF;
+			if (x0==x1 && y0==y1) break;
+			e2 = err;
+			if (e2 >-dx) { err -= dy; x0 += sx; }
+			if (e2 < dy) { err += dx; y0 += sy; }
+		}
+	}
+}
+
+
+void GFX_draw_Grid(GFX_DrawCfgScreen *hgfx, SWindowGimpStyle window, int vlines, float vdeltaline, int hlines, float hdeltalines, uint8_t color)
+{
+    point_t p1;
+    point_t p2;
+    int winthight = window.bottom - window.top;
+	int winwidth = window.right - window.left;
+	float deltaline = 0;
+
+    if(vlines > 0)
+    {
+        deltaline = ((float)winwidth) /vlines;
+
+        p1.y = 479 - window.top;
+        p2.y = 479 - window.bottom;
+		for(int i = 0; i <= vlines; i++)
+		{
+            p1.x = window.left + (int)(i * deltaline + 0.5f);
+            p2.x = p1.x ;
+            GFX_draw_colorline(hgfx, p1,p2, color );
+		}
+    }
+    if(vdeltaline > 0)
+    {
+        p1.y = 479 - window.top;
+        p2.y = 479 - window.bottom;
+		for(int i = 0; i < winwidth/vdeltaline; i++)
+		{
+            p1.x = window.left + (int)(i * vdeltaline + 0.5f);
+            p2.x = p1.x ;
+            GFX_draw_colorline(hgfx, p1,p2, color );
+		}
+    }
+    if(hlines > 0)
+    {
+        deltaline = ((float)winthight)/hlines;
+        p1.x = window.left;
+        p2.x = window.right;
+		for(int i = 0; i <= hlines; i++)
+		{
+            p1.y = 479 - window.top - (int)(i * deltaline + 0.5f);
+            p2.y = p1.y;
+            GFX_draw_colorline(hgfx, p1,p2, color );
+		}
+    }
+}
+
+/*	drawVeilUntil ist auff�llen des Bereichs unter der Kurve mit etwas hellerer Farbe
+ *	Xdivide ist nichr benutzt, wird weggelassen in dieser Version
+ */
+/*
+void  GFX_graph_print(GFX_DrawCfgScreen *hgfx, const  SWindowGimpStyle *window, uint16_t drawVeilUntil, uint8_t Xdivide, uint16_t dataMin, uint16_t dataMax,  uint16_t *data, uint16_t datalength, uint8_t color, uint8_t *colour_data)
+{
+	if(window->bottom > 479)
+		return;
+	if(window->top > 479)
+		return;
+	if(window->right > 799)
+		return;
+	if(window->left > 799)
+		return;
+	if(window->bottom < 0)
+		return;
+	if(window->top < 0)
+		return;
+	if(window->right < 0)
+		return;
+	if(window->left < 0)
+		return;
+	if(window->bottom <= window->top)
+		return;
+	if(window->right <= window->left)
+		return;
+
+	uint16_t windowwidth = (uint16_t)window->right - (uint16_t)window->left;
+
+	if(dataMax == dataMin)
+		dataMax++;
+	
+	uint8_t invert = 0;	
+	if(dataMin > dataMax)
+	{
+		uint16_t dataFlip;
+		dataFlip = dataMin;
+		dataMin = dataMax;
+		dataMax = dataFlip;
+		invert = 1;
+	}
+	else
+		invert = 0;
+
+	uint16_t dataDelta = 0;
+	dataDelta = dataMax - dataMin;
+
+	uint8_t	colormask = color;
+
+	uint16_t loopX, loopData;
+	loopX = 0;
+	loopData = 0;
+	while((loopX <= windowwidth) & (loopData < datalength))
+	{
+
+	}
+
+
+	uint32_t pDestination_zero_veil = 0;
+	uint32_t pDestination = 0;
+	uint32_t pDestinationOld = 0;
+	int windowwidth = -1;
+	int windowheight = -1;
+	int w1 = -1;
+	int w2 = -1;
+	int value = -1;
+	uint8_t	colormask = 0;
+
+	// preparation
+	windowheight = window->bottom - window->top;
+	windowwidth = window->right - window->left;
+	pDestination_zero_veil = hgfx->FBStartAdress + 2 * (  (479 - (drawVeilUntil - 2) ) + ( (window->left) * hgfx->ImageHeight) );
+	
+	while((w1 <= windowwidth) & (w2 < datalength))
+	{
+		// before
+		if(colour_data != NULL)
+		{
+			colormask = color + colour_data[w2];
+		}
+    pDestination = hgfx->FBStartAdress + 2 * (  (479 - (window->top + value) ) + ( (w1 + window->left) * hgfx->ImageHeight) );
+	
+		// after
+		pDestination_zero_veil += (window->left) * hgfx->ImageHeight;
+	}	
+}
+*/
+
+
+
+//  ===============================================================================
+//	GFX_graph_print
+/// @brief	Print all those nice curves, especially in logbook und miniLiveLogGraph
+///	@version 0.0.2 hw 160519
+///	
+/// 151022 hw -bug fix 
+/// - die aktuelle Version macht keine Linien mehr �ber die gesamte Bildschirmh�he.
+/// - daf�r sind L�cher in der Kurve (z.B. Temperaturgraph Tauchgang Matthias 17.10.15 15:19)
+///
+/// more details about range can be found in show_logbook_logbook_show_log_page2() - temperature graph
+///
+///	@param 	window: top and bottom is only the range used by the data of the graph, not the entire screen / scale
+/// @param 	drawVeilUntil: ist auff�llen des Bereichs unter der Kurve mit etwas hellerer Farbe
+///	@param 	Xdivide: wird bisher nichr benutzt.
+//  ===============================================================================
+
+
+void GFX_graph_print(GFX_DrawCfgScreen *hgfx, const  SWindowGimpStyle *window, int16_t drawVeilUntil, uint8_t Xdivide, uint16_t dataMin, uint16_t dataMax,  uint16_t *data, uint16_t datalength, uint8_t color, uint8_t *colour_data)
+{
+  //uint32_t pDestination,pDestination_old,
+	uint32_t pDestination_tmp,pDestination_end, pDestination_start, pDestination_zero_veil;
+
+	uint32_t max = 0;
+	int windowheight = -1;
+	int windowwidth = -1;
+	int i = -1;
+	int w1 = -1;
+	int w2 = -1;
+
+	uint32_t h_ulong = 0;
+	uint32_t h_ulong_old = 0;
+	_Bool invert = 0;
+
+	uint16_t dataDelta = 0;
+	uint16_t dataDeltaHalve = 0;
+	uint16_t dataTemp = 0;
+	
+	uint8_t colorDataTemp;
+	uint8_t	colormask = 0;
+
+	if(dataMin > dataMax)
+	{
+		uint16_t dataFlip;
+		dataFlip = dataMin;
+		dataMin = dataMax;
+		dataMax = dataFlip;
+		invert = 1;
+	}
+	else
+		invert = 0;
+
+	colormask = color;
+	
+		
+	if(window->bottom > 479)
+		return;
+	if(window->top > 479)
+		return;
+	if(window->right > 799)
+		return;
+	if(window->left > 799)
+		return;
+	if(window->bottom < 0)
+		return;
+	if(window->top < 0)
+		return;
+	if(window->right < 0)
+		return;
+	if(window->left < 0)
+		return;
+	if(window->bottom <= window->top)
+		return;
+	if(window->right <= window->left)
+		return;
+	
+	windowheight = window->bottom - window->top ;
+	windowwidth = window->right - window->left;
+	w1 = 0;
+	w2 = 0;
+	if(dataMax == dataMin)
+		dataMax++;
+	dataDelta =  (unsigned long)(dataMax - dataMin);
+	dataDeltaHalve = dataDelta / 2;
+	while((w1 <= windowwidth) & (w2 < datalength))
+	{
+		int tmp = (10 * w1 * (long)datalength)/windowwidth;
+		w2 = tmp/10;
+		int rest = tmp - w2*10;
+		if(rest >= 5)
+			w2++;
+
+		if((datalength - 1) < w2)
+			w2 = datalength-1;
+
+		if(colour_data != NULL)
+		{
+			colorDataTemp = colour_data[w2];
+			colormask =    color + colorDataTemp;
+		}
+
+		dataTemp = data[w2];
+		if(Xdivide > 1)
+		{
+			w2++;
+			for(i=1;i<Xdivide;i++)
+			{
+				if(data[w2]>dataTemp)
+					dataTemp = data[w2];
+				w2++;
+			}
+		}
+		
+		if(dataTemp > dataMin)
+			dataTemp -= dataMin;
+		else
+			dataTemp = 0;
+
+		if(invert)
+		{
+			if(dataTemp < dataDelta)
+				dataTemp = dataDelta - dataTemp;
+			else
+				dataTemp = 0;
+		}
+		
+		h_ulong = (unsigned long)dataTemp;
+		h_ulong *= windowheight;
+		h_ulong += dataDeltaHalve;
+		h_ulong /= dataDelta;
+		
+		if(h_ulong > (window->bottom - window->top))
+			h_ulong = (window->bottom - window->top);
+
+		if(drawVeilUntil > 0)
+		{
+				pDestination_zero_veil = hgfx->FBStartAdress + 2 * (  (479 - (drawVeilUntil - 2) ) + ( (w1 + window->left) * hgfx->ImageHeight) );
+		}
+		else if(drawVeilUntil < 0 )
+		{
+				pDestination_zero_veil = hgfx->FBStartAdress + 2 * (  (479 + (drawVeilUntil) ) + ( (w1 + window->left) * hgfx->ImageHeight) );
+		}
+
+		if(h_ulong + window->top > max)
+		{
+			max = h_ulong + window->top;
+		}
+
+// hw 160519 wof�r ist das? Damit funktioniert Temperatur 25,5�C nicht!
+//		if((dataMax == 255) || (data[w2] != 255))
+//		{
+			//output_content[pointer] = colormask;
+			//output_mask[pointer] = true;
+			if(w1 > 0)
+			{
+				pDestination_start = hgfx->FBStartAdress +  (2 * ((479 - (window->top)) + ((w1 + window->left) * hgfx->ImageHeight)));
+				pDestination_end = pDestination_start;
+				if(h_ulong >= h_ulong_old)
+				{
+					pDestination_start -= 2 * h_ulong_old;
+					pDestination_end -= 2 * h_ulong;
+				}
+				else
+				{
+					pDestination_start -= 2 * h_ulong;
+					pDestination_end -= 2 * h_ulong_old;
+				}
+				
+				// deco stops
+				if(drawVeilUntil < 0)
+				{
+					pDestination_tmp = pDestination_end;
+					while(pDestination_tmp <= pDestination_zero_veil)
+					{
+							*(__IO uint8_t*)pDestination_tmp = colormask;
+											pDestination_tmp -= 1;
+											*(__IO uint8_t*)pDestination_tmp = 0x80;
+											pDestination_tmp += 3;
+					}
+				}
+				else
+				{
+					// regular graph with veil underneath if requested
+					// von oben nach unten
+					// von grossen pDestination Werten zu kleinen pDestination Werten
+					pDestination_tmp = pDestination_start;
+					while(pDestination_tmp >= pDestination_end)
+					{
+							*(__IO uint8_t*)pDestination_tmp = colormask;
+											pDestination_tmp += 1;
+											*(__IO uint8_t*)pDestination_tmp = 0xFF;
+											pDestination_tmp -= 3;
+					}
+					while((drawVeilUntil > 0) && (pDestination_tmp >= pDestination_zero_veil))
+					{
+							*(__IO uint8_t*)pDestination_tmp = colormask;
+											pDestination_tmp += 1;
+											*(__IO uint8_t*)pDestination_tmp = 0x20;
+											pDestination_tmp -= 3;
+					}
+				}
+			}
+			h_ulong_old = h_ulong;
+//		}
+		w1++;
+		w2++;
+	}
+}
+
+
+void GFX_draw_header(GFX_DrawCfgScreen *hgfx, uint8_t colorId)
+{
+	uint32_t pDestination;
+	point_t start, stop, now;
+	uint8_t alpha;
+
+	/* display coordinate system */
+	start.y = 400;
+	stop.y = 479;
+
+	start.x = 0;
+	stop.x = 799;
+
+	now.y = start.y;
+	now.x = start.x;
+
+	while (now.x <= stop.x)
+	{
+		now.y = start.y;
+		pDestination = (uint32_t)hgfx->FBStartAdress;
+		pDestination += now.x * hgfx->ImageHeight * 2;
+		pDestination += now.y * 2;
+		now.x += 1;
+
+		alpha = 27;
+		while(alpha < 246)
+		{
+			alpha += 9;
+			*(__IO uint8_t*)pDestination = colorId;
+			pDestination += 1;
+			*(__IO uint8_t*)pDestination = alpha;
+			pDestination += 1;
+			now.y += 1;
+		}
+
+		while(now.y <= stop.y)
+		{
+			*(__IO uint8_t*)pDestination = colorId;
+			pDestination += 1;
+			*(__IO uint8_t*)pDestination = 0xFF;
+			pDestination += 1;
+			now.y += 1;
+		}
+	}
+}
+
+void GFX_draw_box2(GFX_DrawCfgScreen *hgfx, point_t start, point_t stop, uint8_t color, uint8_t roundCorners)
+{
+	point_t point2, point4;
+
+	if(roundCorners)
+	{
+		point2.x  = stop.x - start.x;
+		point2.y  = stop.y - start.y;
+		GFX_draw_box(hgfx,start,point2,1,color);
+	}
+	else
+	{
+		point2.x  = stop.x;
+		point2.y  = start.y;
+
+		point4.x  = start.x;
+		point4.y  = stop.y;
+		
+		GFX_draw_line(hgfx,start,point2,color);
+		GFX_draw_line(hgfx,point2,stop,color);
+		GFX_draw_line(hgfx,stop,point4,color);
+		GFX_draw_line(hgfx,point4,start,color);
+	}
+}
+
+void GFX_draw_box(GFX_DrawCfgScreen *hgfx, point_t LeftLow, point_t WidthHeight, uint8_t Style, uint8_t color)
+{
+	uint32_t pDestination, pStart;
+	uint32_t j;
+	uint32_t lineWidth, lineHeight;
+	int x, y;
+	uint8_t intensity;
+
+	typedef struct {
+			int x;
+			int y;
+			uint8_t intensity;
+	} corner_t;
+	const corner_t corner[16] = {
+		{3,3,255}, // nur einmal
+		{9,0,242},
+		{8,0,194},
+		{7,0,115},
+		{6,0,36},
+		{9,1,33},
+		{8,1,84},
+		{7,1,161},
+		{6,1,255},
+		{5,1,242},
+		{4,1,36},
+		{6,2,33},
+		{5,2,84},
+		{4,2,255},
+		{3,2,84},
+		{4,3,110}
+	};
+
+	lineWidth = WidthHeight.x;
+	lineHeight = WidthHeight.y;
+
+	pStart = (uint32_t)hgfx->FBStartAdress;
+	pStart += LeftLow.x * hgfx->ImageHeight * 2;
+	pStart += LeftLow.y * 2;
+
+	// Untere Linie
+	pDestination = pStart;
+	if(Style)
+	{
+		pDestination += 2 * 10 * hgfx->ImageHeight;
+		lineWidth -= 18;
+	}
+	for (j = lineWidth; j > 0; j--)
+	{
+		*(__IO uint16_t*)pDestination = 0xFF00 + color;
+		pDestination += hgfx->ImageHeight * 2;
+	}
+
+	// Obere Linie
+	pDestination = pStart + 2 * WidthHeight.y;
+	if(Style)
+	{
+		pDestination += 2 * 10 * hgfx->ImageHeight;
+	}
+
+	for (j = lineWidth; j > 0; j--)
+	{
+		*(__IO uint16_t*)pDestination = 0xFF00 + color;
+		pDestination += hgfx->ImageHeight * 2;
+	}
+
+	// Linke Linie
+	pDestination = pStart;
+	if(Style)
+	{
+		pDestination += 2 * 10;
+		lineHeight -= 18;
+	}
+
+	for (j = lineHeight; j > 0; j--)
+	{
+		*(__IO uint16_t*)pDestination = 0xFF00 + color;
+		pDestination += 2;
+	}
+
+	// Rechte Linie
+	pDestination = pStart + 2 * WidthHeight.x * hgfx->ImageHeight;
+	if(Style)
+	{
+		pDestination += 2 * 10;
+	}
+
+	for (j = lineHeight; j > 0; j--)
+	{
+		*(__IO uint16_t*)pDestination = 0xFF00 + color;
+		pDestination += 2;
+	}
+
+	// Ecken wenn notwendig == Style
+	if(Style)
+	{
+		// links unten
+		pDestination = pStart;
+		x = corner[0].x;
+		y = corner[0].y;
+		intensity = corner[0].intensity;
+    *(__IO uint16_t*)(pDestination  + 2 * (y + (x * hgfx->ImageHeight))) = (intensity << 8) + color;
+
+		for(j = 15; j > 0; j--)
+		{
+			x = corner[j].x;
+			y = corner[j].y;
+			intensity = corner[j].intensity;
+			*(__IO uint16_t*)(pDestination + 2 * (y + (x * hgfx->ImageHeight))) = (intensity << 8) + color;
+			*(__IO uint16_t*)(pDestination + 2	* (x + (y * hgfx->ImageHeight))) = (intensity << 8) + color;
+		}
+		// links oben
+		pDestination = pStart + 2 * WidthHeight.y;
+		x = corner[0].x;
+		y = corner[0].y;
+		intensity = corner[0].intensity;
+    *(__IO uint16_t*)(pDestination + 2 * (-y + (x * hgfx->ImageHeight))) = (intensity << 8) + color;
+
+		for(j = 15; j > 0; j--)
+		{
+			x = corner[j].x;
+			y = corner[j].y;
+			intensity = corner[j].intensity;
+			*(__IO uint16_t*)(pDestination + 2 * (-y + (x * hgfx->ImageHeight))) = (intensity << 8) + color;
+			*(__IO uint16_t*)(pDestination + 2 * (-x + (y * hgfx->ImageHeight))) = (intensity << 8) + color;
+		}
+		// rechts unten
+		pDestination = pStart + 2 * WidthHeight.x * hgfx->ImageHeight;
+		x = corner[0].x;
+		y = corner[0].y;
+		intensity = corner[0].intensity;
+    *(__IO uint16_t*)(pDestination + 2 * (y - (x * hgfx->ImageHeight))) = (intensity << 8) + color;
+
+		for(j = 15; j > 0; j--)
+		{
+			x = corner[j].x;
+			y = corner[j].y;
+			intensity = corner[j].intensity;
+			*(__IO uint16_t*)(pDestination + 2 * (y - (x * hgfx->ImageHeight))) = (intensity << 8) + color;
+			*(__IO uint16_t*)(pDestination + 2 * (x - (y * hgfx->ImageHeight))) = (intensity << 8) + color;
+		}
+		// rechts oben
+		pDestination = pStart + 2 * WidthHeight.y + 2 * WidthHeight.x * hgfx->ImageHeight;
+		x = corner[0].x;
+		y = corner[0].y;
+		intensity = corner[0].intensity;
+    *(__IO uint16_t*)(pDestination - 2 * (y + (x * hgfx->ImageHeight))) = (intensity << 8) + color;
+
+		for(j = 15; j > 0; j--)
+		{
+			x = corner[j].x;
+			y = corner[j].y;
+			intensity = corner[j].intensity;
+			*(__IO uint16_t*)(pDestination - 2 * (y + (x * hgfx->ImageHeight))) = (intensity << 8) + color;
+			*(__IO uint16_t*)(pDestination - 2 * (x + (y * hgfx->ImageHeight))) = (intensity << 8) + color;
+		}
+	}
+}
+
+
+
+
+/**
+  ******************************************************************************
+  * @brief   GFX write label. /  Write string with defined color
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.1
+  * @date    07-July-2014
+  ******************************************************************************
+	*
+  * @param  hgfx: 			check gfx_engine.h.
+  * @param  color: 			16bit Alpha+CLUT.
+  * @retval None
+  */
+
+uint32_t GFX_write_label(const tFont *Font, GFX_DrawCfgWindow* hgfx, const char *pText, uint8_t color)
+{
+	return GFX_write_string_color(Font, hgfx, pText, 0, color);
+}
+
+
+/**
+  ******************************************************************************
+  * @brief   GFX writeGfx_write_label_varstring. /  Write string with all parameters and font color options
+  * @author  Peter Ryser
+  * @version V0.0.1
+  * @date    22-April-2014
+  ******************************************************************************
+	*
+  * @param  XleftGimpStyle:
+  * @param  XrightGimpStyle:
+  * @param  YtopGimpStyle:
+  * @param  color:
+  * @param  tFont:
+  * @param  text: 	text to be printed
+  * @retval None
+  */
+
+void Gfx_write_label_var(GFX_DrawCfgScreen *screenInput, uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle,  const tFont *Font, const uint8_t color, const char *text)
+{
+
+    GFX_DrawCfgWindow	hgfx;
+
+	if(XrightGimpStyle > 799)
+		XrightGimpStyle = 799;
+	if(XleftGimpStyle >= XrightGimpStyle)
+		XleftGimpStyle = 0;
+	if(YtopGimpStyle > 479)
+		YtopGimpStyle = 479;
+    hgfx.Image = screenInput;
+	hgfx.WindowNumberOfTextLines = 1;
+	hgfx.WindowLineSpacing = 0;
+	hgfx.WindowTab = 0;
+	hgfx.WindowX0 = XleftGimpStyle;
+	hgfx.WindowX1 = XrightGimpStyle;
+	hgfx.WindowY1 = 479 - YtopGimpStyle;
+	if(hgfx.WindowY1 < Font->height)
+		hgfx.WindowY0 = 0;
+	else
+		hgfx.WindowY0 = hgfx.WindowY1 - Font->height;
+
+	GFX_write_label(Font, &hgfx, text, color);
+}
+
+/**
+  ******************************************************************************
+  * @brief   GFX write string. /  Write string with all parameters and font options
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.1
+  * @date    22-April-2014
+  ******************************************************************************
+	*
+  * @param  hgfx: 			check gfx_engine.h.
+  * @param  color: 			32bit ARGB8888.
+  * @retval None
+  */
+
+uint16_t GFX_return_offset(const tFont *Font, char *pText, uint8_t position)
+{
+	char character;
+	uint16_t digit, i;
+	uint8_t found;
+	uint16_t distance;
+
+	if(position == 0)
+		return 0;
+
+	distance = 0;
+	for(digit = 0; digit < position; digit++)
+	{
+		character = pText[digit];
+		if(character == 0)
+			return 0;
+
+		found = 0;
+		for(i=0;i<Font->length;i++)
+		{
+			if(Font->chars[i].code == character)
+			{
+				found = 1;
+				break;
+			}
+		}
+		if(found)
+		{
+			distance += (uint16_t)(Font->chars[i].image->width);
+			if(Font == &FontT144)
+				distance += 3;
+			else
+			if(Font == &FontT105)
+				distance += 2;
+		}
+	}
+	return distance;
+
+	/*	 FEHLT:
+	if(*pText < ' ')
+	if((*pText) & 0x80)
+
+	if(((tFont *)settings.font == &FontT105) && settings.dualFont && ((*pText == '.') || (*pText == ':')))
+		settings.font = (uint32_t)&FontT54;
+	*/
+}
+
+void GFX_clean_line(GFX_DrawCfgWindow* hgfx, uint32_t line_number)
+{
+	uint16_t height;
+	uint32_t pDestination, i, j;
+	uint16_t left, width, bottom, nextlineStep;
+
+	bottom = hgfx->WindowY0;
+
+	if(hgfx->WindowNumberOfTextLines && line_number && (line_number <= hgfx->WindowNumberOfTextLines))
+	{
+		bottom += hgfx->WindowLineSpacing * (hgfx->WindowNumberOfTextLines - line_number);
+		height = hgfx->WindowLineSpacing;
+	}
+	else
+	{
+		height 	= 1 + hgfx->WindowY1 - bottom;
+	}
+
+	pDestination = (uint32_t)hgfx->Image->FBStartAdress;
+
+	left 		= hgfx->WindowX0;
+	width 	= 1 + hgfx->WindowX1 - left;
+	nextlineStep = hgfx->Image->ImageHeight - height;
+	nextlineStep *= 2;
+	pDestination += 2 * bottom;
+	pDestination += 2 * hgfx->Image->ImageHeight * left;
+
+	for(j = width; j > 0; j--)
+	{
+		for(i = height; i > 0; i--)
+		{
+			*(__IO uint16_t*)pDestination = 0;
+			pDestination += 2;
+		}
+		pDestination += nextlineStep;
+	}
+}
+
+
+void GFX_clean_area(GFX_DrawCfgScreen *tMscreen, uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle, uint16_t YBottomGimpStyle)
+{
+	uint16_t height;
+	uint32_t pDestination, i, j;
+	int32_t left, width, bottom, nextlineStep;
+
+	bottom = tMscreen->ImageHeight - YBottomGimpStyle;
+	height = 1 + YBottomGimpStyle - YtopGimpStyle;
+
+	if(bottom < 0)
+		bottom = 0;
+	if(height > tMscreen->ImageHeight)
+		height = tMscreen->ImageHeight;
+	
+	pDestination = tMscreen->FBStartAdress;
+
+	left 		= XleftGimpStyle;
+	width 	= 1 + XrightGimpStyle - left;
+	if(width < 1)
+		width = 1;
+
+	if(width > tMscreen->ImageWidth)
+		width = tMscreen->ImageWidth;
+
+	nextlineStep = tMscreen->ImageHeight - height;
+	nextlineStep *= 2;
+	pDestination += 2 * bottom;
+	pDestination += 2 * tMscreen->ImageHeight * left;
+
+	for(j = width; j > 0; j--)
+	{
+		for(i = height; i > 0; i--)
+		{
+			*(__IO uint16_t*)pDestination = 0;
+			pDestination += 2;
+		}
+		pDestination += nextlineStep;
+	}
+}
+
+
+uint32_t GFX_write_string(const tFont *Font, GFX_DrawCfgWindow* hgfx, const char *pText, uint32_t line_number)
+{
+	return GFX_write_string_color(Font, hgfx, pText, line_number, 0);
+}
+
+uint32_t GFX_write_string_color(const tFont *Font, GFX_DrawCfgWindow* hgfx, const char *pText, uint32_t line_number, uint8_t color)
+{
+	if(hgfx->Image->FBStartAdress < FBGlobalStart)
+		return 0;
+
+	GFX_CfgWriteString settings;
+	uint32_t newXdelta;
+	uint8_t minimal = 0;
+//	uint32_t try_again;
+
+	if(hgfx->WindowNumberOfTextLines && line_number && (line_number <= hgfx->WindowNumberOfTextLines))
+	{
+		settings.Ydelta = hgfx->WindowLineSpacing * (hgfx->WindowNumberOfTextLines - line_number);
+	}
+	else
+	{
+		settings.Ydelta = 0;
+	}
+	settings.font = (uint32_t)Font;
+	settings.Xdelta = 0;
+	settings.color = color;
+	settings.invert = 0;
+	settings.resize = 0;
+	settings.dualFont = 0;
+	settings.spaceMode = 0;
+	settings.singleSpaceWithSizeOfNextChar = 0;
+	settings.useTinyFont = 0;
+	settings.TinyFontExtraYdelta = 0;
+	settings.TinyFont = (uint32_t)Font;
+	settings.doubleSize = 0;
+
+	if((*pText) == TXT_MINIMAL) // for customtext and anything with Sonderzeichen
+		minimal = 1;
+	else
+		minimal = 0;
+
+	if(Font == &FontT144)
+		settings.TinyFont = (uint32_t)&FontT84;
+	else
+	if(Font == &FontT105)
+		settings.TinyFont = (uint32_t)&FontT54;
+	else
+	if(Font == &FontT54)
+	{
+		settings.TinyFont = (uint32_t)&FontT48;
+		settings.TinyFontExtraYdelta = -9;
+	}
+	else
+	if(Font == &FontT48)
+	{
+		settings.TinyFont = (uint32_t)&FontT24;
+		settings.TinyFontExtraYdelta = 6;
+	}
+	else
+	if(Font == &FontT42)
+	{
+		settings.TinyFont = (uint32_t)&FontT24;
+		settings.TinyFontExtraYdelta = 2;
+	}
+
+	settings.actualFont = (tFont *)settings.font;
+
+	while ((*pText != 0) && (settings.Xdelta != 0x0000FFFF))// und fehlend: Abfrage window / image size
+	{
+//		try_again = 0;
+
+		if((*pText == '\177') && !minimal)
+		{
+			if(settings.singleSpaceWithSizeOfNextChar)
+			{
+				settings.singleSpaceWithSizeOfNextChar = 0;
+				pText++;
+				settings.Xdelta += *pText;
+			}
+			else
+				settings.singleSpaceWithSizeOfNextChar = 1;
+		}
+		else
+		if(*pText < ' ')
+		{
+			/* Xdelta -inline- changes */
+			if((*pText == '\t') && !minimal)
+				settings.Xdelta = hgfx->WindowTab - hgfx->WindowX0;
+			else
+			if(*pText == '\r') // carriage return, no newline
+				settings.Xdelta = 0;
+			else
+			if((*pText == '\001') && !minimal) // center
+				settings.Xdelta = GFX_write__Modify_Xdelta__Centered(&settings, hgfx, pText+1);
+			else
+			if((*pText == '\002') && !minimal) // right
+				settings.Xdelta = GFX_write__Modify_Xdelta__RightAlign(&settings, hgfx, pText+1);
+			else
+			if((*pText == '\003') && !minimal) // doubleSize
+				settings.doubleSize = 1;
+			else
+			/* Xdelta -up/down changes */
+			if((*pText == '\f') && !minimal) // form feed = top align
+			{
+					if((hgfx->WindowY1 - hgfx->WindowY0) >= ((tFont *)settings.font)->height)
+					{
+						settings.Ydelta = hgfx->WindowY1 - hgfx->WindowY0;
+						settings.Ydelta -= ((tFont *)settings.font)->height;
+					}
+			}
+			else
+			if(*pText == '\n') // newline, no carriage return
+			{
+				if(hgfx->WindowNumberOfTextLines && (line_number < hgfx->WindowNumberOfTextLines))
+				{
+					line_number++;
+					settings.Ydelta = hgfx->WindowLineSpacing * (hgfx->WindowNumberOfTextLines - line_number);
+				}
+			}
+			else
+			/* Font style changes */
+			if(*pText == '\a')
+				settings.invert = 1;
+			else
+			if((*pText == '\016') && !minimal)
+			{
+				if(settings.dualFont == 0)
+					settings.dualFont = 1;
+				else
+					settings.actualFont = (tFont *)settings.TinyFont;
+			}
+			else
+			if((*pText == '\017') && !minimal)
+			{
+				settings.dualFont = 0;
+				settings.actualFont = (tFont *)settings.font;
+			}
+			else
+			if((*pText == '\005') && !minimal)
+			{
+				newXdelta = GFX_write_char(hgfx, &settings, 'a', (tFont *)&Awe48);
+				settings.Xdelta = newXdelta;
+			}
+			else
+			if((*pText == '\006') && !minimal)
+			{
+				newXdelta = GFX_write_char(hgfx, &settings, 'b', (tFont *)&Awe48);
+				settings.Xdelta = newXdelta;
+			}
+			else
+			if((*pText >= '\020') && (*pText <= '\032') && !minimal)
+				settings.color = *pText - '\020';
+			else
+			if((*pText == '\034') && !minimal)
+				settings.spaceMode = 1;
+			else
+			if((*pText == '\035') && !minimal)
+				settings.spaceMode = 0;
+		}
+		else
+		if(((*pText) == TXT_2BYTE) && !minimal)
+		{
+			pText++;
+			settings.Xdelta = GFX_write_substring(&settings, hgfx, (uint8_t)TXT_2BYTE, (int8_t)*pText);
+		}
+		else
+		if(((*pText) & 0x80) && !minimal)
+			settings.Xdelta = GFX_write_substring(&settings, hgfx, (uint8_t)*pText, 0);
+		else
+		if(!settings.invert && (*pText == ' '))
+		{
+			if(settings.spaceMode == 0)
+				settings.Xdelta += ((tFont *)settings.font)->spacesize;
+			else
+				settings.Xdelta += ((tFont *)settings.font)->spacesize2Monospaced;
+		}
+		else
+		if((settings.spaceMode == 1) && (*pText == ' '))
+				settings.Xdelta += ((tFont *)settings.font)->spacesize2Monospaced;
+		else
+		{
+			if(((tFont *)settings.font == &FontT144) && ((*pText == '.') || (*pText == ':')))
+					settings.actualFont = (tFont *)settings.TinyFont;
+			else
+			if(((tFont *)settings.font == &FontT105) && settings.dualFont && ((*pText == '.') || (*pText == ':')))
+					settings.actualFont = (tFont *)settings.TinyFont;
+
+			if(settings.actualFont == (tFont *)settings.TinyFont)
+				settings.Ydelta += settings.TinyFontExtraYdelta;
+
+			newXdelta = GFX_write_char(hgfx, &settings, *(uint8_t *)pText, settings.actualFont);
+			settings.Xdelta = newXdelta;
+
+			if(settings.actualFont == (tFont *)settings.TinyFont)
+				settings.Ydelta -= settings.TinyFontExtraYdelta;
+		}
+		if(pText != 0) /* for TXT_2BYTE */
+			pText++;
+	}
+	return settings.Ydelta;
+}
+
+/* Private functions ---------------------------------------------------------*/
+/******************************************************************************
+                            Static Function
+*******************************************************************************/
+
+/**
+  ******************************************************************************
+  * @brief   GFX write substring. /  Write string without parameters
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.1
+  * @date    22-April-2014
+  ******************************************************************************
+	*
+  * @param  hgfx: 			check gfx_engine.h.
+  * @param  color: 			32bit ARGB8888.
+  * @retval None
+  */
+
+static uint32_t GFX_write_substring(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, uint8_t textId, int8_t nextCharFor2Byte)
+{
+	uint8_t i, j;
+	uint32_t found;
+	uint32_t pText;
+	uint8_t gfx_selected_language;
+#ifndef BOOTLOADER_STANDALONE
+	SSettings *pSettings;
+	pSettings = settingsGetPointer();
+	gfx_selected_language = pSettings->selected_language;
+	if(gfx_selected_language >= LANGUAGE_END)
+#endif		
+		gfx_selected_language = 0;
+// -----------------------------
+	if(textId != (uint8_t)TXT_2BYTE) 
+	{
+		found = 0;
+		j = 0;
+		for(i=(uint8_t)TXT_Language;i<(uint8_t)TXT_END;i++)
+		{
+			if(text_array[j].code == textId)
+			{
+				found = 1;
+				break;
+			}
+			j++;
+		}
+		if(!found)
+			return cfg->Xdelta;
+// -----------------------------
+		pText = (uint32_t)text_array[j].text[gfx_selected_language];
+		if(!pText)
+			pText = (uint32_t)text_array[j].text[0];
+		else
+		if(*(char*)pText == 0)
+			pText = (uint32_t)text_array[j].text[0];
+	}
+// -----------------------------
+	else
+	{
+		if(!nextCharFor2Byte)
+			return cfg->Xdelta;
+		
+		found = 0;
+		for(j=0;j<(uint8_t)TXT2BYTE_END-(uint8_t)TXT2BYTE_START;j++)
+		{
+			if((uint8_t)text_array2[j].code == (uint8_t)nextCharFor2Byte)
+			{
+				found = 1;
+				break;
+			}
+		}
+		if(!found)
+			return cfg->Xdelta;
+// -----------------------------
+		pText = (uint32_t)text_array2[j].text[gfx_selected_language];
+		if(!pText)
+			pText = (uint32_t)text_array2[j].text[0];
+		else
+		if(*(char*)pText == 0)
+			pText = (uint32_t)text_array2[j].text[0];
+	}
+// -----------------------------
+	
+	if(cfg->actualFont == (tFont *)cfg->TinyFont)
+		cfg->Ydelta += cfg->TinyFontExtraYdelta;
+
+	while (*(char*)pText != 0)// und fehlend: Abfrage window / image size
+	{
+		if(*(char*)pText == '\t')
+			cfg->Xdelta = hgfx->WindowTab - hgfx->WindowX0;
+		else
+		if(*(char*)pText == ' ')
+			cfg->Xdelta += ((tFont *)cfg->actualFont)->spacesize;
+		else
+			cfg->Xdelta = GFX_write_char(hgfx, cfg, *(uint8_t *)pText, (tFont *)cfg->actualFont);
+
+    pText++;
+	}
+
+	if(cfg->actualFont == (tFont *)cfg->TinyFont)
+		cfg->Ydelta -= cfg->TinyFontExtraYdelta;
+
+	return cfg->Xdelta;
+}
+
+
+/**
+  ******************************************************************************
+  * @brief   GFX write char. /  Write non-inverted, non-colored with entire 8 bit range
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.1
+  * @date    22-April-2014
+  ******************************************************************************
+	*
+  * @param  hgfx: 			check gfx_engine.h.
+  * @param  Ydelta: 		input
+  * @param  character: 	character
+  * @param  *Font:		 	pointer to font to be used for this char
+	* @retval Ydelta:			0x0000FFFF if not successful or char_truncated
+  */
+
+static uint32_t GFX_write_char_doubleSize(GFX_DrawCfgWindow* hgfx, GFX_CfgWriteString* cfg, uint8_t character, tFont *Font)
+{
+	uint32_t i, j;
+	uint32_t width, height;
+	uint32_t found;
+	uint32_t pDestination;
+	uint32_t pDestinationColor;
+	uint32_t pSource;
+	uint32_t OffsetDestination;
+	uint32_t width_left;
+	uint32_t height_left;
+	uint32_t char_truncated_WidthFlag;
+	uint32_t char_truncated_Height;
+	uint8_t fill;
+	uint32_t widthFont, heightFont;
+	uint32_t nextLine;
+	
+
+	if(hgfx->Image->ImageWidth <= (hgfx->WindowX0 + cfg->Xdelta))
+		return 0x0000FFFF;
+
+	// -----------------------------
+	found = 0;
+	for(i=0;i<Font->length;i++)
+	{
+		if(Font->chars[i].code == character)
+		{
+			found = 1;
+			break;
+		}
+	}
+	if(!found)
+		return cfg->Xdelta;
+
+	pSource = ((uint32_t)Font->chars[i].image->data);
+	pDestination = 1 + (uint32_t)hgfx->Image->FBStartAdress;
+
+	heightFont = Font->chars[i].image->height;
+	widthFont = Font->chars[i].image->width;
+
+	height = heightFont*2;
+	width = widthFont*2;
+	
+	OffsetDestination = 2 * (hgfx->Image->ImageHeight - height);
+
+	pDestination += (hgfx->WindowX0 + cfg->Xdelta) * hgfx->Image->ImageHeight * 2;
+	pDestination += (hgfx->WindowY0 + cfg->Ydelta) * 2;
+	nextLine = hgfx->Image->ImageHeight * 2;
+
+// -----------------------------
+	char_truncated_WidthFlag = 0;
+	width_left = hgfx->Image->ImageWidth - (hgfx->WindowX0 + cfg->Xdelta);
+	if(width_left < width)
+	{
+		char_truncated_WidthFlag = 1;
+		width = width_left;
+		widthFont = width/2;
+	}
+// -----------------------------
+	char_truncated_Height = 0;
+	height_left = hgfx->Image->ImageHeight - (hgfx->WindowY0 + cfg->Ydelta);
+	if(height_left < height)
+	{
+		char_truncated_Height = height - height_left;
+		if((char_truncated_Height & 1) != 0)
+		{
+			height_left -= 1;
+			char_truncated_Height += 1;
+		}
+		height = height_left;
+		heightFont = height/2;
+	}
+	OffsetDestination += 2 * char_truncated_Height;
+// -----------------------------
+	if(height == 0)
+		return 0x0000FFFF;
+// -----------------------------
+	
+	if((cfg->color > 0) )
+	{
+		pDestinationColor = pDestination - 1;
+
+		for(i = width; i > 0; i--)
+		{
+			for (j = height; j > 0; j--)
+			{
+				*(__IO uint32_t*)pDestinationColor =  cfg->color;
+				pDestinationColor += 2;
+			}
+			pDestinationColor += OffsetDestination;
+		}
+	}
+
+	if(cfg->singleSpaceWithSizeOfNextChar)
+	{
+		cfg->singleSpaceWithSizeOfNextChar = 0;
+ 
+		if(cfg->invert)
+			fill = 0xFF;
+		else
+			fill = 0;
+
+		height /= 2;
+		for(i = width; i > 0; i--)
+		{
+			for (j = height; j > 0; j--)
+			{
+				*(__IO uint8_t*)pDestination = fill;
+				pDestination += 2;
+				*(__IO uint8_t*)pDestination = fill;
+				pDestination += 2;
+			}
+			pDestination += OffsetDestination;
+		}
+	}
+	else
+	if(cfg->invert)
+	{
+		if((heightFont & 3) == 0) /* unroll for perfomance, by 4 if possible, by 2 (16bit) otherwise */
+		{
+			heightFont /= 4;
+			for(i = widthFont; i > 0; i--)
+			{
+				if(*(uint8_t*)pSource != 0x01)
+				{
+					for (j = heightFont; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+					}
+					pSource += char_truncated_Height;
+				}
+				else
+				{
+					pSource++;
+					for (j = height; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+					}
+				}
+				pDestination += OffsetDestination + nextLine;
+			}
+		}
+		else
+		{
+			heightFont /= 2;
+			for(i = widthFont; i > 0; i--)
+			{
+				if(*(uint8_t*)pSource != 0x01)
+				{
+					for (j = heightFont; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+					}
+					pSource += char_truncated_Height;
+				}
+				else
+				{
+					pSource++;
+					for (j = heightFont; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						*(__IO uint8_t*)(pDestination + nextLine) = 0xFF;
+						pDestination += 2;
+					}
+				}
+				pDestination += OffsetDestination + nextLine;
+			}
+		}
+	}
+	else
+	{
+		if((heightFont & 3) == 0) /* unroll for perfomance, by 4 if possible, by 2 (16bit) otherwise */
+		{
+			heightFont /= 4;
+			for(i = widthFont; i > 0; i--)
+			{
+				if(*(uint8_t*)pSource != 0x01)
+				{
+					for (j = heightFont; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+					}
+					pSource += char_truncated_Height;
+				}
+				else
+				{
+					pSource++;
+					pDestination +=  2 * height;
+				}
+				pDestination += OffsetDestination + nextLine;
+			}
+		}
+		else
+		{
+			heightFont /= 2;
+			for(i = widthFont; i > 0; i--)
+			{
+				if(*(uint8_t*)pSource != 0x01)
+				{
+					for (j = heightFont; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						*(__IO uint8_t*)(pDestination + nextLine) = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+					}
+					pSource += char_truncated_Height;
+				}
+				else
+				{
+					pSource++;
+					pDestination +=  2 * height;
+				}
+				pDestination += OffsetDestination + nextLine;
+			}
+		}
+	}
+
+// -----------------------------
+
+	if(Font == &FontT144)
+		width += 6;
+	else
+	if(Font == &FontT105)
+		width += 4;
+
+// -----------------------------
+
+	if(char_truncated_WidthFlag)
+		return 0x0000FFFF;
+	else
+		return cfg->Xdelta + width;
+	
+}
+
+
+/**
+  ******************************************************************************
+  * @brief   GFX write char. /  Write non-inverted, non-colored with entire 8 bit range
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.1
+  * @date    22-April-2014
+  ******************************************************************************
+	*
+  * @param  hgfx: 			check gfx_engine.h.
+  * @param  Ydelta: 		input
+  * @param  character: 	character
+  * @param  *Font:		 	pointer to font to be used for this char
+	* @retval Ydelta:			0x0000FFFF if not successful or char_truncated
+  */
+
+static uint32_t GFX_write_char(GFX_DrawCfgWindow* hgfx, GFX_CfgWriteString* cfg, uint8_t character, tFont *Font)
+{
+	if(cfg->doubleSize)
+	{
+		return GFX_write_char_doubleSize(hgfx, cfg, character, Font);
+	}
+	
+	uint32_t i, j;
+	uint32_t width, height;
+	uint32_t found;
+	uint32_t pDestination;
+	uint32_t pDestinationColor;
+	uint32_t pSource;
+	uint32_t OffsetDestination;
+	uint32_t width_left;
+	uint32_t height_left;
+	uint32_t char_truncated_WidthFlag;
+	uint32_t char_truncated_Height;
+	uint8_t fill;
+
+	if(hgfx->Image->ImageWidth <= (hgfx->WindowX0 + cfg->Xdelta))
+		return 0x0000FFFF;
+
+	// -----------------------------
+	found = 0;
+	for(i=0;i<Font->length;i++)
+	{
+		if(Font->chars[i].code == character)
+		{
+			found = 1;
+			break;
+		}
+	}
+	if(!found)
+		return cfg->Xdelta;
+// -----------------------------
+/*
+	if(Font == &Font144)
+		cfg->Xdelta += 3;
+	else
+	if(Font == &Font84)
+		cfg->Xdelta += 2;
+*/
+// -----------------------------
+
+
+	pSource = ((uint32_t)Font->chars[i].image->data);
+	pDestination = 1 + (uint32_t)hgfx->Image->FBStartAdress;
+
+	height = Font->chars[i].image->height;
+	width = Font->chars[i].image->width;
+
+	OffsetDestination = 2 * (hgfx->Image->ImageHeight - height);
+
+	pDestination += (hgfx->WindowX0 + cfg->Xdelta) * hgfx->Image->ImageHeight * 2;
+	pDestination += (hgfx->WindowY0 + cfg->Ydelta) * 2;
+
+
+
+// -----------------------------
+	char_truncated_WidthFlag = 0;
+	width_left = hgfx->Image->ImageWidth - (hgfx->WindowX0 + cfg->Xdelta);
+	if(width_left < width)
+	{
+		char_truncated_WidthFlag = 1;
+		width = width_left;
+	}
+// -----------------------------
+	char_truncated_Height = 0;
+	height_left = hgfx->Image->ImageHeight - (hgfx->WindowY0 + cfg->Ydelta);
+	if(height_left < height)
+	{
+		char_truncated_Height = height - height_left;
+		if((char_truncated_Height & 1) != 0)
+		{
+			height_left -= 1;
+			char_truncated_Height += 1;
+		}
+		height = height_left;
+	}
+	OffsetDestination += 2 * char_truncated_Height;
+// -----------------------------
+	if(height == 0)
+		return 0x0000FFFF;
+// -----------------------------
+	
+	if((cfg->color > 0) )//&& (cfg->color < 6))
+	{
+		pDestinationColor = pDestination - 1;
+
+		for(i = width; i > 0; i--)
+		{
+			for (j = height; j > 0; j--)
+			{
+				*(__IO uint32_t*)pDestinationColor =  cfg->color;//ColorLUT[cfg->color - 1];
+				pDestinationColor += 2;
+			}
+			pDestinationColor += OffsetDestination;
+		}
+	}
+
+	if(cfg->singleSpaceWithSizeOfNextChar)
+	{
+		cfg->singleSpaceWithSizeOfNextChar = 0;
+ 
+		if(cfg->invert)
+			fill = 0xFF;
+		else
+			fill = 0;
+
+		height /= 2;
+		for(i = width; i > 0; i--)
+		{
+			for (j = height; j > 0; j--)
+			{
+				*(__IO uint8_t*)pDestination = fill;
+				pDestination += 2;
+				*(__IO uint8_t*)pDestination = fill;
+				pDestination += 2;
+			}
+			pDestination += OffsetDestination;
+		}
+	}
+	else
+	if(cfg->invert)
+	{
+		if((height & 3) == 0) /* unroll for perfomance, by 4 if possible, by 2 (16bit) otherwise */
+		{
+			height /= 4;
+			for(i = width; i > 0; i--)
+			{
+				if(*(uint8_t*)pSource != 0x01)
+				{
+					for (j = height; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+					}
+					pSource += char_truncated_Height;
+				}
+				else
+				{
+					pSource++;
+					for (j = height; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						pDestination += 2;
+					}
+				}
+				pDestination += OffsetDestination;
+			}
+		}
+		else
+		{
+			height /= 2;
+			for(i = width; i > 0; i--)
+			{
+				if(*(uint8_t*)pSource != 0x01)
+				{
+					for (j = height; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF - *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+					}
+					pSource += char_truncated_Height;
+				}
+				else
+				{
+					pSource++;
+					for (j = height; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = 0xFF;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = 0xFF;
+						pDestination += 2;
+					}
+				}
+				pDestination += OffsetDestination;
+			}
+		}
+	}
+	else
+	{
+		if((height & 3) == 0) /* unroll for perfomance, by 4 if possible, by 2 (16bit) otherwise */
+		{
+			height /= 4;
+			for(i = width; i > 0; i--)
+			{
+				if(*(uint8_t*)pSource != 0x01)
+				{
+					for (j = height; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+					}
+					pSource += char_truncated_Height;
+				}
+				else
+				{
+					pSource++;
+					pDestination +=  2 * height * 4;
+				}
+				pDestination += OffsetDestination;
+			}
+		}
+		else
+		{
+			height /= 2;
+			for(i = width; i > 0; i--)
+			{
+				if(*(uint8_t*)pSource != 0x01)
+				{
+					for (j = height; j > 0; j--)
+					{
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+						*(__IO uint8_t*)pDestination = *(uint8_t*)pSource;
+						pSource++;
+						pDestination += 2;
+					}
+					pSource += char_truncated_Height;
+				}
+				else
+				{
+					pSource++;
+					pDestination +=  2 * height * 2;
+				}
+				pDestination += OffsetDestination;
+			}
+		}
+	}
+
+// -----------------------------
+
+	if(Font == &FontT144)
+		width += 3;
+	else
+	if(Font == &FontT105)
+		width += 2;
+/*
+	else
+	if(Font == &Font144)
+		width += 3;
+	else
+	if(Font == &Font84)
+		width += 1;
+*/
+// -----------------------------
+
+	if(char_truncated_WidthFlag)
+		return 0x0000FFFF;
+	else
+		return cfg->Xdelta + width;
+}
+
+
+/**
+  ******************************************************************************
+  * @brief   GFX write Modify helper for center and right align.
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.1
+  * @date    17-March-2015
+  ******************************************************************************
+	*
+  * @param  *cText: 			output
+  * @param  *pTextInput:	input
+	* @param  gfx_selected_language: 	gfx_selected_language
+	* @retval counter and *cText content
+  */
+int8_t GFX_write__Modify_helper(char *cText, const char *pTextInput, uint8_t gfx_selected_language)
+{
+	uint32_t pText, backup;
+	uint8_t textId;
+	int8_t counter;
+	uint32_t found;
+	uint32_t j;
+	
+	pText = (uint32_t)pTextInput;
+	counter = 0;
+	while((counter < 100) && (*(char*)pText != 0) && (*(char*)pText != '\r'))
+	{
+		if((*(char*)pText) == TXT_2BYTE)
+		{
+			backup = pText;
+			
+			found = 0;
+			j = 0;
+			textId = (int8_t)*(char*)(pText + 1);
+			if(textId != 0)
+			{
+				for(j=0;j<(uint8_t)TXT2BYTE_END-(uint8_t)TXT2BYTE_START;j++)
+				{
+					if((uint8_t)text_array2[j].code == (uint8_t)textId)
+					{
+						found = 1;
+						break;
+					}
+				}
+				if(found)
+				{
+						pText = (uint32_t)text_array2[j].text[gfx_selected_language];
+						if(!pText)
+							pText = (uint32_t)text_array2[j].text[0];
+						else
+						if(*(char*)pText == 0)
+							pText = (uint32_t)text_array2[j].text[0];
+
+						while((counter < 100) && (*(char*)pText != 0))
+							cText[counter++] = *(char*)pText++; 
+				}	
+				pText = backup + 2;
+			}
+			else
+				pText = 0;
+		}
+		if((*(char*)pText) & 0x80)
+		{
+			backup = pText;
+			
+			found = 0;
+			j = 0;
+			textId = (uint8_t)*(char*)pText;
+			for(uint8_t ii=(uint8_t)TXT_Language;ii<(uint8_t)TXT_END;ii++)
+			{
+				if(text_array[j].code == textId)
+				{
+					found = 1;
+					break;
+				}
+				j++;
+			}
+			if(found)
+			{
+					pText = (uint32_t)text_array[j].text[gfx_selected_language];
+					if(!pText)
+						pText = (uint32_t)text_array[j].text[0];
+					else
+					if(*(char*)pText == 0)
+						pText = (uint32_t)text_array[j].text[0];
+
+					while((counter < 100) && (*(char*)pText != 0))
+						cText[counter++] = *(char*)pText++; 
+			}	
+			pText = backup + 1;
+		}
+		else
+		{
+			cText[counter++] = *(char*)pText++; 
+		}
+	}
+	cText[counter] = 0;
+	return counter;
+}
+
+
+/**
+  ******************************************************************************
+  * @brief   GFX write Modify Ydelta for align. /  calc Ydelta for start
+  * @author  heinrichs weikamp gmbh
+  * @version V0.0.1
+  * @date    22-April-2014
+  ******************************************************************************
+	*
+  * @param  *hgfx: 		check gfx_engine.h.
+  * @param  *cfg:		 	Ydelta, Font
+  * @param  *pText: 	character
+	* @retval Ydelta:		0 if text has to start left ( and probably does not fit)
+  */
+
+uint32_t GFX_write__Modify_Xdelta__Centered(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, const char *pTextInput)
+{
+	char cText[101];
+	uint32_t result;
+	uint32_t Xsum;
+	uint32_t i, j;
+	uint8_t gfx_selected_language;
+	uint32_t pText;
+
+#ifndef BOOTLOADER_STANDALONE
+	SSettings *pSettings;
+	pSettings = settingsGetPointer();
+	gfx_selected_language = pSettings->selected_language;
+	if(gfx_selected_language >= LANGUAGE_END)
+#endif
+		gfx_selected_language = 0;
+// -----------------------------
+
+	GFX_write__Modify_helper(cText,pTextInput,gfx_selected_language);
+
+	pText = (uint32_t)&cText[0];
+	Xsum = 0;
+	j = 0;
+	while (*(char*)pText != 0)// und fehlend: Abfrage window / image size
+	{
+		for(i=0;i<((tFont *)cfg->font)->length;i++)
+		{
+			if(((tFont *)cfg->font)->chars[i].code == *(char*)pText)
+			{
+				Xsum += ((tFont *)cfg->font)->chars[i].image->width;
+				break;
+			}
+		}
+		pText++;
+		j++;
+		if(((tFont *)cfg->font == &FontT144) && (*(char*)pText != 0))
+			Xsum += 3;
+		else
+		if(((tFont *)cfg->font == &FontT105) && (*(char*)pText != 0))
+			Xsum += 2;
+	}
+	pText -= j;
+
+	if(cfg->doubleSize)
+		Xsum *= 2;
+	
+	result = hgfx->WindowX1 - hgfx->WindowX0;
+	if(Xsum < result)
+	{
+		result -= Xsum;
+		result /= 2;
+	}
+	else
+		result = 0;
+	return result;
+}
+
+
+uint32_t GFX_write__Modify_Xdelta__RightAlign(GFX_CfgWriteString* cfg, GFX_DrawCfgWindow* hgfx, const char *pTextInput)
+{
+	char cText[101];
+	uint32_t result;
+	uint32_t Xsum;
+	uint32_t i, j;
+	tFont *font;
+	uint8_t gfx_selected_language;
+	uint32_t pText;
+	uint8_t setToTinyFont = 0;
+
+#ifndef BOOTLOADER_STANDALONE
+	SSettings *pSettings;
+	pSettings = settingsGetPointer();
+	gfx_selected_language = pSettings->selected_language;
+	if(gfx_selected_language >= LANGUAGE_END)
+#endif
+		gfx_selected_language = 0;
+// -----------------------------
+
+	GFX_write__Modify_helper(cText,pTextInput,gfx_selected_language);
+	pText = (uint32_t)&cText[0];
+
+// -----------------------------
+
+	setToTinyFont = 0;
+	font = (tFont *)cfg->font;
+	Xsum = 0;
+	j = 0;
+
+	while (*(char*)pText != 0)// und fehlend: Abfrage window / image size
+	{
+		if((font == &FontT144) && (*(char*)pText == '.'))
+		{
+			font = (tFont *)&FontT84;
+		}
+		else
+		if((font == &FontT105) && (*(char*)pText == '\16')) // two times to start tiny font
+		{
+			if(!setToTinyFont)
+				setToTinyFont = 1;
+			else
+				font = (tFont *)&FontT54;
+		}
+		else
+		if((font == &FontT105) && cfg->dualFont && ((*(char*)pText == '.') || (*(char*)pText == ':')))
+		{
+			font = (tFont *)&FontT54;
+		}
+
+		if(*(char*)pText == ' ')
+		{
+			Xsum += font->spacesize;
+		}
+		else
+		{
+			for(i=0;i<font->length;i++)
+			{
+				if(font->chars[i].code == *(char*)pText)
+				{
+					Xsum += font->chars[i].image->width;
+					break;
+				}
+			}
+		}
+		pText++;
+		j++;
+		if((font == &FontT144) && (*(char*)pText != 0))
+			Xsum += 3;
+		else
+		if((font == &FontT105) && (*(char*)pText != 0))
+			Xsum += 2;
+	}
+	pText -= j;
+
+	if(cfg->doubleSize)
+		Xsum *= 2;
+	
+	result = hgfx->WindowX1 - hgfx->WindowX0 - 1;
+	if(Xsum < result)
+		result -= Xsum;
+	else
+		result = 0;
+
+	return result;
+}
+
+
+
+void GFX_LTDC_Init(void)
+{
+	/*
+		HSYNC=10 (9+1)
+		HBP=10 (19-10+1)
+		ActiveW=480 (499-10-10+1)
+		HFP=8 (507-480-10-10+1)
+
+		VSYNC=2 (1+1)
+		VBP=2 (3-2+1)
+		ActiveH=800 (803-2-2+1)
+		VFP=2 (805-800-2-2+1)
+	*/
+
+  /* Timing configuration */
+  /* Horizontal synchronization width = Hsync - 1 */
+  LtdcHandle.Init.HorizontalSync = 9;
+  /* Vertical synchronization height = Vsync - 1 */
+  LtdcHandle.Init.VerticalSync = 1;
+  /* Accumulated horizontal back porch = Hsync + HBP - 1 */
+  LtdcHandle.Init.AccumulatedHBP = 19;
+  /* Accumulated vertical back porch = Vsync + VBP - 1 */
+  LtdcHandle.Init.AccumulatedVBP = 3;
+  /* Accumulated active width = Hsync + HBP + Active Width - 1 */
+  LtdcHandle.Init.AccumulatedActiveW = 499;//500;//499;
+  /* Accumulated active height = Vsync + VBP + Active Heigh - 1 */
+  LtdcHandle.Init.AccumulatedActiveH = 803;
+  /* Total width = Hsync + HBP + Active Width + HFP - 1 */
+  LtdcHandle.Init.TotalWidth = 507;//508;//507;
+  /* Total height = Vsync + VBP + Active Heigh + VFP - 1 */
+  LtdcHandle.Init.TotalHeigh = 805;
+
+	/* Configure R,G,B component values for LCD background color */
+	LtdcHandle.Init.Backcolor.Red= 0;
+	LtdcHandle.Init.Backcolor.Blue= 0;
+	LtdcHandle.Init.Backcolor.Green= 0;
+
+	/* 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 / LTDC_PLLSAI_DIVR_8 = 48/4 = 6Mhz */
+
+/* done in main.c SystemClockConfig
+
+	PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
+	PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
+	PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
+	PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
+	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+*/
+	/* Polarity */
+	LtdcHandle.Init.HSPolarity = LTDC_HSPOLARITY_AL;
+	LtdcHandle.Init.VSPolarity = LTDC_VSPOLARITY_AL;
+	LtdcHandle.Init.DEPolarity = LTDC_DEPOLARITY_AL;
+	LtdcHandle.Init.PCPolarity = LTDC_PCPOLARITY_IIPC;//LTDC_PCPOLARITY_IPC;
+
+	LtdcHandle.Instance = LTDC;
+
+  /* Configure the LTDC */
+  if(HAL_LTDC_Init(&LtdcHandle) != HAL_OK) // auch init der GPIO Pins
+  {
+    /* Initialization Error */
+    GFX_Error_Handler();
+  }
+}
+
+void GFX_VGA_LTDC_Init_test(void)
+{
+
+  LtdcHandle.Init.HorizontalSync = 48;
+  /* Vertical synchronization height = Vsync - 1 */
+  LtdcHandle.Init.VerticalSync = 3;
+  /* Accumulated horizontal back porch = Hsync + HBP - 1 */
+  LtdcHandle.Init.AccumulatedHBP = 48 + 40 - 1;
+  /* Accumulated vertical back porch = Vsync + VBP - 1 */
+  LtdcHandle.Init.AccumulatedVBP = 3 + 29 - 1;
+  /* Accumulated active width = Hsync + HBP + Active Width - 1 */
+  LtdcHandle.Init.AccumulatedActiveW = 800 + 48 + 40 - 1;//499;//500;//499;
+  /* Accumulated active height = Vsync + VBP + Active Heigh - 1 */
+  LtdcHandle.Init.AccumulatedActiveH = 480 + 3 + 29 - 1;
+  /* Total width = Hsync + HBP + Active Width + HFP - 1 */
+  LtdcHandle.Init.TotalWidth = 800 + 48 + 40 - 1 + 40;//508;//507;
+  /* Total height = Vsync + VBP + Active Heigh + VFP - 1 */
+  LtdcHandle.Init.TotalHeigh = 480 + 3 + 29 - 1 + 13;
+
+	/* Configure R,G,B component values for LCD background color */
+	LtdcHandle.Init.Backcolor.Red= 0;
+	LtdcHandle.Init.Backcolor.Blue= 0;
+	LtdcHandle.Init.Backcolor.Green= 0;
+
+	/* 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 / LTDC_PLLSAI_DIVR_8 = 48/4 = 6Mhz */
+
+/* done in main.c SystemClockConfig
+
+	PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
+	PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
+	PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
+	PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
+	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+*/
+	/* Polarity */
+	LtdcHandle.Init.HSPolarity = LTDC_HSPOLARITY_AL;
+	LtdcHandle.Init.VSPolarity = LTDC_VSPOLARITY_AL;
+	LtdcHandle.Init.DEPolarity = LTDC_DEPOLARITY_AL;
+	LtdcHandle.Init.PCPolarity = LTDC_PCPOLARITY_IPC;//LTDC_PCPOLARITY_IPC;
+
+	LtdcHandle.Instance = LTDC;
+
+  /* Configure the LTDC */
+  if(HAL_LTDC_Init(&LtdcHandle) != HAL_OK) // auch init der GPIO Pins
+  {
+    /* Initialization Error */
+    GFX_Error_Handler();
+  }
+}
+
+
+void GFX_VGA_LTDC_Init_org(void)
+{
+
+  LtdcHandle.Init.HorizontalSync = 96;
+  /* Vertical synchronization height = Vsync - 1 */
+  LtdcHandle.Init.VerticalSync = 2;
+  /* Accumulated horizontal back porch = Hsync + HBP - 1 */
+  LtdcHandle.Init.AccumulatedHBP = 96 + 48;
+  /* Accumulated vertical back porch = Vsync + VBP - 1 */
+  LtdcHandle.Init.AccumulatedVBP = 2 + 35;
+  /* Accumulated active width = Hsync + HBP + Active Width - 1 */
+  LtdcHandle.Init.AccumulatedActiveW = 96 + 48 + 800;//499;//500;//499;
+  /* Accumulated active height = Vsync + VBP + Active Heigh - 1 */
+  LtdcHandle.Init.AccumulatedActiveH = 2 + 35 + 480;
+  /* Total width = Hsync + HBP + Active Width + HFP - 1 */
+  LtdcHandle.Init.TotalWidth = 96 + 48 + 800 + 12;//508;//507;
+  /* Total height = Vsync + VBP + Active Heigh + VFP - 1 */
+  LtdcHandle.Init.TotalHeigh = 2 + 35 + 480 + 12;
+
+	/* Configure R,G,B component values for LCD background color */
+	LtdcHandle.Init.Backcolor.Red= 0;
+	LtdcHandle.Init.Backcolor.Blue= 0;
+	LtdcHandle.Init.Backcolor.Green= 0;
+
+	/* 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 / LTDC_PLLSAI_DIVR_8 = 48/4 = 6Mhz */
+
+/* done in main.c SystemClockConfig
+
+	PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
+	PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
+	PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
+	PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
+	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+*/
+	/* Polarity */
+	LtdcHandle.Init.HSPolarity = LTDC_HSPOLARITY_AL;
+	LtdcHandle.Init.VSPolarity = LTDC_VSPOLARITY_AH;
+	LtdcHandle.Init.DEPolarity = LTDC_DEPOLARITY_AL;
+	LtdcHandle.Init.PCPolarity = LTDC_PCPOLARITY_IPC;//LTDC_PCPOLARITY_IPC;
+
+	LtdcHandle.Instance = LTDC;
+
+  /* Configure the LTDC */
+  if(HAL_LTDC_Init(&LtdcHandle) != HAL_OK) // auch init der GPIO Pins
+  {
+    /* Initialization Error */
+    GFX_Error_Handler();
+  }
+}
+
+void GFX_VGA_LTDC_Init(void)
+//void GFX_VGA_LTDC_Init_640x480(void)
+{
+
+  LtdcHandle.Init.HorizontalSync = 96;
+  /* Vertical synchronization height = Vsync - 1 */
+  LtdcHandle.Init.VerticalSync = 2;
+  /* Accumulated horizontal back porch = Hsync + HBP - 1 */
+  LtdcHandle.Init.AccumulatedHBP = 96 + 48;
+  /* Accumulated vertical back porch = Vsync + VBP - 1 */
+  LtdcHandle.Init.AccumulatedVBP = 2 + 35;
+  /* Accumulated active width = Hsync + HBP + Active Width - 1 */
+  LtdcHandle.Init.AccumulatedActiveW = 96 + 48 + 640;//499;//500;//499;
+  /* Accumulated active height = Vsync + VBP + Active Heigh - 1 */
+  LtdcHandle.Init.AccumulatedActiveH = 2 + 35 + 480;
+  /* Total width = Hsync + HBP + Active Width + HFP - 1 */
+  LtdcHandle.Init.TotalWidth = 96 + 48 + 640 + 12;//508;//507;
+  /* Total height = Vsync + VBP + Active Heigh + VFP - 1 */
+  LtdcHandle.Init.TotalHeigh = 2 + 35 + 480 + 12;
+
+	/* Configure R,G,B component values for LCD background color */
+	LtdcHandle.Init.Backcolor.Red= 0;
+	LtdcHandle.Init.Backcolor.Blue= 0;
+	LtdcHandle.Init.Backcolor.Green= 0;
+
+	/* 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 / LTDC_PLLSAI_DIVR_8 = 48/4 = 6Mhz */
+
+/* done in main.c SystemClockConfig
+
+	PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
+	PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
+	PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
+	PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
+	HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
+*/
+	/* Polarity */
+	LtdcHandle.Init.HSPolarity = LTDC_HSPOLARITY_AL;
+	LtdcHandle.Init.VSPolarity = LTDC_VSPOLARITY_AH;
+	LtdcHandle.Init.DEPolarity = LTDC_DEPOLARITY_AL;
+	LtdcHandle.Init.PCPolarity = LTDC_PCPOLARITY_IPC;//LTDC_PCPOLARITY_IPC;
+
+	LtdcHandle.Instance = LTDC;
+
+  /* Configure the LTDC */
+  if(HAL_LTDC_Init(&LtdcHandle) != HAL_OK) // auch init der GPIO Pins
+  {
+    /* Initialization Error */
+    GFX_Error_Handler();
+  }
+}
+
+
+void GFX_LTDC_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address)
+{
+  LTDC_LayerCfgTypeDef   Layercfg;
+
+ /* Layer Init */
+  Layercfg.WindowX0 = 0;
+  Layercfg.WindowX1 = 480;
+  Layercfg.WindowY0 = 0;
+  Layercfg.WindowY1 = 800;
+  Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_AL88;//LTDC_PIXEL_FORMAT_ARGB8888;
+  Layercfg.FBStartAdress = FB_Address;
+  Layercfg.Alpha = 255;
+  Layercfg.Alpha0 = 0;
+  Layercfg.Backcolor.Blue = 0;
+  Layercfg.Backcolor.Green = 0;
+  Layercfg.Backcolor.Red = 0;
+  Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
+  Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
+  Layercfg.ImageWidth = 480;
+  Layercfg.ImageHeight = 800;
+
+	HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, LayerIndex);
+  HAL_LTDC_ConfigLayer(&LtdcHandle, &Layercfg, LayerIndex);
+	HAL_LTDC_EnableCLUT(&LtdcHandle, LayerIndex);
+}
+
+void GFX_VGA_LTDC_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address)
+{
+  LTDC_LayerCfgTypeDef   Layercfg;
+
+ /* Layer Init */
+  Layercfg.WindowX0 = 0;
+  Layercfg.WindowX1 = 640;
+  Layercfg.WindowY0 = 0;
+  Layercfg.WindowY1 = 480;
+  Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_AL88;//LTDC_PIXEL_FORMAT_ARGB8888;
+  Layercfg.FBStartAdress = FB_Address;
+  Layercfg.Alpha = 255;
+  Layercfg.Alpha0 = 0;
+  Layercfg.Backcolor.Blue = 0;
+  Layercfg.Backcolor.Green = 0;
+  Layercfg.Backcolor.Red = 0;
+  Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
+  Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
+  Layercfg.ImageWidth = 640;
+  Layercfg.ImageHeight = 480;
+
+	HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, LayerIndex);
+  HAL_LTDC_ConfigLayer(&LtdcHandle, &Layercfg, LayerIndex);
+	HAL_LTDC_EnableCLUT(&LtdcHandle, LayerIndex);
+}
+
+void GFX_LTDC_LayerTESTInit(uint16_t LayerIndex, uint32_t FB_Address)
+{
+  LTDC_LayerCfgTypeDef   Layercfg;
+
+ /* Layer Init */
+  Layercfg.WindowX0 = 0;
+  Layercfg.WindowX1 = 390;
+  Layercfg.WindowY0 = 0;
+  Layercfg.WindowY1 = 800;
+  Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_AL88;//LTDC_PIXEL_FORMAT_ARGB8888;
+  Layercfg.FBStartAdress = FB_Address;
+  Layercfg.Alpha = 255;
+  Layercfg.Alpha0 = 255;
+  Layercfg.Backcolor.Blue = 0;
+  Layercfg.Backcolor.Green = 0;
+  Layercfg.Backcolor.Red = 200;
+  Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
+  Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
+  Layercfg.ImageWidth = 480;
+  Layercfg.ImageHeight = 800;
+
+	HAL_LTDC_ConfigCLUT(&LtdcHandle, ColorLUT, CLUT_END, LayerIndex);
+  HAL_LTDC_ConfigLayer(&LtdcHandle, &Layercfg, LayerIndex);
+	HAL_LTDC_EnableCLUT(&LtdcHandle, LayerIndex);
+}
+
+
+uint32_t GFX_doubleBufferOne(void)
+{
+	return SDRAM_DOUBLE_BUFFER_ONE;
+}
+
+
+uint32_t GFX_doubleBufferTwo(void)
+{
+	return SDRAM_DOUBLE_BUFFER_TWO;
+}
+
+/*
+void doubleBufferClear(uint32_t pDestination)
+{
+	for(uint32_t i = 2*200*480; i > 0; i--)
+	{
+		*(__IO uint16_t*)pDestination = 0;
+		pDestination += 2;
+		*(__IO uint16_t*)pDestination = 0;
+		pDestination += 2;
+		*(__IO uint16_t*)pDestination = 0;
+		pDestination += 2;
+		*(__IO uint16_t*)pDestination = 0;
+		pDestination += 2;
+	}
+}
+
+
+void GFX_doubleBufferClearOne(void)
+{
+	doubleBufferClear(SDRAM_DOUBLE_BUFFER_ONE);
+}
+
+
+void GFX_doubleBufferClearTwo(void)
+{
+	doubleBufferClear(SDRAM_DOUBLE_BUFFER_TWO);
+}
+*/
+
+uint32_t getFrameByNumber(uint8_t ZeroToMaxFrames)
+{
+	if(ZeroToMaxFrames >= MAXFRAMES)
+		return 0;
+	else
+		return frame[ZeroToMaxFrames].StartAddress;
+}
+
+uint32_t getFrame(uint8_t callerId)
+{
+	uint8_t i;
+
+	i = 0;
+	while((i < MAXFRAMES) && (frame[i].status != CLEAR))
+		i++;
+
+	if((i < MAXFRAMES) && (frame[i].status == CLEAR))
+	{
+		frame[i].status = BLOCKED;
+		frame[i].caller = callerId;
+		return frame[i].StartAddress;
+	}
+
+	i = 0;
+	while((i < MAXFRAMES) && (frame[i].status != RELEASED))
+		i++;
+
+	if((i < MAXFRAMES) && (frame[i].status == RELEASED))
+	{
+		GFX_clear_frame_immediately(frame[i].StartAddress);
+		frame[i].status = BLOCKED;
+		return frame[i].StartAddress;
+	}
+	return 0;
+}
+
+
+void GFX_forceReleaseFramesWithId(uint8_t callerId)
+{
+	for(int i=0; i<MAXFRAMES; i++)
+		if((frame[i].caller == callerId) && (frame[i].status == BLOCKED))
+			frame[i].status = RELEASED;
+}
+
+
+void releaseAllFramesExcept(uint8_t callerId, uint32_t frameStartAddress)
+{
+	for(int i=0; i<MAXFRAMES; i++)
+		if((frame[i].caller == callerId) && (frame[i].status == BLOCKED) && (frame[i].StartAddress != frameStartAddress))
+			frame[i].status = RELEASED;
+}
+
+
+uint8_t releaseFrame(uint8_t callerId, uint32_t frameStartAddress)
+{
+	static uint8_t countErrorCalls = 0;
+	
+	if(frameStartAddress < FBGlobalStart)
+		return 2;
+
+
+	uint8_t i;
+
+	i = 0;
+	while((i < MAXFRAMES) && (frame[i].StartAddress != frameStartAddress))
+		i++;
+
+	if((i < MAXFRAMES) && (frame[i].StartAddress == frameStartAddress))
+	{
+		if(frame[i].caller == callerId)
+		{
+			frame[i].status = RELEASED;
+			return 1;
+		}
+		else
+			countErrorCalls++;
+	}
+	return 0;
+}
+
+
+uint16_t blockedFramesCount(void)
+{
+	uint16_t count = MAXFRAMES;
+	
+	for(int i = 0;i<MAXFRAMES;i++)
+		if(frame[i].status == BLOCKED)
+			count--;
+		
+	return count;
+}
+
+
+uint8_t getFrameCount(uint8_t frameId)
+{
+	if(frameId < (MAXFRAMECOUNTER - 3))
+		return frameCounter[frameId];
+	else
+		return frameCounter[MAXFRAMECOUNTER - 2];
+}
+
+
+void housekeepingFrame(void)
+{
+	static uint8_t countLogClear = 0;
+	
+	if(DMA2D_at_work != 255)
+		return;
+
+	/* new for debug hw 151202 */
+	for(int i=1;i<MAXFRAMECOUNTER;i++)
+	{
+		frameCounter[i] = 0;
+	}
+	for(int i=1;i<MAXFRAMES;i++)
+	{
+		if(frame[i].status == BLOCKED)
+		{
+			if(frame[i].caller < (MAXFRAMECOUNTER - 2))
+				frameCounter[frame[i].caller]++;
+			else
+				frameCounter[MAXFRAMECOUNTER-3]++;
+		}
+		else
+		if(frame[i].status == RELEASED)
+			frameCounter[MAXFRAMECOUNTER-2]++;
+		else
+			frameCounter[MAXFRAMECOUNTER-1]++;
+	}
+	
+	
+	uint8_t i;
+
+	i = 0;
+	while((i < MAXFRAMES) && ((frame[i].status != RELEASED) || (frame[i].StartAddress == GFX_get_pActualFrameTop()) || (frame[i].StartAddress == GFX_get_pActualFrameBottom())))
+		i++;
+
+	if((i < MAXFRAMES) && (frame[i].status == RELEASED))
+	{
+		if(frame[i].caller == 15)
+			countLogClear++;
+		GFX_clear_frame_dma2d(i);
+	}
+}
+
+
+static void GFX_Dma2d_TransferComplete(DMA2D_HandleTypeDef* Dma2dHandle)
+{
+	if(DMA2D_at_work < MAXFRAMES)
+		frame[DMA2D_at_work].status = CLEAR;
+
+	DMA2D_at_work = 255;
+}
+
+
+static void GFX_Dma2d_TransferError(DMA2D_HandleTypeDef* Dma2dHandle)
+{
+
+}
+
+static void GFX_Error_Handler(void)
+{
+    /* Turn LED3 on */
+//    BSP_LED_On(LED3);
+    while(1)
+    {
+    }
+}
+
+void write_content_simple(GFX_DrawCfgScreen *tMscreen, uint16_t XleftGimpStyle, uint16_t XrightGimpStyle, uint16_t YtopGimpStyle, const tFont *Font, const char *text, uint8_t color)
+{
+	GFX_DrawCfgWindow	hgfx;
+
+	if(XrightGimpStyle > 799)
+		XrightGimpStyle = 799;
+	if(XleftGimpStyle >= XrightGimpStyle)
+		XleftGimpStyle = 0;
+	if(YtopGimpStyle > 479)
+		YtopGimpStyle = 479;
+	hgfx.Image = tMscreen;
+	hgfx.WindowNumberOfTextLines = 1;
+	hgfx.WindowLineSpacing = 0;
+	hgfx.WindowTab = 0;
+	hgfx.WindowX0 = XleftGimpStyle;
+	hgfx.WindowX1 = XrightGimpStyle;
+	hgfx.WindowY1 = 479 - YtopGimpStyle;
+	if(hgfx.WindowY1 < Font->height)
+		hgfx.WindowY0 = 0;
+	else
+		hgfx.WindowY0 = hgfx.WindowY1 - Font->height;
+
+	GFX_write_string_color(Font, &hgfx, text, 0, color);
+}
+
+
+void gfx_write_topline_simple(GFX_DrawCfgScreen *tMscreen, const char *text, uint8_t color)
+{
+	GFX_DrawCfgWindow	hgfx;
+	const tFont *Font = &FontT48;
+	
+	hgfx.Image = tMscreen;
+	hgfx.WindowNumberOfTextLines = 1;
+	hgfx.WindowLineSpacing = 0;
+	hgfx.WindowTab = 0;
+	hgfx.WindowX0 = 20;
+	hgfx.WindowX1 = 779;
+	hgfx.WindowY1 = 479;
+	hgfx.WindowY0 = hgfx.WindowY1 - Font->height;
+	
+	GFX_write_label(Font, &hgfx, text, color);
+	
+}
+
+
+void gfx_write_page_number(GFX_DrawCfgScreen *tMscreen, uint8_t page, uint8_t total, uint8_t color)
+{
+	GFX_DrawCfgWindow	hgfx;
+	const tFont *Font = &FontT48;
+	char text[7];
+	uint8_t i, secondDigitPage, secondDigitTotal;
+	
+	hgfx.Image = tMscreen;
+	hgfx.WindowNumberOfTextLines = 1;
+	hgfx.WindowLineSpacing = 0;
+	hgfx.WindowTab = 0;
+	hgfx.WindowX1 = 779;
+	hgfx.WindowX0 = hgfx.WindowX1 - (25*5);
+	hgfx.WindowY1 = 479;
+	hgfx.WindowY0 = hgfx.WindowY1 - Font->height;
+	
+	if(page > 99)
+		page = 99;
+	if(total > 99)
+		total = 99;
+	
+	i = 0;
+	text[i++] = '\002';
+	
+	secondDigitPage = page / 10;
+	page -= secondDigitPage * 10;
+
+	secondDigitTotal = total / 10;
+	total -= secondDigitTotal * 10;
+	
+	if(secondDigitPage)
+		text[i++] = '0' + secondDigitPage;
+	text[i++] = '0' + page;
+
+	text[i++] = '/';
+
+	if(secondDigitTotal)
+		text[i++] = '0' + secondDigitTotal;
+	text[i++] = '0' + total;
+
+	text[i] = 0;
+	
+	GFX_clear_window_immediately(&hgfx);
+	GFX_write_label(Font, &hgfx, text, color);
+}
+
+
+uint8_t gfx_number_to_string(uint8_t max_digits, _Bool fill, char *pText, uint32_t input)
+{
+	uint8_t digits[10];
+	uint32_t number, divider;
+	int first;
+	uint8_t out;
+	
+	number = input;
+	first = 0;
+	divider = 1000000000;
+	for(int i=9;i>=0;i--)
+	{
+		digits[i] = (uint8_t)(number / divider);
+		number -= digits[i] * divider;
+		divider /= 10;
+		if((first == 0) && (digits[i] != 0))
+			first = i;
+	}
+	
+	if((first + 1) > max_digits)
+	{
+		for(int i = 0; i<max_digits; i++)
+			pText[i] = '9';
+		out = max_digits;
+	}
+	else if(fill)
+	{
+		int i = 0;
+		for(int k = max_digits; k>0; k--)
+			pText[i++] = digits[k -1] +  '0';
+		out = max_digits;
+	}
+	else
+	{
+		int i = 0;
+		for(int k = first; k>=0; k--)
+			pText[i++] = digits[k] +  '0';
+		out = i;
+	}
+	
+	return out;
+}
+
+
+	/* output is
+	 * 0->
+	 *    |
+	 *    v
+	 *
+	 * input is
+	 * 
+	 *   -> 
+	 * A
+	 * |
+	 * 0
+	 */
+void GFX_screenshot(void)
+{
+	uint32_t pSource = GFX_get_pActualFrameTop();
+	uint32_t pSourceBottom =GFX_get_pActualFrameBottom();
+	uint32_t pBottomNew = getFrame(99);
+	uint32_t pDestination = GFX_doubleBufferOne();
+	uint32_t sourceNow;
+
+	
+	uint32_t 	bot_leftStart = FrameHandler.actualBottom.leftStart; 			// x0 z.B. 0
+	uint32_t 	bot_bottomStart = FrameHandler.actualBottom.bottomStart; 	// y0 z.B. 25
+	uint32_t  bot_width = FrameHandler.actualBottom.width;							// 800
+	uint32_t  bot_height = FrameHandler.actualBottom.height;						// 390
+
+	struct split
+	{
+		uint8_t blue;
+		uint8_t green;
+		uint8_t red;
+		uint8_t alpha;
+	};
+
+	union inout_u
+	{
+		uint32_t in;
+		struct split out;
+	};
+	
+	union inout_u value;
+
+/* test	
+ uint32_t pSourceTemp = pSource + (2*479);
+	for (int j = 0xFFFF; j > 0x00FF; j -= 0x0100)
+	{
+		*(__IO uint16_t*)pSourceTemp = j;
+		pSourceTemp += 480*2;
+	}
+*/
+	// Top Layer
+	const unsigned width = 800, height = 480;
+	const uint32_t heightX2 = height*2;
+	
+	for(unsigned y = 0; y < height; y++)
+	{
+		sourceNow = pSource + 2 * ((height - 1) - y);
+		for(unsigned x = 0; x < width; x++)
+		{
+//			sourceNow += 2 * height * x  + 2 * (height - 1 - y);
+			value.in = ColorLUT[*(__IO uint8_t*)(sourceNow)];
+			value.out.alpha = *(__IO uint8_t*)(sourceNow + 1);
+			
+			*(__IO uint8_t*)(pDestination++) = value.out.red;
+			*(__IO uint8_t*)(pDestination++) = value.out.green;
+			*(__IO uint8_t*)(pDestination++) = value.out.blue;
+			*(__IO uint8_t*)(pDestination++) = value.out.alpha;
+			sourceNow += heightX2;
+		}
+	}
+	
+	// Bottom Layer
+	// build newBottom
+	pSource = pSourceBottom;
+	for(unsigned x = bot_leftStart; x < bot_leftStart+bot_width; x++)
+	{
+		for(unsigned y = bot_bottomStart; y < bot_bottomStart+bot_height; y++)
+		{
+				pDestination = pBottomNew + (2 * y);
+				pDestination += heightX2 * x;
+				*(__IO uint16_t*)(pDestination) = *(__IO uint16_t*)(pSource);
+				pSource += 2;
+		}
+	}		
+	
+	// output Bottom Layer
+	pSource = pBottomNew;
+	pDestination = GFX_doubleBufferTwo();
+
+	for(unsigned y = 0; y < height; y++)
+	{
+		sourceNow = pSource + 2 * ((height - 1) - y);
+		for(unsigned x = 0; x < width; x++)
+		{
+//		sourceNow =  pSource + 2 * height * x  + 2 * (height - 1 - y);
+			value.in = ColorLUT[*(__IO uint8_t*)(sourceNow)];
+			value.out.alpha = *(__IO uint8_t*)(sourceNow + 1);
+			
+			*(__IO uint8_t*)(pDestination++) = value.out.red;
+			*(__IO uint8_t*)(pDestination++) = value.out.green;
+			*(__IO uint8_t*)(pDestination++) = value.out.blue;
+			*(__IO uint8_t*)(pDestination++) = value.out.alpha;
+			sourceNow += heightX2;
+		}
+	}
+	releaseFrame(99,pBottomNew);
+/*
+	// das kommt dazu!
+	unsigned yEnd = 480 - FrameHandler.actualBottom.bottomStart;
+	unsigned yStart = yEnd - FrameHandler.actualBottom.height;
+	
+	if(yStart > 0)
+	{
+		for(unsigned y = 0; y < yStart; y++)
+		for(unsigned x = 0; x < width; x++)
+		{
+			*(__IO uint8_t*)(pDestination++) = 0;
+			*(__IO uint8_t*)(pDestination++) = 0;
+			*(__IO uint8_t*)(pDestination++) = 0;
+			*(__IO uint8_t*)(pDestination++) = 0;
+		}
+	}
+	for(unsigned y = yStart; y < yEnd; y++)
+	for(unsigned x = 0; x < width; x++)
+	{
+		sourceNow =  pSource + 2 * height * x  + 2 * (height - 1 - y);
+		value.in = ColorLUT[*(__IO uint8_t*)(sourceNow)];
+		value.out.alpha = *(__IO uint8_t*)(sourceNow + 1);
+		
+		*(__IO uint8_t*)(pDestination++) = value.out.red;
+		*(__IO uint8_t*)(pDestination++) = value.out.green;
+		*(__IO uint8_t*)(pDestination++) = value.out.blue;
+		*(__IO uint8_t*)(pDestination++) = value.out.alpha;
+	}
+	if(yEnd < 480)
+	{
+		for(unsigned y = yEnd; y < 480; y++)
+		for(unsigned x = 0; x < width; x++)
+		{
+			*(__IO uint8_t*)(pDestination++) = 0;
+			*(__IO uint8_t*)(pDestination++) = 0;
+			*(__IO uint8_t*)(pDestination++) = 0;
+			*(__IO uint8_t*)(pDestination++) = 0;
+		}
+	}
+*/	
+}