1 /* Copyright (C) 2015 by Jacob Alexander
3 * This file is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * This file is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this file. If not, see <http://www.gnu.org/licenses/>.
17 // ----- Includes -----
20 #include <Lib/ScanLib.h>
32 // ----- Defines -----
34 #define LCD_TOTAL_VISIBLE_PAGES 4
35 #define LCD_PAGE_LEN 128
41 // Number of entries in the SPI0 TxFIFO
42 #define SPI0_TxFIFO_CNT ( ( SPI0_SR & SPI_SR_TXCTR ) >> 12 )
46 // ----- Structs -----
48 // ----- Function Declarations -----
51 void cliFunc_lcdCmd( char* args );
52 void cliFunc_lcdInit( char* args );
53 void cliFunc_lcdTest( char* args );
57 // ----- Variables -----
60 uint8_t cliFullToggleState = 0;
62 // Normal/Reverse Toggle State
63 uint8_t cliNormalReverseToggleState = 0;
65 // Scan Module command dictionary
66 CLIDict_Entry( lcdCmd, "Send byte via SPI, second argument enables a0. Defaults to control." );
67 CLIDict_Entry( lcdInit, "Re-initialize the LCD display." );
68 CLIDict_Entry( lcdTest, "Test out the LCD display." );
70 CLIDict_Def( lcdCLIDict, "ST LCD Module Commands" ) = {
71 CLIDict_Item( lcdCmd ),
72 CLIDict_Item( lcdInit ),
73 CLIDict_Item( lcdTest ),
74 { 0, 0, 0 } // Null entry for dictionary end
79 // ----- Interrupt Functions -----
83 // ----- Functions -----
85 inline void SPI_setup()
87 // Enable SPI internal clock
88 SIM_SCGC6 |= SIM_SCGC6_SPI0;
90 // Setup MOSI (SOUT) and SCLK (SCK)
91 PORTC_PCR6 = PORT_PCR_DSE | PORT_PCR_MUX(2);
92 PORTC_PCR5 = PORT_PCR_DSE | PORT_PCR_MUX(2);
95 PORTC_PCR4 = PORT_PCR_DSE | PORT_PCR_MUX(2);
98 SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(1);
100 // DSPI Clock and Transfer Attributes
101 // Frame Size: 8 bits
103 // CLK Low by default
104 SPI0_CTAR0 = SPI_CTAR_FMSZ(7)
108 | SPI_CTAR_PBR(0) | SPI_CTAR_BR(7);
111 // Write buffer to SPI FIFO
112 void SPI_write( uint8_t *buffer, uint8_t len )
115 for ( uint8_t byte = 0; byte < len; byte++ )
117 // Wait for SPI TxFIFO to have 4 or fewer entries
118 while ( !( SPI0_SR & SPI_SR_TFFF ) )
119 delayMicroseconds(10);
121 // Write byte to TxFIFO
123 SPI0_PUSHR = ( buffer[ byte ] & 0xff ) | SPI_PUSHR_PCS(1);
125 // Indicate transfer has completed
126 while ( !( SPI0_SR & SPI_SR_TCF ) );
127 SPI0_SR |= SPI_SR_TCF;
131 // Write to a control register
132 void LCD_writeControlReg( uint8_t byte )
134 // Wait for TxFIFO to be empt
135 while ( SPI0_TxFIFO_CNT != 0 );
137 // Set A0 low to enter control register mode
138 GPIOC_PCOR |= (1<<7);
140 // Write byte to SPI FIFO
141 SPI_write( &byte, 1 );
143 // Wait for TxFIFO to be empty
144 while ( SPI0_TxFIFO_CNT != 0 );
146 // Make sure data has transferred
147 delayMicroseconds(10); // XXX Adjust if SPI speed changes
149 // Set A0 high to go back to display register mode
150 GPIOC_PSOR |= (1<<7);
153 // Write to display register
154 // Pages 0-7 normal display
155 // Page 8 icon buffer
156 void LCD_writeDisplayReg( uint8_t page, uint8_t *buffer, uint8_t len )
158 // Set the register page
159 LCD_writeControlReg( 0xB0 | ( 0x0F & page ) );
161 // Set display start line
162 LCD_writeControlReg( 0x40 );
164 // Reset Column Address
165 LCD_writeControlReg( 0x10 );
166 LCD_writeControlReg( 0x00 );
168 // Write buffer to SPI
169 SPI_write( buffer, len );
172 inline void LCD_clearPage( uint8_t page )
174 // Set the register page
175 LCD_writeControlReg( 0xB0 | ( 0x0F & page ) );
177 // Set display start line
178 LCD_writeControlReg( 0x40 );
180 // Reset Column Address
181 LCD_writeControlReg( 0x10 );
182 LCD_writeControlReg( 0x00 );
184 for ( uint8_t page_reg = 0; page_reg < LCD_PAGE_LEN; page_reg++ )
188 // Write buffer to SPI
189 SPI_write( &byte, 1 );
192 // Wait for TxFIFO to be empty
193 while ( SPI0_TxFIFO_CNT != 0 );
200 for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
202 LCD_clearPage( page );
205 // Reset Page, Start Line, and Column Address
207 LCD_writeControlReg( 0xB0 );
210 LCD_writeControlReg( 0x40 );
212 // Reset Column Address
213 LCD_writeControlReg( 0x10 );
214 LCD_writeControlReg( 0x00 );
218 void LCD_initialize()
220 // ADC Select (Normal)
221 LCD_writeControlReg( 0xA0 );
224 LCD_writeControlReg( 0xAE );
226 // COM Scan Output Direction
227 LCD_writeControlReg( 0xC0 );
229 // LCD Bias (1/6 bias)
230 LCD_writeControlReg( 0xA2 );
232 // Power Supply Operating Mode (Internal Only)
233 LCD_writeControlReg( 0x2F );
235 // Internal Rb/Ra Ratio
236 LCD_writeControlReg( 0x26 );
239 LCD_writeControlReg( 0xE2 );
241 // Electric volume mode set, and value
242 LCD_writeControlReg( 0x81 );
243 LCD_writeControlReg( 0x00 );
246 LCD_writeControlReg( 0xAF );
253 inline void LCD_setup()
255 // Register Scan CLI dictionary
256 CLI_registerDictionary( lcdCLIDict, lcdCLIDictName );
262 // Setup Register Control Signal (A0)
263 // Start in display register mode (1)
264 GPIOC_PDDR |= (1<<7);
265 PORTC_PCR7 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
266 GPIOC_PSOR |= (1<<7);
268 // Setup LCD Reset pin (RST)
269 // 0 - Reset, 1 - Normal Operation
270 // Start in normal mode (1)
271 GPIOC_PDDR |= (1<<8);
272 PORTC_PCR8 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
273 GPIOC_PSOR |= (1<<8);
275 // Run LCD intialization sequence
280 // LCD State processing loop
281 inline uint8_t LCD_scan()
283 // NOP - Screen Refresh
284 //LCD_writeControlReg( 0xE3 );
290 // ----- CLI Command Functions -----
292 void cliFunc_lcdInit( char* args )
294 print( NL ); // No \r\n by default after the command is entered
298 void cliFunc_lcdTest( char* args )
300 print( NL ); // No \r\n by default after the command is entered
304 uint8_t pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 //uint8_t pattern[] = { 0xFF, 0x00, 0x96, 0xFF, 0x00, 0xFF, 0x00 };
316 //LCD_writeDisplayReg( 0, pattern, sizeof( pattern ) );
318 for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
320 LCD_writeDisplayReg( page, &logo[page * LCD_PAGE_LEN], LCD_PAGE_LEN );
324 void cliFunc_lcdCmd( char* args )
328 char* arg2Ptr = args;
330 print( NL ); // No \r\n by default after the command is entered
332 curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list
333 CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
336 if ( *arg1Ptr == '\0' )
340 uint8_t cmd = (uint8_t)numToInt( arg1Ptr );
342 curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list
343 CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
346 if ( *arg1Ptr == '\0' )
351 info_msg("Sending - ");
354 LCD_writeControlReg( cmd );