diff --git a/.gitignore b/.gitignore index 38defbf..b762c35 100644 --- a/.gitignore +++ b/.gitignore @@ -31,8 +31,30 @@ *.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/ project/cmake-build-debug/ + +project/.settings/ + +project/.mxproject + +project/project.launch + +project/Scripts +Scripts/ +project/project\ Debug.launch \ No newline at end of file diff --git a/README.md b/README.md index 284570e..8d8ba21 100644 --- a/README.md +++ b/README.md @@ -21,9 +21,9 @@ This way we can keep the code clean. [tasks_and_taskowners.md](tasks_and_taskowners.md) ## Style Guide -To maintain a consistent and clean codebase, follow the [style guide](style_guide.md). This document provides detailed instructions on naming conventions, code structure, and commenting practices. +To maintain a consistent and clean codebase, follow the [style guide](docs/style_guide.md). This document provides detailed instructions on naming conventions, code structure, and commenting practices. -Please read the [style_guide.md](style_guide.md) carefully before making contributions. +Please read the [style_guide.md](docs/style_guide.md) carefully before making contributions. ### Editor Configuration @@ -57,4 +57,7 @@ Documentation is placed in the [docs](docs) folder. If your part needs documentation (e.g. how to use tcp cmd interface), add a markdown file in the above-mentioned folder. This folder contains the following documents: +- [llfs.md](docs/llfs.md): Linked List File System - [logger.md](docs/logger.md): Logging and Debugging Messages +- [mkllfs.md](docs/mkllfs.md): Make Linked List File System +- [style_guide.md](docs/style_guide.md): Style Guide \ 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 new file mode 100644 index 0000000..2fa6986 --- /dev/null +++ b/docs/llfs.md @@ -0,0 +1,163 @@ +# LLFS (Linked List File System) + +## Introduction +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]; + + // Get the file list + size_t file_count = llfs_file_list(file_list, 10, NULL); + + // Loop through the files and print their names and sizes + for (int i = 0; i < file_count; i++) { + LOG_INFO(TAG, "File: %s, size: %d", file_list[i].name, file_list[i].len); + } +} +``` +Result: +``` +[Info] (2009) [main]: File: image.bmp, size: 9270 +[Info] (2013) [main]: File: python_file.py, size: 645 +[Info] (2019) [main]: File: image2.bmp, size: 7738 +[Info] (2024) [main]: File: filename with a space.txt, size: 61 +[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"); + + if (file != NULL) { + // Print the file name, size and data + LOG_INFO(TAG, "File found: %s, size: %d", file->name, file->len); + LOG_INFO(TAG, "File data: %s", file->data); + } else { + LOG_WARN(TAG, "File not found"); + } +} +``` +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/style_guide.md b/docs/style_guide.md similarity index 100% rename from style_guide.md rename to docs/style_guide.md diff --git a/project/.clang-format b/project/.clang-format new file mode 100644 index 0000000..a71906b --- /dev/null +++ b/project/.clang-format @@ -0,0 +1,69 @@ +--- +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: true +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Left +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +BinPackArguments: true +BinPackParameters: false +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Attach +BreakBeforeTernaryOperators: true +BreakStringLiterals: true +ColumnLimit: 120 +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +IncludeBlocks: Preserve +IncludeCategories: + - Regex: "^<(.*)>" + Priority: 0 + - Regex: ^"(.*)" + Priority: 1 + - Regex: "(.*)" + Priority: 2 +IncludeIsMainRegex: "(_test)?$" +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: false +Language: Cpp +MaxEmptyLinesToKeep: 1 +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 1000 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Never +UseCRLF: false +... diff --git a/project/.cproject b/project/.cproject index b36ef16..2b2e80a 100644 --- a/project/.cproject +++ b/project/.cproject @@ -24,7 +24,7 @@