552 lines
13 KiB
NASM
552 lines
13 KiB
NASM
; ***************************************************************************
|
|
; copyright : (C) 2026 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. *
|
|
; ***************************************************************************
|
|
|
|
#ifndef AQH_AVR_GUI2_KEYPAD_ASM
|
|
#define AQH_AVR_GUI2_KEYPAD_ASM
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; defines
|
|
|
|
.equ KEYPAD_OFFS_BEGIN = WIDGET_SIZE
|
|
.equ KEYPAD_OFFS_KEYWIDTH = KEYPAD_OFFS_BEGIN+0
|
|
.equ KEYPAD_OFFS_KEYHEIGHT = KEYPAD_OFFS_BEGIN+1
|
|
.equ KEYPAD_OFFS_KEYHDIST = KEYPAD_OFFS_BEGIN+2
|
|
.equ KEYPAD_OFFS_KEYVDIST = KEYPAD_OFFS_BEGIN+3
|
|
.equ KEYPAD_OFFS_TXTOFFS_X = KEYPAD_OFFS_BEGIN+4
|
|
.equ KEYPAD_OFFS_TXTOFFS_Y = KEYPAD_OFFS_BEGIN+5
|
|
.equ KEYPAD_OFFS_KEYSPERROW = KEYPAD_OFFS_BEGIN+6
|
|
.equ KEYPAD_OFFS_ROWS = KEYPAD_OFFS_BEGIN+7
|
|
.equ KEYPAD_OFFS_KEYS_LO = KEYPAD_OFFS_BEGIN+8
|
|
.equ KEYPAD_OFFS_KEYS_HI = KEYPAD_OFFS_BEGIN+9
|
|
.equ KEYPAD_OFFS_SELECTEDKEY = KEYPAD_OFFS_BEGIN+10
|
|
.equ KEYPAD_SIZE = KEYPAD_OFFS_BEGIN+11
|
|
|
|
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine KeyPad_new @global
|
|
;
|
|
; @return CFLAG set of okay, cleared otherwise
|
|
; @return Y address of newly created object
|
|
; @param X parent widget
|
|
; @param r16 value for OBJECT_OFFS_OPTS
|
|
; @param r17 value for WIDGET_OFFS_PACK
|
|
; @param r20 number of keys per row
|
|
; @param r21 number of rows
|
|
; @param r23:r22 pointer to null-terminated string containing keys
|
|
; @clobbers any
|
|
|
|
KeyPad_new:
|
|
push r20
|
|
push r21
|
|
push r22
|
|
push r23
|
|
ldi r24, LOW(KEYPAD_SIZE)
|
|
ldi r25, HIGH(KEYPAD_SIZE)
|
|
bigcall Object_Alloc ; (!r16, !r17, !X)
|
|
pop r23
|
|
pop r22
|
|
pop r21
|
|
pop r20
|
|
brcc KeyPad_new_ret
|
|
rcall KeyPad_Init
|
|
sec
|
|
KeyPad_new_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine KeyPad_Init @global
|
|
;
|
|
; @param Y address of newly created object
|
|
; @param X parent widget
|
|
; @param r16 value for OBJECT_OFFS_OPTS
|
|
; @param r17 value for WIDGET_OFFS_PACK
|
|
; @param r20 number of keys per row
|
|
; @param r21 number of rows
|
|
; @param r23:r22 pointer to null-terminated string containing keys
|
|
; @clobbers any
|
|
|
|
KeyPad_Init:
|
|
push r20
|
|
push r21
|
|
push r22
|
|
push r23
|
|
; call base class
|
|
bigcall Widget_Init ; (r16, r17, X)
|
|
pop r23
|
|
pop r22
|
|
pop r21
|
|
pop r20
|
|
|
|
std Y+KEYPAD_OFFS_KEYSPERROW, r20
|
|
std Y+KEYPAD_OFFS_ROWS, r21
|
|
std Y+KEYPAD_OFFS_KEYS_LO, r22
|
|
std Y+KEYPAD_OFFS_KEYS_HI, r23
|
|
|
|
; set input and timer opts
|
|
ldd r16, Y+OBJECT_OFFS_OPTS
|
|
sbr r16, (1<<WIDGET_OPTS_INPUT_BIT) | (1<<OBJECT_OPTS_TIMER_BIT)
|
|
std Y+OBJECT_OFFS_OPTS, r16
|
|
|
|
; set default signal map
|
|
ldi r16, LOW(KeyPad_DefaultSignalmap*2)
|
|
std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
|
|
ldi r16, HIGH(KeyPad_DefaultSignalmap*2)
|
|
std Y+OBJECT_OFFS_SIGNALMAP_HI, r16
|
|
|
|
; set default style
|
|
ldi r16, LOW(KeyPad_DefaultStyle*2)
|
|
std Y+WIDGET_OFFS_STYLE_LO, r16
|
|
ldi r16, HIGH(KeyPad_DefaultStyle*2)
|
|
std Y+WIDGET_OFFS_STYLE_HI, r16
|
|
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; signal handlers
|
|
|
|
|
|
KeyPad_OnLayout:
|
|
rcall keyPadLayoutX ; (r16, r18, r19)
|
|
rcall keyPadLayoutY ; (r16, r18, r19)
|
|
|
|
ldd r17, Y+OBJECT_OFFS_FLAGS
|
|
; only clear layout bit
|
|
cbr r17, (1<<WIDGET_FLAGS_LAYOUT_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r17
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
KeyPad_OnGetDefaultWidth:
|
|
rcall keyPadLayoutX ; (r16, r18, r19)
|
|
|
|
ldd r18, Y+KEYPAD_OFFS_KEYHDIST
|
|
ldd r19, Y+KEYPAD_OFFS_KEYSPERROW
|
|
bigcall Utils_Mulu8x8_16 ; R17:R16 = R18 * R19 (r19-r21)
|
|
mov r18, r16
|
|
mov r19, r17
|
|
|
|
rcall keyPadAdjustForBordersAndSpacings
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
KeyPad_OnGetDefaultHeight:
|
|
rcall keyPadLayoutY ; (r16, r18, r19)
|
|
ldd r18, Y+KEYPAD_OFFS_KEYVDIST
|
|
ldd r19, Y+KEYPAD_OFFS_ROWS
|
|
bigcall Utils_Mulu8x8_16 ; R17:R16 = R18 * R19 (r19-r21)
|
|
mov r18, r16
|
|
mov r19, r17
|
|
|
|
rcall keyPadAdjustForBordersAndSpacings
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine KeyPad_OnDraw @global
|
|
;
|
|
; @param Y address of widget
|
|
; @return CFLAG set if signal handled
|
|
; @clobbers any, !Y
|
|
|
|
KeyPad_OnDraw:
|
|
ldd r17, Y+OBJECT_OFFS_FLAGS
|
|
; check whether widget is visible
|
|
sbrs r17, WIDGET_FLAGS_VISIBLE_BIT
|
|
rjmp KeyPad_OnDraw_ret
|
|
; check whether widget is dirty
|
|
sbrs r17, WIDGET_FLAGS_DIRTY_BIT
|
|
rjmp KeyPad_OnDraw_ret
|
|
|
|
; clear widget background
|
|
bigcall Widget_Clear ; (any, !Y)
|
|
|
|
; draw keys
|
|
rcall keyPadDrawKeys ; (any, !Y)
|
|
|
|
ldd r17, Y+OBJECT_OFFS_OPTS
|
|
sbrs r17, WIDGET_OPTS_BORDER_BIT
|
|
rjmp KeyPad_OnDraw_done
|
|
bigcall Widget_DrawBorder
|
|
|
|
KeyPad_OnDraw_done:
|
|
; clear dirty bit
|
|
cbr r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
|
|
std Y+OBJECT_OFFS_FLAGS, r17
|
|
|
|
KeyPad_OnDraw_ret:
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
KeyPad_OnTimer:
|
|
KeyPad_OnTouchBegin:
|
|
KeyPad_OnTouchEnd:
|
|
sec
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine keyPadAdjustForBordersAndSpacings
|
|
;
|
|
; @param Y widget
|
|
; @param r19:r18 size so far (width or height)
|
|
; @return r19:r18 adjusted size
|
|
; @clobbers r16, r17, r20, r21
|
|
|
|
keyPadAdjustForBordersAndSpacings:
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIDGET_OFFS_STYLE_LO
|
|
ldd zh, Y+WIDGET_OFFS_STYLE_HI
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_SPACING
|
|
lpm r16, Z
|
|
pop zh
|
|
pop zl
|
|
clr r17
|
|
sub r18, r16 ; subtract one spacing
|
|
sbc r19, r17
|
|
bigcall Widget_AddOuterStyleBorders ; (r20, r21)
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine keyPadLayoutX
|
|
;
|
|
; @param Y widget
|
|
; @clobbers r16-r23, r25
|
|
|
|
keyPadLayoutX:
|
|
bigcall Widget_GetCharWidth ; r16=width (none)
|
|
clr r19
|
|
mov r18, r16
|
|
lsl r18 ; x2
|
|
rol r19
|
|
add r18, r16 ; x3
|
|
adc r19, r16
|
|
sub r19, r16
|
|
std Y+KEYPAD_OFFS_KEYWIDTH, r18
|
|
std Y+KEYPAD_OFFS_TXTOFFS_X, r16
|
|
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIDGET_OFFS_STYLE_LO
|
|
ldd zh, Y+WIDGET_OFFS_STYLE_HI
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_SPACING
|
|
lpm r16, Z
|
|
pop zh
|
|
pop zl
|
|
add r18, r16
|
|
std Y+KEYPAD_OFFS_KEYHDIST, r18
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine keyPadLayoutY
|
|
;
|
|
; @param Y widget
|
|
; @clobbers r16, r18, r19
|
|
|
|
keyPadLayoutY:
|
|
bigcall Widget_GetCharHeight ; r16=height (none)
|
|
clr r19
|
|
mov r18, r16
|
|
lsl r18 ; x2
|
|
rol r19
|
|
add r18, r16 ; x3
|
|
adc r19, r16
|
|
sub r19, r16
|
|
std Y+KEYPAD_OFFS_KEYHEIGHT, r18
|
|
std Y+KEYPAD_OFFS_TXTOFFS_Y, r16
|
|
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIDGET_OFFS_STYLE_LO
|
|
ldd zh, Y+WIDGET_OFFS_STYLE_HI
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_SPACING
|
|
lpm r16, Z
|
|
pop zh
|
|
pop zl
|
|
add r18, r16
|
|
std Y+KEYPAD_OFFS_KEYVDIST, r18
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
keyPadDrawKeys:
|
|
; get start pos
|
|
ldd zl, Y+WIDGET_OFFS_STYLE_LO
|
|
ldd zh, Y+WIDGET_OFFS_STYLE_HI
|
|
adiw zh:zl, WIDGET_STYLE_OFFS_OUTERBORDERSIZE
|
|
lpm r20, Z
|
|
clr r21
|
|
mov r4, r20 ; X
|
|
clr r5
|
|
mov r6, r20 ; Y
|
|
clr r7
|
|
|
|
; get key contents
|
|
ldd zl, Y+KEYPAD_OFFS_KEYS_LO
|
|
ldd zh, Y+KEYPAD_OFFS_KEYS_HI
|
|
mov r16, zl
|
|
or r16, zh
|
|
breq keyPadDrawKeys_ret
|
|
ldd r16, Y+KEYPAD_OFFS_ROWS
|
|
tst r16
|
|
breq keyPadDrawKeys_ret
|
|
ldd r16, Y+KEYPAD_OFFS_KEYSPERROW
|
|
tst r16
|
|
breq keyPadDrawKeys_ret
|
|
|
|
; draw keys
|
|
ldd r20, Y+KEYPAD_OFFS_ROWS ; row counter
|
|
clr r21 ; key idx
|
|
keyPadDrawKeys_loop1: ; loop for every row
|
|
push r20
|
|
ldd r20, Y+KEYPAD_OFFS_KEYSPERROW ; key counter per row
|
|
push r4 ; X
|
|
push r5
|
|
keyPadDrawKeys_loop2: ; loop for every key in a row
|
|
lpm r16, Z
|
|
tst r16
|
|
breq keyPadDrawKeys_loop2End ; end reached
|
|
cpi r16, 0xff
|
|
breq keyPadDrawKeys_loop2Next ; no key, ignore
|
|
push r4 ; X
|
|
push r5
|
|
push r6 ; Y
|
|
push r7
|
|
push r20 ; key counter per row
|
|
push r21 ; key idx
|
|
rcall keyPadDrawKey
|
|
pop r21
|
|
pop r20
|
|
pop r7
|
|
pop r6
|
|
pop r5
|
|
pop r4
|
|
keyPadDrawKeys_loop2Next:
|
|
ldd r16, Y+KEYPAD_OFFS_KEYHDIST ; increment X
|
|
add r4, r16
|
|
adc r5, r16
|
|
sub r5, r16
|
|
adiw zh:zl, 1
|
|
inc r21
|
|
dec r20
|
|
breq keyPadDrawKeys_loop2End
|
|
rjmp keyPadDrawKeys_loop2
|
|
keyPadDrawKeys_loop2End:
|
|
pop r5
|
|
pop r4
|
|
pop r20
|
|
dec r20
|
|
breq keyPadDrawKeys_loop1End
|
|
ldd r16, Y+KEYPAD_OFFS_KEYVDIST ; increment Y
|
|
add r6, r16
|
|
adc r7, r16
|
|
sub r7, r16
|
|
rjmp keyPadDrawKeys_loop1
|
|
keyPadDrawKeys_loop1End:
|
|
|
|
keyPadDrawKeys_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine keyPadDrawKey
|
|
;
|
|
; @param Y widget
|
|
; @param r5:r4 X
|
|
; @param r7:r6 Y
|
|
; @param r21 key idx
|
|
; @param Z pointer to current key byte
|
|
|
|
keyPadDrawKey:
|
|
; get colors
|
|
mov r16, r21
|
|
rcall keyPadGetColsForKey ; (r17)
|
|
push r4
|
|
push r5
|
|
push r6
|
|
push r7
|
|
push r21
|
|
push zl
|
|
push zh
|
|
ldd r8, Y+KEYPAD_OFFS_KEYWIDTH
|
|
clr r9
|
|
ldd r10, Y+KEYPAD_OFFS_KEYHEIGHT
|
|
clr r11
|
|
mov r2, r0
|
|
mov r3, r1
|
|
bigcall Widget_FillRect
|
|
pop zh
|
|
pop zl
|
|
pop r21
|
|
pop r7
|
|
pop r6
|
|
pop r5
|
|
pop r4
|
|
|
|
; get colors again
|
|
mov r16, r21
|
|
rcall keyPadGetColsForKey ; (r17)
|
|
|
|
push r4
|
|
push r5
|
|
push r6
|
|
push r7
|
|
push r21
|
|
push zl
|
|
push zh
|
|
ldd r8, Y+KEYPAD_OFFS_KEYWIDTH
|
|
clr r9
|
|
ldd r10, Y+KEYPAD_OFFS_KEYHEIGHT
|
|
clr r11
|
|
bigcall Widget_DrawRect
|
|
pop zh
|
|
pop zl
|
|
pop r21
|
|
pop r7
|
|
pop r6
|
|
pop r5
|
|
pop r4
|
|
|
|
; get colors again
|
|
mov r16, r21
|
|
rcall keyPadGetColsForKey ; (r17)
|
|
|
|
; adjust XPos
|
|
clr r17
|
|
ldd r16, Y+KEYPAD_OFFS_TXTOFFS_X
|
|
add r4, r16
|
|
adc r5, r17
|
|
; adjust YPos
|
|
ldd r16, Y+KEYPAD_OFFS_TXTOFFS_Y
|
|
add r6, r16
|
|
adc r7, r17
|
|
lpm r16, Z
|
|
push zl
|
|
push zh
|
|
bigcall Widget_DrawCharAt
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine keyPadGetColsForKey
|
|
;
|
|
; @param Y widget
|
|
; @param r16 key idx (starting at 0)
|
|
; @return r1:r0 background color
|
|
; @return r3:r2 foreground color
|
|
; @clobbers r17
|
|
|
|
keyPadGetColsForKey:
|
|
ldd r17, Y+KEYPAD_OFFS_SELECTEDKEY
|
|
cp r16, r17
|
|
breq keyPadGetColsForKey_activated
|
|
bigcall Widget_GetNormalColors ; (none)
|
|
rjmp keyPadGetColsForKey_ret
|
|
keyPadGetColsForKey_activated:
|
|
bigcall Widget_GetActivatedColors ; (none)
|
|
keyPadGetColsForKey_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; data in FLASH
|
|
|
|
|
|
KeyPad_DefaultStyle:
|
|
.dw DISPLAY_COLOR_BLACK ; frontCol_norm
|
|
.dw DISPLAY_COLOR_LIGHTGREY ; backCol_norm
|
|
.dw DISPLAY_COLOR_BLACK ; borderCol_norm
|
|
.dw DISPLAY_COLOR_WHITE ; shadowCol_norm
|
|
|
|
.dw DISPLAY_COLOR_WHITE ; frontCol_activated
|
|
.dw DISPLAY_COLOR_NAVY ; backCol_activated
|
|
.dw DISPLAY_COLOR_BLACK ; borderCol_activated
|
|
.dw DISPLAY_COLOR_WHITE ; shadowCol_activated
|
|
|
|
.db 4, 8 ; outerBorderSize, innerBorderSize
|
|
.dw ili9341Font12x16_1*2 ; font
|
|
.db 12, 16 ; charWidth, charHeight
|
|
; @end
|
|
|
|
|
|
|
|
KeyPad_DefaultSignalmap:
|
|
; header
|
|
.dw Widget_DefaultSignalmap*2 ; next table to use
|
|
; entries
|
|
.db 0, OBJECT_SIGNAL_TIMER, LOW(KeyPad_OnTimer), HIGH(KeyPad_OnTimer)
|
|
.db 0, WIDGET_SIGNAL_DRAW, LOW(KeyPad_OnDraw), HIGH(KeyPad_OnDraw)
|
|
.db 0, WIDGET_SIGNAL_TOUCH_BEGIN, LOW(KeyPad_OnTouchBegin), HIGH(KeyPad_OnTouchBegin)
|
|
.db 0, WIDGET_SIGNAL_TOUCH_END, LOW(KeyPad_OnTouchEnd), HIGH(KeyPad_OnTouchEnd)
|
|
.db 0, WIDGET_SIGNAL_LAYOUT, LOW(KeyPad_OnLayout), HIGH(KeyPad_OnLayout)
|
|
.db WIDGET_VALUE_DEFAULT_WIDTH, WIDGET_SIGNAL_GETVALUE, LOW(KeyPad_OnGetDefaultWidth), HIGH(KeyPad_OnGetDefaultWidth)
|
|
.db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(KeyPad_OnGetDefaultHeight), HIGH(KeyPad_OnGetDefaultHeight)
|
|
|
|
.db 0, 0, 0, 0 ; end of table
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|