class EmulateEfuseControllerBase(object): """ The class for virtual efuse operations. Using for HOST_TEST. """ CHIP_NAME = "" mem = None debug = False Blocks = None Fields = None REGS = None def __init__(self, efuse_file=None, debug=False): self.debug = debug self.efuse_file = efuse_file if self.efuse_file: try: self.mem = BitString(open(self.efuse_file, 'a+b'), length=(self.REGS.EFUSE_MEM_SIZE & self.REGS.EFUSE_ADDR_MASK) * 8) except ValueError: # the file is empty or does not fit the length. self.mem = BitString(length=(self.REGS.EFUSE_MEM_SIZE & self.REGS.EFUSE_ADDR_MASK) * 8) self.mem.set(0) self.mem.tofile(open(self.efuse_file, 'a+b')) else: # efuse_file is not provided it means we do not want to keep the result of efuse operations self.mem = BitString( (self.REGS.EFUSE_MEM_SIZE & self.REGS.EFUSE_ADDR_MASK) * 8) self.mem.set(0) """ esptool method start >> """ def read_efuse(self, n, block=0): """ Read the nth word of the ESP3x EFUSE region. """ blk = self.Blocks.get(self.Blocks.BLOCKS[block]) return self.read_reg(blk.rd_addr + (4 * n)) def read_reg(self, addr): self.mem.pos = self.mem.length - ( (addr & self.REGS.EFUSE_ADDR_MASK) * 8 + 32) return self.mem.read("uint:32") def write_reg(self, addr, value, mask=0xFFFFFFFF, delay_us=0, delay_after_us=0): self.mem.pos = self.mem.length - ( (addr & self.REGS.EFUSE_ADDR_MASK) * 8 + 32) self.mem.overwrite("uint:32={}".format(value & mask)) self.handle_writing_event(addr, value) def update_reg(self, addr, mask, new_val): position = self.mem.length - ( (addr & self.REGS.EFUSE_ADDR_MASK) * 8 + 32) self.mem.pos = position cur_val = self.mem.read("uint:32") self.mem.pos = position self.mem.overwrite("uint:32={}".format(cur_val | (new_val & mask))) def write_efuse(self, n, value, block=0): """ Write the nth word of the ESP3x EFUSE region. """ blk = self.Blocks.get(self.Blocks.BLOCKS[block]) self.write_reg(blk.wr_addr + (4 * n), value) """ << esptool method end """ def handle_writing_event(self, addr, value): self.save_to_file() def save_to_file(self): if self.efuse_file: with open(self.efuse_file, 'wb') as f: self.mem.tofile(f) def handle_coding_scheme(self, blk, data): return data def copy_blocks_wr_regs_to_rd_regs(self, updated_block=None): for b in reversed(self.Blocks.BLOCKS): blk = self.Blocks.get(b) if updated_block is not None: if blk.id != updated_block: continue data = self.read_block(blk.id, wr_regs=True) if self.debug: print(blk.name, data.hex) plain_data = self.handle_coding_scheme(blk, data) plain_data = self.check_wr_protection_area(blk.id, plain_data) self.update_block(blk, plain_data) def clean_blocks_wr_regs(self): for b in self.Blocks.BLOCKS: blk = self.Blocks.get(b) for offset in range(0, blk.len * 4, 4): wr_addr = blk.wr_addr + offset self.write_reg(wr_addr, 0) def read_field(self, name, bitstring=True): for e in self.Fields.EFUSES: field = self.Fields.get(e) if field.name == name: self.read_block(field.block) block = self.read_block(field.block) if field.type.startswith("bool"): field_len = 1 else: field_len = int(re.search(r'\d+', field.type).group()) if field.type.startswith("bytes"): field_len *= 8 block.pos = block.length - (field.word * 32 + field.pos + field_len) if bitstring: return block.read(field_len) else: return block.read(field.type) return None def get_bitlen_of_block(self, blk, wr=False): return 32 * blk.len def read_block(self, idx, wr_regs=False): block = None for b in self.Blocks.BLOCKS: blk = self.Blocks.get(b) if blk.id == idx: blk_len_bits = self.get_bitlen_of_block(blk, wr=wr_regs) addr = blk.wr_addr if wr_regs else blk.rd_addr self.mem.pos = self.mem.length - ( (addr & self.REGS.EFUSE_ADDR_MASK) * 8 + blk_len_bits) block = self.mem.read(blk_len_bits) break return block def update_block(self, blk, wr_data): wr_data = self.read_block(blk.id) | wr_data self.overwrite_mem_from_block(blk, wr_data) def overwrite_mem_from_block(self, blk, wr_data): self.mem.pos = self.mem.length - ( (blk.rd_addr & self.REGS.EFUSE_ADDR_MASK) * 8 + wr_data.len) self.mem.overwrite(wr_data) def check_wr_protection_area(self, num_blk, wr_data): # checks fields which have the write protection bit. # if the write protection bit is set then we need to protect that area from changes. write_disable_bit = self.read_field("WR_DIS", bitstring=False) mask_wr_data = BitString(len(wr_data)) mask_wr_data.set(0) blk = self.Blocks.get(self.Blocks.BLOCKS[num_blk]) if blk.write_disable_bit is not None and write_disable_bit & ( 1 << blk.write_disable_bit): mask_wr_data.set(1) else: for e in self.Fields.EFUSES: field = self.Fields.get(e) if blk.id == field.block and field.block == num_blk: if field.write_disable_bit is not None and write_disable_bit & ( 1 << field.write_disable_bit): data = self.read_field(field.name) data.set(1) mask_wr_data.pos = mask_wr_data.length - ( field.word * 32 + field.pos + data.len) mask_wr_data.overwrite(data) mask_wr_data.invert() return wr_data & mask_wr_data def check_rd_protection_area(self): # checks fields which have the read protection bits. # if the read protection bit is set then we need to reset this field to 0. read_disable_bit = self.read_field("RD_DIS", bitstring=False) for b in self.Blocks.BLOCKS: blk = self.Blocks.get(b) block = self.read_block(blk.id) if blk.read_disable_bit is not None and read_disable_bit & ( 1 << blk.read_disable_bit): block.set(0) else: for e in self.Fields.EFUSES: field = self.Fields.get(e) if blk.id == field.block and field.read_disable_bit is not None and read_disable_bit & ( 1 << field.read_disable_bit): raw_data = self.read_field(field.name) raw_data.set(0) block.pos = block.length - ( field.word * 32 + field.pos + raw_data.length) block.overwrite(BitString(raw_data.length)) self.overwrite_mem_from_block(blk, block) def clean_mem(self): self.mem.set(0) if self.efuse_file: with open(self.efuse_file, 'wb') as f: self.mem.tofile(f)
def generate(height, codepoints, font_file_path, output_file_name, packed, code, smoke): font = Font(font_file_path, height) if smoke: glyphs = [chr(x) for x in codepoints] f = sys.stdout.buffer if output_file_name is not None: f = open(output_file_name, 'wt') for cur_glyph in glyphs: ch = font.render_character(cur_glyph) f.write(cur_glyph + '\n') f.write(repr(ch)) f.write('\n\n') f.close() return ili9341_t3_font = OrderedDict() ili9341_t3_font['index'] = 0 ili9341_t3_font['unicode'] = 0 ili9341_t3_font['data'] = 0 ili9341_t3_font['version'] = 1 ili9341_t3_font['reserved'] = 0 ili9341_t3_font['index1_first'] = (len(codepoints) & 0xff00) >> 8 ili9341_t3_font['index1_last'] = len(codepoints) & 0xff ili9341_t3_font['index2_first'] = 0 ili9341_t3_font['index2_last'] = 0 ili9341_t3_font['bits_index'] = 0 ili9341_t3_font['bits_width'] = 0 ili9341_t3_font['bits_height'] = 0 ili9341_t3_font['bits_xoffset'] = 0 ili9341_t3_font['bits_yoffset'] = 0 ili9341_t3_font['bits_delta'] = 0 ili9341_t3_font['line_space'] = font.height e_cap = font.glyph_for_character('E') ili9341_t3_font['cap_height'] = e_cap.height - e_cap.descent max_width = 1 max_height = 1 max_xoffset = 1 max_yoffset = 1 max_delta = 1 glyph_data = dict() for codepoint in codepoints: cur_glyph = chr(codepoint) glyph_header = build_glyph(cur_glyph, font, glyph_data) max_width = max(max_width, glyph_header['width']) max_height = max(max_height, glyph_header['height']) max_xoffset = max(abs(max_xoffset), abs(glyph_header['xoffset'])) max_yoffset = max(abs(max_yoffset), abs(glyph_header['yoffset'])) max_delta = max(max_delta, glyph_header['delta']) ili9341_t3_font['bits_width'] = int(math.floor(math.log(max_width, 2))) + 1 ili9341_t3_font['bits_height'] = int(math.floor(math.log(max_height, 2))) + 1 ili9341_t3_font['bits_xoffset'] = int(math.floor(math.log(max_xoffset, 2))) + 2 ili9341_t3_font['bits_yoffset'] = int(math.floor(math.log(max_yoffset, 2))) + 2 ili9341_t3_font['bits_delta'] = int(math.floor(math.log(max_delta, 2))) + 1 output_data = bytearray() index = list() total_size = 0 for codepoint in codepoints: ch = chr(codepoint) index.append(total_size) glyph = glyph_data[ch] glyph_bytes = pack_glyph(glyph, ili9341_t3_font) output_data.extend(glyph_bytes) total_size += len(glyph_bytes) ili9341_t3_font['bits_index'] = int(math.floor(math.log(total_size, 2))) + 1 index_bits = BitString() for idx in index: index_bits.append(Bits(uint=idx, length=ili9341_t3_font['bits_index'])) codepoint_table = BitString() for codepoint in codepoints: codepoint_table.append(Bits(uint=codepoint, length=21)) if packed: f = sys.stdout.buffer if output_file_name is not None: f = open(output_file_name, 'wb') f.write(struct.pack('<3I14Bxx', *tuple(ili9341_t3_font.values()))) index_bits.tofile(f) codepoint_table.tofile(f) f.write(output_data) f.close() if code: f = sys.stdout.buffer if output_file_name is not None: f = open(output_file_name, 'wb') variable_name = os.path.splitext(os.path.basename(font_file_path))[0] + '_' + str(height) c = io.StringIO() c.write('// extern const ILI9341_t3_font_t {};\n\n'.format(variable_name)) c.write('static const unsigned char {}_data[] = {{\n'.format(variable_name)) data_byte_array = ['0x' + binascii.hexlify(bytes([x])).decode() for x in output_data] for i in range(0, len(data_byte_array), 10): c.write(','.join(data_byte_array[i:i + 10]) + ',\n') c.write('};\n') c.write('/* font data size: {} bytes */\n\n'.format(len(data_byte_array))) c.write('static const unsigned char {}_index[] = {{\n'.format(variable_name)) index_byte_array = ['0x' + binascii.hexlify(bytes([x])).decode() for x in index_bits.tobytes()] for i in range(0, len(index_byte_array), 10): c.write(','.join(index_byte_array[i:i + 10]) + ',\n') c.write('};\n') c.write('/* font index size: {} bytes */\n\n'.format(len(index_byte_array))) c.write('static const unsigned char {}_codepoints[] = {{\n'.format(variable_name)) codepoint_byte_array = ['0x' + binascii.hexlify(bytes([x])).decode() for x in codepoint_table.tobytes()] for i in range(0, len(codepoint_byte_array), 10): c.write(','.join(codepoint_byte_array[i:i + 10]) + ',\n') c.write('};\n') c.write('/* Unicode codepoint table size: {} bytes */\n\n'.format(len(codepoint_byte_array))) c.write('const ILI9341_t3_font_t {} = {{\n'.format(variable_name)) c.write(' {}_index,\n'.format(variable_name)) c.write(' {}_codepoints,\n'.format(variable_name)) c.write(' {}_data,\n'.format(variable_name)) c.write(' {},\n'.format(ili9341_t3_font['version'])) c.write(' {},\n'.format(ili9341_t3_font['reserved'])) c.write(' {},\n'.format(ili9341_t3_font['index1_first'])) c.write(' {},\n'.format(ili9341_t3_font['index1_last'])) c.write(' {},\n'.format(ili9341_t3_font['index2_first'])) c.write(' {},\n'.format(ili9341_t3_font['index2_last'])) c.write(' {},\n'.format(ili9341_t3_font['bits_index'])) c.write(' {},\n'.format(ili9341_t3_font['bits_width'])) c.write(' {},\n'.format(ili9341_t3_font['bits_height'])) c.write(' {},\n'.format(ili9341_t3_font['bits_xoffset'])) c.write(' {},\n'.format(ili9341_t3_font['bits_yoffset'])) c.write(' {},\n'.format(ili9341_t3_font['bits_delta'])) c.write(' {},\n'.format(ili9341_t3_font['line_space'])) c.write(' {}\n'.format(ili9341_t3_font['cap_height'])) c.write('};\n') f.write(c.getvalue().encode('ascii'))