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

Subversion Repositories openrisc

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

powered by: WebSVN 2.1.0

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