]> git.donarmstrong.com Git - kiibohd-controller.git/blob - Scan/STLcd/lcd_scan.c
df07b5aa9391209772458851f3a8dc41dc6792dc
[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         // Setup Register Control Signal (A0)
262         // Start in display register mode (1)
263         GPIOC_PDDR |= (1<<7);
264         PORTC_PCR7 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
265         GPIOC_PSOR |= (1<<7);
266
267         // Setup LCD Reset pin (RST)
268         // 0 - Reset, 1 - Normal Operation
269         // Start in normal mode (1)
270         GPIOC_PDDR |= (1<<8);
271         PORTC_PCR8 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
272         GPIOC_PSOR |= (1<<8);
273
274         // Run LCD intialization sequence
275         LCD_initialize();
276
277         // Setup Backlight
278         // TODO Expose default settings
279         // TODO Setup PWM
280         GPIOC_PDDR |= (1<<1);
281         PORTC_PCR1 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
282         GPIOC_PCOR |= (1<<1);
283         GPIOC_PDDR |= (1<<2);
284         PORTC_PCR2 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
285         GPIOC_PCOR |= (1<<2);
286         GPIOC_PDDR |= (1<<3);
287         PORTC_PCR3 = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
288         GPIOC_PCOR |= (1<<3);
289 }
290
291
292 // LCD State processing loop
293 inline uint8_t LCD_scan()
294 {
295         // NOP - Screen Refresh
296         //LCD_writeControlReg( 0xE3 );
297         return 0;
298 }
299
300
301
302 // ----- CLI Command Functions -----
303
304 void cliFunc_lcdInit( char* args )
305 {
306         print( NL ); // No \r\n by default after the command is entered
307         LCD_initialize();
308 }
309
310 void cliFunc_lcdTest( char* args )
311 {
312         print( NL ); // No \r\n by default after the command is entered
313
314         //LCD_initialize();
315         // Test pattern
316         uint8_t pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
317
318
319 uint8_t logo[] = {
320 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,
321 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,
322 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,
323 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,
324 };
325         //uint8_t pattern[] = { 0xFF, 0x00, 0x96, 0xFF, 0x00, 0xFF, 0x00 };
326
327         // Write to page D0
328         //LCD_writeDisplayReg( 0, pattern, sizeof( pattern ) );
329
330         for ( uint8_t page = 0; page < LCD_TOTAL_VISIBLE_PAGES; page++ )
331         {
332                 LCD_writeDisplayReg( page, &logo[page * LCD_PAGE_LEN], LCD_PAGE_LEN );
333         }
334 }
335
336 void cliFunc_lcdCmd( char* args )
337 {
338         char* curArgs;
339         char* arg1Ptr;
340         char* arg2Ptr = args;
341
342         print( NL ); // No \r\n by default after the command is entered
343
344         curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list
345         CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
346
347         // No args
348         if ( *arg1Ptr == '\0' )
349                 return;
350
351         // SPI Command
352         uint8_t cmd = (uint8_t)numToInt( arg1Ptr );
353
354         curArgs = arg2Ptr; // Use the previous 2nd arg pointer to separate the next arg from the list
355         CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );
356
357         // Single Arg
358         if ( *arg1Ptr == '\0' )
359                 goto cmd;
360
361         // TODO Deal with a0
362 cmd:
363         info_msg("Sending - ");
364         printHex( cmd );
365         print( NL );
366         LCD_writeControlReg( cmd );
367 }
368