8 Commits

Author SHA1 Message Date
Martin Preuss
ae1e4c3e37 avr: bootloader works with new com2w code. 2025-07-20 00:05:53 +02:00
Martin Preuss
78cbbf334e com2w: alloc buffer after receiving message. receiving works now. 2025-07-19 17:47:52 +02:00
Martin Preuss
c8c12bb892 t03: use router app. 2025-07-19 17:08:39 +02:00
Martin Preuss
ae1853ba62 enable sending messages. 2025-07-19 17:08:19 +02:00
Martin Preuss
e8423ae97f check dest address for ping requests. 2025-07-19 17:07:52 +02:00
Martin Preuss
597504fb08 t03: added test firmware. 2025-07-19 15:02:46 +02:00
Martin Preuss
59a0962420 added com2w0 2025-07-19 15:02:31 +02:00
Martin Preuss
323a5b76be sync test. 2025-07-19 09:48:56 +02:00
12 changed files with 1597 additions and 23 deletions

View File

@@ -48,6 +48,7 @@ AppRouter_Init:
ldi r17, (appRouterDataEnd-appRouterDataBegin)
rcall Utils_FillSram
#ifndef APP_ROUTER_NO_ADDR_MGR
ldi r16, 0xe0 ; default range from 0xe0-0xef (will be changed later)
sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16 ; use first address for router itself
sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16 ; use same address for both interfaces to save on addresses
@@ -57,6 +58,7 @@ AppRouter_Init:
sts appRouterRangeEnd, r16
rcall appRouterReadConfFromEeprom ; try to read config from EEPROM
#endif
; set interface number for NETDEV0
ldi r16, NETDEV0_IFACENUM
@@ -65,9 +67,11 @@ AppRouter_Init:
ldi r16, NETDEV1_IFACENUM
sts netInterfaceData2+NET_IFACE_OFFS_IFACENUM, r16
#ifndef APP_ROUTER_NO_ADDR_MGR
ldi r18, NETMSG_CMD_ADDRESS_RANGE
rcall appRouterSendRangeMsgToDev1
#endif
ret
; @end
@@ -140,6 +144,7 @@ appRouterHandleMsgAnyDev_handleSetValue:
breq appRouterHandleMsgAnyDev_handleSetRange
rjmp appRouterHandleMsgAnyDev_clcRet
appRouterHandleMsgAnyDev_handleSetRange:
#ifndef APP_ROUTER_NO_ADDR_MGR
sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r18 ; use first address for router itself
sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r18 ; use same address for both interfaces to save on addresses
inc r18 ; start range after router
@@ -152,6 +157,7 @@ appRouterHandleMsgAnyDev_handleSetRange:
ldi r18, NETMSG_CMD_REENUM
rcall appRouterSendRangeMsgToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y)
rcall appRouterWriteConfToEeprom ; (r16, r17, X)
#endif
sec
ret
appRouterHandleMsgAnyDev_clcRet:
@@ -172,6 +178,7 @@ appRouterHandleMsgAnyDev_end:
; @clobbers any, !X
appRouterHandleDev1Msg:
#ifndef APP_ROUTER_NO_ADDR_MGR
push xl
push xh
rcall appRouterHandleDev1Msg_savedX
@@ -202,6 +209,7 @@ appRouterHandleDev1Msg_handleClaimAddr:
rcall appRouterSendDenyAddrR19ToDev1 ; (R16, R17, R18, R19, R20, R21, X, Y)
sec
rjmp appRouterHandleDev1Msg_end
#endif
appRouterHandleDev1Msg_clcRet:
clc
appRouterHandleDev1Msg_end:
@@ -340,8 +348,18 @@ appRouterHandleRebootRequest_end:
; @param X pointer to received message
appRouterHandlePingRequest:
ld r17, X
lds r16, (netInterfaceData+NET_IFACE_OFFS_ADDRESS)
cp r16, r17
breq appRouterHandlePingRequest_forMe
cpi r17, 0xff
breq appRouterHandlePingRequest_forMe
clc
rjmp appRouterHandlePingRequest_end
appRouterHandlePingRequest_forMe:
adiw xh:xl, NETMSG_OFFS_SRCADDR
ld r17, X
sbiw xh:xl, NETMSG_OFFS_SRCADDR
push r17
bigcall NET_Buffer_Alloc ; (R16, R17, X)
pop r17
@@ -408,8 +426,10 @@ appRouterHandleRouterMsgWithHdr:
andi r17, (1<<NET_IFACE_BUFFER_IFACENUM1_BIT) | (1<<NET_IFACE_BUFFER_IFACENUM0_BIT)
cpi r17, NETDEV1_IFACENUM
brne appRouterHandleRouterMsgWithHdr_any
#ifndef APP_ROUTER_NO_ADDR_MGR
rcall appRouterHandleDev1Msg ; handle messages from controlled subnet
brcs appRouterHandleRouterMsgWithHdr_msgHandled
#endif
appRouterHandleRouterMsgWithHdr_any:
rcall appRouterHandleMsgAnyDev ; handle any msg
brcs appRouterHandleRouterMsgWithHdr_msgHandled

View File

@@ -104,6 +104,14 @@
#ifdef MODULES_COM2W0
.include "modules/com2w/defs.asm"
.include "modules/com2w/common.asm"
.include "modules/com2w/com2w0.asm"
#endif
#ifdef MODULES_COM2W1
.include "modules/com2w/defs.asm"
.include "modules/com2w/common.asm"

View File

