diff --git a/Firmware/Fonts/FontGen.py b/Firmware/Fonts/FontGen.py index 5cfc1e652..1e8dbe660 100644 --- a/Firmware/Fonts/FontGen.py +++ b/Firmware/Fonts/FontGen.py @@ -42,13 +42,25 @@ fontTable = [ def generateLineInTable(index, chars): pixels = chars[index]["PIXELS"].split(',') + + # Generate the rows binary data rows = [] for i in range(8): rows.append(0) for j in range(5): rows[i] |= (1 << (5 - j - 1)) if pixels[j * 8 + i] == "0" else 0 - line = "{{" - for r in rows: + + # compress the rows data + colByte = 0 + compressedRows = [] + for i in range(4): + rowByte = ((rows[i * 2 + 1] >> 1) & 0xF) | (((rows[i * 2 + 0] >> 1) & 0xF) << 4) + colByte |= (1 << i * 2 + 0) if (rows[i * 2 + 0] & 0x1) else 0 + colByte |= (1 << i * 2 + 1) if (rows[i * 2 + 1] & 0x1) else 0 + compressedRows.append(rowByte) + + line = f"{{0x{colByte:02X}, {{" + for r in compressedRows: line += f"0x{r:02X}, " line += f"}}, '{fontTable[index].alternate}'}}, // '{fontTable[index].utf}', \\x{fontTable[index].default:02X}" return line diff --git a/Firmware/Fonts/FontTable.h b/Firmware/Fonts/FontTable.h index 0dc1e6eae..385ae4f0c 100644 --- a/Firmware/Fonts/FontTable.h +++ b/Firmware/Fonts/FontTable.h @@ -1,18 +1,18 @@ -{{0x00, 0x1F, 0x15, 0x11, 0x15, 0x1F, 0x00, 0x00, }, 'H'}, // '๐Ÿ„ท', \x80 -{{0x0C, 0x12, 0x12, 0x0C, 0x00, 0x00, 0x00, 0x00, }, '\xdf'}, // 'ยฐ', \x81 -{{0x04, 0x0A, 0x0A, 0x0A, 0x0A, 0x11, 0x11, 0x0E, }, 'h'}, // '๐ŸŒก', \x82 -{{0x04, 0x0E, 0x1F, 0x04, 0x1C, 0x00, 0x00, 0x00, }, '^'}, // 'โฌ', \x83 -{{0x00, 0x06, 0x19, 0x18, 0x03, 0x13, 0x0C, 0x00, }, '\xf3'}, // '๐Ÿ”ƒ', \x84 -{{0x00, 0x1C, 0x1F, 0x11, 0x11, 0x1F, 0x00, 0x00, }, '\xdb'}, // '๐Ÿ—€', \x85 -{{0x00, 0x04, 0x12, 0x09, 0x12, 0x04, 0x00, 0x00, }, '>'}, // 'ยป', \x86 -{{0x00, 0x0E, 0x13, 0x15, 0x11, 0x0E, 0x00, 0x00, }, '\xe5'}, // '๐Ÿ•‘', \x87 -{{0x00, 0x00, 0x11, 0x0A, 0x04, 0x11, 0x0A, 0x04, }, '\x7e'}, // 'โฌ', \x88 -{{0x00, 0x01, 0x03, 0x16, 0x1C, 0x08, 0x00, 0x00, }, '\x7e'}, // 'โœ”', \x89 -{{0x11, 0x0E, 0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0F, }, 'a'}, // 'ฤƒ', \x8A -{{0x04, 0x0A, 0x00, 0x0E, 0x01, 0x0F, 0x11, 0x0F, }, 'a'}, // 'รข', \x8B -{{0x04, 0x0A, 0x00, 0x0C, 0x04, 0x04, 0x04, 0x0E, }, 'i'}, // 'รฎ', \x8C -{{0x00, 0x0E, 0x10, 0x0E, 0x01, 0x1E, 0x04, 0x08, }, 's'}, // 'ศ™', \x8D -{{0x08, 0x1C, 0x08, 0x08, 0x09, 0x06, 0x04, 0x08, }, 't'}, // 'ศ›', \x8E -{{0x04, 0x0A, 0x00, 0x0E, 0x04, 0x04, 0x04, 0x0E, }, 'I'}, // 'รŽ', \x8F -{{0x0E, 0x11, 0x0C, 0x06, 0x11, 0x0E, 0x04, 0x08, }, 'S'}, // 'ศ˜', \x90 -{{0x1F, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x08, }, 'T'}, // 'ศš', \x91 +{0x3E, {0x0F, 0xA8, 0xAF, 0x00, }, 'H'}, // '๐Ÿ„ท', \x80 +{0x00, {0x69, 0x96, 0x00, 0x00, }, '\xdf'}, // 'ยฐ', \x81 +{0x60, {0x25, 0x55, 0x58, 0x87, }, 'h'}, // '๐ŸŒก', \x82 +{0x04, {0x27, 0xF2, 0xE0, 0x00, }, '^'}, // 'โฌ', \x83 +{0x34, {0x03, 0xCC, 0x19, 0x60, }, '\xf3'}, // '๐Ÿ”ƒ', \x84 +{0x3C, {0x0E, 0xF8, 0x8F, 0x00, }, '\xdb'}, // '๐Ÿ—€', \x85 +{0x08, {0x02, 0x94, 0x92, 0x00, }, '>'}, // 'ยป', \x86 +{0x1C, {0x07, 0x9A, 0x87, 0x00, }, '\xe5'}, // '๐Ÿ•‘', \x87 +{0x24, {0x00, 0x85, 0x28, 0x52, }, '\x7e'}, // 'โฌ', \x88 +{0x06, {0x00, 0x1B, 0xE4, 0x00, }, '\x7e'}, // 'โœ”', \x89 +{0xF1, {0x87, 0x07, 0x07, 0x87, }, 'a'}, // 'ฤƒ', \x8A +{0xF0, {0x25, 0x07, 0x07, 0x87, }, 'a'}, // 'รข', \x8B +{0x00, {0x25, 0x06, 0x22, 0x27, }, 'i'}, // 'รฎ', \x8C +{0x10, {0x07, 0x87, 0x0F, 0x24, }, 's'}, // 'ศ™', \x8D +{0x10, {0x4E, 0x44, 0x43, 0x24, }, 't'}, // 'ศ›', \x8E +{0x00, {0x25, 0x07, 0x22, 0x27, }, 'I'}, // 'รŽ', \x8F +{0x12, {0x78, 0x63, 0x87, 0x24, }, 'S'}, // 'ศ˜', \x90 +{0x01, {0xF2, 0x22, 0x20, 0x24, }, 'T'}, // 'ศš', \x91 diff --git a/Firmware/lcd.cpp b/Firmware/lcd.cpp index 818e4eead..0fc507384 100644 --- a/Firmware/lcd.cpp +++ b/Firmware/lcd.cpp @@ -376,13 +376,42 @@ void lcd_set_cursor_column(uint8_t col) // Allows us to fill the first 8 CGRAM locations // with custom characters -void lcd_createChar_P(uint8_t location, const uint8_t* charmap) +void lcd_createChar_P(uint8_t location, const CustomCharacter *char_p) { - location &= 0x7; // we only have 8 locations 0-7 - lcd_command(LCD_SETCGRAMADDR | (location << 3)); - for (uint8_t i = 0; i < 8; i++) - lcd_send(pgm_read_byte(&charmap[i]), HIGH); - lcd_command(LCD_SETDDRAMADDR | lcd_ddram_address); // no need for masking the address + uint8_t charmap[8]; + + uint8_t temp; + uint8_t colByte; + __asm__ __volatile__ ( + // load colByte + "lpm %1, Z+" "\n\t" + + // begin for loop + "ldi %0, 8" "\n\t" + "mov __zero_reg__, %0" "\n\t" // use zero_reg as loop counter + "forBegin_%=: " "\n\t" + "sbrs __zero_reg__, 0" "\n\t" // test LSB of counter. Fetch new data if counter is even + "lpm __tmp_reg__, Z+" "\n\t" // load next data byte from progmem, increment + "swap __tmp_reg__" "\n\t" // swap the nibbles + "mov %0, __tmp_reg__" "\n\t" // copy row data to temp + + "andi %0, 0xF" "\n\t" // mask lower nibble + "ror %1" "\n\t" // consume LSB of colByte and push it to the carry + "rol %0" "\n\t" // insert the column LSB from carry + "st %a3+, %0" "\n\t" // push the generated row data to the output + // end for loop + "dec __zero_reg__" "\n\t" + "brne forBegin_%=" "\n\t" + + : "=&d" (temp), "=&r" (colByte) + : "z" (char_p), "e" (charmap) + ); + + lcd_command(LCD_SETCGRAMADDR | (location << 3)); + for (uint8_t i = 0; i < 8; i++) { + lcd_send(charmap[i], HIGH); + } + lcd_command(LCD_SETDDRAMADDR | lcd_ddram_address); // no need for masking the address } #ifdef VT100 @@ -854,7 +883,7 @@ static void lcd_print_custom(uint8_t c) { // try to find a slot where it could be placed for (uint8_t i = 0; i < 8; i++) { if (lcd_custom_characters[i] == 0x7F) { //found an empty slot. create a new custom character and send it - lcd_createChar_P(i, Font[c - 0x80].data); + lcd_createChar_P(i, &Font[c - 0x80]); lcd_custom_characters[i] = c; // mark the custom character as used #ifdef DEBUG_CUSTOM_CHARACTERS printf_P(PSTR("created char %02x at slot %u\n"), c, i); diff --git a/Firmware/lcd.h b/Firmware/lcd.h index 3d0d22b63..8bce8a394 100644 --- a/Firmware/lcd.h +++ b/Firmware/lcd.h @@ -186,8 +186,9 @@ private: #define LCD_STR_SOLID_BLOCK "\xFF" //from the default character set struct CustomCharacter { - const uint8_t data[8]; - const char alternate; + uint8_t colByte; + uint8_t rowData[4]; + char alternate; }; extern void lcd_frame_start();