\ ********************************************************************* \ Manage commands for OLED SSD1306 128x32 display \ Filename: SSD10306commands.txt \ Date: 09 feb 2022 \ Updated: 22 feb 2022 \ File Version: 1.0 \ MCU: ESP32-WROOM-32 \ Forth: ESP32forth all versions 7.x++ \ Copyright: Marc PETREMANN \ Author: Marc PETREMANN \ GNU General Public License \ ********************************************************************* DEFINED? --SSD1306 [if] forget --SSD1306 [then] create --SSD1306 vocabulary SSD1306 only forth also Wire also SSD1306 definitions \ for SSD1306_128_64 \ 128 constant SSD1306_LCDWIDTH \ 64 constant SSD1306_LCDHEIGHT \ for SSD1306_128_32 128 constant SSD1306_LCDWIDTH 32 constant SSD1306_LCDHEIGHT \ definition of SSD1306 display dimensions in pixels SSD1306_LCDWIDTH constant DISPLAY_WIDTH SSD1306_LCDHEIGHT constant DISPLAY_HEIGHT $91 constant SSD1306_SETCONTRAST $a4 constant SSD1306_DISPLAYALLON_RESUME $a5 constant SSD1306_DISPLAYALLON $a6 constant SSD1306_NORMALDISPLAY $a7 constant SSD1306_INVERTDISPLAY $a8 constant SSD1306_SETMULTIPLEX $ae constant SSD1306_DISPLAYOFF $af constant SSD1306_DISPLAYON $d3 constant SSD1306_SETDISPLAYOFFSET $da constant SSD1306_SETCOMPINS $db constant SSD1306_SETVCOMDETECT $d5 constant SSD1306_SETDISPLAYCLOCKDIV $d9 constant SSD1306_SETPRECHARGE \ $00 constant SSD1306_SETLOWCOLUMN \ $10 constant SSD1306_SETHIGHCOLUMN $40 constant SSD1306_SETSTARTLINE $20 constant SSD1306_MEMORYMODE $21 constant SSD1306_COLUMNADDR $22 constant SSD1306_PAGEADDR $c0 constant SSD1306_COMSCANINC $c8 constant SSD1306_COMSCANDEC $a0 constant SSD1306_SEGREMAP $8d constant SSD1306_CHARGEPUMP $01 constant SSD1306_EXTERNALVCC $02 constant SSD1306_SWITCHCAPVCC \ Scrolling constants $2f constant SSD1306_ACTIVATE_SCROLL $2e constant SSD1306_DEACTIVATE_SCROLL $a3 constant SSD1306_SET_VERTICAL_SCROLL_AREA $26 constant SSD1306_RIGHT_HORIZONTAL_SCROLL $27 constant SSD1306_LEFT_HORIZONTAL_SCROLL $29 constant SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL $2a constant SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL \ Addressing modes $00 constant HORIZONTAL_ADDRESSING_MODE $01 constant VERTICAL_ADDRESSING_MODE $02 constant PAGE_ADDRESSING_MODE \ control: $00 for commands \ $40 for datas $00 constant CTRL_COMMANDS $40 constant CTRL_DATAS \ set adress of OLED SSD1306 display 128x32 pixels $3c constant addrSSD1306 \ begin I2C transmssion to SSD1306 OLED display : SSD1306beginTransmission ( -- ) addrSSD1306 Wire.beginTransmission ; \ memoryze transmitted bytes, interval [00..31] variable maxBytesSended \ end I2C transmssion to SSD1306 OLED display : SSD1306endTransmission ( -- ) -1 Wire.endTransmission drop 0 maxBytesSended ! ; \ if sended bytes > 32 end and restart transmission : incrementMaxBytes ( -- ) 1 maxBytesSended +! maxBytesSended @ 31 > if SSD1306endTransmission SSD1306beginTransmission then ; \ Send code c to I2C bus : Wire.send ( c -- ) >r 0 <# r> hold #> Wire.write drop incrementMaxBytes ; \ send a data array to SSD1306 connected via I2C bus \ CAUTION: array size max 32 bytes : sendStringToSSD1306 ( addr len -- ) SSD1306beginTransmission Wire.write drop SSD1306endTransmission ; \ define a command or data stream for SSD1306 : streamCreate: ( comp:| exec: -- addr len ) create here \ leave current dictionnary pointer on stack 0 c, \ initial lenght data is 0 does> dup 1+ swap c@ \ send a data array to SSD1306 connected via I2C bus sendStringToSSD1306 ; \ store ataddr length of datas compiled beetween \and here : ;endStream ( addr-var len ---) dup 1+ here swap - \ calculate cdata length \ store c in first byte of word defined by streamCreate: swap c! ; \ Initialize SSD105 128x32 display streamCreate: dispSetup CTRL_COMMANDS c, SSD1306_DISPLAYOFF c, SSD1306_SETDISPLAYCLOCKDIV c, $80 c, SSD1306_SETMULTIPLEX c, DISPLAY_HEIGHT 1- c, SSD1306_SETDISPLAYOFFSET c, $00 c, SSD1306_SETSTARTLINE $00 or c, SSD1306_CHARGEPUMP c, $14 c, ( CHARGE_PUMP_ON ) SSD1306_SEGREMAP $01 or c, ( Reverse mapping ) SSD1306_COMSCANDEC c, SSD1306_SETCOMPINS c, $02 c, SSD1306_SETCONTRAST c, $7f c, SSD1306_SETPRECHARGE c, $22 c, SSD1306_SETVCOMDETECT c, $40 c, \ SSD1306_MEMORYMODE c, HORIZONTAL_ADDRESSING_MODE c, SSD1306_DISPLAYALLON_RESUME c, SSD1306_NORMALDISPLAY c, SSD1306_DISPLAYON c, ;endStream \ Reset SSD105 128x32 display streamCreate: dispReset CTRL_COMMANDS c, SSD1306_DISPLAYOFF c, SSD1306_MEMORYMODE c, HORIZONTAL_ADDRESSING_MODE c, SSD1306_COLUMNADDR c, \ $21 $00 c, \ start $7f c, \ end SSD1306_PAGEADDR c, \ $22 $00 c, \ start $07 c, \ end SSD1306_DISPLAYON c, ;endStream \ main INITialization for SSD1306 128x32 OLED display : dispInit ( -- ) \ start the I2C interface using pin 21 and 22 on ESP32 DEVKIT V1 \ with 21 used as sda and 22 as scl. 21 22 wire.begin drop dispSetup dispReset ; streamCreate: dispOn \ toggle display on CTRL_COMMANDS c, $af c, \ DISPLAYON ;endStream streamCreate: dispOff \ toggle display off CTRL_COMMANDS c, $ae c, \ DISPLAYOFF ;endStream \ store normal | inverse display state SSD1306_NORMALDISPLAY value _SSD1306_DISPLAY \ set display mode normal : dispNormal ( -- ) SSD1306beginTransmission CTRL_COMMANDS Wire.send SSD1306_NORMALDISPLAY Wire.send SSD1306endTransmission SSD1306_NORMALDISPLAY to _SSD1306_DISPLAY ; \ invert display mode : dispInvert SSD1306beginTransmission CTRL_COMMANDS Wire.send SSD1306_INVERTDISPLAY Wire.send SSD1306endTransmission SSD1306_INVERTDISPLAY to _SSD1306_DISPLAY ; : OledInvert ( -- ) \ test if actual display mode is normal _SSD1306_DISPLAY SSD1306_NORMALDISPLAY = if dispInvert else dispNormal then ; : setLine { page -- } SSD1306beginTransmission CTRL_COMMANDS Wire.send SSD1306_COLUMNADDR Wire.send $00 Wire.send \ start $7f Wire.send \ end SSD1306_PAGEADDR Wire.send page Wire.send \ start page Wire.send \ end SSD1306endTransmission ; \ pointer for current page [0..3] 0 value currentPage \ move pointer to next page : crLine ( ---) currentPage 1+ 3 and to currentPage currentPage setLine ; \ Reset SSD105 128x32 display streamCreate: dispReset CTRL_COMMANDS c, SSD1306_MEMORYMODE c, HORIZONTAL_ADDRESSING_MODE c, SSD1306_COLUMNADDR c, \ $21 $00 c, \ start $7f c, \ end SSD1306_PAGEADDR c, \ $22 $00 c, \ start $03 c, \ end ;endStream \ send 32x 0 value streamCreate: sendBlock32bytesWith0 ( -- ) CTRL_DATAS c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, ;endStream \ clear a complete line : lineCLS ( -- ) 4 for aft sendBlock32bytesWith0 then next ; \ clear complete screen : OledCLS ( -- ) dispReset DISPLAY_HEIGHT 8 / for aft lineCLS then next ;
Legal: site web personnel sans commerce / personal site without seling