@@ -26,6 +26,7 @@
.include "../defs.asm"
.include "common/calls.asm"
.include "common/utils_io.asm"
.include "devices/all/defs.asm"
@@ -122,8 +123,7 @@ main:
.include "modules/flash/defs.asm"
.include "modules/flash/eeprom.asm"
.include "modules/flash/io.asm"
.include "modules/flash/io_attn.asm"
.include "modules/flash/io_bitbang.asm"
.include "modules/flash/io_com2w.asm"
.include "modules/flash/flash1p.asm"
.include "modules/flash/flashxp.asm"
.include "modules/flash/flashprocess.asm"

View File

@@ -5,6 +5,7 @@
<subdirs>
boot
main
test
</subdirs>
<extradist>

View File

@@ -0,0 +1,33 @@
<?xml?>
<gwbuild>
<target type="AvrHexFile" name="t03_test" >
<includes type="avrasm" >
-I $(builddir)
-I $(srcdir)
-I $(topsrcdir)/avr
-I $(topbuilddir)/avr
</includes>
<sources type="avrasm" >
main.asm
</sources>
</target>
<subdirs>
</subdirs>
<extradist>
</extradist>
</gwbuild>

View File

@@ -0,0 +1,257 @@
; ***************************************************************************
; copyright : (C) 2024 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; Source file for temperature sensor node on AtTiny 84
;
; This is for the full system (i.e. not the boot loader).
;
; All definitions and changes should go into this file.
;
;
; ***************************************************************************
;.equ clock=1000000 ; Define the clock frequency
.equ clock=8000000 ; Define the clock frequency
.nolist
.include "include/tn841def.inc" ; Define device ATtiny841
.list
.include "../defs.asm"
.include "version.asm"
;.include "defs_all.asm"
.include "devices/all/defs.asm"
.include "common/calls.asm"
.include "common/utils_wait.asm"
.include "common/utils_io.asm"
; ***************************************************************************
; defines
; ---------------------------------------------------------------------------
; generic
.equ COMONUART0_IFACENUM = 1
.equ TTYONUART1_IFACENUM = 2
; ---------------------------------------------------------------------------
; firmware settings including list of modules used
#define MAIN_WITHOUT_MSG_HANDLING ; we do message handling ourselfes
#define APP_STATS_NETDEV2
#define APP_ROUTER_NO_ADDR_MGR
#define MODULES_CLOCK
;#define MODULES_COM
;#define MODULES_COM_WITH_ADDR_PROTO
;#define MODULES_LED
#define MODULES_LED_SIMPLE
;#define MODULES_TWI_MASTER
;#define MODULES_LCD
;#define LCD_MINIMAL_FONT
;#define MODULES_SI7021
;#define MODULES_STATS
;#define MODULES_CNY70
;#define MODULES_REED
;#define MODULES_OWI_MASTER
;#define MODULES_DS18B20
;#define MODULES_MOTION
#define MODULES_NETWORK
#define MODULES_COM2W0
;#define MODULES_COMONUART0
#define MODULES_TTYONUART1
#define APPS_STATS
;#define APPS_NETWORK
#define APPS_ROUTER
.equ NET_BUFFERS_NUM = 10
.equ UART_HW_MSGNUMINBUF_SIZE = 8
.equ UART_HW_MSGNUMOUTBUF_SIZE = 8
; ---------------------------------------------------------------------------
; defines for values
.equ VALUE_ID_DS18B20_TEMP = 0x06
.equ VALUE_ID_LEDSIMPLE_TIMING = 0x88
.equ VALUE_ID_ROUTER_SETRANGE = 0x89
.equ COM_DATA0_DDR = COM_DATA_DDR
.equ COM_DATA0_INPUT = COM_DATA_INPUT
.equ COM_DATA0_OUTPUT = COM_DATA_OUTPUT
.equ COM_DATA0_PUE = COM_DATA_PUE
.equ COM_DATA0_PIN = COM_DATA_PIN
.equ COM_CLK0_DDR = COM_CLK_DDR
.equ COM_CLK0_INPUT = COM_CLK_INPUT
.equ COM_CLK0_OUTPUT = COM_CLK_OUTPUT
.equ COM_CLK0_PUE = COM_CLK_PUE
.equ COM_CLK0_PIN = COM_CLK_PIN
.equ COM_IRQ_ADDR_CLK0 = COM_IRQ_ADDR_CLK
.equ COM_IRQ_BIT_CLK0 = COM_IRQ_BIT_CLK
.equ COM_IRQ_GIFR_CLK0 = COM_IRQ_GIFR_CLK
.equ COM_IRQ_GIMSK_CLK0 = COM_IRQ_GIMSK_CLK
; ***************************************************************************
; code segment
.cseg
.org 000000
; ---------------------------------------------------------------------------
; Reset and interrupt vectors
rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system
reti ; 2: INT0 External Interrupt Request 0
rjmp COM2W0_ClkChangeIsr ; 3: PCINT0 Pin Change Interrupt 0
reti ; 4: PCINT1 Pin Change Interrupt 1
reti ; 5: WDT Watchdog Time-out
reti ; 6: TIM1_CAPT Timer/Counter1 Capture Event
reti ; 7: TIM1_COMPA (OC1A) Timer/Counter1 Compare Match A
reti ; 8: TIM1_COMPB (OC1B) Timer/Counter1 Compare Match B
reti ; 9: TIM1_OVF (OVF1) Timer/Counter1 Overflow
rjmp baseTimerIrqOC0A ; 10: TIM0_COMPA (OC0A) Timer/Counter0 Compare Match A
reti ; 11: TIM0_COMPB (OC0B) Timer/Counter0 Compare Match B
reti ; 12: TIM0_OVF (OVF0) Timer/Counter0 Overflow
reti ; 13: ANA_COMP0 Analog Comparator 0
reti ; 14: ADC_READY ADC Conversion Complete
reti ; 15: EE_RDY (ERDY) EEPROM Ready
reti ; 16: ANA_COMP1 Analog Comparator 1
reti ; 17: TIM2_CAPT Timer/Counter2 Capture Event
reti ; 18: TIM2_COMPA (OC2A) Timer/Counter2 Compare Match A
reti ; 19: TIM2_COMPB (OC2B) Timer/Counter2 Compare Match B
reti ; 20: TIM2_OVF (OVF2) Timer/Counter2 Overflow
reti ; 21: SPI SPI Serial Transfer Complete
reti ; 22: USART0_RXS USART0 Rx Start
; rjmp ComOnUart0_RxCharIsr ; 23: USART0_RXC USART0 Rx Complete
reti ; 23: USART0_RXC USART0 Rx Complete
reti ; 24: USART0_DRE USART0 Data Register Empty
reti ; 25: USART0_TXC USART0 Tx Complete
reti ; 26: USART1_RXS USART1 Rx Start
rjmp TtyOnUart1_RxCharIsr ; 27: USART1_RXC USART1 Rx Complete
rjmp TtyOnUart1_TxUdreIsr ; 28: USART1_DRE USART1 Data Register Empty
rjmp TtyOnUart1_TxCharIsr ; 29: USART1_TXC USART1 Tx Complete
reti ; 30: TWI Two-Wire-Interface
reti ; 31: RESERVED reserved
devInfoBlock: ; 12 bytes
devInfoManufacturer: .db 'A', 'Q', 'U', 'A'
devInfoId: .db DEVICEINFO_ID, 0
devInfoVersion: .db DEVICEINFO_VERSION, DEVICEINFO_REVISION ; version, revision
firmwareVersion: .db FIRMWARE_VARIANT_TEMP_WINDOW, FIRMWARE_VERSION_MAJOR
.db FIRMWARE_VERSION_MINOR, FIRMWARE_VERSION_PATCHLEVEL
; ---------------------------------------------------------------------------
; @routine firmwareStart @global
firmwareStart:
rjmp main
; @end
; ---------------------------------------------------------------------------
; @routine onSystemStart
onSystemStart:
ldi r16, 0xf0
sts netInterfaceData+NET_IFACE_OFFS_ADDRESS, r16
sts netInterfaceData2+NET_IFACE_OFFS_ADDRESS, r16
ret
; @end
onEvery100ms:
onEverySecond:
onEveryMinute:
onEveryHour:
onEveryDay:
ret
; ---------------------------------------------------------------------------
; @routine onEveryLoop
;
; Called on every loop (i.e. after awakening from sleep).
onEveryLoop:
ret
; @end
; ---------------------------------------------------------------------------
; @routine onMessageReceived
;
; Called on every message received
onMessageReceived:
clc
ret
; @end
; ***************************************************************************
; includes
.include "devices/all/hw_tn841.asm"
.include "devices/all/includes.asm"
.include "common/debug.asm"
; ---------------------------------------------------------------------------
; defines for network interface
.equ netInterfaceData = ttyOnUart1_iface
;.equ netInterfaceData2 = comOnUart0_iface
.equ netInterfaceData2 = com2w0_iface
; debug
push r18
push r19
rcall LedSimple_SetFastTiming
pop r19
pop r18

