From 6468e76545e572d69784049950684a12353c7790 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Wed, 18 Jan 2023 01:09:31 +0100 Subject: [PATCH] Added and simplified COM module. Directly use pins, no complicated redirections. Router modules will probably use real UARTs or MCUs programmed as UARTs. --- avr/com.asm | 508 ++++++++++++++++++++++++++++++++------------------ avr/main.asm | 58 +++--- avr/utils.asm | 45 +++++ 3 files changed, 402 insertions(+), 209 deletions(-) diff --git a/avr/com.asm b/avr/com.asm index 3cb2d0e..a1263c4 100644 --- a/avr/com.asm +++ b/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< 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< (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 + + + +