Subversion Repositories Code-Repo

Rev

Rev 128 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 128 Rev 129
Line 1... Line 1...
1
#include "maindefs.h"
1
#include "maindefs.h"
2
#include "oled_ssd1306.h"
2
#include "oled_ssd1306.h"
3
#include "spi.h"
3
#include "spi.h"
4
#include "string.h"
4
#include "string.h"
5
#include "Adafruit_GFX.h"
5
#include "glcdfont.c"
6
#include <delays.h>
6
#include <delays.h>
-
 
7
#include <string.h>
-
 
8
#include <stdio.h>
7
 
9
 
-
 
10
static SSD1306_DATA ssd1306_data;
-
 
11
static SSD1306_DATA *ssd1306_data_p = &ssd1306_data;
-
 
12
 
-
 
13
#pragma idata LCD_BUFFER
8
// 512 (128x32) or 1024 (128x64) bytes allocated for LCD buffer
14
// 512 (128x32) or 1024 (128x64) bytes allocated for LCD buffer
9
// See linker file for details
15
// See linker file for details
10
#ifdef GFX_SSD1306
-
 
11
static unsigned char LCD_Buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
16
static unsigned char LCD_Buffer[SSD1306_LCDHEIGHT * SSD1306_LCDWIDTH / 8] = {
12
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
13
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
18
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
14
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
19
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
15
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
20
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
Line 74... Line 79...
74
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
81
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
77
#endif
82
#endif
78
};
83
};
-
 
84
#pragma idata
-
 
85
 
-
 
86
int SSD1306_Abs(int i) {
-
 
87
    if (i < 0)
-
 
88
        return -i;
79
#else
89
    else
-
 
90
        return i;
-
 
91
}
-
 
92
 
80
static unsigned char *LCD_Buffer;
93
void SSD1306_Swap(int *a, int *b) {
-
 
94
    int tmp = *a;
-
 
95
    *a = *b;
-
 
96
    *b = tmp;
81
#endif
97
}
82
 
98
 
83
void SSD1306_Init() {
99
void SSD1306_Init() {
84
    GFX_Init(SSD1306_LCDWIDTH, SSD1306_LCDHEIGHT);
100
    ssd1306_data_p->_width = ssd1306_data_p->WIDTH = SSD1306_LCDWIDTH;
-
 
101
    ssd1306_data_p->_height = ssd1306_data_p->HEIGHT = SSD1306_LCDHEIGHT;
-
 
102
    ssd1306_data_p->rotation = 0;
-
 
103
    ssd1306_data_p->cursor_x = ssd1306_data_p->cursor_y = 0;
-
 
104
    ssd1306_data_p->textsize = 1;
-
 
105
    ssd1306_data_p->textcolor = SSD1306_WHITE;
-
 
106
    ssd1306_data_p->textbgcolor = SSD1306_BLACK;
-
 
107
    ssd1306_data_p->wrap = 1;
85
}
108
}
86
 
109
 
87
void SSD1306_Begin(unsigned char vccstate) {
110
void SSD1306_Begin(unsigned char vccstate) {
88
    // Toggle reset pin
111
    // Toggle reset pin
89
    LATBbits.LATB6 = 0;
112
    SPI_RESET_LAT = 0;
90
    Delay10KTCYx(1);
113
    Delay10KTCYx(1);
91
    LATBbits.LATB6 = 1;
114
    SPI_RESET_LAT = 1;
92
 
115
 
93
#if defined SSD1306_128_32
116
#if defined SSD1306_128_32
94
    // Init sequence for 128x32 OLED module
117
    // Init sequence for 128x32 OLED module
95
    SSD1306_Command(SSD1306_DISPLAYOFF); // 0xAE
118
    SSD1306_Command(SSD1306_DISPLAYOFF); // 0xAE
96
    SSD1306_Command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
119
    SSD1306_Command(SSD1306_SETDISPLAYCLOCKDIV); // 0xD5
Line 169... Line 192...
169
    SSD1306_Command(SSD1306_DISPLAYON); // Turn on OLED panel
192
    SSD1306_Command(SSD1306_DISPLAYON); // Turn on OLED panel
170
}
193
}
171
 
194
 
172
void SSD1306_Command(unsigned char cmd) {
195
void SSD1306_Command(unsigned char cmd) {
173
    unsigned char c = cmd;
196
    unsigned char c = cmd;
174
    LATBbits.LATB5 = 0; // D/C low (cmd)
197
    SPI_DC_SELECT_LAT = 0; // D/C low (cmd)
175
    SPI2_Write(&c, 1);
198
    SPI2_Write(&c, 1);
176
}
199
}
177
 
200
 
178
void SSD1306_Data(unsigned char data) {
201
void SSD1306_Data(unsigned char data) {
179
    unsigned char c = data;
202
    unsigned char c = data;
180
    LATBbits.LATB5 = 1; // D/C high (data)
203
    SPI_DC_SELECT_LAT = 1; // D/C high (data)
181
    SPI2_Write(&c, 1);
204
    SPI2_Write(&c, 1);
182
}
205
}
183
 
206
 
