/* * Copyright (c) 2009-2021 Arm Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*============================ INCLUDES ======================================*/ #include #include #include #include #include #include #define GLCD_WIDTH LCD_WIDTH #define GLCD_HEIGHT LCD_HEIGHT #include "lcd_printf.h" #include "lcd_fonts.h" #include "arm_2d.h" #if defined(__clang__) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wformat-nonliteral" # pragma clang diagnostic ignored "-Wsign-compare" # pragma clang diagnostic ignored "-Wmissing-prototypes" # pragma clang diagnostic ignored "-Wcast-qual" # pragma clang diagnostic ignored "-Wsign-conversion" #endif /*============================ MACROS ========================================*/ #define GLCD_COLOR_BLACK 0x0000 /* 0, 0, 0 */ #define GLCD_COLOR_GREEN 0x07E0 /* 0, 255, 0 */ /*============================ MACROFIED FUNCTIONS ===========================*/ /*============================ TYPES =========================================*/ /*============================ GLOBAL VARIABLES ==============================*/ extern const uint8_t Font_6x8_h[(144-32)*8]; extern const GLCD_FONT GLCD_Font_16x24; extern const GLCD_FONT GLCD_Font_6x8; /*============================ PROTOTYPES ====================================*/ /*============================ LOCAL VARIABLES ===============================*/ static struct { arm_2d_region_t tRegion; struct { uint8_t chX; uint8_t chY; } tTextLocation; } s_tLCDTextControl = { .tRegion = { .tSize = { .iWidth = GLCD_WIDTH, .iHeight = GLCD_HEIGHT, }, }, }; /*============================ IMPLEMENTATION ================================*/ void lcd_text_location(uint8_t chY, uint8_t chX) { s_tLCDTextControl.tTextLocation.chX = chX; s_tLCDTextControl.tTextLocation.chY = chY; if ( s_tLCDTextControl.tTextLocation.chX * GLCD_Font_6x8.width >= s_tLCDTextControl.tRegion.tSize.iWidth ) { s_tLCDTextControl.tTextLocation.chX = 0; s_tLCDTextControl.tTextLocation.chY++; if ( s_tLCDTextControl.tTextLocation.chY * GLCD_Font_6x8.height >= s_tLCDTextControl.tRegion.tSize.iHeight) { s_tLCDTextControl.tTextLocation.chY = 0; } } } static void lcd_draw_char(int16_t iX, int16_t iY, char chChar) { //! use default frame buffer arm_2d_tile_t *ptFrameBuffer = (arm_2d_tile_t *) -1; const static arm_2d_tile_t s_tileFont6x8 = { .tRegion = { .tSize = { .iWidth = 6, .iHeight = 8 * 112, }, }, .tInfo = { .bIsRoot = true, .bHasEnforcedColour = true, .tColourInfo = { .chScheme = ARM_2D_COLOUR_BIN, }, }, .pchBuffer = (uint8_t *)Font_6x8_h, }; static arm_2d_tile_t s_tileChar = { .tRegion = { .tSize = { .iWidth = 6, .iHeight = 8, }, }, .ptParent = (arm_2d_tile_t *)&s_tileFont6x8, }; s_tileChar.tRegion.tLocation.iY = (chChar - (int16_t)GLCD_Font_6x8.offset) * 8; arm_2d_region_t tDrawRegion = { .tLocation = {.iX = iX, .iY = iY}, .tSize = s_tileChar.tRegion.tSize, }; arm_2d_rgb16_draw_pattern( &s_tileChar, ptFrameBuffer, &tDrawRegion, ARM_2D_DRW_PATN_MODE_COPY //| ARM_2D_DRW_PATN_MODE_NO_FG_COLOR //| ARM_2D_DRW_PATN_MODE_WITH_BG_COLOR //| ARM_2D_DRW_PATH_MODE_COMP_FG_COLOUR , GLCD_COLOR_GREEN, GLCD_COLOR_BLACK); } void lcd_puts(const char *str) { while(*str) { if (*str == '\r') { s_tLCDTextControl.tTextLocation.chX = 0; } else if (*str == '\n') { s_tLCDTextControl.tTextLocation.chX = 0; s_tLCDTextControl.tTextLocation.chY++; } else if (*str == '\t') { s_tLCDTextControl.tTextLocation.chX += 8; s_tLCDTextControl.tTextLocation.chX &= ~(_BV(3)-1); if ( s_tLCDTextControl.tTextLocation.chX * GLCD_Font_6x8.width >= s_tLCDTextControl.tRegion.tSize.iWidth ) { s_tLCDTextControl.tTextLocation.chX = 0; s_tLCDTextControl.tTextLocation.chY++; } }else if (*str == '\b') { if (s_tLCDTextControl.tTextLocation.chX) { s_tLCDTextControl.tTextLocation.chX--; } } else { int16_t iX = s_tLCDTextControl.tTextLocation.chX * GLCD_Font_6x8.width; int16_t iY = s_tLCDTextControl.tTextLocation.chY * GLCD_Font_6x8.height; lcd_draw_char( s_tLCDTextControl.tRegion.tLocation.iX + iX, iY, *str); s_tLCDTextControl.tTextLocation.chX++; if ( s_tLCDTextControl.tTextLocation.chX * GLCD_Font_6x8.width >= s_tLCDTextControl.tRegion.tSize.iWidth ) { s_tLCDTextControl.tTextLocation.chX = 0; s_tLCDTextControl.tTextLocation.chY++; if ( s_tLCDTextControl.tTextLocation.chY * GLCD_Font_6x8.height >= s_tLCDTextControl.tRegion.tSize.iHeight) { s_tLCDTextControl.tTextLocation.chY = 0; } } } str++; } } int lcd_printf(const char *format, ...) { int real_size; static char s_chBuffer[MAX(((GLCD_WIDTH/6)+1), 54)]; __va_list ap; va_start(ap, format); real_size = vsnprintf(s_chBuffer, sizeof(s_chBuffer)-1, format, ap); va_end(ap); real_size = MIN(sizeof(s_chBuffer)-1, real_size); s_chBuffer[real_size] = '\0'; lcd_puts(s_chBuffer); return real_size; } #if defined(__clang__) # pragma clang diagnostic pop #endif