Skip to content

Initialize dmuart repository template based on dmgpio and dmclk#3

Merged
JohnAmadis merged 7 commits into
mainfrom
copilot/prepare-repository-template-for-uart
May 28, 2026
Merged

Initialize dmuart repository template based on dmgpio and dmclk#3
JohnAmadis merged 7 commits into
mainfrom
copilot/prepare-repository-template-for-uart

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 28, 2026

Bootstraps the dmuart repository with the same DMOD module structure used in dmgpio and dmclk, adapted for UART.

Structure

  • Build system: CMakeLists.txt with DMUART_MCU_SERIES parameter, DMOD FetchContent integration, dmod_add_library usage
  • DMOD metadata: manifest.dmm, dmuart.dmr resource file
  • Types (include/dmuart_types.h): Typed enums for all configuration parameters — word length, parity, stop bit, flow control, bit order, invert, loopback, interrupt trigger; interrupt handler types and params struct
  • Public API (include/dmuart.h): dmuart_config_t structure with typed fields; ioctl command set for runtime configuration
  • Port layer (include/dmuart_port.h): Individual setters/getters for each parameter (baudrate, word_length, parity, stop_bit, bit_order, invert, loopback), interrupt trigger/handler registration, flush, transmit/receive
  • Core driver (src/dmuart.c): Full DMDRVI implementation — create/free/open/close/read/write/ioctl/flush/stat with dmhaman interrupt dispatch support
  • STM32F7 port (src/port/stm32f7/port.c): Register-level USART1-8 support with ISR handlers, all setters/getters, polled TX/RX
  • STM32F4 port (src/port/stm32f4/port.c): Register-level USART1-6 support with ISR handlers for the F4 family
  • Configs: Per-board folders with per-UART config files including GPIO pin configuration for dmdevfs auto-setup (8 boards: nucleo-f401re, nucleo-f411re, nucleo-f446re, nucleo-f767zi, stm32f4-discovery, stm32f429i-discovery, stm32f746g-disco, stm32f769i-discovery)
  • CI: GitHub Actions workflow with dynamic CPU family discovery and matrix build
  • Tests: Loopback test application using dmdrvi interface with config file path (tests/dmuart-test/)
  • Docs: Module overview, API reference, configuration guide, port implementation guide

Usage

[stlink_vcp]
driver_name=dmuart
baudrate=921600
databits=8
parity=none
stopbits=1
flowcontrol=none
instance=1

[stlink_vcp_tx]
driver_name=dmgpio
pin=PA9
mode=alternate
alternate_function=7
speed=maximum
output_circuit=push_pull
pull=up

[stlink_vcp_rx]
driver_name=dmgpio
pin=PB7
mode=alternate
alternate_function=7
pull=up
dmini_context_t config = dmini_load("configs/board/stm32f746g-disco/usart1.ini");
dmdrvi_dev_num_t dev_num = {0};
dmdrvi_context_t ctx = dmuart_dmdrvi_create(config, &dev_num);
void* handle = dmuart_dmdrvi_open(ctx, DMDRVI_O_RDWR);

dmuart_dmdrvi_write(ctx, handle, data, len, 0);
size_t n = dmuart_dmdrvi_read(ctx, handle, buf, sizeof(buf), 0);
dmuart_dmdrvi_flush(ctx, handle);
cmake -DDMUART_MCU_SERIES=stm32f7 -B build
cmake --build build

# or for STM32F4:
cmake -DDMUART_MCU_SERIES=stm32f4 -B build
cmake --build build

Copilot AI added 2 commits May 28, 2026 10:00
- Add CMakeLists.txt with DMOD build system integration
- Add manifest.dmm and dmuart.dmr resource files
- Add include/ with dmuart.h (public API) and dmuart_port.h (port layer)
- Add include/port/ with STM32 register definitions
- Add src/dmuart.c core DMDRVI implementation
- Add src/port/ with STM32F7 UART port implementation
- Add configs/ with board and MCU configuration files
- Add docs/ with module, API, configuration, and port guides
- Add tests/dmuart-test/ with loopback test application
- Add examples/config.ini
- Add .vscode/ settings and tasks
- Update .gitignore and README.md
Copilot AI changed the title [WIP] Prepare repository template based on dmgpio and dmclk Initialize dmuart repository template based on dmgpio and dmclk May 28, 2026
Copilot AI requested a review from JohnAmadis May 28, 2026 10:02
Copy link
Copy Markdown
Contributor

