led7seg.inc
author Tero Marttila <terom@paivola.fi>
Sun, 20 Apr 2014 23:51:57 +0300
changeset 80 5254ba612630
parent 30 5226e512755c
permissions -rw-r--r--
dmx-web: slightly better RGB colorpicker control..
;;
;; Driving 7-segment LED displays over SPI
;;

; Output Enable control
.equ LED7_DDR    = DDRB
.equ LED7_PORT   = PORTB
.equ LED7_OE     = PORTB1                ; Output Enable (Low)

; Font for 7-segment display
; Includes decimal digits 0-9, hexadecimal digits A-F, and some special chars
LED7_Font:
.db     0b00111111, 0b00000110      ; 0, 1
.db     0b01011011, 0b01001111      ; 2, 3
.db     0b01100110, 0b01101101      ; 4, 5
.db     0b01111101, 0b00000111      ; 6, 7
.db     0b01111111, 0b01100111      ; 8, 9
.db     0b01110111, 0b01111100      ; A, b
.db     0b00111001, 0b01011110      ; C, d
.db     0b01111001, 0b01110001      ; E, f
.db     0b10000000, 0b00000000      ; ., 

.equ LED7_0     = 0
.equ LED7_1     = 1
.equ LED7_2     = 2
.equ LED7_3     = 3
.equ LED7_4     = 4
.equ LED7_5     = 5
.equ LED7_6     = 6
.equ LED7_7     = 7
.equ LED7_8     = 8
.equ LED7_9     = 9
.equ LED7_A     = 10
.equ LED7_B     = 11
.equ LED7_C     = 12
.equ LED7_D     = 13
.equ LED7_E     = 14
.equ LED7_F     = 15
.equ LED7_DOT   = 16
.equ LED7_EMPTY = 17

; LEDs are on beginning of SPI universe
.set led7_buffer = spi_outbuf + 0

;; Initialize LCD to empty, and enable
LED7_Init:
    ; Setup ENable port
        sbi         LED7_PORT, LED7_OE    ; Disabled (Low)
        sbi         LED7_DDR, LED7_OE     ; Out
    
    ; Initialize buffer
        ldi         r16, 0b01000000
        sts         led7_buffer + 0, r16
        sts         led7_buffer + 1, r16

    ; Update display
        rcall       SPI_SendRecv

    ; Enable output once the initial display has been shifted out
        cbi         LED7_PORT, LED7_OE

    ; Done
        ret

LED7_LoadChar:
        clr         r0, 0

    ; Prep address
        ; base addr for font table
        ldi         ZH, high(2 * LED7_Font)
        ldi         ZL, low(2 * LED7_Font)
        
        ; offset
        add         ZL, r8
        adc         ZH, r0

    ; Load char
        lpm         r8, Z

    ; Done
        ret

;; Display an 8-bit hexadecimal value on the display
;;  Input: r16
LED7_ShowHex:
        ; base16
        ldi         r17, 16 

        ; 1's
        call        div8u
        
        ; r16 = result, r15 = remainder
        mov         r17, r15 

    ; Continue
        rjmp        LED7_Show

;; Display an 8-bit decimal value on the display
;;  Input: r16
LED7_ShowDec:
        ; base10
        ldi         r17, 10

        ; 1's
        call        div8u
        mov         r8, r15

        ; 10's
        call        div8u
        mov         r9, r16         ; 100's
        
        ; 1's from r8
        rcall       LED7_LoadChar
        mov         r17, r8

        ; 10's from r15
        mov         r8, r15
        rcall       LED7_LoadChar
        mov         r16, r8
           
        ; Set dots for 100's 
        sbrc        r9, 0
        ori         r17, 0b10000000 ; +100
        sbrc        r9, 1
        ori         r16, 0b10000000 ; +200

    ; Continue
        rjmp        LED7_ShowRaw

;; Display a single digit on the display
;;  Input: r16, r17
LED7_Show:
        mov         r8, r16
        rcall       LED7_LoadChar
        mov         r16, r8

        mov         r8, r17
        rcall       LED7_LoadChar
        mov         r17, r8
        
    ;; Continue

;; Display a raw segment mask
;;  Input: r16, r17
LED7_ShowRaw:
    ; Store buffer
        sts         led7_buffer + 0, r16
        sts         led7_buffer + 1, r17

    ; Update display
        rjmp        SPI_Update