diff options
Diffstat (limited to 'source/hal/profiles/bare-metal/data_presentation')
3 files changed, 295 insertions, 0 deletions
diff --git a/source/hal/profiles/bare-metal/data_presentation/data_psn.c b/source/hal/profiles/bare-metal/data_presentation/data_psn.c new file mode 100644 index 0000000..474d552 --- /dev/null +++ b/source/hal/profiles/bare-metal/data_presentation/data_psn.c @@ -0,0 +1,46 @@ +/* + * 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 "data_psn.h" + +#include "bsp.h" +#include "lcd_img.h" + +#include <assert.h> +#include <string.h> + +int data_psn_system_init(data_psn_module* module) +{ + assert(module); + + /* LCD output supported. */ + module->system_init = lcd_init; + module->present_data_image = lcd_display_image; + module->present_data_text = lcd_display_text; + module->present_box = lcd_display_box; + module->set_text_color = lcd_set_text_color; + module->clear = lcd_clear; + strncpy(module->system_name, "lcd", sizeof(module->system_name)); + module->inited = !module->system_init(); + return !module->inited; +} + +int data_psn_system_release(data_psn_module* module) +{ + assert(module); + module->inited = 0; + return 0; +} diff --git a/source/hal/profiles/bare-metal/data_presentation/lcd/include/lcd_img.h b/source/hal/profiles/bare-metal/data_presentation/lcd/include/lcd_img.h new file mode 100644 index 0000000..e4ad791 --- /dev/null +++ b/source/hal/profiles/bare-metal/data_presentation/lcd/include/lcd_img.h @@ -0,0 +1,90 @@ +/* + * 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. + */ +#ifndef LCD_IMG_H +#define LCD_IMG_H + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> + +/** + * @brief Initialise the LCD + * @return 0 if successful, error code otherwise. + **/ +int lcd_init(void); + +/** + * @brief Display a given image on the LCD. This allows displaying 8 bit + * single or multi-channel images on the LCD. + * @param[in] data Pointer to start of the image. + * @param[in] width Width of this image. + * @param[in] height Image height. + * @param[in] channels Number of channels. + * @param[in] pos_x Screen position x co-ordinate. + * @param[in] pos_y Screen position y co-ordinate. + * @param[in] downsample_factor Factor by which the image needs to be + * downsampled. + * @return 0 if successful, non-zero otherwise. + **/ +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); + +/** + * @brief Display a given image on the LCD. This allows displaying 8 bit + * single or multi-channel images on the LCD. + * @param[in] str Pointer to a null terminated string. + * @param[in] str_sz Length of the string. + * @param[in] pos_x Screen position x co-ordinate. + * @param[in] pos_y Screen position y co-ordinate. + * @param[in] allow_multiple_lines The function will try and spread + * the string into multiple lines if + * they don't fit in one. + * @return 0 if successful, non-zero otherwise. + **/ +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); + +/** + * @brief Display a box with given color on LCD. + * @param[in] pos_x Screen position x co-ordinate. + * @param[in] pos_y Screen position y co-ordinate. + * @param[in] width Width. + * @param[in] height Height. + * @param[in] color Fill color. + * @return 0 if successful, non-zero otherwise. + **/ +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); + +/** + * @brief Clear LCD. + * @param[in] color Fill color. + * @return 0 if successful, non-zero otherwise. + **/ +int lcd_clear(const uint16_t color); + +/** + * @brief Set text color. + * @param[in] color Fill color. + * @return 0 if successful, non-zero otherwise. + **/ +int lcd_set_text_color(const uint16_t color); + +#endif /* LCD_IMG_H */ 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; +} |