diff --git a/Documentation/epicardium-guide.rst b/Documentation/epicardium-guide.rst index fd6d54f11659f24c852017f02d6404f50f7a3380..7a549214442083b5a033b25ac84331fbda1a470f 100644 --- a/Documentation/epicardium-guide.rst +++ b/Documentation/epicardium-guide.rst @@ -1,3 +1,5 @@ +.. _epicardium_api_guide: + Epicardium API Development ========================== If you are interested in augmenting the Epicardium API with new calls, this diff --git a/Documentation/how-to-build.rst b/Documentation/how-to-build.rst index 36b5343f5c9095b7aa89ec360bbeb7465a27eac6..c509bff4f82b716383fe86d0b24909b0ddc09a88 100644 --- a/Documentation/how-to-build.rst +++ b/Documentation/how-to-build.rst @@ -13,6 +13,7 @@ Dependencies - Arch: ``arm-none-eabi-gcc``, ``arm-none-eabi-binutils``, ``arm-none-eabi-newlib`` - Alternative: Download `ARM's GNU toolchain`_. **TODO** * **python3**: For meson and various scripts needed for building. +* **ninja**: Needed for meson. * **meson** (>0.43.0): Unfortunately most distros only have very old versions of meson in their repositories. Instead, you'll probably save yourself a lot of headaches by installing meson from ``pip3 install --user meson``. diff --git a/Documentation/overview.rst b/Documentation/overview.rst index e9708c9277e9a9358cd4f4c5dee86540fd532ab5..9025c1a76134e1f75d55351dc17f44de9badb868 100644 --- a/Documentation/overview.rst +++ b/Documentation/overview.rst @@ -19,6 +19,9 @@ number of tasks that will have been keeping card10 running. These are: statistics that can be gathered from our power manager IC (MAX77650). * **Serial**: Handles serial communication via *UART*, *CDC ACM* and possibly Bluetooth. +* **BHI160**: Housekeeping task for interaction with the `BHI160`_. + +.. _BHI160: https://www.bosch-sensortec.com/bst/products/all_products/bhi160 .. todo:: @@ -29,6 +32,13 @@ number of tasks that will have been keeping card10 running. These are: .. _#23: https://git.card10.badge.events.ccc.de/card10/firmware/issues/23 +Epicardium API +-------------- +Epicardium exposes lots of functionality via the *Epicardium API*. The +technical details if this API can be found in this :ref:`overview +<epicardium_api_overview>`. If you are interesting in adding new API calls, +you should probably read the :ref:`epicardium_api_guide` guide. + Pycardium --------- Pycardium is our MicroPython fork. Its purpose is to make it as easy as diff --git a/card10-cross.ini b/card10-cross.ini index be7a3da43835c016bd8171c39b563349fee79eea..bf0693cc7b1b20ec342cc5dd5689a0ec4dd1b001 100644 --- a/card10-cross.ini +++ b/card10-cross.ini @@ -4,7 +4,7 @@ ar = 'arm-none-eabi-ar' strip = 'arm-none-eabi-strip' [properties] -c_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=hard', '-mfpu=fpv4-sp-d16', '-Wa,-mimplicit-it=thumb', '-ffunction-sections', '-fdata-sections', '-fsingle-precision-constant', '-fno-isolate-erroneous-paths-dereference', '-Wl,--start-group', '-lc', '-lnosys', '-Wl,--end-group'] +c_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=hard', '-mfpu=fpv4-sp-d16', '-Wa,-mimplicit-it=thumb', '-ffunction-sections', '-fdata-sections', '-fsingle-precision-constant', '-fno-isolate-erroneous-paths-dereference'] c_link_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=hard', '-mfpu=fpv4-sp-d16', '-Wl,--start-group', '-lc', '-lnosys', '-Wl,--end-group', '--specs=nano.specs', '-u _printf_float'] diff --git a/epicardium/FreeRTOSConfig.h b/epicardium/FreeRTOSConfig.h index 6822b06869e173a68ccef3a8081ce558478bf675..b92b12b9ec223da13082f23fcad849a1337ba316 100644 --- a/epicardium/FreeRTOSConfig.h +++ b/epicardium/FreeRTOSConfig.h @@ -56,6 +56,13 @@ /* Allow static allocation of data structures */ #define configSUPPORT_STATIC_ALLOCATION 1 +/* + * Enable stack overflow detector. + * + * TODO: Remove for production. + */ +#define configCHECK_FOR_STACK_OVERFLOW 2 + /* Alias the default handler names to match CMSIS weak symbols */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 1b932e8b6664c9b7352514b69b394614ce7a2ac1..19759aea78315b3e2f31815916945b32add61b72 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -47,6 +47,7 @@ typedef unsigned int size_t; #define API_DISP_LINE 0x15 #define API_DISP_RECT 0x16 #define API_DISP_CIRC 0x17 +#define API_DISP_PIXEL 0x18 /* clang-format on */ typedef uint32_t api_int_id_t; @@ -310,6 +311,23 @@ API(API_DISP_PRINT, */ API(API_DISP_CLEAR, int epic_disp_clear(uint16_t color)); +/** + * Draws a pixel on the display + * + * :param x: x position; 0 <= x <= 160 + * :param y: y position; 0 <= y <= 80 + * :param color: pixel color in rgb565 + * :return: ``0`` on success or a negative value in case of an error: + * + * - ``-EBUSY``: Display was already locked from another task. + */ +API(API_DISP_PIXEL, + int epic_disp_pixel( + uint16_t x, + uint16_t y, + uint16_t color) + ); + /** * Draws a line on the display * diff --git a/epicardium/modules/display.c b/epicardium/modules/display.c index 26db0d136baba57f0dca00733e063da574e92437..1786d80534ed630e405763c9a7efd77fddc9806c 100644 --- a/epicardium/modules/display.c +++ b/epicardium/modules/display.c @@ -46,6 +46,17 @@ int epic_disp_clear(uint16_t color) } } +int epic_disp_pixel(uint16_t x, uint16_t y, uint16_t color) +{ + int cl = check_lock(); + if (cl < 0) { + return cl; + } else { + Paint_SetPixel(x, y, color); + return 0; + } +} + int epic_disp_line( uint16_t xstart, uint16_t ystart, diff --git a/epicardium/support.c b/epicardium/support.c index 534506ba3ca22fe6e827b3fe1aca22a1668be853..a4af99db481fc0530545832221af9a99fb90bc64 100644 --- a/epicardium/support.c +++ b/epicardium/support.c @@ -6,6 +6,7 @@ #include "task.h" #include "api/dispatcher.h" +#include "modules/log.h" #include "card10.h" @@ -112,3 +113,8 @@ void vApplicationGetTimerTaskMemory( */ *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; } + +void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) +{ + LOG_CRIT("rtos", "Task \"%s\" overflowed stack!", pcTaskName); +} diff --git a/lib/card10/card10.c b/lib/card10/card10.c index 8f9587d2476e4892e98a1005f8a11bb73f67f232..eaedb136674ad91e3b4ff798f625bc886025ad18 100644 --- a/lib/card10/card10.c +++ b/lib/card10/card10.c @@ -24,7 +24,11 @@ #include <stdint.h> #include <string.h> -#define SPI_SPEED (15 * 1000 * 1000 * 1) // Bit Rate. Display has 15 MHz limit +/* XXX: The display supports max 15 Mhz, but we have stability issues at that rate. + * Current suspicion is that the SDK is buggy. + * + * At 12 MHz things seem stable*/ +#define SPI_SPEED (12 * 1000 * 1000) // Bit Rate. Display has 15 MHz limit const gpio_cfg_t bhi_interrupt_pin = {PORT_0, PIN_13, GPIO_FUNC_IN, GPIO_PAD_PULL_UP}; diff --git a/pycardium/modules/py/display.py b/pycardium/modules/py/display.py index 2f7f85a8774886815f3e00d8ee049adbb5ce1f81..ebb276367ff96827e9a91aeeaa4bc6cc2ab8f9f3 100644 --- a/pycardium/modules/py/display.py +++ b/pycardium/modules/py/display.py @@ -76,6 +76,20 @@ class Display: sys_display.print(text, posx, posy, fg, bg) return self + def pixel(self, x, y, *, col=None): + """ + Draws a pixel on the display + + :param x: X coordinate, 0<= x <= 160 + :param y: Y coordinate, 0<= y <= 80 + :param col: color of the pixel (expects RGB tripple) + """ + + col = col or color.WHITE + + sys_display.pixel(x, y, col) + return self + def line(self, xs, ys, xe, ye, *, col=None, dotted=False, size=1): """ Draws a line on the display. diff --git a/pycardium/modules/qstrdefs.h b/pycardium/modules/qstrdefs.h index 70813adc1670a3ae91fb2f014f91c8c160f22487..3dda54d667557f66d39978788fbde813f8e39390 100644 --- a/pycardium/modules/qstrdefs.h +++ b/pycardium/modules/qstrdefs.h @@ -35,6 +35,7 @@ Q(BHI160) Q(sys_display) Q(display) Q(print) +Q(pixel) Q(line) Q(rect) Q(circ) diff --git a/pycardium/modules/sys_display.c b/pycardium/modules/sys_display.c index 1e5d61d3c682fef8ec4767169bebd2b1bf47a653..96cdcb01b03d26748b3f78eecbcd81274a7c147d 100644 --- a/pycardium/modules/sys_display.c +++ b/pycardium/modules/sys_display.c @@ -49,6 +49,29 @@ static mp_obj_t mp_display_print(size_t n_args, const mp_obj_t *args) return mp_const_none; } +/* draw pixel on the display */ +static mp_obj_t mp_display_pixel(size_t n_args, const mp_obj_t *args) +{ + uint16_t x = mp_obj_get_int(args[0]); + uint16_t y = mp_obj_get_int(args[1]); + uint16_t col = get_color(args[2]); + + //TODO: Move sanity checks to epicardium + if (x > 160 || x < 0) { + mp_raise_ValueError("X-Coords have to be 0 < x < 160"); + } + + if (y > 80 || y < 0) { + mp_raise_ValueError("Y-Coords have to be 0 < y < 80"); + } + + int res = epic_disp_pixel(x, y, col); + if (res < 0) { + mp_raise_OSError(-res); + } + return mp_const_none; +} + /* draw line on the display */ static mp_obj_t mp_display_line(size_t n_args, const mp_obj_t *args) { @@ -174,6 +197,9 @@ static mp_obj_t mp_display_close() STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( display_print_obj, 5, 5, mp_display_print ); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( + display_pixel_obj, 3, 3, mp_display_pixel +); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN( display_line_obj, 7, 7, mp_display_line ); @@ -194,6 +220,7 @@ static const mp_rom_map_elem_t display_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&display_open_obj) }, { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&display_close_obj) }, { MP_ROM_QSTR(MP_QSTR_print), MP_ROM_PTR(&display_print_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel), MP_ROM_PTR(&display_pixel_obj) }, { MP_ROM_QSTR(MP_QSTR_line), MP_ROM_PTR(&display_line_obj) }, { MP_ROM_QSTR(MP_QSTR_rect), MP_ROM_PTR(&display_rect_obj) }, { MP_ROM_QSTR(MP_QSTR_circ), MP_ROM_PTR(&display_circ_obj) }, diff --git a/tools/code-style.sh b/tools/code-style.sh index b18533bdf16129f5e6e9ed38ae2bc7ffa69b09f3..2d459c575b1e74a8d11e6bbc10b783083ba3e74f 100755 --- a/tools/code-style.sh +++ b/tools/code-style.sh @@ -12,7 +12,7 @@ if ! command -v python3 >/dev/null 2>&1; then exit 127 fi -if [ "$#" == 0 ]; then +if [[ "$#" == 0 ]]; then echo "usage: $0 <source.c> ..." exit 1 fi @@ -20,7 +20,12 @@ fi script_dir="$(dirname "$0")" for source_file in "$@"; do - echo "Formatting $source_file ..." - clang-format -i "$source_file" - python3 "$script_dir/fix-multi-decl.py" "$source_file" + if [[ "$source_file" == *.c ]]; then + echo "Formatting $source_file ..." + clang-format -i "$source_file" + python3 "$script_dir/fix-multi-decl.py" "$source_file" + else + echo "Not a C file: $source_file" >&2 + continue + fi done