-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
1 changed file
with
79 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
from LCD_API import LcdApi | ||
from machine import I2C | ||
from time import sleep_ms | ||
|
||
# Defines shifts or masks for the various LCD line attached to the PCF8574 | ||
# wire black to GND | ||
# wire white to VSYS | ||
# wire grey to GPIO 2 | ||
# wire purple to GPIO 3 | ||
|
||
# 8574AT chip = 0x3F address | ||
|
||
MASK_RS = 0x01 | ||
MASK_RW = 0x02 | ||
MASK_E = 0x04 | ||
SHIFT_BACKLIGHT = 3 | ||
SHIFT_DATA = 4 | ||
|
||
|
||
class I2CLcd(LcdApi): | ||
def __init__(self, i2c, i2c_addr, num_lines, num_columns): | ||
self.i2c = i2c | ||
self.i2c_addr = i2c_addr | ||
self.i2c.writeto(self.i2c_addr, bytearray([0])) | ||
sleep_ms(20) # Allow LCD time to powerup | ||
# Send reset 3 times | ||
self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) | ||
sleep_ms(5) # need to delay at least 4.1 msec | ||
self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) | ||
sleep_ms(1) | ||
self.hal_write_init_nibble(self.LCD_FUNCTION_RESET) | ||
sleep_ms(1) | ||
# Put LCD into 4 bit mode | ||
self.hal_write_init_nibble(self.LCD_FUNCTION) | ||
sleep_ms(1) | ||
LcdApi.__init__(self, num_lines, num_columns) | ||
cmd = self.LCD_FUNCTION | ||
if num_lines > 1: | ||
cmd |= self.LCD_FUNCTION_2LINES | ||
self.hal_write_command(cmd) | ||
|
||
def hal_write_init_nibble(self, nibble): | ||
"""Writes an initialization nibble to the LCD. | ||
This particular function is only used during initialization. | ||
""" | ||
byte = ((nibble >> 4) & 0x0f) << SHIFT_DATA | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E])) | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte])) | ||
|
||
def hal_backlight_on(self): | ||
"""Allows the hal layer to turn the backlight on.""" | ||
self.i2c.writeto(self.i2c_addr, bytearray([1 << SHIFT_BACKLIGHT])) | ||
|
||
def hal_backlight_off(self): | ||
"""Allows the hal layer to turn the backlight off.""" | ||
self.i2c.writeto(self.i2c_addr, bytearray([0])) | ||
|
||
def hal_write_command(self, cmd): | ||
"""Writes a command to the LCD. | ||
Data is latched on the falling edge of E. | ||
""" | ||
byte = ((self.backlight << SHIFT_BACKLIGHT) | (((cmd >> 4) & 0x0f) << SHIFT_DATA)) | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E])) | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte])) | ||
byte = ((self.backlight << SHIFT_BACKLIGHT) | ((cmd & 0x0f) << SHIFT_DATA)) | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E])) | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte])) | ||
if cmd <= 3: | ||
# The home and clear commands require a worst case delay of 4.1 msec | ||
sleep_ms(5) | ||
|
||
def hal_write_data(self, data): | ||
"""Write data to the LCD.""" | ||
byte = (MASK_RS | (self.backlight << SHIFT_BACKLIGHT) | (((data >> 4) & 0x0f) << SHIFT_DATA)) | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E])) | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte])) | ||
byte = (MASK_RS | (self.backlight << SHIFT_BACKLIGHT) | ((data & 0x0f) << SHIFT_DATA)) | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte | MASK_E])) | ||
self.i2c.writeto(self.i2c_addr, bytearray([byte])) |