diff --git a/.gitignore b/.gitignore index e818d98..b762c35 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,18 @@ *.out *.app +# Log files +*.log + +# Metadata directories +.metadata/ +project/.metadata + +# Test files +project/Core/Inc/stlogo.h +project/Core/Inc/test_img.h +project/Core/Inc/test_data.h + project/Debug/ project/.idea/ @@ -43,4 +55,6 @@ project/.mxproject project/project.launch -project/.cproject \ No newline at end of file +project/Scripts +Scripts/ +project/project\ Debug.launch \ No newline at end of file diff --git a/docs/lcd_api.md b/docs/lcd_api.md new file mode 100644 index 0000000..32c46ae --- /dev/null +++ b/docs/lcd_api.md @@ -0,0 +1,92 @@ +# LCD API + +## Introduction + +The LCD API can be used to display BMP images or text onto the LCD screen. +At the moment of writing, only BMP's in C array's are supported. +Supported color schemes for BMP's are ARGB8888, RGB565, RGB888. +Displayed text that is exceeds the LCD width size, will be wrapped onto the next line and a '-' character will be injected if the wrap occurs within a word. + +## Usage of LCD API +### Generating BMP C header files +#### Resizing images +To resize an image to the desired size (width and height), one can use an image editor such as Photoshop, GIMP, ImageMagick, ... . + +For example, using ImageMagick: +```bash +convert in.png -resize 10% BMP3:out.bmp +#OR (depending on the version of ImageMagick) +magick in.png -resize 50x50 out.png +``` + +The resize option can both be used to resize in percentages or in pixels. + +The BMP3 option is used to convert the PNG to Bitmap version 3.0 (note that the BMP header will still be present in the output image). + +#### Generating the C array +To easily generate a BMP C array (in the desired color scheme) from an image, [lv_img_conv](https://github.com/lvgl/lv_img_conv) can be used. + +See the installation instructions on Github or use the [online version](https://lvgl.io/tools/imageconverter). + +Example: +```bash +./lv_img_conv.js test.png -f -c CF_TRUE_COLOR +``` + +The command above will generate a .c file in which arrays can be found for RGB332, RGB565, ARGB8888. It is also possible to generate a binary BMP image file in ARGB8332, ARGB8565, ARGB8565_RBSWAP, ARGB8888. +```bash +./lv_img_conv.js logo_lvgl.png -f -c CF_TRUE_COLOR -t bin --binary-format ARGB8888 +``` + +### Using the LCD API +#### Initialization of LCD API +The `lcd_init(bool bl_on)` function initialises the LCD screen. The `bl_on` variable allows to enable or disable the LCD backlight. +```c +#include "lcd_api.h" + +... + +void main(void) { + ... + lcd_init(true); + ... +} +``` + +#### Drawing text on the screen + +```c +void lcd_display_text(const char* text, uint16_t x_pos, uint16_t y_pos, uint32_t color, uint32_t bg_color, sFONT *font); +``` + +```c +#include "lcd_api.h" + +... + +void main(void) { + ... + lcd_init(true); + ... + lcd_display_text("This is a text string.", 10, 10, LCD_GREEN, LCD_BLACK, LCD_FONT16); +} +``` +Display text on the LCD screen in a certain color. When text width exceeds BSP_LCD_GetXSize(), a text wrap will be performed. If the text wrap is between two will be injected. + +#### Drawing a BMP (C-array) onto the screen +```c +void lcd_draw_bmp(const void* p_src, uint32_t x_pos, uint32_t y_pos, uint32_t x_size, uint32_t y_size, uint32_t color_mode); +``` + +```c +#include "lcd_api.h" +#include "test_image.h" + +void main(void) { + ... + lcd_init(true); + ... + lcd_draw_bmp(bmp_array, 0, 0, 50, 50, LCD_ARGB8888); +} +``` +Draw BMP image from C array to the LCD screen at position X, Y. In color mode ARGB8888, RGB888, RGB565 or ARGB1555 Supports ARGB8888, RGB565, RGB888 (see LCD_* defines in header file). diff --git a/docs/llfs.md b/docs/llfs.md index eac7c21..2fa6986 100644 --- a/docs/llfs.md +++ b/docs/llfs.md @@ -1,17 +1,52 @@ # LLFS (Linked List File System) ## Introduction -The llfs filesystem can be generated using the mkllfss utility. -It is a simple filesystem that uses a linked list to store files. -The filesystem is stored in a single c file (`llfs_data.c`), which can be compiled and read by the llfs library. -The llfs filesystem is a flat filesystem, meaning that it does not support directories. +The llfs filesystem can be generated using the [mkllfs](mkllfs.md) utility. +The resulting C file encapsulates the filesystem data within a linked list which can be used by the llfs library. + +As a flat filesystem, llfs lacks support for directories. +Using the llfs API, information about the files in the filesystem can be retrieved, +and the files can be read using direct memory access. +Alternatively, the POSIX file functions can be used. +But this is more resource intensive, as data must be copied before using it. + +It's essential to note that the llfs filesystem operates in a read-only mode, +restricting operations solely to read functions. + +## Table of contents + - [Introduction](#introduction) + - [Table of contents](#table-of-contents) + - [Initialization](#initialization) + - [Usage of the llfs API](#usage-of-the-llfs-api) + - [The `llfs_file_t` struct](#the-llfs_file_t-struct) + - [Getting a list of files](#getting-a-list-of-files) + - [Iterator function (not recommended)](#iterator-function-not-recommended) + - [Reading a file](#reading-a-file) + - [Getting the number of files](#getting-the-number-of-files) + - [Using the POSIX file functions](#using-the-posix-file-functions) + +## Initialization +Before using the llfs API, or the file related POSIX (fopen, fgetc, ...) functions, the filesystem must be initialized by calling `llfs_init()`. ## Usage of the llfs API +### The `llfs_file_t` struct +The `llfs_file_t` struct contains information about a file in the filesystem. +```c +typedef struct { + const uint8_t* data; // Pointer to the file data (len bytes) + const char* name; // Null-terminated string with the filename + size_t len; // Length of the file data +} llfs_file_t; +``` +The data pointer points to the data of the file in the filesystem, and can be used to read the file. + ### Getting a list of files ```c #include "llfs.h" void main(void) { + llfs_init(); + // Allocate space for 10 files llfs_file_t file_list[10]; @@ -33,13 +68,50 @@ Result: [Info] (2031) [main]: File: file1.txt, size: 77 ``` +It is also possible to use a file extension filter (e.g. `*.bmp`, `*.txt`, `*.py`). +```c + // ... + size_t file_count = llfs_file_list(file_list, 10, "*.bmp"); + // ... +``` +This will only return files with the `.bmp` extension. +```` +[Info] (2009) [main]: File: image.bmp, size: 9270 +[Info] (2019) [main]: File: image2.bmp, size: 7738 +```` + +#### Iterator function (not recommended) +It is also possible to iterate through the files without allocating an array. +When the memory pointer is `NULL`, the iterator will start at the beginning of the file list. +Each call to `llfs_next_file()` will return the next file in the list, +if a filter is specified files that don't match the filter will be skipped. +```c +#include "llfs.h" + +void main(void) { + llfs_init(); + + // Get the file list + void* mem = NULL; // Pointer for internal use by the llfs library + llfs_file_t* file; + while ((file = llfs_next_file(&mem, ".bmp")) != NULL) { + LOG_INFO(TAG, "File: %s", file->name); + } +} +``` +While this method doesn't require allocating memory for the file list, +it is slower than the previous method due to the overhead calling the function for each file. +Additionally, the required memory for the filelist is very small, so it's recommended to use the first method. + ### Reading a file ```c #include "llfs.h" void main(void) { + llfs_init(); + // Get a file by name - llfs_file_t *file = llfs_file_open("filename with a space.txt"); + llfs_file_t* file = llfs_file_open("filename with a space.txt"); if (file != NULL) { // Print the file name, size and data @@ -55,3 +127,37 @@ Result: [Info] (2040) [main]: File found: filename with a space.txt, size: 61 [Info] (2047) [main]: File data: This is a file with a space in it's filename. ``` + +### Getting the number of files +```c +#include "llfs.h" + +void main(void) { + llfs_init(); + + // Get the number of files + size_t file_count = llfs_file_count(); + + // Print the number of files + LOG_INFO(TAG, "File count: %d", file_count); +} +``` + +## Using the POSIX file functions +The llfs library also supports the POSIX file functions. +As the file system is read-only, write functions are not implemented. +There is also a limit on the number of files that can be open concurrently, +this is set by the `POSIX_MAX_FILES` macro in `llfs.c`. +The default value is 10, but there are already 3 files in use (stdin, stdout, stderr), +so the maximum number of files that can be open is 7. + +The following functions are tested and working, but other functions might also work: + - `fopen` + - `fclose` + - `fgetc` + - `fread` + - `fseek` + - `ftell` + - `rewind` + - `fstat` + - `fileno` diff --git a/project/.cproject b/project/.cproject index b36ef16..2b2e80a 100644 --- a/project/.cproject +++ b/project/.cproject @@ -24,7 +24,7 @@