;;
;; 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
; output buffer
.set LED7_COUNT = 2
.dseg
led7_buffer: .byte LED7_COUNT
.cseg
;; 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, 0b11111111
sts led7_buffer + 0, r16
sts led7_buffer + 1, r16
; Output
ldi r16, LED7_COUNT
ldi XL, low(led7_buffer + LED7_COUNT)
ldi XH, high(led7_buffer + LED7_COUNT)
rcall SPI_SendBuf
; 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 a single digit on the display
;; Input: r16, r17
LED7_Show:
mov r8, r16
rcall LED7_LoadChar
mov r16, r8
mov r8, r16
rcall LED7_LoadChar
mov r16, r8
;; Continue
;; Display a raw segment mask
;; Input: r16, r17
LED7_ShowRaw:
; Set buffer
sts led7_buffer + 0, r16
sts led7_buffer + 1, r17
; Output
ldi r16, LED7_COUNT
ldi XL, low(led7_buffer + LED7_COUNT)
ldi XH, high(led7_buffer + LED7_COUNT)
; Display
rjmp SPI_SendBuf