/\___/\
   /       \
  l  u   u  l
--l----*----l--      _   _ _                      _           _             
   \   w   /        | |_(_) |_ ____ __  __ _ _ _ ( )___  _ __| |__ _ __ ___ 
     ======         | / / |  _|_ / '  \/ _` | ' \|/(_-< | '_ \ / _` / _/ -_)
   /       \ __     |_\_\_|\__/__|_|_|_\__,_|_||_| /__/ | .__/_\__,_\__\___|
   l        l\ \                                        |_|                 
   l        l/ /
   l  l l   l /
   \ ml lm /_/
	
kitzman's place

Interfacing an LCD with an SBC - with Zig! #1

embedded

Intro

When one looks up how to add a display to an SBC (such as a Raspberry PI), most of the examples/tutorials just say to use this or that kernel module, or library.

Since I’m a DIY person, I refused this approach when it came to this parallel I/O I randomly got my hands on.

This can shed some light, more on how easy it is to bootstrap a cross platform embedded program, than how to read documentation/a datasheet.


 ___________
||         ||            _______
||ASCII ART||           | _____ |
||         ||           ||_____||
||_________||           |  ___  |
|  + + + +  |           | |___| |
    _|_|_   \           |       |
   (_____)   \          |       |
	      \    ___  |       |
       ______  \__/   \_|       |
      |   _  |      _/  |       |
      |  ( ) |     /    |_______|
      |___|__|    /         CA15
	   \_____/

Materials

SBC

Since I, most of the time, use an ODroid, I decided to write it for that platform. I’m sure the project, once finished, will easily be ported for any other SBC.

Display

The display I got my hands on is an RG12864B-BIW-V from Raystar. It features 20 pins, out of which 8 are for sending/receiving data. You can power it with 5V, but for communication, 3.3V will work as well for the output-only pins.

I have estimated a maximum of 300mA, so the ODroid pins will be able to handle it with no issue.

Components & assembly

Pretty basic:

  • two 3.3V to 5V bidirectional translator (for data)
  • resistors for contrast an backlight
  • an NPN transistor
  • a switch (of course)

Connecting them is quite trivial.

I used hand-cutâ„¢ male pin connectors for interfacing with the computer, with a post-it to reference each pin.

For the display, two female connectors allow sufficient height for the other components. Double-adhesive tape is a must so I make sure I don’t bend the pins.

Bootstrapping the project

I maintained the following project structure:


+ display-project
|
|- build.zig
|- src  <- my Zig files
\- external +- .bazelrc   \
	    |- BUILD       |<- Bazel rules
	    |- WORKSPACE  /
	    |- libgpiod   <- a kernel-provided library for GPIO
	    \- fb         <- a lightweight framebuffer library 

Zig’s build.zig

For this, the default build file is a good starting point. It takes few minutes to add a CrossTarget . For any external, non-Zig project, one just has to addIncludeDir and addObjectFile , and they’re good to go!

Bazel’s BUILD

Since I tried to take as much as I can from toying around, I used Bazel, as it’s quite a no-brainer to add simple dependencies.

For my WORKSPACE , the rules_foreign_cc is sufficient to compile the external dependencies. Since a toolchain is needed and I’m using Zig, why not use the Zig C compiler?

For the BUILD file, add a platform, the filegroups, and follow the rules’ documentation. CAREFUL: if you’re using musl, as I am, make sure to configure with ac_cv_func_malloc_0_nonnull=yes to avoid compilation problems.

How will it work?

Well, writing kernel modules seems like a total overkill for this. And since I got a bit into microkernels lately, I decided the best way would be if this is a daemon in userspace, which is fed data (text or images) through a socket.

Current status

I will put the code online once it’s finished.

I have to finish my high-precision soldering job and hope I got it right, before I can move on to testing. :}