Merge branch 'master' of mjesec.ffzg.hr:/git/Arduino
[Arduino] / c2_ulx3s_test / oled.cpp
1 #include <Arduino.h>
2 #include "spi.h"
3
4 enum 
5 {
6   C_OLED_NOP1 = 0xBC,
7   C_OLED_NOP2 = 0xBD, // delay nop
8   C_OLED_NOP3 = 0xE3,
9   C_OLED_SET_DISPLAY_OFF = 0xAE, // 10101110
10   C_OLED_SET_REMAP_COLOR = 0xA0,
11   C_OLED_ULX3S_REMAP = 0b00100010, // A[7:6] = 00; 256 color. A[7:6] = 01; 65k color format rotation for ULX3S, A[1] = 1 scan right to left
12   C_OLED_SET_DISPLAY_START_LINE = 0xA1,
13   C_OLED_SET_DISPLAY_OFFSET = 0xA1,
14   C_OLED_SET_DISPLAY_MODE_NORMAL = 0xA4,
15   C_OLED_SET_MULTIPLEX_RATIO = 0xA8,
16   C_OLED_SET_MASTER_CONFIGURATION = 0xAD,
17   C_OLED_SET_POWER_SAVE_MODE = 0xB0,
18   C_OLED_SET_PHASE_1_AND_2_PERIOD_ADJUSTMENT = 0xB1,
19   C_OLED_SET_DISPLAY_CLOCK_DIVIDER = 0xF0,
20   C_OLED_SET_PRECHARGE_A = 0x8A,
21   C_OLED_SET_PRECHARGE_B = 0x8B,
22   C_OLED_SET_PRECHARGE_C = 0x8C,
23   C_OLED_SET_PRECHARGE_LEVEL = 0xBB,
24   C_OLED_SET_VCOMH = 0xBE,
25   C_OLED_SET_MASTER_CURRENT_CONTROL = 0x87,
26   C_OLED_SET_CONTRAST_COLOR_A = 0x81,
27   C_OLED_SET_CONTRAST_COLOR_B = 0x82,
28   C_OLED_SET_CONTRAST_COLOR_C = 0x83,
29   C_OLED_SET_COLUMN_ADDRESS = 0x15,
30   C_OLED_SET_ROW_ADDRESS = 0x75,
31   C_OLED_SET_DISPLAY_ON = 0xAF,
32 };
33
34 uint8_t oled_init_sequence[] =
35 {
36     C_OLED_NOP1, // 0, 10111100
37     C_OLED_SET_DISPLAY_OFF, // 1, 10101110
38     C_OLED_SET_REMAP_COLOR, C_OLED_ULX3S_REMAP, // 2
39     C_OLED_SET_DISPLAY_START_LINE, 0x00, // 4
40     C_OLED_SET_DISPLAY_OFFSET, 0x00, // 6
41     C_OLED_SET_DISPLAY_MODE_NORMAL, // 8
42     C_OLED_SET_MULTIPLEX_RATIO, 0b00111111, // 9, 15-16
43     C_OLED_SET_MASTER_CONFIGURATION, 0b10001110, // 11, a[0]=0 Select external Vcc supply, a[0]=1 Reserved(reset)
44     C_OLED_SET_POWER_SAVE_MODE, 0x00, // 13, 0-no power save, 0x1A-power save
45     C_OLED_SET_PHASE_1_AND_2_PERIOD_ADJUSTMENT, 0x74, // 15
46     C_OLED_SET_DISPLAY_CLOCK_DIVIDER, 0xF0, // 17
47     C_OLED_SET_PRECHARGE_A, 0x64, // 19
48     C_OLED_SET_PRECHARGE_B, 0x78, // 21
49     C_OLED_SET_PRECHARGE_C, 0x64, // 23
50     C_OLED_SET_PRECHARGE_LEVEL, 0x31, // 25
51     C_OLED_SET_CONTRAST_COLOR_A, 0xFF, // 27, 255
52     C_OLED_SET_CONTRAST_COLOR_B, 0xFF, // 29, 255
53     C_OLED_SET_CONTRAST_COLOR_C, 0xFF, // 31, 255
54     C_OLED_SET_VCOMH, 0x3E,
55     C_OLED_SET_MASTER_CURRENT_CONTROL, 0x06,
56     C_OLED_SET_COLUMN_ADDRESS, 0x00, 0x5F, // 33, 96
57     C_OLED_SET_ROW_ADDRESS, 0x00, 0x3F, // 36, 63
58     C_OLED_SET_DISPLAY_ON, // 39
59     C_OLED_NOP1, // 40 -- during debugging sent as data
60 };
61
62 volatile uint16_t *oled_spi   = (uint16_t *)0xFFFFFB60;
63 volatile uint32_t *simple_out = (uint32_t *)0xFFFFFF10;
64
65 uint8_t oled_y = 0; // increments y-line to be drawn
66
67 void dc(uint8_t state)
68 {
69   if(state)
70     *simple_out |= (1<<11);
71   else
72     *simple_out &= ~(1<<11);
73 }
74
75
76 void resn(uint8_t state)
77 {
78   if(state)
79     *simple_out |= (1<<10);
80   else
81     *simple_out &= ~(1<<10);
82 }
83
84
85 void oled_fill_screen(uint8_t color)
86 {
87   dc(0); // command
88   spi_rxtx(oled_spi, C_OLED_SET_COLUMN_ADDRESS);
89   spi_rxtx(oled_spi, 0);
90   spi_rxtx(oled_spi, 0x5F);
91   spi_rxtx(oled_spi, C_OLED_SET_ROW_ADDRESS);
92   spi_rxtx(oled_spi, 0);
93   spi_rxtx(oled_spi, 0x3F);
94   dc(1); // data
95   for(int i = 0; i < 6144; i++)
96     spi_rxtx(oled_spi, color);
97 }
98
99 void oled_init()
100 {
101   dc(0); // commands
102   resn(0);
103   delay(5);
104   resn(1);
105   delay(20);
106   // spi_start_tx(oled_spi);
107   for(int i = 0; i < sizeof(oled_init_sequence)/sizeof(oled_init_sequence[0]); i++)
108     spi_rxtx(oled_spi, oled_init_sequence[i]);
109   oled_fill_screen(0x42);
110   oled_y = 0;
111 }
112
113 void oled_horizontal_line(uint8_t y, uint8_t color)
114 {
115   dc(0); // command
116   spi_rxtx(oled_spi, C_OLED_SET_ROW_ADDRESS);
117   spi_rxtx(oled_spi, y);
118   spi_rxtx(oled_spi, y);
119   dc(1); // data
120   for(int i = 0; i < 96; i++)
121     spi_rxtx(oled_spi, color);
122 }
123
124 uint8_t oled_color_stripes()
125 {
126   oled_horizontal_line((oled_y+ 0) & 63, 0xFF); // white
127   oled_horizontal_line((oled_y+16) & 63, 0x03); // blue
128   oled_horizontal_line((oled_y+32) & 63, 0x1C); // green
129   oled_horizontal_line((oled_y+48) & 63, 0xE0); // red
130   return oled_y++ & 63;
131 }
132
133
134 // set up variables using the SD utility library functions:
135 void oled_read(char *a)
136 {
137   uint8_t line = oled_color_stripes();
138   sprintf(a, "OLED: %02x", line);
139 }