1 //*****************************************************************************
\r
3 // rit128x96x4.c - Driver for the RIT 128x96x4 graphical OLED display.
\r
5 // Copyright (c) 2007 Luminary Micro, Inc. All rights reserved.
\r
7 // Software License Agreement
\r
9 // Luminary Micro, Inc. (LMI) is supplying this software for use solely and
\r
10 // exclusively on LMI's microcontroller products.
\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
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
24 // This is part of revision 1504-conf of the Stellaris Peripheral Driver Library.
\r
26 //*****************************************************************************
\r
28 //*****************************************************************************
\r
30 //! \addtogroup ek_lm3sLM3S8962_api
\r
33 //*****************************************************************************
\r
36 #include "hw_memmap.h"
\r
37 #include "hw_sysctl.h"
\r
38 #include "hw_types.h"
\r
43 #include "rit128x96x4.h"
\r
45 //*****************************************************************************
\r
47 // Macros that define the peripheral, port, and pin used for the OLEDDC
\r
48 // panel control signal.
\r
50 //*****************************************************************************
\r
52 unsigned long ulGPIOId = 0, ulGPIOBase = 0, ulOLEDDC_PIN = 0, ulOLEDEN_PIN = 0;
\r
54 #define LM3S8962_SYSCTL_PERIPH_GPIO_OLEDDC SYSCTL_PERIPH_GPIOA
\r
55 #define LM3S8962_GPIO_OLEDDC_BASE GPIO_PORTA_BASE
\r
56 #define LM3S8962_GPIO_OLEDDC_PIN GPIO_PIN_6
\r
57 #define LM3S8962_GPIO_OLEDEN_PIN GPIO_PIN_7
\r
59 #define LM3S1968_SYSCTL_PERIPH_GPIO_OLEDDC SYSCTL_PERIPH_GPIOH
\r
60 #define LM3S1968_GPIO_OLEDDC_BASE GPIO_PORTH_BASE
\r
61 #define LM3S1968_GPIO_OLEDDC_PIN GPIO_PIN_2
\r
62 #define LM3S1968_GPIO_OLEDEN_PIN GPIO_PIN_3
\r
65 //*****************************************************************************
\r
67 // Flag to indicate if SSI port is enabled for display usage.
\r
69 //*****************************************************************************
\r
70 static volatile tBoolean g_bSSIEnabled = false;
\r
72 //*****************************************************************************
\r
74 // Buffer for storing sequences of command and data for the display.
\r
76 //*****************************************************************************
\r
77 static unsigned char g_pucBuffer[8];
\r
79 //*****************************************************************************
\r
81 // Define the SSD1329 128x96x4 Remap Setting(s). This will be used in
\r
82 // several places in the code to switch between vertical and horizontal
\r
83 // address incrementing. Note that the controller support 128 rows while
\r
84 // the RIT display only uses 96.
\r
86 // The Remap Command (0xA0) takes one 8-bit parameter. The parameter is
\r
87 // defined as follows.
\r
90 // Bit 6: Disable(0)/Enable(1) COM Split Odd Even
\r
91 // When enabled, the COM signals are split Odd on one side, even on
\r
92 // the other. Otherwise, they are split 0-63 on one side, 64-127 on
\r
95 // Bit 4: Disable(0)/Enable(1) COM Remap
\r
96 // When Enabled, ROW 0-127 map to COM 127-0 (i.e. reverse row order)
\r
98 // Bit 2: Horizontal(0)/Vertical(1) Address Increment
\r
99 // When set, data RAM address will increment along the column rather
\r
100 // than along the row.
\r
101 // Bit 1: Disable(0)/Enable(1) Nibble Remap
\r
102 // When enabled, the upper and lower nibbles in the DATA bus for access
\r
103 // to the data RAM are swapped.
\r
104 // Bit 0: Disable(0)/Enable(1) Column Address Remap
\r
105 // When enabled, DATA RAM columns 0-63 are remapped to Segment Columns
\r
108 //*****************************************************************************
\r
109 #define RIT_INIT_REMAP 0x52 // app note says 0x51
\r
110 #define RIT_INIT_OFFSET 0x00
\r
111 static const unsigned char g_pucRIT128x96x4VerticalInc[] = { 0xA0, 0x56 };
\r
112 static const unsigned char g_pucRIT128x96x4HorizontalInc[] = { 0xA0, 0x52 };
\r
114 //*****************************************************************************
\r
116 // A 5x7 font (in a 6x8 cell, where the sixth column is omitted from this
\r
117 // table) for displaying text on the OLED display. The data is organized as
\r
118 // bytes from the left column to the right column, with each byte containing
\r
119 // the top row in the LSB and the bottom row in the MSB.
\r
121 // Note: This is the same font data that is used in the EK-LM3S811
\r
122 // osram96x16x1 driver. The single bit-per-pixel is expaned in the StringDraw
\r
123 // function to the appropriate four bit-per-pixel gray scale format.
\r
125 //*****************************************************************************
\r
126 static const unsigned char g_pucFont[96][5] =
\r
128 { 0x00, 0x00, 0x00, 0x00, 0x00 }, // " "
\r
129 { 0x00, 0x00, 0x4f, 0x00, 0x00 }, // !
\r
130 { 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
\r
131 { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #
\r
132 { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $
\r
133 { 0x23, 0x13, 0x08, 0x64, 0x62 }, // %
\r
134 { 0x36, 0x49, 0x55, 0x22, 0x50 }, // &
\r
135 { 0x00, 0x05, 0x03, 0x00, 0x00 }, // '
\r
136 { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (
\r
137 { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )
\r
138 { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // *
\r
139 { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // +
\r
140 { 0x00, 0x50, 0x30, 0x00, 0x00 }, // ,
\r
141 { 0x08, 0x08, 0x08, 0x08, 0x08 }, // -
\r
142 { 0x00, 0x60, 0x60, 0x00, 0x00 }, // .
\r
143 { 0x20, 0x10, 0x08, 0x04, 0x02 }, // /
\r
144 { 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 0
\r
145 { 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 1
\r
146 { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
\r
147 { 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 3
\r
148 { 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 4
\r
149 { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
\r
150 { 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 6
\r
151 { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7
\r
152 { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
\r
153 { 0x06, 0x49, 0x49, 0x29, 0x1e }, // 9
\r
154 { 0x00, 0x36, 0x36, 0x00, 0x00 }, // :
\r
155 { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;
\r
156 { 0x08, 0x14, 0x22, 0x41, 0x00 }, // <
\r
157 { 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
\r
158 { 0x00, 0x41, 0x22, 0x14, 0x08 }, // >
\r
159 { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?
\r
160 { 0x32, 0x49, 0x79, 0x41, 0x3e }, // @
\r
161 { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // A
\r
162 { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B
\r
163 { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C
\r
164 { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // D
\r
165 { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E
\r
166 { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // F
\r
167 { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // G
\r
168 { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H
\r
169 { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I
\r
170 { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // J
\r
171 { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K
\r
172 { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // L
\r
173 { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // M
\r
174 { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // N
\r
175 { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O
\r
176 { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // P
\r
177 { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // Q
\r
178 { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // R
\r
179 { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S
\r
180 { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // T
\r
181 { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // U
\r
182 { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // V
\r
183 { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // W
\r
184 { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
\r
185 { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y
\r
186 { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
\r
187 { 0x00, 0x7f, 0x41, 0x41, 0x00 }, // [
\r
188 { 0x02, 0x04, 0x08, 0x10, 0x20 }, // "\"
\r
189 { 0x00, 0x41, 0x41, 0x7f, 0x00 }, // ]
\r
190 { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^
\r
191 { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _
\r
192 { 0x00, 0x01, 0x02, 0x04, 0x00 }, // `
\r
193 { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a
\r
194 { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // b
\r
195 { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c
\r
196 { 0x38, 0x44, 0x44, 0x48, 0x7f }, // d
\r
197 { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e
\r
198 { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // f
\r
199 { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // g
\r
200 { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // h
\r
201 { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // i
\r
202 { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // j
\r
203 { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // k
\r
204 { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // l
\r
205 { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // m
\r
206 { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // n
\r
207 { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o
\r
208 { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // p
\r
209 { 0x08, 0x14, 0x14, 0x18, 0x7c }, // q
\r
210 { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // r
\r
211 { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s
\r
212 { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // t
\r
213 { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // u
\r
214 { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // v
\r
215 { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // w
\r
216 { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x
\r
217 { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // y
\r
218 { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // z
\r
219 { 0x00, 0x08, 0x36, 0x41, 0x00 }, // {
\r
220 { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // |
\r
221 { 0x00, 0x41, 0x36, 0x08, 0x00 }, // }
\r
222 { 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~
\r
223 { 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~
\r
226 //*****************************************************************************
\r
228 // The sequence of commands used to initialize the SSD1329 controller. Each
\r
229 // command is described as follows: there is a byte specifying the number of
\r
230 // bytes in the command sequence, followed by that many bytes of command data.
\r
231 // Note: This initialization sequence is derived from RIT App Note for
\r
232 // the P14201. Values used are from the RIT app note, except where noted.
\r
234 //*****************************************************************************
\r
235 static const unsigned char g_pucRIT128x96x4Init[] =
\r
240 3, 0xFD, 0x12, 0xe3,
\r
260 3, 0x81, 0xb7, 0xe3,
\r
263 // Pre-charge current
\r
265 3, 0x82, 0x3f, 0xe3,
\r
270 3, 0xA0, RIT_INIT_REMAP, 0xe3,
\r
273 // Display Start Line
\r
280 3, 0xA2, RIT_INIT_OFFSET, 0xe3,
\r
283 // Display Mode Normal
\r
290 3, 0xB1, 0x11, 0xe3,
\r
295 3, 0xB2, 0x23, 0xe3,
\r
298 // Front Clock Divider
\r
300 3, 0xB3, 0xe2, 0xe3,
\r
303 // Set gray scale table. App note uses default command:
\r
305 // This gray scale attempts some gamma correction to reduce the
\r
306 // the brightness of the low levels.
\r
308 17, 0xB8, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 19, 22, 26, 30, 0xe3,
\r
311 // Second pre-charge period. App note uses value 0x04.
\r
313 3, 0xBB, 0x01, 0xe3,
\r
316 // Pre-charge voltage
\r
318 3, 0xBC, 0x3f, 0xe3,
\r
326 //*****************************************************************************
\r
330 //! Write a sequence of command bytes to the SSD1329 controller.
\r
332 //! The data is written in a polled fashion; this function will not return
\r
333 //! until the entire byte sequence has been written to the controller.
\r
337 //*****************************************************************************
\r
339 RITWriteCommand(const unsigned char *pucBuffer, unsigned long ulCount)
\r
341 unsigned long ulTemp;
\r
344 // Return if SSI port is not enabled for RIT display.
\r
352 // Clear the command/control bit to enable command mode.
\r
354 GPIOPinWrite(ulGPIOBase, ulOLEDDC_PIN, 0);
\r
357 // Loop while there are more bytes left to be transferred.
\r
359 while(ulCount != 0)
\r
362 // Write the next byte to the controller.
\r
364 SSIDataPut(SSI0_BASE, *pucBuffer++);
\r
367 // Dummy read to drain the fifo and time the GPIO signal.
\r
369 SSIDataGet(SSI0_BASE, &ulTemp);
\r
372 // Decrement the BYTE counter.
\r
378 //*****************************************************************************
\r
382 //! Write a sequence of data bytes to the SSD1329 controller.
\r
384 //! The data is written in a polled fashion; this function will not return
\r
385 //! until the entire byte sequence has been written to the controller.
\r
389 //*****************************************************************************
\r
391 RITWriteData(const unsigned char *pucBuffer, unsigned long ulCount)
\r
393 unsigned long ulTemp;
\r
396 // Return if SSI port is not enabled for RIT display.
\r
404 // Set the command/control bit to enable data mode.
\r
406 GPIOPinWrite(ulGPIOBase, ulOLEDDC_PIN, ulOLEDDC_PIN);
\r
409 // Loop while there are more bytes left to be transferred.
\r
411 while(ulCount != 0)
\r
414 // Write the next byte to the controller.
\r
416 SSIDataPut(SSI0_BASE, *pucBuffer++);
\r
419 // Dummy read to drain the fifo and time the GPIO signal.
\r
421 SSIDataGet(SSI0_BASE, &ulTemp);
\r
424 // Decrement the BYTE counter.
\r
430 //*****************************************************************************
\r
432 //! Clears the OLED display.
\r
434 //! This function will clear the display RAM. All pixels in the display will
\r
437 //! This function is contained in <tt>rit128x96x4.c</tt>, with
\r
438 //! <tt>rit128x96x4.h</tt> containing the API definition for use by
\r
443 //*****************************************************************************
\r
445 RIT128x96x4Clear(void)
\r
447 static const unsigned char pucCommand1[] = { 0x15, 0, 63 };
\r
448 static const unsigned char pucCommand2[] = { 0x75, 0, 127 };
\r
449 unsigned long ulRow, ulColumn;
\r
452 // Clear out the buffer used for sending bytes to the display.
\r
453 *(unsigned long *)&g_pucBuffer[0] = 0;
\r
454 *(unsigned long *)&g_pucBuffer[4] = 0;
\r
457 // Set the window to fill the entire display.
\r
459 RITWriteCommand(pucCommand1, sizeof(pucCommand1));
\r
460 RITWriteCommand(pucCommand2, sizeof(pucCommand2));
\r
461 RITWriteCommand(g_pucRIT128x96x4HorizontalInc,
\r
462 sizeof(g_pucRIT128x96x4HorizontalInc));
\r
465 // Loop through the rows
\r
467 for(ulRow = 0; ulRow < 96; ulRow++)
\r
470 // Loop through the columns. Each byte is two pixels,
\r
471 // and the buffer hold 8 bytes, so 16 pixels are cleared
\r
474 for(ulColumn = 0; ulColumn < 128; ulColumn += 8 * 2)
\r
477 // Write 8 clearing bytes to the display, which will
\r
478 // clear 16 pixels across.
\r
480 RITWriteData(g_pucBuffer, sizeof(g_pucBuffer));
\r
485 //*****************************************************************************
\r
487 //! Displays a string on the OLED display.
\r
489 //! \param pcStr is a pointer to the string to display.
\r
490 //! \param ulX is the horizontal position to display the string, specified in
\r
491 //! columns from the left edge of the display.
\r
492 //! \param ulY is the vertical position to display the string, specified in
\r
493 //! rows from the top edge of the display.
\r
494 //! \param ucLevel is the 4-bit grey scale value to be used for displayed text.
\r
496 //! This function will draw a string on the display. Only the ASCII characters
\r
497 //! between 32 (space) and 126 (tilde) are supported; other characters will
\r
498 //! result in random data being draw on the display (based on whatever appears
\r
499 //! before/after the font in memory). The font is mono-spaced, so characters
\r
500 //! such as "i" and "l" have more white space around them than characters such
\r
503 //! If the drawing of the string reaches the right edge of the display, no more
\r
504 //! characters will be drawn. Therefore, special care is not required to avoid
\r
505 //! supplying a string that is "too long" to display.
\r
507 //! This function is contained in <tt>rit128x96x4.c</tt>, with
\r
508 //! <tt>rit128x96x4.h</tt> containing the API definition for use by
\r
511 //! \note Because the OLED display packs 2 pixels of data in a single byte, the
\r
512 //! parameter \e ulX must be an even column number (e.g. 0, 2, 4, etc).
\r
516 //*****************************************************************************
\r
518 RIT128x96x4StringDraw(const char *pcStr, unsigned long ulX,
\r
519 unsigned long ulY, unsigned char ucLevel)
\r
521 unsigned long ulIdx1, ulIdx2;
\r
522 unsigned char ucTemp;
\r
525 // Check the arguments.
\r
528 ASSERT((ulX & 1) == 0);
\r
530 ASSERT(ucLevel < 16);
\r
533 // Setup a window starting at the specified column and row, ending
\r
534 // at the right edge of the display and 8 rows down (single character row).
\r
536 g_pucBuffer[0] = 0x15;
\r
537 g_pucBuffer[1] = ulX / 2;
\r
538 g_pucBuffer[2] = 63;
\r
539 RITWriteCommand(g_pucBuffer, 3);
\r
540 g_pucBuffer[0] = 0x75;
\r
541 g_pucBuffer[1] = ulY;
\r
542 g_pucBuffer[2] = ulY + 7;
\r
543 RITWriteCommand(g_pucBuffer, 3);
\r
544 RITWriteCommand(g_pucRIT128x96x4VerticalInc,
\r
545 sizeof(g_pucRIT128x96x4VerticalInc));
\r
548 // Loop while there are more characters in the string.
\r
553 // Get a working copy of the current character and convert to an
\r
554 // index into the character bit-map array.
\r
568 // Build and display the character buffer.
\r
570 for(ulIdx1 = 0; ulIdx1 < 3; ulIdx1++)
\r
573 // Convert two columns of 1-bit font data into a single data
\r
574 // byte column of 4-bit font data.
\r
576 for(ulIdx2 = 0; ulIdx2 < 8; ulIdx2++)
\r
578 g_pucBuffer[ulIdx2] = 0;
\r
579 if(g_pucFont[ucTemp][ulIdx1*2] & (1 << ulIdx2))
\r
581 g_pucBuffer[ulIdx2] = ((ucLevel << 4) & 0xf0);
\r
584 (g_pucFont[ucTemp][ulIdx1*2+1] & (1 << ulIdx2)))
\r
586 g_pucBuffer[ulIdx2] |= ((ucLevel << 0) & 0x0f);
\r
591 // If there is room, dump the single data byte column to the
\r
592 // display. Otherwise, bail out.
\r
596 RITWriteData(g_pucBuffer, 8);
\r
606 // Advance to the next character.
\r
612 //*****************************************************************************
\r
614 //! Displays an image on the OLED display.
\r
616 //! \param pucImage is a pointer to the image data.
\r
617 //! \param ulX is the horizontal position to display this image, specified in
\r
618 //! columns from the left edge of the display.
\r
619 //! \param ulY is the vertical position to display this image, specified in
\r
620 //! rows from the top of the display.
\r
621 //! \param ulWidth is the width of the image, specified in columns.
\r
622 //! \param ulHeight is the height of the image, specified in rows.
\r
624 //! This function will display a bitmap graphic on the display. Because of the
\r
625 //! format of the display RAM, the starting column (\e ulX) and the number of
\r
626 //! columns (\e ulWidth) must be an integer multiple of two.
\r
628 //! The image data is organized with the first row of image data appearing left
\r
629 //! to right, followed immediately by the second row of image data. Each byte
\r
630 //! contains the data for two columns in the current row, with the leftmost
\r
631 //! column being contained in bits 7:4 and the rightmost column being contained
\r
634 //! For example, an image six columns wide and seven scan lines tall would
\r
635 //! be arranged as follows (showing how the twenty one bytes of the image would
\r
636 //! appear on the display):
\r
639 //! +-------------------+-------------------+-------------------+
\r
640 //! | Byte 0 | Byte 1 | Byte 2 |
\r
641 //! +---------+---------+---------+---------+---------+---------+
\r
642 //! | 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
643 //! +---------+---------+---------+---------+---------+---------+
\r
644 //! | Byte 3 | Byte 4 | Byte 5 |
\r
645 //! +---------+---------+---------+---------+---------+---------+
\r
646 //! | 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
647 //! +---------+---------+---------+---------+---------+---------+
\r
648 //! | Byte 6 | Byte 7 | Byte 8 |
\r
649 //! +---------+---------+---------+---------+---------+---------+
\r
650 //! | 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
651 //! +---------+---------+---------+---------+---------+---------+
\r
652 //! | Byte 9 | Byte 10 | Byte 11 |
\r
653 //! +---------+---------+---------+---------+---------+---------+
\r
654 //! | 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
655 //! +---------+---------+---------+---------+---------+---------+
\r
656 //! | Byte 12 | Byte 13 | Byte 14 |
\r
657 //! +---------+---------+---------+---------+---------+---------+
\r
658 //! | 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
659 //! +---------+---------+---------+---------+---------+---------+
\r
660 //! | Byte 15 | Byte 16 | Byte 17 |
\r
661 //! +---------+---------+---------+---------+---------+---------+
\r
662 //! | 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
663 //! +---------+---------+---------+---------+---------+---------+
\r
664 //! | Byte 18 | Byte 19 | Byte 20 |
\r
665 //! +---------+---------+---------+---------+---------+---------+
\r
666 //! | 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
667 //! +---------+---------+---------+---------+---------+---------+
\r
670 //! This function is contained in <tt>rit128x96x4.c</tt>, with
\r
671 //! <tt>rit128x96x4.h</tt> containing the API definition for use by
\r
676 //*****************************************************************************
\r
678 RIT128x96x4ImageDraw(const unsigned char *pucImage, unsigned long ulX,
\r
679 unsigned long ulY, unsigned long ulWidth,
\r
680 unsigned long ulHeight)
\r
683 // Check the arguments.
\r
686 ASSERT((ulX & 1) == 0);
\r
688 ASSERT((ulX + ulWidth) <= 128);
\r
689 ASSERT((ulY + ulHeight) <= 96);
\r
690 ASSERT((ulWidth & 1) == 0);
\r
693 // Setup a window starting at the specified column and row, and ending
\r
694 // at the column + width and row+height.
\r
696 g_pucBuffer[0] = 0x15;
\r
697 g_pucBuffer[1] = ulX / 2;
\r
698 g_pucBuffer[2] = (ulX + ulWidth - 2) / 2;
\r
699 RITWriteCommand(g_pucBuffer, 3);
\r
700 g_pucBuffer[0] = 0x75;
\r
701 g_pucBuffer[1] = ulY;
\r
702 g_pucBuffer[2] = ulY + ulHeight - 1;
\r
703 RITWriteCommand(g_pucBuffer, 3);
\r
704 RITWriteCommand(g_pucRIT128x96x4HorizontalInc,
\r
705 sizeof(g_pucRIT128x96x4HorizontalInc));
\r
708 // Loop while there are more rows to display.
\r
713 // Write this row of image data.
\r
715 RITWriteData(pucImage, (ulWidth / 2));
\r
718 // Advance to the next row of the image.
\r
720 pucImage += (ulWidth / 2);
\r
724 //*****************************************************************************
\r
726 //! Enable the SSI component of the OLED display driver.
\r
728 //! \param ulFrequency specifies the SSI Clock Frequency to be used.
\r
730 //! This function initializes the SSI interface to the OLED display.
\r
732 //! This function is contained in <tt>rit128x96x4.c</tt>, with
\r
733 //! <tt>rit128x96x4.h</tt> containing the API definition for use by
\r
738 //*****************************************************************************
\r
740 RIT128x96x4Enable(unsigned long ulFrequency)
\r
742 unsigned long ulTemp;
\r
745 // Disable the SSI port.
\r
747 SSIDisable(SSI0_BASE);
\r
750 // Configure the SSI0 port for master mode.
\r
752 SSIConfig(SSI0_BASE, SSI_FRF_MOTO_MODE_2, SSI_MODE_MASTER, ulFrequency, 8);
\r
755 // (Re)Enable SSI control of the FSS pin.
\r
757 GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_3);
\r
758 GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA,
\r
759 GPIO_PIN_TYPE_STD_WPU);
\r
762 // Enable the SSI port.
\r
764 SSIEnable(SSI0_BASE);
\r
767 // Drain the receive fifo.
\r
769 while(SSIDataNonBlockingGet(SSI0_BASE, &ulTemp) != 0)
\r
774 // Indicate that the RIT driver can use the SSI Port.
\r
776 g_bSSIEnabled = true;
\r
779 //*****************************************************************************
\r
781 //! Enable the SSI component of the OLED display driver.
\r
783 //! This function initializes the SSI interface to the OLED display.
\r
785 //! This function is contained in <tt>rit128x96x4.c</tt>, with
\r
786 //! <tt>rit128x96x4.h</tt> containing the API definition for use by
\r
791 //*****************************************************************************
\r
793 RIT128x96x4Disable(void)
\r
795 unsigned long ulTemp;
\r
798 // Indicate that the RIT driver can no longer use the SSI Port.
\r
800 g_bSSIEnabled = false;
\r
803 // Drain the receive fifo.
\r
805 while(SSIDataNonBlockingGet(SSI0_BASE, &ulTemp) != 0)
\r
810 // Disable the SSI port.
\r
812 SSIDisable(SSI0_BASE);
\r
815 // Disable SSI control of the FSS pin.
\r
817 GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_3);
\r
818 GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_STRENGTH_8MA,
\r
819 GPIO_PIN_TYPE_STD_WPU);
\r
820 GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_3, GPIO_PIN_3);
\r
823 //*****************************************************************************
\r
825 //! Initialize the OLED display.
\r
827 //! \param ulFrequency specifies the SSI Clock Frequency to be used.
\r
829 //! This function initializes the SSI interface to the OLED display and
\r
830 //! configures the SSD1329 controller on the panel.
\r
832 //! This function is contained in <tt>rit128x96x4.c</tt>, with
\r
833 //! <tt>rit128x96x4.h</tt> containing the API definition for use by
\r
838 //*****************************************************************************
\r
840 RIT128x96x4Init(unsigned long ulFrequency)
\r
842 unsigned long ulIdx;
\r
845 /* Determine which board is being used. */
\r
846 if( SysCtlPeripheralPresent( SYSCTL_PERIPH_ETH ) )
\r
848 /* Ethernet is present, we must be using the LM3S8962 EK. */
\r
849 ulGPIOId = LM3S8962_SYSCTL_PERIPH_GPIO_OLEDDC;
\r
850 ulGPIOBase = LM3S8962_GPIO_OLEDDC_BASE;
\r
851 ulOLEDDC_PIN = GPIO_PIN_6;
\r
852 ulOLEDEN_PIN = GPIO_PIN_7;
\r
856 /* Ethernet is not present, we must be using the LM3S1968 EK. */
\r
857 ulGPIOId = LM3S1968_SYSCTL_PERIPH_GPIO_OLEDDC;
\r
858 ulGPIOBase = LM3S1968_GPIO_OLEDDC_BASE;
\r
859 ulOLEDDC_PIN = GPIO_PIN_2;
\r
860 ulOLEDEN_PIN = GPIO_PIN_3;
\r
864 // Enable the SSI0 and GPIO port blocks as they are needed by this driver.
\r
866 SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
\r
867 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
\r
868 SysCtlPeripheralEnable(ulGPIOId);
\r
871 // Configure the SSI0CLK and SSIOTX pins for SSI operation.
\r
873 GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5);
\r
874 GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_5,
\r
875 GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU);
\r
878 // Configure the GPIO port pin used as a D/Cn signal for OLED device,
\r
879 // and the port pin used to enable power to the OLED panel.
\r
881 GPIOPinTypeGPIOOutput(ulGPIOBase, ulOLEDDC_PIN | ulOLEDEN_PIN);
\r
882 GPIOPadConfigSet(ulGPIOBase, ulOLEDDC_PIN | ulOLEDEN_PIN,
\r
883 GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
\r
884 GPIOPinWrite(ulGPIOBase, ulOLEDDC_PIN | ulOLEDEN_PIN,
\r
885 ulOLEDDC_PIN | ulOLEDEN_PIN);
\r
888 // Configure and enable the SSI0 port for master mode.
\r
890 RIT128x96x4Enable(ulFrequency);
\r
893 // Clear the frame buffer.
\r
895 RIT128x96x4Clear();
\r
898 // Initialize the SSD1329 controller. Loop through the initialization
\r
899 // sequence array, sending each command "string" to the controller.
\r
901 for(ulIdx = 0; ulIdx < sizeof(g_pucRIT128x96x4Init);
\r
902 ulIdx += g_pucRIT128x96x4Init[ulIdx] + 1)
\r
905 // Send this command.
\r
907 RITWriteCommand(g_pucRIT128x96x4Init + ulIdx + 1,
\r
908 g_pucRIT128x96x4Init[ulIdx] - 1);
\r
912 //*****************************************************************************
\r
914 //! Turns on the OLED display.
\r
916 //! This function will turn on the OLED display, causing it to display the
\r
917 //! contents of its internal frame buffer.
\r
919 //! This function is contained in <tt>rit128x96x4.c</tt>, with
\r
920 //! <tt>rit128x96x4.h</tt> containing the API definition for use by
\r
925 //*****************************************************************************
\r
927 RIT128x96x4DisplayOn(void)
\r
929 unsigned long ulIdx;
\r
932 // Initialize the SSD1329 controller. Loop through the initialization
\r
933 // sequence array, sending each command "string" to the controller.
\r
935 for(ulIdx = 0; ulIdx < sizeof(g_pucRIT128x96x4Init);
\r
936 ulIdx += g_pucRIT128x96x4Init[ulIdx] + 1)
\r
939 // Send this command.
\r
941 RITWriteCommand(g_pucRIT128x96x4Init + ulIdx + 1,
\r
942 g_pucRIT128x96x4Init[ulIdx] - 1);
\r
946 //*****************************************************************************
\r
948 //! Turns off the OLED display.
\r
950 //! This function will turn off the OLED display. This will stop the scanning
\r
951 //! of the panel and turn off the on-chip DC-DC converter, preventing damage to
\r
952 //! the panel due to burn-in (it has similar characters to a CRT in this
\r
955 //! This function is contained in <tt>rit128x96x4.c</tt>, with
\r
956 //! <tt>rit128x96x4.h</tt> containing the API definition for use by
\r
961 //*****************************************************************************
\r
963 RIT128x96x4DisplayOff(void)
\r
965 static const unsigned char pucCommand1[] =
\r
971 // Put the display to sleep.
\r
973 RITWriteCommand(pucCommand1, sizeof(pucCommand1));
\r
976 //*****************************************************************************
\r
978 // Close the Doxygen group.
\r
981 //*****************************************************************************
\r