-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsmlcd_shim.py
More file actions
126 lines (96 loc) · 4.23 KB
/
Copy pathsmlcd_shim.py
File metadata and controls
126 lines (96 loc) · 4.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
from hd44780 import HD44780
from memory import Memory
class SMlcd:
def __init__(self, i2c: int = 1, mmap_path: str | None = None):
self._hd = HD44780()
self._mem = Memory(self._hd, path=mmap_path)
self._encoder_changed = False
self.display_init()
def close(self):
self._mem.close()
@property
def hd(self) -> HD44780:
return self._hd
@property
def mem(self) -> Memory:
return self._mem
# display control
def display_init(self):
self.cmd(0x38) # function set: 8-bit, 2-line, 5x8
self.cmd(0x0C) # display on, cursor off, blink off
self.cmd(0x06) # entry mode: increment, no shift
self.cmd(0x01) # clear display
def cmd(self, value: int):
self._mem.registers[self._mem.I2C_LCD_DATA] = value
self._mem.write_data(self._mem.I2C_LCD_CMD, self._mem.LCD_INST_WR)
def data_write(self, value: int):
self._mem.registers[self._mem.I2C_LCD_DATA] = value
self._mem.write_data(self._mem.I2C_LCD_CMD, self._mem.LCD_DATA_WR)
def data_read(self) -> int:
self._mem.write_data(self._mem.I2C_LCD_CMD, self._mem.LCD_DATA_RD)
return self._mem.read_data(self._mem.I2C_LCD_DATA)
def busy(self) -> int:
self._mem.write_data(self._mem.I2C_LCD_CMD, self._mem.LCD_BUSY_RD)
return self._mem.read_data(self._mem.I2C_LCD_DATA)
# --- cursor & text ---
def cursor_set(self, line: int, column: int):
addr = self._hd._DDRAM_LINE_ADDR[line - 1] + (column - 1)
self.cmd(self._hd._INST_SET_DDRAM | addr)
def text_write(self, text: str):
for ch in text:
self.data_write(ord(ch))
def text_write_at(self, line: int, column: int, text: str):
self.cursor_set(line, column)
self.text_write(text)
# --- backlight ---
def bl_single(self, val: int):
self._mem.registers[self._mem.I2C_LCD_BL] = val
self._mem.registers[self._mem.I2C_LCD_BL_G] = val
self._mem.registers[self._mem.I2C_LCD_BL_B] = val
def bl_rgb(self, red: int, green: int, blue: int):
self._mem.registers[self._mem.I2C_LCD_BL] = red
self._mem.registers[self._mem.I2C_LCD_BL_G] = green
self._mem.registers[self._mem.I2C_LCD_BL_B] = blue
# buttons
def get_button(self, button: int) -> int:
return (self._mem.registers[self._mem.I2C_SW_MOM_ADD] >> (button - 1)) & 1
def get_all_buttons(self) -> int:
return self._mem.registers[self._mem.I2C_SW_MOM_ADD]
def get_button_int(self, button: int) -> int:
val = (self._mem.registers[self._mem.I2C_SW_INT_ADD] >> (button - 1)) & 1
self._mem.registers[self._mem.I2C_SW_INT_ADD] &= ~(1 << (button - 1))
return val
def get_all_buttons_int(self) -> int:
val = self._mem.registers[self._mem.I2C_SW_INT_ADD]
self._mem.registers[self._mem.I2C_SW_INT_ADD] = 0
return val
# encoder
def get_encoder_int(self) -> int:
changed = 1 if self._encoder_changed else 0
self._encoder_changed = False
return changed
def get_encoder_val(self) -> int:
lo = self._mem.registers[self._mem.I2C_ROTARY_VAL]
hi = self._mem.registers[self._mem.I2C_ROTARY_VAL + 1]
val = (hi << 8) | lo
if val >= 0x8000:
val -= 0x10000
return val
def reset_encoder(self):
self._mem.registers[self._mem.I2C_ROTARY_VAL] = 0
self._mem.registers[self._mem.I2C_ROTARY_VAL + 1] = 0
self._mem.registers[self._mem.I2C_ROTARY_RESET] = 1
# injection helpers (emulator-only)
def inject_button(self, button: int, pressed: bool):
if pressed:
self._mem.registers[self._mem.I2C_SW_MOM_ADD] |= (1 << (button - 1))
self._mem.registers[self._mem.I2C_SW_INT_ADD] |= (1 << (button - 1))
else:
self._mem.registers[self._mem.I2C_SW_MOM_ADD] &= ~(1 << (button - 1))
def inject_encoder(self, delta: int):
current = self.get_encoder_val()
new_val = max(-32767, min(32767, current + delta))
raw = new_val & 0xFFFF
self._mem.registers[self._mem.I2C_ROTARY_VAL] = raw & 0xFF
self._mem.registers[self._mem.I2C_ROTARY_VAL + 1] = (raw >> 8) & 0xFF
self._encoder_changed = True