Skip to content

Instantly share code, notes, and snippets.

@yunfan
Created September 29, 2017 07:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yunfan/2d3ee14697f3ebd3cb43ae411216d9aa to your computer and use it in GitHub Desktop.
Save yunfan/2d3ee14697f3ebd3cb43ae411216d9aa to your computer and use it in GitHub Desktop.
\ ssd1306 I2C display driver for 128x32 pixel OLED displays, this is work in progress
\ Tested with wemos oled shield
\ Usage:
\ display-init
\ font5x7 font !
\ 10 text-top ! 8 text-left !
\ "Hello" draw-str
\ display
\ display-clear
128 constant: WIDTH
32 constant: HEIGHT
5 ( D1 SCL ) constant: SCL
4 ( D2 SDA ) constant: SDA
0 ( D3 RST ) constant: RST
16r3C constant: SLAVE
WIDTH HEIGHT * 8 / constant: SIZE
SIZE 1+ buffer: screen1
16r40 ( control byte ) screen1 !
: screen ( -- buffer ) screen1 1+ ;
exception: EI2C
\ i2c-write-slave in rtos uses uint8_t len parameter
\ this version uses 32bit integer
\ TODO: use updated version of RTOS and delete this word
: i2c-write-slave ( len buffer slave-addr -- cbool )
i2c-start
1 lshift i2c-write 1 <> if 2drop i2c-stop 0 exit then
swap 0 do
dup i + c@ i2c-write 1 <> if
unloop drop i2c-stop 0 exit
then
loop
drop i2c-stop 1 ;
: wire ( -- )
SCL GPIO_OUT gpio-mode
SDA GPIO_OUT gpio-mode
RST GPIO_LOW gpio-write ;
: check ( code -- | throws:EI2C ) 1 <> if EI2C throw then ;
create: buf 16r80 c, 0 c,
: cmd ( byte -- | throws:EI2C ) buf 1+ c! 2 buf SLAVE i2c-write-slave check ;
: reset ( -- )
RST GPIO_HIGH gpio-write 1 ms
RST GPIO_LOW gpio-write 10 ms
RST GPIO_HIGH gpio-write ;
: init ( -- )
16rAE ( SSD1306_DISPLAYOFF ) cmd
16rD5 ( SSD1306_SETDISPLAYCLOCKDIV ) cmd
16r80 cmd
16rA8 ( SSD1306_SETMULTIPLEX ) cmd
HEIGHT 1- cmd
16rD3 ( SSD1306_SETDISPLAYOFFSET ) cmd
16r00 cmd
16r40 ( SSD1306_SETSTARTLINE ) cmd
16r8D ( SSD1306_CHARGEPUMP ) cmd
16r14 cmd
16r20 ( SSD1306_MEMORYMODE ) cmd
16r00 cmd
16rA1 ( SSD1306_SEGREMAP ) cmd
16rC8 ( SSD1306_COMSCANDEC ) cmd
16rDA ( SSD1306_SETCOMPINS ) cmd
16r12 cmd
16r81 ( SSD1306_SETCONTRAST ) cmd
16rCF cmd
16rD9 ( SSD1306_SETPRECHARGE ) cmd
16rF1 cmd
16rDB ( SSD1306_SETVCOMDETECT ) cmd
16r40 cmd
16rA4 ( SSD1306_DISPLAYALLON_RESUME ) cmd
16rA6 ( SSD1306_NORMALDISPLAY ) cmd
16rAF ( SSD1306_DISPLAYON ) cmd ;
: y>bitmask ( y -- bit-index ) 7 and 1 swap lshift ;
: xy-trunc ( x y -- x' y' ) swap 127 and swap 32 % ;
: xy>i ( x y -- bit-mask buffer-index )
xy-trunc
dup
y>bitmask -rot
3 rshift ( 8 / )
WIDTH * + ;
: or! ( value addr -- ) tuck c@ or swap c! ;
: and! ( value addr -- ) tuck c@ and swap c! ;
: set-pixel ( x y -- ) xy>i screen + or! ;
: unset-pixel ( x y -- ) xy>i screen + swap invert swap and! ;
: pixel-set? ( x y -- ) xy>i screen + c@ and 0<> ;
: hline ( x y width -- ) 0 do 2dup set-pixel { 1+ } dip loop 2drop ;
: rect-fill ( x y width height -- ) 0 do 3dup hline { 1+ } dip loop 3drop ;
: fill-buffer ( value -- ) SIZE 0 do dup i screen + c! loop drop ;
: display ( -- )
16r21 ( COLUMNADDR ) cmd
32 cmd
95 cmd
16r22 ( PAGEADD ) cmd
0 cmd
5 cmd
SIZE 1+ screen 1- SLAVE i2c-write-slave check ;
: display-clear ( -- ) 0 fill-buffer display ;
: display-init ( -- | throws:ESSD1306 ) wire SDA SCL i2c-init reset init display-clear ;
\ TODO move these to common place as they're used in the spi driver too
0 init-variable: font
0 init-variable: text-left
0 init-variable: text-top
1 init-variable: font-size
: font-small ( -- ) 1 font-size ! ;
: font-medium ( -- ) 2 font-size ! ;
: font-big ( -- ) 3 font-size ! ;
: font-xbig ( -- ) 4 font-size ! ;
: draw-lf ( -- ) 9 text-top +! ;
: draw-cr ( -- ) 0 text-left ! ;
: dot ( x y -- ) { font-size @ * } bi@ font-size @ dup rect-fill ;
: stripe ( bits -- )
8 0 do
dup 1 and 1= if
text-left @ text-top @ i + dot
then
1 rshift
loop
drop ;
: draw-char ( char -- )
255 and 5 * font @ +
5 0 do
dup c@ stripe 1+
1 text-left +!
loop
1 text-left +!
drop ;
: draw-str ( str -- )
font @ 0= if
println: 'Set a font like: "font5x7 font !"'
drop exit
then
dup strlen 0 do
dup i + c@
case
10 of draw-lf endof
13 of draw-cr endof
draw-char
endcase
loop
drop ;
: str-width ( str -- ) strlen 8 * font-size @ * ;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment