]> begriffs open source - cmsis-freertos/blob - Demo/CORTEX_LM3Sxxxx_Rowley/osram128x64x4.c
Set error state if no delay or already expired
[cmsis-freertos] / Demo / CORTEX_LM3Sxxxx_Rowley / osram128x64x4.c
1 //*****************************************************************************
2 //
3 // osram128x64x4.c - Driver for the OSRAM 128x64x4 graphical OLED display.
4 //
5 // Copyright (c) 2006-2007 Luminary Micro, Inc.  All rights reserved.
6 // 
7 // Software License Agreement
8 // 
9 // Luminary Micro, Inc. (LMI) is supplying this software for use solely and
10 // exclusively on LMI's microcontroller products.
11 // 
12 // The software is owned by LMI and/or its suppliers, and is protected under
13 // applicable copyright laws.  All rights are reserved.  Any use in violation
14 // of the foregoing restrictions may subject the user to criminal sanctions
15 // under applicable laws, as well as to civil liability for the breach of the
16 // terms and conditions of this license.
17 // 
18 // THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
19 // OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
20 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
21 // LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
22 // CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
23 // 
24 // This is part of revision 1408 of the Stellaris Peripheral Driver Library.
25 //
26 //*****************************************************************************
27
28 //*****************************************************************************
29 //
30 //! \addtogroup ek_lm3sx965_api
31 //! @{
32 //
33 //*****************************************************************************
34
35 #include "hw_ssi.h"
36 #include "hw_memmap.h"
37 #include "hw_sysctl.h"
38 #include "hw_types.h"
39 #include "debug.h"
40 #include "gpio.h"
41 #include "ssi.h"
42 #include "sysctl.h"
43 #include "osram128x64x4.h"
44
45 //*****************************************************************************
46 //
47 // Flag to indicate if SSI port is enabled for OSRAM usage.
48 //
49 //*****************************************************************************
50 static volatile tBoolean g_bSSIEnabled = false;
51
52 //*****************************************************************************
53 //
54 // Define the OSRAM 128x64x4 Remap Setting(s).  This will be used in
55 // several places in the code to switch between vertical and horizontal
56 // address incrementing.
57 //
58 // The Remap Command (0xA0) takes one 8-bit parameter.  The parameter is
59 // defined as follows.
60 //
61 // Bit 7: Reserved
62 // Bit 6: Disable(0)/Enable(1) COM Split Odd Even
63 //        When enabled, the COM signals are split Odd on one side, even on
64 //        the other.  Otherwise, they are split 0-39 on one side, 40-79 on
65 //        the other.
66 // Bit 5: Reserved
67 // Bit 4: Disable(0)/Enable(1) COM Remap
68 //        When Enabled, ROW 0-79 map to COM 79-0 (i.e. reverse row order)
69 // Bit 3: Reserved
70 // Bit 2: Horizontal(0)/Vertical(1) Address Increment
71 //        When set, data RAM address will increment along the column rather
72 //        than along the row.
73 // Bit 1: Disable(0)/Enable(1) Nibble Remap
74 //        When enabled, the upper and lower nibbles in the DATA bus for access
75 //        to the data RAM are swapped.
76 // Bit 0: Disable(0)/Enable(1) Column Address Remap
77 //        When enabled, DATA RAM columns 0-63 are remapped to Segment Columns
78 //        127-0.
79 //
80 //*****************************************************************************
81 #define OSRAM_INIT_REMAP    0x52
82 #define OSRAM_INIT_OFFSET   0x4C
83 static const unsigned char g_pucOSRAM128x64x4VerticalInc[]   = { 0xA0, 0x56 };
84 static const unsigned char g_pucOSRAM128x64x4HorizontalInc[] = { 0xA0, 0x52 };
85
86 //*****************************************************************************
87 //
88 // A 5x7 font (in a 6x8 cell, where the sixth column is omitted from this
89 // table) for displaying text on the OLED display.  The data is organized as
90 // bytes from the left column to the right column, with each byte containing
91 // the top row in the LSB and the bottom row in the MSB.
92 //
93 // Note:  This is the same font data that is used in the EK-LM3S811
94 // osram96x16x1 driver.  The single bit-per-pixel is expaned in the StringDraw
95 // function to the appropriate four bit-per-pixel gray scale format.
96 //
97 //*****************************************************************************
98 static const unsigned char g_pucFont[96][5] =
99 {
100     { 0x00, 0x00, 0x00, 0x00, 0x00 }, // " "
101     { 0x00, 0x00, 0x4f, 0x00, 0x00 }, // !
102     { 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
103     { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #
104     { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $
105     { 0x23, 0x13, 0x08, 0x64, 0x62 }, // %
106     { 0x36, 0x49, 0x55, 0x22, 0x50 }, // &
107     { 0x00, 0x05, 0x03, 0x00, 0x00 }, // '
108     { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (
109     { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )
110     { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // *
111     { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // +
112     { 0x00, 0x50, 0x30, 0x00, 0x00 }, // ,
113     { 0x08, 0x08, 0x08, 0x08, 0x08 }, // -
114     { 0x00, 0x60, 0x60, 0x00, 0x00 }, // .
115     { 0x20, 0x10, 0x08, 0x04, 0x02 }, // /
116     { 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 0
117     { 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 1
118     { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
119     { 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 3
120     { 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 4
121     { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
122     { 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 6
123     { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7
124     { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
125     { 0x06, 0x49, 0x49, 0x29, 0x1e }, // 9
126     { 0x00, 0x36, 0x36, 0x00, 0x00 }, // :
127     { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;
128     { 0x08, 0x14, 0x22, 0x41, 0x00 }, // <
129     { 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
130     { 0x00, 0x41, 0x22, 0x14, 0x08 }, // >
131     { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?
132     { 0x32, 0x49, 0x79, 0x41, 0x3e }, // @
133     { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // A
134     { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B
135     { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C
136     { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // D
137     { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E
138     { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // F
139     { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // G
140     { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H
141     { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I
142     { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // J
143     { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K
144     { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // L
145     { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // M
146     { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // N
147     { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O
148     { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // P
149     { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // Q
150     { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // R
151     { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S
152     { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // T
153     { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // U
154     { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // V
155     { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // W
156     { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
157     { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y
158     { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
159     { 0x00, 0x7f, 0x41, 0x41, 0x00 }, // [
160     { 0x02, 0x04, 0x08, 0x10, 0x20 }, // "\"
161     { 0x00, 0x41, 0x41, 0x7f, 0x00 }, // ]
162     { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^
163     { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _
164     { 0x00, 0x01, 0x02, 0x04, 0x00 }, // `
165     { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a
166     { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // b
167     { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c
168     { 0x38, 0x44, 0x44, 0x48, 0x7f }, // d
169     { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e
170     { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // f
171     { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // g
172     { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // h
173     { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // i
174     { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // j
175     { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // k
176     { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // l
177     { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // m
178     { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // n
179     { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o
180     { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // p
181     { 0x08, 0x14, 0x14, 0x18, 0x7c }, // q
182     { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // r
183     { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s
184     { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // t
185     { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // u
186     { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // v
187     { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // w
188     { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x
189     { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // y
190     { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // z
191     { 0x00, 0x08, 0x36, 0x41, 0x00 }, // {
192     { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // |
193     { 0x00, 0x41, 0x36, 0x08, 0x00 }, // }
194     { 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~
195     { 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~
196 };
197
198 //*****************************************************************************
199 //
200 // The sequence of commands used to initialize the SSD0303 controller.  Each
201 // command is described as follows:  there is a byte specifying the number of
202 // bytes in the command sequence, followed by that many bytes of command data.
203 // Note:  This initialization sequence is derived from OSRAM App Note AN018.
204 //
205 //*****************************************************************************
206 static const unsigned char g_pucOSRAM128x64x4Init[] =
207 {
208     //
209     // Column Address
210     //
211     4, 0x15, 0, 63, 0xe3,
212
213     //
214     // Row Address
215     //
216     4, 0x75, 0, 63, 0xe3,
217
218     //
219     // Contrast Control
220     //
221     3, 0x81, 50, 0xe3,
222
223     //
224     // Half Current Range
225     //
226     2, 0x85, 0xe3,
227
228     //
229     // Display Re-map
230     //
231     3, 0xA0, OSRAM_INIT_REMAP, 0xe3,
232
233     //
234     // Display Start Line
235     //
236     3, 0xA1, 0, 0xe3,
237
238     //
239     // Display Offset
240     //
241     3, 0xA2, OSRAM_INIT_OFFSET, 0xe3,
242
243     //
244     // Display Mode Normal
245     //
246     2, 0xA4, 0xe3,
247
248     //
249     // Multiplex Ratio
250     //
251     3, 0xA8, 63, 0xe3,
252
253     //
254     // Phase Length
255     //
256     3, 0xB1, 0x22, 0xe3,
257
258     //
259     // Row Period
260     //
261     3, 0xB2, 70, 0xe3,
262
263     //
264     // Display Clock Divide
265     //
266     3, 0xB3, 0xF1, 0xe3,
267
268     //
269     // VSL
270     //
271     3, 0xBF, 0x0D, 0xe3,
272
273     //
274     // VCOMH
275     //
276     3, 0xBE, 0x02, 0xe3,
277
278     //
279     // VP
280     //
281     3, 0xBC, 0x10, 0xe3,
282
283     //
284     // Gamma
285     //
286     10, 0xB8, 0x01, 0x11, 0x22, 0x32, 0x43, 0x54, 0x65, 0x76, 0xe3,
287
288     //
289     // Set DC-DC
290     3, 0xAD, 0x03, 0xe3,
291
292     //
293     // Display ON/OFF
294     //
295     2, 0xAF, 0xe3,
296 };
297
298 //*****************************************************************************
299 //
300 //! \internal
301 //!
302 //! Write a sequence of command bytes to the SSD0323 controller.
303 //!
304 //! The data is written in a polled fashion; this function will not return
305 //! until the entire byte sequence has been written to the controller.
306 //!
307 //! \return None.
308 //
309 //*****************************************************************************
310 static void
311 OSRAMWriteCommand(const unsigned char *pucBuffer, unsigned long ulCount)
312 {
313     unsigned long ulTemp;
314
315     //
316     // Return iff SSI port is not enabled for OSRAM.
317     //
318     if(!g_bSSIEnabled)
319     {
320         return;
321     }
322
323     //
324     // Clear the command/control bit to enable command mode.
325     //
326     GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, 0);
327
328     //
329     // Loop while there are more bytes left to be transferred.
330     //
331     while(ulCount != 0)
332     {
333         //
334         // Write the next byte to the controller.
335         //
336         SSIDataPut(SSI0_BASE, *pucBuffer++);
337
338         //
339         // Dummy read to drain the fifo and time the GPIO signal.
340         //
341         SSIDataGet(SSI0_BASE, &ulTemp);
342
343         //
344         // Decrement the BYTE counter.
345         //
346         ulCount--;
347     }
348 }
349
350 //*****************************************************************************
351 //
352 //! \internal
353 //!
354 //! Write a sequence of data bytes to the SSD0323 controller.
355 //!
356 //! The data is written in a polled fashion; this function will not return
357 //! until the entire byte sequence has been written to the controller.
358 //!
359 //! \return None.
360 //
361 //*****************************************************************************
362 static void
363 OSRAMWriteData(const unsigned char *pucBuffer, unsigned long ulCount)
364 {
365     unsigned long ulTemp;
366
367     //
368     // Return iff SSI port is not enabled for OSRAM.
369     //
370     if(!g_bSSIEnabled)
371     {
372         return;
373     }
374
375     //
376     // Set the command/control bit to enable data mode.
377     //
378     GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_PIN_7);
379
380     //
381     // Loop while there are more bytes left to be transferred.
382     //
383     while(ulCount != 0)
384     {
385         //
386         // Write the next byte to the controller.
387         //
388         SSIDataPut(SSI0_BASE, *pucBuffer++);
389
390         //
391         // Dummy read to drain the fifo and time the GPIO signal.
392         //
393         SSIDataGet(SSI0_BASE, &ulTemp);
394
395         //
396         // Decrement the BYTE counter.
397         //
398         ulCount--;
399     }
400 }
401
402 //*****************************************************************************
403 //
404 //! Clears the OLED display.
405 //!
406 //! This function will clear the display RAM.  All pixels in the display will
407 //! be turned off.
408 //!
409 //! This function is contained in <tt>osram128x64x4.c</tt>, with
410 //! <tt>osram128x64x4.h</tt> containing the API definition for use by
411 //! applications.
412 //!
413 //! \return None.
414 //
415 //*****************************************************************************
416 void
417 OSRAM128x64x4Clear(void)
418 {
419     static const unsigned char pucCommand1[] = { 0x15, 0, 63 };
420     static const unsigned char pucCommand2[] = { 0x75, 0, 79 };
421     unsigned long ulRow, ulColumn;
422     static unsigned char pucZeroBuffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0};
423
424     //
425     // Set the window to fill the entire display.
426     //
427     OSRAMWriteCommand(pucCommand1, sizeof(pucCommand1));
428     OSRAMWriteCommand(pucCommand2, sizeof(pucCommand2));
429     OSRAMWriteCommand(g_pucOSRAM128x64x4VerticalInc,
430                       sizeof(g_pucOSRAM128x64x4VerticalInc));
431
432     //
433     // In vertical address increment mode, loop through each column, filling
434     // each row with 0.
435     //
436     for(ulColumn = 0; ulColumn < (128/2); ulColumn++)
437     {
438         //
439         // 8 rows (bytes) per row of text.
440         //
441         for(ulRow = 0; ulRow < 80; ulRow += 8)
442         {
443             OSRAMWriteData(pucZeroBuffer, sizeof(pucZeroBuffer));
444         }
445     }
446 }
447
448 //*****************************************************************************
449 //
450 //! Displays a string on the OLED display.
451 //!
452 //! \param pcStr is a pointer to the string to display.
453 //! \param ulX is the horizontal position to display the string, specified in
454 //! columns from the left edge of the display.
455 //! \param ulY is the vertical position to display the string, specified in
456 //! rows from the top edge of the display.
457 //! \param ucLevel is the 4-bit grey scale value to be used for displayed text.
458 //!
459 //! This function will draw a string on the display.  Only the ASCII characters
460 //! between 32 (space) and 126 (tilde) are supported; other characters will
461 //! result in random data being draw on the display (based on whatever appears
462 //! before/after the font in memory).  The font is mono-spaced, so characters
463 //! such as "i" and "l" have more white space around them than characters such
464 //! as "m" or "w".
465 //!
466 //! If the drawing of the string reaches the right edge of the display, no more
467 //! characters will be drawn.  Therefore, special care is not required to avoid
468 //! supplying a string that is "too long" to display.
469 //!
470 //! This function is contained in <tt>osram128x64x4.c</tt>, with
471 //! <tt>osram128x64x4.h</tt> containing the API definition for use by
472 //! applications.
473 //!
474 //! \note Because the OLED display packs 2 pixels of data in a single byte, the
475 //! parameter \e ulX must be an even column number (e.g. 0, 2, 4, etc).
476 //!
477 //! \return None.
478 //
479 //*****************************************************************************
480 void
481 OSRAM128x64x4StringDraw(const char *pcStr, unsigned long ulX,
482                         unsigned long ulY, unsigned char ucLevel)
483 {
484     static unsigned char pucBuffer[8];
485     unsigned long ulIdx1, ulIdx2;
486     unsigned char ucTemp;
487
488     //
489     // Check the arguments.
490     //
491     ASSERT(ulX < 128);
492     ASSERT((ulX & 1) == 0);
493     ASSERT(ulY < 64);
494     ASSERT(ucLevel < 16);
495
496     //
497     // Setup a window starting at the specified column and row, ending
498     // at the right edge of the display and 8 rows down (single character row).
499     //
500     pucBuffer[0] = 0x15;
501     pucBuffer[1] = ulX / 2;
502     pucBuffer[2] = 63;
503     OSRAMWriteCommand(pucBuffer, 3);
504     pucBuffer[0] = 0x75;
505     pucBuffer[1] = ulY;
506     pucBuffer[2] = ulY + 7;
507     OSRAMWriteCommand(pucBuffer, 3);
508     OSRAMWriteCommand(g_pucOSRAM128x64x4VerticalInc,
509                       sizeof(g_pucOSRAM128x64x4VerticalInc));
510
511     //
512     // Loop while there are more characters in the string.
513     //
514     while(*pcStr != 0)
515     {
516         //
517         // Get a working copy of the current character and convert to an
518         // index into the character bit-map array.
519         //
520         ucTemp = *pcStr;
521         ucTemp &= 0x7F;
522         if(ucTemp < ' ')
523         {
524             ucTemp = ' ';
525         }
526         else
527         {
528             ucTemp -= ' ';
529         }
530
531         //
532         // Build and display the character buffer.
533         //
534         for(ulIdx1 = 0; ulIdx1 < 3; ulIdx1++)
535         {
536             //
537             // Convert two columns of 1-bit font data into a single data
538             // byte column of 4-bit font data.
539             //
540             for(ulIdx2 = 0; ulIdx2 < 8; ulIdx2++)
541             {
542                 pucBuffer[ulIdx2] = 0;
543                 if(g_pucFont[ucTemp][ulIdx1*2] & (1 << ulIdx2))
544                 {
545                     pucBuffer[ulIdx2] = ((ucLevel << 4) & 0xf0);
546                 }
547                 if((ulIdx1 < 2) &&
548                     (g_pucFont[ucTemp][ulIdx1*2+1] & (1 << ulIdx2)))
549                 {
550                     pucBuffer[ulIdx2] |= ((ucLevel << 0) & 0x0f);
551                 }
552             }
553
554             //
555             // If there is room, dump the single data byte column to the
556             // display.  Otherwise, bail out.
557             //
558             if(ulX < 126)
559             {
560                 OSRAMWriteData(pucBuffer, 8);
561                 ulX += 2;
562             }
563             else
564             {
565                 return;
566             }
567         }
568
569         //
570         // Advance to the next character.
571         //
572         pcStr++;
573     }
574 }
575
576 //*****************************************************************************
577 //
578 //! Displays an image on the OLED display.
579 //!
580 //! \param pucImage is a pointer to the image data.
581 //! \param ulX is the horizontal position to display this image, specified in
582 //! columns from the left edge of the display.
583 //! \param ulY is the vertical position to display this image, specified in
584 //! rows from the top of the display.
585 //! \param ulWidth is the width of the image, specified in columns.
586 //! \param ulHeight is the height of the image, specified in rows.
587 //!
588 //! This function will display a bitmap graphic on the display.  Because of the
589 //! format of the display RAM, the starting column (/e ulX) and the number of
590 //! columns (/e ulWidth) must be an integer multiple of two.
591 //!
592 //! The image data is organized with the first row of image data appearing left
593 //! to right, followed immediately by the second row of image data.  Each byte
594 //! contains the data for two columns in the current row, with the leftmost
595 //! column being contained in bits 7:4 and the rightmost column being contained
596 //! in bits 3:0.
597 //!
598 //! For example, an image six columns wide and seven scan lines tall would
599 //! be arranged as follows (showing how the twenty one bytes of the image would
600 //! appear on the display):
601 //!
602 //! \verbatim
603 //!     +-------------------+-------------------+-------------------+
604 //!     |      Byte 0       |      Byte 1       |      Byte 2       |
605 //!     +---------+---------+---------+---------+---------+---------+
606 //!     | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 |
607 //!     +---------+---------+---------+---------+---------+---------+
608 //!     |      Byte 3       |      Byte 4       |      Byte 5       |
609 //!     +---------+---------+---------+---------+---------+---------+
610 //!     | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 |
611 //!     +---------+---------+---------+---------+---------+---------+
612 //!     |      Byte 6       |      Byte 7       |      Byte 8       |
613 //!     +---------+---------+---------+---------+---------+---------+
614 //!     | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 |
615 //!     +---------+---------+---------+---------+---------+---------+
616 //!     |      Byte 9       |      Byte 10      |      Byte 11      |
617 //!     +---------+---------+---------+---------+---------+---------+
618 //!     | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 |
619 //!     +---------+---------+---------+---------+---------+---------+
620 //!     |      Byte 12      |      Byte 13      |      Byte 14      |
621 //!     +---------+---------+---------+--3------+---------+---------+
622 //!     | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 |
623 //!     +---------+---------+---------+---------+---------+---------+
624 //!     |      Byte 15      |      Byte 16      |      Byte 17      |
625 //!     +---------+---------+---------+---------+---------+---------+
626 //!     | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 |
627 //!     +---------+---------+---------+---------+---------+---------+
628 //!     |      Byte 18      |      Byte 19      |      Byte 20      |
629 //!     +---------+---------+---------+---------+---------+---------+
630 //!     | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 | 7 6 5 4 | 3 2 1 0 |
631 //!     +---------+---------+---------+---------+---------+---------+
632 //! \endverbatim
633 //!
634 //! This function is contained in <tt>osram128x64x4.c</tt>, with
635 //! <tt>osram128x64x4.h</tt> containing the API definition for use by`
636 //! applications.
637 //!
638 //! \return None.
639 //
640 //*****************************************************************************
641 void
642 OSRAM128x64x4ImageDraw(const unsigned char *pucImage, unsigned long ulX,
643                unsigned long ulY, unsigned long ulWidth,
644                unsigned long ulHeight)
645 {
646     static unsigned char pucBuffer[8];
647
648     //
649     // Check the arguments.
650     //
651     ASSERT(ulX < 128);
652     ASSERT((ulX & 1) == 0);
653     ASSERT(ulY < 64);
654     ASSERT((ulX + ulWidth) <= 128);
655     ASSERT((ulY + ulHeight) <= 64);
656     ASSERT((ulWidth & 1) == 0);
657
658     //
659     // Setup a window starting at the specified column and row, and ending
660     // at the column + width and row+height.
661     //
662     pucBuffer[0] = 0x15;
663     pucBuffer[1] = ulX / 2;
664     pucBuffer[2] = (ulX + ulWidth - 2) / 2;
665     OSRAMWriteCommand(pucBuffer, 3);
666     pucBuffer[0] = 0x75;
667     pucBuffer[1] = ulY;
668     pucBuffer[2] = ulY + ulHeight - 1;
669     OSRAMWriteCommand(pucBuffer, 3);
670     OSRAMWriteCommand(g_pucOSRAM128x64x4HorizontalInc,
671                       sizeof(g_pucOSRAM128x64x4HorizontalInc));
672
673     //
674     // Loop while there are more rows to display.
675     //
676     while(ulHeight--)
677     {
678         //
679         // Write this row of image data.
680         //
681         OSRAMWriteData(pucImage, (ulWidth / 2));
682
683         //
684         // Advance to the next row of the image.
685         //
686         pucImage += (ulWidth / 2);
687     }
688 }
689
690 //*****************************************************************************
691 //
692 //! Enable the SSI component of the OLED display driver.
693 //!
694 //! \param ulFrequency specifies the SSI Clock Frequency to be used.
695 //!
696 //! This function initializes the SSI interface to the OLED display.
697 //!
698 //! This function is contained in <tt>osram128x64x4.c</tt>, with
699 //! <tt>osram128x64x4.h</tt> containing the API definition for use by
700 //! applications.
701 //!
702 //! \return None.
703 //
704 //*****************************************************************************
705 void
706 OSRAM128x64x4Enable(unsigned long ulFrequency)
707 {
708     unsigned long ulTemp;
709
710     //
711     // Disable the SSI port.
712     //
713     SSIDisable(SSI0_BASE);
714
715     //
716     // Configure the SSI0 port for master mode.
717     //
718     SSIConfig(SSI0_BASE, SSI_FRF_MOTO_MODE_2, SSI_MODE_MASTER, ulFrequency, 8);
719
720     //
721     // (Re)Enable SSI control of the FSS pin.
722     //
723     GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_3);
724     GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA,
725                      GPIO_PIN_TYPE_STD_WPU);
726
727     //
728     // Enable the SSI port.
729     //
730     SSIEnable(SSI0_BASE);
731
732     //
733     // Drain the receive fifo.
734     //
735     while(SSIDataNonBlockingGet(SSI0_BASE, &ulTemp) != 0)
736     {
737     }
738
739     //
740     // Indicate that the OSRAM driver can use the SSI Port.
741     //
742     g_bSSIEnabled = true;
743 }
744
745 //*****************************************************************************
746 //
747 //! Enable the SSI component of the OLED display driver.
748 //!
749 //! \param ulFrequency specifies the SSI Clock Frequency to be used.
750 //!
751 //! This function initializes the SSI interface to the OLED display.
752 //!
753 //! This function is contained in <tt>osram128x64x4.c</tt>, with
754 //! <tt>osram128x64x4.h</tt> containing the API definition for use by
755 //! applications.
756 //!
757 //! \return None.
758 //
759 //*****************************************************************************
760 void
761 OSRAM128x64x4Disable(void)
762 {
763     unsigned long ulTemp;
764
765     //
766     // Indicate that the OSRAM driver can no longer use the SSI Port.
767     //
768     g_bSSIEnabled = false;
769
770     //
771     // Drain the receive fifo.
772     //
773     while(SSIDataNonBlockingGet(SSI0_BASE, &ulTemp) != 0)
774     {
775     }
776
777     //
778     // Disable the SSI port.
779     //
780     SSIDisable(SSI0_BASE);
781
782     //
783     // Disable SSI control of the FSS pin.
784     //
785     GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_DIR_MODE_OUT);
786     GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA,
787                      GPIO_PIN_TYPE_STD_WPU);
788     GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3);
789
790 }
791
792 //*****************************************************************************
793 //
794 //! Initialize the OLED display.
795 //!
796 //! \param ulFrequency specifies the SSI Clock Frequency to be used.
797 //!
798 //! This function initializes the SSI interface to the OLED display and
799 //! configures the SSD0323 controller on the panel.
800 //!
801 //! This function is contained in <tt>osram128x64x4.c</tt>, with
802 //! <tt>osram128x64x4.h</tt> containing the API definition for use by
803 //! applications.
804 //!
805 //! \return None.
806 //
807 //*****************************************************************************
808 void
809 OSRAM128x64x4Init(unsigned long ulFrequency)
810 {
811     unsigned long ulIdx;
812
813     //
814     // Enable the SSI0 and GPIO port  blocks as they are needed by this driver.
815     //
816     SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
817     SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
818     SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
819
820     //
821     // Configure the SSI0CLK and SSIOTX pins for SSI operation.
822     //
823     GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5);
824     GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_2, GPIO_STRENGTH_8MA,
825                      GPIO_PIN_TYPE_STD_WPU);
826     GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA,
827                      GPIO_PIN_TYPE_STD_WPU);
828     GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_5, GPIO_STRENGTH_8MA,
829                      GPIO_PIN_TYPE_STD_WPU);
830
831     //
832     // Configure the PC7 pin as a D/Cn signal for OLED device.
833     //
834     GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_DIR_MODE_OUT);
835     GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_STRENGTH_8MA,
836                      GPIO_PIN_TYPE_STD);
837     GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_PIN_7);
838
839     //
840     // Configure and enable the SSI0 port for master mode.
841     //
842     OSRAM128x64x4Enable(ulFrequency);
843
844     //
845     // Clear the frame buffer.
846     //
847     OSRAM128x64x4Clear();
848
849     //
850     // Initialize the SSD0323 controller.  Loop through the initialization
851     // sequence array, sending each command "string" to the controller.
852     //
853     for(ulIdx = 0; ulIdx < sizeof(g_pucOSRAM128x64x4Init);
854         ulIdx += g_pucOSRAM128x64x4Init[ulIdx] + 1)
855     {
856         //
857         // Send this command.
858         //
859         OSRAMWriteCommand(g_pucOSRAM128x64x4Init + ulIdx + 1,
860                           g_pucOSRAM128x64x4Init[ulIdx] - 1);
861     }
862 }
863
864 //*****************************************************************************
865 //
866 //! Turns on the OLED display.
867 //!
868 //! This function will turn on the OLED display, causing it to display the
869 //! contents of its internal frame buffer.
870 //!
871 //! This function is contained in <tt>osram128x64x4.c</tt>, with
872 //! <tt>osram128x64x4.h</tt> containing the API definition for use by
873 //! applications.
874 //!
875 //! \return None.
876 //
877 //*****************************************************************************
878 void
879 OSRAM128x64x4DisplayOn(void)
880 {
881     unsigned long ulIdx;
882
883     //
884     // Initialize the SSD0323 controller.  Loop through the initialization
885     // sequence array, sending each command "string" to the controller.
886     //
887     for(ulIdx = 0; ulIdx < sizeof(g_pucOSRAM128x64x4Init);
888         ulIdx += g_pucOSRAM128x64x4Init[ulIdx] + 1)
889     {
890         //
891         // Send this command.
892         //
893         OSRAMWriteCommand(g_pucOSRAM128x64x4Init + ulIdx + 1,
894                           g_pucOSRAM128x64x4Init[ulIdx] - 1);
895     }
896 }
897
898 //*****************************************************************************
899 //
900 //! Turns off the OLED display.
901 //!
902 //! This function will turn off the OLED display.  This will stop the scanning
903 //! of the panel and turn off the on-chip DC-DC converter, preventing damage to
904 //! the panel due to burn-in (it has similar characters to a CRT in this
905 //! respect).
906 //!
907 //! This function is contained in <tt>osram128x64x4.c</tt>, with
908 //! <tt>osram128x64x4.h</tt> containing the API definition for use by
909 //! applications.
910 //!
911 //! \return None.
912 //
913 //*****************************************************************************
914 void
915 OSRAM128x64x4DisplayOff(void)
916 {
917     static const unsigned char pucCommand1[] =
918     {
919         0xAE, 0xAD, 0x02
920     };
921
922     //
923     // Turn off the DC-DC converter and the display.
924     //
925     OSRAMWriteCommand(pucCommand1, sizeof(pucCommand1));
926 }
927
928 //*****************************************************************************
929 //
930 // Close the Doxygen group.
931 //! @}
932 //
933 //*****************************************************************************