@JohnAmadis JohnAmadis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot popraw to proszę

Comment thread configs/board/stm32f746g-disco.ini Outdated
@@ -0,0 +1,9 @@
; STM32F746G-DISCO board UART configuration
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dodaj więcej konfiguracji płytek, przynajmniej tyle samo co w dmgpio

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added board configurations for: nucleo-f401re, nucleo-f411re, nucleo-f446re, nucleo-f767zi, stm32f4-discovery, stm32f429i-discovery, stm32f746g-disco, stm32f769i-discovery — matching the same set as dmgpio.

Comment thread configs/board/stm32f746g-disco.ini Outdated
; STM32F746G-DISCO board UART configuration
; Uses USART1 (connected to ST-Link virtual COM port)
[dmuart]
baudrate=115200
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

daj jakąś wyższą prędkość, ta jest za niska

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed default baud rate to 921600 across all board and MCU configs.

Comment thread .vscode/settings.json
@@ -0,0 +1,8 @@
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

brakuje też konfiguracji CI dla githuba

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added .github/workflows/ci.yml with the same pattern as dmgpio — auto-discovers CPU families from src/port/*/port.c and builds each in a matrix using the chocotechnologies/dmod:1.0.4 container.

Comment thread src/port/stm32f7/port.c
@@ -0,0 +1,325 @@
#define DMOD_ENABLE_REGISTRATION ON
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wsparcie dla innych rodzin (przynajmniej f4) też powinno być

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added full STM32F4 port at src/port/stm32f4/port.c with register definitions in include/port/stm32f4_regs.h. Supports USART1-6 with the same API as STM32F7. CI will now build both families.

Comment thread src/port/stm32f7/port.c Outdated
*
* @return int 0 on success, non-zero on failure
*/
dmod_dmuart_port_api_declaration(1.0, int, _init, ( uint32_t instance, dmuart_baudrate_t baudrate, dmuart_databits_t databits, uint8_t parity, uint8_t stopbits, uint8_t flowcontrol) )
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

w dmgpio dla każdego parametru konfiguracyjnego były enumy - sprawdź sobie header dmgpio_types.h - tutaj też tak powinno być. Nie chcemy zgadywać co tam się przekazuje

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created include/dmuart_types.h with typed enums for all parameters: dmuart_word_length_t, dmuart_parity_t, dmuart_stop_bit_t, dmuart_flow_control_t, dmuart_bit_order_t, dmuart_invert_t, dmuart_loopback_t, dmuart_int_trigger_t. The port layer now uses these types in all setters/getters instead of raw uint8_t.

Comment thread src/port/stm32f7/port.c Outdated
return -1;
}

volatile USART_TypeDef *USART = (USART_TypeDef *)uart_base_addresses[instance - 1];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a co z obsługą przerwań? Nie widzę żadnej

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added full interrupt support — DMOD_IRQ_HANDLER entries for all UART instances (both F4 and F7), set_interrupt_trigger to enable/disable specific interrupt sources (RXNE, TXE, TC, IDLE, Error), and add/remove_interrupt_handler for callback registration. ISR dispatches to registered handler with trigger type and received data.

Comment thread configs/board/stm32f746g-disco.ini Outdated
@@ -0,0 +1,9 @@
; STM32F746G-DISCO board UART configuration
; Uses USART1 (connected to ST-Link virtual COM port)
[dmuart]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pliki konfiguracyjne dla uarta powinny również zawierać konfigurację dla niezbędnych pinów w gpio - tak, aby jak ktoś zdecyduje, że chce używać uarta, to automatycznie mu się skonfiguruje też gpio odpowiednio. dmdevfs wspiera takie coś - wystarczy dodać osobną sekcję i dodać w niej klucz driver_name (sprawdz sobie dokumentację dmdevfs).

