Added and simplified COM module.
Directly use pins, no complicated redirections. Router modules will probably use real UARTs or MCUs programmed as UARTs.
This commit is contained in:
508
avr/com.asm
508
avr/com.asm
@@ -1,121 +1,34 @@
|
||||
|
||||
|
||||
|
||||
.equ COM_BIT_LENGTH = 52000 ; 104000=9600, 52000=19200, 26000=38400
|
||||
; ***************************************************************************
|
||||
; defines
|
||||
|
||||
.equ COM_MAXWAIT = 200 ; maximum loop count when waiting for rising/falling clock (TODO: Make frequency-dependant)
|
||||
|
||||
.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
|
||||
; data
|
||||
|
||||
.dseg
|
||||
|
||||
|
||||
comDataBegin:
|
||||
comFlags: .byte 1
|
||||
comAddress: .byte 1
|
||||
comStatsPacketsIn: .byte 2
|
||||
comStatsPacketsOut: .byte 2
|
||||
comStatsRecvErrs: .byte 2
|
||||
comStatsCollisions: .byte 2
|
||||
comStatsMissed: .byte 2
|
||||
comRingBuffer: .byte RINGBUFFER_OFFS_DATA+COM_RINGBUFFER_SIZE
|
||||
comDataEnd:
|
||||
|
||||
|
||||
|
||||
@@ -130,105 +43,332 @@
|
||||
; 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
|
||||
; preset SRAM data area
|
||||
ldi xh, HIGH(comDataBegin)
|
||||
ldi xl, LOW(comDataBegin)
|
||||
clr r16
|
||||
ldi r17, COM_SRAM_SIZE
|
||||
ldi r17, (comDataEnd-comDataBegin)
|
||||
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
|
||||
; init ringbuffer
|
||||
ldi r16, COM_RINGBUFFER_SIZE
|
||||
ldi yl, LOW(comRingBuffer)
|
||||
ldi yh, HIGH(comRingBuffer)
|
||||
rcall RingBuffer_Init
|
||||
|
||||
; 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
|
||||
; setup pins and interrupts
|
||||
sbi COM_DDR_DATA, COM_PINNUM_DATA ; set DATA port as input
|
||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; disable internal pullup for DATA
|
||||
|
||||
; 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
|
||||
sbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN port as input
|
||||
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; disable internal pullup for ATTN
|
||||
|
||||
sbi COM_IRQ_ADDR_ATTN, COM_IRQ_BIT_ATTN ; enable pin change irq for ATTN line
|
||||
in r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
||||
ori r16, (1<<COM_IRQ_GIMSK_ATTN)
|
||||
out GIMSK, R16
|
||||
in r16, GIFR ; clear pending irq
|
||||
andi r16, ~(1<<COM_IRQ_GIFR_ATTN)
|
||||
out GIFR, 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
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comSendPacket
|
||||
;
|
||||
; Send a packet. (TODO: input buffer in x, length in r16)
|
||||
;
|
||||
; IN:
|
||||
; - R18: pos pointer inside ring buffer to read from next
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R10, R11, R12, R16, R20 (R3, R21, R22)
|
||||
|
||||
comSendPacket:
|
||||
ldi yl, LOW(comRingBuffer)
|
||||
ldi yh, HIGH(comRingBuffer)
|
||||
ldd r19, y+RINGBUFFER_OFFS_MAXSIZE
|
||||
rcall RingBuffer_Read ; read entry length from buffer (advances r18) (R3, R22)
|
||||
cpi r16, 3 ; at least 3 bytes?
|
||||
brcs comSendPacket_error ; too few bytes
|
||||
mov r10, r16 ; r10: number of bytes at current ringbuffer pos
|
||||
dec r10
|
||||
dec r10
|
||||
dec r10 ; r10: number of bytes in message
|
||||
clr r11 ; r11: XOR checksum
|
||||
mov r20, r18 ; store pos of flags in buffer for later ref
|
||||
rcall RingBuffer_Read ; read flags from buffer
|
||||
mov r12, r16 ; r12: flags
|
||||
rcall RingBuffer_Read ; read dest address from buffer
|
||||
eor r11, r16 ; calculate checksum
|
||||
rcall comSendByte ; send destination address (R16, R21, R22)
|
||||
brcc comSendPacket_error
|
||||
mov r16, r10 ; send msg length
|
||||
eor r11, r16 ; calculate checksum
|
||||
rcall comSendByte ; send destination address
|
||||
brcc comSendPacket_error
|
||||
tst r10 ; payload?
|
||||
breq comSendPacket_sendCrc ; no payload, go send checksum
|
||||
comSendPacket_loop:
|
||||
rcall RingBuffer_Read ; read byte from buffer
|
||||
eor r11, r16 ; calculate checksum
|
||||
rcall comSendByte ; send byte
|
||||
brcc comSendPacket_error
|
||||
dec r10
|
||||
brne comSendPacket_loop
|
||||
comSendPacket_sendCrc:
|
||||
mov r16, r10 ; send checksum
|
||||
rcall comSendByte ; send byte
|
||||
brcc comSendPacket_error
|
||||
mov r18, r20 ; pos of flags byte in ringbuffer
|
||||
mov r16, r12
|
||||
ori r16, COM_BUFFER_FLAGS_DONE ; set flag
|
||||
rcall RingBuffer_Write ; write new flags (R3, R22)
|
||||
sec
|
||||
ret
|
||||
|
||||
comSendPacket_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comReceivePacket
|
||||
;
|
||||
; Receive a packet. If we are the recipient of the packet then space will be allocated inside the
|
||||
; given ringbuffer and the received packet will be stored there.
|
||||
;
|
||||
; Packages are stored in the buffer like this:
|
||||
; - 1 byte : buffer size
|
||||
; - 1 byte: flags (e.g. WAN_BUFFER_RECEIVED)
|
||||
; - 1 byte : destination address
|
||||
; - n bytes: packet (i.e. buffer size -2 bytes)
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R1, R2, R3, R16, R17, R18, R19 (R20, R21, R22, XL, XH)
|
||||
|
||||
comReceivePacket:
|
||||
ldi yl, LOW(comRingBuffer)
|
||||
ldi yh, HIGH(comRingBuffer)
|
||||
clr r1 ; r1: checksum
|
||||
; read destination address
|
||||
rcall comReceiveByte ; read byte
|
||||
brcc comReceivePacket_error
|
||||
; compare destination address (accept "0" and own address)
|
||||
tst r16
|
||||
breq comReceivePacket_acceptAddr
|
||||
lds r17, comAddress
|
||||
cp r16, r17
|
||||
breq comReceivePacket_acceptAddr
|
||||
clc ; not for me
|
||||
ret
|
||||
comReceivePacket_acceptAddr:
|
||||
mov r3, r16 ; r3: destination address (maybe we need to forward the packet)
|
||||
eor r1, r16
|
||||
rcall comReceiveByte ; read packet length (R16, R17, R20, R21, R22)
|
||||
brcc comReceivePacket_error
|
||||
; alloc ring buffer
|
||||
mov r17, r16 ; r17: packet length
|
||||
inc r16 ; packet length bytes + length byte
|
||||
inc r16 ; + flags
|
||||
inc r16 ; + dest addr
|
||||
mov r2, r16 ; r2: number of bytes allocated in ringbuffer
|
||||
push r17
|
||||
rcall RingBuffer_Alloc ; (r16, r17, r18, r19, r20, r21)
|
||||
pop r17
|
||||
brcc comReceivePacket_error
|
||||
mov r18, r16 ; r18: pos in ring buffer
|
||||
ldd r19, y+RINGBUFFER_OFFS_MAXSIZE ; max size
|
||||
mov r16, r2 ; write number of bytes allocated to ringbuffer
|
||||
ori r16, COM_BUFFER_FLAGS_RECEIVED
|
||||
rcall RingBuffer_Write ; (r3, r22)
|
||||
ldi r16, COM_BUFFER_FLAGS_RECEIVED ; write flags to ringbuffer
|
||||
rcall RingBuffer_Write ; (r3, r22)
|
||||
mov r16, r3 ; write destination address for packet we saved earlier
|
||||
rcall RingBuffer_Write ; (r3, r22)
|
||||
; read packet (except XOR byte, that will be read later)
|
||||
comReceivePacket_loop1:
|
||||
rcall comReceiveByte ; (R16, R17, R20, R21, R22)
|
||||
brcc comReceivePacket_error_release_buffer
|
||||
eor r1, r16
|
||||
rcall RingBuffer_Write ; (r3, r22)
|
||||
dec r17
|
||||
brne comReceivePacket_loop1
|
||||
; read XOR byte, don't store
|
||||
rcall comReceiveByte ; (R16, R17, R20, R21, R22)
|
||||
brcc comReceivePacket_error
|
||||
eor r1, r16
|
||||
brne comReceivePacket_error_release_buffer ; XOR should be 0 here, otherwise error
|
||||
sec
|
||||
ret
|
||||
comReceivePacket_error_release_buffer:
|
||||
mov r16, r2 ; number of bytes allocated in ringbuffer
|
||||
rcall RingBuffer_DeallocWrite ; (r17, r18, r19, r20, r21)
|
||||
comReceivePacket_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comSendByte
|
||||
;
|
||||
; Send a byte.
|
||||
; We only set the data pin to low at the beginning for the startbit. After that
|
||||
; we only change the pin direction (e.g. input vs output):
|
||||
; - for 0 bit: set DDR to output, forcing the data line low
|
||||
; - for 1 bit: set DDR to input, letting the external pullup R pull the data line to HIGH
|
||||
; since the output pin is still set to 0 the internal pullup is disabled
|
||||
; IN:
|
||||
; - R16: byte to send
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R21, R22
|
||||
|
||||
comSendByte:
|
||||
ldi r21, 8 ; +1 bits left
|
||||
; send startbit
|
||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; +2 set DATA low
|
||||
sbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as output
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 5, r22 ; wait for on bit duration
|
||||
; send remaining bits
|
||||
comSendByte_loop:
|
||||
lsr r16 ; 1+ bit to send -> CARRY
|
||||
brcc comSendByte_setHigh ; HI: +2, LO: +1
|
||||
comSendByte_setLow:
|
||||
sbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as output
|
||||
nop
|
||||
rjmp comSendByte_waitBit ; +2
|
||||
comSendByte_setHigh:
|
||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as input, pullup R makes it ONE
|
||||
nop ; +1 (to make pin change available)
|
||||
sbic COM_PIN_DATA, (1<<COM_PINNUM_DATA) ; +1 if okay, +2 otherwise
|
||||
rjmp comSendByte_error ; +2 if error
|
||||
comSendByte_waitBit: ; 7 cycles in this loop until now
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 10, r22
|
||||
dec r21 ; +1
|
||||
brne comSendByte_loop ; +2, sum per loop: 10 cycles
|
||||
; send stopbit
|
||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as input, pullup R makes it ONE
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 4, r22
|
||||
sec
|
||||
ret
|
||||
|
||||
comSendByte_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comReceiveByte
|
||||
;
|
||||
; Receive a byte.
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; - R16: byte read (if CFLAG set)
|
||||
; MODIFIED REGS: R16, R20, R21, R22 (R17)
|
||||
|
||||
comReceiveByte:
|
||||
sbi COM_DDR_DATA, COM_PINNUM_DATA ; set DATA port as input
|
||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; disable internal pullup for DATA
|
||||
ldi r21, 8 ; bits left
|
||||
clr r20 ; byte currently receiving
|
||||
; wait for startbit
|
||||
rcall comWaitForDataLow
|
||||
brcc comReceiveByte_error
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH/2, 5, r22 ; goto middle of startbit to maximize sync stability
|
||||
comReceiveByte_loop:
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 8, r22 ; 8 cycles used in the complete loop between waits
|
||||
sec ; +1
|
||||
sbic COM_PIN_DATA, COM_PINNUM_DATA ; LOW: +2, HIGH: +1
|
||||
rjmp comReceiveByte_shiftIn ; HIGH: +2, rjmp, use set CFLAG
|
||||
clc ; LOW: +1
|
||||
comReceiveByte_shiftIn:
|
||||
ror r20 ; +1
|
||||
dec r21 ; +1
|
||||
brne comReceiveByte_loop ; +2, sum per loop: 8 cycles
|
||||
rcall comWaitForDataHigh ; wait for start of stopbit
|
||||
; brcc comReceiveByte_error
|
||||
mov r16, r20
|
||||
sec
|
||||
ret
|
||||
comReceiveByte_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comWaitForDataLow
|
||||
;
|
||||
; Waits up to COM_MAXWAIT loops for low data line
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r17, r22, X
|
||||
|
||||
comWaitForDataLow:
|
||||
ldi r17, COM_MAXWAIT
|
||||
|
||||
comWaitForDataLow_loop:
|
||||
sbis COM_PIN_DATA, COM_PINNUM_DATA
|
||||
rjmp comWaitForDataLow_done
|
||||
dec r17
|
||||
brne comWaitForDataLow_loop
|
||||
clc ; timeout
|
||||
ret
|
||||
|
||||
comWaitForDataLow_done:
|
||||
sec ; ok
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comWaitForDataHigh
|
||||
;
|
||||
; Waits up to COM_MAXWAIT loops for high data line
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r17, r22, X
|
||||
|
||||
comWaitForDataHigh:
|
||||
ldi r17, COM_MAXWAIT
|
||||
|
||||
comWaitForDataHigh_loop:
|
||||
sbic COM_PIN_DATA, COM_PINNUM_DATA
|
||||
rjmp comWaitForDataHigh_done
|
||||
dec r17
|
||||
brne comWaitForDataHigh_loop
|
||||
clc ; timeout
|
||||
ret
|
||||
|
||||
comWaitForDataHigh_done:
|
||||
sec ; ok
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
58
avr/main.asm
58
avr/main.asm
@@ -7,24 +7,35 @@
|
||||
; ***************************************************************************
|
||||
; defines
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; generic
|
||||
|
||||
.equ clock=1000000 ; Define the clock frequency
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; COM module
|
||||
|
||||
.equ COM_DDR_DATA DDRA
|
||||
.equ COM_PORT_DATA PORTA
|
||||
.equ COM_PIN_DATA PINA
|
||||
.equ COM_PINMASK_DATA (1<<PORTA1)
|
||||
.equ COM_PINNUM_DATA PORTA1
|
||||
.equ COM_BIT_LENGTH = 52000 ; 104000=9600, 52000=19200, 26000=38400
|
||||
|
||||
.equ COM_DDR_ATTN DDRA
|
||||
.equ COM_PORT_ATTN PORTA
|
||||
.equ COM_PIN_ATTN PINA
|
||||
.equ COM_PINMASK_ATTN (1<<PORTA7)
|
||||
.equ COM_PINNUM_ATTN PORTA7
|
||||
.equ COM_RINGBUFFER_SIZE = 32 ; 32 bytes for now
|
||||
|
||||
.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
|
||||
|
||||
.equ COM_IRQ_ADDR_ATTN PCMSK0
|
||||
.equ COM_IRQ_MASK_ATTN (1<<7) ; bit 7 in PCMSK0
|
||||
.equ COM_IRQ_GIFR_ATTN (1 << PCIF0)
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +45,9 @@
|
||||
.cseg
|
||||
.org 000000
|
||||
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Reset and interrupt vectors
|
||||
|
||||
rjmp main ; Reset vector
|
||||
@@ -60,11 +73,11 @@
|
||||
; ***************************************************************************
|
||||
; includes
|
||||
|
||||
.include "utils.asm"
|
||||
.include "ringbuffer.asm"
|
||||
.include "timer.asm"
|
||||
.include "led.asm"
|
||||
.include "com.asm"
|
||||
.include "utils.asm"
|
||||
|
||||
|
||||
|
||||
@@ -74,7 +87,6 @@
|
||||
.dseg
|
||||
|
||||
ledA3Sram: .byte LED_SRAM_SIZE
|
||||
wanA7A1Sram: .byte COM_SRAM_SIZE
|
||||
|
||||
|
||||
|
||||
@@ -83,11 +95,7 @@ wanA7A1Sram: .byte COM_SRAM_SIZE
|
||||
|
||||
.cseg
|
||||
|
||||
ledA3Flash: .db DDRA+0x20, PORTA+0x20, PINA+0x20, (1<<PORTA3)
|
||||
comA7A1Flash: .db 1, 0 ; id, flags
|
||||
.db DDRA+0x20, PORTA+0x20, PINA+0x20, (1<<PORTA1) ; port info for DATA line
|
||||
.db DDRA+0x20, PORTA+0x20, PINA+0x20, (1<<PORTA7) ; port info for ATTN line
|
||||
.db 0, 0x80 ; ATTN: PCINT irq type, irq mask (e.g. for PCMSK0)
|
||||
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
|
||||
|
||||
|
||||
@@ -134,7 +142,7 @@ main_loop:
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; ---------------------------------------------------------------------------
|
||||
; initModules
|
||||
;
|
||||
; Call init functions of the used modules. Add your routine calls here.
|
||||
@@ -157,7 +165,7 @@ initModules:
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; ---------------------------------------------------------------------------
|
||||
; runModulesUntilIdle
|
||||
;
|
||||
; Call run functions of the used modules. Add your routine calls here.
|
||||
@@ -178,7 +186,7 @@ runModulesUntilIdle_Timer: ; repeat this block for every run function
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; ---------------------------------------------------------------------------
|
||||
; onEvery100ms
|
||||
;
|
||||
; Called every 100ms. Add your routine calls here.
|
||||
@@ -203,7 +211,7 @@ onEvery100ms:
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; ---------------------------------------------------------------------------
|
||||
; onEverySecond
|
||||
;
|
||||
; Called every second. Add your routine calls here.
|
||||
|
||||
@@ -1,6 +1,47 @@
|
||||
|
||||
|
||||
|
||||
; Utils_WaitNanoSecs waittime_in_ns , cyles_already_used , waitcount_register
|
||||
;
|
||||
; cycles already used will be subtracted from the delay
|
||||
; the waittime resolution is 1 cycle (delay from exact to +1 cycle)
|
||||
; the maximum delay at 20MHz (50ns/clock) is 38350ns
|
||||
; waitcount register must specify an immediate register
|
||||
; taken from https://www.mikrocontroller.net/articles/AVR_Assembler_Makros#Verz%C3%B6gerung_um_X_Nanosekunden
|
||||
;
|
||||
.set Osc_Hz = clock ; 1 MHz
|
||||
.set cycle_time_ns = (1000000000 / Osc_Hz) ; clock duration
|
||||
.macro Utils_WaitNanoSecs
|
||||
.set cycles = ((@0 + cycle_time_ns - 1) / cycle_time_ns - @1)
|
||||
.if (cycles > (255 * 3 + 2))
|
||||
.error "MACRO Utils_WaitNanoSecs - too many cycles to burn"
|
||||
.else
|
||||
.if (cycles > 6)
|
||||
.set loop_cycles = (cycles / 3)
|
||||
ldi @2,loop_cycles
|
||||
dec @2
|
||||
brne pc-1
|
||||
.set cycles = (cycles - (loop_cycles * 3))
|
||||
.endif
|
||||
.if (cycles > 0)
|
||||
.if (cycles & 4)
|
||||
rjmp pc+1
|
||||
rjmp pc+1
|
||||
.endif
|
||||
.if (cycles & 2)
|
||||
rjmp pc+1
|
||||
.endif
|
||||
.if (cycles & 1)
|
||||
nop
|
||||
.endif
|
||||
.endif
|
||||
.endif
|
||||
.endmacro
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; Utils_FillSram
|
||||
;
|
||||
@@ -49,3 +90,7 @@ Utils_IncrementCounter32:
|
||||
st -x, r18
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user