2020-08-03

2020-08-02 Longan Nano GD32vf103 Display and Screen Classes

>>>Longan Nano GD32VF103<<<

Longan Nano GD32VF103 Risc-V 108MHz 32b MCU toolchain, libraries and applications

>>>Longan Nano Screen and Display Classes<<<


Display Class: Interfaces with the ST7735 80x160 display using SPI0 and DMA0.
Screen Class: Provides asynchronous methods to print on the display



1Longan Nano GD32VF103 Display and Screen Classes

The Longan Nano is equipped with an OLED 0.96 inches 80x160 color screen interfaced to the GD32VF103 through the SPI0 peripheral. Additional GPIO pins are used for chip select, reset and data/command mode.

The scope of this document is to explain the design decision, constraints and architectural choices behind the Screen and Display classes that control the display.



2Pin Configuration

The Screen uses a ST7735S controller. The screen is interfaced directly with the microcontroller.

Illustration 1: Schematics

The CS pin unfortunately is not the SPI0 CS, so cannot be generated by hardware and must be controlled via software.

The RS pin as well must be toggled quite often. The SS7735S has a communication protocol in which a command byte is followed by a number of data bytes. In a typical draw operation there are at least four commands to be sent, requiring at least four toggles.


2.1MCU Peripherals

The GD32VF103 is equipped with two majestic DMA controllers for a total of twelve channels.

To minimize CPU use I can use the DMA0 to handle multi byte transfers from memory to the SPI0 peripheral, making the job of transferring pixel data that much cheaper for the CPU.

All of the DMA channels can steal up to 50% of the CPU main bus bandwidth, so some performance degradation can be expected on the CPU.


Illustration 2: GD32VF103 Peripherals


2.2Screen Configuration

The screen uses a 16bit RGB565 color space with 80x160 = 12800 pixels.

SPI0 has been tested up to 6.7MHz of speed.

Others modes are available but would take time to develop and not offer much savings. Current Screen and Display classes are good enough.


3Software Architecture

A lot of effort went into the design of the software, partitioning the workload and in deciding the ABI and HAL structures.


3.1Specifications

First thing to do is to understand my use case and what I want out of the Longan Nano screen.

  • Debug and profiling: Show things like voltages, currents, encoder readings, communication and errors.

  • Mostly ASCII characters: A fancy real time chart would be cool, but a waste of performance. I have the Raspberry Pi if I want to show fancy charts, and have more pixels and cpu to do so.

  • Low CPU and Memory footprint: I need the MCU to perform a fixed function. That's its primary objective. Debug and profile helps out and is secondary.


3.2Bandwidth and Memory Considerations

In order to refresh each pixel I need at minimum a 80x160x2x8=204.800 [Kb] transfer which yield a theoretical maximum of 32.8 [FPS], but would require the CPU to do nothing but line up bytes for the screen considering the prep time.

Any meaningful implementation needs a frame buffer, that for a full screen would be: 80x160x2 = 25.6 [KB] on an available memory of 32 [KB] meaning at minimum I would consume 80% of the working memory just for the screen.


3.3Architecture

I made a sprite based library. This means that the screen only need a frame buffer as big as the biggest sprite.

I partition the driver in two:

  • Display Class: HAL and interface with the physical OLED. Provides sprite draw methods.

  • Screen Class: I abstract one level up and build all my sprite methods in a Screen class. All the print, sprite maps, frame buffer, etc... So if I change display, I can reuse the screen class.

The division means that I have two frame buffers. A frame buffer for the sprites that has the size of the number of sprites that can be drawn on the screen, and a frame buffer for the pixel data of a single sprite that is used for drawing.

Imagining a screen size of 80x160 and a sprite size of 16x8, this mean the frame buffer for the pixel data will be 16x8x2 = 256[B] while the frame buffer for the sprites will be 80/16x160/8 = 100 [B]. A massive saving in memory. Since I need to only show ascii characters anyway, this is not even limiting the flexibility of the draw too much. A drawback is that character are in a fixed grid, instead of being printable in each position.

The SPI needs time to send data, I can make the class asynchronous by returning after initiating the communication. I construct a core Update() method that returns without doing anything if the peripherals are busy.

This architectural decision means that the user will have to periodically call the update method, and it also means that the user decides how much resources allocate to the screen. If the user calls the update method slower than they are calling the print methods, simply some sprites won't be drawn.

Finally, I decide to split the update method in two. The Display::Update() is busy while sending a sprite, and idle otherwise. The higher Screen::Update() scans the frame buffer and register a sprite to send, then loops around the Display::Update() until the draw is complete. Since they are all non blocking calls, this reduces the CPU use to the minimum.

Another optimization is to have an update flag. Sprites are only redrawn if they have changed. This optimization costs an additional update frame buffer, but massively reduces bandwidth use when characters change sparsely.

Illustration 3: Display and Screen Class Architectures


4Conclusions

The Screen Class and Display class provide a ascii based frame buffer and support asynchronous control of the screen on board the Longan Nano board.

Extensive print methods allow to format numbers in a variety of ways for the library primary propose, which is to show fast updating debug information while using little CPU.

No graphics mode is supported as of now.

Future developments include:

  • Reduce idle use by using a pending counter

  • Improve the FSM of the display

  • Improve CPU use


5Source Code

Source code of the Demo application. Repository.



No comments: