Files
aqhomecontrol/avr/main.asm
Martin Preuss 84403d07f6 avr: added initial module to handle reed contacts.
Detects and reports opening and closing of a window/door.
Nexts step is to allow for external configuration (e.g. standard mode
with one reed contact versus multi-contact mode to detect tilting of a
window/door).
2023-05-12 21:41:39 +02:00

397 lines
7.9 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. *
; ***************************************************************************
; ***************************************************************************
; data in SRAM
.dseg
#ifdef MODULES_LED
ledA3Sram: .byte LED_SRAM_SIZE
#endif
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; main
;
main:
; setup stack
.ifdef SPH ; if SPH is defined
ldi r16, High(RAMEND)
out SPH, r16 ; init MSB stack pointer
.endif
ldi r16, Low(RAMEND)
out SPL, r16 ; init LSB stack pointer
; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
rcall initModules
rcall Utils_SetupUid
rcall initialWait
sei ; Enable interrupts
rcall onSystemStart
#ifdef MODULES_LED
ldi xl, LOW(blinkPattern) ; debug: set blink pattern
ldi xh, HIGH(blinkPattern)
ldi zl, LOW(ledA3Flash)
ldi zh, HIGH(ledA3Flash)
ldi yl, LOW(ledA3Sram)
ldi yh, HIGH(ledA3Sram)
rcall Led_SetPattern
#endif
; sbi DDRA, PORTA2 ; debug
; sbi PINA, PORTA2 ; debug (toggle)
; cbi PORTA, PORTA2 ; debug (on)
; sbi PORTA, PORTA2 ; debug (off)
; ldi r16, 1
; sts twiMasterScanEnabled, r16
main_loop:
rcall runModulesUntilIdle
sei ; make sure interrupts really are enabled
; only modify SE, SM1 and SM0
in r16, MCUCR
ldi r17, (1<<SE) | (1<<SM1) | (1<<SM0)
neg r17
and r16, r17
ori r16, (1<<SE) ; sleep mode "idle", enable
out MCUCR, r16
sleep ; sleep, wait for interrupt
rjmp main_loop
; ---------------------------------------------------------------------------
; initModules
;
; Call init functions of the used modules. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines
initModules:
rcall Utils_Init
#ifdef MODULES_TIMER
rcall Timer_Init
#endif
#ifdef MODULES_LED
ldi zl, LOW(ledA3Flash)
ldi zh, HIGH(ledA3Flash)
ldi yl, LOW(ledA3Sram)
ldi yh, HIGH(ledA3Sram)
rcall Led_Init
#endif
#ifdef MODULES_COM
rcall Com2_Init ; init COM module
rcall CPRO_Init ; init COM protocol module
#endif
#ifdef MODULES_TWI_MASTER
rcall TWI_Master_Init
#endif
#ifdef MODULES_LCD
rcall LCD_Init
#endif
#ifdef MODULES_BMP280
rcall BMP280_Init
#endif
#ifdef MODULES_SI7021
rcall SI7021_Init
#endif
#ifdef MODULES_STATS
rcall Stats_Init
#endif
#ifdef MODULES_CNY70
rcall CNY70_Init
#endif
#ifdef MODULES_REED
rcall REED_Init
#endif
; done
ret
; ---------------------------------------------------------------------------
; runModulesUntilIdle
;
; Call run functions of the used modules. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines
runModulesUntilIdle:
#ifdef MODULES_TIMER
; TIMER module
rcall Timer_Run
#endif
#ifdef MODULES_COM
; COM module (call until carry flag cleared but at most 10 times to not starve other modules)
ldi r16, 10
runModulesUntilIdle_Com:
push r16
rcall Com2_Run
pop r16
brcc runModulesUntilIdle_ComEnd
dec r16
brne runModulesUntilIdle_Com
runModulesUntilIdle_ComEnd:
#endif
#ifdef MODULES_STATS
rcall Stats_Run
#endif
#ifdef MODULES_REED
rcall REED_Run
#endif
; add more modules here
ret
; ---------------------------------------------------------------------------
; initialWait
;
; Initial wait to desync nodes.
;
; This routine waits for between 10 to 2560 milliseconds (derived from UID)
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: r16, r17, r18, r19, r20, r21, r22, X
initialWait:
; setup initial wait loop
rcall Utils_ReadUid ; (R16, X)
clr r16
eor r16, r18
eor r16, r19
eor r16, r20
eor r16, r21
initialWait_l1: ; wait R16 x 10 milliseconds
ldi r17, 200
initialWait_l2: ; wait for 10ms
Utils_WaitNanoSecs 50000, 0, r22 ; wait for 50 microseconds
dec r17
brne initialWait_l2
dec r16
brne initialWait_l1
ret
#ifdef MODULES_LCD
printTimerMark:
in r15, SREG ; debug
push r15
cli
ldi r18, 1
ldi r19, 1
rcall LCD_SetCursor
lds r16, timerModuleCounterSecs
rcall LCD_PrintHexByte
pop r15
out SREG, r15
ret
printSendStats:
in r15, SREG ; debug
push r15
cli
ldi r18, 0
ldi r19, 2
rcall LCD_SetCursor
ldi zl, LOW(textUid)
ldi zh, HIGH(textUid)
rcall LCD_PrintFromFlash
push xh ; 1-4: UID
push xl
rcall Utils_ReadUid ; (R16, X)
pop xl
pop xh
push r18
push r19
mov r18, r20
mov r19, r21
rcall LCD_PrintHexWord
pop r19
pop r18
rcall LCD_PrintHexWord
ldi r18, 0
ldi r19, 3
rcall LCD_SetCursor
ldi zl, LOW(textAddress)
ldi zh, HIGH(textAddress)
rcall LCD_PrintFromFlash
lds r16, com2Address
rcall LCD_PrintHexByte
ldi r16, 32
rcall LCD_PrintChar
lds r16, cproMode
rcall LCD_PrintHexByte
ldi r16, 32
rcall LCD_PrintChar
lds r16, cproAddrRangeBegin
rcall LCD_PrintHexByte
ldi r18, 0
ldi r19, 4
rcall LCD_SetCursor
ldi zl, LOW(textBitmap)
ldi zh, HIGH(textBitmap)
rcall LCD_PrintFromFlash
lds r16, cproUsedAddresses
rcall LCD_PrintHexByte
lds r16, cproUsedAddresses+1
rcall LCD_PrintHexByte
lds r16, cproUsedAddresses+2
rcall LCD_PrintHexByte
lds r16, cproUsedAddresses+3
rcall LCD_PrintHexByte
#ifdef MODULES_COM
ldi r18, 0
ldi r19, 5
rcall LCD_SetCursor
ldi zl, LOW(textStatsPacketsIn)
ldi zh, HIGH(textStatsPacketsIn)
rcall LCD_PrintFromFlash
lds r18, com2StatsPacketsIn
lds r19, com2StatsPacketsIn+1
rcall LCD_PrintHexWord
ldi r18, 0
ldi r19, 6
rcall LCD_SetCursor
ldi zl, LOW(textStatsPacketsOut)
ldi zh, HIGH(textStatsPacketsOut)
rcall LCD_PrintFromFlash
lds r18, com2StatsPacketsOut
lds r19, com2StatsPacketsOut+1
rcall LCD_PrintHexWord
#endif
pop r15
out SREG, r15
ret
#endif
#ifdef MODULES_SI7021
#ifdef MODULES_COM
#if 0
Main_SendValueMsg:
in r15, SREG
push r15
cli
lds r16, com2Address ; do we have an address assigned?
tst r16
breq sendValueMsg_done ; no, do nothing
; send message for current temp
lds r22, si7021Flags
mov r16, r22
andi r16, SI7021_FLAGS_TEMP_VALID
breq sendValueMsg_checkHum
ldi r16, 0xff ; destination address
ldi r17, VALUE_ID_TEMP1 ; value id
push r22
ldi r22, AQHOME_VALUETYPE_TEMP
lds r18, si7021LastTemp ; value
lds r19, si7021LastTemp+1
ldi r20, 100 ; denominator
clr r21
rcall CPRO_EnqueueValue
pop r22
sendValueMsg_checkHum:
mov r16, r22
andi r16, SI7021_FLAGS_HUM_VALID
breq sendValueMsg_done
ldi r16, 0xff ; destination address
ldi r17, VALUE_ID_HUM1 ; value id
push r22
ldi r22, AQHOME_VALUETYPE_HUMIDITY
lds r18, si7021LastHumidity ; value
lds r19, si7021LastHumidity+1
ldi r20, 1 ; denominator
clr r21
rcall CPRO_EnqueueValue
pop r22
sendValueMsg_done:
pop r15
out SREG, r15
ret
#endif
#ifdef MODULES_LCD
textStatsPacketsIn: .db "In : ", 0
textStatsPacketsRecvErr: .db "RecvErr: ", 0
textStatsPacketsOut: .db "Out : ", 0
textUid: .db "UID : ", 0
textAddress: .db "ADDR :", 0, 0
textBitmap: .db "BITMAP :", 0, 0
#endif
#endif
#endif