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