;-------------------------------------------------------- ; Armpit Scheme 00.0160 LCD Output Port DRAW Example. ; For Nokia-Like LCD. ;-------------------------------------------------------- ; S1D15G00 ; 132x130 pixels (row x col) ; 8-bit color ; serial 9-bit interface ;-------------------------------------------------------- ; open an output file to write code (define p (open-output-file "init-lcd-draw")) ; define output pins for LCD ; (Note 1: these pins are assumed to already be configured as gpios, ; and all LCD pins are on the same gpio line, i.e. all are ; on gpio.0, or all are on gpio.1, ...) ; (Note 2: per Armpit Scheme's use of 30-bit integers, ; pins 29, 30 and 31, if used within Scheme, are set/cleared together, ; as controlled by pin 29 => keep ~RST < 29, other pins are controlled ; in assembly only and can be >= 29) ; LPC-H2214 (write '(begin (define lcdo #xe002800) ; LCD output lines are on GPIO 0 (base address) (define lcdr 22) ; ~RST is P0.22 (define lcdd 23) ; DATA is P0.23 (define lcdc 24) ; CLOCK is P0.24 (define lcds 25)) ; ~CS is P0.25 p) ; TINY-2138 (write '(begin (define lcdo #xe002800) ; LCD output lines are on GPIO 0 (base address) (define lcdr 27) ; ~RST is P0.27 (define lcdd 28) ; DATA is P0.28 (define lcdc 29) ; CLOCK is P0.29 (define lcds 30)) ; ~CS is P0.30 p) ; TINY-2106 (write '(begin (define lcdo #xe002800) ; LCD output lines are on GPIO 0 (base address) (define lcdr 5) ; ~RST is P0.5 (define lcdd 4) ; DATA is P0.4 (define lcdc 7) ; CLOCK is P0.7 (define lcds 6)) ; ~CS is P0.6 p) ; COMMON CODE STARTS: ; define bit manipulation functions (utility) (write '(begin (define (LOS val reg ofst) (write (logior val (read reg ofst)) reg ofst)) (define (LMOS mask val reg ofst) (write (logior val (logand mask (read reg ofst))) reg ofst)) (define (bset bit reg ofst) (LOS (ash 1 (min bit 29)) reg ofst)) (define (set-pin port pin) (write (ash 1 (min pin 29)) port #x04)) (define (clear-pin port pin) (write (ash 1 (min pin 29)) port #x0c))) p) ; define vector-append function (utility) (write '(define (vector-append v1 v2) (let* ((n1 (vector-length v1)) (n2 (vector-length v2)) (v (make-vector (+ n1 n2)))) (let loop ((n (- n1 1))) (if (< n 0) #t (begin (vector-set! v n (vector-ref v1 n)) (loop (- n 1))))) (let loop ((n (- n2 1))) (if (< n 0) #t (begin (vector-set! v (+ n n1) (vector-ref v2 n)) (loop (- n 1))))) v)) p) ; configure lcd pins as output (assumed gpio already) and reset lcd (write '(begin (LOS (ash 1 (min lcdr 29)) lcdo #x08) ; set ~RST line as output (LOS (ash 1 (min lcdd 29)) lcdo #x08) ; set DATA line as output (LOS (ash 1 (min lcdc 29)) lcdo #x08) ; set CLOCK line as output (LOS (ash 1 (min lcds 29)) lcdo #x08) ; set ~CS line as output (set-pin lcdo lcdr) ; ~RST line high (set-pin lcdo lcdd) ; DATA line high (set-pin lcdo lcdc) ; CLOCK line high (set-pin lcdo lcds) ; ~CS line high (clear-pin lcdo lcdr) ; assert reset (set-pin lcdo lcdr)) ; de-assert reset p) ; define and install the lcd output port (write '(begin (define lcop (install '#(0 0 #xff000002 0 #xff000011 0 1 0 #xff000004 0 #xff000008 0 #xff000006 0 1 0 #x0f 0 #x084b 0 1 0 1 0 1 0 #x49 0 #x03fd 0 1 0 #x49 0 #x55 0 #x0a4b 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0))) (let ((v (cdr lcop))) (let loop ((n 0)) (if (= n 5) #t (begin (vector-set! v n (vector-ref _OPR n)) (loop (+ n 1))))))) p) ; lcdcmd -- assembly function to write commands and data to LCD ; (step 1 -- due to read buffer size) (write '(define temp '#(#x27 0 #xeb 0 #x7070 #xE28F #x7000 #xE597 #x206C #xE28F #x2000 #xE592 #x2004 #xE587 #xC058 #xE28F #xE000 #xE58C #x200C #xE587 #x2058 #xE28F #x2000 #xE592 #xC054 #xE28F #xC000 #xE59C #xEC01 #xE3A0 #x200C #xE587 #xE #xE113 #xC00C #x587 #xC004 #x1587 #x2004 #xE587 #xE0AE #xE1B0 #xF020 #x124F #xC02 #xE353 #x3A01 #x5243 #xF030 #x524F #x2018 #xE28F #x2000 #xE592 #x2004 #xE587 #xE004 #xE28F #xE000 #xE59E #xF00E #xE1A0 #x0 #x0)) p) ; lcdcmd -- install phase ; (step 2 -- due to read buffer size) (write '(begin (vector-set! (cdr lcop) 6 (install (vector-append temp (vector (logand (ash lcdo 4) #xffff) (logand (ash lcdo -12) #xffff) (logand (ash 1 lcds) #xffff) (logand (ash 1 (- lcds 16)) #xffff) (logand (ash 1 lcdc) #xffff) (logand (ash 1 (- lcdc 16)) #xffff) (logand (ash 1 lcdd) #xffff) (logand (ash 1 (- lcdd 16)) #xffff))))) (set! temp #t)) p) ; (wlcd cmd/dat) -- Scheme interface to lcdcmd assembly function (write '(define wlcd (install (list->vector `(#x27 0 #x01eb 0 #x3124 #xE1A0 #x401C #xE28F #x4000 #xE594 #x4004 #xE594 #xC01C #xE594 #xC004 #xE28C #xE000 #xE28F #xF00C #xE1A0 #x400F #xE3A0 #xF001 #xE1A0 ,(logand (ash lcop 2) #xffff) ,(logand (ash lcop -14) #xffff))))) p) ; configure and turn on the LCD (write '(for-each wlcd '(#xCA #x100 #x120 #x101 #xBB #x101 #xD1 #x94 ; DISCTL COMSCN OSCON SLPOUT #x81 #x10f #x103 #x82 #x101 #xBC #x100 #x100 #x101 ; VOLCTR TMPGRD DATCTL #xCE #x100 #x102 #x104 #x106 #x108 #x10a #x10c #x10f ; RGBSET8 #x100 #x102 #x104 #x106 #x108 #x10a #x10c #x10f ; RGBSET8 #x100 #x104 #x109 #x10f ; RGBSET8 #x25 #xA7 #x20 #x10f #x25 #xAF ; NOP DISINV PWRCTR NOP DISON #xAA #x100 #x129 #x129 #x103)) ; SCROLL-SET p) ; define pixel and fill functions (write '(begin (define (pixel x y c) (for-each wlcd (list #x15 (logior x #x0100) #x183 #x75 (logior y #x0100) #x183 #x5C (logior c #x0100)))) (define (fill xs ys xe ye col) (for-each wlcd (list #x15 (logior #x100 xs) (logior #x100 xe) #x75 (logior #x100 ys) (logior #x100 ye) #x5c (logior (ash (* (- xe xs -1) (- ye ys -1)) 12) (logior #x100 col)))))) p) ; define clear screen function and call it (write '(begin (define (cls) (for-each wlcd '(#x75 #x100 #x183 #x15 #x100 #x181 #x5c)) (let ((stat (cadar lcop))) (wlcd (logior (ash (* 130 132) 12) (logior #x0100 (vector-ref stat 5)))) (vector-set! stat 0 0) (vector-set! stat 1 0) (vector-set! stat 3 (vector-ref stat 6)) (for-each wlcd '(#xab #x100)))) (cls)) p) ; close the file (close-output-port p) ; if the screen is too dark (see VOLCTR command above) (for-each wlcd '(#x81 #x10f #x105))