184
void SSD1306_Clear_Display() {
207
void SSD1306_Clear_Display() {
185
    memset(LCD_Buffer, 0, (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8));
208
    memset(LCD_Buffer, 0, (SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8));
Line 199... Line 222...
199
 
222
 
200
    SSD1306_Command(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0
223
    SSD1306_Command(SSD1306_SETLOWCOLUMN | 0x0); // low col = 0
201
    SSD1306_Command(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0
224
    SSD1306_Command(SSD1306_SETHIGHCOLUMN | 0x0); // hi col = 0
202
    SSD1306_Command(SSD1306_SETSTARTLINE | 0x0); // line #0
225
    SSD1306_Command(SSD1306_SETSTARTLINE | 0x0); // line #0
203
 
226
 
204
    LATBbits.LATB5 = 1; // D/C high (data)
227
    SPI_DC_SELECT_LAT = 1; // D/C high (data)
205
    SPI2_Write(LCD_Buffer, SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8);
228
    SPI2_Write(LCD_Buffer, SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8);
206
 
229
 
207
//    if (SSD1306_LCDHEIGHT == 32) {
230
//    if (SSD1306_LCDHEIGHT == 32) {
208
//        SPI2_Write_Repeat(0, SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8);
231
//        SPI2_Write_Repeat(0, SSD1306_LCDWIDTH * SSD1306_LCDHEIGHT / 8);
209
//    }
232
//    }
210
}
233
}
211
 
234
 
212
void SSD1306_Draw_Pixel(int x, int y, unsigned int color) {
235
void SSD1306_Draw_Pixel(int x, int y, unsigned int color) {
213
    if ((x < 0) || (x >= GFX_width()) || (y < 0) || (y >= GFX_height()))
236
    if ((x < 0) || (x >= ssd1306_data_p->_width) || (y < 0) || (y >= ssd1306_data_p->_height))
214
        return;
237
        return;
215
 
238
 
216
    // check rotation, move pixel around if necessary
239
    // check rotation, move pixel around if necessary
217
    switch (GFX_getRotation()) {
240
    switch (ssd1306_data_p->rotation) {
218
        case 1:
241
        case 1:
219
            GFX_Swap(&x, &y);
242
            SSD1306_Swap(&x, &y);
220
            x = SSD1306_LCDWIDTH - x - 1;
243
            x = SSD1306_LCDWIDTH - x - 1;
221
            break;
244
            break;
222
        case 2:
245
        case 2:
223
            x = SSD1306_LCDWIDTH - x - 1;
246
            x = SSD1306_LCDWIDTH - x - 1;
224
            y = SSD1306_LCDHEIGHT - y - 1;
247
            y = SSD1306_LCDHEIGHT - y - 1;
225
            break;
248
            break;
226
        case 3:
249
        case 3:
227
            GFX_Swap(&x, &y);
250
            SSD1306_Swap(&x, &y);
228
            y = SSD1306_LCDHEIGHT - y - 1;
251
            y = SSD1306_LCDHEIGHT - y - 1;
229
            break;
252
            break;
230
    }
253
    }
231
 
254
 
232
    // x is which column
255
    // x is which column
Line 234... Line 257...
234
        LCD_Buffer[x + (y / 8) * SSD1306_LCDWIDTH] |= 1<<(y % 8);
257
        LCD_Buffer[x + (y / 8) * SSD1306_LCDWIDTH] |= 1<<(y % 8);
235
    else
258
    else
236
        LCD_Buffer[x + (y / 8) * SSD1306_LCDWIDTH] &= ~(1<<(y % 8));
259
        LCD_Buffer[x + (y / 8) * SSD1306_LCDWIDTH] &= ~(1<<(y % 8));
237
}
260
}
238
 
261
 
-
 
262
void SSD1306_Draw_Line(int x0, int y0, int x1, int y1, unsigned int color) {
-
 
263
    int dx, dy, err, ystep;
-
 
264
    int steep = SSD1306_Abs(y1 - y0) > SSD1306_Abs(x1 - x0);
-
 
265
    if (steep) {
-
 
266
        SSD1306_Swap(&x0, &y0);
-
 
267
        SSD1306_Swap(&x1, &y1);
-
 
268
    }
-
 
269
 
-
 
270
    if (x0 > x1) {
-
 
271
        SSD1306_Swap(&x0, &x1);
-
 
272
        SSD1306_Swap(&y0, &y1);
-
 
273
    }
-
 
274
 
-
 
275
    dx = x1 - x0;
-
 
276
    dy = SSD1306_Abs(y1 - y0);
-
 
277
 
-
 
278
    err = dx / 2;
-
 
279
 
-
 
280
    if (y0 < y1) {
-
 
281
        ystep = 1;
-
 
282
    } else {
-
 
283
        ystep = -1;
-
 
284
    }
-
 
285
 
-
 
286
    for (; x0 <= x1; x0++) {
-
 
287
 
-
 
288
        if (steep) {
-
 
289
            SSD1306_Draw_Pixel(y0, x0, color);
-
 
290
        } else {
-
 
291
            SSD1306_Draw_Pixel(x0, y0, color);
-
 
292
        }
-
 
293
        err -= dy;
-
 
294
        if (err < 0) {
-
 
295
            y0 += ystep;
-
 
296
            err += dx;
-
 
297
        }
-
 
298
    }
-
 
299
}
-
 
300
 
-
 
301
void SSD1306_Draw_Fast_VLine(int x, int y, int h, unsigned int color) {
-
 
302
    SSD1306_Draw_Line(x, y, x, y + h - 1, color);
-
 
303
}
-
 
304
 
-
 
305
void SSD1306_Draw_Fast_HLine(int x, int y, int w, unsigned int color) {
-
 
306
    SSD1306_Draw_Line(x, y, x + w - 1, y, color);
-
 
307
}
-
 
308
 
-
 
309
void SSD1306_Draw_Rect(int x, int y, int w, int h, unsigned int color) {
-
 
310
    SSD1306_Draw_Fast_HLine(x, y, w, color);
-
 
311
    SSD1306_Draw_Fast_HLine(x, y + h, w, color);
-
 
312
    SSD1306_Draw_Fast_VLine(x, y, h, color);
-
 
313
    SSD1306_Draw_Fast_VLine(x + w, y, h, color);
-
 
314
}
-
 
315
 
-
 
316
void SSD1306_Fill_Rect(int x, int y, int w, int h, unsigned int color) {
-
 
317
    int i;
-
 
318
    for (i = x; i < x + w; i++) {
-
 
319
        SSD1306_Draw_Fast_VLine(i, y, h, color);
-
 
320
    }
-
 
321
}
-
 
322
 
-
 
323
void SSD1306_Draw_Circle(int x0, int y0, int r, unsigned int color) {
-
 
324
    int f = 1 - r;
-
 
325
    int ddF_x = 1;
-
 
326
    int ddF_y = -2 * r;
-
 
327
    int x = 0;
-
 
328
    int y = r;
-
 
329
 
-
 
330
    SSD1306_Draw_Pixel(x0, y0 + r, color);
-
 
331
    SSD1306_Draw_Pixel(x0, y0 - r, color);
-
 
332
    SSD1306_Draw_Pixel(x0 + r, y0, color);
-
 
333
    SSD1306_Draw_Pixel(x0 - r, y0, color);
-
 
334
 
-
 
335
    while (x < y) {
-
 
336
        if (f >= 0) {
-
 
337
            y--;
-
 
338
            ddF_y += 2;
-
 
339
            f += ddF_y;
-
 
340
        }
-
 
341
        x++;
-
 
342
        ddF_x += 2;
-
 
343
        f += ddF_x;
-
 
344
 
-
 
345
        SSD1306_Draw_Pixel(x0 + x, y0 + y, color);
-
 
346
        SSD1306_Draw_Pixel(x0 - x, y0 + y, color);
-
 
347
        SSD1306_Draw_Pixel(x0 + x, y0 - y, color);
-
 
348
        SSD1306_Draw_Pixel(x0 - x, y0 - y, color);
-
 
349
        SSD1306_Draw_Pixel(x0 + y, y0 + x, color);
-
 
350
        SSD1306_Draw_Pixel(x0 - y, y0 + x, color);
-
 
351
        SSD1306_Draw_Pixel(x0 + y, y0 - x, color);
-
 
352
        SSD1306_Draw_Pixel(x0 - y, y0 - x, color);
-
 
353
    }
-
 
354
}
-
 
355
 
-
 
356
void SSD1306_Draw_Circle_Helper(int x0, int y0, int r, unsigned char cornername, unsigned int color) {
-
 
357
    int f = 1 - r;
-
 
358
    int ddF_x = 1;
-
 
359
    int ddF_y = -2 * r;
-
 
360
    int x = 0;
-
 
361
    int y = r;
-
 
362
 
-
 
363
    while (x < y) {
-
 
364
        if (f >= 0) {
-
 
365
            y--;
-
 
366
            ddF_y += 2;
-
 
367
            f += ddF_y;
-
 
368
        }
-
 
369
        x++;
-
 
370
        ddF_x += 2;
-
 
371
        f += ddF_x;
-
 
372
        if (cornername & 0x4) {
-
 
373
            SSD1306_Draw_Pixel(x0 + x, y0 + y, color);
-
 
374
            SSD1306_Draw_Pixel(x0 + y, y0 + x, color);
-
 
375
        }
-
 
376
        if (cornername & 0x2) {
-
 
377
            SSD1306_Draw_Pixel(x0 + x, y0 - y, color);
-
 
378
            SSD1306_Draw_Pixel(x0 + y, y0 - x, color);
-
 
379
        }
-
 
380
        if (cornername & 0x8) {
-
 
381
            SSD1306_Draw_Pixel(x0 - y, y0 + x, color);
-
 
382
            SSD1306_Draw_Pixel(x0 - x, y0 + y, color);
-
 
383
        }
-
 
384
        if (cornername & 0x1) {
-
 
385
            SSD1306_Draw_Pixel(x0 - y, y0 - x, color);
-
 
386
            SSD1306_Draw_Pixel(x0 - x, y0 - y, color);
-
 
387
        }
-
 
388
    }
-
 
389
}
-
 
390
 
-
 
391
void SSD1306_Fill_Circle(int x0, int y0, int r, unsigned int color) {
-
 
392
    SSD1306_Draw_Fast_VLine(x0, y0 - r, 2 * r + 1, color);
-
 
393
    SSD1306_Fill_Circle_Helper(x0, y0, r, 3, 0, color);
-
 
394
}
-
 
395
 
-
 
396
void SSD1306_Fill_Circle_Helper(int x0, int y0, int r, unsigned char cornername, int delta, unsigned int color) {
-
 
397
    int f = 1 - r;
-
 
398
    int ddF_x = 1;
-
 
399
    int ddF_y = -2 * r;
-
 
400
    int x = 0;
-
 
401
    int y = r;
-
 
402
 
-
 
403
    while (x < y) {
-
 
404
        if (f >= 0) {
-
 
405
            y--;
-
 
406
            ddF_y += 2;
-
 
407
            f += ddF_y;
-
 
408
        }
-
 
409
        x++;
-
 
410
        ddF_x += 2;
-
 
411
        f += ddF_x;
-
 
412
 
-
 
413
        if (cornername & 0x1) {
-
 
414
            SSD1306_Draw_Fast_VLine(x0 + x, y0 - y, 2 * y + 1 + delta, color);
-
 
415
            SSD1306_Draw_Fast_VLine(x0 + y, y0 - x, 2 * x + 1 + delta, color);
-
 
416
        }
-
 
417
        if (cornername & 0x2) {
-
 
418
            SSD1306_Draw_Fast_VLine(x0 - x, y0 - y, 2 * y + 1 + delta, color);
-
 
419
            SSD1306_Draw_Fast_VLine(x0 - y, y0 - x, 2 * x + 1 + delta, color);
-
 
420
        }
-
 
421
    }
-
 
422
}
-
 
423
 
-
 
424
void SSD1306_Draw_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {
-
 
425
    SSD1306_Draw_Line(x0, y0, x1, y1, color);
-
 
426
    SSD1306_Draw_Line(x1, y1, x2, y2, color);
-
 
427
    SSD1306_Draw_Line(x2, y2, x0, y0, color);
-
 
428
}
-
 
429
 
-
 
430
void SSD1306_Fill_Triangle(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {
-
 
431
    int a, b, y, last;
-
 
432
    int dx01 = x1 - x0;
-
 
433
    int dy01 = y1 - y0;
-
 
434
    int dx02 = x2 - x0;
-
 
435
    int dy02 = y2 - y0;
-
 
436
    int dx12 = x2 - x1;
-
 
437
    int dy12 = y2 - y1;
-
 
438
    int sa = 0;
-
 
439
    int sb = 0;
-
 
440
 
-
 
441
    // Sort coordinates by Y order (y2 >= y1 >= y0)
-
 
442
    if (y0 > y1) {
-
 
443
        SSD1306_Swap(&y0, &y1);
-
 
444
        SSD1306_Swap(&x0, &x1);
-
 
445
    }
-
 
446
    if (y1 > y2) {
-
 
447
        SSD1306_Swap(&y2, &y1);
-
 
448
        SSD1306_Swap(&x2, &x1);
-
 
449
    }
-
 
450
    if (y0 > y1) {
-
 
451
        SSD1306_Swap(&y0, &y1);
-
 
452
        SSD1306_Swap(&x0, &x1);
-
 
453
    }
-
 
454
 
-
 
455
    if (y0 == y2) { // Handle awkward all-on-same-line case as its own thing
-
 
456
        a = b = x0;
-
 
457
        if (x1 < a) a = x1;
-
 
458
        else if (x1 > b) b = x1;
-
 
459
        if (x2 < a) a = x2;
-
 
460
        else if (x2 > b) b = x2;
-
 
461
        SSD1306_Draw_Fast_HLine(a, y0, b - a + 1, color);
-
 
462
        return;
-
 
463
    }
-
 
464
 
-
 
465
    // For upper part of triangle, find scanline crossings for segments
-
 
466
    // 0-1 and 0-2.  If y1=y2 (flat-bottomed triangle), the scanline y1
-
 
467
    // is included here (and second loop will be skipped, avoiding a /0
-
 
468
    // error there), otherwise scanline y1 is skipped here and handled
-
 
469
    // in the second loop...which also avoids a /0 error here if y0=y1
-
 
470
    // (flat-topped triangle).
-
 
471
    if (y1 == y2) last = y1; // Include y1 scanline
-
 
472
    else last = y1 - 1; // Skip it
-
 
473
 
-
 
474
    for (y = y0; y <= last; y++) {
-
 
475
        a = x0 + sa / dy01;
-
 
476
        b = x0 + sb / dy02;
-
 
477
        sa += dx01;
-
 
478
        sb += dx02;
-
 
479
        /* longhand:
-
 
480
        a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
-
 
481
        b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
-
 
482
         */
-
 
483
        if (a > b) SSD1306_Swap(&a, &b);
-
 
484
        SSD1306_Draw_Fast_HLine(a, y, b - a + 1, color);
-
 
485
    }
-
 
486
 
-
 
487
    // For lower part of triangle, find scanline crossings for segments
-
 
488
    // 0-2 and 1-2.  This loop is skipped if y1=y2.
-
 
489
    sa = dx12 * (y - y1);
-
 
490
    sb = dx02 * (y - y0);
-
 
491
    for (; y <= y2; y++) {
-
 
492
        a = x1 + sa / dy12;
-
 
493
        b = x0 + sb / dy02;
-
 
494
        sa += dx12;
-
 
495
        sb += dx02;
-
 
496
        /* longhand:
-
 
497
        a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
-
 
498
        b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
-
 
499
         */
-
 
500
        if (a > b) SSD1306_Swap(&a, &b);
-
 
501
        SSD1306_Draw_Fast_HLine(a, y, b - a + 1, color);
-
 
502
    }
-
 
503
}
-
 
504
 
-
 
505
void SSD1306_Draw_Round_Rect(int x, int y, int w, int h, int r, unsigned int color) {
-
 
506
    // smarter version
-
 
507
    SSD1306_Draw_Fast_HLine(x + r, y, w - 2 * r, color); // Top
-
 
508
    SSD1306_Draw_Fast_HLine(x + r, y + h - 1, w - 2 * r, color); // Bottom
-
 
509
    SSD1306_Draw_Fast_VLine(x, y + r, h - 2 * r, color); // Left
-
 
510
    SSD1306_Draw_Fast_VLine(x + w - 1, y + r, h - 2 * r, color); // Right
-
 
511
 
-
 
512
    // draw four corners
-
 
513
    SSD1306_Draw_Circle_Helper(x + r, y + r, r, 1, color);
-
 
514
    SSD1306_Draw_Circle_Helper(x + w - r - 1, y + r, r, 2, color);
-
 
515
    SSD1306_Draw_Circle_Helper(x + w - r - 1, y + h - r - 1, r, 4, color);
-
 
516
    SSD1306_Draw_Circle_Helper(x + r, y + h - r - 1, r, 8, color);
-
 
517
}
-
 
518
 
-
 
519
void SSD1306_Fill_Round_Rect(int x, int y, int w, int h, int r, unsigned int color) {
-
 
520
    // smarter version
-
 
521
    SSD1306_Fill_Rect(x + r, y, w - 2 * r, h, color);
-
 
522
 
-
 
523
    // draw four corners
-
 
524
    SSD1306_Fill_Circle_Helper(x + w - r - 1, y + r, r, 1, h - 2 * r - 1, color);
-
 
525
    SSD1306_Fill_Circle_Helper(x + r, y + r, r, 2, h - 2 * r - 1, color);
-
 
526
}
-
 
527
 
-
 
528
void SSD1306_Draw_Bitmap(int x, int y, const unsigned char* bitmap, int w, int h, unsigned int color) {
-
 
529
    int i, j;
-
 
530
    for (j = 0; j < h; j++) {
-
 
531
        for (i = 0; i < w; i++) {
-
 
532
            if (bitmap[i + (j / 8) * w] & (j % 8)) {
-
 
533
                SSD1306_Draw_Pixel(x + i, y + j, color);
-
 
534
            }
-
 
535
        }
-
 
536
    }
-
 
537
}
-
 
538
 
-
 
539
void SSD1306_Draw_Char(int x, int y, unsigned char c, unsigned int color, unsigned int bg, unsigned char size) {
-
 
540
    int i, j;
-
 
541
    unsigned int line;
-
 
542
 
-
 
543
    if ((x >= ssd1306_data_p->_width) || // Clip right
-
 
544
            (y >= ssd1306_data_p->_height) || // Clip bottom
-
 
545
            ((x + 5 * size - 1) < 0) || // Clip left
-
 
546
            ((y + 8 * size - 1) < 0)) // Clip top
-
 
547
        return;
-
 
548
 
-
 
549
    for (i = 0; i < 6; i++) {
-
 
550
        if (i == 5)
-
 
551
            line = 0x0;
-
 
552
        else
-
 
553
            line = font[(c * 5) + i];
-
 
554
        for (j = 0; j < 8; j++) {
-
 
555
            if (line & 0x1) {
-
 
556
                if (size == 1) {// default size
-
 
557
                    SSD1306_Draw_Pixel(x + i, y + j, color);
-
 
558
                } else { // big size
-
 
559
                    SSD1306_Fill_Rect(x + (i * size), y + (j * size), size, size, color);
-
 
560
                }
-
 
561
            } else if (bg != color) {
-
 
562
                if (size == 1) { // default size
-
 
563
                    SSD1306_Draw_Pixel(x + i, y + j, bg);
-
 
564
                } else { // big size
-
 
565
                    SSD1306_Fill_Rect(x + i*size, y + j*size, size, size, bg);
-
 
566
                }
-
 
567
            }
-
 
568
            line >>= 1;
-
 
569
        }
-
 
570
    }
-
 
571
}
-
 
572
 
-
 
573
void SSD1306_Write(unsigned char c) {
-
 
574
    if (c == '\n' || c == '\r') {
-
 
575
        ssd1306_data_p->cursor_y += ssd1306_data_p->textsize * 8;
-
 
576
        ssd1306_data_p->cursor_x = 0;
-
 
577
        //    } else if (c == '\r') {
-
 
578
        //        // skip em
-
 
579
    } else {
-
 
580
        SSD1306_Draw_Char(ssd1306_data_p->cursor_x, ssd1306_data_p->cursor_y, c, ssd1306_data_p->textcolor, ssd1306_data_p->textbgcolor, ssd1306_data_p->textsize);
-
 
581
        ssd1306_data_p->cursor_x += ssd1306_data_p->textsize * 6;
-
 
582
        if (ssd1306_data_p->wrap && (ssd1306_data_p->cursor_x > (ssd1306_data_p->_width - ssd1306_data_p->textsize * 6))) {
-
 
583
            ssd1306_data_p->cursor_y += ssd1306_data_p->textsize * 8;
-
 
584
            ssd1306_data_p->cursor_x = 0;
-
 
585
        }
-
 
586
    }
-
 
587
}
-
 
588
 
-
 
589
void SSD1306_Write_String(const rom char *fmt, ...) {
-
 
590
    unsigned char i, len;
-
 
591
    unsigned char buffer[SSD1306_STRING_BUFFER_SIZE];
-
 
592
    
-
 
593
    // Parse and create string
-
 
594
    va_list args;
-
 
595
    va_start(args, fmt);
-
 
596
    vsprintf((char *) buffer, fmt, args);
-
 
597
    va_end(args);
-
 
598
    len = strlen((char *) buffer);
-
 
599
 
-
 
600
    // Make sure string to insert fits in buffer, truncate if necessary
-
 
601
    if (len > SSD1306_STRING_BUFFER_SIZE)
-
 
602
        len = SSD1306_STRING_BUFFER_SIZE;
-
 
603
 
-
 
604
    // Print buffer to string
-
 
605
    for (i = 0; i < len; i++) {
-
 
606
        SSD1306_Write(buffer[i]);
-
 
607
    }
-
 
608
}
-
 
609
 
-
 
610
//void SSD1306_Append_String(const rom char *fmt, ...) {
-
 
611
//    unsigned char i, len;
-
 
612
//    unsigned char buffer[SSD1306_STRING_BUFFER_SIZE];
-
 
613
//
-
 
614
//    // Parse and create string
-
 
615
//    va_list args;
-
 
616
//    va_start(args, fmt);
-
 
617
//    vsprintf((char *) buffer, fmt, args);
-
 
618
//    va_end(args);
-
 
619
//
-
 
620
//    // Make sure string to insert fits in buffer, truncate if necessary
-
 
621
//    len = strlen((char *) buffer);
-
 
622
//
-
 
623
//    if (len == 1) {  // This will only occur on "\n"
-
 
624
//        // Do nothing?
-
 
625
//        return;
-
 
626
//    }
-
 
627
//
-
 
628
//    if (len > SSD1306_STRING_BUFFER_SIZE)
-
 
629
//        len = SSD1306_STRING_BUFFER_SIZE;
-
 
630
//
-
 
631
//    // Omit the newline if string fill entire line
-
 
632
//    if (((len - 1)%(ssd1306_data_p->_width / 6)) == 0) { // 16 or 10
-
 
633
//        len -= 1;
-
 
634
//    }
-
 
635
//
-
 
636
//    // Shift everything right and insert string at beginning
-
 
637
//    for (i = 127; i > len - 1; i--) {
-
 
638
//        ssd1306_data_p->lcd_buffer[i] = ssd1306_data_p->lcd_buffer[i - len];
-
 
639
//    }
-
 
640
//    memcpy((char *)ssd1306_data_p->lcd_buffer, (const char *) buffer, len);
-
 
641
//
-
 
642
//    // Print full buffer to screen
-
 
643
//    SSD1306_Clear_Display();
-
 
644
//    SSD1306_Display();
-
 
645
//
-
 
646
//    SSD1306_Set_Cursor(0,0);
-
 
647
//    for (i = 0; i < SSD1306_LCD_BUFFER_SIZE-1; i++) {
-
 
648
//        SSD1306_Write(ssd1306_data_p->lcd_buffer[i]);
-
 
649
//    }
-
 
650
//}
-
 
651
 
-
 
652
void SSD1306_Set_Cursor(int x, int y) {
-
 
653
    ssd1306_data_p->cursor_x = x;
-
 
654
    ssd1306_data_p->cursor_y = y;
-
 
655
}
-
 
656
 
-
 
657
void SSD1306_Set_Text_Color(unsigned int c) {
-
 
658
    // for 'transparent' background, we'll set the bg
-
 
659
    // to the same as fg instead of using a flag
-
 
660
    ssd1306_data_p->textcolor = c;
-
 
661
    ssd1306_data_p->textbgcolor = c;
-
 
662
}
-
 
663
 
-
 
664
void SSD1306_Set_Text_Color_BG(unsigned int c, unsigned int bg) {
-
 
665
    ssd1306_data_p->textcolor = c;
-
 
666
    ssd1306_data_p->textbgcolor = bg;
-
 
667
}
-
 
668
 
-
 
669
void SSD1306_Set_Text_Size(unsigned char s) {
-
 
670
    ssd1306_data_p->textsize = (s > 0) ? s : 1;
-
 
671
}
-
 
672
 
-
 
673
void SSD1306_Set_Text_Wrap(unsigned char w) {
-
 
674
    ssd1306_data_p->wrap = w;
-
 
675
}
-
 
676
 
-
 
677
void SSD1306_Set_Rotation(unsigned char x) {
-
 
678
    x %= 4; // cant be higher than 3
-
 
679
    ssd1306_data_p->rotation = x;
-
 
680
    switch (x) {
-
 
681
        case 0:
-
 
682
        case 2:
-
 
683
            ssd1306_data_p->_width = ssd1306_data_p->WIDTH;
-
 
684
            ssd1306_data_p->_height = ssd1306_data_p->HEIGHT;
-
 
685
            break;
-
 
686
        case 1:
-
 
687
        case 3:
-
 
688
            ssd1306_data_p->_width = ssd1306_data_p->HEIGHT;
-
 
689
            ssd1306_data_p->_height = ssd1306_data_p->WIDTH;
-
 
690
            break;
-
 
691
    }
-
 
692
}
-
 
693
 
-
 
694
 
-
 
695
 
239
void SSD1306_Test_DrawChar() {
696
void SSD1306_Test_DrawChar() {
240
    unsigned char i;
697
    unsigned char i;
241
    GFX_setTextSize(1);
698
    SSD1306_Set_Text_Size(1);
242
    GFX_setTextColor(SSD1306_WHITE);
699
    SSD1306_Set_Text_Color(SSD1306_WHITE);
243
    GFX_setCursor(0, 0);
700
    SSD1306_Set_Cursor(0, 0);
244
 
701
 
245
    for (i = 0; i < 168; i++) {
702
    for (i = 0; i < 168; i++) {
246
        if (i == '\n') continue;
703
        if (i == '\n') continue;
247
        GFX_write(i);
704
        SSD1306_Write(i);
248
//        if ((i > 0) && (i % 21 == 0))
705
//        if ((i > 0) && (i % 21 == 0))
249
//            GFX_write('\n');
706
//            SSD1306_write('\n');
250
    }
707
    }
251
    SSD1306_Display();
708
    SSD1306_Display();
252
}
709
}
253
 
710
 
254
void SSD1306_Test_DrawCircle() {
711
void SSD1306_Test_DrawCircle() {
255
    int i;
712
    int i;
256
    for (i = 0; i < GFX_height(); i += 2) {
713
    for (i = 0; i < ssd1306_data_p->_height; i += 2) {
257
        GFX_drawCircle(GFX_width() / 2, GFX_height() / 2, i, SSD1306_WHITE);
714
        SSD1306_Draw_Circle(ssd1306_data_p->_width / 2, ssd1306_data_p->_height / 2, i, SSD1306_WHITE);
258
        SSD1306_Display();
715
        SSD1306_Display();
259
    }
716
    }
260
}
717
}
261
 
718
 
262
void SSD1306_Test_DrawRect(void) {
719
void SSD1306_Test_DrawRect(void) {
263
    int i;
720
    int i;
264
    for (i = 0; i < GFX_height() / 2; i += 2) {
721
    for (i = 0; i < ssd1306_data_p->_height / 2; i += 2) {
265
        GFX_drawRect(i, i, GFX_width() - 2 * i, GFX_height() - 2 * i, SSD1306_WHITE);
722
        SSD1306_Draw_Rect(i, i, ssd1306_data_p->_width - 2 * i, ssd1306_data_p->_height - 2 * i, SSD1306_WHITE);
266
        SSD1306_Display();
723
        SSD1306_Display();
267
    }
724
    }
268
}
725
}
269
 
726
 
270
void SSD1306_Test_FillRect(void) {
727
void SSD1306_Test_FillRect(void) {
271
    unsigned char color = 1;
728
    unsigned char color = 1;
272
    int i;
729
    int i;
273
    for (i = 0; i < GFX_height() / 2; i += 3) {
730
    for (i = 0; i < ssd1306_data_p->_height / 2; i += 3) {
274
        // alternate colors
731
        // alternate colors
275
        GFX_fillRect(i, i, GFX_width() - i * 2, GFX_height() - i * 2, color % 2);
732
        SSD1306_Fill_Rect(i, i, ssd1306_data_p->_width - i * 2, ssd1306_data_p->_height - i * 2, color % 2);
276
        SSD1306_Display();
733
        SSD1306_Display();
277
        color++;
734
        color++;
278
    }
735
    }
279
}
736
}
280
 
737
 
281
void SSD1306_Test_DrawTriangle(void) {
738
void SSD1306_Test_DrawTriangle(void) {
282
    int i;
739
    int i;
283
    int min = GFX_width() < GFX_height() ? GFX_width() : GFX_height();
740
    int min = ssd1306_data_p->_width < ssd1306_data_p->_height ? ssd1306_data_p->_width : ssd1306_data_p->_height;
284
    for (i = 0; i < min / 2; i += 5) {
741
    for (i = 0; i < min / 2; i += 5) {
285
        GFX_drawTriangle(GFX_width() / 2, GFX_height() / 2 - i,
742
        SSD1306_Draw_Triangle(ssd1306_data_p->_width / 2, ssd1306_data_p->_height / 2 - i,
286
                GFX_width() / 2 - i, GFX_height() / 2 + i,
743
                ssd1306_data_p->_width / 2 - i, ssd1306_data_p->_height / 2 + i,
287
                GFX_width() / 2 + i, GFX_height() / 2 + i, SSD1306_WHITE);
744
                ssd1306_data_p->_width / 2 + i, ssd1306_data_p->_height / 2 + i, SSD1306_WHITE);
288
        SSD1306_Display();
745
        SSD1306_Display();
289
    }
746
    }
290
}
747
}
291
 
748
 
292
void SSD1306_Test_FillTriangle(void) {
749
void SSD1306_Test_FillTriangle(void) {
293
    unsigned char color = SSD1306_WHITE;
750
    unsigned char color = SSD1306_WHITE;
294
    int i;
751
    int i;
295
    int min = GFX_width() < GFX_height() ? GFX_width() : GFX_height();
752
    int min = ssd1306_data_p->_width < ssd1306_data_p->_height ? ssd1306_data_p->_width : ssd1306_data_p->_height;
296
    for (i = min / 2; i > 0; i -= 5) {
753
    for (i = min / 2; i > 0; i -= 5) {
297
        GFX_fillTriangle(GFX_width() / 2, GFX_height() / 2 - i,
754
        SSD1306_Fill_Triangle(ssd1306_data_p->_width / 2, ssd1306_data_p->_height / 2 - i,
298
                GFX_width() / 2 - i, GFX_height() / 2 + i,
755
                ssd1306_data_p->_width / 2 - i, ssd1306_data_p->_height / 2 + i,
299
                GFX_width() / 2 + i, GFX_height() / 2 + i, SSD1306_WHITE);
756
                ssd1306_data_p->_width / 2 + i, ssd1306_data_p->_height / 2 + i, SSD1306_WHITE);
300
        if (color == SSD1306_WHITE) color = SSD1306_BLACK;
757
        if (color == SSD1306_WHITE) color = SSD1306_BLACK;
301
        else color = SSD1306_WHITE;
758
        else color = SSD1306_WHITE;
302
        SSD1306_Display();
759
        SSD1306_Display();
303
    }
760
    }
304
}
761
}
305
 
762
 
306
void SSD1306_Test_DrawRoundRect(void) {
763
void SSD1306_Test_DrawRoundRect(void) {
307
    int i;
764
    int i;
308
    for (i = 0; i < GFX_height() / 2 - 2; i += 2) {
765
    for (i = 0; i < ssd1306_data_p->_height / 2 - 2; i += 2) {
309
        GFX_drawRoundRect(i, i, GFX_width() - 2 * i, GFX_height() - 2 * i, GFX_height() / 4, SSD1306_WHITE);
766
        SSD1306_Draw_Round_Rect(i, i, ssd1306_data_p->_width - 2 * i, ssd1306_data_p->_height - 2 * i, ssd1306_data_p->_height / 4, SSD1306_WHITE);
310
        SSD1306_Display();
767
        SSD1306_Display();
311
    }
768
    }
312
}
769
}
313
 
770
 
314
void SSD1306_Test_FillRoundRect(void) {
771
void SSD1306_Test_FillRoundRect(void) {
315
    unsigned char color = SSD1306_WHITE;
772
    unsigned char color = SSD1306_WHITE;
316
    int i;
773
    int i;
317
    for (i = 0; i < GFX_height() / 2 - 2; i += 2) {
774
    for (i = 0; i < ssd1306_data_p->_height / 2 - 2; i += 2) {
318
        GFX_fillRoundRect(i, i, GFX_width() - 2 * i, GFX_height() - 2 * i, GFX_height() / 4, color);
775
        SSD1306_Fill_Round_Rect(i, i, ssd1306_data_p->_width - 2 * i, ssd1306_data_p->_height - 2 * i, ssd1306_data_p->_height / 4, color);
319
        if (color == SSD1306_WHITE) color = SSD1306_BLACK;
776
        if (color == SSD1306_WHITE) color = SSD1306_BLACK;
320
        else color = SSD1306_WHITE;
777
        else color = SSD1306_WHITE;
321
        SSD1306_Display();
778
        SSD1306_Display();
322
    }
779
    }
323
}
780
}
324
 
781
 
325
void SSD1306_Test_DrawLine(void) {
782
void SSD1306_Test_DrawLine(void) {
326
    int i;
783
    int i;
327
    for (i = 0; i < GFX_width(); i += 4) {
784
    for (i = 0; i < ssd1306_data_p->_width; i += 4) {
328
        GFX_drawLine(0, 0, i, GFX_height() - 1, SSD1306_WHITE);
785
        SSD1306_Draw_Line(0, 0, i, ssd1306_data_p->_height - 1, SSD1306_WHITE);
329
        SSD1306_Display();
786
        SSD1306_Display();
330
    }
787
    }
331
    for (i = 0; i < GFX_height(); i += 4) {
788
    for (i = 0; i < ssd1306_data_p->_height; i += 4) {
332
        GFX_drawLine(0, 0, GFX_width() - 1, i, SSD1306_WHITE);
789
        SSD1306_Draw_Line(0, 0, ssd1306_data_p->_width - 1, i, SSD1306_WHITE);
333
        SSD1306_Display();
790
        SSD1306_Display();
334
    }
791
    }
335
    Delay10KTCYx(255);
792
    Delay10KTCYx(255);
336
 
793
 
337
    SSD1306_Clear_Display();
794
    SSD1306_Clear_Display();
338
    for (i = 0; i < GFX_width(); i += 4) {
795
    for (i = 0; i < ssd1306_data_p->_width; i += 4) {
339
        GFX_drawLine(0, GFX_height() - 1, i, 0, SSD1306_WHITE);
796
        SSD1306_Draw_Line(0, ssd1306_data_p->_height - 1, i, 0, SSD1306_WHITE);
340
        SSD1306_Display();
797
        SSD1306_Display();
341
    }
798
    }
342
    for (i = GFX_height() - 1; i >= 0; i -= 4) {
799
    for (i = ssd1306_data_p->_height - 1; i >= 0; i -= 4) {
343
        GFX_drawLine(0, GFX_height() - 1, GFX_width() - 1, i, SSD1306_WHITE);
800
        SSD1306_Draw_Line(0, ssd1306_data_p->_height - 1, ssd1306_data_p->_width - 1, i, SSD1306_WHITE);
344
        SSD1306_Display();
801
        SSD1306_Display();
345
    }
802
    }
346
    Delay10KTCYx(255);
803
    Delay10KTCYx(255);
347
 
804
 
348
    SSD1306_Clear_Display();
805
    SSD1306_Clear_Display();
349
    for (i = GFX_width() - 1; i >= 0; i -= 4) {
806
    for (i = ssd1306_data_p->_width - 1; i >= 0; i -= 4) {
350
        GFX_drawLine(GFX_width() - 1, GFX_height() - 1, i, 0, SSD1306_WHITE);
807
        SSD1306_Draw_Line(ssd1306_data_p->_width - 1, ssd1306_data_p->_height - 1, i, 0, SSD1306_WHITE);
351
        SSD1306_Display();
808
        SSD1306_Display();
352
    }
809
    }
353
    for (i = GFX_height() - 1; i >= 0; i -= 4) {
810
    for (i = ssd1306_data_p->_height - 1; i >= 0; i -= 4) {
354
        GFX_drawLine(GFX_width() - 1, GFX_height() - 1, 0, i, SSD1306_WHITE);
811
        SSD1306_Draw_Line(ssd1306_data_p->_width - 1, ssd1306_data_p->_height - 1, 0, i, SSD1306_WHITE);
355
        SSD1306_Display();
812
        SSD1306_Display();
356
    }
813
    }
357
    Delay10KTCYx(255);
814
    Delay10KTCYx(255);
358
 
815
 
359
    SSD1306_Clear_Display();
816
    SSD1306_Clear_Display();
360
    for (i = 0; i < GFX_height(); i += 4) {
817
    for (i = 0; i < ssd1306_data_p->_height; i += 4) {
361
        GFX_drawLine(GFX_width() - 1, 0, 0, i, SSD1306_WHITE);
818
        SSD1306_Draw_Line(ssd1306_data_p->_width - 1, 0, 0, i, SSD1306_WHITE);
362
        SSD1306_Display();
819
        SSD1306_Display();
363
    }
820
    }
364
    for (i = 0; i < GFX_width(); i += 4) {
821
    for (i = 0; i < ssd1306_data_p->_width; i += 4) {
365
        GFX_drawLine(GFX_width() - 1, 0, i, GFX_height() - 1, SSD1306_WHITE);
822
        SSD1306_Draw_Line(ssd1306_data_p->_width - 1, 0, i, ssd1306_data_p->_height - 1, SSD1306_WHITE);
366
        SSD1306_Display();
823
        SSD1306_Display();
367
    }
824
    }
368
    Delay10KTCYx(255);
825
    Delay10KTCYx(255);
369
}
826
}