OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [CORTEX_LM3S811_KEIL/] [LuminaryCode/] [osram96x16.c] - Blame information for rev 581

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 581 jeremybenn
//*****************************************************************************
2
//
3
// osram96x16.c - Driver for the OSRAM 96x16 graphical OLED display.
4
//
5
// Copyright (c) 2006 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 Stellaris Family of 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 816 of the Stellaris Driver Library.
25
//
26
//*****************************************************************************
27
 
28
//*****************************************************************************
29
//
30
//! \addtogroup ev_lm3s811_api
31
//! @{
32
//
33
//*****************************************************************************
34
 
35
#include "hw_i2c.h"
36
#include "hw_memmap.h"
37
#include "hw_sysctl.h"
38
#include "hw_types.h"
39
#include "src/debug.h"
40
#include "src/gpio.h"
41
#include "src/i2c.h"
42
#include "src/sysctl.h"
43
#include "osram96x16.h"
44
 
45
extern void I2CMasterInitExpClk(unsigned long ulBase, unsigned long ulI2CClk,  tBoolean bFast);
46
//*****************************************************************************
47
//
48
// The I2C slave address of the SSD0303 controller on the OLED display.
49
//
50
//*****************************************************************************
51
#define SSD0303_ADDR            0x3d
52
 
53
//*****************************************************************************
54
//
55
// A 5x7 font (in a 6x8 cell, where the sixth column is omitted from this
56
// table) for displaying text on the OLED display.  The data is organized as
57
// bytes from the left column to the right column, with each byte containing
58
// the top row in the LSB and the bottom row in the MSB.
59
//
60
//*****************************************************************************
61
static const unsigned char g_pucFont[95][5] =
62
{
63
    { 0x00, 0x00, 0x00, 0x00, 0x00 }, // " "
64
    { 0x00, 0x00, 0x4f, 0x00, 0x00 }, // !
65
    { 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
66
    { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #
67
    { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $
68
    { 0x23, 0x13, 0x08, 0x64, 0x62 }, // %
69
    { 0x36, 0x49, 0x55, 0x22, 0x50 }, // &
70
    { 0x00, 0x05, 0x03, 0x00, 0x00 }, // '
71
    { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (
72
    { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )
73
    { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // *
74
    { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // +
75
    { 0x00, 0x50, 0x30, 0x00, 0x00 }, // ,
76
    { 0x08, 0x08, 0x08, 0x08, 0x08 }, // -
77
    { 0x00, 0x60, 0x60, 0x00, 0x00 }, // .
78
    { 0x20, 0x10, 0x08, 0x04, 0x02 }, // /
79
    { 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 0
80
    { 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 1
81
    { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
82
    { 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 3
83
    { 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 4
84
    { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
85
    { 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 6
86
    { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7
87
    { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
88
    { 0x06, 0x49, 0x49, 0x29, 0x1e }, // 9
89
    { 0x00, 0x36, 0x36, 0x00, 0x00 }, // :
90
    { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;
91
    { 0x08, 0x14, 0x22, 0x41, 0x00 }, // <
92
    { 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
93
    { 0x00, 0x41, 0x22, 0x14, 0x08 }, // >
94
    { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?
95
    { 0x32, 0x49, 0x79, 0x41, 0x3e }, // @
96
    { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // A
97
    { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // B
98
    { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // C
99
    { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // D
100
    { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // E
101
    { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // F
102
    { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // G
103
    { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // H
104
    { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // I
105
    { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // J
106
    { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // K
107
    { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // L
108
    { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // M
109
    { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // N
110
    { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // O
111
    { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // P
112
    { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // Q
113
    { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // R
114
    { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S
115
    { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // T
116
    { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // U
117
    { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // V
118
    { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // W
119
    { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
120
    { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y
121
    { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
122
    { 0x00, 0x7f, 0x41, 0x41, 0x00 }, // [
123
    { 0x02, 0x04, 0x08, 0x10, 0x20 }, // "\"
124
    { 0x00, 0x41, 0x41, 0x7f, 0x00 }, // ]
125
    { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^
126
    { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _
127
    { 0x00, 0x01, 0x02, 0x04, 0x00 }, // `
128
    { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a
129
    { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // b
130
    { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c
131
    { 0x38, 0x44, 0x44, 0x48, 0x7f }, // d
132
    { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e
133
    { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // f
134
    { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // g
135
    { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // h
136
    { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // i
137
    { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // j
138
    { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // k
139
    { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // l
140
    { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // m
141
    { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // n
142
    { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o
143
    { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // p
144
    { 0x08, 0x14, 0x14, 0x18, 0x7c }, // q
145
    { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // r
146
    { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s
147
    { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // t
148
    { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // u
149
    { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // v
150
    { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // w
151
    { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x
152
    { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // y
153
    { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // z
154
    { 0x00, 0x08, 0x36, 0x41, 0x00 }, // {
155
    { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // |
156
    { 0x00, 0x41, 0x36, 0x08, 0x00 }, // }
157
    { 0x02, 0x01, 0x02, 0x04, 0x02 }, // ~
158
};
159
 
160
//*****************************************************************************
161
//
162
// The sequence of commands used to initialize the SSD0303 controller.  Each
163
// command is described as follows:  there is a byte specifying the number of
164
// bytes in the I2C transfer, followed by that many bytes of command data.
165
//
166
//*****************************************************************************
167
static const unsigned char g_pucOSRAMInit[] =
168
{
169
    //
170
    // Turn off the panel
171
    //
172
    0x02, 0x80, 0xae,
173
 
174
    //
175
    // Set lower column address
176
    //
177
    0x02, 0x80, 0x04,
178
 
179
    //
180
    // Set higher column address
181
    //
182
    0x02, 0x80, 0x12,
183
 
184
    //
185
    // Set contrast control register
186
    //
187
    0x04, 0x80, 0x81, 0x80, 0x2b,
188
 
189
    //
190
    // Set segment re-map
191
    //
192
    0x02, 0x80, 0xa1,
193
 
194
    //
195
    // Set display start line
196
    //
197
    0x02, 0x80, 0x40,
198
 
199
    //
200
    // Set display offset
201
    //
202
    0x04, 0x80, 0xd3, 0x80, 0x00,
203
 
204
    //
205
    // Set multiplex ratio
206
    //
207
    0x04, 0x80, 0xa8, 0x80, 0x0f,
208
 
209
    //
210
    // Set the display to normal mode
211
    //
212
    0x02, 0x80, 0xa4,
213
 
214
    //
215
    // Non-inverted display
216
    //
217
    0x02, 0x80, 0xa6,
218
 
219
    //
220
    // Set the page address
221
    //
222
    0x02, 0x80, 0xb0,
223
 
224
    //
225
    // Set COM output scan direction
226
    //
227
    0x02, 0x80, 0xc8,
228
 
229
    //
230
    // Set display clock divide ratio/oscillator frequency
231
    //
232
    0x04, 0x80, 0xd5, 0x80, 0x72,
233
 
234
    //
235
    // Enable mono mode
236
    //
237
    0x04, 0x80, 0xd8, 0x80, 0x00,
238
 
239
    //
240
    // Set pre-charge period
241
    //
242
    0x04, 0x80, 0xd9, 0x80, 0x22,
243
 
244
    //
245
    // Set COM pins hardware configuration
246
    //
247
    0x04, 0x80, 0xda, 0x80, 0x12,
248
 
249
    //
250
    // Set VCOM deslect level
251
    //
252
    0x04, 0x80, 0xdb, 0x80, 0x0f,
253
 
254
    //
255
    // Set DC-DC on
256
    //
257
    0x04, 0x80, 0xad, 0x80, 0x8b,
258
 
259
    //
260
    // Turn on the panel
261
    //
262
    0x02, 0x80, 0xaf,
263
};
264
 
265
//*****************************************************************************
266
//
267
// The inter-byte delay required by the SSD0303 OLED controller.
268
//
269
//*****************************************************************************
270
static unsigned long g_ulDelay;
271
 
272
//*****************************************************************************
273
//
274
//! \internal
275
//!
276
//! Provide a small delay.
277
//!
278
//! \param ulCount is the number of delay loop iterations to perform.
279
//!
280
//! Since the SSD0303 controller needs a delay between bytes written to it over
281
//! the I2C bus, this function provides a means of generating that delay.  It
282
//! is written in assembly to keep the delay consistent across tool chains,
283
//! avoiding the need to tune the delay based on the tool chain in use.
284
//!
285
//! \return None.
286
//
287
//*****************************************************************************
288
#if defined(ewarm)
289
static void
290
OSRAMDelay(unsigned long ulCount)
291
{
292
    __asm("    subs    r0, #1\n"
293
          "    bne     OSRAMDelay\n"
294
          "    bx      lr");
295
}
296
#endif
297
#if defined(gcc)
298
static void __attribute__((naked))
299
OSRAMDelay(unsigned long ulCount)
300
{
301
    __asm("    subs    r0, #1\n"
302
          "    bne     OSRAMDelay\n"
303
          "    bx      lr");
304
}
305
#endif
306
#if defined(rvmdk) || defined(__ARMCC_VERSION)
307
__asm void
308
OSRAMDelay(unsigned long ulCount)
309
{
310
    subs    r0, #1;
311
    bne     OSRAMDelay;
312
    bx      lr;
313
}
314
#endif
315
 
316
//*****************************************************************************
317
//
318
//! \internal
319
//!
320
//! Start a transfer to the SSD0303 controller.
321
//!
322
//! \param ucChar is the first byte to be written to the controller.
323
//!
324
//! This function will start a transfer to the SSD0303 controller via the I2C
325
//! bus.
326
//!
327
//! The data is written in a polled fashion; this function will not return
328
//! until the byte has been written to the controller.
329
//!
330
//! \return None.
331
//
332
//*****************************************************************************
333
static void
334
OSRAMWriteFirst(unsigned char ucChar)
335
{
336
    //
337
    // Set the slave address.
338
    //
339
    I2CMasterSlaveAddrSet(I2C_MASTER_BASE, SSD0303_ADDR, false);
340
 
341
    //
342
    // Write the first byte to the controller.
343
    //
344
    I2CMasterDataPut(I2C_MASTER_BASE, ucChar);
345
 
346
    //
347
    // Start the transfer.
348
    //
349
    I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_START);
350
}
351
 
352
//*****************************************************************************
353
//
354
//! \internal
355
//!
356
//! Write a byte to the SSD0303 controller.
357
//!
358
//! \param ucChar is the byte to be transmitted to the controller.
359
//!
360
//! This function continues a transfer to the SSD0303 controller by writing
361
//! another byte over the I2C bus.  This must only be called after calling
362
//! OSRAMWriteFirst(), but before calling OSRAMWriteFinal().
363
//!
364
//! The data is written in a polled faashion; this function will not return
365
//! until the byte has been written to the controller.
366
//!
367
//! \return None.
368
//
369
//*****************************************************************************
370
static void
371
OSRAMWriteByte(unsigned char ucChar)
372
{
373
    //
374
    // Wait until the current byte has been transferred.
375
    //
376
    while(I2CMasterIntStatus(I2C_MASTER_BASE, false) == 0)
377
    {
378
    }
379
 
380
    //
381
    // Provide the required inter-byte delay.
382
    //
383
    OSRAMDelay(g_ulDelay);
384
 
385
    //
386
    // Write the next byte to the controller.
387
    //
388
    I2CMasterDataPut(I2C_MASTER_BASE, ucChar);
389
 
390
    //
391
    // Continue the transfer.
392
    //
393
    I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
394
}
395
 
396
//*****************************************************************************
397
//
398
//! \internal
399
//!
400
//! Write a sequence of bytes to the SSD0303 controller.
401
//!
402
//! This function continues a transfer to the SSD0303 controller by writing a
403
//! sequence of bytes over the I2C bus.  This must only be called after calling
404
//! OSRAMWriteFirst(), but before calling OSRAMWriteFinal().
405
//!
406
//! The data is written in a polled fashion; this function will not return
407
//! until the entire byte sequence has been written to the controller.
408
//!
409
//! \return None.
410
//
411
//*****************************************************************************
412
static void
413
OSRAMWriteArray(const unsigned char *pucBuffer, unsigned long ulCount)
414
{
415
    //
416
    // Loop while there are more bytes left to be transferred.
417
    //
418
    while(ulCount != 0)
419
    {
420
        //
421
        // Wait until the current byte has been transferred.
422
        //
423
        while(I2CMasterIntStatus(I2C_MASTER_BASE, false) == 0)
424
        {
425
        }
426
 
427
        //
428
        // Provide the required inter-byte delay.
429
        //
430
        OSRAMDelay(g_ulDelay);
431
 
432
        //
433
        // Write the next byte to the controller.
434
        //
435
        I2CMasterDataPut(I2C_MASTER_BASE, *pucBuffer++);
436
        ulCount--;
437
 
438
        //
439
        // Continue the transfer.
440
        //
441
        I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
442
    }
443
}
444
 
445
//*****************************************************************************
446
//
447
//! \internal
448
//!
449
//! Finish a transfer to the SSD0303 controller.
450
//!
451
//! \param ucChar is the final byte to be written to the controller.
452
//!
453
//! This function will finish a transfer to the SSD0303 controller via the I2C
454
//! bus.  This must only be called after calling OSRAMWriteFirst().
455
//!
456
//! The data is written in a polled fashion; this function will not return
457
//! until the byte has been written to the controller.
458
//!
459
//! \return None.
460
//
461
//*****************************************************************************
462
static void
463
OSRAMWriteFinal(unsigned char ucChar)
464
{
465
    //
466
    // Wait until the current byte has been transferred.
467
    //
468
    while(I2CMasterIntStatus(I2C_MASTER_BASE, false) == 0)
469
    {
470
    }
471
 
472
    //
473
    // Provide the required inter-byte delay.
474
    //
475
    OSRAMDelay(g_ulDelay);
476
 
477
    //
478
    // Write the final byte to the controller.
479
    //
480
    I2CMasterDataPut(I2C_MASTER_BASE, ucChar);
481
 
482
    //
483
    // Finish the transfer.
484
    //
485
    I2CMasterControl(I2C_MASTER_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
486
 
487
    //
488
    // Wait until the final byte has been transferred.
489
    //
490
    while(I2CMasterIntStatus(I2C_MASTER_BASE, false) == 0)
491
    {
492
    }
493
 
494
    //
495
    // Provide the required inter-byte delay.
496
    //
497
    OSRAMDelay(g_ulDelay);
498
}
499
 
500
//*****************************************************************************
501
//
502
//! Clears the OLED display.
503
//!
504
//! This function will clear the display.  All pixels in the display will be
505
//! turned off.
506
//!
507
//! \return None.
508
//
509
//*****************************************************************************
510
void
511
OSRAMClear(void)
512
{
513
    static const unsigned char pucRow1[] =
514
    {
515
        0xb0, 0x80, 0x04, 0x80, 0x12, 0x40
516
    };
517
    static const unsigned char pucRow2[] =
518
    {
519
        0xb1, 0x80, 0x04, 0x80, 0x12, 0x40
520
    };
521
    unsigned long ulIdx;
522
 
523
    //
524
    // Move the display cursor to the first column of the first row.
525
    //
526
    OSRAMWriteFirst(0x80);
527
    OSRAMWriteArray(pucRow1, sizeof(pucRow1));
528
 
529
    //
530
    // Fill this row with zeros.
531
    //
532
    for(ulIdx = 0; ulIdx < 95; ulIdx++)
533
    {
534
        OSRAMWriteByte(0x00);
535
    }
536
    OSRAMWriteFinal(0x00);
537
 
538
    //
539
    // Move the display cursor to the first column of the second row.
540
    //
541
    OSRAMWriteFirst(0x80);
542
    OSRAMWriteArray(pucRow2, sizeof(pucRow2));
543
 
544
    //
545
    // Fill this row with zeros.
546
    //
547
    for(ulIdx = 0; ulIdx < 95; ulIdx++)
548
    {
549
        OSRAMWriteByte(0x00);
550
    }
551
    OSRAMWriteFinal(0x00);
552
}
553
 
554
//*****************************************************************************
555
//
556
//! Displays a string on the OLED display.
557
//!
558
//! \param pcStr is a pointer to the string to display.
559
//! \param ulX is the horizontal position to display the string, specified in
560
//! columns from the left edge of the display.
561
//! \param ulY is the vertical position to display the string, specified in
562
//! eight scan line blocks from the top of the display (i.e. only 0 and 1 are
563
//! valid).
564
//!
565
//! This function will draw a string on the display.  Only the ASCII characters
566
//! between 32 (space) and 126 (tilde) are supported; other characters will
567
//! result in random data being draw on the display (based on whatever appears
568
//! before/after the font in memory).  The font is mono-spaced, so characters
569
//! such as "i" and "l" have more white space around them than characters such
570
//! as "m" or "w".
571
//!
572
//! If the drawing of the string reaches the right edge of the display, no more
573
//! characters will be drawn.  Therefore, special care is not required to avoid
574
//! supplying a string that is "too long" to display.
575
//!
576
//! \return None.
577
//
578
//*****************************************************************************
579
void
580
OSRAMStringDraw(const char *pcStr, unsigned long ulX, unsigned long ulY)
581
{
582
    //
583
    // Check the arguments.
584
    //
585
    ASSERT(ulX < 96);
586
    ASSERT(ulY < 2);
587
 
588
    //
589
    // Move the display cursor to the requested position on the display.
590
    //
591
    OSRAMWriteFirst(0x80);
592
    OSRAMWriteByte((ulY == 0) ? 0xb0 : 0xb1);
593
    OSRAMWriteByte(0x80);
594
    OSRAMWriteByte((ulX + 36) & 0x0f);
595
    OSRAMWriteByte(0x80);
596
    OSRAMWriteByte(0x10 | (((ulX + 36) >> 4) & 0x0f));
597
    OSRAMWriteByte(0x40);
598
 
599
    //
600
    // Loop while there are more characters in the string.
601
    //
602
    while(*pcStr != 0)
603
    {
604
        //
605
        // See if there is enough space on the display for this entire
606
        // character.
607
        //
608
        if(ulX <= 90)
609
        {
610
            //
611
            // Write the contents of this character to the display.
612
            //
613
            OSRAMWriteArray(g_pucFont[*pcStr - ' '], 5);
614
 
615
            //
616
            // See if this is the last character to display (either because the
617
            // right edge has been reached or because there are no more
618
            // characters).
619
            //
620
            if((ulX == 90) || (pcStr[1] == 0))
621
            {
622
                //
623
                // Write the final column of the display.
624
                //
625
                OSRAMWriteFinal(0x00);
626
 
627
                //
628
                // The string has been displayed.
629
                //
630
                return;
631
            }
632
 
633
            //
634
            // Write the inter-character padding column.
635
            //
636
            OSRAMWriteByte(0x00);
637
        }
638
        else
639
        {
640
            //
641
            // Write the portion of the character that will fit onto the
642
            // display.
643
            //
644
            OSRAMWriteArray(g_pucFont[*pcStr - ' '], 95 - ulX);
645
            OSRAMWriteFinal(g_pucFont[*pcStr - ' '][95 - ulX]);
646
 
647
            //
648
            // The string has been displayed.
649
            //
650
            return;
651
        }
652
 
653
        //
654
        // Advance to the next character.
655
        //
656
        pcStr++;
657
 
658
        //
659
        // Increment the X coordinate by the six columns that were just
660
        // written.
661
        //
662
        ulX += 6;
663
    }
664
}
665
 
666
//*****************************************************************************
667
//
668
//! Displays an image on the OLED display.
669
//!
670
//! \param pucImage is a pointer to the image data.
671
//! \param ulX is the horizontal position to display this image, specified in
672
//! columns from the left edge of the display.
673
//! \param ulY is the vertical position to display this image, specified in
674
//! eight scan line blocks from the top of the display (i.e. only 0 and 1 are
675
//! valid).
676
//! \param ulWidth is the width of the image, specified in columns.
677
//! \param ulHeight is the height of the image, specified in eight row blocks
678
//! (i.e. only 1 and 2 are valid).
679
//!
680
//! This function will display a bitmap graphic on the display.  The image to
681
//! be displayed must be a multiple of eight scan lines high (i.e. one row) and
682
//! will be drawn at a vertical position that is a multiple of eight scan lines
683
//! (i.e. scan line zero or scan line eight, corresponding to row zero or row
684
//! one).
685
//!
686
//! The image data is organized with the first row of image data appearing left
687
//! to right, followed immediately by the second row of image data.  Each byte
688
//! contains the data for the eight scan lines of the column, with the top scan
689
//! line being in the least significant bit of the byte and the bottom scan
690
//! line being in the most significant bit of the byte.
691
//!
692
//! For example, an image four columns wide and sixteen scan lines tall would
693
//! be arranged as follows (showing how the eight bytes of the image would
694
//! appear on the display):
695
//!
696
//! \verbatim
697
//!     +-------+  +-------+  +-------+  +-------+
698
//!     |   | 0 |  |   | 0 |  |   | 0 |  |   | 0 |
699
//!     | B | 1 |  | B | 1 |  | B | 1 |  | B | 1 |
700
//!     | y | 2 |  | y | 2 |  | y | 2 |  | y | 2 |
701
//!     | t | 3 |  | t | 3 |  | t | 3 |  | t | 3 |
702
//!     | e | 4 |  | e | 4 |  | e | 4 |  | e | 4 |
703
//!     |   | 5 |  |   | 5 |  |   | 5 |  |   | 5 |
704
//!     | 0 | 6 |  | 1 | 6 |  | 2 | 6 |  | 3 | 6 |
705
//!     |   | 7 |  |   | 7 |  |   | 7 |  |   | 7 |
706
//!     +-------+  +-------+  +-------+  +-------+
707
//!
708
//!     +-------+  +-------+  +-------+  +-------+
709
//!     |   | 0 |  |   | 0 |  |   | 0 |  |   | 0 |
710
//!     | B | 1 |  | B | 1 |  | B | 1 |  | B | 1 |
711
//!     | y | 2 |  | y | 2 |  | y | 2 |  | y | 2 |
712
//!     | t | 3 |  | t | 3 |  | t | 3 |  | t | 3 |
713
//!     | e | 4 |  | e | 4 |  | e | 4 |  | e | 4 |
714
//!     |   | 5 |  |   | 5 |  |   | 5 |  |   | 5 |
715
//!     | 4 | 6 |  | 5 | 6 |  | 6 | 6 |  | 7 | 6 |
716
//!     |   | 7 |  |   | 7 |  |   | 7 |  |   | 7 |
717
//!     +-------+  +-------+  +-------+  +-------+
718
//! \endverbatim
719
//!
720
//! \return None.
721
//
722
//*****************************************************************************
723
void
724
OSRAMImageDraw(const unsigned char *pucImage, unsigned long ulX,
725
               unsigned long ulY, unsigned long ulWidth,
726
               unsigned long ulHeight)
727
{
728
    //
729
    // Check the arguments.
730
    //
731
    ASSERT(ulX < 96);
732
    ASSERT(ulY < 2);
733
    ASSERT((ulX + ulWidth) <= 96);
734
    ASSERT((ulY + ulHeight) <= 2);
735
 
736
    //
737
    // The first 36 columns of the LCD buffer are not displayed, so increment
738
    // the X coorddinate by 36 to account for the non-displayed frame buffer
739
    // memory.
740
    //
741
    ulX += 36;
742
 
743
    //
744
    // Loop while there are more rows to display.
745
    //
746
    while(ulHeight--)
747
    {
748
        //
749
        // Write the starting address within this row.
750
        //
751
        OSRAMWriteFirst(0x80);
752
        OSRAMWriteByte((ulY == 0) ? 0xb0 : 0xb1);
753
        OSRAMWriteByte(0x80);
754
        OSRAMWriteByte(ulX & 0x0f);
755
        OSRAMWriteByte(0x80);
756
        OSRAMWriteByte(0x10 | ((ulX >> 4) & 0x0f));
757
        OSRAMWriteByte(0x40);
758
 
759
        //
760
        // Write this row of image data.
761
        //
762
        OSRAMWriteArray(pucImage, ulWidth - 1);
763
        OSRAMWriteFinal(pucImage[ulWidth - 1]);
764
 
765
        //
766
        // Advance to the next row of the image.
767
        //
768
        pucImage += ulWidth;
769
        ulY++;
770
    }
771
}
772
 
773
//*****************************************************************************
774
//
775
//! Initialize the OLED display.
776
//!
777
//! \param bFast is a boolean that is \e true if the I2C interface should be
778
//! run at 400 kbps and \e false if it should be run at 100 kbps.
779
//!
780
//! This function initializes the I2C interface to the OLED display and
781
//! configures the SSD0303 controller on the panel.
782
//!
783
//! \return None.
784
//
785
//*****************************************************************************
786
void
787
OSRAMInit(tBoolean bFast)
788
{
789
    unsigned long ulIdx;
790
 
791
    //
792
    // Enable the I2C and GPIO port B blocks as they are needed by this driver.
793
    //
794
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C);
795
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
796
 
797
    //
798
    // Configure the I2C SCL and SDA pins for I2C operation.
799
    //
800
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);
801
 
802
    //
803
    // Initialize the I2C master.
804
    //
805
    I2CMasterInitExpClk(I2C_MASTER_BASE, SysCtlClockGet(), bFast);
806
 
807
    //
808
    // Compute the inter-byte delay for the SSD0303 controller.  This delay is
809
    // dependent upon the I2C bus clock rate; the slower the clock the longer
810
    // the delay required.
811
    //
812
    // The derivation of this formula is based on a measured delay of
813
    // OSRAMDelay(1700) for a 100 kHz I2C bus with the CPU running at 50 MHz
814
    // (referred to as C).  To scale this to the delay for a different CPU
815
    // speed (since this is just a CPU-based delay loop) is:
816
    //
817
    //           f(CPU)
818
    //     C * ----------
819
    //         50,000,000
820
    //
821
    // To then scale this to the actual I2C rate (since it won't always be
822
    // precisely 100 kHz):
823
    //
824
    //           f(CPU)     100,000
825
    //     C * ---------- * -------
826
    //         50,000,000    f(I2C)
827
    //
828
    // This equation will give the inter-byte delay required for any
829
    // configuration of the I2C master.  But, as arranged it is impossible to
830
    // directly compute in 32-bit arithmetic (without loosing a lot of
831
    // accuracy).  So, the equation is simplified.
832
    //
833
    // Since f(I2C) is generated by dividing down from f(CPU), replace it with
834
    // the equivalent (where TPR is the value programmed into the Master Timer
835
    // Period Register of the I2C master, with the 1 added back):
836
    //
837
    //                        100,000
838
    //           f(CPU)       -------
839
    //     C * ---------- *    f(CPU)
840
    //         50,000,000   ------------
841
    //                      2 * 10 * TPR
842
    //
843
    // Inverting the dividend in the last term:
844
    //
845
    //           f(CPU)     100,000 * 2 * 10 * TPR
846
    //     C * ---------- * ----------------------
847
    //         50,000,000          f(CPU)
848
    //
849
    // The f(CPU) now cancels out.
850
    //
851
    //         100,000 * 2 * 10 * TPR
852
    //     C * ----------------------
853
    //               50,000,000
854
    //
855
    // Since there are no clock frequencies left in the equation, this equation
856
    // also works for 400 kHz bus operation as well, since the 100,000 in the
857
    // numerator becomes 400,000 but C is 1/4, which cancel out each other.
858
    // Reducing the constants gives:
859
    //
860
    //         TPR              TPR             TPR
861
    //     C * ---   =   1700 * ---   =   340 * ---
862
    //         25               25               5
863
    //
864
    // Note that the constant C is actually a bit larger than it needs to be in
865
    // order to provide some safety margin.
866
    //
867
    // When the panel is being initialized, the value of C actually needs to be
868
    // a bit longer (3200 instead of 1700).  So, set the larger value for now.
869
    //
870
    g_ulDelay = (640 * (HWREG(I2C_MASTER_BASE + I2C_MASTER_O_TPR) + 1)) / 5;
871
 
872
    //
873
    // Initialize the SSD0303 controller.  Loop through the initialization
874
    // sequence doing a single I2C transfer for each command.
875
    //
876
    for(ulIdx = 0; ulIdx < sizeof(g_pucOSRAMInit);
877
        ulIdx += g_pucOSRAMInit[ulIdx] + 1)
878
    {
879
        //
880
        // Send this command.
881
        //
882
        OSRAMWriteFirst(g_pucOSRAMInit[ulIdx + 1]);
883
        OSRAMWriteArray(g_pucOSRAMInit + ulIdx + 2, g_pucOSRAMInit[ulIdx] - 2);
884
        OSRAMWriteFinal(g_pucOSRAMInit[ulIdx + g_pucOSRAMInit[ulIdx]]);
885
    }
886
 
887
    //
888
    // Now, switch to the actual value of C.
889
    //
890
    g_ulDelay = (340 * (HWREG(I2C_MASTER_BASE + I2C_MASTER_O_TPR) + 1)) / 5;
891
 
892
    //
893
    // Clear the frame buffer.
894
    //
895
    OSRAMClear();
896
}
897
 
898
//*****************************************************************************
899
//
900
//! Turns on the OLED display.
901
//!
902
//! This function will turn on the OLED display, causing it to display the
903
//! contents of its internal frame buffer.
904
//!
905
//! \return None.
906
//
907
//*****************************************************************************
908
void
909
OSRAMDisplayOn(void)
910
{
911
    //
912
    // Turn on the DC-DC converter and the display.
913
    //
914
    OSRAMWriteFirst(0x80);
915
    OSRAMWriteByte(0xad);
916
    OSRAMWriteByte(0x80);
917
    OSRAMWriteByte(0x8b);
918
    OSRAMWriteByte(0x80);
919
    OSRAMWriteFinal(0xaf);
920
}
921
 
922
//*****************************************************************************
923
//
924
//! Turns off the OLED display.
925
//!
926
//! This function will turn off the OLED display.  This will stop the scanning
927
//! of the panel and turn off the on-chip DC-DC converter, preventing damage to
928
//! the panel due to burn-in (it has similar characters to a CRT in this
929
//! respect).
930
//!
931
//! \return None.
932
//
933
//*****************************************************************************
934
void
935
OSRAMDisplayOff(void)
936
{
937
    //
938
    // Turn off the DC-DC converter and the display.
939
    //
940
    OSRAMWriteFirst(0x80);
941
    OSRAMWriteByte(0xad);
942
    OSRAMWriteByte(0x80);
943
    OSRAMWriteByte(0x8a);
944
    OSRAMWriteByte(0x80);
945
    OSRAMWriteFinal(0xae);
946
}
947
 
948
//*****************************************************************************
949
//
950
// Close the Doxygen group.
951
//! @}
952
//
953
//*****************************************************************************

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.