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

Subversion Repositories openarty

[/] [openarty/] [trunk/] [sw/] [board/] [oledtest.c] - Blame information for rev 34

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 34 dgisselq
#include "artyboard.h"
2
#include "zipsys.h"
3
 
4
void    idle_task(void) {
5
        while(1)
6
                zip_idle();
7
}
8
 
9
extern int      splash[], mug[];
10
 
11
#define OLED_PMODEN             0x0010001
12
#define OLED_PMODEN_OFF         0x0010000
13
#define OLED_IOPWR              OLED_PMODEN
14
#define OLED_VCCEN              0x0020002
15
#define OLED_VCC_DISABLE        0x0020000
16
#define OLED_RESET              0x0040000
17
#define OLED_RESET_CLR          0x0040004
18
#define OLED_PWRRESET           (OLED_PMODEN|OLED_RESET) // 5
19
#define OLED_FULLPOWER          (OLED_PMODEN|OLED_VCCEN|OLED_RESET_CLR) // 3->7
20
#define OLED_POWER_DOWN         (OLED_PMODEN_OFF|OLED_VCC_DISABLE)
21
#define OLED_BUSY               1
22
#define OLED_DISPLAYON          0x0af
23
 
24
 
25
#define MICROSECOND             (CLOCKFREQ_HZ/1000000)
26
 
27
#define OLED_DISPLAY_OFF
28
 
29
        const int       init_sequence[] = {
30
                //  Unlock commands
31
                0x01fd12,
32
                //  Display off
33
                0x0ae,
34
                //  Set remap and data format
35
                0x01a072,
36
                //  Set the start line
37
                0x01a100,
38
                //  Set the display offset
39
                0x01a200,
40
                //  Normal display mode
41
                0x0000a4,
42
                //  Set multiplex ratio
43
                0x01a83f,
44
                //  Set master configuration:
45
                //      Use External VCC
46
                0x01ad8e,
47
                //  Disable power save mode
48
                0x01b00b,
49
                //  Set phase length
50
                0x01b131,
51
                //  Set clock divide
52
                0x01b3f0,
53
                //  Set Second Pre-change Speed For ColorA
54
                0x018a64,
55
                //  5l) Set Set Second Pre-charge Speed of Color B
56
                0x018b78,
57
                //  5m) Set Second Pre-charge Speed of Color C
58
                0x018c64,
59
                //  5n) Set Pre-Charge Voltage
60
                0x01bb3a,
61
                //  50) Set VCOMH Deselect Level
62
                0x01be3e,
63
                //  5p) Set Master Current
64
                0x018706,
65
                //  5q) Set Contrast for Color A
66
                0x018191,
67
                //  5r) Set Contrast for Color B
68
                0x018250,
69
                //  5s) Set Contrast for Color C
70
                0x01837D,
71
                //  disable scrolling
72
                0x02e };
73
 
74
void    timer_delay(int counts) {
75
        // Clear the PIC.  We want to exit from here on timer counts alone
76
        zip->pic = CLEARPIC;
77
 
78
        if (counts > 10) {
79
                // Set our timer to count down the given number of counts
80
                zip->tma = counts;
81
                zip->pic = EINT(SYSINT_TMA);
82
                zip_rtu();
83
                zip->pic = CLEARPIC;
84
        } // else anything less has likely already passed
85
}
86
 
87
void oled_clear(void);
88
 
89
void    oled_init(void) {
90
        int     i;
91
 
92
        for(i=0; i<sizeof(init_sequence); i++) {
93
                while(sys->io_oled.o_ctrl & OLED_BUSY)
94
                        ;
95
                sys->io_oled.o_ctrl = init_sequence[i];
96
        }
97
 
98
        // 5u) Clear Screen
99
        oled_clear();
100
 
101
        zip->tma = (CLOCKFREQ_HZ/200);
102
        zip->pic = EINT(SYSINT_TMA);
103
        zip_rtu();
104
        zip->pic = CLEARPIC;
105
 
106
 
107
        // Turn on VCC and wait 100ms
108
        sys->io_oled.o_data = OLED_VCCEN;
109
        // Wait 100 ms
110
        timer_delay(CLOCKFREQ_HZ/10);
111
 
112
        // Send Display On command
113
        sys->io_oled.o_ctrl = 0xaf;
114
}
115
 