View File

@@ -98,34 +98,64 @@ COM2W_Every100ms:
; @clobbers R16, R17, R18, R19, R20, R22, R24, R25, X
com2wReceiveNextPkg:
; ldi r20, 3 ; make sure clock remains low for at least 15us
; rcall com2wWaitForClockHighMulti5Us ; (R20, R22)
; brcs com2wReceiveNextPkg_end ; clock got high quite soon, maybe just flaky line
mov xl, yl
mov xh, yh
adiw xh:xl, COM2W_IFACE_OFFS_BUFFER
ldd r18, Y+NET_IFACE_OFFS_ADDRESS
ldi r19, COM2W_BUFFER_SIZE
rcall com2wRecvMsg ; (r16, r17, r18, r19, r20, r22, r24, r25, X)
brcc com2wReceiveNextPkg_end
mov xl, yl
mov xh, yh
adiw xh:xl, COM2W_IFACE_OFFS_BUFFER
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
brcc com2wReceiveNextPkg_eCrc
; msg received, alloc buffer for it
rcall NET_Buffer_Alloc ; R16=buffer num (R16, R17, X)
brcs com2wReceiveNextPkg_gotBuffer
ldi r16, NET_IFACE_OFFS_ERR_NOBUF_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
rjmp com2wReceiveNextPkg_end
; copy received message into allocated buffer
com2wReceiveNextPkg_gotBuffer:
push r16 ; buffer number
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
adiw xh:xl, 1
ldd r18, Y+NET_IFACE_OFFS_ADDRESS
ldi r19, NET_BUFFERS_SIZE-1
rcall com2wReceiveAndCheckMsg ; (R16, R17, R18, R19, R20, R22, R24, R25)
pop r16
brcc com2wReceiveNextPkg_relBuffer
mov r19, r16 ; save buffer num
rcall NET_Interface_SetIfaceNumInBuffer ; (R16, R17)
mov r16, r19 ; restore buffer num
push zl
push zh
mov zl, yl
mov zh, yh
adiw zh:zl, COM2W_IFACE_OFFS_BUFFER
adiw xh:xl, 1
ldd r18, Z+NETMSG_OFFS_MSGLEN
inc r18
inc r18
inc r18
com2wReceiveNextPkg_copyLoop:
ld r17, Z+
st X+, r17
dec r18
brne com2wReceiveNextPkg_copyLoop
pop zh
pop zl
; add to incoming msg pool
rcall NET_AddIncomingMsgNum ; (R17, R18, X)
brcs com2wReceiveNextPkg_end
; debug
push r18
push r19
rcall LedSimple_SetFastTiming
pop r19
pop r18
brcc com2wReceiveNextPkg_eMissed
ldi r16, NET_IFACE_OFFS_PACKETSIN_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
rjmp com2wReceiveNextPkg_end
com2wReceiveNextPkg_eCrc:
push r16
ldi r16, NET_IFACE_OFFS_ERR_CONTENT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
pop r16
rjmp com2wReceiveNextPkg_relBuffer
com2wReceiveNextPkg_eMissed:
push r16
ldi r16, NET_IFACE_OFFS_ERR_MISSED_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
@@ -133,6 +163,7 @@ pop r18
; fall-through to release buffer
com2wReceiveNextPkg_relBuffer:
rcall NET_Buffer_ReleaseByNum ; (R16, X)
clc
com2wReceiveNextPkg_end:
ret
; @end

View File

@@ -0,0 +1,643 @@
; ***************************************************************************
; copyright : (C) 2025 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
#ifndef AVR_MODULES_COM2W_COM2W0_H
#define AVR_MODULES_COM2W_COM2W0_H
.dseg
com2w0_iface: .byte COM2W_IFACE_SIZE
.cseg
; ---------------------------------------------------------------------------
; @routine COM2W0_Init
;
; @clobbers
COM2W0_Init:
ldi yl, LOW(com2w0_iface)
ldi yh, HIGH(com2w0_iface)
rcall NET_Interface_Init ; (R16, R17, X)
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (R17)
; setup CLK line (as input, disable internal pull-up resistor)
cbi COM_CLK0_DDR, COM_CLK0_PIN ; set CLK as input
.ifdef COM_CLK0_PUE
inr r16, COM_CLK0_PUE
cbr r16, (1<<COM_CLK0_PIN) ; disable pullup on CLK
outr COM_CLK0_PUE, r16
.else
cbi COM_CLK0_OUTPUT, COM_CLK0_PIN ; disable pullup on CLK
.endif
; setup DATA line (as input, disable internal pull-up resistor)
cbi COM_DATA0_DDR, COM_DATA0_PIN ; set DATA as input
.ifdef COM_DATA0_PUE
inr r16, COM_DATA0_PUE
cbr r16, (1<<COM_DATA0_PIN) ; disable pullup on DATA
outr COM_DATA0_PUE, r16
.else
cbi COM_DATA0_OUTPUT, COM_DATA0_PIN ; disable pullup on DATA
.endif
; setup pin-change interrupt for CLK
rcall com2w0EnableClkIrq
inr r16, COM_IRQ_ADDR_CLK0
sbr r16, (1<<COM_IRQ_BIT_CLK0) ; enable pin change irq for ATTN line
outr COM_IRQ_ADDR_CLK0, r16
inr r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
sbr r16, (1<<COM_IRQ_GIMSK_CLK0)
outr GIMSK, r16
ldi r16, (1<<COM_IRQ_GIFR_CLK0) ; clear pending irq by writing 1 to ATTN bit
outr GIFR, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W0_Periodically @global
;
; @clobbers R16, Y
COM2W0_Periodically:
ldi yl, LOW(com2w0_iface)
ldi yh, HIGH(com2w0_iface)
rcall com2wPeriodically
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0EnableClkIrq
;
; @clobbers
com2w0EnableClkIrq:
push r16
inr r16, COM_IRQ_ADDR_CLK0
sbr r16, (1<<COM_IRQ_BIT_CLK0) ; enable pin change irq for CLK line
outr COM_IRQ_ADDR_CLK0, r16
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0DisableClkIrq
;
; @clobbers none
com2w0DisableClkIrq:
push r16
inr r16, COM_IRQ_ADDR_CLK0
cbr r16, (1<<COM_IRQ_BIT_CLK0) ; disable pin change irq for CLK line
outr COM_IRQ_ADDR_CLK0, r16
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0ClkSetHigh
;
; @clobbers none
com2w0ClkSetHigh:
cbi COM_CLK0_DDR, COM_CLK0_PIN ; set CLK as input
.ifdef COM_CLK0_PUE
; cbi COM_CLK0_PUE, COM_CLK0_PIN ; disable pullup on CLK
.else
cbi COM_CLK0_OUTPUT, COM_CLK0_PIN ; disable pullup on CLK
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0ClkSetLow
;
; @clobbers none
com2w0ClkSetLow:
sbi COM_CLK0_DDR, COM_CLK0_PIN ; set CLK as output
cbi COM_CLK0_OUTPUT, COM_CLK0_PIN ; set CLK low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0DataSetHigh
;
; @clobbers none
com2w0DataSetHigh:
cbi COM_DATA0_DDR, COM_DATA0_PIN ; set DATA as input
.ifdef COM_DATA0_PUE
; cbi COM_DATA0_PUE, COM_CLK0_PIN ; disable pullup on DATA
.else
cbi COM_DATA0_OUTPUT, COM_DATA0_PIN ; disable pullup on DATA
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0DataSetLow
;
; @clobbers none
com2w0DataSetLow:
sbi COM_DATA0_DDR, COM_DATA0_PIN ; set DATA as output
cbi COM_DATA0_OUTPUT, COM_DATA0_PIN ; set DATA low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0ReadNextBit
;
; @clobbers r16, r17, r18, r20, r22
com2w0ReadNextBit:
; ldi r20, 50 ; wait for up to 250us for clock rise
; rcall com2w0WaitForClockHighMulti5Us ; (R20, R22)
; brcc com2w0ReadNextBit_end
; clock is high now, read bit
inr r17, COM_DATA0_INPUT
; reset read timer (for leaving skipping mode)
clr r16
std Y+NET_IFACE_OFFS_READTIMER, r16
; check mode
ldd r16, Y+COM2W_IFACE_OFFS_MODE
cpi r16, COM2W_MODE_READING
brne com2w0ReadNextBit_end
; handle received bit
ldd r16, Y+COM2W_IFACE_OFFS_CURRBYTE
ldd r18, Y+COM2W_IFACE_OFFS_BITCOUNTER
andi r17, (1<<COM_DATA0_PIN)
clc
breq com2w0ReadNextBit_clockData
sec
com2w0ReadNextBit_clockData:
ror r16
std Y+COM2W_IFACE_OFFS_CURRBYTE, r16
inc r18 ; bit counter
std Y+COM2W_IFACE_OFFS_BITCOUNTER, r18
cpi r18, 8
brne com2w0ReadNextBit_end
; write byte into buffer
push xl
push xh
rcall com2wByteRecvd ; (r16, r17, r18, X)
pop xh
pop xl
; prepare for next byte
clr r16
std Y+COM2W_IFACE_OFFS_BITCOUNTER, r16
std Y+COM2W_IFACE_OFFS_CURRBYTE, r16
com2w0ReadNextBit_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0WaitForClockHighMulti5Us
;
; Wait for high CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2w0WaitForClockHighMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2w0WaitForClockHighMulti5Us_loop: ; 5 cycles per loop
sbic COM_CLK0_INPUT, COM_CLK0_PIN ; +2 if skipped, +1 if not
rjmp com2w0WaitForClockHighMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2w0WaitForClockHighMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2w0WaitForClockHighMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2w0WaitForClockLowMulti5Us
;
; Wait for low CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2w0WaitForClockLowMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2w0WaitForClockLowMulti5Us_loop: ; 5 cycles per loop
sbis COM_CLK0_INPUT, COM_CLK0_PIN ; +2 if skipped, +1 if not
rjmp com2w0WaitForClockLowMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2w0WaitForClockLowMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2w0WaitForClockLowMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2w0SendMsg
;
; @param X pointer to bytes to send
; @param Y pointer to interface data in SRAM
; @return CFLAG set if message sent, cleared otherwise
; @clobbers R16, R18 (R20, R22, R24, R25, X)
com2w0SendMsg:
ldi r20, 11 ; wait for about 55us for clock low
rcall com2w0WaitForClockLowMulti5Us ; (R20, R22)
brcs com2w0SendMsg_busy ; CLK got low while waiting, so line is busy
push r15
in r15, SREG
cli ; atomic disable irq and set CLK low
rcall com2w0DisableClkIrq ; (none)
rcall com2w0ClkSetLow ; reserve bus (none)
out SREG, r15
pop r15
adiw xh:xl, NETMSG_OFFS_MSGLEN
ld r18, X
sbiw xh:xl, NETMSG_OFFS_MSGLEN
inc r18 ; adjust for DESTADDR
inc r18 ; adjust for MSGLEN
inc r18 ; adjust for CRCBYTE
rcall com2wWaitTime1 ; longer wait period (R22)
rcall com2w0SendBytes ; (r16, r17, r18, r22, X)
rcall com2w0ClkSetHigh ; make sure bus is released
rcall com2w0DataSetHigh
rcall com2w0EnableClkIrq ; (none)
ldi r16, NET_IFACE_OFFS_PACKETSOUT_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
sec
ret
com2w0SendMsg_busy:
ldi r16, NET_IFACE_OFFS_ERR_BUSY_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0SendBytes
;
; @param R18 number of bytes to send
; @param X pointer to bytes to send
; @param Y pointer to interface data in SRAM
; @clobbers: r16, r18, X (r17, r22)
com2w0SendBytes:
com2w0SendBytes_loop:
rcall com2w0ClkSetLow ; (none)
rcall com2wWaitTime1 ; longer wait period (R22)
ld r16, X+
rcall com2w0SendByte ; (R16, R17, R22)
dec r18
brne com2w0SendBytes_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0SendByte
;
; @param R16 byte to send
; @clobbers: r16, r17 (r22)
com2w0SendByte:
ldi r17, 8
com2w0SendByte_loop:
rcall com2w0ClkSetLow
rcall com2wWaitTime1 ; longer wait period (R22)
lsr r16
brcs com2w0SendByte_send1
rcall com2w0DataSetLow
rjmp com2w0SendByte_sent
com2w0SendByte_send1:
rcall com2w0DataSetHigh
com2w0SendByte_sent:
rcall com2wWaitTime2 ; shorter wait period (R22)
push r15
in r15, SREG
cli ; ensure time period by disabling irqs
rcall com2w0ClkSetHigh
rcall com2wWaitTime1 ; longer wait period (R22)
out SREG, r15
pop r15
dec r17
brne com2w0SendByte_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W0_Run @global
;
; @return CFLAG set if something done, cleared otherwise
; @clobbers all
COM2W0_Run:
ldi yl, LOW(com2w0_iface)
ldi yh, HIGH(com2w0_iface)
rjmp com2w0RunMode ; (all but Y)
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunMode
;
; @clobbers all
com2w0RunMode:
cpi r16, COM2W_MODE_NUM
brcs COM2W0_Run_jump
ldi r16, COM2W_MODE_IDLE ; unknown mode, set to idle
rcall com2wSetMode ; (R17)
sec
ret
COM2W0_Run_jump:
ldi zl, LOW(com2w0ModeJumpTable)
ldi zh, HIGH(com2w0ModeJumpTable)
add zl, r16
adc zh, r16
sub zh, r16
ijmp
com2w0ModeJumpTable:
rjmp com2w0RunIdle
rjmp com2w0RunReading
rjmp com2w0RunSkipping
rjmp com2w0RunWriting
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunIdle
;
; @param Y pointer to interface data in SRAM
; @clobbers R16, R17, R22, R24, R25, X
com2w0RunIdle:
;rjmp com2w0RunIdle_end ; DEBUG
push r15
in r15, SREG
cli
; look for outbound message
rcall NET_Interface_PeekNextOutgoingMsgNum ; r16=msgNum
brcs com2w0RunIdle_haveMsg
out SREG, r15
pop r15
clc
rjmp com2w0RunIdle_end
com2w0RunIdle_haveMsg:
mov r24, r16
ldi r16, COM2W_MODE_WRITING
rcall com2wSetMode ; (R17)
mov r16, r24
out SREG, r15
pop r15
push r16
rcall NET_Buffer_Locate ; (R17)
adiw xh:xl, 1
rcall com2w0SendMsg ; (R16, R17, R22, R24, R25, X)
push r15
in r15, SREG ; save SREG (no CLI, we want to save CFLAG only)
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (R17)
out SREG, r15 ; restore SREG
pop r15
pop r16
brcc com2w0RunIdle_end
push r15
in r15, SREG
cli
rcall NET_Interface_GetNextOutgoingMsgNum ; take current msg off the queue
rcall NET_Buffer_ReleaseByNum ; (R16, X)
out SREG, r15
pop r15
sec
com2w0RunIdle_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunReading
;
; @param Y pointer to interface data in SRAM
; @clobbers none
com2w0RunReading:
; check for timeout (Y+NET_IFACE_OFFS_READTIMER)
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, COM2W_READING_MAXREADCOUNTER
brcc com2w0RunReading_goIdle
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
cpi r16, COM2W_READING_MAXMODECOUNTER
brcc com2w0RunReading_goIdle
clc
rjmp com2w0RunReading_end
com2w0RunReading_goIdle:
ldi r16, NET_IFACE_OFFS_ERR_IO_LOW
rcall NET_Interface_IncCounter16 ; (R24, R25)
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (r17)
sec
com2w0RunReading_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunSkipping
;
; @param Y pointer to interface data in SRAM
; @clobbers r16 (r17)
com2w0RunSkipping:
; check for timeout (Y+NET_IFACE_OFFS_READTIMER)
ldd r16, Y+NET_IFACE_OFFS_READTIMER
cpi r16, COM2W_SKIPPING_MAXREADCOUNTER
brcc com2w0RunSkipping_goIdle
ldd r16, Y+COM2W_IFACE_OFFS_MODECOUNTER
cpi r16, COM2W_SKIPPING_MAXMODECOUNTER
brcc com2w0RunSkipping_goIdle
clc
rjmp com2w0RunSkipping_end
com2w0RunSkipping_goIdle:
ldi r16, COM2W_MODE_IDLE
rcall com2wSetMode ; (r17)
sec
com2w0RunSkipping_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0RunWriting
;
; @param Y pointer to interface data in SRAM
; @clobbers none
com2w0RunWriting:
; TODO: check for timeout
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine COM2W0_ClkChangeIsr @global @isr
;
; @clobbers none
COM2W0_ClkChangeIsr:
push r15
in r15, SREG
push r16
inr r16, COM_CLK0_INPUT ; read clk state early
rcall COM2W0_HandleClockInterrupt
pop r16
out SREG, r15
pop r15
reti
; @end
; ---------------------------------------------------------------------------
; @routine COM2W0_HandleClockInterrupt @global
;
; @param r16 data from COM_CLKn_INPUT
; @clobbers none
COM2W0_HandleClockInterrupt:
push r16
push r17
push r18
push xl
push xh
push yl
push yh
ldi yl, LOW(com2w0_iface)
ldi yh, HIGH(com2w0_iface)
rcall com2w0ActOnClock ; (r16, r17, r18, X)
pop yh
pop yl
pop xh
pop xl
pop r18
pop r17
pop r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2w0ActOnClock
;
; @param r16 data from COM_CLKn_INPUT
; @clobbers r16 (r17, r18, X)
com2w0ActOnClock:
andi r16, (1<<COM_CLK0_PIN)
brne com2w0ActOnClock_clockHigh
; clock low
ldd r17, Y+COM2W_IFACE_OFFS_MODE
cpi r17, COM2W_MODE_IDLE
brne com2w0ActOnClock_end
rcall com2wStartReading ; (r16, r17, X)
rjmp com2w0ActOnClock_end
com2w0ActOnClock_clockHigh:
ldd r17, Y+COM2W_IFACE_OFFS_MODE
cpi r17, COM2W_MODE_READING
brne com2w0ActOnClock_end
push r20
push r22
rcall com2w0ReadNextBit ; (r16, r17, r18, r20, r22)
pop r22
pop r20
com2w0ActOnClock_end:
ret
; @end
#endif ; AVR_MODULES_COM2W_COM2W0_H

