If you would like to generate the init code for CircuitPython, you can do so in a couple of ways with the conversion script below. In both ways you will need to run it using Python on your computer. Start by saving the code below as convert_initcode.py.
# convert_initcode.py # MIT license import re ( BEGIN_WRITE, WRITE_COMMAND_8, WRITE_COMMAND_16, WRITE_DATA_8, WRITE_DATA_16, WRITE_BYTES, WRITE_C8_D8, WRITE_C8_D16, WRITE_C16_D16, END_WRITE, DELAY, ) = range(11) class Encoder: def __init__(self): self.content = bytearray() self.reset() def command(self, command): if self.pending_command is not None: self.flush() self.pending_command = command self.pending_data = bytearray() def data(self, data): self.pending_data.append(data) def delay(self, value): self.pending_delay = value def flush(self): if self.pending_command is not None: self.content.append(self.pending_command) len_and_delay = len(self.pending_data) | (bool(self.pending_delay) << 7) self.content.append(len_and_delay) self.content.extend(self.pending_data) if self.pending_delay: self.content.append(self.pending_delay) print(f" {bytes(self.content)}") self.reset() def reset(self): self.pending_command = None self.pending_data = bytearray() self.pending_delay = 0 self.content = bytearray() def translate_init_operations(*initcode): initcode = iter(initcode) encoder = Encoder() print("init_code = bytes((") for op in initcode: if op in (BEGIN_WRITE, END_WRITE): continue elif op == WRITE_COMMAND_8: encoder.command(next(initcode)) elif op == WRITE_C8_D8: encoder.command(next(initcode)) encoder.data(next(initcode)) elif op == WRITE_C8_D16: encoder.command(next(initcode)) encoder.data(next(initcode)) encoder.data(next(initcode)) elif op == WRITE_BYTES: for _ in range(next(initcode)): encoder.data(next(initcode)) elif op == DELAY: encoder.delay(next(initcode)) else: raise ValueError(f"Invalid operation 0x{op:02x}") encoder.flush() print("))") def translate_init_file(initcode_filename): initcode_regex = r"\( *0x([0-9a-fA-F]+) *\);" command_data_regex = r"\( *0x([0-9a-fA-F]+), *0x([0-9a-fA-F]+) *\);" delay_regex = r"\( *(\d+) *\);" # Init code files are inconsistent in their naming of command, data, and delay functions command8_values = ("SPI_WriteComm", "W_C", "WriteCommand", "WriteComm") data_values = ("SPI_WriteData", "W_D", "WriteParameter", "WriteData") delay_values = ("Delayms", "Delay", "Delay_ms") encoder = Encoder() def get_command8(line): for command in command8_values: if command in line: encoder.command(get_initcode8(line)) return True return False def get_data(line): for data in data_values: if data in line: encoder.data(get_initcode8(line)) return True return False def get_delay(line): for delay in delay_values: if delay in line: encoder.delay(get_delay_value(line)) return True return False def get_initcode8(line): match = re.search(initcode_regex, line) if match: return int(match.group(1), 16) raise ValueError(f"Warning: could not parse initcode in line '{line}'") def get_initcode16(line): match = re.search(command_data_regex, line) if match: command = int(match.group(1), 16) data = int(match.group(2), 16) return command, data raise ValueError(f"Warning: could not parse initcode in line '{line}'") def get_delay_value(line): match = re.search(delay_regex, line) if match: return int(match.group(1)) raise ValueError(f"Warning: could not parse delay in line '{line}'") with open(initcode_filename, encoding='utf-8', errors='ignore') as f: print("init_code = bytes((") for line in f.readlines(): line = line.strip() # Remove comments or commented out code line = line.split("//")[0] if get_command8(line): continue if get_data(line): continue if get_delay(line): continue if "Wrt_Reg_3052" in line: command, data = get_initcode16(line) encoder.command(command) encoder.data(data) encoder.flush() print("))")
To use the code, you can just import the conversion script into your own code:
from convert_initcode import *
Using Arduino_GFX Init Codes
The first method is to convert the codes from the Arduino_GFX library, which can be found at https://github.com/moononournation/Arduino_GFX. The initialization codes for the dot clock displays are found inside of src/display/Arduino_RGB_Display.h by searching for the display's model number.
In your main script, just call translate_init_operations()
like this:
translate_init_operations( WRITE_COMMAND_8, 0xFF, WRITE_BYTES, 5, 0x77, 0x01, 0x00, 0x00, 0x13, WRITE_C8_D8, 0xEF, 0x08, ... )
These operations are supported: COMMAND_8
, C8_D8
, C8_D16
, WRITE_BYTES
. Adding support for WRITE_DATA_8
and WRITE_DATA_16
"should be easy" but it was not used in any examples so far.
It's assumed that BEGIN_WRITE
/END_WRITE
are not 'important'. However, DELAY
is accounted for.
Using Init Code Files
The second method is by using one of the init code files found on the product page for the display. Near the bottom of the page under Technical Details, most of the displays have a link to a file containing the init codes. Just save the file to your computer as something like display_init_codes.txt.
Then to convert the file, in your main script, just run translate_init_file()
like this:
translate_init_file("display_init_codes.txt")
Text editor powered by tinymce.