Files
aqhomecontrol/avr/main.asm
2023-01-30 01:03:02 +01:00

458 lines
9.1 KiB
NASM

.nolist
.include "include/tn84def.inc" ; Define device ATtiny84
.list
; ***************************************************************************
; defines
; ---------------------------------------------------------------------------
; generic
.equ clock=1000000 ; Define the clock frequency
; ---------------------------------------------------------------------------
; COM module
.equ COM_BIT_LENGTH = 52000 ; 104000=9600, 52000=19200, 26000=38400
.equ COM_DDR_DATA = DDRA
.equ COM_PORT_DATA = PORTA
.equ COM_PIN_DATA = PINA
.equ COM_PINNUM_DATA = PORTA1
.equ COM_DDR_ATTN = DDRA
.equ COM_PORT_ATTN = PORTA
.equ COM_PIN_ATTN = PINA
.equ COM_PINNUM_ATTN = PORTA7
.equ COM_IRQ_ADDR_ATTN = PCMSK0
.equ COM_IRQ_BIT_ATTN = 7 ; bit 7 in PCMSK0
.equ COM_IRQ_GIFR_ATTN = PCIF0
.equ COM_IRQ_GIMSK_ATTN = PCIE0
; ---------------------------------------------------------------------------
; TWI master module
.equ LCD_TWI_ADDRESS = 0x3c
.equ TWI_DDR_SCL = DDRA
.equ TWI_PORT_SCL = PORTA
.equ TWI_PIN_SCL = PINA
.equ TWI_PINNUM_SCL = PORTA4
.equ TWI_DDR_SDA = DDRA
.equ TWI_PORT_SDA = PORTA
.equ TWI_PIN_SDA = PINA
.equ TWI_PINNUM_SDA = PORTA6
; ---------------------------------------------------------------------------
; BMP 280
.equ BMP280_ADDR = 0x76
; ***************************************************************************
; code segment
.cseg
.org 000000
; ---------------------------------------------------------------------------
; Reset and interrupt vectors
rjmp main ; Reset vector
reti ; EXT_INT0
rjmp comIsrPcint0 ; PCI0
reti ; PCI1
reti ; WATCHDOG
reti ; ICP1
reti ; OC1A
reti ; OC1B
reti ; OVF1
rjmp timerIrqOC0A ; OC0A
reti ; OC0B
reti ; OVF0
reti ; ACI
reti ; ADCC
reti ; ERDY
reti ; USI_STR
reti ; USI_OVF
; ***************************************************************************
; includes
.include "utils.asm"
.include "timer.asm"
.include "led.asm"
.include "com.asm"
.include "twimaster.asm"
.include "lcd.asm"
.include "bmp280.asm"
; ***************************************************************************
; data in SRAM
.dseg
ledA3Sram: .byte LED_SRAM_SIZE
; ***************************************************************************
; data in EEPROM
.eseg
; ***************************************************************************
; data in FLASH
.cseg
ledA3Flash: .db DDRA+0x20, PORTA+0x20, PINA+0x20, (1<<PORTA3)
blinkPattern: .db 5, 5, 5, 5, 5, 10, 0xff, 0xff ; 3 short blinks, 1s pause, restart
blinkPattern2: .db 10, 20, 0xff, 0xff ; 1 long blink, 2s pause, restart
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
sei ; Enable interrupts
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
; 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 Timer_Init
ldi zl, LOW(ledA3Flash)
ldi zh, HIGH(ledA3Flash)
ldi yl, LOW(ledA3Sram)
ldi yh, HIGH(ledA3Sram)
rcall Led_Init
rcall Com_Init
rcall TWI_Master_Init
rcall LCD_Init
rcall BMP280_Init
ret
; ---------------------------------------------------------------------------
; runModulesUntilIdle
;
; Call run functions of the used modules. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines
runModulesUntilIdle:
; TIMER module
rcall Timer_Run
; 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:
; add more modules here
ret
; ---------------------------------------------------------------------------
; onEvery100ms
;
; Called every 100ms. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines
onEvery100ms:
; ticker for LED module
ldi zl, LOW(ledA3Flash)
ldi zh, HIGH(ledA3Flash)
ldi yl, LOW(ledA3Sram)
ldi yh, HIGH(ledA3Sram)
rcall Led_Tick
; add more calls here
ret
; ---------------------------------------------------------------------------
; onEverySecond
;
; Called every second. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines
onEverySecond:
; rcall TWI_Master_ScanNext
ret
; ---------------------------------------------------------------------------
; onEvery10s
;
; Called every 10 seconds. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines
onEvery10s:
ret
; ---------------------------------------------------------------------------
; onEveryMinute
;
; Called every minute. Add your routine calls here.
;
; IN:
; - nothing
; OUT:
; - nothing
; USED: depending on called routines
onEveryMinute:
in r15, SREG ; debug
cli
push r15
ldi r16, 219
rcall COM_EnqueueComSendStats
rcall printSendStats
;ldi r16, 219
;rcall COM_EnqueuePing
pop r15
out SREG, r15
ret
; ---------------------------------------------------------------------------
; onPacketReceived:
;
; Called after a packet was received via COM module. Add your routine calls here.
;
; The packet will be removed from buffer in any case after return from this call.
; IN:
; - Y : pointer to received buffer
; OUT:
; - CFLAG: set if handled, cleared otherwise
; USED: depending on called routines
onPacketReceived:
clc ; not handled
ret
debugSendByte:
push r15
in r15, SREG ; debug
cli
push r17
push r22
ldi r17, 8
sbi DDRA, PORTA2 ; debug
cbi PORTA, PORTA2 ; debug (on)
Utils_WaitNanoSecs 100000, 0, r22 ; start with 2t low
sbi PORTA, PORTA2 ; debug (off)
nop
nop
cbi PORTA, PORTA2 ; debug (on)
Utils_WaitNanoSecs 100000, 0, r22 ; start with 2t low
debugSendByte_loop:
lsr r16
brcs debugSendByte_sendLow
cbi PORTA, PORTA2 ; debug (on)
rjmp debugSendByte_wait
debugSendByte_sendLow:
sbi PORTA, PORTA2 ; debug (off)
debugSendByte_wait:
Utils_WaitNanoSecs 100000, 0, r22
dec r17
brne debugSendByte_loop
cbi PORTA, PORTA2 ; debug (on)
Utils_WaitNanoSecs 200000, 0, r22 ; end with 2t low
sbi PORTA, PORTA2 ; debug (off)
pop r22
pop r17
out SREG, r15
pop r15
ret
printSendStats:
push r15
in r15, SREG ; debug
cli
ldi r18, 0
ldi r19, 2
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, 3
rcall LCD_SetCursor
ldi zl, LOW(textStatsPacketsRecvErr)
ldi zh, HIGH(textStatsPacketsRecvErr)
rcall LCD_PrintFromFlash
lds r18, comStatsRecvErrs
lds r19, comStatsRecvErrs+1
rcall LCD_PrintHexWord
ldi r18, 0
ldi r19, 5
rcall LCD_SetCursor
ldi zl, LOW(textStatsPacketsOut)
ldi zh, HIGH(textStatsPacketsOut)
rcall LCD_PrintFromFlash
lds r18, comStatsPacketsOut
lds r19, comStatsPacketsOut+1
rcall LCD_PrintHexWord
ldi r18, 0
ldi r19, 6
rcall LCD_SetCursor
ldi zl, LOW(textStatsCollisions)
ldi zh, HIGH(textStatsCollisions)
rcall LCD_PrintFromFlash
lds r18, comStatsCollisions
lds r19, comStatsCollisions+1
rcall LCD_PrintHexWord
ldi r18, 0
ldi r19, 7
rcall LCD_SetCursor
ldi zl, LOW(textStatsAborted)
ldi zh, HIGH(textStatsAborted)
rcall LCD_PrintFromFlash
lds r18, comStatsAborted
lds r19, comStatsAborted+1
rcall LCD_PrintHexWord
pop r15
out SREG, r15
ret
textStatsPacketsIn: .db "In : ", 0
textStatsPacketsRecvErr: .db "RecvErr: ", 0
textStatsPacketsOut: .db "Out : ", 0
textStatsCollisions: .db "Coll : ", 0
textStatsAborted: .db "Aborted: ", 0