Ponadto, jako że jest tam kilka uartów różnych na płytce, to moglibyśmy zrobić tak, że stworzymy folder configs/board/stm32f746g-disco/ a wewnątrz dodamy osobne pliki z konfiguracjami na każdego dostępnego uarta na płytce

Jako nazwę sekcji użyj też jakieś human friendly nazwy tego uarta, bo dzięki temu dmdevfs stworzy odpowiedni plik o tej nazwie.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restructured configs: each board is now a folder (e.g. configs/board/stm32f746g-disco/) with per-UART .ini files. Each file uses human-friendly section names (e.g. [stlink_vcp], [arduino_uart]) and includes GPIO pin configuration sections with driver_name=dmgpio for TX/RX pins, so dmdevfs will auto-configure both drivers.

Comment thread src/dmuart.c Outdated
*/
dmod_dmdrvi_dif_api_declaration(1.0, dmuart, int, _flush, ( dmdrvi_context_t context, void* handle ))
{
return 0;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

czemu flusha nie implementujesz? Też jest potrzebny

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flush is now properly implemented — calls dmuart_port_flush() which waits for TX complete and drains RX FIFO.

Comment thread tests/dmuart-test/dmuart_test.c Outdated
Dmod_Printf("Baud rate : %u\n\n", baudrate);

/* Initialize UART: 8N1, no flow control */
int ret = dmuart_port_init(instance, baudrate, 8, 0, 0, 0);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nie powinieneś sam inicjalizować uarta do testów - lepiej jak Ci użytkownik przekażę ścieżkę do pliku z gotowym uartem

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redesigned the test — it now takes a config file path as argument and creates the UART via dmuart_dmdrvi_create() using dmini_load(). No more direct port initialization.

Comment thread src/dmuart.c
dmdrvi_context_t context = Dmod_Malloc(sizeof(struct dmdrvi_context));
if (context != NULL)
{
memset(context, 0, sizeof(*context));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

z tego co widzę, to też nie obsługujesz kompletnie przerwań i dmhaman - powinieneś dać możliwość podania interrupt_trigger tak jak dmgpio - czyli żeby się dało triggerować handlery jak się otrzyma dane z uarta

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added dmhaman integration: the driver reads interrupt_trigger and interrupt_handler from the INI config. When configured, it registers a port interrupt handler that calls dmhaman_call_handler() with dmuart_interrupt_params_t (instance, trigger type, received data). Also available via dmuart_ioctl_cmd_set_interrupt_handler ioctl.

Copilot AI added 2 commits May 28, 2026 10:47
…CI, board configs

- Add dmuart_types.h with enums for all parameters (word_length, parity,
  stop_bit, flow_control, bit_order, invert, loopback, interrupt_trigger)
- Redesign port layer with individual setters/getters per parameter
- Add interrupt support with dmhaman integration (interrupt_trigger config)
- Implement flush properly via port layer
- Add STM32F4 port implementation
- Add GitHub CI workflow (matching dmgpio pattern)
- Restructure board configs as folders with per-UART files + GPIO pin config
- Increase default baud rate to 921600
- Redesign test to accept config file path via dmdrvi
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 28, 2026

@copilot popraw to proszę

Done — addressed all review feedback in commits Address review feedback: add types, STM32F4 port, interrupts, flush, CI, board configs and Fix circular include in dmuart_port.h and clarify loopback comments.

Copilot AI requested a review from JohnAmadis May 28, 2026 10:50
Copy link
Copy Markdown
Contributor

@JohnAmadis JohnAmadis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot kolejne poprawki są niezbędne

Comment thread .github/workflows/ci.yml
@@ -0,0 +1,70 @@
name: CI
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a release? Czemu tylko jedno skopiowałeś? Nie przyszło Ci do głowy, że drugie też jest potrzebne?

flowcontrol=none
instance=6

[arduino_uart_tx]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wydaje mi się, że gpio piny powinny być konfigurowane jako pierwsze, bo inaczej nie będziesz mógł użyć uarta

Comment thread .github/workflows/ci.yml Outdated

on:
push:
branches: [ master, develop ]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tutaj w repo jest branch main

Comment thread tests/dmuart-test/dmuart_test.c Outdated
}

const char *config_path = argv[1];
Dmod_Printf("Config file: %s\n\n", config_path);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nie rozumiesz - nie potrzebujesz czytać config file'a,bo już powinien być skonfigurowany przez dmdevfs - użytkownik ma ci tylko podac sciezke do pliku

Comment thread src/dmuart.c
dmuart_config_t *c = &context->config;
int ret;

ret = dmuart_port_init(c->instance);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dodaj jeszcze kontrolę zajętości kanału - tak, żeby przed skonfigurowaniem najpierw driver spróbował oznaczyć go sobie jako "zajęty" - tak aby następnym razem jak ktoś próbuje jeszcze raz użyć tego samego kanału i skonfigurować go do czegoś innego, żeby dostał błąd "channel is already used"

Comment thread src/port/stm32f7/port.c
{
if (validate_instance(instance) != 0 || data == NULL || received == NULL) return -1;

volatile USART_TypeDef *USART = get_usart(instance);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

te Twoje nazwy typów USART_TypeDef aż biją po oczach biblioteką stm32 cube - dopasuj nazewnictwo do lokalnego standardu kodowania - snake_case, z suffixem _t dla typów

Comment thread src/port/stm32f7/port.c
return -1;
}

data[i] = (uint8_t)(USART->RDR & 0xFF);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a gdzie jakiś lokalny bufor? Z przerwania, jak tylko przyjdą dane, powinieneś je wrzucać do lokalnego bufora, np cycle ring. I jak ktoś zawoła receive to z niego to odczytywać... Nie powinniśmy tracić żadnych danych - a tymczasem w twoim rozwiazaniu jak nie zdazymy czegos odebrac to to przepada.

Możesz sobie zobaczyć jak ja to zaimplementowałem w innym systemie:
https://bitbucket.org/chocos/chocos/src/develop/Source/system/portable/src/st/stm32f7/lld/uart/oc_uart_lld.c

oc_uart_lld.c

Comment thread src/dmuart.c
return received;
}

dmod_dmdrvi_dif_api_declaration(1.0, dmuart, size_t, _write, ( dmdrvi_context_t context, void* handle, const void* buffer, size_t size, uint32_t offset ))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dodaj jakieś komentarze doxygen do tych wszystkich funkcji bo pusto jest jakoś tak.

I najlepiej też jakiś komentarz separacyjny w stylu:

// ==========================================================================
/**
 * @brief moja znakomita funkcja
*
...
 */
// ==========================================================================

@JohnAmadis
Copy link
Copy Markdown
Contributor

@copilot nie buduje Ci sie projekt:

[ 68%] Building C object src/port/CMakeFiles/dmuart_port.dir/stm32f4/port.c.o
/__w/dmuart/dmuart/src/port/stm32f4/port.c: In function 'dmod_init':
/__w/dmuart/dmuart/src/port/stm32f4/port.c:82:5: warning: implicit declaration of function 'Dmod_Printf' [-Wimplicit-function-declaration]
82 | Dmod_Printf("DMUART port module initialized (STM32F4)\n");
| ^~~~~~~~~~~
[ 75%] Building C object src/port/CMakeFiles/dmuart_port.dir/dmuart_port_header.c.o
[ 81%] Linking C executable dmuart_port
/tools/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: CMakeFiles/dmuart_port.dir/stm32f4/port.c.o: in function dmod_init': port.c:(.text.dmod_init+0x6): undefined reference to Dmod_Printf'
/tools/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: CMakeFiles/dmuart_port.dir/stm32f4/port.c.o: in function dmod_deinit': port.c:(.text.dmod_deinit+0x6): undefined reference to Dmod_Printf'
collect2: error: ld returned 1 exit status
make[2]: *** [src/port/CMakeFiles/dmuart_port.dir/build.make:120: src/port/dmuart_port] Error 1
make[1]: *** [CMakeFiles/Makefile2:589: src/port/CMakeFiles/dmuart_port.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

@JohnAmadis JohnAmadis marked this pull request as ready for review May 28, 2026 12:41
@JohnAmadis JohnAmadis merged commit c8ab0c2 into main May 28, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Przygotować szablon repozytorium bazując na dmgpio i dmclk

2 participants