]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/STLcd/lcd_scan.c
Adding example logo to the lcdtest and bmp conversion script.
[kiibohd-controller.git] / Scan / STLcd / lcd_scan.c
1 /* Copyright (C) 2015 by Jacob Alexander
2  *
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.
7  *
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.
12  *
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/>.
15  */
16
17 // ----- Includes -----
18
19 // Compiler Includes
20 #include <Lib/ScanLib.h>
21
22 // Project Includes
23 #include <cli.h>
24 #include <led.h>
25 #include <print.h>
26
27 // Local Includes
28 #include "lcd_scan.h"
29
30
31
32 // ----- Defines -----
33
34 #define LCD_TOTAL_VISIBLE_PAGES 4
35 #define LCD_PAGE_LEN 128
36
37
38
39 // ----- Macros -----
40
41 // Number of entries in the SPI0 TxFIFO
42 #define SPI0_TxFIFO_CNT ( ( SPI0_SR & SPI_SR_TXCTR ) >> 12 )
43
44
45
46 // ----- Structs -----
47
48 // ----- Function Declarations -----
49
50 // CLI Functions
51 void cliFunc_lcdCmd( char* args );
52 void cliFunc_lcdInit( char* args );
53 void cliFunc_lcdTest( char* args );
54
55
56
57 // ----- Variables -----
58
59 // Full Toggle State
60 uint8_t cliFullToggleState = 0;
61
62 // Normal/Reverse Toggle State
63 uint8_t cliNormalReverseToggleState = 0;
64
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." );
69
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
75 };
76
77
78
79 // ----- Interrupt Functions -----
80
81
82
83 // ----- Functions -----
84
85 inline void SPI_setup()
86 {
87         // Enable SPI internal clock
88         SIM_SCGC6 |= SIM_SCGC6_SPI0;
89
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);
93
94         // Setup SS (PCS)
95         PORTC_PCR4 = PORT_PCR_DSE | PORT_PCR_MUX(2);
96
97         // Master Mode, CS0
98         SPI0_MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(1);
99
100         // DSPI Clock and Transfer Attributes
101         // Frame Size: 8 bits
102         // MSB First
103         // CLK Low by default
104         SPI0_CTAR0 = SPI_CTAR_FMSZ(7)
105                 | SPI_CTAR_ASC(7)
106                 | SPI_CTAR_DT(7)
107                 | SPI_CTAR_CSSCK(7)
108                 | SPI_CTAR_PBR(0) | SPI_CTAR_BR(7);
109 }
110
111 // Write buffer to SPI FIFO
112 void SPI_write( uint8_t *buffer, uint8_t len )
113 {
114
115         for ( uint8_t byte = 0; byte < len; byte++ )
116         {
117                 // Wait for SPI TxFIFO to have 4 or fewer entries
118                 while ( !( SPI0_SR & SPI_SR_TFFF ) )
119                         delayMicroseconds(10);
120
121                 // Write byte to TxFIFO
122                 // CS0, CTAR0
123                 SPI0_PUSHR = ( buffer[ byte ] & 0xff ) | SPI_PUSHR_PCS(1);
124
125                 // Indicate transfer has completed
126                 while ( !( SPI0_SR & SPI_SR_TCF ) );
127                 SPI0_SR |= SPI_SR_TCF;
128         }
129 }
130
131 // Write to a control register
132 void LCD_writeControlReg( uint8_t byte )
133 {
134         // Wait for TxFIFO to be empt
135         while ( SPI0_TxFIFO_CNT != 0 );
136
137         // Set A0 low to enter control register mode
138         GPIOC_PCOR |= (1<<7);
139
140         // Write byte to SPI FIFO
141         SPI_write( &byte, 1 );
142
143         // Wait for TxFIFO to be empty
144         while ( SPI0_TxFIFO_CNT != 0 );
145
146         // Make sure data has transferred
147         delayMicroseconds(10); // XXX Adjust if SPI speed changes
148
149         // Set A0 high to go back to display register mode
150         GPIOC_PSOR |= (1<<7);
151 }
152
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 )
157 {
158         // Set the register page
159         LCD_writeControlReg( 0xB0 | ( 0x0F & page ) );
160
161         // Set display start line
162         LCD_writeControlReg( 0x40 );
163
164         // Reset Column Address
165         LCD_writeControlReg( 0x10 );
166         LCD_writeControlReg( 0x00 );
167
168         // Write buffer to SPI
169         SPI_write( buffer, len );
170 }
171
172 inline void LCD_clearPage( uint8_t page )
173 {
174         // Set the register page
175         LCD_writeControlReg( 0xB0 | ( 0x0F & page ) );
176
177         // Set display start line
178         LCD_writeControlReg( 0x40 );
179
180         // Reset Column Address
181         LCD_writeControlReg( 0x10 );
182         LCD_writeControlReg( 0x00 );
183
184         for ( uint8_t page_reg = 0; page_reg < LCD_PAGE_LEN; page_reg++ )
185         {
186                 uint8_t byte = 0;
187
188                 // Write buffer to SPI
189                 SPI_write( &byte, 1 );
190         }
191
192         // Wait for TxFIFO to be empty
193         while ( SPI0_TxFIFO_CNT != 0 );
194 }
195
196 // Clear Display
197 void LCD_clear()
198 {
199         // Setup each page
200         for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
201         {
202                 LCD_clearPage( page );
203         }
204
205         // Reset Page, Start Line, and Column Address
206         // Page
207         LCD_writeControlReg( 0xB0 );
208
209         // Start Line
210         LCD_writeControlReg( 0x40 );
211
212         // Reset Column Address
213         LCD_writeControlReg( 0x10 );
214         LCD_writeControlReg( 0x00 );
215 }
216
217 // Intialize display
218 void LCD_initialize()
219 {
220         // ADC Select (Normal)
221         LCD_writeControlReg( 0xA0 );
222
223         // LCD Off
224         LCD_writeControlReg( 0xAE );
225
226         // COM Scan Output Direction
227         LCD_writeControlReg( 0xC0 );
228
229         // LCD Bias (1/6 bias)
230         LCD_writeControlReg( 0xA2 );
231
232         // Power Supply Operating Mode (Internal Only)
233         LCD_writeControlReg( 0x2F );
234
235         // Internal Rb/Ra Ratio
236         LCD_writeControlReg( 0x26 );
237
238         // Reset
239         LCD_writeControlReg( 0xE2 );
240
241         // Electric volume mode set, and value
242         LCD_writeControlReg( 0x81 );
243         LCD_writeControlReg( 0x00 );
244
245         // LCD On
246         LCD_writeControlReg( 0xAF );
247
248         // Clear Display RAM
249         LCD_clear();
250 }
251
252 // Setup
253 inline void LCD_setup()
254 {
255         // Register Scan CLI dictionary
256         CLI_registerDictionary( lcdCLIDict, lcdCLIDictName );
257
258         // Initialize SPI
259         SPI_setup();
260
261
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);
267
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);
274
275         // Run LCD intialization sequence
276         LCD_initialize();
277 }
278
279
280 // LCD State processing loop
281 inline uint8_t LCD_scan()
282 {
283         // NOP - Screen Refresh
284         //LCD_writeControlReg( 0xE3 );
285         return 0;
286 }
287
288
289
290 // ----- CLI Command Functions -----
291
292 void cliFunc_lcdInit( char* args )
293 {
294         print( NL ); // No \r\n by default after the command is entered
295         LCD_initialize();
296 }
297
298 void cliFunc_lcdTest( char* args )
299 {
300         print( NL ); // No \r\n by default after the command is entered
301
302         //LCD_initialize();
303         // Test pattern
304         uint8_t pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
305
306
307 uint8_t logo[] = {
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,
312 };
313         //uint8_t pattern[] = { 0xFF, 0x00, 0x96, 0xFF, 0x00, 0xFF, 0x00 };
314
315         // Write to page D0
316         //LCD_writeDisplayReg( 0, pattern, sizeof( pattern ) );
317
318         for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
319         {
320                 LCD_writeDisplayReg( page, &logo[page * LCD_PAGE_LEN], LCD_PAGE_LEN );
321         }
322 }
323
324 void cliFunc_lcdCmd( char* args )
325 {
326         char* curArgs;
327         char* arg1Ptr;
328         char* arg2Ptr = args;
329
330         print( NL ); // No \r\n by default after the command is entered
331
332         curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list
333         CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
334
335         // No args
336         if ( *arg1Ptr == '\0' )
337                 return;
338
339         // SPI Command
340         uint8_t cmd = (uint8_t)numToInt( arg1Ptr );
341
342         curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list
343         CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
344
345         // Single Arg
346         if ( *arg1Ptr == '\0' )
347                 goto cmd;
348
349         // TODO Deal with a0
350 cmd:
351         info_msg("Sending - ");
352         printHex( cmd );
353         print( NL );
354         LCD_writeControlReg( cmd );
355 }
356