MCU Protocol ideas for 'large IO' peripherals

Hi all,
I’ll try to keep this quick.
I’ve got a Tronxy X5SA that I’ve just installed Klipper on. Obviously the LCD doesn’t work under Klipper.
I want to fix this.

My thoughts are first to implement a Memory Mapped peripheral ‘driver’ within Klipper (like SPI / I2C / CAN… but for wide data). For my MCU implementation, I only care about the STM32F103… but I still want to make the configuration portable for others to easily implement similar for other MCUs.

One challenge is around the communication between the Python layer, and the MCU for configuration the bus itself. For SPI / I2S there are a handful of pins (i.e. SPI=mosi, miso, clk… and then per device cs). For a bus like 8080/6800 there are d0…d15, a0…a23, nrd, nrw, nwait, etc… and THEN cs also.
This seems like too much to throw at a single ‘config_mmap’ config command.

So… my thoughts are to have an Enum defined in the MCU for mmap_pin_def (which would be d0…d15, a0…a27, etc, etc), and then the Python layer would send multiple ‘config_mmap’ commands, one for each pin.

Would this be considered as ‘acceptable’?

Given the LCD, there would also be quite a lot of large IO transfers. I haven’t seen a standard way of doing DMA or background IO actions. Is there any reference for this?

1 Like

FYI, there was a similar discussion at (wip) Et4x by pienjo · Pull Request #3724 · Klipper3d/klipper · GitHub . Unfortunately, it doesn’t seem anyone currently has a good feel for how this should be implemented.

It’s worth pointing out that implementing display code in Klipper itself has some significant limitations. An ideal display should be able to provide information on software versions, provide for software restarts, have temperature history, etc. - all things that moonraker currently supports. Thus, in addition to the question of how to best support high bandwidth screens, there is also the question of how to get all the really pertinent information to those screens.

-Kevin

Thanks for the reply.
I’m just looking at the bus interface at this stage, not LCD or graphics.
It’s possible that such a memory mapped bus may be used for other non-LCD purposes.

The issue I have is with offering a flexible configuration of such a high number of possible IO points.
For the STM32 they are fixed across the series (from what I can tell… PE2 is always FSMC_A23), but other more advanced MCUs likely have A23 configurable across a wide number of pin. Plus there is the consideration that applications likely won’t use all the assigned pins anyway (i.e. most STM32 implementations for LCD control will only use A0… not A1 through A25)
So I’d like to have the mmap_bus config interface able to send to the MCU which ‘physical’ pins should be used for which bus pins.

I think doing it via one config command per IO pin in the desired bus (i.e. d0-d15, a0, +controls) and then one to ‘seal’ the bus interface (that might throw a shutdown error on a misconfiguration).
Any objections to such an idea?
Unlike the SPI / I2C, I’d also have it defined as its own section, rather than nested within an end device section.

Once it comes to the actual graphical aspect. My thoughts are:
LCD driver would be stacked atop the mmap_bus interface (since almost all higher pixel count LCDs have a memory mapped controller). But for small OLEDs etc then it could be stacked atop the SPI / I2C bus driver also.
Then there would be a low level graphical library (like LVGL or something) which would run host-side, but not rendering to a host side screen buffer. The host side LVGL would send to the LCD driver (likely an intermediate layer for line drawing etc when LCD controller doesn’t support such 2D hardware accel).
I’m not married to the idea of LVGL, perhaps there is a better lightweight library. It would be nice if there was one that handled both pixel based and character based displays.