diff --git a/touchscreengames/Core/Inc/ILI9341_GFX.h b/touchscreengames/Core/Inc/ILI9341_GFX.h new file mode 100644 index 0000000..42d4933 --- /dev/null +++ b/touchscreengames/Core/Inc/ILI9341_GFX.h @@ -0,0 +1,18 @@ +#ifndef ILI9341_GFX_H +#define ILI9341_GFX_H + +#include "stm32f4xx_hal.h" +#include "fonts.h" + +#define HORIZONTAL_IMAGE 0 +#define VERTICAL_IMAGE 1 + +void ILI9341_DrawHollowCircle(uint16_t X, uint16_t Y, uint16_t radius, uint16_t color); +void ILI9341_DrawFilledCircle(uint16_t X, uint16_t Y, uint16_t radius, uint16_t color); +void ILI9341_DrawHollowRectangleCoord(uint16_t X0, uint16_t Y0, uint16_t X1, uint16_t Y1, uint16_t color); +void ILI9341_DrawFilledRectangleCoord(uint16_t X0, uint16_t Y0, uint16_t X1, uint16_t Y1, uint16_t color); +void ILI9341_DrawChar(char ch, const uint8_t font[], uint16_t X, uint16_t Y, uint16_t color, uint16_t bgcolor); +void ILI9341_DrawText(const char* str, const uint8_t font[], uint16_t X, uint16_t Y, uint16_t color, uint16_t bgcolor); +void ILI9341_DrawImage(const uint8_t* image, uint8_t orientation); + +#endif diff --git a/touchscreengames/Core/Inc/ILI9341_STM32_Driver.h b/touchscreengames/Core/Inc/ILI9341_STM32_Driver.h new file mode 100644 index 0000000..ca7bee9 --- /dev/null +++ b/touchscreengames/Core/Inc/ILI9341_STM32_Driver.h @@ -0,0 +1,61 @@ +#ifndef ILI9341_STM32_DRIVER_H +#define ILI9341_STM32_DRIVER_H + +#include "stm32f4xx_hal.h" + +extern SPI_HandleTypeDef hspi1; + +#define ILI9341_SCREEN_HEIGHT 240 +#define ILI9341_SCREEN_WIDTH 320 + +/* PIN Configuration */ +#define HSPI_INSTANCE &hspi1 //&hspi1 +#define LCD_CS_PORT GPIOA +#define LCD_CS_PIN GPIO_PIN_4 +#define LCD_DC_PORT GPIOB +#define LCD_DC_PIN GPIO_PIN_2 +#define LCD_RST_PORT GPIOA +#define LCD_RST_PIN GPIO_PIN_10 + +#define BURST_MAX_SIZE 500 +#define BLACK 0x0000 +#define NAVY 0x000F +#define DARKGREEN 0x03E0 +#define DARKCYAN 0x03EF +#define MAROON 0x7800 +#define PURPLE 0x780F +#define OLIVE 0x7BE0 +#define LIGHTGREY 0xC618 +#define DARKGREY 0x7BEF +#define BLUE 0x001F +#define GREEN 0x07E0 +#define CYAN 0x07FF +#define RED 0xF800 +#define MAGENTA 0xF81F +#define YELLOW 0xFFE0 +#define WHITE 0xFFFF +#define ORANGE 0xFD20 +#define GREENYELLOW 0xAFE5 +#define PINK 0xF81F + +#define SCREEN_VERTICAL_1 0 +#define SCREEN_HORIZONTAL_1 1 +#define SCREEN_VERTICAL_2 2 +#define SCREEN_HORIZONTAL_2 3 + +void ILI9341_WriteCommand(uint8_t cmd); +void ILI9341_WriteData(uint8_t data); +void ILI9341_WriteBuffer(uint8_t *buffer, uint16_t len); +void ILI9341_Reset(void); +void ILI9341_Enable(void); +void ILI9341_Init(void); +void ILI9341_SetRotation(uint8_t rotation); +void ILI9341_SetAddress(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); +void ILI9341_DrawColor(uint16_t color); +void ILI9341_DrawColorBurst(uint16_t color, uint32_t size); +void ILI9341_FillScreen(uint16_t color); +void ILI9341_DrawPixel(uint16_t x,uint16_t y,uint16_t color); +void ILI9341_DrawRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color); +void ILI9341_DrawHLine(uint16_t x, uint16_t y, uint16_t width, uint16_t color); +void ILI9341_DrawVLine(uint16_t x, uint16_t y, uint16_t height, uint16_t color); +#endif diff --git a/touchscreengames/Core/Inc/fonts.h b/touchscreengames/Core/Inc/fonts.h new file mode 100644 index 0000000..dabb49d --- /dev/null +++ b/touchscreengames/Core/Inc/fonts.h @@ -0,0 +1,16 @@ +#ifndef __FONTS_H__ +#define __FONTS_H__ + +#include + +#define FONT1 Arial_Narrow8x12 +#define FONT2 Arial_Narrow10x13 +#define FONT3 Arial_Narrow12x16 +#define FONT4 Arial_Narrow15x19 + +extern const uint8_t Arial_Narrow8x12[]; +extern const uint8_t Arial_Narrow10x13[]; +extern const uint8_t Arial_Narrow12x16[]; +extern const uint8_t Arial_Narrow15x19[]; + +#endif // __FONTS_H__ diff --git a/touchscreengames/Core/Inc/main.h b/touchscreengames/Core/Inc/main.h new file mode 100644 index 0000000..3ff6b4c --- /dev/null +++ b/touchscreengames/Core/Inc/main.h @@ -0,0 +1,79 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.h + * @brief : Header for main.c file. + * This file contains the common defines of the application. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_H +#define __MAIN_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + +/* Exported functions prototypes ---------------------------------------------*/ +void Error_Handler(void); + +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +/* Private defines -----------------------------------------------------------*/ +#define LED_BLUE_Pin GPIO_PIN_13 +#define LED_BLUE_GPIO_Port GPIOC +#define DISPLAY_CS_Pin GPIO_PIN_4 +#define DISPLAY_CS_GPIO_Port GPIOA +#define DISPLAY_DC_Pin GPIO_PIN_2 +#define DISPLAY_DC_GPIO_Port GPIOB +#define DISPLAY_RES_Pin GPIO_PIN_10 +#define DISPLAY_RES_GPIO_Port GPIOA + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __MAIN_H */ diff --git a/touchscreengames/Core/Inc/stm32f4xx_it.h b/touchscreengames/Core/Inc/stm32f4xx_it.h new file mode 100644 index 0000000..8877fbf --- /dev/null +++ b/touchscreengames/Core/Inc/stm32f4xx_it.h @@ -0,0 +1,68 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f4xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_IT_H +#define __STM32F4xx_IT_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Exported types ------------------------------------------------------------*/ +/* USER CODE BEGIN ET */ + +/* USER CODE END ET */ + +/* Exported constants --------------------------------------------------------*/ +/* USER CODE BEGIN EC */ + +/* USER CODE END EC */ + +/* Exported macro ------------------------------------------------------------*/ +/* USER CODE BEGIN EM */ + +/* USER CODE END EM */ + +/* Exported functions prototypes ---------------------------------------------*/ +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void DebugMon_Handler(void); +void TIM3_IRQHandler(void); +void SPI1_IRQHandler(void); +void DMA2_Stream0_IRQHandler(void); +void DMA2_Stream3_IRQHandler(void); +void USART6_IRQHandler(void); +/* USER CODE BEGIN EFP */ + +/* USER CODE END EFP */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_IT_H */ diff --git a/touchscreengames/Core/Src/ILI9341_GFX.c b/touchscreengames/Core/Src/ILI9341_GFX.c new file mode 100644 index 0000000..7cdc2ce --- /dev/null +++ b/touchscreengames/Core/Src/ILI9341_GFX.c @@ -0,0 +1,261 @@ +#include "ILI9341_STM32_Driver.h" +#include "ILI9341_GFX.h" + +/* imprecise small delay */ +__STATIC_INLINE void DelayUs(volatile uint32_t us) +{ + us *= (SystemCoreClock / 1000000); + while (us--); +} + +void ILI9341_DrawHollowCircle(uint16_t X, uint16_t Y, uint16_t radius, uint16_t color) +{ + int x = radius-1; + int y = 0; + int dx = 1; + int dy = 1; + int err = dx - (radius << 1); + + while (x >= y) + { + ILI9341_DrawPixel(X + x, Y + y, color); + ILI9341_DrawPixel(X + y, Y + x, color); + ILI9341_DrawPixel(X - y, Y + x, color); + ILI9341_DrawPixel(X - x, Y + y, color); + ILI9341_DrawPixel(X - x, Y - y, color); + ILI9341_DrawPixel(X - y, Y - x, color); + ILI9341_DrawPixel(X + y, Y - x, color); + ILI9341_DrawPixel(X + x, Y - y, color); + + if (err <= 0) + { + y++; + err += dy; + dy += 2; + } + + if (err > 0) + { + x--; + dx += 2; + err += (-radius << 1) + dx; + } + } +} + +void ILI9341_DrawFilledCircle(uint16_t X, uint16_t Y, uint16_t radius, uint16_t color) +{ + + int x = radius; + int y = 0; + int xChange = 1 - (radius << 1); + int yChange = 0; + int radiusError = 0; + + while (x >= y) + { + for (int i = X - x; i <= X + x; i++) + { + ILI9341_DrawPixel(i, Y + y,color); + ILI9341_DrawPixel(i, Y - y,color); + } + + for (int i = X - y; i <= X + y; i++) + { + ILI9341_DrawPixel(i, Y + x,color); + ILI9341_DrawPixel(i, Y - x,color); + } + + y++; + radiusError += yChange; + yChange += 2; + + if (((radiusError << 1) + xChange) > 0) + { + x--; + radiusError += xChange; + xChange += 2; + } + } +} + +void ILI9341_DrawHollowRectangleCoord(uint16_t X0, uint16_t Y0, uint16_t X1, uint16_t Y1, uint16_t color) +{ + uint16_t xLen = 0; + uint16_t yLen = 0; + uint8_t negX = 0; + uint8_t negY = 0; + float negCalc = 0; + + negCalc = X1 - X0; + if(negCalc < 0) negX = 1; + negCalc = 0; + + negCalc = Y1 - Y0; + if(negCalc < 0) negY = 1; + + //DRAW HORIZONTAL! + if(!negX) + { + xLen = X1 - X0; + } + else + { + xLen = X0 - X1; + } + ILI9341_DrawHLine(X0, Y0, xLen, color); + ILI9341_DrawHLine(X0, Y1, xLen, color); + + //DRAW VERTICAL! + if(!negY) + { + yLen = Y1 - Y0; + } + else + { + yLen = Y0 - Y1; + } + + ILI9341_DrawVLine(X0, Y0, yLen, color); + ILI9341_DrawVLine(X1, Y0, yLen, color); + + if((xLen > 0)||(yLen > 0)) + { + ILI9341_DrawPixel(X1, Y1, color); + } +} + +void ILI9341_DrawFilledRectangleCoord(uint16_t X0, uint16_t Y0, uint16_t X1, uint16_t Y1, uint16_t color) +{ + uint16_t xLen = 0; + uint16_t yLen = 0; + uint8_t negX = 0; + uint8_t negY = 0; + int32_t negCalc = 0; + uint16_t X0True = 0; + uint16_t Y0True = 0; + + negCalc = X1 - X0; + if(negCalc < 0) negX = 1; + negCalc = 0; + + negCalc = Y1 - Y0; + if(negCalc < 0) negY = 1; + + if(!negX) + { + xLen = X1 - X0; + X0True = X0; + } + else + { + xLen = X0 - X1; + X0True = X1; + } + + if(!negY) + { + yLen = Y1 - Y0; + Y0True = Y0; + } + else + { + yLen = Y0 - Y1; + Y0True = Y1; + } + + ILI9341_DrawRectangle(X0True, Y0True, xLen, yLen, color); +} + +void ILI9341_DrawChar(char ch, const uint8_t font[], uint16_t X, uint16_t Y, uint16_t color, uint16_t bgcolor) +{ + if ((ch < 31) || (ch > 127)) return; + + uint8_t fOffset, fWidth, fHeight, fBPL; + uint8_t *tempChar; + + fOffset = font[0]; + fWidth = font[1]; + fHeight = font[2]; + fBPL = font[3]; + + tempChar = (uint8_t*)&font[((ch - 0x20) * fOffset) + 4]; /* Current Character = Meta + (Character Index * Offset) */ + + /* Clear background first */ + ILI9341_DrawRectangle(X, Y, fWidth, fHeight, bgcolor); + + for (int j=0; j < fHeight; j++) + { + for (int i=0; i < fWidth; i++) + { + uint8_t z = tempChar[fBPL * i + ((j & 0xF8) >> 3) + 1]; /* (j & 0xF8) >> 3, increase one by 8-bits */ + uint8_t b = 1 << (j & 0x07); + if (( z & b ) != 0x00) + { + ILI9341_DrawPixel(X+i, Y+j, color); + } + } + } +} + +void ILI9341_DrawText(const char* str, const uint8_t font[], uint16_t X, uint16_t Y, uint16_t color, uint16_t bgcolor) +{ + uint8_t charWidth; /* Width of character */ + uint8_t fOffset = font[0]; /* Offset of character */ + uint8_t fWidth = font[1]; /* Width of font */ + + while (*str) + { + ILI9341_DrawChar(*str, font, X, Y, color, bgcolor); + + /* Check character width and calculate proper position */ + uint8_t *tempChar = (uint8_t*)&font[((*str - 0x20) * fOffset) + 4]; + charWidth = tempChar[0]; + + if(charWidth + 2 < fWidth) + { + /* If character width is smaller than font width */ + X += (charWidth + 2); + } + else + { + X += fWidth; + } + + str++; + } +} + +void ILI9341_DrawImage(const uint8_t* image, uint8_t orientation) +{ + if(orientation == SCREEN_HORIZONTAL_1) + { + ILI9341_SetRotation(SCREEN_HORIZONTAL_1); + ILI9341_SetAddress(0,0,ILI9341_SCREEN_WIDTH,ILI9341_SCREEN_HEIGHT); + } + else if(orientation == SCREEN_HORIZONTAL_2) + { + ILI9341_SetRotation(SCREEN_HORIZONTAL_2); + ILI9341_SetAddress(0,0,ILI9341_SCREEN_WIDTH,ILI9341_SCREEN_HEIGHT); + } + else if(orientation == SCREEN_VERTICAL_2) + { + ILI9341_SetRotation(SCREEN_VERTICAL_2); + ILI9341_SetAddress(0,0,ILI9341_SCREEN_HEIGHT,ILI9341_SCREEN_WIDTH); + } + else if(orientation == SCREEN_VERTICAL_1) + { + ILI9341_SetRotation(SCREEN_VERTICAL_1); + ILI9341_SetAddress(0,0,ILI9341_SCREEN_HEIGHT,ILI9341_SCREEN_WIDTH); + } + + uint32_t counter = 0; + for(uint32_t i = 0; i < ILI9341_SCREEN_WIDTH*ILI9341_SCREEN_HEIGHT*2/BURST_MAX_SIZE; i++) + { + ILI9341_WriteBuffer((uint8_t*)(image + counter), BURST_MAX_SIZE); + counter += BURST_MAX_SIZE; + + /* DMA Tx is too fast, It needs some delay */ + DelayUs(1); + } +} diff --git a/touchscreengames/Core/Src/ILI9341_STM32_Driver.c b/touchscreengames/Core/Src/ILI9341_STM32_Driver.c new file mode 100644 index 0000000..6136747 --- /dev/null +++ b/touchscreengames/Core/Src/ILI9341_STM32_Driver.c @@ -0,0 +1,371 @@ +#include "ILI9341_STM32_Driver.h" + +volatile uint16_t LCD_HEIGHT = ILI9341_SCREEN_HEIGHT; +volatile uint16_t LCD_WIDTH = ILI9341_SCREEN_WIDTH; + +void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) +{ + /* Deselect when Tx Complete */ + if(hspi == HSPI_INSTANCE) + { + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); + } +} + +static void ILI9341_SPI_Tx(uint8_t data) +{ + while(!__HAL_SPI_GET_FLAG(HSPI_INSTANCE, SPI_FLAG_TXE)); + HAL_SPI_Transmit_DMA(HSPI_INSTANCE, &data, 1); + //HAL_SPI_Transmit(HSPI_INSTANCE, &data, 1, 10); +} + +static void ILI9341_SPI_TxBuffer(uint8_t *buffer, uint16_t len) +{ + while(!__HAL_SPI_GET_FLAG(HSPI_INSTANCE, SPI_FLAG_TXE)); + HAL_SPI_Transmit_DMA(HSPI_INSTANCE, buffer, len); + //HAL_SPI_Transmit(HSPI_INSTANCE, buffer, len, 10); +} + +void ILI9341_WriteCommand(uint8_t cmd) +{ + HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_RESET); //command + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); //select + ILI9341_SPI_Tx(cmd); + //HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); //deselect +} + +void ILI9341_WriteData(uint8_t data) +{ + HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); //data + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); //select + ILI9341_SPI_Tx(data); + //HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); //deselect +} + +void ILI9341_WriteBuffer(uint8_t *buffer, uint16_t len) +{ + HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); //data + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); //select + ILI9341_SPI_TxBuffer(buffer, len); + //HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); //deselect +} + +void ILI9341_SetAddress(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) +{ + uint8_t buffer[4]; + buffer[0] = x1 >> 8; + buffer[1] = x1; + buffer[2] = x2 >> 8; + buffer[3] = x2; + + ILI9341_WriteCommand(0x2A); + ILI9341_WriteBuffer(buffer, sizeof(buffer)); + + buffer[0] = y1 >> 8; + buffer[1] = y1; + buffer[2] = y2 >> 8; + buffer[3] = y2; + + ILI9341_WriteCommand(0x2B); + ILI9341_WriteBuffer(buffer, sizeof(buffer)); + + ILI9341_WriteCommand(0x2C); +} + +void ILI9341_Reset(void) +{ + HAL_GPIO_WritePin(LCD_RST_PORT, LCD_RST_PIN, GPIO_PIN_RESET); //Disable + HAL_Delay(10); + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); //Select + HAL_Delay(10); + HAL_GPIO_WritePin(LCD_RST_PORT, LCD_RST_PIN, GPIO_PIN_SET); //Enable + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); //Deselect +} + +void ILI9341_Enable(void) +{ + HAL_GPIO_WritePin(LCD_RST_PORT, LCD_RST_PIN, GPIO_PIN_SET); //Enable +} + +void ILI9341_Init(void) +{ + ILI9341_Enable(); + ILI9341_Reset(); + + //SOFTWARE RESET + ILI9341_WriteCommand(0x01); + HAL_Delay(10); + + //POWER CONTROL A + ILI9341_WriteCommand(0xCB); + ILI9341_WriteData(0x39); + ILI9341_WriteData(0x2C); + ILI9341_WriteData(0x00); + ILI9341_WriteData(0x34); + ILI9341_WriteData(0x02); + + //POWER CONTROL B + ILI9341_WriteCommand(0xCF); + ILI9341_WriteData(0x00); + ILI9341_WriteData(0xC1); + ILI9341_WriteData(0x30); + + //DRIVER TIMING CONTROL A + ILI9341_WriteCommand(0xE8); + ILI9341_WriteData(0x85); + ILI9341_WriteData(0x00); + ILI9341_WriteData(0x78); + + //DRIVER TIMING CONTROL B + ILI9341_WriteCommand(0xEA); + ILI9341_WriteData(0x00); + ILI9341_WriteData(0x00); + + //POWER ON SEQUENCE CONTROL + ILI9341_WriteCommand(0xED); + ILI9341_WriteData(0x64); + ILI9341_WriteData(0x03); + ILI9341_WriteData(0x12); + ILI9341_WriteData(0x81); + + //PUMP RATIO CONTROL + ILI9341_WriteCommand(0xF7); + ILI9341_WriteData(0x20); + + //POWER CONTROL,VRH[5:0] + ILI9341_WriteCommand(0xC0); + ILI9341_WriteData(0x23); + + //POWER CONTROL,SAP[2:0];BT[3:0] + ILI9341_WriteCommand(0xC1); + ILI9341_WriteData(0x10); + + //VCM CONTROL + ILI9341_WriteCommand(0xC5); + ILI9341_WriteData(0x3E); + ILI9341_WriteData(0x28); + + //VCM CONTROL 2 + ILI9341_WriteCommand(0xC7); + ILI9341_WriteData(0x86); + + //MEMORY ACCESS CONTROL + ILI9341_WriteCommand(0x36); + ILI9341_WriteData(0x48); + + //PIXEL FORMAT + ILI9341_WriteCommand(0x3A); + ILI9341_WriteData(0x55); + + //FRAME RATIO CONTROL, STANDARD RGB COLOR + ILI9341_WriteCommand(0xB1); + ILI9341_WriteData(0x00); + ILI9341_WriteData(0x18); + + //DISPLAY FUNCTION CONTROL + ILI9341_WriteCommand(0xB6); + ILI9341_WriteData(0x08); + ILI9341_WriteData(0x82); + ILI9341_WriteData(0x27); + + //3GAMMA FUNCTION DISABLE + ILI9341_WriteCommand(0xF2); + ILI9341_WriteData(0x00); + + //GAMMA CURVE SELECTED + ILI9341_WriteCommand(0x26); + ILI9341_WriteData(0x01); + + //POSITIVE GAMMA CORRECTION + ILI9341_WriteCommand(0xE0); + ILI9341_WriteData(0x0F); + ILI9341_WriteData(0x31); + ILI9341_WriteData(0x2B); + ILI9341_WriteData(0x0C); + ILI9341_WriteData(0x0E); + ILI9341_WriteData(0x08); + ILI9341_WriteData(0x4E); + ILI9341_WriteData(0xF1); + ILI9341_WriteData(0x37); + ILI9341_WriteData(0x07); + ILI9341_WriteData(0x10); + ILI9341_WriteData(0x03); + ILI9341_WriteData(0x0E); + ILI9341_WriteData(0x09); + ILI9341_WriteData(0x00); + + //NEGATIVE GAMMA CORRECTION + ILI9341_WriteCommand(0xE1); + ILI9341_WriteData(0x00); + ILI9341_WriteData(0x0E); + ILI9341_WriteData(0x14); + ILI9341_WriteData(0x03); + ILI9341_WriteData(0x11); + ILI9341_WriteData(0x07); + ILI9341_WriteData(0x31); + ILI9341_WriteData(0xC1); + ILI9341_WriteData(0x48); + ILI9341_WriteData(0x08); + ILI9341_WriteData(0x0F); + ILI9341_WriteData(0x0C); + ILI9341_WriteData(0x31); + ILI9341_WriteData(0x36); + ILI9341_WriteData(0x0F); + + //EXIT SLEEP + ILI9341_WriteCommand(0x11); + HAL_Delay(100); + + //TURN ON DISPLAY + ILI9341_WriteCommand(0x29); + + //STARTING ROTATION + ILI9341_SetRotation(SCREEN_VERTICAL_1); +} + +void ILI9341_SetRotation(uint8_t rotation) +{ + ILI9341_WriteCommand(0x36); + HAL_Delay(1); + + switch(rotation) + { + case SCREEN_VERTICAL_1: + ILI9341_WriteData(0x40|0x08); + LCD_WIDTH = 240; + LCD_HEIGHT = 320; + break; + case SCREEN_HORIZONTAL_1: + ILI9341_WriteData(0x20|0x08); + LCD_WIDTH = 320; + LCD_HEIGHT = 240; + break; + case SCREEN_VERTICAL_2: + ILI9341_WriteData(0x80|0x08); + LCD_WIDTH = 240; + LCD_HEIGHT = 320; + break; + case SCREEN_HORIZONTAL_2: + ILI9341_WriteData(0x40|0x80|0x20|0x08); + LCD_WIDTH = 320; + LCD_HEIGHT = 240; + break; + default: + break; + } +} + +void ILI9341_DrawColor(uint16_t color) +{ + uint8_t buffer[2] = {color>>8, color}; + ILI9341_WriteBuffer(buffer, sizeof(buffer)); +} + +void ILI9341_DrawColorBurst(uint16_t color, uint32_t size) +{ + uint32_t BufferSize = 0; + + if((size*2) < BURST_MAX_SIZE) + { + BufferSize = size; + } + else + { + BufferSize = BURST_MAX_SIZE; + } + + HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); + + uint8_t chifted = color>>8; + uint8_t BurstBuffer[BufferSize]; + + for(uint32_t j = 0; j < BufferSize; j+=2) + { + BurstBuffer[j] = chifted; + BurstBuffer[j+1] = color; + } + + uint32_t SendingSize = size * 2; + uint32_t SendingInBlock = SendingSize / BufferSize; + uint32_t RemainderFromBlock = SendingSize % BufferSize; + + if(SendingInBlock != 0) + { + for(uint32_t j = 0; j < (SendingInBlock); j++) + { + HAL_SPI_Transmit(HSPI_INSTANCE, BurstBuffer, BufferSize, 10); + } + } + + HAL_SPI_Transmit(HSPI_INSTANCE, BurstBuffer, RemainderFromBlock, 10); + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); +} + +void ILI9341_FillScreen(uint16_t color) +{ + ILI9341_SetAddress(0, 0, LCD_WIDTH, LCD_HEIGHT); + ILI9341_DrawColorBurst(color, LCD_WIDTH*LCD_HEIGHT); +} + +void ILI9341_DrawPixel(uint16_t x,uint16_t y,uint16_t color) +{ + if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return; + + uint8_t bufferX[4] = {x>>8, x, (x+1)>>8, (x+1)}; + uint8_t bufferY[4] = {y>>8, y, (y+1)>>8, (y+1)}; + uint8_t bufferC[2] = {color>>8, color}; + + ILI9341_WriteCommand(0x2A); //ADDRESS + ILI9341_WriteBuffer(bufferX, sizeof(bufferX)); //XDATA + + ILI9341_WriteCommand(0x2B); //ADDRESS + ILI9341_WriteBuffer(bufferY, sizeof(bufferY)); //YDATA + + ILI9341_WriteCommand(0x2C); //ADDRESS + ILI9341_WriteBuffer(bufferC, sizeof(bufferC)); //COLOR +} + +void ILI9341_DrawRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) +{ + if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return; + + if((x+width-1)>=LCD_WIDTH) + { + width=LCD_WIDTH-x; + } + + if((y+height-1)>=LCD_HEIGHT) + { + height=LCD_HEIGHT-y; + } + + ILI9341_SetAddress(x, y, x+width-1, y+height-1); + ILI9341_DrawColorBurst(color, height*width); +} + +void ILI9341_DrawHLine(uint16_t x, uint16_t y, uint16_t width, uint16_t color) +{ + if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return; + + if((x+width-1)>=LCD_WIDTH) + { + width=LCD_WIDTH-x; + } + + ILI9341_SetAddress(x, y, x+width-1, y); + ILI9341_DrawColorBurst(color, width); +} + +void ILI9341_DrawVLine(uint16_t x, uint16_t y, uint16_t height, uint16_t color) +{ + if((x >=LCD_WIDTH) || (y >=LCD_HEIGHT)) return; + + if((y+height-1)>=LCD_HEIGHT) + { + height=LCD_HEIGHT-y; + } + + ILI9341_SetAddress(x, y, x, y+height-1); + ILI9341_DrawColorBurst(color, height); +} diff --git a/touchscreengames/Core/Src/fonts.c b/touchscreengames/Core/Src/fonts.c new file mode 100644 index 0000000..4e85209 --- /dev/null +++ b/touchscreengames/Core/Src/fonts.c @@ -0,0 +1,409 @@ +#include "fonts.h" + +const uint8_t Arial_Narrow8x12[] = { + /* Offset, Width, Height, BPL */ + 17,8,12,2, + + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + 0x02, 0x00, 0x00, 0x7E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! + 0x03, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " + 0x05, 0xE8, 0x01, 0x5E, 0x00, 0xE8, 0x01, 0x5E, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # + 0x05, 0x8C, 0x00, 0x12, 0x01, 0xFF, 0x03, 0x12, 0x01, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ + 0x07, 0x0C, 0x00, 0x12, 0x00, 0x8C, 0x01, 0x70, 0x00, 0xCC, 0x00, 0x22, 0x01, 0xC0, 0x00, 0x00, 0x00, // Code for char % + 0x05, 0xE0, 0x00, 0x2C, 0x01, 0x32, 0x01, 0xCC, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & + 0x01, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' + 0x02, 0xFC, 0x03, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( + 0x02, 0x02, 0x04, 0xFC, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) + 0x03, 0x14, 0x00, 0x0E, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * + 0x05, 0x20, 0x00, 0x20, 0x00, 0xF8, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + + 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , + 0x02, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . + 0x03, 0xC0, 0x01, 0x30, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / + 0x04, 0xFC, 0x00, 0x02, 0x01, 0x02, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 + 0x03, 0x08, 0x00, 0x04, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 + 0x04, 0x84, 0x01, 0x42, 0x01, 0x22, 0x01, 0x1C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 + 0x04, 0x84, 0x00, 0x12, 0x01, 0x12, 0x01, 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 + 0x05, 0x60, 0x00, 0x58, 0x00, 0x44, 0x00, 0xFE, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 + 0x04, 0x98, 0x00, 0x16, 0x01, 0x12, 0x01, 0xE2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 + 0x04, 0xFC, 0x00, 0x22, 0x01, 0x12, 0x01, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 + 0x04, 0x02, 0x00, 0xC2, 0x01, 0x3A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 + 0x04, 0xEC, 0x00, 0x12, 0x01, 0x12, 0x01, 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 + 0x04, 0x9C, 0x00, 0x22, 0x01, 0x12, 0x01, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 + 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : + 0x02, 0x00, 0x04, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; + 0x04, 0x20, 0x00, 0x50, 0x00, 0x50, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < + 0x04, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = + 0x04, 0x88, 0x00, 0x50, 0x00, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > + 0x04, 0x04, 0x00, 0x62, 0x01, 0x12, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? + 0x08, 0xF0, 0x01, 0x08, 0x02, 0xF4, 0x04, 0x0A, 0x09, 0x0A, 0x09, 0xF2, 0x09, 0x0C, 0x05, 0xF8, 0x02, // Code for char @ + 0x05, 0x80, 0x01, 0x7C, 0x00, 0x42, 0x00, 0x7C, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A + 0x05, 0xFE, 0x01, 0x12, 0x01, 0x12, 0x01, 0x12, 0x01, 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B + 0x06, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C + 0x05, 0xFE, 0x01, 0x02, 0x01, 0x02, 0x01, 0x84, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D + 0x05, 0xFE, 0x01, 0x12, 0x01, 0x12, 0x01, 0x12, 0x01, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E + 0x05, 0x00, 0x00, 0xFE, 0x01, 0x12, 0x00, 0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F + 0x06, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x22, 0x01, 0x22, 0x01, 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G + 0x05, 0xFE, 0x01, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H + 0x01, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I + 0x04, 0xC0, 0x00, 0x00, 0x01, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J + 0x05, 0xFE, 0x01, 0x10, 0x00, 0x38, 0x00, 0xC4, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K + 0x04, 0xFE, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L + 0x07, 0xFE, 0x01, 0x0C, 0x00, 0xF0, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x0C, 0x00, 0xFE, 0x01, 0x00, 0x00, // Code for char M + 0x06, 0xFE, 0x01, 0x04, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char N + 0x06, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x02, 0x01, 0x84, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O + 0x05, 0xFE, 0x01, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P + 0x06, 0x78, 0x00, 0x84, 0x00, 0x02, 0x01, 0x82, 0x01, 0x84, 0x00, 0x78, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char Q + 0x07, 0x00, 0x00, 0xFE, 0x01, 0x12, 0x00, 0x32, 0x00, 0x52, 0x00, 0x8C, 0x00, 0x00, 0x01, 0x00, 0x00, // Code for char R + 0x05, 0xCC, 0x00, 0x12, 0x01, 0x12, 0x01, 0x12, 0x01, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S + 0x05, 0x02, 0x00, 0x02, 0x00, 0xFE, 0x01, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T + 0x06, 0x7E, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x80, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U + 0x05, 0x06, 0x00, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V + 0x07, 0xFE, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x02, 0x00, 0xFC, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, // Code for char W + 0x06, 0x02, 0x01, 0xCC, 0x00, 0x30, 0x00, 0x30, 0x00, 0xCC, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char X + 0x05, 0x02, 0x00, 0x0C, 0x00, 0xF0, 0x01, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y + 0x05, 0x82, 0x01, 0x42, 0x01, 0x32, 0x01, 0x0A, 0x01, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z + 0x02, 0xFE, 0x07, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ + 0x03, 0x06, 0x00, 0x78, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash + 0x02, 0x02, 0x04, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] + 0x03, 0x1C, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ + 0x05, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ + 0x02, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` + 0x04, 0xC8, 0x00, 0x28, 0x01, 0x28, 0x01, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a + 0x04, 0xFE, 0x01, 0x90, 0x00, 0x08, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b + 0x04, 0xF0, 0x00, 0x08, 0x01, 0x08, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c + 0x04, 0xF0, 0x00, 0x08, 0x01, 0x90, 0x00, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d + 0x04, 0xF0, 0x00, 0x28, 0x01, 0x28, 0x01, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e + 0x02, 0xFE, 0x01, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f + 0x04, 0xF0, 0x04, 0x08, 0x05, 0x90, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g + 0x04, 0xFE, 0x01, 0x10, 0x00, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h + 0x01, 0xFA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i + 0x01, 0xFA, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j + 0x04, 0xFE, 0x01, 0x20, 0x00, 0x50, 0x00, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k + 0x01, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l + 0x07, 0xF8, 0x01, 0x10, 0x00, 0x08, 0x00, 0xF0, 0x01, 0x10, 0x00, 0x08, 0x00, 0xF8, 0x01, 0x00, 0x00, // Code for char m + 0x04, 0xF8, 0x01, 0x10, 0x00, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n + 0x04, 0xF0, 0x00, 0x08, 0x01, 0x08, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o + 0x04, 0xF8, 0x07, 0x90, 0x00, 0x08, 0x01, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p + 0x04, 0xF0, 0x00, 0x08, 0x01, 0x90, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q + 0x03, 0xF8, 0x01, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r + 0x04, 0x98, 0x00, 0x28, 0x01, 0x48, 0x01, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s + 0x02, 0xFE, 0x01, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t + 0x04, 0xF8, 0x00, 0x00, 0x01, 0x80, 0x00, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u + 0x05, 0x18, 0x00, 0xE0, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v + 0x07, 0xF8, 0x00, 0x00, 0x01, 0xF0, 0x00, 0x08, 0x00, 0xF0, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, // Code for char w + 0x05, 0x08, 0x01, 0x90, 0x00, 0x60, 0x00, 0x90, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x + 0x05, 0x08, 0x00, 0x70, 0x04, 0x80, 0x03, 0x70, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y + 0x04, 0x88, 0x01, 0x48, 0x01, 0x28, 0x01, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z + 0x02, 0xDE, 0x03, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { + 0x01, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | + 0x03, 0x02, 0x04, 0xDE, 0x07, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } + 0x05, 0x30, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ + 0x03, 0xFF, 0x00, 0x81, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char  + }; + +const uint8_t Arial_Narrow10x13[] = { + /* Offset, Width, Height, BPL */ + 21,10,13,2, + + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + 0x02, 0x00, 0x00, 0xFE, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! + 0x03, 0x0E, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " + 0x07, 0x50, 0x00, 0x50, 0x03, 0xF8, 0x00, 0x56, 0x00, 0x50, 0x03, 0xF8, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # + 0x05, 0x9C, 0x01, 0x22, 0x02, 0xFF, 0x07, 0x22, 0x02, 0xC4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ + 0x0A, 0x1C, 0x00, 0x22, 0x00, 0x22, 0x02, 0x9C, 0x01, 0x40, 0x00, 0x30, 0x00, 0xCC, 0x01, 0x22, 0x02, 0x20, 0x02, 0xC0, 0x01, // Code for char % + 0x08, 0x00, 0x00, 0xC0, 0x01, 0x3C, 0x02, 0x22, 0x02, 0x52, 0x02, 0x8C, 0x01, 0xC0, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, // Code for char & + 0x01, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' + 0x04, 0x00, 0x00, 0xF0, 0x03, 0x0C, 0x0C, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( + 0x03, 0x02, 0x10, 0x0C, 0x0C, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) + 0x03, 0x14, 0x00, 0x0E, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * + 0x07, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xF8, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + + 0x02, 0x00, 0x08, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , + 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . + 0x03, 0x00, 0x03, 0xF0, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / + 0x05, 0xF8, 0x00, 0x04, 0x01, 0x02, 0x02, 0x04, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 + 0x03, 0x08, 0x00, 0x04, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 + 0x05, 0x0C, 0x03, 0x82, 0x02, 0x42, 0x02, 0x24, 0x02, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 + 0x05, 0x84, 0x01, 0x02, 0x02, 0x22, 0x02, 0x54, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 + 0x05, 0xC0, 0x00, 0xB0, 0x00, 0x8C, 0x00, 0xFE, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 + 0x05, 0xB8, 0x01, 0x16, 0x02, 0x12, 0x02, 0x22, 0x01, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 + 0x05, 0xF8, 0x00, 0x24, 0x01, 0x12, 0x02, 0x22, 0x01, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 + 0x05, 0x02, 0x00, 0x82, 0x03, 0x72, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 + 0x05, 0x88, 0x00, 0x54, 0x01, 0x22, 0x02, 0x54, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 + 0x05, 0x18, 0x01, 0x24, 0x02, 0x42, 0x02, 0x24, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 + 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : + 0x02, 0x00, 0x08, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; + 0x05, 0x20, 0x00, 0x50, 0x00, 0x50, 0x00, 0x88, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < + 0x05, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = + 0x05, 0x04, 0x01, 0x88, 0x00, 0x50, 0x00, 0x50, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > + 0x05, 0x0C, 0x00, 0x06, 0x00, 0xC2, 0x02, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? + 0x0A, 0xF0, 0x03, 0x08, 0x04, 0xF4, 0x09, 0x0A, 0x12, 0x0A, 0x12, 0x0A, 0x11, 0xF2, 0x13, 0x1A, 0x12, 0x04, 0x0A, 0xF8, 0x05, // Code for char @ + 0x07, 0x00, 0x03, 0xE0, 0x00, 0x5C, 0x00, 0x42, 0x00, 0x5C, 0x00, 0xE0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A + 0x06, 0x00, 0x00, 0xFE, 0x03, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0xDC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B + 0x07, 0x00, 0x00, 0xF8, 0x00, 0x04, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x8C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C + 0x07, 0x00, 0x00, 0xFE, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D + 0x06, 0x00, 0x00, 0xFE, 0x03, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E + 0x06, 0x00, 0x00, 0xFE, 0x03, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F + 0x07, 0x00, 0x00, 0xF8, 0x00, 0x04, 0x01, 0x02, 0x02, 0x22, 0x02, 0x22, 0x02, 0xEC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G + 0x07, 0x00, 0x00, 0xFE, 0x03, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H + 0x02, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I + 0x04, 0x80, 0x01, 0x00, 0x02, 0x00, 0x02, 0xFE, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J + 0x06, 0x00, 0x00, 0xFE, 0x03, 0x20, 0x00, 0x78, 0x00, 0x84, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K + 0x06, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L + 0x08, 0x00, 0x00, 0xFE, 0x03, 0x1C, 0x00, 0xE0, 0x01, 0x00, 0x02, 0xE0, 0x01, 0x1C, 0x00, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, // Code for char M + 0x07, 0x00, 0x00, 0xFE, 0x03, 0x0C, 0x00, 0x30, 0x00, 0x40, 0x00, 0x80, 0x01, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N + 0x07, 0x00, 0x00, 0xF8, 0x00, 0x04, 0x01, 0x02, 0x02, 0x02, 0x02, 0x04, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O + 0x06, 0x00, 0x00, 0xFE, 0x03, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P + 0x07, 0x00, 0x00, 0xF8, 0x00, 0x04, 0x01, 0x02, 0x02, 0x02, 0x03, 0x04, 0x01, 0xF8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q + 0x08, 0x00, 0x00, 0xFE, 0x03, 0x22, 0x00, 0x22, 0x00, 0x62, 0x00, 0xA2, 0x00, 0x1C, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, // Code for char R + 0x06, 0x00, 0x00, 0x9C, 0x01, 0x22, 0x02, 0x22, 0x02, 0x22, 0x02, 0xCC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S + 0x06, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0xFE, 0x03, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T + 0x07, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U + 0x07, 0x06, 0x00, 0x38, 0x00, 0xC0, 0x01, 0x00, 0x02, 0xC0, 0x01, 0x38, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V + 0x09, 0x06, 0x00, 0xF8, 0x01, 0x00, 0x02, 0xFC, 0x01, 0x02, 0x00, 0xFC, 0x01, 0x00, 0x02, 0xF0, 0x01, 0x0E, 0x00, 0x00, 0x00, // Code for char W + 0x07, 0x02, 0x02, 0x04, 0x01, 0xD8, 0x00, 0x20, 0x00, 0xD8, 0x00, 0x04, 0x01, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X + 0x07, 0x02, 0x00, 0x0C, 0x00, 0x10, 0x00, 0xE0, 0x03, 0x10, 0x00, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y + 0x06, 0x02, 0x03, 0x82, 0x02, 0x62, 0x02, 0x12, 0x02, 0x0A, 0x02, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z + 0x03, 0x00, 0x00, 0xFE, 0x1F, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ + 0x03, 0x06, 0x00, 0xF8, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash + 0x02, 0x02, 0x10, 0xFE, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] + 0x05, 0x20, 0x00, 0x1C, 0x00, 0x02, 0x00, 0x1C, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ + 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ + 0x02, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` + 0x05, 0x90, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a + 0x05, 0xFE, 0x03, 0x10, 0x01, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b + 0x04, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c + 0x05, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d + 0x05, 0xF0, 0x01, 0x48, 0x02, 0x48, 0x02, 0x48, 0x02, 0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e + 0x02, 0xFE, 0x03, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f + 0x05, 0xF0, 0x09, 0x08, 0x12, 0x08, 0x12, 0x10, 0x11, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g + 0x05, 0xFE, 0x03, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h + 0x01, 0xFA, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i + 0x01, 0xFA, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j + 0x04, 0xFE, 0x03, 0x20, 0x00, 0xD0, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k + 0x01, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l + 0x07, 0xF8, 0x03, 0x10, 0x00, 0x08, 0x00, 0xF0, 0x03, 0x10, 0x00, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m + 0x05, 0xF8, 0x03, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n + 0x05, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o + 0x05, 0xF8, 0x1F, 0x10, 0x01, 0x08, 0x02, 0x08, 0x02, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p + 0x05, 0xF0, 0x01, 0x08, 0x02, 0x08, 0x02, 0x10, 0x01, 0xF8, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q + 0x03, 0xF8, 0x03, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r + 0x04, 0x30, 0x01, 0x48, 0x02, 0x48, 0x02, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s + 0x02, 0xFE, 0x03, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t + 0x05, 0xF8, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u + 0x05, 0x18, 0x00, 0xE0, 0x01, 0x00, 0x02, 0xE0, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v + 0x07, 0xF8, 0x01, 0x00, 0x02, 0xE0, 0x01, 0x18, 0x00, 0xE0, 0x01, 0x00, 0x02, 0xF8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w + 0x05, 0x08, 0x02, 0xB0, 0x01, 0x40, 0x00, 0xB0, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x + 0x05, 0x18, 0x10, 0xE0, 0x10, 0x00, 0x0F, 0xE0, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y + 0x04, 0x08, 0x03, 0xC8, 0x02, 0x28, 0x02, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z + 0x03, 0x40, 0x00, 0xBC, 0x0F, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { + 0x02, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | + 0x03, 0x02, 0x10, 0xBC, 0x0F, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } + 0x05, 0x30, 0x00, 0x10, 0x00, 0x30, 0x00, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ + 0x03, 0xFF, 0x03, 0x01, 0x02, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char  + }; + +const uint8_t Arial_Narrow12x16[] = { + /* Offset, Width, Height, BPL */ + 25,12,16,2, + + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + 0x02, 0x00, 0x00, 0xFE, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! + 0x04, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " + 0x08, 0x10, 0x01, 0x10, 0x0F, 0xF0, 0x01, 0x1E, 0x01, 0x10, 0x0F, 0xF0, 0x01, 0x1E, 0x01, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # + 0x06, 0x1C, 0x06, 0x22, 0x08, 0x42, 0x08, 0xFF, 0x1F, 0x42, 0x08, 0x8C, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ + 0x0B, 0x00, 0x00, 0x3C, 0x00, 0x42, 0x00, 0x42, 0x08, 0x3C, 0x06, 0x80, 0x01, 0x70, 0x00, 0x8C, 0x07, 0x42, 0x08, 0x40, 0x08, 0x80, 0x07, 0x00, 0x00, // Code for char % + 0x09, 0x00, 0x00, 0x80, 0x07, 0xDC, 0x08, 0x62, 0x08, 0xA2, 0x08, 0x1C, 0x07, 0x00, 0x07, 0x80, 0x09, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & + 0x02, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' + 0x04, 0x00, 0x00, 0xF0, 0x0F, 0x0C, 0x38, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( + 0x03, 0x02, 0x40, 0x0C, 0x38, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) + 0x05, 0x04, 0x00, 0x34, 0x00, 0x0E, 0x00, 0x34, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * + 0x07, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xF8, 0x03, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + + 0x02, 0x00, 0x20, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , + 0x04, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - + 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . + 0x04, 0x00, 0x0C, 0x80, 0x03, 0x70, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / + 0x06, 0xF8, 0x03, 0x04, 0x04, 0x02, 0x08, 0x02, 0x08, 0x04, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 + 0x04, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 + 0x06, 0x0C, 0x0C, 0x02, 0x0A, 0x02, 0x09, 0x82, 0x08, 0x44, 0x08, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 + 0x06, 0x0C, 0x06, 0x02, 0x08, 0x42, 0x08, 0x42, 0x08, 0xA4, 0x04, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 + 0x06, 0x80, 0x01, 0x40, 0x01, 0x30, 0x01, 0x0C, 0x01, 0xFE, 0x0F, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 + 0x06, 0x70, 0x06, 0x4E, 0x08, 0x22, 0x08, 0x22, 0x08, 0x42, 0x04, 0x82, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 + 0x06, 0xF8, 0x03, 0x44, 0x04, 0x22, 0x08, 0x22, 0x08, 0x42, 0x04, 0x8C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 + 0x06, 0x02, 0x00, 0x02, 0x0E, 0xC2, 0x01, 0x32, 0x00, 0x0A, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 + 0x06, 0x18, 0x03, 0xA4, 0x04, 0x42, 0x08, 0x42, 0x08, 0xA4, 0x04, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 + 0x06, 0x38, 0x06, 0x44, 0x08, 0x82, 0x08, 0x82, 0x08, 0x44, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 + 0x02, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : + 0x02, 0x00, 0x20, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; + 0x07, 0x00, 0x00, 0x40, 0x00, 0xA0, 0x00, 0xA0, 0x00, 0x10, 0x01, 0x10, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < + 0x07, 0x00, 0x00, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = + 0x07, 0x00, 0x00, 0x08, 0x02, 0x10, 0x01, 0x10, 0x01, 0xA0, 0x00, 0xA0, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > + 0x06, 0x0C, 0x00, 0x02, 0x00, 0x02, 0x0B, 0x82, 0x00, 0x42, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? + 0x0C, 0x00, 0x00, 0xE0, 0x07, 0x10, 0x08, 0xE8, 0x17, 0x14, 0x28, 0x12, 0x48, 0x12, 0x44, 0x22, 0x47, 0xF2, 0x48, 0x04, 0x28, 0x08, 0x28, 0xF0, 0x17, // Code for char @ + 0x09, 0x00, 0x08, 0x00, 0x07, 0xE0, 0x00, 0x9C, 0x00, 0x82, 0x00, 0x9C, 0x00, 0xE0, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A + 0x08, 0x00, 0x00, 0xFE, 0x0F, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0xBC, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B + 0x08, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x04, 0x04, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C + 0x08, 0x00, 0x00, 0xFE, 0x0F, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x04, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D + 0x08, 0x00, 0x00, 0xFE, 0x0F, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E + 0x07, 0x00, 0x00, 0xFE, 0x0F, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F + 0x09, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x02, 0x08, 0x02, 0x08, 0x82, 0x08, 0x82, 0x08, 0x84, 0x08, 0x98, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G + 0x08, 0x00, 0x00, 0xFE, 0x0F, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H + 0x02, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I + 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0xFE, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J + 0x08, 0x00, 0x00, 0xFE, 0x0F, 0x40, 0x00, 0x20, 0x00, 0xD0, 0x00, 0x08, 0x01, 0x04, 0x06, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K + 0x07, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L + 0x0A, 0x00, 0x00, 0xFE, 0x0F, 0x06, 0x00, 0x78, 0x00, 0x80, 0x03, 0x00, 0x0C, 0x80, 0x03, 0x78, 0x00, 0x06, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, // Code for char M + 0x08, 0x00, 0x00, 0xFE, 0x0F, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x01, 0x00, 0x06, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N + 0x09, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x02, 0x08, 0x04, 0x04, 0xF8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O + 0x08, 0x00, 0x00, 0xFE, 0x0F, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P + 0x09, 0x00, 0x00, 0xF8, 0x03, 0x04, 0x04, 0x02, 0x08, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x04, 0x04, 0x06, 0xF8, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q + 0x09, 0x00, 0x00, 0xFE, 0x0F, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0xC2, 0x00, 0xC2, 0x01, 0x3C, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R + 0x08, 0x00, 0x00, 0x18, 0x03, 0x24, 0x04, 0x42, 0x08, 0x42, 0x08, 0x42, 0x08, 0x84, 0x04, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S + 0x07, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0xFE, 0x0F, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T + 0x08, 0x00, 0x00, 0xFE, 0x03, 0x00, 0x04, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0xFE, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U + 0x09, 0x02, 0x00, 0x1C, 0x00, 0xE0, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x07, 0xE0, 0x00, 0x1C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V + 0x0B, 0x1E, 0x00, 0xE0, 0x03, 0x00, 0x0C, 0xC0, 0x03, 0x3C, 0x00, 0x02, 0x00, 0x3C, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0xE0, 0x03, 0x1E, 0x00, 0x00, 0x00, // Code for char W + 0x08, 0x02, 0x08, 0x04, 0x04, 0x18, 0x03, 0xE0, 0x00, 0xA0, 0x00, 0x18, 0x03, 0x04, 0x04, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X + 0x09, 0x02, 0x00, 0x04, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x0F, 0x60, 0x00, 0x18, 0x00, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y + 0x07, 0x02, 0x0C, 0x02, 0x0A, 0x82, 0x09, 0x42, 0x08, 0x32, 0x08, 0x0A, 0x08, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z + 0x03, 0x00, 0x00, 0xFE, 0x7F, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ + 0x04, 0x06, 0x00, 0x78, 0x00, 0x80, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash + 0x03, 0x00, 0x00, 0x02, 0x40, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] + 0x05, 0x40, 0x00, 0x38, 0x00, 0x06, 0x00, 0x38, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ + 0x07, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ + 0x03, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` + 0x06, 0x00, 0x00, 0x60, 0x06, 0x10, 0x09, 0x10, 0x09, 0xA0, 0x04, 0xC0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a + 0x07, 0x00, 0x00, 0xFE, 0x0F, 0x20, 0x04, 0x10, 0x08, 0x10, 0x08, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b + 0x06, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x10, 0x08, 0x10, 0x08, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c + 0x07, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x10, 0x08, 0x10, 0x08, 0x20, 0x04, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d + 0x07, 0x00, 0x00, 0xC0, 0x03, 0xA0, 0x04, 0x90, 0x08, 0x90, 0x08, 0xA0, 0x04, 0xC0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e + 0x03, 0x10, 0x00, 0xFE, 0x0F, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f + 0x07, 0x00, 0x00, 0xC0, 0x33, 0x20, 0x44, 0x10, 0x48, 0x10, 0x48, 0x20, 0x24, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g + 0x06, 0x00, 0x00, 0xFE, 0x0F, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h + 0x02, 0x00, 0x00, 0xF2, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i + 0x02, 0x00, 0x40, 0xF2, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j + 0x06, 0x00, 0x00, 0xFE, 0x0F, 0x80, 0x00, 0xC0, 0x00, 0x20, 0x03, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k + 0x02, 0x00, 0x00, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l + 0x0A, 0x00, 0x00, 0xF0, 0x0F, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0xE0, 0x0F, 0x30, 0x00, 0x10, 0x00, 0x10, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, // Code for char m + 0x06, 0x00, 0x00, 0xF0, 0x0F, 0x20, 0x00, 0x10, 0x00, 0x10, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n + 0x07, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x10, 0x08, 0x10, 0x08, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o + 0x07, 0x00, 0x00, 0xF0, 0x7F, 0x20, 0x04, 0x10, 0x08, 0x10, 0x08, 0x20, 0x04, 0xC0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p + 0x07, 0x00, 0x00, 0xC0, 0x03, 0x20, 0x04, 0x10, 0x08, 0x10, 0x08, 0x20, 0x04, 0xF0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q + 0x04, 0x00, 0x00, 0xF0, 0x0F, 0x20, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r + 0x06, 0x00, 0x00, 0x60, 0x06, 0x90, 0x08, 0x90, 0x08, 0x10, 0x09, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s + 0x03, 0x10, 0x00, 0xFE, 0x0F, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t + 0x06, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u + 0x07, 0x10, 0x00, 0xE0, 0x00, 0x00, 0x07, 0x00, 0x08, 0x00, 0x07, 0xE0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v + 0x09, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0xC0, 0x03, 0x30, 0x00, 0xC0, 0x03, 0x00, 0x0C, 0xC0, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w + 0x06, 0x00, 0x00, 0x10, 0x08, 0x60, 0x06, 0x80, 0x01, 0x60, 0x06, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x + 0x07, 0x10, 0x00, 0xE0, 0x40, 0x00, 0x47, 0x00, 0x38, 0x00, 0x07, 0xE0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y + 0x06, 0x00, 0x00, 0x10, 0x0C, 0x10, 0x0A, 0x90, 0x09, 0x50, 0x08, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z + 0x03, 0x00, 0x01, 0xFE, 0x7E, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { + 0x02, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | + 0x03, 0x02, 0x40, 0xFE, 0x7E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } + 0x07, 0x40, 0x00, 0x20, 0x00, 0x20, 0x00, 0x60, 0x00, 0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ + 0x04, 0xFF, 0x0F, 0x01, 0x08, 0x01, 0x08, 0xFF, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char  + }; + +const uint8_t Arial_Narrow15x19[] = { + /* Offset, Width, Height, BPL */ + 46,15,19,3, + + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + 0x02, 0x00, 0x00, 0x00, 0xFE, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ! + 0x04, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char " + 0x08, 0x20, 0x04, 0x00, 0x20, 0x74, 0x00, 0xF0, 0x0F, 0x00, 0x2E, 0x04, 0x00, 0x20, 0x74, 0x00, 0xF0, 0x0F, 0x00, 0x2E, 0x04, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char # + 0x08, 0x00, 0x00, 0x00, 0x78, 0x18, 0x00, 0xC6, 0x20, 0x00, 0x82, 0x40, 0x00, 0xFF, 0xFF, 0x01, 0x02, 0x41, 0x00, 0x06, 0x23, 0x00, 0x0C, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char $ + 0x0B, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x82, 0x00, 0x00, 0x82, 0x40, 0x00, 0x7C, 0x38, 0x00, 0x00, 0x07, 0x00, 0xE0, 0x00, 0x00, 0x18, 0x3E, 0x00, 0x06, 0x41, 0x00, 0x00, 0x41, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char % + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0xBC, 0x21, 0x00, 0xC6, 0x40, 0x00, 0xC2, 0x41, 0x00, 0x42, 0x42, 0x00, 0x66, 0x64, 0x00, 0x3C, 0x3C, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x63, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char & + 0x02, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ' + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x1C, 0xC0, 0x03, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ( + 0x03, 0x02, 0x00, 0x04, 0x1C, 0xC0, 0x03, 0xE0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ) + 0x05, 0x04, 0x00, 0x00, 0x34, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x34, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char * + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char + + 0x02, 0x00, 0x00, 0x02, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char , + 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char - + 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char . + 0x04, 0x00, 0x40, 0x00, 0x00, 0x3E, 0x00, 0xE0, 0x01, 0x00, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char / + 0x08, 0xF8, 0x0F, 0x00, 0x06, 0x30, 0x00, 0x03, 0x60, 0x00, 0x01, 0x40, 0x00, 0x01, 0x40, 0x00, 0x03, 0x60, 0x00, 0x06, 0x30, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 0 + 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1 + 0x08, 0x0C, 0x60, 0x00, 0x02, 0x50, 0x00, 0x01, 0x48, 0x00, 0x01, 0x44, 0x00, 0x01, 0x42, 0x00, 0x81, 0x41, 0x00, 0xC2, 0x40, 0x00, 0x3C, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 2 + 0x08, 0x04, 0x18, 0x00, 0x02, 0x20, 0x00, 0x01, 0x40, 0x00, 0x81, 0x40, 0x00, 0x81, 0x40, 0x00, 0x81, 0x40, 0x00, 0xC2, 0x21, 0x00, 0x3C, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 3 + 0x08, 0x00, 0x06, 0x00, 0x80, 0x05, 0x00, 0x40, 0x04, 0x00, 0x30, 0x04, 0x00, 0x0C, 0x04, 0x00, 0xFF, 0x7F, 0x00, 0x00, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 4 + 0x08, 0xF0, 0x18, 0x00, 0x6F, 0x20, 0x00, 0x21, 0x40, 0x00, 0x21, 0x40, 0x00, 0x21, 0x40, 0x00, 0x61, 0x60, 0x00, 0xC1, 0x30, 0x00, 0x81, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 5 + 0x08, 0xF8, 0x0F, 0x00, 0x86, 0x30, 0x00, 0x42, 0x60, 0x00, 0x41, 0x40, 0x00, 0x41, 0x40, 0x00, 0x41, 0x40, 0x00, 0x82, 0x20, 0x00, 0x04, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 6 + 0x08, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x78, 0x00, 0x01, 0x07, 0x00, 0xE1, 0x00, 0x00, 0x39, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 7 + 0x08, 0x3C, 0x1F, 0x00, 0xC2, 0x21, 0x00, 0x81, 0x40, 0x00, 0x81, 0x40, 0x00, 0x81, 0x40, 0x00, 0x81, 0x40, 0x00, 0xC2, 0x21, 0x00, 0x7C, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 8 + 0x08, 0x7C, 0x10, 0x00, 0x86, 0x20, 0x00, 0x03, 0x41, 0x00, 0x01, 0x41, 0x00, 0x01, 0x41, 0x00, 0x01, 0x21, 0x00, 0x86, 0x38, 0x00, 0xF8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 9 + 0x02, 0x00, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char : + 0x02, 0x00, 0x00, 0x02, 0x20, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ; + 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x40, 0x04, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char < + 0x08, 0x00, 0x00, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char = + 0x08, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x40, 0x04, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char > + 0x07, 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x5C, 0x00, 0x02, 0x03, 0x00, 0x84, 0x01, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ? + 0x0F, 0x00, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x60, 0xC0, 0x00, 0x18, 0x00, 0x01, 0x0C, 0x1F, 0x02, 0xC4, 0x60, 0x02, 0x62, 0x40, 0x04, 0x22, 0x40, 0x04, 0x22, 0x20, 0x04, 0x42, 0x38, 0x04, 0xE2, 0x47, 0x04, 0x04, 0x40, 0x02, 0x0C, 0x20, 0x02, 0x38, 0x18, 0x01, 0xE0, 0x87, 0x00, // Code for char @ + 0x0B, 0x00, 0x40, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0xE0, 0x02, 0x00, 0x1C, 0x02, 0x00, 0x02, 0x02, 0x00, 0x1C, 0x02, 0x00, 0xE0, 0x02, 0x00, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char A + 0x09, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0xC4, 0x21, 0x00, 0x78, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char B + 0x0A, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x18, 0x18, 0x00, 0x04, 0x20, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x04, 0x20, 0x00, 0x18, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char C + 0x0A, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x04, 0x20, 0x00, 0x0C, 0x18, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char D + 0x09, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char E + 0x09, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x82, 0x00, 0x00, 0x82, 0x00, 0x00, 0x82, 0x00, 0x00, 0x82, 0x00, 0x00, 0x82, 0x00, 0x00, 0x82, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char F + 0x0B, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x18, 0x18, 0x00, 0x04, 0x20, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0x41, 0x00, 0x02, 0x41, 0x00, 0x02, 0x61, 0x00, 0x04, 0x21, 0x00, 0x18, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char G + 0x0A, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char H + 0x02, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I + 0x07, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char J + 0x0A, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x03, 0x00, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x20, 0x01, 0x00, 0x10, 0x06, 0x00, 0x08, 0x18, 0x00, 0x06, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char K + 0x08, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char L + 0x0C, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x06, 0x00, 0x00, 0x38, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x03, 0x00, 0x70, 0x00, 0x00, 0x0E, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char M + 0x0A, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x04, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x18, 0x00, 0x00, 0x20, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char N + 0x0B, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x18, 0x18, 0x00, 0x04, 0x20, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x04, 0x20, 0x00, 0x18, 0x18, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char O + 0x09, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x86, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char P + 0x0B, 0x00, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x18, 0x18, 0x00, 0x04, 0x20, 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x02, 0x58, 0x00, 0x02, 0x70, 0x00, 0x04, 0x20, 0x00, 0x18, 0x78, 0x00, 0xE0, 0xCF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Q + 0x0B, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x01, 0x00, 0x02, 0x07, 0x00, 0x86, 0x0C, 0x00, 0x78, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char R + 0x09, 0x00, 0x00, 0x00, 0x38, 0x18, 0x00, 0x44, 0x20, 0x00, 0x82, 0x40, 0x00, 0x82, 0x40, 0x00, 0x02, 0x41, 0x00, 0x02, 0x41, 0x00, 0x04, 0x22, 0x00, 0x18, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char S + 0x09, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T + 0x0A, 0x00, 0x00, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xFE, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char U + 0x0B, 0x02, 0x00, 0x00, 0x1C, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x38, 0x00, 0x00, 0x40, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0xE0, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char V + 0x0E, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0xC0, 0x1F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0xC0, 0x03, 0x00, 0x38, 0x00, 0x00, 0x06, 0x00, 0x00, 0x38, 0x00, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x60, 0x00, 0xC0, 0x1F, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char W + 0x0A, 0x02, 0x40, 0x00, 0x04, 0x20, 0x00, 0x18, 0x18, 0x00, 0x20, 0x04, 0x00, 0xC0, 0x03, 0x00, 0xC0, 0x03, 0x00, 0x20, 0x04, 0x00, 0x18, 0x18, 0x00, 0x04, 0x20, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char X + 0x09, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x30, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x7F, 0x00, 0xC0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Y + 0x09, 0x02, 0x60, 0x00, 0x02, 0x50, 0x00, 0x02, 0x4C, 0x00, 0x02, 0x42, 0x00, 0x82, 0x41, 0x00, 0x42, 0x40, 0x00, 0x32, 0x40, 0x00, 0x0A, 0x40, 0x00, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char Z + 0x04, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [ + 0x04, 0x06, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char BackSlash + 0x03, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0xFE, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ] + 0x07, 0x80, 0x00, 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x06, 0x00, 0x00, 0x18, 0x00, 0x00, 0x60, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ^ + 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char _ + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ` + 0x08, 0x00, 0x00, 0x00, 0x80, 0x3C, 0x00, 0x40, 0x66, 0x00, 0x20, 0x42, 0x00, 0x20, 0x42, 0x00, 0x20, 0x42, 0x00, 0x20, 0x31, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char a + 0x08, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x40, 0x20, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x40, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char b + 0x07, 0x80, 0x1F, 0x00, 0x40, 0x20, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x60, 0x20, 0x00, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char c + 0x08, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x40, 0x20, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x40, 0x20, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char d + 0x08, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x40, 0x22, 0x00, 0x20, 0x42, 0x00, 0x20, 0x42, 0x00, 0x20, 0x42, 0x00, 0x40, 0x22, 0x00, 0x80, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char e + 0x05, 0x20, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x22, 0x00, 0x00, 0x22, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f + 0x08, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x03, 0x40, 0x20, 0x04, 0x20, 0x40, 0x04, 0x20, 0x40, 0x04, 0x20, 0x40, 0x04, 0x40, 0x20, 0x02, 0xE0, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char g + 0x08, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char h + 0x02, 0x00, 0x00, 0x00, 0xE2, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i + 0x02, 0x00, 0x00, 0x04, 0xE2, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j + 0x07, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x80, 0x04, 0x00, 0x40, 0x18, 0x00, 0x20, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char k + 0x02, 0x00, 0x00, 0x00, 0xFE, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l + 0x0C, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char m + 0x08, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char n + 0x08, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x40, 0x20, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x40, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char o + 0x08, 0x00, 0x00, 0x00, 0xE0, 0xFF, 0x07, 0x40, 0x20, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x40, 0x20, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char p + 0x08, 0x00, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x40, 0x20, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x20, 0x40, 0x00, 0x40, 0x20, 0x00, 0xE0, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char q + 0x05, 0x00, 0x00, 0x00, 0xE0, 0x7F, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char r + 0x07, 0x00, 0x00, 0x00, 0xC0, 0x31, 0x00, 0x20, 0x42, 0x00, 0x20, 0x42, 0x00, 0x20, 0x44, 0x00, 0x20, 0x44, 0x00, 0xC0, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s + 0x03, 0x20, 0x00, 0x00, 0xFC, 0x7F, 0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t + 0x08, 0x00, 0x00, 0x00, 0xE0, 0x3F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0xE0, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char u + 0x07, 0x60, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x40, 0x00, 0x00, 0x3C, 0x00, 0x80, 0x03, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char v + 0x0B, 0x60, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x60, 0x00, 0x80, 0x1F, 0x00, 0x60, 0x00, 0x00, 0x80, 0x1F, 0x00, 0x00, 0x60, 0x00, 0x00, 0x1C, 0x00, 0x80, 0x03, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char w + 0x07, 0x20, 0x40, 0x00, 0xC0, 0x30, 0x00, 0x00, 0x09, 0x00, 0x00, 0x06, 0x00, 0x00, 0x09, 0x00, 0xC0, 0x30, 0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char x + 0x07, 0x60, 0x00, 0x04, 0x80, 0x03, 0x04, 0x00, 0x3C, 0x02, 0x00, 0xC0, 0x01, 0x00, 0x3C, 0x00, 0x80, 0x03, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y + 0x07, 0x20, 0x60, 0x00, 0x20, 0x50, 0x00, 0x20, 0x48, 0x00, 0x20, 0x46, 0x00, 0x20, 0x41, 0x00, 0xA0, 0x40, 0x00, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char z + 0x05, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x00, 0xFC, 0xFB, 0x03, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char { + 0x02, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char | + 0x05, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0xFC, 0xFB, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char } + 0x08, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ~ + 0x05, 0xFE, 0x3F, 0x00, 0x02, 0x20, 0x00, 0x02, 0x20, 0x00, 0x02, 0x20, 0x00, 0xFE, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char  + }; diff --git a/touchscreengames/Core/Src/main.c b/touchscreengames/Core/Src/main.c new file mode 100644 index 0000000..e9247c5 --- /dev/null +++ b/touchscreengames/Core/Src/main.c @@ -0,0 +1,1038 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file : main.c + * @brief : Main program body + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "cmsis_os.h" + +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +//#include "ili9341.h" +#include "ILI9341_STM32_Driver.h" +#include "ILI9341_GFX.h" +#include "snake.h" + +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ + +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +I2C_HandleTypeDef hi2c1; + +SPI_HandleTypeDef hspi1; +DMA_HandleTypeDef hdma_spi1_rx; +DMA_HandleTypeDef hdma_spi1_tx; + +TIM_HandleTypeDef htim1; +TIM_HandleTypeDef htim4; +TIM_HandleTypeDef htim5; + +UART_HandleTypeDef huart6; + +/* Definitions for control */ +osThreadId_t controlHandle; +const osThreadAttr_t control_attributes = { + .name = "control", + .stack_size = 128 * 4, + .priority = (osPriority_t) osPriorityNormal, +}; +/* Definitions for draw */ +osThreadId_t drawHandle; +const osThreadAttr_t draw_attributes = { + .name = "draw", + .stack_size = 512 * 4, + .priority = (osPriority_t) osPriorityLow, +}; +/* Definitions for menu */ +osThreadId_t menuHandle; +const osThreadAttr_t menu_attributes = { + .name = "menu", + .stack_size = 256 * 4, + .priority = (osPriority_t) osPriorityLow, +}; +/* Definitions for presses */ +osMessageQueueId_t pressesHandle; +const osMessageQueueAttr_t presses_attributes = { + .name = "presses" +}; +/* Definitions for display */ +osMutexId_t displayHandle; +const osMutexAttr_t display_attributes = { + .name = "display" +}; +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +static void MX_DMA_Init(void); +static void MX_SPI1_Init(void); +static void MX_TIM1_Init(void); +static void MX_TIM4_Init(void); +static void MX_TIM5_Init(void); +static void MX_USART6_UART_Init(void); +static void MX_I2C1_Init(void); +void start_control(void *argument); +void snakegame(void *argument); +void handle_menu(void *argument); + +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ +int run_snake = 0; +int run_menu = 1; + +#define RX_BUFFER_SIZE 1 +#define LINE_BUFFER_SIZE 128 + +uint8_t rx_buffer[RX_BUFFER_SIZE]; +char line_buffer[LINE_BUFFER_SIZE]; +uint16_t line_pos = 0; + +//menu +int redraw_menu_pending; +#define GRID_X 2 +#define GRID_Y 3 +uint8_t menu_status[GRID_X][GRID_Y] = { 0 }; +void process_line(const char *line) { + if (strncmp(line, "ABS:", 4) == 0) { + char axis[32]; + int value; + if (sscanf(line, "ABS:%31[^:]:%d:", axis, &value) == 2) { + // Handle axis input + if (strcmp(axis, "ABS_X") == 0) { + + // Do something with X axis + + } else if (strcmp(axis, "ABS_Y") == 0) { + // Do something with Y axis + + } + } + } else if (strncmp(line, "KEY:", 4) == 0) { + char key[32]; + int state; + if (sscanf(line, "KEY:%31[^:]:%d:", key, &state) == 2) { + // Handle button press/release + + //we only care about presses + if (state) { + char dir; + dir = key[0]; + osStatus_t status = osMessageQueuePut(pressesHandle, &dir, 0, + 0); + + if (status != osOK) { + // Optional: Handle error + } + } + + if (key[0] == 'B' && state == 1) { // B goes to the menu + run_snake = 0; + run_menu = 1; + redraw_menu_pending = 1; + } + if (key[0] == 'Y' && state == 1) { // Y reboot + + } + } + } +} +void UART_CALLBACK() { + char ch = rx_buffer[0]; + + if (ch == '\r') { + // ignore + } else if (ch == '\n') { + //line_buffer[line_pos] = '\0'; + if (line_buffer[1] == 'K' || line_buffer[1] == 'A') { + process_line(&line_buffer[1]); + } else { + process_line(line_buffer); + } + + line_pos = 0; + } else if (line_pos < LINE_BUFFER_SIZE - 1) { + line_buffer[line_pos++] = ch; + } + + HAL_UART_Receive_IT(&huart6, rx_buffer, RX_BUFFER_SIZE); +} +#define TIM4_ARR_VALUE 1024 +uint32_t TIM4_CurrentCount; +uint32_t TIM4_PreviousCount = 0; +#define TS 0.01 +#define M_PI 3.1415 +float encoder_TIM4_speed_rad() { + int32_t TIM4_DiffCount; + TIM4_CurrentCount = __HAL_TIM_GET_COUNTER(&htim4); + /* evaluate increment of TIM3 counter from previous count */ + if (__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim4)) { + /* check for counter underflow */ + if (TIM4_CurrentCount <= TIM4_PreviousCount) + TIM4_DiffCount = TIM4_CurrentCount - TIM4_PreviousCount; + else + TIM4_DiffCount = -((TIM4_ARR_VALUE + 1) - TIM4_CurrentCount) + - TIM4_PreviousCount; + } else { + /* check for counter overflow */ + if (TIM4_CurrentCount >= TIM4_PreviousCount) + TIM4_DiffCount = TIM4_CurrentCount - TIM4_PreviousCount; + else + TIM4_DiffCount = ((TIM4_ARR_VALUE + 1) - TIM4_PreviousCount) + + TIM4_CurrentCount; + } + TIM4_PreviousCount = TIM4_CurrentCount; + return (float) TIM4_DiffCount / (TIM4_ARR_VALUE * TS) * 2 * M_PI; +} +#define TIM5_ARR_VALUE 4000 +void set_pwm(float duty, char motor, char mode) { + // Limit the duty cycle to ±70% + duty = fabsf(duty) > 0.7f ? (duty / fabsf(duty)) * 0.7f : duty; + + if (motor == 'r') { + if (duty >= 0) { // rotate forward + if (mode == 'c') { // coast + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_1, + duty * TIM5_ARR_VALUE); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_2, 0); + } else if (mode == 'b') { // brake + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_1, TIM5_ARR_VALUE); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_2, + TIM5_ARR_VALUE - duty * TIM5_ARR_VALUE); + } + } else { // rotate backward + if (mode == 'c') { // coast + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_1, 0); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_2, + (-duty) * TIM5_ARR_VALUE); + } else if (mode == 'b') { // brake + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_1, + TIM5_ARR_VALUE - (-duty) * TIM5_ARR_VALUE); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_2, TIM5_ARR_VALUE); + } + } + } + + if (motor == 'l') { + if (duty >= 0) { // rotate forward + if (mode == 'c') { + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_3, + duty * TIM5_ARR_VALUE); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_4, 0); + } else if (mode == 'b') { + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_3, TIM5_ARR_VALUE); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_4, + TIM5_ARR_VALUE - duty * TIM5_ARR_VALUE); + } + } else { // rotate backward + if (mode == 'c') { + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_3, 0); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_4, + (-duty) * TIM5_ARR_VALUE); + } else if (mode == 'b') { + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_3, + TIM5_ARR_VALUE - (-duty) * TIM5_ARR_VALUE); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_4, TIM5_ARR_VALUE); + } + } + } +} +/* USER CODE END 0 */ + +/** + * @brief The application entry point. + * @retval int + */ +int main(void) +{ + + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration--------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_DMA_Init(); + MX_SPI1_Init(); + MX_TIM1_Init(); + MX_TIM4_Init(); + MX_TIM5_Init(); + MX_USART6_UART_Init(); + MX_I2C1_Init(); + /* USER CODE BEGIN 2 */ + ILI9341_Init(); + ILI9341_SetRotation(SCREEN_HORIZONTAL_1); + //ILI9341_FillScreen(WHITE); + //void XPT2046_Init(); + //Flash_Write_HighScore(100); + /* USER CODE END 2 */ + + /* Init scheduler */ + osKernelInitialize(); + /* Create the mutex(es) */ + /* creation of display */ + displayHandle = osMutexNew(&display_attributes); + + /* USER CODE BEGIN RTOS_MUTEX */ + /* add mutexes, ... */ + /* USER CODE END RTOS_MUTEX */ + + /* USER CODE BEGIN RTOS_SEMAPHORES */ + /* add semaphores, ... */ + /* USER CODE END RTOS_SEMAPHORES */ + + /* USER CODE BEGIN RTOS_TIMERS */ + /* start timers, add new ones, ... */ + /* USER CODE END RTOS_TIMERS */ + + /* Create the queue(s) */ + /* creation of presses */ + pressesHandle = osMessageQueueNew (16, sizeof(char), &presses_attributes); + + /* USER CODE BEGIN RTOS_QUEUES */ + /* add queues, ... */ + /* USER CODE END RTOS_QUEUES */ + + /* Create the thread(s) */ + /* creation of control */ + controlHandle = osThreadNew(start_control, NULL, &control_attributes); + + /* creation of draw */ + drawHandle = osThreadNew(snakegame, NULL, &draw_attributes); + + /* creation of menu */ + menuHandle = osThreadNew(handle_menu, NULL, &menu_attributes); + + /* USER CODE BEGIN RTOS_THREADS */ + /* add threads, ... */ + + char dir; +// check the queue blocking +//osStatus_t status = osMessageQueueGet(pressesHandle, &dir, NULL, +//osWaitForever); // blocking +//if (dir == 'L') +// drawHandle = osThreadNew(snakegame, NULL, &draw_attributes); +//if (dir == 'R') +//reactiongameHandle = osThreadNew(startreactiongame, NULL, +// &reactiongame_attributes); + /* USER CODE END RTOS_THREADS */ + + /* USER CODE BEGIN RTOS_EVENTS */ + /* add events, ... */ + /* USER CODE END RTOS_EVENTS */ + + /* Start scheduler */ + osKernelStart(); + + /* We should never get here as control is now taken by the scheduler */ + + /* Infinite loop */ + /* USER CODE BEGIN WHILE */ + +//int a[4] = { ILI9341_GREEN, ILI9341_WHITE, ILI9341_BLACK, ILI9341_BLUE }; + int cnt; + + while (hspi1.State != HAL_SPI_STATE_READY) + ; + + while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY) + ; + + while (1) { + + /* USER CODE END WHILE */ + + /* USER CODE BEGIN 3 */ + float tempspeed; + tempspeed = encoder_TIM4_speed_rad(); + HAL_Delay(10); + + } + /* USER CODE END 3 */ +} + +/** + * @brief System Clock Configuration + * @retval None + */ +void SystemClock_Config(void) +{ + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + + /** Configure the main internal regulator output voltage + */ + __HAL_RCC_PWR_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); + + /** Initializes the RCC Oscillators according to the specified parameters + * in the RCC_OscInitTypeDef structure. + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + Error_Handler(); + } + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) + { + Error_Handler(); + } +} + +/** + * @brief I2C1 Initialization Function + * @param None + * @retval None + */ +static void MX_I2C1_Init(void) +{ + + /* USER CODE BEGIN I2C1_Init 0 */ + + /* USER CODE END I2C1_Init 0 */ + + /* USER CODE BEGIN I2C1_Init 1 */ + + /* USER CODE END I2C1_Init 1 */ + hi2c1.Instance = I2C1; + hi2c1.Init.ClockSpeed = 100000; + hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; + hi2c1.Init.OwnAddress1 = 0; + hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; + hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; + hi2c1.Init.OwnAddress2 = 0; + hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; + hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; + if (HAL_I2C_Init(&hi2c1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN I2C1_Init 2 */ + + /* USER CODE END I2C1_Init 2 */ + +} + +/** + * @brief SPI1 Initialization Function + * @param None + * @retval None + */ +static void MX_SPI1_Init(void) +{ + + /* USER CODE BEGIN SPI1_Init 0 */ + + /* USER CODE END SPI1_Init 0 */ + + /* USER CODE BEGIN SPI1_Init 1 */ + + /* USER CODE END SPI1_Init 1 */ + /* SPI1 parameter configuration*/ + hspi1.Instance = SPI1; + hspi1.Init.Mode = SPI_MODE_MASTER; + hspi1.Init.Direction = SPI_DIRECTION_2LINES; + hspi1.Init.DataSize = SPI_DATASIZE_8BIT; + hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; + hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi1.Init.NSS = SPI_NSS_SOFT; + hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; + hspi1.Init.TIMode = SPI_TIMODE_DISABLE; + hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + hspi1.Init.CRCPolynomial = 10; + if (HAL_SPI_Init(&hspi1) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN SPI1_Init 2 */ + + /* USER CODE END SPI1_Init 2 */ + +} + +/** + * @brief TIM1 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM1_Init(void) +{ + + /* USER CODE BEGIN TIM1_Init 0 */ + + /* USER CODE END TIM1_Init 0 */ + + TIM_Encoder_InitTypeDef sConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM1_Init 1 */ + + /* USER CODE END TIM1_Init 1 */ + htim1.Instance = TIM1; + htim1.Init.Prescaler = 0; + htim1.Init.CounterMode = TIM_COUNTERMODE_UP; + htim1.Init.Period = 65535; + htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim1.Init.RepetitionCounter = 0; + htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + sConfig.EncoderMode = TIM_ENCODERMODE_TI12; + sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; + sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; + sConfig.IC1Prescaler = TIM_ICPSC_DIV8; + sConfig.IC1Filter = 15; + sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; + sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; + sConfig.IC2Prescaler = TIM_ICPSC_DIV8; + sConfig.IC2Filter = 15; + if (HAL_TIM_Encoder_Init(&htim1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM1_Init 2 */ + + /* USER CODE END TIM1_Init 2 */ + +} + +/** + * @brief TIM4 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM4_Init(void) +{ + + /* USER CODE BEGIN TIM4_Init 0 */ + + /* USER CODE END TIM4_Init 0 */ + + TIM_Encoder_InitTypeDef sConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + + /* USER CODE BEGIN TIM4_Init 1 */ + + /* USER CODE END TIM4_Init 1 */ + htim4.Instance = TIM4; + htim4.Init.Prescaler = 0; + htim4.Init.CounterMode = TIM_COUNTERMODE_UP; + htim4.Init.Period = TIM4_ARR_VALUE; + htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + sConfig.EncoderMode = TIM_ENCODERMODE_TI12; + sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; + sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; + sConfig.IC1Prescaler = TIM_ICPSC_DIV1; + sConfig.IC1Filter = 15; + sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; + sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; + sConfig.IC2Prescaler = TIM_ICPSC_DIV1; + sConfig.IC2Filter = 15; + if (HAL_TIM_Encoder_Init(&htim4, &sConfig) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM4_Init 2 */ + HAL_TIM_Encoder_Start(&htim4, TIM_CHANNEL_ALL); + /* USER CODE END TIM4_Init 2 */ + +} + +/** + * @brief TIM5 Initialization Function + * @param None + * @retval None + */ +static void MX_TIM5_Init(void) +{ + + /* USER CODE BEGIN TIM5_Init 0 */ + + /* USER CODE END TIM5_Init 0 */ + + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + + /* USER CODE BEGIN TIM5_Init 1 */ + + /* USER CODE END TIM5_Init 1 */ + htim5.Instance = TIM5; + htim5.Init.Prescaler = 15; + htim5.Init.CounterMode = TIM_COUNTERMODE_UP; + htim5.Init.Period = TIM5_ARR_VALUE; + htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_PWM_Init(&htim5) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 0; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM5_Init 2 */ + /* Start motor PWM */ + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_1, 0); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_2, 0); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_3, 0); + __HAL_TIM_SET_COMPARE(&htim5, TIM_CHANNEL_4, 0); + + HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_1); + HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_2); + HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_3); + HAL_TIM_PWM_Start(&htim5, TIM_CHANNEL_4); + /* USER CODE END TIM5_Init 2 */ + HAL_TIM_MspPostInit(&htim5); + +} + +/** + * @brief USART6 Initialization Function + * @param None + * @retval None + */ +static void MX_USART6_UART_Init(void) +{ + + /* USER CODE BEGIN USART6_Init 0 */ + + /* USER CODE END USART6_Init 0 */ + + /* USER CODE BEGIN USART6_Init 1 */ + + /* USER CODE END USART6_Init 1 */ + huart6.Instance = USART6; + huart6.Init.BaudRate = 115200; + huart6.Init.WordLength = UART_WORDLENGTH_8B; + huart6.Init.StopBits = UART_STOPBITS_1; + huart6.Init.Parity = UART_PARITY_NONE; + huart6.Init.Mode = UART_MODE_TX_RX; + huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart6.Init.OverSampling = UART_OVERSAMPLING_16; + if (HAL_UART_Init(&huart6) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN USART6_Init 2 */ + uint8_t rx_byte; + HAL_UART_Receive_IT(&huart6, &rx_byte, 1); + + /* USER CODE END USART6_Init 2 */ + +} + +/** + * Enable DMA controller clock + */ +static void MX_DMA_Init(void) +{ + + /* DMA controller clock enable */ + __HAL_RCC_DMA2_CLK_ENABLE(); + + /* DMA interrupt init */ + /* DMA2_Stream0_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); + /* DMA2_Stream3_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); + +} + +/** + * @brief GPIO Initialization Function + * @param None + * @retval None + */ +static void MX_GPIO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct = {0}; + /* USER CODE BEGIN MX_GPIO_Init_1 */ + + /* USER CODE END MX_GPIO_Init_1 */ + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOA, DISPLAY_CS_Pin|DISPLAY_RES_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(DISPLAY_DC_GPIO_Port, DISPLAY_DC_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin : LED_BLUE_Pin */ + GPIO_InitStruct.Pin = LED_BLUE_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LED_BLUE_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : DISPLAY_CS_Pin DISPLAY_RES_Pin */ + GPIO_InitStruct.Pin = DISPLAY_CS_Pin|DISPLAY_RES_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pin : DISPLAY_DC_Pin */ + GPIO_InitStruct.Pin = DISPLAY_DC_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(DISPLAY_DC_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN MX_GPIO_Init_2 */ + + /* USER CODE END MX_GPIO_Init_2 */ +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/* USER CODE BEGIN Header_start_control */ +/** + * @brief Function implementing the control thread. + * @param argument: Not used + * @retval None + */ +/* USER CODE END Header_start_control */ +void start_control(void *argument) +{ + /* USER CODE BEGIN 5 */ + /* Infinite loop */ + float tempspeed; + + for (;;) { + osDelay(10); + set_pwm(0.1, 'l', 'c'); + + tempspeed=encoder_TIM4_speed_rad(); + } + /* USER CODE END 5 */ +} + +/* USER CODE BEGIN Header_snakegame */ +/** + * @brief Function implementing the draw thread. + * @param argument: Not used + * @retval None + */ +/* USER CODE END Header_snakegame */ +void snakegame(void *argument) +{ + /* USER CODE BEGIN snakegame */ + /* Infinite loop */ + //ILI9341_FillScreen(BLACK); + GameInit(); + + for (;;) { + + if (run_snake) { + GameRender(); + static char statsBuffer[200]; + vTaskGetRunTimeStats(statsBuffer); + + vTaskDelay(300); + + if (isGameOver()) { + vTaskDelay(2000); + GameInit(); + } + UpdateGame(); + } else { + vTaskDelay(10); + } + + } + /* USER CODE END snakegame */ +} + +/* USER CODE BEGIN Header_handle_menu */ +/** + * @brief Function implementing the menu thread. + * @param argument: Not used + * @retval None + */ + +#define CELL_WIDTH 120 // Adjust as needed for your screen +#define CELL_HEIGHT 40 +#define START_X 10 +#define START_Y 10 + +#define COLOR_TEXT BLACK +#define COLOR_BG WHITE +#define COLOR_SELECTED GREEN +#define COLOR_ACTIVATED RED +#define COLOR_ACTIVATED_AND_SELECTED MAGENTA + +int sel_x; +int sel_y; +//redraw_menu_pending is for redrawing + +// Customize grid labels as needed +const char *grid_labels[GRID_X][GRID_Y] = { { "Snake", "Options", "About" }, { + "Highscore", "Credits", "Exit" } }; + +void redraw_menu() { //only done onece saves resources + // Redraw grid + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_FillScreen(WHITE); + osMutexRelease(displayHandle); + } + for (int i = 0; i < GRID_X; i++) { + for (int j = 0; j < GRID_Y; j++) { + uint16_t x = START_X + i * CELL_WIDTH; + uint16_t y = START_Y + j * CELL_HEIGHT; + + uint16_t bg; + if (menu_status[i][j]) { + + if (i == sel_x && j == sel_y) { + bg = COLOR_ACTIVATED_AND_SELECTED; + } else { + bg = COLOR_ACTIVATED; + } + + } else { + if (i == sel_x && j == sel_y) { + bg = COLOR_SELECTED; + } else { + bg = COLOR_BG; + } + + } + + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_DrawText(grid_labels[i][j], FONT2, x, y, COLOR_TEXT, + bg); + osMutexRelease(displayHandle); + } + } + } + +} + +/* USER CODE END Header_handle_menu */ +void handle_menu(void *argument) +{ + /* USER CODE BEGIN handle_menu */ + /* Infinite loop */ + + char dir; + vTaskDelay(50); + redraw_menu(); + while (1) { + + // Check input + if (run_menu) { + osStatus_t status = osMessageQueueGet(pressesHandle, &dir, NULL, + osWaitForever); + if (status == osOK) { + //what was selected? + if (dir == 'A') { + if (grid_labels[sel_x][sel_y] == "Snake") { + run_snake = 1; + run_menu = 0; + } + menu_status[sel_x][sel_y] = !menu_status[sel_x][sel_y]; + } + if (dir == 'U' || dir == 'D' || dir == 'L' || dir == 'R') { + if (menu_status[sel_x][sel_y]) { + ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2, + START_X + sel_x * CELL_WIDTH, + START_Y + sel_y * CELL_HEIGHT, COLOR_TEXT, + COLOR_ACTIVATED); + } else { + ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2, + START_X + sel_x * CELL_WIDTH, + START_Y + sel_y * CELL_HEIGHT, COLOR_TEXT, + COLOR_BG); + } + } + if (dir == 'U' && sel_y > 0) + sel_y--; + else if (dir == 'D' && sel_y < GRID_Y - 1) + sel_y++; + else if (dir == 'L' && sel_x > 0) + sel_x--; + else if (dir == 'R' && sel_x < GRID_X - 1) + sel_x++; + } + if (menu_status[sel_x][sel_y]) { + ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2, + START_X + sel_x * CELL_WIDTH, START_Y + sel_y * CELL_HEIGHT, + COLOR_TEXT, + COLOR_ACTIVATED_AND_SELECTED); + } else { + ILI9341_DrawText(grid_labels[sel_x][sel_y], FONT2, + START_X + sel_x * CELL_WIDTH, START_Y + sel_y * CELL_HEIGHT, + COLOR_TEXT, + COLOR_SELECTED); + } + if (redraw_menu_pending) { + redraw_menu(); + redraw_menu_pending = 0; + } + } + + osDelay(10); + } + /* USER CODE END handle_menu */ +} + +/** + * @brief Period elapsed callback in non blocking mode + * @note This function is called when TIM3 interrupt took place, inside + * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment + * a global variable "uwTick" used as application time base. + * @param htim : TIM handle + * @retval None + */ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* USER CODE BEGIN Callback 0 */ + + /* USER CODE END Callback 0 */ + if (htim->Instance == TIM3) + { + HAL_IncTick(); + } + /* USER CODE BEGIN Callback 1 */ + + /* USER CODE END Callback 1 */ +} + +/** + * @brief This function is executed in case of error occurrence. + * @retval None + */ +void Error_Handler(void) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + __disable_irq(); + while (1) { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t *file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/touchscreengames/Core/Src/script.py b/touchscreengames/Core/Src/script.py new file mode 100644 index 0000000..e3d0391 --- /dev/null +++ b/touchscreengames/Core/Src/script.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 +import evdev +from evdev import InputDevice, categorize, ecodes +import glob +import serial +import time +# Controller +#device_candidates = glob.glob('/dev/input/by-id/usb-8BitDo*-event*') +device_candidates = glob.glob('/dev/input/by-id/usb-8Bit*') +if not device_candidates: + print("Error: No matching 8BitDo input device found.") + sys.exit(1) + +device_path = device_candidates[0] +#device_path = '/dev/input/by-id/usb-8BitDo_8BitDo_Ultimate_Controller_6fdf5bd817e4-event-joystick' #or just put it in + +# UART +serial_port = '/dev/ttyUSB0' +baudrate = 115200 + + +device = InputDevice(device_path) +print(f"Listening on {device.name} ({device_path})") + +ser = serial.Serial(serial_port, baudrate, timeout=1) +print(f"UART opened on {serial_port} at {baudrate} bps") + +# diganostic time stamps +def timestamp_ms(): + return int(time.time() * 1000) + +import select + +button_map = { + 'BTN_SOUTH': 'B', + 'BTN_EAST': 'A', + 'BTN_NORTH': 'Y', + 'BTN_WEST': 'X', +} +try: + while True: + r, w, x = select.select([device.fd], [], [], 0.005) # timeout = 10ms + if device.fd in r: + for event in device.read(): + ts = timestamp_ms() + if event.type == ecodes.EV_KEY: + key_event = categorize(event) + k = key_event.keycode + if isinstance(k, tuple): + name = next((button_map[x] for x in k if x in button_map), str(k)) + else: + name = button_map.get(k, k) + + msg = f"KEY:{name}:{key_event.keystate}\n" + ser.write(msg.encode('utf-8')) + print(f"[{ts}] Sent: {msg.strip()}") + + elif event.type == ecodes.EV_ABS: + axis = ecodes.ABS.get(event.code, f"ABS_{event.code}") + val = event.value + if axis == 'ABS_HAT0Y' or axis == 'ABS_HAT0X': + if axis == 'ABS_HAT0Y': + if val == -1: + ser.write(b"KEY:U:1\r\n") + print(f"[{ts}] Sent: KEY:U:1:") + elif val == 1: + ser.write(b"KEY:D:1\r\n") + print(f"[{ts}] Sent: KEY:D:1:") + elif val == 0: + #ser.write(b"KEY:U:0\r\nKEY:D:0\r\n") + print(f"[{ts}] Sent: KEY:U:0\n[{ts}] Sent: KEY:D:0") + elif axis == 'ABS_HAT0X': + if val == -1: + ser.write(b"KEY:L:1\r\n") + print(f"[{ts}] Sent: KEY:L:1:") + elif val == 1: + ser.write(b"KEY:R:1\r\n") + print(f"[{ts}] Sent: KEY:R:1:") + elif val == 0: + #ser.write(b"KEY:L:0\r\nKEY:R:0\r\n") + print(f"[{ts}] Sent: KEY:L:0\n[{ts}] Sent: KEY:R:0") + else: + msg = f"ABS:{axis}:{event.value}:\r\n" + ser.write(msg.encode('utf-8')) + print(f"[{ts}] Sent: {msg.strip()}") + +except KeyboardInterrupt: + print("\nExiting...") + +finally: + ser.close() + print("UART closed.") diff --git a/touchscreengames/Core/Src/snake.c b/touchscreengames/Core/Src/snake.c new file mode 100644 index 0000000..40aca6b --- /dev/null +++ b/touchscreengames/Core/Src/snake.c @@ -0,0 +1,285 @@ +#include "main.h" // HAL, ILI9341, CMSIS-RTOS handles +#include "cmsis_os.h" // RTOS types like osMutexAcquire, osMessageQueueGet +#include "stdlib.h" // For rand() +#include "stdio.h" // For sprintf() +#include "snake.h" // Your own header for declarations +#include "ILI9341_STM32_Driver.h" +#include "fonts.h" + +struct Snake snake; // define the global variable here +#define FLASH_USER_ADDR ((uint32_t)0x0803F000) // Last 4 KB +void Flash_Write_HighScore(uint32_t highscore) { + HAL_FLASH_Unlock(); + + // Erase the sector first + FLASH_EraseInitTypeDef EraseInitStruct; + uint32_t PageError = 0; + + EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; + EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; + EraseInitStruct.Sector = FLASH_SECTOR_5; + EraseInitStruct.NbSectors = 1; + + if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK) { + // Handle error + return; + } + + // Program the word + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FLASH_USER_ADDR, highscore) + != HAL_OK) { + // Handle error + } + + HAL_FLASH_Lock(); +} +uint32_t Flash_Read_HighScore(void) { + return *(uint32_t*) FLASH_USER_ADDR; +} + + +// Function to initialize game variables +void GameInit() { + + snake.gamesizeheight = 6; + snake.gamesizewidth = 8; + snake.isGameOver = 0; + snake.Dir = RIGHT; + snake.x = 1; //snake.gamesizewidth / 2; + snake.y = 1; //snake.gamesizeheight / 2; + snake.fruitCordX = rand() % snake.gamesizewidth; + snake.fruitCordY = rand() % snake.gamesizeheight; + snake.playerScore = 0; + snake.TailLen = 0; + snake.TailGrowPending = 0; + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_FillScreen(WHITE); + osMutexRelease(displayHandle); + } +} +// Function for updating the game state +void UpdateGame() { + + char dir; +// check the queue non blocking + osStatus_t status = osMessageQueueGet(pressesHandle, &dir, NULL, 0); // 0 = no wait + + if (status == osOK) { + switch (dir) { + case 'L': + snake.Dir = LEFT; + break; + case 'R': + snake.Dir = RIGHT; + break; + case 'U': + snake.Dir = UP; + break; + case 'D': + snake.Dir = DOWN; + break; + } + } + if (!snake.TailGrowPending) { + if (snake.TailLen > 0) { + snake.TailPendingDeletionX = snake.TailX[snake.TailLen - 1]; + snake.TailPendingDeletionY = snake.TailY[snake.TailLen - 1]; + } else { + snake.TailPendingDeletionX = snake.x; + snake.TailPendingDeletionY = snake.y; + } + } + snake.TailGrowPending = 0; + // tail movement + if (snake.TailLen > 0) { + for (int i = snake.TailLen - 1; i > 0; i--) { + snake.TailX[i] = snake.TailX[i - 1]; + snake.TailY[i] = snake.TailY[i - 1]; + } + snake.TailX[0] = snake.x; + snake.TailY[0] = snake.y; + } + + switch (snake.Dir) { + case LEFT: + snake.x--; + break; + case RIGHT: + snake.x++; + break; + case UP: + snake.y--; + break; + case DOWN: + snake.y++; + break; + } + +// Checks for snake's collision with the wall + if (snake.x >= snake.gamesizewidth || snake.x < 0 + || snake.y >= snake.gamesizeheight || snake.y < 0) + snake.isGameOver = 1; + +// Checks for collision with the tail (o) + for (int i = 0; i < snake.TailLen; i++) { + if (snake.TailX[i] == snake.x && snake.TailY[i] == snake.y) + snake.isGameOver = 1; + } + +// Checks for snake's collision with the food (#) + if (snake.x == snake.fruitCordX && snake.y == snake.fruitCordY) { + snake.playerScore += 10; + snake.fruitCordX = rand() % snake.gamesizewidth; + snake.fruitCordY = rand() % snake.gamesizeheight; + snake.TailLen++; + snake.TailX[snake.TailLen - 1] = snake.x; + snake.TailY[snake.TailLen - 1] = snake.y; + snake.TailGrowPending = 1; + //snake.TailPendingDeletionX = -1; + } + if (snake.isGameOver) { + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + + if (Flash_Read_HighScore() > snake.playerScore) { + char str[50]; + sprintf(str, "Highscore Remains: %lu", Flash_Read_HighScore()); + ILI9341_DrawText(str, FONT3, 320 / 2 - 70, 240 / 2, BLACK, + WHITE); + // ILI9341_WriteString(320 / 2 - 70, 240 / 2, str, Font_11x18, + //ILI9341_MAGENTA, ILI9341_WHITE); + } else { + char str[50]; + sprintf(str, "New Highscore: %lu", snake.playerScore); + //ILI9341_WriteString(320 / 2 - 70, 240 / 2, str, Font_11x18, + //ILI9341_MAGENTA, ILI9341_WHITE); + ILI9341_DrawText(str, FONT3, 320 / 2 - 70, 240 / 2, BLACK, + WHITE); + Flash_Write_HighScore(snake.playerScore); + } + osMutexRelease(displayHandle); + + } + + } +} + +// Function for creating the game board & rendering +void GameRender() { + +// Creating top walls +// Creating side walls +//ILI9341_FillRectangle(j, i, ILI9341_WIDTH/snake.gamesizewidth, ILI9341_HEIGHT/snake.gamesizeheight, ILI9341_YELLOW); +//ILI9341_FillScreen(MAGENTA); + for (int x = 0; x < snake.gamesizewidth; x++) { + for (int y = 0; y <= snake.gamesizeheight; y++) { + + if (x == snake.x && y == snake.y) { + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_DrawFilledRectangleCoord( + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight, + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth + + ILI9341_SCREEN_WIDTH + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight + + ILI9341_SCREEN_HEIGHT + / snake.gamesizeheight, + BLACK); +// ILI9341_FillRectangle( +// (x * ILI9341_WIDTH) / snake.gamesizewidth, +// (y * ILI9341_HEIGHT) / snake.gamesizeheight, +// ILI9341_WIDTH / snake.gamesizewidth, +// ILI9341_HEIGHT / snake.gamesizeheight, +// ILI9341_BLACK); + osMutexRelease(displayHandle); + } + } + + //cout << "O"; + // Creating the sanke's food with '#' + else if (x == snake.fruitCordX && y == snake.fruitCordY) { + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_DrawFilledRectangleCoord( + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight, + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth + + ILI9341_SCREEN_WIDTH + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight + + ILI9341_SCREEN_HEIGHT + / snake.gamesizeheight, + RED); +// ILI9341_FillRectangle( +// (x * ILI9341_WIDTH) / snake.gamesizewidth, +// (y * ILI9341_HEIGHT) / snake.gamesizeheight, +// ILI9341_WIDTH / snake.gamesizewidth, +// ILI9341_HEIGHT / snake.gamesizeheight, ILI9341_RED); + osMutexRelease(displayHandle); + } + } + + //cout << "#"; + + else if (snake.TailLen >= 0) { + for (int i = 0; i < snake.TailLen; i++) { + + if (snake.TailX[0] == x && snake.TailY[0] == y) { + if (osMutexAcquire(displayHandle, osWaitForever) + == osOK) { + ILI9341_DrawFilledRectangleCoord( + (x * ILI9341_SCREEN_WIDTH) + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) + / snake.gamesizeheight, + (x * ILI9341_SCREEN_WIDTH) + / snake.gamesizewidth + + ILI9341_SCREEN_WIDTH + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) + / snake.gamesizeheight + + ILI9341_SCREEN_HEIGHT + / snake.gamesizeheight, + GREEN); +// ILI9341_FillRectangle( +// (x * ILI9341_WIDTH) / snake.gamesizewidth, +// (y * ILI9341_HEIGHT) / snake.gamesizeheight, +// ILI9341_WIDTH / snake.gamesizewidth, +// ILI9341_HEIGHT / snake.gamesizeheight, +// ILI9341_GREEN); + osMutexRelease(displayHandle); + } + } + } + + } + if (snake.TailPendingDeletionX == x + && snake.TailPendingDeletionY == y) { + + if (osMutexAcquire(displayHandle, osWaitForever) == osOK) { + ILI9341_DrawFilledRectangleCoord( + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight, + (x * ILI9341_SCREEN_WIDTH) / snake.gamesizewidth + + ILI9341_SCREEN_WIDTH + / snake.gamesizewidth, + (y * ILI9341_SCREEN_HEIGHT) / snake.gamesizeheight + + ILI9341_SCREEN_HEIGHT + / snake.gamesizeheight, + WHITE); +// ILI9341_FillRectangle( +// (x * ILI9341_WIDTH) / snake.gamesizewidth, +// (y * ILI9341_HEIGHT) / snake.gamesizeheight, +// ILI9341_WIDTH / snake.gamesizewidth, +// ILI9341_HEIGHT / snake.gamesizeheight, +// ILI9341_WHITE); + osMutexRelease(displayHandle); + } + } + } + + } + +} +int isGameOver(){ + return snake.isGameOver; +} diff --git a/touchscreengames/Core/Src/snake.h b/touchscreengames/Core/Src/snake.h new file mode 100644 index 0000000..69ffe54 --- /dev/null +++ b/touchscreengames/Core/Src/snake.h @@ -0,0 +1,54 @@ +/* + * snake.h + * + * Created on: Jul 10, 2025 + * Author: user + */ + +#ifndef SRC_SNAKE_H_ +#define SRC_SNAKE_H_ + + +#include "main.h" +extern osMutexId_t displayHandle; +extern osMessageQueueId_t pressesHandle; +// Flash storage address for highscore +#define FLASH_USER_ADDR ((uint32_t)0x0803F000) // Adjusted to your sector layout + +// Highscore flash functions +void Flash_Write_HighScore(uint32_t highscore); +uint32_t Flash_Read_HighScore(void); + +// Snake movement direction enum +enum Direction { + STOP = 0, LEFT, RIGHT, UP, DOWN +}; + +// Snake structure definition +struct Snake { + int x, y; + int fruitCordX, fruitCordY; + int playerScore; + int TailX[100], TailY[100]; + int TailLen; + enum Direction Dir; + int gamesizewidth; + int gamesizeheight; + int TailPendingDeletionX; + int TailPendingDeletionY; + int TailGrowPending; + int isGameOver; +}; + +// External instance of the snake object +extern struct Snake snake; + + +// Game functions +void GameInit(void); +void UpdateGame(void); +void GameRender(void); +int isGameOver(); + + +#endif /* SRC_SNAKE_H_ */ diff --git a/touchscreengames/Core/Src/stm32f4xx_it.c b/touchscreengames/Core/Src/stm32f4xx_it.c new file mode 100644 index 0000000..78ca51c --- /dev/null +++ b/touchscreengames/Core/Src/stm32f4xx_it.c @@ -0,0 +1,237 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file stm32f4xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * @attention + * + * Copyright (c) 2025 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" +#include "stm32f4xx_it.h" +/* Private includes ----------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ +/* USER CODE END Includes */ + +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN TD */ + +/* USER CODE END TD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ +/* USER CODE BEGIN PV */ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +/* USER CODE BEGIN PFP */ + +/* USER CODE END PFP */ + +/* Private user code ---------------------------------------------------------*/ +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ +extern DMA_HandleTypeDef hdma_spi1_rx; +extern DMA_HandleTypeDef hdma_spi1_tx; +extern SPI_HandleTypeDef hspi1; +extern UART_HandleTypeDef huart6; +extern TIM_HandleTypeDef htim3; + +/* USER CODE BEGIN EV */ + +/* USER CODE END EV */ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ +/** + * @brief This function handles Non maskable interrupt. + */ +void NMI_Handler(void) +{ + /* USER CODE BEGIN NonMaskableInt_IRQn 0 */ + + /* USER CODE END NonMaskableInt_IRQn 0 */ + /* USER CODE BEGIN NonMaskableInt_IRQn 1 */ + while (1) { + } + /* USER CODE END NonMaskableInt_IRQn 1 */ +} + +/** + * @brief This function handles Hard fault interrupt. + */ +void HardFault_Handler(void) +{ + /* USER CODE BEGIN HardFault_IRQn 0 */ + + /* USER CODE END HardFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_HardFault_IRQn 0 */ + /* USER CODE END W1_HardFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Memory management fault. + */ +void MemManage_Handler(void) +{ + /* USER CODE BEGIN MemoryManagement_IRQn 0 */ + + /* USER CODE END MemoryManagement_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */ + /* USER CODE END W1_MemoryManagement_IRQn 0 */ + } +} + +/** + * @brief This function handles Pre-fetch fault, memory access fault. + */ +void BusFault_Handler(void) +{ + /* USER CODE BEGIN BusFault_IRQn 0 */ + + /* USER CODE END BusFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_BusFault_IRQn 0 */ + /* USER CODE END W1_BusFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Undefined instruction or illegal state. + */ +void UsageFault_Handler(void) +{ + /* USER CODE BEGIN UsageFault_IRQn 0 */ + + /* USER CODE END UsageFault_IRQn 0 */ + while (1) + { + /* USER CODE BEGIN W1_UsageFault_IRQn 0 */ + /* USER CODE END W1_UsageFault_IRQn 0 */ + } +} + +/** + * @brief This function handles Debug monitor. + */ +void DebugMon_Handler(void) +{ + /* USER CODE BEGIN DebugMonitor_IRQn 0 */ + + /* USER CODE END DebugMonitor_IRQn 0 */ + /* USER CODE BEGIN DebugMonitor_IRQn 1 */ + + /* USER CODE END DebugMonitor_IRQn 1 */ +} + +/******************************************************************************/ +/* STM32F4xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32f4xx.s). */ +/******************************************************************************/ + +/** + * @brief This function handles TIM3 global interrupt. + */ +void TIM3_IRQHandler(void) +{ + /* USER CODE BEGIN TIM3_IRQn 0 */ + + /* USER CODE END TIM3_IRQn 0 */ + HAL_TIM_IRQHandler(&htim3); + /* USER CODE BEGIN TIM3_IRQn 1 */ + + /* USER CODE END TIM3_IRQn 1 */ +} + +/** + * @brief This function handles SPI1 global interrupt. + */ +void SPI1_IRQHandler(void) +{ + /* USER CODE BEGIN SPI1_IRQn 0 */ + + /* USER CODE END SPI1_IRQn 0 */ + HAL_SPI_IRQHandler(&hspi1); + /* USER CODE BEGIN SPI1_IRQn 1 */ + + /* USER CODE END SPI1_IRQn 1 */ +} + +/** + * @brief This function handles DMA2 stream0 global interrupt. + */ +void DMA2_Stream0_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */ + + /* USER CODE END DMA2_Stream0_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_spi1_rx); + /* USER CODE BEGIN DMA2_Stream0_IRQn 1 */ + + /* USER CODE END DMA2_Stream0_IRQn 1 */ +} + +/** + * @brief This function handles DMA2 stream3 global interrupt. + */ +void DMA2_Stream3_IRQHandler(void) +{ + /* USER CODE BEGIN DMA2_Stream3_IRQn 0 */ + + /* USER CODE END DMA2_Stream3_IRQn 0 */ + HAL_DMA_IRQHandler(&hdma_spi1_tx); + /* USER CODE BEGIN DMA2_Stream3_IRQn 1 */ + + /* USER CODE END DMA2_Stream3_IRQn 1 */ +} + +/** + * @brief This function handles USART6 global interrupt. + */ +void USART6_IRQHandler(void) +{ + /* USER CODE BEGIN USART6_IRQn 0 */ + + /* USER CODE END USART6_IRQn 0 */ + HAL_UART_IRQHandler(&huart6); + /* USER CODE BEGIN USART6_IRQn 1 */ + //UART_CALLBACK(); + /* USER CODE END USART6_IRQn 1 */ +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */