\ ********************************************************************* 
\ Manage monochrome OLED display SSD1306 128x32                       * 
\    Filename:      stepperULN2003.txt                                * 
\    Date:          04.11.2020                                        * 
\    Updated:       12.11.2020 22:15                                  * 
\    File Version:  1.0                                               * 
\    MCU:           ARDUINO all models                                * 
\    GNU General Public License                                       * 
\    FF Version:    5.0                                               * 
\    Forth Author:  Marc PETREMANN                                    * 
\ ********************************************************************* 
 
\ require part of i2c-new.txt 
 
\ usage of stream: example 
\ eeprom 
\ stream: XX    \ create XX like as array with no datas 
\     2 c,      \ compile one byte (command or data) 
\     3 c,      \ compile other datas or commands 
\     4 c, 
\   ;stream     \ store at XX addr the legth of datas 
\ ram 
 
-stream 
marker -stream 
 
\ do nothing - default action for stream: 
: nothing ( ---) 
  ; 
 
defer stream.action \ default action for stream: 
 
\ define a command or data stream for SSD1306 
: stream: 
    \ set nothing as execute action by default 
    \ ['] nothing is stream.action 
    create 
        here    \ leave current dictionnary pointer on stack 
        0 c,    \ initial lenght data is 0 
    does> 
        stream.action 
  ; 
 
\ store at  addr length of datas compiled beetween 
\  and here 
: ;stream ( addr-var len ---) 
    dup 1+ here 
    swap -      \ calculate cdata length 
    \ store c in first byte of word defined by stream: 
    swap c! 
  ; 
 
-streamDebug 
marker -streamDebug 
 
\ get real addr2 and u length form addr1 
: count ( addr1 --- addr2 u) 
    dup c@          \ push real length 
    swap 1+ swap    \ push start address of datas 
  ; 
 
\ used for debugging streams 
\ for use: 
\  ' disp.stream is stream.action 
: disp.stream ( stream-addr ---) 
    count 
    for 
        c@+ . 
    next 
    drop 
  ; 
 
 
\ *** Manage OLED display 128x32 ******** 
 
-ssd1306 
marker -ssd1306 
 
$3c constant addrSSD1306    \ i2c device address 
 
\  control: $00 for commands 
\           $40 for datas 
$00 constant CTRL_COMMANDS 
$40 constant CTRL_DATAS 
 
\ send stream of datas or commands to SSD1306 
: i2c.stream.tx ( stream-addr ---) 
    addrSSD1306  i2c.addr.write drop \ send SSD1306 address 
    count  \ fetch real addr and length of datas to send 
    for 
        c@+ i2c.tx  \ send commands or datas 
    next 
    drop 
    i2c.stop 
  ; 
 
\ usage: 
' i2c.stream.tx is stream.action 
 
-commands 
marker -commands 
 
\ define SSD1306 128x32 ram size 
128 constant DISPLAY_WIDTH 
 32 constant DISPLAY_HEIGHT 
DISPLAY_WIDTH DISPLAY_HEIGHT * 8 / constant SSDramSize 
 
 
\ *** list of constants for Display commands *** 
\ $08 constant CHARGEPUMP 
\ $21 constant COLUMNADDR 
\ $c8 constant COMSCANDEC 
\ $c0 constant COMSCANINC 
\ $01 constant EXTERNALVCC 
\ $a7 constant INVERTDISPLAY 
\ $20 constant MEMORYMODE 
\ $a6 constant NORMALDISPLAY 
\ $22 constant PAGEADDR 
\ $a0 constant SEGREMAP 
\ $da constant SETCOMPINS 
\ $d5 constant SETDISPLAYCLOCKDIV 
\ $d3 constant SETDISPLAYOFFSET 
\ $10 constant SETHIGHCOLUMN 
\ $00 constant SETLOWCOLUMN 
\ $a8 constant SETMULTIPLEX 
\ $d9 constant SETPRECHARGE 
\ $a1 constant SETSEGMENTREMAP 
\ $40 constant STARTLINE 
\ $db constant SETVCOMDETECT 
\ $02 constant SWITCHCAPVCC 
 
\ fundamental commands 
\ $81 constant SETCONTRAST 
\ $a4 constant DISPONRESUME 
\ $a5 constant DISPLAYALLON 
\ $ae constant DISPLAYOFF 
\ $af constant DISPLAYON 
 
flash 
stream: disp.setup 
    CTRL_COMMANDS c, 
    $ae c, ( DISP_SLEEP ) 
    $d5 c, ( SET_DISP_CLOCK ) 
    $80 c, 
    $a8 c, ( SET_MULTIPLEX_RATIO ) 
    $3f c, 
    $d3 c, ( SET_VERTICAL_OFFSET ) 
    $00 c, 
    $40 c, ( SET_DISP_START_LINE ) 
    $8d c, ( CHARGE_PUMP_REGULATOR ) 
    $14 c, ( CHARGE_PUMP_ON ) 
    $20 c, ( MEM_ADDRESSING ) 
    $00 c, 
    $a0 c, ( SET_SEG_REMAP_0 ) 
    $c0 c, ( SET_COM_SCAN_NORMAL ) 
    $da c, ( SETCOMPINS ) 
    $02 c, \ or $12 ??? 
    $db c, ( SET_VCOM_DESELECT_LEVEL ) 
    $40 c, 
    $a4 c, ( RESUME_TO_RAM_CONTENT ) 
    $a6 c, ( NORMALDISPLAY ) 
    $af c, ( DISP_ON ) 
  ;stream 
 
stream: disp.reset 
    CTRL_COMMANDS c, 
    $21 c,  \ COL START_END 
    $00 c,  \ start 
    $7f c,  \ end 
    $22 c,  \ PAGE START_END 
    $00 c,  \ start 
    $03 c,  \ end 
  ;stream 
ram 
 
: disp.init ( -- ) 
    disp.setup 
    disp.reset 
  ; 
 
: disp.clear ( ---) 
    disp.reset 
    addrSSD1306  i2c.addr.write drop \ send SSD1306 address 
    CTRL_DATAS i2c.tx 
    SSDramSize 
    for 
        $00 i2c.tx  \ send commands or datas 
    next 
    i2c.stop 
    disp.reset 
  ; 
 
 
: init ( ---) 
    i2c.init 
    ['] i2c.stream.tx is stream.action 
    disp.init ; 
 
 
flash 
stream: disp.on 
    CTRL_COMMANDS c, 
    $af c, \ DISPLAYON 
    ;stream 
 
stream: disp.off 
    CTRL_COMMANDS c, 
    $ae c, \ DISPLAYOFF 
    ;stream 
 
stream: disp.invert 
    CTRL_COMMANDS c, 
    $a7 c,  \ INVERTDISPLAY 
    ;stream 
 
stream: disp.normal 
    CTRL_COMMANDS c, 
    $a6 c, \ NORMALDISPLAY 
    ;stream 
 
\ Stop scroll 
stream: scroll.off ( -- ) 
    CTRL_COMMANDS c, 
    $2e c,  \ SCROLLOFF 
    ;stream 
 
\ Start scroll 
stream: scroll.on ( -- ) 
    CTRL_COMMANDS c, 
    $2f c,  \ SCROLLON 
    ;stream 
 
\ set contrast 
stream: contrast.max ( -- ) 
    CTRL_COMMANDS c, 
    $81 c,  \ SETCONTRAST 
    $fa c,  \ value between 00..fe 
    ;stream 
ram 
 
' i2c.stream.tx is stream.action 
 
-zz 
marker -zz 
 
flash 
stream: BATT 
    CTRL_DATAS c, 
    %01111110 c, 
    %01000010 c, 
    %11000011 c, 
    %10111101 c, 
    %10111101 c, 
    %10111101 c, 
    %10000001 c, 
    %10111101 c, 
    %10111101 c, 
    %10111101 c, 
    %10000001 c, 
    %10111101 c, 
    %10111101 c, 
    %10111101 c, 
    %10000001 c, 
    %10111101 c, 
    %10111101 c, 
    %10111101 c, 
    %10000001 c, 
    %11111111 c, 
    ;stream 
ram 
 
stream: xy.batt 
    CTRL_COMMANDS c, 
    $21 c,  \ COL START_END 
    $6b c,  \ start 
    $7f c,  \ end 
    $22 c,  \ PAGE START_END 
    $00 c,  \ start 
    $00 c,  \ end 
  ;stream 
ram 
 
 
 
\ : x. 0 base @ >r 2 base ! <# # # # # # # # # #> type r> base ! ; 
 
flash 
stream: set.col07 ( -- ) 
    CTRL_COMMANDS c, 
    $21 c,  \ set column address 
    $00 c,  \ start col 00 
    $07 c,  \ end col 07 
    ;stream 
 
\ set Page Addressing mode 
stream: set.PAM ( -- ) 
    CTRL_COMMANDS c, 
    $20 c,  \ set memory addressing mode 
    $10 c,  \ Page Addressing mode 
    ;stream 
 
\ set Horizontal Addressing mode 
stream: set.HAM ( -- ) 
    CTRL_COMMANDS c, 
    $20 c,  \ set memory addressing mode 
    $00 c,  \ Horizontal Addressin mode 
    ;stream 
 
\ set Vertical Addressing mode 
stream: set.VAM ( -- ) 
    CTRL_COMMANDS c, 
    $20 c,  \ set memory addressing mode 
    $01 c,  \ 
    ;stream 
 
stream: set.colALL ( -- ) 
    CTRL_COMMANDS c, 
    $21 c,  \ set column address 
    $00 c,  \ start col 00 
    $7f c,  \ end col 07 
    ;stream 
 
ram 
 
' i2c.stream.tx is stream.action 
 
 
\ *** Manage ram buffer for commands vith variable datas 
 
\ store command|data in txBuffer 
: sc! ( c --- addr+1) 
    pc! p+ 
  ; 
 
: xxx 
    p>r 
    r> ; 
 
-buff 
marker -buff 
 
: buffer: ( ---  | ---) 
    create 
        0 c, 
        128 allot 
    does> 
        dup !p 
  ; 
 
 
 
buffer: txBUFFER 
 
 
 
 
 
 
-yy 
marker -yy 
 
\ scroll direction 
$26 constant RIGHT 
$27 constant LEFT 
$29 constant xx1 
$2a constant xx2 
 
\ activate scroll. Display is 16 row tall 
: scroll.start ( end-page start-page direction -- ) 
          ssd.command     \ direction 
    0     ssd.command 
          ssd.command     \ start page 0..7 
    0     ssd.command     \ time interval 
          ssd.command     \ stop page  0..7 
    0     ssd.command 
    $ff   ssd.command 
 SCROLLON ssd.command     \ activate scrolling 
    i2c.stop 
  ; 
\ *** IMPORTANT voir doc SSD1306 page 28 *** 
 
: scroll.RIGHT ( end-page start-page ---) 
    $26 scroll.start \ $26 constant RIGHT 
  ; 
 
: scroll.LEFT ( end-page start-page ---) 
    $27  scroll.start \ $27 constant LEFT 
  ; 
 
: set.col.start ( end start  --- ) 
    0     ssd.command   \ Command stream 
    $21   ssd.command   \ Set display start line 
    0     ssd.command 
          ssd.command   \ Set column start address 
    0     ssd.command 
          ssd.command   \ Set column end address 
    i2c.stop 
  ; 
 
: set.vert.mode ( --- ) 
    0     ssd.command   \ Command stream 
    $20   ssd.command   \ Set Memory Addressing Mode 
    0     ssd.command 
    $01   ssd.command   \ Vertical Addressing Mode 
    i2c.stop 
  ; 
 
-datasTX 
marker -datasTX 
 
flash 
stream: scroll.RIGHT 
    CTRL_COMMANDS c, 
    $27 c, \ $27 constant LEFT 
    $00 c,  \ dummy byte 
    $00 c,  \ start page 
    $00 c,  \ time interval 
    $07 c,  \ end page 
    $00 c,  \ dummy byte 
    $ff c,  \ dummy byte 
    $2f c,  \ SCROLLON 
    ;stream 
ram 
\ start scroll RIGHT entire screen 
: scroll.RIGHT ( ---) 
    scrollOFF i2c.stream.tx 
  ; 
 
flash 
stream: scrollOFF 
    SCROLLOFF c, 
scrollOFF str.resolve 
ram 
\stop scrolling entire screen 
: scroll.stop ( ---) 
    scrollOFF i2c.stream.tx 
  ; 
 
-aaa 
marker -aaa 
 
 
: CB 
    8bytes i2c.stream.tx 
  ;