116
void    oled_clear(void) {
117
        while(sys->io_oled.o_ctrl & OLED_BUSY)
118
                ;
119
        sys->io_oled.o_a = 0x5f3f0000;
120
        sys->io_oled.o_ctrl = 0x40250000;
121
        while(sys->io_oled.o_ctrl & OLED_BUSY)
122
                ;
123
}
124
 
125
void    oled_fill(int c, int r, int w, int h, int pix) {
126
        int     ctrl; // We'll send this value out the control/command port
127
 
128
        if (c > 95) c = 95;
129
        if (c <  0) c =  0;
130
        if (r > 63) r = 63;
131
        if (r <  0) r =  0;
132
        if (w <  0) w = 0;
133
        if (h <  0) h = 0;
134
        if (c+w > 95) w = 95-c;
135
        if (r+h > 63) h = 63-r;
136
 
137
        // Enable a rectangle to fill
138
        while(sys->io_oled.o_ctrl & OLED_BUSY)
139
                ;
140
        sys->io_oled.o_ctrl = 0x12601;
141
 
142
        // Now, let's build the actual copy command
143
        ctrl = 0xa0220000 | ((c&0x07f)<<8) | (r&0x03f);
144
        sys->io_oled.o_a = (((c+w)&0x07f)<<24) | (((r+h)&0x03f)<<16);
145
        sys->io_oled.o_a|= ((pix >> 11) & 0x01f)<< 9;
146
        sys->io_oled.o_a|= ((pix >>  5) & 0x03f)    ;
147
        sys->io_oled.o_b = ((pix >> 11) & 0x01f)<<17;
148
        sys->io_oled.o_b|= ((pix >>  5) & 0x03f)<< 8;
149
        sys->io_oled.o_b|= ((pix      ) & 0x01f)<< 1;
150
 
151
        // Make certain we had finished with the port (should've ...)
152
        while(sys->io_oled.o_ctrl & OLED_BUSY)
153
                ;
154
 
155
        // and send our new command
156
        sys->io_oled.o_ctrl = ctrl;
157
 
158
        // To be nice to whatever routine follows, we'll wait 'til the port
159
        // is clear again.
160
        while(sys->io_oled.o_ctrl & OLED_BUSY)
161
                ;
162
}
163
 
164
void    entry(void) {
165
        unsigned        user_regs[16];
166
        for(int i=0; i<15; i++)
167
                user_regs[i] = 0;
168
        user_regs[15] = (unsigned int)idle_task;
169
        zip_restore_context(user_regs);
170
 
171
        // Clear the PIC.  We'll come back and use it later.
172
        zip->pic = CLEARPIC;
173
 
174
        if (0) { // Wait till we've had power for at least a quarter second
175
                int pwrcount = sys->io_pwrcount;
176
                do {
177
                        pwrcount = sys->io_pwrcount;
178
                } while((pwrcount>0)&&(pwrcount < CLOCKFREQ_HZ/4));
179
        } else {
180
                int pwrcount = sys->io_pwrcount;
181
                if ((pwrcount > 0)&&(pwrcount < CLOCKFREQ_HZ/4)) {
182
                        pwrcount = CLOCKFREQ_HZ/4 - pwrcount;
183
                        timer_delay(pwrcount);
184
                }
185
        }
186
 
187
 
188
        // If the OLED is already powered, such as might be the case if
189
        // we rebooted but the board was still hot, shut it down
190
        if (sys->io_oled.o_data & 0x07) {
191
                sys->io_oled.o_data = OLED_VCC_DISABLE;
192
                // Wait 100 ms
193
                timer_delay(CLOCKFREQ_HZ/10);
194
                // Shutdown the entire devices power
195
                sys->io_oled.o_data = OLED_POWER_DOWN;
196
                // Wait 100 ms
197
                timer_delay(CLOCKFREQ_HZ/10);
198
 
199
                // Now let's try to restart it
200
        }
201
 
202
        // 1. Power up the OLED by applying power to VCC
203
        //      This means we need to apply power to both the VCCEN line as well
204
        //      as the PMODEN line.  We'll also set the reset line low, so the
205
        //      device starts in a reset condition.
206
        sys->io_oled.o_data = OLED_PMODEN|OLED_RESET_CLR;
207
        timer_delay(4*MICROSECOND);
208
        sys->io_oled.o_data = OLED_RESET;
209
        timer_delay(4*MICROSECOND);
210
 
211
        // 2. Send the Display OFF command
212
        //      This isn't necessary, since we already pulled RESET low.
213
        //
214
        // sys->io_oled.o_ctrl = OLED_DISPLAY_OFF;
215
        //
216
 
217
        // However, we must hold the reset line low for at least 3us, as per
218
        // the spec.  We may also need to wait another 2us after that.  Let's
219
        // hold reset low for 4us here.
220
        timer_delay(4*MICROSECOND);
221
 
222
        // Clear the reset condition.
223
        sys->io_oled.o_data = OLED_RESET_CLR;
224
        // Wait another 4us.
225
        timer_delay(4*MICROSECOND);
226
 
227
        // 3. Initialize the display to the default settings
228
        //      This just took place during the reset cycle we just completed.
229
        //
230
        oled_init();
231
 
232
        // 4. Clear screen
233
        // sys->io_oled.o_ctrl = OLED_CLEAR_SCREEN;
234
 
235
        // Wait for the command to complete
236
        while(sys->io_oled.o_ctrl & OLED_BUSY)
237
                ;
238
 
239
        // 5. Apply power to VCCEN
240
        sys->io_oled.o_data = OLED_FULLPOWER;
241
 
242
        // 6. Delay 100ms
243
        timer_delay(CLOCKFREQ_HZ/10);
244
 
245
        while(1) {
246
        // 7. Send Display On command
247
        // sys->io_oled.o_ctrl = OLED_CLEAR_SCREEN; // ?? What command is this?
248
                sys->io_ledctrl = 0x0ff;
249
 
250
                sys->io_oled.o_ctrl = OLED_DISPLAYON;
251
 
252
                oled_clear();
253
 
254
                while(sys->io_oled.o_ctrl & OLED_BUSY)
255
                        ;
256
                sys->io_oled.o_ctrl = 0x2015005f;
257
 
258
                while(sys->io_oled.o_ctrl & OLED_BUSY)
259
                        ;
260
                sys->io_oled.o_ctrl = 0x2075003f;
261
 
262
                sys->io_ledctrl = 0x0fe;
263
                // Now ... finally ... we can send our image.
264
                for(int i=0; i<6144; i++) {
265
                        while(sys->io_oled.o_ctrl & OLED_BUSY)
266
                                ;
267
                        sys->io_oled.o_data = splash[i];
268
                }
269
                sys->io_ledctrl = 0x0fc;
270
                timer_delay(CLOCKFREQ_HZ*5);
271
                timer_delay(CLOCKFREQ_HZ*5);
272
                timer_delay(CLOCKFREQ_HZ*5);
273
                timer_delay(CLOCKFREQ_HZ*5);
274
                timer_delay(CLOCKFREQ_HZ*5);
275
 
276
 
277
                for(int i=0; i<6144; i++) {
278
                        while(sys->io_oled.o_ctrl & OLED_BUSY)
279
                                ;
280
                        sys->io_oled.o_data = mug[i];
281
                }
282
 
283
                sys->io_ledctrl = 0x0f0;
284
                timer_delay(CLOCKFREQ_HZ*5);
285
        }
286
 
287
        zip_halt();
288
}
289
 

powered by: WebSVN 2.1.0

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