diff --git a/Scan/STLcd/DOS_8x8.h b/Scan/STLcd/DOS_8x8.h new file mode 100644 index 000000000..105238eeb --- /dev/null +++ b/Scan/STLcd/DOS_8x8.h @@ -0,0 +1,149 @@ +/* "DOS 8x8" font by Neil Roy + * Licensed under Creative Commons Attribution ShareAlike 3.0 (CC-BY-SA 3.0) + * See: https://creativecommons.org/licenses/by-sa/3.0/ + * Original: http://opengameart.org/content/dos-8x8-font + * + * This file contains the hexadecimal representation of the "DOS 8x8" bitmap + * font for code points 0-127. "DOS 8x8" contains the Code Page 437 characters. + * I.e., it contains dingbats instead of ASCII control codes. Note that + * character \010 is an inverse circle rather than the standard rectangle. + * + * The original "DOS 8x8" artwork has been modified as follows: Character \124 + * has been changed from a broken bar to an unbroken bar. + */ + +#pragma once + +#include + +uint8_t font_8x8[128][8] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // \000 nul + { 0x7E, 0x81, 0xA9, 0x8D, 0x8D, 0xA9, 0x81, 0x7E }, // \001 smiley + { 0x7E, 0xFF, 0xD7, 0xF3, 0xF3, 0xD7, 0xFF, 0x7E }, // \002 inverse smiley + { 0x70, 0xF8, 0xFC, 0x7E, 0xFC, 0xF8, 0x70, 0x00 }, // \003 heart + { 0x10, 0x38, 0x7C, 0xFE, 0x7C, 0x38, 0x10, 0x00 }, // \004 diamond + { 0x1C, 0x5C, 0xF9, 0xFF, 0xF9, 0x5C, 0x1C, 0x00 }, // \005 club + { 0x08, 0x1C, 0x3D, 0xFF, 0x3D, 0x1C, 0x08, 0x00 }, // \006 spade + { 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 }, // \007 bullet + { 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF }, // \008 inverse bullet + { 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 }, // \009 circle + { 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF }, // \010 inverse circle + { 0x0E, 0x1F, 0x11, 0x11, 0xBF, 0xFE, 0xE0, 0xF0 }, // \011 mars + { 0x00, 0x72, 0xFA, 0x8F, 0x8F, 0xFA, 0x72, 0x00 }, // \012 venus + { 0x03, 0x07, 0xFF, 0xFE, 0xA0, 0xA0, 0xE0, 0xE0 }, // \013 eighth note + { 0x03, 0xFF, 0xFE, 0xA0, 0xA0, 0xA6, 0xFE, 0xFC }, // \014 beamed eighth note + { 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99 }, // \015 solar + { 0xFE, 0x7C, 0x7C, 0x38, 0x38, 0x10, 0x10, 0x00 }, // \016 right-pointing triangle + { 0x10, 0x10, 0x38, 0x38, 0x7C, 0x7C, 0xFE, 0x00 }, // \017 left-pointing triangle + { 0x00, 0x24, 0x66, 0xFF, 0xFF, 0x66, 0x24, 0x00 }, // \018 up-down arrow + { 0x00, 0xFA, 0xFA, 0x00, 0x00, 0xFA, 0xFA, 0x00 }, // \019 !! + { 0x60, 0xF0, 0x90, 0xFE, 0xFE, 0x80, 0xFE, 0xFE }, // \020 pilcrow + { 0x5B, 0xFD, 0xA5, 0xA5, 0xBF, 0x9A, 0xC0, 0x70 }, // \021 section + { 0x00, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x00 }, // \022 rectangle + { 0x01, 0x29, 0x6D, 0xFF, 0xFF, 0x6D, 0x29, 0x01 }, // \023 up-down arrow with base + { 0x00, 0x20, 0x60, 0xFE, 0xFE, 0x60, 0x20, 0x00 }, // \024 up arrow + { 0x00, 0x08, 0x0C, 0xFE, 0xFE, 0x0C, 0x08, 0x00 }, // \025 down arrow + { 0x10, 0x10, 0x10, 0x54, 0x7C, 0x38, 0x10, 0x00 }, // \026 right arrow + { 0x10, 0x38, 0x7C, 0x54, 0x10, 0x10, 0x10, 0x00 }, // \027 left arrow + { 0x3C, 0x3C, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00 }, // \028 right angle + { 0x10, 0x38, 0x7C, 0x10, 0x10, 0x7C, 0x38, 0x10 }, // \029 left-rigth arrow + { 0x0C, 0x1C, 0x3C, 0x7C, 0x7C, 0x3C, 0x1C, 0x0C }, // \030 up-pointing triangle + { 0x60, 0x70, 0x78, 0x7C, 0x7C, 0x78, 0x70, 0x60 }, // \031 down-pointing triangle + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // \032 space + { 0x00, 0x60, 0xFA, 0xFA, 0x60, 0x00, 0x00, 0x00 }, // \033 ! + { 0x00, 0xE0, 0xE0, 0x00, 0xE0, 0xE0, 0x00, 0x00 }, // \034 " + { 0x28, 0xFE, 0xFE, 0x28, 0xFE, 0xFE, 0x28, 0x00 }, // \035 # + { 0x24, 0x74, 0xD6, 0xD6, 0x5C, 0x48, 0x00, 0x00 }, // \036 $ + { 0x62, 0x66, 0x0C, 0x18, 0x30, 0x66, 0x46, 0x00 }, // \037 % + { 0x0C, 0x5E, 0xF2, 0xBA, 0xEC, 0x5E, 0x12, 0x00 }, // \038 & + { 0x20, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00 }, // \039 ' + { 0x00, 0x38, 0x7C, 0xC6, 0x82, 0x00, 0x00, 0x00 }, // \040 ( + { 0x00, 0x82, 0xC6, 0x7C, 0x38, 0x00, 0x00, 0x00 }, // \041 ) + { 0x10, 0x54, 0x7C, 0x38, 0x38, 0x7C, 0x54, 0x10 }, // \042 * + { 0x10, 0x10, 0x7C, 0x7C, 0x10, 0x10, 0x00, 0x00 }, // \043 + + { 0x00, 0x05, 0x07, 0x06, 0x00, 0x00, 0x00, 0x00 }, // \044 , + { 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00 }, // \045 - + { 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00 }, // \046 . + { 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00 }, // \047 / + { 0x7C, 0xFE, 0x9A, 0xB2, 0xFE, 0x7C, 0x00, 0x00 }, // \048 0 + { 0x42, 0x42, 0xFE, 0xFE, 0x02, 0x02, 0x00, 0x00 }, // \049 1 + { 0x46, 0xCE, 0x9A, 0x92, 0xF6, 0x66, 0x00, 0x00 }, // \050 2 + { 0x44, 0xC6, 0x92, 0x92, 0xFE, 0x6C, 0x00, 0x00 }, // \051 3 + { 0x18, 0x38, 0x68, 0xC8, 0xFE, 0xFE, 0x08, 0x00 }, // \052 4 + { 0xE4, 0xE6, 0xA2, 0xA2, 0xBE, 0x9C, 0x00, 0x00 }, // \053 5 + { 0x3C, 0x7E, 0xD2, 0x92, 0x9E, 0x0C, 0x00, 0x00 }, // \054 6 + { 0xC0, 0xC6, 0x8E, 0x98, 0xF0, 0xE0, 0x00, 0x00 }, // \055 7 + { 0x6C, 0xFE, 0x92, 0x92, 0xFE, 0x6C, 0x00, 0x00 }, // \056 8 + { 0x60, 0xF2, 0x92, 0x96, 0xFC, 0x78, 0x00, 0x00 }, // \057 9 + { 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00 }, // \058 : + { 0x00, 0x05, 0x37, 0x36, 0x00, 0x00, 0x00, 0x00 }, // \059 ; + { 0x10, 0x38, 0x6C, 0xC6, 0x82, 0x00, 0x00, 0x00 }, // \060 < + { 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00 }, // \061 = + { 0x00, 0x82, 0xC6, 0x6C, 0x38, 0x10, 0x00, 0x00 }, // \062 > + { 0x40, 0xC0, 0x8A, 0x9A, 0xF0, 0x60, 0x00, 0x00 }, // \063 ? + { 0x3C, 0xFE, 0x82, 0xBA, 0xBA, 0xF8, 0x78, 0x00 }, // \064 @ + { 0x3E, 0x7E, 0xC8, 0xC8, 0x7E, 0x3E, 0x00, 0x00 }, // \065 A + { 0x82, 0xFE, 0xFE, 0x92, 0x92, 0xFE, 0x6C, 0x00 }, // \066 B + { 0x38, 0x7C, 0xC6, 0x82, 0x82, 0xC6, 0x44, 0x00 }, // \067 C + { 0x82, 0xFE, 0xFE, 0x82, 0xC6, 0xFE, 0x38, 0x00 }, // \068 D + { 0x82, 0xFE, 0xFE, 0x92, 0xBA, 0x82, 0xC6, 0x00 }, // \069 E + { 0x82, 0xFE, 0xFE, 0x92, 0xB8, 0x80, 0xC0, 0x00 }, // \070 F + { 0x38, 0x7C, 0xC6, 0x82, 0x8A, 0xCE, 0x4E, 0x00 }, // \071 G + { 0xFE, 0xFE, 0x10, 0x10, 0xFE, 0xFE, 0x00, 0x00 }, // \072 H + { 0x00, 0x82, 0xFE, 0xFE, 0x82, 0x00, 0x00, 0x00 }, // \073 I + { 0x0C, 0X0E, 0x02, 0x82, 0xFE, 0xFC, 0x80, 0x00 }, // \074 J + { 0x82, 0xFE, 0xFE, 0x10, 0x38, 0xEE, 0xC6, 0x00 }, // \075 K + { 0x82, 0xFE, 0xFE, 0x82, 0x02, 0x06, 0x0E, 0x00 }, // \076 L + { 0xFE, 0xFE, 0x60, 0x30, 0x60, 0xFE, 0xFE, 0x00 }, // \077 M + { 0xFE, 0xFE, 0x60, 0x30, 0x18, 0xFE, 0xFE, 0x00 }, // \078 N + { 0x38, 0x7C, 0xC6, 0x82, 0xC6, 0x7C, 0x38, 0x00 }, // \079 O + { 0x82, 0xFE, 0xFE, 0x92, 0x90, 0xF0, 0x60, 0x00 }, // \080 P + { 0x78, 0xFC, 0x84, 0x8E, 0xFE, 0x7A, 0x00, 0x00 }, // \081 Q + { 0x82, 0xFE, 0xFE, 0x98, 0x9C, 0xF6, 0x62, 0x00 }, // \082 R + { 0x64, 0xE6, 0xB2, 0x9A, 0xDE, 0x4C, 0x00, 0x00 }, // \083 S + { 0xC0, 0x82, 0xFE, 0xFE, 0x82, 0xC0, 0x00, 0x00 }, // \084 T + { 0xFE, 0xFE, 0x02, 0x02, 0xFE, 0xFE, 0x00, 0x00 }, // \085 U + { 0xF8, 0xFC, 0x06, 0x06, 0xFC, 0xF8, 0x00, 0x00 }, // \086 V + { 0xFE, 0xFE, 0x0C, 0x18, 0x0C, 0xFE, 0xFE, 0x00 }, // \087 W + { 0xC6, 0xEE, 0x38, 0x10, 0x38, 0xEE, 0xC6, 0x00 }, // \088 X + { 0xE0, 0xF2, 0x1E, 0x1E, 0xF2, 0xE0, 0x00, 0x00 }, // \089 Y + { 0xE6, 0xCE, 0x9A, 0xB2, 0xE2, 0xC6, 0x8E, 0x00 }, // \090 Z + { 0x00, 0xFE, 0xFE, 0x82, 0x82, 0x00, 0x00, 0x00 }, // \091 [ + { 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00 }, // \092 \ . + { 0x00, 0x82, 0x82, 0xFE, 0xFE, 0x00, 0x00, 0x00 }, // \093 ] + { 0x10, 0x30, 0x60, 0xC0, 0x60, 0x30, 0x10, 0x00 }, // \094 ^ + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, // \095 _ + { 0x00, 0x00, 0xC0, 0xE0, 0x20, 0x00, 0x00, 0x00 }, // \096 ` + { 0x04, 0x2E, 0x2A, 0x2A, 0x3C, 0x1E, 0x02, 0x00 }, // \097 a + { 0x82, 0xFC, 0xFE, 0x22, 0x22, 0x3E, 0x1C, 0x00 }, // \098 b + { 0x1C, 0x3E, 0x22, 0x22, 0x36, 0x14, 0x00, 0x00 }, // \099 c + { 0x0C, 0x1E, 0x12, 0x92, 0xFC, 0xFE, 0x02, 0x00 }, // \100 d + { 0x1C, 0x3E, 0x2A, 0x2A, 0x3A, 0x18, 0x00, 0x00 }, // \101 e + { 0x12, 0x7E, 0xFE, 0x92, 0xC0, 0x70, 0x00, 0x00 }, // \102 f + { 0x19, 0x3D, 0x25, 0x25, 0x1F, 0x3E, 0x20, 0x00 }, // \103 g + { 0x82, 0xFE, 0xFE, 0x10, 0x20, 0x3E, 0x1E, 0x00 }, // \104 h + { 0x00, 0x22, 0xBE, 0xBE, 0x02, 0x00, 0x00, 0x00 }, // \105 i + { 0x02, 0x23, 0x21, 0xBF, 0xBE, 0x00, 0x00, 0x00 }, // \106 j + { 0x82, 0xFE, 0xFE, 0x08, 0x1C, 0x36, 0x22, 0x00 }, // \107 k + { 0x00, 0x82, 0xFE, 0xFE, 0x02, 0x00, 0x00, 0x00 }, // \108 l + { 0x3E, 0x3E, 0x30, 0x18, 0x30, 0x3E, 0x1E, 0x00 }, // \109 m + { 0x3E, 0x3E, 0x20, 0x20, 0x3E, 0x1E, 0x00, 0x00 }, // \110 n + { 0x1C, 0x3E, 0x22, 0x22, 0x3E, 0x1C, 0x00, 0x00 }, // \111 o + { 0x21, 0x3F, 0x1F, 0x25, 0x24, 0x3C, 0x18, 0x00 }, // \112 p + { 0x18, 0x3C, 0x24, 0x2A, 0x1F, 0x3F, 0x21, 0x00 }, // \113 q + { 0x22, 0x3E, 0x1E, 0x22, 0x38, 0x18, 0x00, 0x00 }, // \114 r + { 0x12, 0x3A, 0x2A, 0x2A, 0x2E, 0x24, 0x00, 0x00 }, // \115 s + { 0x00, 0x20, 0x7C, 0xFE, 0x22, 0x24, 0x00, 0x00 }, // \116 t + { 0x3C, 0x3E, 0x02, 0x02, 0x3C, 0x3E, 0x02, 0x00 }, // \117 u + { 0x38, 0x3C, 0x06, 0x06, 0x3C, 0x38, 0x00, 0x00 }, // \118 v + { 0x3C, 0x3E, 0x06, 0x0C, 0x06, 0x3E, 0x3C, 0x00 }, // \119 w + { 0x22, 0x36, 0x1C, 0x08, 0x1C, 0x36, 0x22, 0x00 }, // \120 x + { 0x39, 0x3D, 0x05, 0x05, 0x3F, 0x3E, 0x00, 0x00 }, // \121 y + { 0x32, 0x26, 0x2E, 0x3A, 0x32, 0x26, 0x00, 0x00 }, // \122 z + { 0x10, 0x10, 0x7C, 0xEE, 0x82, 0x82, 0x00, 0x00 }, // \123 { + { 0x00, 0x00, 0x00, 0xFE, 0xFE, 0x00, 0x00, 0x00 }, // \124 | + { 0x82, 0x82, 0xEE, 0x7C, 0x10, 0x10, 0x00, 0x00 }, // \125 } + { 0x40, 0xC0, 0x80, 0xC0, 0x40, 0xC0, 0x80, 0x00 }, // \126 ~ + { 0x1E, 0x3E, 0x62, 0xC2, 0x62, 0x3E, 0x1E, 0x00 } // \127 house +}; diff --git a/Scan/STLcd/lcd_scan.c b/Scan/STLcd/lcd_scan.c index 1dd912682..3c30ddbaf 100644 --- a/Scan/STLcd/lcd_scan.c +++ b/Scan/STLcd/lcd_scan.c @@ -32,6 +32,7 @@ // Local Includes #include "lcd_scan.h" +#include "DOS_8x8.h" @@ -60,6 +61,8 @@ void cliFunc_lcdColor( char* args ); void cliFunc_lcdDisp ( char* args ); void cliFunc_lcdInit ( char* args ); void cliFunc_lcdTest ( char* args ); +void cliFunc_lcdClear( char* args ); +void cliFunc_lcdPrint( char* args ); @@ -80,6 +83,8 @@ CLIDict_Entry( lcdColor, "Set backlight color. 3 16-bit numbers: R G B. i.e. CLIDict_Entry( lcdDisp, "Write byte(s) to given page starting at given address. i.e. 0x1 0x5 0xFF 0x00" ); CLIDict_Entry( lcdInit, "Re-initialize the LCD display." ); CLIDict_Entry( lcdTest, "Test out the LCD display." ); +CLIDict_Entry( lcdClear, "Clear the LCD display." ); +CLIDict_Entry( lcdPrint, "Write text to LCD based on row and column. I.e., 0x3 0x1 Hello world. Character codes can be entered with \\nnn (decimal)." ); CLIDict_Def( lcdCLIDict, "ST LCD Module Commands" ) = { CLIDict_Item( lcdCmd ), @@ -87,6 +92,8 @@ CLIDict_Def( lcdCLIDict, "ST LCD Module Commands" ) = { CLIDict_Item( lcdDisp ), CLIDict_Item( lcdInit ), CLIDict_Item( lcdTest ), + CLIDict_Item( lcdClear ), + CLIDict_Item( lcdPrint ), { 0, 0, 0 } // Null entry for dictionary end }; @@ -650,3 +657,110 @@ void cliFunc_lcdDisp( char* args ) } } +void cliFunc_lcdClear( char* args ) +{ + for ( uint8_t page = 0; page < 4; ++page) + { + LCD_writeControlReg( 0xB0 | page ); + + // Starting address 0x0 + LCD_writeControlReg( 0x10 ); + LCD_writeControlReg( 0x00 ); + + // See SPI_write() + for ( uint8_t i = 0; i < 128; ++i) + { + // Wait for SPI TxFIFO to have 4 or fewer entries + while ( !( SPI0_SR & SPI_SR_TFFF ) ) + delayMicroseconds( 10 ); + + // Write byte to TxFIFO + // CS0, CTAR0 + SPI0_PUSHR = ( 0 ) | SPI_PUSHR_PCS(1); + + // Indicate transfer has completed + while ( !( SPI0_SR & SPI_SR_TCF ) ); + SPI0_SR |= SPI_SR_TCF; + } + } +} + +void cliFunc_lcdPrint( char* args ) +{ + char* curArgs; + char* arg1Ptr; + char* arg2Ptr = args; + + // Get row + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + return; + + // Check range + uint8_t row = numToInt( arg1Ptr ); + if ( row > 3 ) + return; + + // Get column + curArgs = arg2Ptr; + CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr ); + + // Stop processing args if no more are found + if ( *arg1Ptr == '\0' ) + return; + + // Check range + uint8_t col = numToInt( arg1Ptr ); + if ( col > 15 ) + return; + + // Set page (inverse of row) + LCD_writeControlReg( 0xB0 | ( 0x0F & (3 - row) ) ); + + // Set starting address (column * 8) + LCD_writeControlReg( 0x10 | ( ( 0xF0 & (col << 3) ) >> 4 ) ); + LCD_writeControlReg( 0x00 | ( 0x0F & (col << 3) )); + + // Don't walk off right side of display + uint8_t columns = 16 - col; + + // There's an extra space before nul. Gobble it, but make sure not to walk off array. + while ( !( arg2Ptr[0] == '\0' || ( arg2Ptr[0] == ' ' && arg2Ptr[1] == '\0' ) ) && columns ) + { + uint8_t char_idx = (uint8_t) arg2Ptr[ 0 ]; + + // Primitive escape sequences + // Handle character codes (decimal of form \ddd) + if ( arg2Ptr[ 0 ] == '\\' && + arg2Ptr[ 1 ] >= '0' && arg2Ptr[ 1 ] <= '9' && + arg2Ptr[ 2 ] >= '0' && arg2Ptr[ 2 ] <= '9' && + arg2Ptr[ 3 ] >= '0' && arg2Ptr[ 3 ] <= '9' ) + { + char code[4]; + for (unsigned int i = 0; i < 3; ++i) + code[ i ] = arg2Ptr[ i+1 ]; + code[ 3 ] = '\0'; + + char_idx = numToInt( code ); + arg2Ptr += 3; + } + // \\ becomes \ . + else if ( arg2Ptr[ 0 ] == '\\' && arg2Ptr[ 1 ] == '\\' ) + { + ++arg2Ptr; + char_idx = (uint8_t) '\\'; + } + + ++arg2Ptr; + + if ( char_idx > 127 ) + continue; + + uint8_t* char_ptr = font_8x8[ char_idx ]; + SPI_write( char_ptr, 8); + --columns; + } +}