View File

@@ -9,6 +9,7 @@
flash4p.asm
flashxp.asm
flashprocess.asm
io_stub.asm
io.asm
io_attn.asm
io_bitbang.asm

View File

@@ -0,0 +1,462 @@
; ***************************************************************************
; copyright : (C) 2025 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
#ifndef AVR_MODULES_FLASH_IO_COM2W_H
#define AVR_MODULES_FLASH_IO_COM2W_H
.equ COM2W_WAITTIME1 = 30000
.equ COM2W_WAITTIME2 = 10000
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ioRawInit
;
; Init raw message subsystem.
;
ioRawInit:
; setup CLK line (as input, disable internal pull-up resistor)
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
.ifdef COM_CLK_PUE
inr r16, COM_CLK_PUE
cbr r16, (1<<COM_CLK_PIN) ; disable pullup on CLK
outr COM_CLK_PUE, r16
.else
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
.endif
; setup DATA line (as input, disable internal pull-up resistor)
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
.ifdef COM_DATA_PUE
inr r16, COM_DATA_PUE
cbr r16, (1<<COM_DATA_PIN) ; disable pullup on DATA
outr COM_DATA_PUE, r16
.else
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawSendMsg
;
; Send a message
;
ioRawSendMsg:
ioRawSendMsg_loop:
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
ldi r19, FLASH_RECVBUFFER_MAXLEN
rcall com2wSendMsg
brcc ioRawSendMsg_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawWaitForValidMsg
;
; Wait for valid incoming msg
;
; @return CFLAG set if okay (packet received), cleared on error
ioRawWaitForValidMsg:
; wait for CLK low
ldi r19, 20 ; wait for up to 10s
ioRawWaitForValidMsg_waitLowLoop1:
.ifdef LED_PIN
sbi LED_PIN, LED_PINNUM ; toggle
.endif
ldi r18, 5
ioRawWaitForValidMsg_waitLowLoop2:
ldi r20, 20 ; wait for about 100us for clock low
rcall com2wWaitForClockLowMulti5Us ; R20, R22
brcs ioRawWaitForValidMsg_recvMsg
dec r18
brne ioRawWaitForValidMsg_waitLowLoop2
dec r19
brne ioRawWaitForValidMsg_waitLowLoop1
clc ; no msg received
rjmp ioRawWaitForValidMsg_end
ioRawWaitForValidMsg_recvMsg:
; receive message
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
ldi r18, NET_MAINTENANCE_ADDR
ldi r19, FLASH_RECVBUFFER_MAXLEN
rcall com2wRecvMsg
brcc ioRawWaitForValidMsg_end
; validate CRC
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
rcall NETMSG_CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
ioRawWaitForValidMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendMsg
;
; @param X pointer to bytes to send
; @return CFLAG set if message sent, cleared otherwise
; @clobbers R18, R20 (R16, R17, R20, R22, X)
com2wSendMsg:
ldi r20, 11 ; wait for about 55us for clock low
rcall com2wWaitForClockLowMulti5Us
brcs com2wSendMsg_busy ; CLK got low while waiting, so line is busy
rcall com2wClkSetLow ; reserve bus (none)
adiw xh:xl, NETMSG_OFFS_MSGLEN
ld r18, X
sbiw xh:xl, NETMSG_OFFS_MSGLEN
inc r18 ; adjust for DESTADDR
inc r18 ; adjust for MSGLEN
inc r18 ; adjust for CRCBYTE
rcall com2wWaitTime1 ; longer wait period (R22)
rcall com2wSendBytes ; (r16, r17, r18, r22, X)
rcall com2wClkSetHigh ; make sure bus is released
rcall com2wDataSetHigh
sec
ret
com2wSendMsg_busy:
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendBytes
;
; @param R18 number of bytes to send
; @param X pointer to bytes to send
; @clobbers: r16, r18, X (r17, r22)
com2wSendBytes:
com2wSendBytes_loop:
rcall com2wClkSetLow ; (none)
rcall com2wWaitTime1 ; longer wait period (R22)
ld r16, X+
rcall com2wSendByte ; (R16, R17, R22)
dec r18
brne com2wSendBytes_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wSendByte
;
; @param R16 byte to send
; @clobbers: r16, r17 (r22)
com2wSendByte:
ldi r17, 8
com2wSendByte_loop:
rcall com2wClkSetLow
rcall com2wWaitTime1 ; longer wait period (R22)
lsr r16
brcs com2wSendByte_send1
rcall com2wDataSetLow
rjmp com2wSendByte_sent
com2wSendByte_send1:
rcall com2wDataSetHigh
com2wSendByte_sent:
rcall com2wWaitTime2 ; shorter wait period (R22)
rcall com2wClkSetHigh
rcall com2wWaitTime1 ; longer wait period (R22)
dec r17
brne com2wSendByte_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wRecvMsg
;
; Receive a packet into buffer pointed to by X.
; Expects interrupts to be disabled.
;
; @param R18 COM address to listen to
; @param R19 max buffer size
; @param X buffer to receive to
; @return CFLAG set if msg received, cleared on error (see R16)
; @return R16 if CFLAG cleared: 0=message not for this node, otherwise error
; @clobbers r16, r17, r18, r19, r20, r22, r24, r25, X
com2wRecvMsg:
mov r21, r18 ; address
; read destination address
rcall com2wRecvByte ; (r17, r18, r20, r22)
brcc com2wRecvMsg_eIo
; store in buffer
subi r19, 1
brcs com2wRecvMsg_eBadSize
st X+, r16
; read remaining msg size
rcall com2wRecvByte ; (r17, r18, r20, r22)
brcc com2wRecvMsg_eIo
; store in buffer
subi r19, 1
brcs com2wRecvMsg_eBadSize
st X+, r16
inc r16 ; account for CRC byte
sub r19, r16
brcs com2wRecvMsg_eBadSize
mov r19, r16
com2wRecvMsg_loop:
rcall com2wRecvByte ; (r17, r18, r20, r22)
brcc com2wRecvMsg_eIo
st X+, r16
dec r19
brne com2wRecvMsg_loop
sec
rjmp com2wRecvMsg_end
com2wRecvMsg_eBadSize:
com2wRecvMsg_eIo:
com2wRecvMsg_clcRet:
clc
com2wRecvMsg_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wRecvByte
;
; @return CFLAG set if byte received, cleared on error
; @return r16 byte received
; @clobbers r17, r18, r20, r22
com2wRecvByte:
ldi r17, 8
clr r16
com2wRecvByte_loop:
ldi r20, 31 ; wait up to 155us for clock low
rcall com2wWaitForClockLowMulti5Us ; (R20, R22)
brcs com2wRecvByte_waitForClkHigh
ldi r20, 31 ; wait up to 155us for clock low
rcall com2wWaitForClockLowMulti5Us ; (R20, R22)
brcc com2wRecvByte_end
com2wRecvByte_waitForClkHigh:
ldi r20, 31 ; wait up to 155us for clock high
rcall com2wWaitForClockHighMulti5Us ; (R20, R22)
brcs com2wRecvByte_readBit
ldi r20, 31 ; wait up to 155us for clock high
rcall com2wWaitForClockHighMulti5Us ; (R20, R22)
brcc com2wRecvByte_end
com2wRecvByte_readBit:
; handle received bit
inr r18, COM_DATA_INPUT
andi r18, (1<<COM_DATA_PIN)
clc
breq com2wRecvByte_clockData
sec
com2wRecvByte_clockData:
ror r16
dec r17
brne com2wRecvByte_loop
sec
com2wRecvByte_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wClkSetHigh
;
; @clobbers none
com2wClkSetHigh:
cbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as input
.ifdef COM_CLK_PUE
; cbi COM_CLK_PUE, COM_CLK_PIN ; disable pullup on CLK
.else
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; disable pullup on CLK
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wClkSetLow
;
; @clobbers none
com2wClkSetLow:
sbi COM_CLK_DDR, COM_CLK_PIN ; set CLK as output
cbi COM_CLK_OUTPUT, COM_CLK_PIN ; set CLK low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wDataSetHigh
;
; @clobbers none
com2wDataSetHigh:
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as input
.ifdef COM_DATA_PUE
; cbi COM_DATA_PUE, COM_CLK_PIN ; disable pullup on DATA
.else
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable pullup on DATA
.endif
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wDataSetLow
;
; @clobbers none
com2wDataSetLow:
sbi COM_DATA_DDR, COM_DATA_PIN ; set DATA as output
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; set DATA low
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockHighMulti5Us
;
; Wait for high CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2wWaitForClockHighMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2wWaitForClockHighMulti5Us_loop: ; 5 cycles per loop
sbic COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if not
rjmp com2wWaitForClockHighMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2wWaitForClockHighMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2wWaitForClockHighMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitForClockLowMulti5Us
;
; Wait for low CLK
;
; @param R20 multiple of 5us to wait (e.g. "2" for "10" us, max: 64)
; @return CFLAG set if okay (state reached), cleared on error
; @clobbers: r20, r22
com2wWaitForClockLowMulti5Us:
.if clock == 8000000
add r20, r20 ; *2
add r20, r20 ; *4
add r20, r20 ; *8
.endif
.elif clock == 1000000
; nothing to do
.else
.error "Unhandled clock speed"
.endif
com2wWaitForClockLowMulti5Us_loop: ; 5 cycles per loop
sbis COM_CLK_INPUT, COM_CLK_PIN ; +2 if skipped, +1 if not
rjmp com2wWaitForClockLowMulti5Us_stateReached ; +2
dec r20 ; +1
brne com2wWaitForClockLowMulti5Us_loop ; +2
clc ; +1
ret ; +4
com2wWaitForClockLowMulti5Us_stateReached:
sec ; +1
ret ; +4
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitTime1
;
; waits for longer period (e.g. 30ns)
;
; @clobbers R22
com2wWaitTime1:
Utils_WaitNanoSecs COM2W_WAITTIME1, 7, r22 ; wait for longer time (minus RCALL and RET)
ret
; @end
; ---------------------------------------------------------------------------
; @routine com2wWaitTime2
;
; waits for shorter period (e.g. 10ns)
;
; @clobbers R22
com2wWaitTime2:
Utils_WaitNanoSecs COM2W_WAITTIME2, 7, r22 ; wait for shorter time (minus RCALL and RET)
ret
; @end
#endif ; AVR_MODULES_FLASH_IO_COM2W_H

