Skip to content

dcharles525/smulator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

smulator

Terminal emulator for the Sequent Microsystems SMLCD 4x20 LCD HAT. Runs on any machine without the hardware, with a drop-in replacement for the SMlcd Python library.

╔══════════════════════════════╗
║        SMLCD EMULATOR        ║
╠══════════════════════════════╣
║ LCD DISPLAY                  ║
║     == SMLCD Emulator ==     ║
║        Hello, World!         ║
║       Type to write...       ║
║       q=quit  c=clear        ║
╠══════════════════════════════╣
║ Disp:ON  Cursor:BLK  AC:0x68 ║
║ Backlight R: 50 G:200 B: 50  ║
║ Line:1 Col:00  Encoder:  300 ║
╠══════════════════════════════╣
║  1   2   3   4   5   6       ║
╠══════════════════════════════╣
║ 1-4:line  <->  c:clr  q:quit ║
║ +/-:BL  !@#$%^:btn toggle    ║
╚══════════════════════════════╝

Requirements

Python 3.10+. No external dependencies.

Running the TUI

python3 tui.py

This launches an interactive terminal display showing the LCD contents, backlight values, button states, and encoder position.

TUI Controls

Key Action
1 2 3 4 Jump cursor to that line
LEFT / RIGHT Move cursor left / right
Any printable char Write character at cursor
Backspace Delete character to the left
+ / - Increase / decrease backlight brightness
! @ # $ % ^ Toggle buttons 1-6 (Shift+1 through Shift+6)
c Clear display
q / Ctrl+C Quit

Using the Shim

smlcd_shim.py implements the same interface as SMlcd from the real library. Swap the import and everything else stays the same:

# Real hardware
from smlcd import SMlcd
lcd = SMlcd(1)

# Emulator
from smlcd_shim import SMlcd
lcd = SMlcd()

All SMlcd methods are implemented: cmd, data_write, data_read, busy, cursor_set, text_write, text_write_at, bl_single, bl_rgb, get_button, get_all_buttons, get_button_int, get_all_buttons_int, get_encoder_int, get_encoder_val, reset_encoder.

Two emulator-only helpers are available for scripted testing:

lcd.inject_button(3, True)   # press button 3
lcd.inject_encoder(10)       # rotate encoder by +10

Shared memory

Pass mmap_path to share the register state across processes. The file is created automatically if it does not exist.

# Process A: emulator
lcd = SMlcd(mmap_path='/tmp/smlcd.mmap')
tui = TUI(lcd.hd, lcd.mem)
tui.run()

# Process B: reads the same state
import mmap
from memory import Memory
with open('/tmp/smlcd.mmap', 'r+b') as f:
    shm = mmap.mmap(f.fileno(), 256)
    backlight = shm[Memory.I2C_LCD_BL]

Design Decisions

Three-layer architecture. HD44780 models the controller chip (DDRAM, CGRAM, instruction decode). Memory models the I2C register map that sits between the Pi and the chip on the real hardware. SMlcd is the user-facing API. Keeping these separate means the register map and the chip logic can be tested independently.

Flat DDRAM array. The HD44780 uses non-contiguous DDRAM addresses for a 4-line display: lines start at 0x00, 0x40, 0x14, 0x54. The emulator allocates 104 bytes to cover the full address range (0x00 to 0x67) rather than remapping, matching how the hardware actually works.

mmap-backed registers. Memory.registers is optionally backed by mmap rather than a bytearray. The two share the same index/slice interface, so no other code changes. This allows an external process to read and write the register file directly without any IPC layer.

No smbus2 dependency. Rather than shimming smbus2, the emulator replicates the SMlcd class interface directly. Code that uses SMlcd needs only a one-line import change to run against the emulator.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages