334 lines
6.8 KiB
NASM
334 lines
6.8 KiB
NASM
; ***************************************************************************
|
|
; copyright : (C) 2023 by Martin Preuss
|
|
; email : martin@libchipcard.de
|
|
;
|
|
; ***************************************************************************
|
|
; * This file is part of the project "AqHome". *
|
|
; * Please see toplevel file COPYING of that project for license details. *
|
|
; ***************************************************************************
|
|
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; defs
|
|
|
|
.equ LED_DATA_OFFS_ADDRDDR = 0
|
|
.equ LED_DATA_OFFS_ADDRPORT = 1
|
|
.equ LED_DATA_OFFS_ADDRPIN = 2
|
|
.equ LED_DATA_OFFS_PINMASK = 3
|
|
|
|
|
|
.equ LED_SRAM_OFFS_PATTERNADDR = 0
|
|
.equ LED_SRAM_OFFS_COUNTER = 2
|
|
.equ LED_SRAM_OFFS_POS = 3
|
|
.equ LED_SRAM_SIZE = 4
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; data
|
|
|
|
.dseg
|
|
|
|
ledA3Sram: .byte LED_SRAM_SIZE
|
|
|
|
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
LED_BEGIN:
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; Led_Init
|
|
;
|
|
; IN:
|
|
; - Y: pointer to SRAM data
|
|
; - Z: pointer to FLASH data
|
|
; OUT:
|
|
; - CFLAG: set if okay, clear on error
|
|
; USED: R1, R2, R3, R4, R16, R17, X
|
|
|
|
Led_Init:
|
|
mov xh, yh
|
|
mov xl, yl
|
|
clr r16
|
|
ldi r17, LED_SRAM_SIZE
|
|
rcall Utils_FillSram
|
|
|
|
rcall ledGetFlashDataIntoRegs
|
|
brcc Led_Init_end
|
|
|
|
; set bit in DDR register (-> output)
|
|
mov xl, r1 ; DDR register address
|
|
clr xh
|
|
ld r16, x
|
|
or r16, r4 ; output
|
|
st x, r16
|
|
|
|
; turn off led
|
|
rcall ledOff
|
|
sec
|
|
Led_Init_end:
|
|
ret
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; Led_SetPattern
|
|
;
|
|
; IN:
|
|
; - X: pointer to led pattern in flash
|
|
; - Y: pointer to SRAM data
|
|
; - Z: pointer to FLASH data
|
|
; OUT:
|
|
; - CFLAG: set if okay, clear on error
|
|
; USED: R1, R2, R3, R4, R16, R17, Z
|
|
|
|
Led_SetPattern:
|
|
rcall ledGetFlashDataIntoRegs
|
|
brcc Led_SetPattern_l2
|
|
|
|
std y+LED_SRAM_OFFS_PATTERNADDR, xl ; param 1
|
|
std y+LED_SRAM_OFFS_PATTERNADDR+1, xh ; param 2
|
|
|
|
; reset pos in pattern
|
|
clr r19
|
|
std y+LED_SRAM_OFFS_POS, r19
|
|
|
|
; store counter for current pattern element
|
|
mov zl, xl
|
|
mov zh, xh
|
|
lsl zl ; multiplay Z by 2
|
|
rol zh
|
|
lpm r19, z ; read current pattern counter
|
|
std y+LED_SRAM_OFFS_COUNTER, r19
|
|
|
|
; each pattern starts with LED on
|
|
rcall ledOn
|
|
|
|
Led_SetPattern_l2:
|
|
ret
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; Led_Tick
|
|
;
|
|
; IN:
|
|
; - Y: pointer to SRAM data
|
|
; - Z: pointer to FLASH data
|
|
; OUT:
|
|
; - CFLAG: set if something done, reset otherwise
|
|
; USED:
|
|
|
|
Led_Tick:
|
|
rcall ledGetFlashDataIntoRegs
|
|
brcs Led_Tick_l1
|
|
ret
|
|
|
|
Led_Tick_l1:
|
|
ldd zl, y+LED_SRAM_OFFS_PATTERNADDR
|
|
ldd zh, y+LED_SRAM_OFFS_PATTERNADDR+1
|
|
ldd r18, y+LED_SRAM_OFFS_POS
|
|
ldd r19, y+LED_SRAM_OFFS_COUNTER
|
|
|
|
; test NULL ptr
|
|
mov r16, zl;
|
|
or r16, zh
|
|
breq Led_Tick_end ; no current pattern, end
|
|
|
|
cpi r19, 2 ; current counter less than 2?
|
|
brcs Led_Tick_nextPhase
|
|
|
|
dec r19
|
|
std y+LED_SRAM_OFFS_COUNTER, r19
|
|
ret
|
|
|
|
Led_Tick_nextPhase:
|
|
lsl zl ; multiplay Z by 2
|
|
rol zh
|
|
inc r18 ; next pos
|
|
rcall Led_Tick_getPattern
|
|
cpi r16, 0xff
|
|
breq Led_Tick_restart
|
|
cpi r16, 0
|
|
breq Led_Tick_stop
|
|
|
|
std y+LED_SRAM_OFFS_POS, r18
|
|
std y+LED_SRAM_OFFS_COUNTER, r16
|
|
|
|
mov r17, r18
|
|
andi r17, 1 ; even?
|
|
breq Led_Tick_switchOn
|
|
rjmp ledOff
|
|
|
|
Led_Tick_switchOn:
|
|
; turn on led
|
|
rjmp ledOn
|
|
|
|
|
|
Led_Tick_stop:
|
|
clr r16
|
|
std y+LED_SRAM_OFFS_PATTERNADDR, r16
|
|
std y+LED_SRAM_OFFS_PATTERNADDR+1, r16
|
|
std y+LED_SRAM_OFFS_COUNTER, r16
|
|
std y+LED_SRAM_OFFS_POS, r16
|
|
|
|
; LED off
|
|
rcall ledOff
|
|
|
|
|
|
Led_Tick_restart:
|
|
ldi r18, 0
|
|
rcall Led_Tick_getPattern
|
|
cpi r16, 0xff
|
|
breq Led_Tick_stop ; stop, because restart as first pattern is invalid
|
|
cpi r16, 0
|
|
breq Led_Tick_stop
|
|
std y+LED_SRAM_OFFS_POS, r18 ; incremented pos in pattern
|
|
std y+LED_SRAM_OFFS_COUNTER, r16 ; new counter value
|
|
|
|
rcall ledOn
|
|
ret
|
|
|
|
|
|
Led_Tick_getPattern: ; r18=pos
|
|
ldd zl, y+LED_SRAM_OFFS_PATTERNADDR
|
|
ldd zh, y+LED_SRAM_OFFS_PATTERNADDR+1
|
|
lsl zl ; multiplay Z by 2
|
|
rol zh
|
|
|
|
ldi r16, 0
|
|
add zl, r18
|
|
adc zh, r16
|
|
lpm r16, z
|
|
ret
|
|
|
|
Led_Tick_end:
|
|
ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; ledGetFlashDataIntoRegs
|
|
;
|
|
; IN:
|
|
; - R28/ZL: pointer to data in flash (low)
|
|
; - R29/ZH: pointer to data in flash (hi)
|
|
; OUT:
|
|
; - CARRY flag set if okay, clear on error
|
|
; - R1: memory address of DDR register
|
|
; - R2: memory address of PORT register
|
|
; - R3: memory address of PIN register
|
|
; - R4: mask for used pin
|
|
; USED: R16
|
|
|
|
ledGetFlashDataIntoRegs:
|
|
push zh
|
|
push zl
|
|
mov r16, zl
|
|
or r16, zh
|
|
breq ledGetFlashDataIntoRegs_error
|
|
lsl zl
|
|
rol zh
|
|
lpm r1, z+ ; DDR
|
|
lpm r2, z+ ; PORTR
|
|
lpm r3, z+ ; PINR
|
|
lpm r4, z ; pin mask
|
|
pop zl
|
|
pop zh
|
|
sec
|
|
ret
|
|
|
|
ledGetFlashDataIntoRegs_error:
|
|
pop zl
|
|
pop zh
|
|
clc
|
|
ret
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; ledOff
|
|
;
|
|
; IN:
|
|
; - R2: port register address (low part only)
|
|
; - R4: bit mask for pin to use
|
|
; OUT:
|
|
; - nothing
|
|
; MODIFIED REGS: none
|
|
; CYCLES: 26 (if R2 and R4 valid)
|
|
|
|
ledOff:
|
|
tst r2 ; 1
|
|
breq ledOff_end ; 1 if not taken
|
|
tst r4 ; 1
|
|
breq ledOff_end ; 1 if not taken
|
|
push xh ; 2
|
|
push xl ; 2
|
|
push r16 ; 2
|
|
mov xl, r2 ; 1 PORT register address
|
|
clr xh ; 1
|
|
ld r16, x ; 1
|
|
or r16, r4 ; 1
|
|
st x, r16 ; 2
|
|
pop r16 ; 2
|
|
pop xl ; 2
|
|
pop xh ; 2
|
|
ledOff_end:
|
|
ret ; 4
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; ledOn
|
|
;
|
|
; IN:
|
|
; - R2: port register address (low part only)
|
|
; - R4: bit mask for pin to use
|
|
; OUT:
|
|
; - nothing
|
|
; MODIFIED REGS: none
|
|
; CYCLES: 28
|
|
|
|
ledOn: ; clock cycles
|
|
tst r2 ; 1
|
|
breq ledOn_end ; 1 if not taken
|
|
tst r4 ; 1
|
|
breq ledOn_end ; 1 if not taken
|
|
|
|
push xh ; 2
|
|
push xl ; 2
|
|
push r16 ; 2
|
|
mov xl, r2 ; 1 PORT register address
|
|
clr xh ; 1
|
|
ld r16, x ; 1
|
|
com r4 ; 1 invert bit mask for following AND
|
|
and r16, r4 ; 1
|
|
com r4 ; 1 undo inversion
|
|
st x, r16 ; 2
|
|
pop r16 ; 2
|
|
pop xl ; 2
|
|
pop xh ; 2
|
|
ledOn_end:
|
|
ret ; 4
|
|
|
|
|
|
|
|
LED_END:
|
|
.equ MODULE_SIZE_LED = LED_END-LED_BEGIN
|
|
|
|
|
|
|