View File

@@ -0,0 +1,60 @@
; ***************************************************************************
; copyright : (C) 2025 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine ioRawInit
;
; Init raw message subsystem.
;
ioRawInit:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawSendMsg
;
; Send a message
;
ioRawSendMsg:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawWaitForValidMsg
;
; Wait for valid incoming msg
;
; @return CFLAG set if okay (packet received), cleared on error
ioRawWaitForValidMsg:
ret
; @end

View File

@@ -0,0 +1,58 @@
; ***************************************************************************
; copyright : (C) 2025 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
#ifndef AVR_MODULES_UART_HW2_SYNC_H
#define AVR_MODULES_UART_HW2_SYNC_H
.dseg
.cseg
; sync length is 1000 us, so this should return:
; - 125 for 1 MHz
; - 1000 for 8 MHz
syncRecv:
syncRecv_waitForHigh:
sbis COM_DATA0_INPUT, COM_DATA0_PIN
rjmp syncRecv_waitForHigh
clr r24
clr r25
syncRecv_waitForLow:
sbic COM_DATA0_INPUT, COM_DATA0_PIN
rjmp syncRecv_waitForLow
syncRecv_countLow: ; total: +8 per loop
sbic COM_DATA0_INPUT, COM_DATA0_PIN ; +1 if noskip, +2 if skip
rjmp syncRecv_countDone ; +2, total: +2 every loop, +3 in last loop
adiw r25:r24, 1 ; +1
breq syncRecv_countError ; +1 if not 0, +2 if 0
nop ; +1
nop ; +1
rjmp syncRecv_countLow ; +2
syncRecv_countError:
clr r24
clr r25
syncRecv_countDone:
ret
; @end
#endif