-
Notifications
You must be signed in to change notification settings - Fork 0
/
ssd1327.fs
204 lines (185 loc) · 9.47 KB
/
ssd1327.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
\ interface to 128x128 ssd1327 OLED
\ uses i2c
$3c constant ssd1327
\
: lcd? ( -- f ) \ probe whether device exists, return true if it does
ssd1327 i2c-addr 0 i2c-xfer 0= ;
: lcd!c ( v -- ) \ send a command to the lcd
ssd1327 i2c-addr $80 >i2c >i2c 0 i2c-xfer drop ;
\ the oled's display memory each byte is 2 pixel, 128x128 pixel
8192 buffer: lcdmem
\ clear, putpixel, and display are used by the graphics.fs code
: clear ( -- ) \ clear display memory
lcdmem 8192 0 fill ;
: lcdfill ( c - ) \ fills all with 1
lcdmem 8192 rot fill
;
\ greyscale g is $0 - $f
: putpixelg ( g x y -- ) \ set a pixel in display memory with greyscale info
6 lshift swap \ y is 64 times
dup shr
rot + lcdmem +
swap 1 and
0= if
dup c@ rot $0f and or swap c!
else
dup c@ rot $0f and 4 lshift or swap c!
then
;
\
: putpixel ( x y -- ) \ set a pixel in display memory
6 lshift swap \ y is 64 times
dup shr
rot + lcdmem +
swap 1 and
0= if
dup c@ $F0 or swap c!
else
dup c@ $0F or swap c!
then
;
: display ( -- ) \ update the oled from display memory
$15 lcd!c $00 lcd!c $7F lcd!c \ SET_COL_ADDR, ((128 - self.width) // 4), 63 - ((128 - self.width) // 4),
$75 lcd!c $00 lcd!c $7f lcd!c \ SET_ROW_ADDR, 0x00, self.height - 1,
ssd1327 i2c-addr $40 >i2c \ start transmission
lcdmem
8192 0 do dup c@ >i2c 1+ loop
0 i2c-xfer drop drop ;
create logo \ 64x64 pixels
binary
00000000000000000000000000000111 , 11100000000000000000000000000000 ,
00000000000000000000000111111111 , 11111111100000000000000000000000 ,
00000000000000000000111111111111 , 11111111111100000000000000000000 ,
00000000000000000011111111111111 , 11111111111111000000000000000000 ,
00000000000000001111111111111111 , 11111111111111110000000000000000 ,
00000000000000011111111111000000 , 00000011111111111000000000000000 ,
00000000000001111111110000000000 , 00000000011111111110000000000000 ,
00000000000011111111000000000000 , 00000000000011111111000000000000 ,
00000000000111111100000000000000 , 00000000000000111111100000000000 ,
00000000001111111000000000000000 , 00000000000000011111110000000000 ,
00000000011111100000000000000000 , 00000000000000000111111000000000 ,
00000000111111000000000000000000 , 00000001100000000011111100000000 ,
00000001111110000000000000000000 , 00000001000000000001111110000000 ,
00000011111100000000000000000000 , 00000001000000000000111111000000 ,
00000011111000000000000000000000 , 00000011000000000000011111000000 ,
00000111110000000000000000000111 , 10000010000000000000001111100000 ,
00001111110000000000000000000111 , 11000110000000000000001111110000 ,
00001111100000000000000000001111 , 11000100000000000000000111110000 ,
00011111000000000000000000001111 , 10000100000000000000000011111000 ,
00011111000000000000000000001111 , 10001100011110000000000011111000 ,
00111110000000000000000000011111 , 10001000011111000000000001111100 ,
00111110000000000000000000011111 , 00001000111111000000000001111100 ,
00111110000000000000000000011111 , 00011000111110000000000001111100 ,
01111100000000000000000000111110 , 00010000111110000000000000111110 ,
01111100000000000000000000111110 , 00110001111110000000000000111110 ,
01111100000000000000000001111110 , 00110001111100000000000000111110 ,
01111000000000000000000001111100 , 00100001111100011000000000011110 ,
01111000000000000000000001111100 , 01100011111000010000000000011110 ,
01111000000000000000000011111100 , 01000011111000010000000000011110 ,
11111000000000000000000011111000 , 01000111111000110000000000011111 ,
11111000000000000000000011111000 , 11000111110000100000000000011111 ,
11111111111111111111111111111111 , 10000111110001111111111111111111 ,
11111000000000000000001111110001 , 10001111110001100000000000011111 ,
11111000000000000000000111110001 , 10001111100001000000000000011111 ,
11111000000000000000001111100001 , 00001111100011000000000000011111 ,
01111000000000000000001111100011 , 00011111100010000000000000011110 ,
01111000000000000000011111100010 , 00011111000010000000000000011110 ,
01111000000010000000011111000010 , 00011111000000000000000000011110 ,
01111100011111000000011111000110 , 00111110000000000000000000111110 ,
01111100011111000000111111000100 , 00111110000000000000000000111110 ,
00111100011111100001111110000100 , 01111110000000000000000000111100 ,
00111110011111111111111110001100 , 01111111111111111111000001111100 ,
00111110001111111111111100001000 , 01111111111111111111000001111100 ,
00011110000111111111111000011000 , 11111111111111111111000001111000 ,
00011111000011111111110000011000 , 11111111111111111111000011111000 ,
00011111000001111111000000100001 , 11111111111111111111000011110000 ,
00001111100000000000000000110000 , 00000000000000000000000111110000 ,
00001111110000000000000000100000 , 00000000000000000000001111110000 ,
00000111110000000000000000100000 , 00000000000000000000001111100000 ,
00000011111000000000000001100000 , 00000000000000000000011111000000 ,
00000011111100000000000001000000 , 00000000000000000000111111000000 ,
00000001111110000000000001000000 , 00000000000000000001111110000000 ,
00000000111111000000000000000000 , 00000000000000000011111100000000 ,
00000000011111100000000000000000 , 00000000000000000111111000000000 ,
00000000001111111000000000000000 , 00000000000000011111110000000000 ,
00000000000111111100000000000000 , 00000000000000111111100000000000 ,
00000000000011111111000000000000 , 00000000000011111111000000000000 ,
00000000000001111111111000000000 , 00000000011111111110000000000000 ,
00000000000000011111111111000000 , 00000011111111111000000000000000 ,
00000000000000001111111111111111 , 11111111111111110000000000000000 ,
00000000000000000011111111111111 , 11111111111111000000000000000000 ,
00000000000000000000011111111111 , 11111111111000000000000000000000 ,
00000000000000000000000011111111 , 11111111000000000000000000000000 ,
00000000000000000000000000000111 , 11100000000000000000000000000000 ,
decimal
: show-logo ( -- ) \ show the JeeLabs logo
clear
logo 64 0 do
64 0 do
dup i 5 rshift cells + @
i not $1F and rshift
1 and if i 32 + j 32 + putpixel then
loop
8 +
loop
drop display ;
: lcd-init2 ( -- ) \ initialise the oled display
i2c-init
$ae lcd!c \ SET_DISP, # $ae Display off, $af display on
$15 lcd!c $00 lcd!c $7f lcd!c \ SET_COL_ADDR, ((128 - self.width) // 4), 63 - ((128 - self.width) // 4), (?)
$75 lcd!c $00 lcd!c $7f lcd!c \ SET_ROW_ADDR, 0x00, self.height - 1, (?)
$81 lcd!c $80 lcd!c \ SET_CONTRAST, 0x7f, # Medium brightness
$a0 lcd!c $51 lcd!c \ SET_SEG_REMAP, $51,
$a1 lcd!c $00 lcd!c \ SET_DISP_START_LINE, $00,
$a2 lcd!c $00 lcd!c \ SET_DISP_OFFSET, $20, # Set vertical offset by COM from 0~127 (!)changed
$a4 lcd!c \ SET_DISP_MODE, # Normal, not inverted $a4, inverted $a7, all off $a6, all on $a5
$a8 lcd!c $7f lcd!c \ SET_MUX_RATIO, self.height - 1,
$b1 lcd!c $f1 lcd!c \ SET_PHASE_LEN, 0x51, # Phase 1: 1 DCLK, Phase 2: 5 DCLKs
$b3 lcd!c $00 lcd!c \ SET_DISP_CLK_DIV, 0x01, # Divide ratio: 1, Oscillator Frequency: 0
$ab lcd!c $01 lcd!c \ SET_FN_SELECT_A, $01, # Enable internal VDD regulator
$b6 lcd!c $0f lcd!c \ SET_SECOND_PRECHARGE, 0x01, # Second Pre-charge period: 1 DCLK
$be lcd!c $0f lcd!c \ SET_VCOM_DESEL, 0x07, # Set VCOMH COM deselect voltage level: 0.86*Vcc
$bc lcd!c $08 lcd!c \ SET_PRECHARGE, 0x08, # Set pre-charge voltage level: VCOMH
$d5 lcd!c $62 lcd!c \ SET_FN_SELECT_B, 0x62, # Enable enternal VSL, Enable second precharge
$fd lcd!c $12 lcd!c \ SET_COMMAND_LOCK, $12, # Unlock
$af lcd!c \ SET_DISP | 0x01): # Display on
;
: lcd-init ( -- ) \ initialise the oled display
i2c-init
$fd lcd!c $12 lcd!c \ SET_COMMAND_LOCK, $12, # Unlock
$ae lcd!c \ SET_DISP, # $ae Display off, $af display on
\ Resolution and layout
$a1 lcd!c $00 lcd!c \ SET_DISP_START_LINE, $00,
$a2 lcd!c $00 lcd!c \ SET_DISP_OFFSET, $20, # Set vertical offset by COM from 0~127 (!)changed
\ Set re-map
\ Enable column address re-map
\ Disable nibble re-map
\ Horizontal address increment
\ Enable COM re-map
\ Enable COM split odd even
$a0 lcd!c $51 lcd!c \ SET_SEG_REMAP, $51,
$a8 lcd!c $7f lcd!c \ SET_MUX_RATIO, self.height - 1,
\ Timing and driving scheme
$ab lcd!c $01 lcd!c \ SET_FN_SELECT_A, $01, # Enable internal VDD regulator
$b1 lcd!c $51 lcd!c \ SET_PHASE_LEN, 0x51, # Phase 1: 1 DCLK, Phase 2: 5 DCLKs
$b3 lcd!c $01 lcd!c \ SET_DISP_CLK_DIV, 0x01, # Divide ratio: 1, Oscillator Frequency: 0
$bc lcd!c $08 lcd!c \ SET_PRECHARGE, 0x08, # Set pre-charge voltage level: VCOMH
$be lcd!c $07 lcd!c \ SET_VCOM_DESEL, 0x07, # Set VCOMH COM deselect voltage level: 0.86*Vcc
$b6 lcd!c $01 lcd!c \ SET_SECOND_PRECHARGE, 0x01, # Second Pre-charge period: 1 DCLK
$d5 lcd!c $62 lcd!c \ SET_FN_SELECT_B, 0x62, # Enable enternal VSL, Enable second precharge
\ Display
$b9 lcd!c \ SET_GRAYSCALE_LINEAR, # Use linear greyscale lookup table
$81 lcd!c $53 lcd!c \ SET_CONTRAST, 0x7f, # Medium brightness
$a4 lcd!c \ SET_DISP_MODE, # Normal, not inverted $a4, inverted $a7, all off $a6, all on $a5
\ 96x96:
\ SET_ROW_ADDR, 0 95,
\ SET_COL_ADDR, 8, 55,
\ 128x128:
\ SET_ROW_ADDR, 0 127,
\ SET_COL_ADDR, 0, 63,
$75 lcd!c $00 lcd!c $7f lcd!c \ SET_ROW_ADDR, 0x00, self.height - 1, (?)
$15 lcd!c $00 lcd!c $7f lcd!c \ SET_COL_ADDR, ((128 - self.width) // 4), 63 - ((128 - self.width) // 4), (?)
$2e lcd!c \ SET_SCROLL_DEACTIVATE,
$af lcd!c \ SET_DISP | 0x01): # Display on
;
\ lcd-init show-logo