;;
;; 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