diff options
Diffstat (limited to 'source/hal/profiles/bare-metal/data_presentation/lcd/lcd_img.c')
-rw-r--r-- | source/hal/profiles/bare-metal/data_presentation/lcd/lcd_img.c | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/source/hal/profiles/bare-metal/data_presentation/lcd/lcd_img.c b/source/hal/profiles/bare-metal/data_presentation/lcd/lcd_img.c new file mode 100644 index 0000000..f03566f --- /dev/null +++ b/source/hal/profiles/bare-metal/data_presentation/lcd/lcd_img.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 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 + * + * http://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. + */ +#include "lcd_img.h" + +#include "bsp.h" + +#include <string.h> +#include <assert.h> + +static int show_title(void) +{ + char title[128]; + int status = 0; + + /* LCD title string */ +#if defined(CPU_CORTEX_M55) + const char* cpu_name = "Arm Cortex-M55"; +#else /* defined(CPU_CORTEX_M55) */ + const char* cpu_name = "Arm CPU"; +#endif /* defined(CPU_CORTEX_M55) */ + + lcd_set_text_color(White); + + /* First line */ + snprintf(title, sizeof(title), "Arm ML embedded code samples"); + + if (0 != (status = lcd_display_text( + title, strlen(title), 10, 0, false))) { + return status; + } + + /* Second line */ +#if defined (ARM_NPU) + snprintf(title, sizeof(title), "%s + Arm Ethos-U NPU", cpu_name); +#else /* defined (ARM_NPU) */ + snprintf(title, sizeof(title), "%s", cpu_name); +#endif /* defined (ARM_NPU) */ + + return lcd_display_text(title, strlen(title), 10, 20, false); +} + +int lcd_init(void) +{ + GLCD_Initialize(); + GLCD_Clear(Black); + return show_title(); +} + +int lcd_display_image(uint8_t* data, const uint32_t width, + const uint32_t height, const uint32_t channels, + const uint32_t pos_x, const uint32_t pos_y, + const uint32_t downsample_factor) +{ + /* Sanity checks */ + assert(data); + if ((pos_x + width/downsample_factor > GLCD_WIDTH) || + (pos_y + height/downsample_factor > GLCD_HEIGHT)) { + printf_err("Invalid image size for given location!\n"); + return 1; + } + + if (1 == channels || 3 == channels) { + GLCD_Image(data, width, height, channels, pos_x, pos_y, + downsample_factor); + } else { + printf_err("Only single and three channel images are supported!\n"); + return 1; + } + + return 0; +} + +int lcd_display_text(const char* str, const size_t str_sz, + const uint32_t pos_x, const uint32_t pos_y, + const bool allow_multiple_lines) +{ + /* We use a font 0 which is 9x15. */ + const uint32_t x_span = 9; /* Each character is this 9 pixels "wide". */ + const uint32_t y_span = 15; /* Each character is this 15 pixels "high". */ + + if (str_sz == 0) { + return 1; + } + + /* If not within the LCD bounds, return error. */ + if (pos_x + x_span > GLCD_WIDTH || pos_y + y_span > GLCD_HEIGHT) { + return 1; + } else { + const unsigned char font_idx = 0; /* We are using the custom font = 0 */ + + const uint32_t col = pos_x/x_span; + const uint32_t max_cols = GLCD_WIDTH/x_span - 1; + const uint32_t max_lines = GLCD_HEIGHT/y_span - 1; + + uint32_t i = 0; + uint32_t current_line = pos_y/y_span; + uint32_t current_col = col; + + /* Display the string on the LCD. */ + for (i = 0; i < str_sz; ++i) { + + if (allow_multiple_lines) { + + /* If the next character won't fit. */ + if (current_col > max_cols) { + current_col = col; + + /* If the next line won't fit. */ + if (++current_line > max_lines) { + return 1; + } + } + } + + GLCD_DisplayChar(current_line, current_col++, font_idx, str[i]); + } + } + return 0; +} + +int lcd_display_box(const uint32_t pos_x, const uint32_t pos_y, + const uint32_t width, const uint32_t height, const uint16_t color) +{ + /* If not within the LCD bounds, return error. */ + if (pos_x > GLCD_WIDTH || pos_y > GLCD_HEIGHT) { + return 1; + } + else { + GLCD_Box(pos_x, pos_y, width, height, color); + } + return 0; +} + +int lcd_clear(const uint16_t color) +{ + GLCD_Clear(color); + GLCD_SetTextColor(White); + return show_title(); +} + +int lcd_set_text_color(const uint16_t color) +{ + GLCD_SetTextColor(color); + return 0; +} |