Files
aqhomecontrol/avr/com.asm
2023-01-17 20:56:18 +01:00

235 lines
5.4 KiB
NASM

.equ COM_BIT_LENGTH = 52000 ; 104000=9600, 52000=19200, 26000=38400
.equ COM_DATA_OFFS_ID = 0
.equ COM_DATA_OFFS_FLAGS = 1
.equ COM_DATA_OFFS_ADDR_DDR_DATA = 2
.equ COM_DATA_OFFS_ADDR_PORT_DATA = 3
.equ COM_DATA_OFFS_ADDR_PIN_DATA = 4
.equ COM_DATA_OFFS_PINMASK_DATA = 5
.equ COM_DATA_OFFS_ADDR_DDR_ATTN = 6
.equ COM_DATA_OFFS_ADDR_PORT_ATTN = 7
.equ COM_DATA_OFFS_ADDR_PIN_ATTN = 8
.equ COM_DATA_OFFS_PINMASK_ATTN = 9
.equ COM_DATA_OFFS_IRQNUM_ATTN = 10 ; 0 for PCINT0, 1 for PCINT1
.equ COM_DATA_OFFS_IRQMASK_ATTN = 11 ; e.g. 0x80 for PCINT7 in PCMSK0
.equ COM_DATA_SIZE = 12
.equ COM_BUFFER_FLAGS_DONE = 0x80
.equ COM_BUFFER_FLAGS_RECEIVED = 0x40
; interface data in SRAM
.equ COM_SRAM_OFFS_ID = 0
.equ COM_SRAM_OFFS_FLAGS = 1
.equ COM_SRAM_OFFS_ADDRESS = 2
.equ COM_SRAM_OFFS_MODULE_ID = 3
.equ COM_SRAM_OFFS_SUBNET_START = 4
.equ COM_SRAM_OFFS_SUBNET_END = 5
.equ COM_SRAM_OFFS_DATA_BITMASK = 6
.equ COM_SRAM_OFFS_DATA_INPUT_PORT = 7
.equ COM_SRAM_OFFS_DATA_OUTPUT_PORT = 8
.equ COM_SRAM_OFFS_DATA_DDR_PORT = 9
.equ COM_SRAM_OFFS_ATTN_BITMASK = 10
.equ COM_SRAM_OFFS_ATTN_INPUT_PORT = 11
.equ COM_SRAM_OFFS_ATTN_OUTPUT_PORT = 12
.equ COM_SRAM_OFFS_ATTN_DDR_PORT = 13
.equ COM_SRAM_OFFS_STAT_PACKETS_IN = 14 ; 2 bytes
.equ COM_SRAM_OFFS_STAT_PACKETS_OUT = 16 ; 2 bytes
.equ COM_SRAM_OFFS_STAT_COLLISIONS = 18 ; 2 bytes
.equ COM_SRAM_OFFS_STAT_RECVERR = 20 ; 2 bytes
.equ COM_SRAM_OFFS_STAT_MISSED = 22 ; 2 bytes
.equ COM_SRAM_SIZE = 24
; ***************************************************************************
; macros
; ---------------------------------------------------------------------------
; comSetRamBitInX
;
; Set a given bit in the byte pointed to by X.
; IN:
; - @0: bit mask to check
; - @1: temporary register to use
; OUT:
; - nothing
; MODIFIED REGS: temporary register
; CYCLES: 4
.macro comSetRamBitInX
ld @1, x ; 1
or @1, @0 ; 1
st x, @1 ; 2
.endmacro
; ---------------------------------------------------------------------------
; comClearRamBitInX
;
; Clear a given bit in the byte pointed to by X.
; IN:
; - @0: bit mask to check
; - @1: temporary register to use
; OUT:
; - nothing
; MODIFIED REGS: temporary register
; CYCLES: 6 (CAVE: two cycles more than comSetRamBitInX!)
.macro comClearRamBitInX
ld @1, x ; 1
com @0 ; 1
and @1, @0 ; 1
com @0 ; 1
st x, @1 ; 2
.endmacro
; ---------------------------------------------------------------------------
; comTestRamBitInX
;
; Test a given bit in the byte pointed to by X.
; IN:
; - @0: bit mask to check
; - @1: temporary register to use
; OUT:
; - ZFLAG: set if bit is zero, cleared otherwise
; MODIFIED REGS: temporary register
; CYCLES: 6 (CAVE: two cycles more than comSetRamBitInX!)
.macro comTestRamBitInX
ld @1, x ; 1
and @1, @0 ; 1
.endmacro
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; Com_Init
;
; IN:
; - Y: pointer to SRAM data
; - Z: pointer to FLASH data
; OUT:
; - CFLAG: set if okay, clear on error
; USED:
Com_Init:
mov xh, yh
mov xl, yl
clr r16
ldi r17, COM_SRAM_SIZE
rcall Utils_FillSram
; copy data from flash to sram
push zh
push zl
lsl zl
rol zh
lpm r16, z+ ; id
std y+COM_SRAM_OFFS_ID, r16
lpm r16, z+ ; flags
std y+COM_SRAM_OFFS_FLAGS, r16
lpm r16, z+ ; ADDR_DDR_DATA
std y+COM_SRAM_OFFS_DATA_DDR_PORT, r16
lpm r16, z+ ; ADDR_PORT_DATA
std y+COM_SRAM_OFFS_DATA_OUTPUT_PORT, r16
lpm r16, z+ ; ADDR_PIN_DATA
std y+COM_SRAM_OFFS_DATA_INPUT_PORT, r16
lpm r16, z+ ; PINMASK_DATA
std y+COM_SRAM_OFFS_DATA_INPUT_PORT, r16
lpm r16, z+ ; ADDR_DDR_ATTN
std y+COM_SRAM_OFFS_ATTN_DDR_PORT, r16
lpm r16, z+ ; ADDR_PORT_ATTN
std y+COM_SRAM_OFFS_ATTN_OUTPUT_PORT, r16
lpm r16, z+ ; ADDR_PIN_ATTN
std y+COM_SRAM_OFFS_ATTN_INPUT_PORT, r16
lpm r16, z+ ; PINMASK_ATTN
std y+COM_SRAM_OFFS_ATTN_INPUT_PORT, r16
lpm r17, z+ ; IRQNUM_ATTN
lpm r18, z+ ; COM_DATA_OFFS_IRQMASK_ATTN
pop zl
pop zh
; set DATA port as input
clr xh
ldd xl, y+COM_SRAM_OFFS_DATA_DDR_PORT
ldd r4, y+COM_SRAM_OFFS_DATA_BITMASK
comClearRamBitInX r4, r16
; disable internal pullup for DATA
ldd xl, y+COM_SRAM_OFFS_DATA_OUTPUT_PORT
comClearRamBitInX r4, r16
; set ATTN as input
ldd xl, y+COM_SRAM_OFFS_ATTN_DDR_PORT
ldd r4, y+COM_SRAM_OFFS_ATTN_BITMASK
comClearRamBitInX r4, r16
; disable internal pullup for DATA
ldd xl, y+COM_SRAM_OFFS_ATTN_OUTPUT_PORT
comClearRamBitInX r4, r16
; setup pin IRQ for ATTN (intnum in r17, irqmask in r18)
tst r17
brne Com_Init_setupInt1
Com_Init_setupInt0:
; enable PCIE0
in r16, GIMSK
ori r16, (1 << PCIE0)
out GIMSK, r16
; clear pending interrupts
in r16, GIFR
andi r16, ~(1 << PCIF0)
out GIFR, r16
ldi xl, PCMSK0+0x20
rjmp Com_Init_enablePinIrq
Com_Init_setupInt1:
; enable PCIE1
in r16, GIMSK
ori r16, (1 << PCIE1)
out GIMSK, r16
; clear pending interrupts
in r16, GIFR
andi r16, ~(1 << PCIF1)
out GIFR, r16
ldi xl, PCMSK1+0x20
Com_Init_enablePinIrq:
ld r16, x
or r16, r18 ; set mask bits
st x, r16
sec
ret