Files
aqhomecontrol/avr/main.asm

326 lines
6.6 KiB
NASM

.cseg
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 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
; ldi r16, 1
; sts twiMasterScanEnabled, r16
main_loop:
rcall runModulesUntilIdle
; sbi DDRA, PORTA2 ; debug
; sbi PINA, PORTA2 ; debug (toggle)
; cbi PORTA, PORTA2 ; debug (on)
; sbi PORTA, PORTA2 ; debug (off)
; 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 Com_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
; 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 Com_Run
pop r16
brcc runModulesUntilIdle_ComEnd
dec r16
brne runModulesUntilIdle_Com
runModulesUntilIdle_ComEnd:
#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
printSendStats:
push r15
in r15, SREG ; debug
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, comAddress
rcall LCD_PrintHexByte
ldi r16, 32
rcall LCD_PrintChar
lds r16, cproMode
rcall LCD_PrintHexByte
lds r16, cproAddressWaitCounter
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, comStatsPacketsIn
lds r19, comStatsPacketsIn+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, comStatsPacketsOut
lds r19, comStatsPacketsOut+1
rcall LCD_PrintHexWord
#endif
pop r15
out SREG, r15
ret
#endif
#ifdef MODULES_SI7021
#ifdef MODULES_COM
Main_SendValueMsg:
in r15, SREG
push r15
cli
lds r16, comAddress ; 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
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