Original Board: Raspberry Pi 4 model B New Board: Up Squared 7100 LCD: NHD-PCB12832A1Zrev2
import RPi.GPIO as GPIO
from ascii_values import ASCII168
import icon_manager
# Mapping based on BCM (Broadcom) pinout from /
LCD_CS = 8
LCD_RST = 22
LCD_A0 = 23
LCD_CLK = 11
LCD_SI = 10
class LCD:
_instance = None
def __new__(cls, *args, **kwargs):
"""Ensure only one instance of the LCD class exists."""
if cls._instance is None:
cls._instance = super(LCD, cls).__new__(cls)
cls._instance._initialize_lcd()
return cls._instance
def __del__(self):
GPIO.cleanup()
def _initialize_lcd(self):
self.io_init()
self.lcd_init()
GPIO.setwarnings(False)
def cleanup(self):
GPIO.cleanup()
def io_init(self):
GPIO.setmode(GPIO.BCM)
GPIO.setup(LCD_CS, GPIO.OUT)
GPIO.setup(LCD_RST, GPIO.OUT)
GPIO.setup(LCD_A0, GPIO.OUT)
GPIO.setup(LCD_CLK, GPIO.OUT)
GPIO.setup(LCD_SI, GPIO.OUT)
def lcd_init(self):
GPIO.output(LCD_CS, True)
GPIO.output(LCD_RST, False)
GPIO.output(LCD_RST, True)
self.lcd_transfer_data(0xe2, 0) # Internal reset
self.lcd_transfer_data(0xa2, 0) # Sets the LCD drive voltage bias ratio
##A2: 1/9 bias
##A3: 1/7 bias (ST7565V)
self.lcd_transfer_data(0xa0, 0) # Sets the display RAM address SEG output correspondence
##A0: normal
##A1: reverse
self.lcd_transfer_data(0xc8, 0) # Select COM output scan direction
##C0~C7: normal direction
##C8~CF: reverse direction
self.lcd_transfer_data(0xa4, 0) # Display all points ON/OFF
##A4: normal display
##A5: all points ON
self.lcd_transfer_data(0xa6, 0) # Sets the LCD display normal/inverted
##A6: normal
##A7: inverted
self.lcd_transfer_data(0x2F, 0) # Select internal power supply operating mode
##28~2F: Operating mode
self.lcd_transfer_data(0x40, 0) # Display start line set
##40~7F: Display start address
self.lcd_transfer_data(0x20, 0) # V5 voltage regulator internal resistor ratio set (contrast)
##20~27: small~large
self.lcd_transfer_data(0x81, 0) # Electronic volume mode set
##81: Set the V5 output voltage
self.lcd_transfer_data(0x30, 0) # Electronic volume register set
##00~3F: electronic volume register
self.lcd_transfer_data(0b10101111, 0) # Display ON/OFF
## 0b10101111: ON
## 0b10101110: OFF
self.lcd_clear()
def display_icon(self, x_pos, y_pos, icon, negative=False):
icon_matrix = icon_manager.format_icon(icon, negative)
if not isinstance(icon_matrix, list) or not all(isinstance(i, int) for i in icon_matrix):
raise TypeError("icon_matrix must be a list of integers")
quadrant_offsets = [
(0, 0, 0, 8), # Quadrant 1: Top-left
(1, 0, 8, 16), # Quadrant 2: Bottom-left
(0, 8, 16, 24), # Quadrant 3: Top-right
(1, 8, 24, 32), # Quadrant 4: Bottom-right
]
for y_offset, x_offset, start_idx, end_idx in quadrant_offsets:
self.lcd_set_page(y_pos + y_offset, x_pos + x_offset)
# Transfer the entire quadrant data at once
data = icon_matrix[start_idx:end_idx]
self.lcd_transfer_data_bulk(data)
def lcd_ascii168_string(self, x_pos, y_pos, string):
string_len = len(string)
for i in range(0, string_len):
self.lcd_ascii168(x_pos + i * 8, y_pos, ord(string[i]) - 32)
def lcd_ascii168(self, x_pos, y_pos, char):
self.lcd_set_page(y_pos, x_pos)
for i in range(0, 8):
self.lcd_transfer_data(ASCII168[char][i], 1)
self.lcd_set_page(y_pos + 1, x_pos)
for i in range(8, 16):
self.lcd_transfer_data(ASCII168[char][i], 1)
def lcd_clear(self):
GPIO.output(LCD_CS, False)
for i in range(0, 8):
self.lcd_set_page(i, 0)
for j in range(0, 128):
self.lcd_transfer_data(0x00, 1)
GPIO.output(LCD_CS, True)
def lcd_set_page(self, page, column):
lsb = column & 0x0f
msb = column & 0xf0
msb >>= 4
msb |= 0x10
page |= 0xb0
self.lcd_transfer_data(page, 0)
self.lcd_transfer_data(msb, 0)
self.lcd_transfer_data(lsb, 0)
def lcd_transfer_data(self, value, A0):
GPIO.output(LCD_CS, False)
GPIO.output(LCD_CLK, True)
if (A0):
GPIO.output(LCD_A0, True)
else:
GPIO.output(LCD_A0, False)
self.lcd_byte(value)
GPIO.output(LCD_CS, True)
def lcd_transfer_data_bulk(self, data_list):
"""Transfers a list of data in bulk, minimizing GPIO operations."""
GPIO.output(LCD_CS, False)
GPIO.output(LCD_CLK, True)
for data in data_list:
GPIO.output(LCD_A0, True) # Data mode
self.lcd_byte(data)
GPIO.output(LCD_CS, True)
def lcd_byte(self, bits):
tmp = bits
for i in range(0, 8):
GPIO.output(LCD_CLK, False)
if (tmp & 0x80):
GPIO.output(LCD_SI, True)
else:
GPIO.output(LCD_SI, False)
tmp = (tmp << 1)
GPIO.output(LCD_CLK, True)
I am able to send data to display on the LCD using the RPi.GPIO package; however, I want to run the code on an up squared board and the RPi.GPIO package does not work on a non-raspberry pi.
I am using an UP Squared 7100 that has the same 40 pin header as a Raspberry Pi. I am trying to connect to the LCD using the spidev package