avr: bootloader partially works now but stops after 3 messages...

This commit is contained in:
Martin Preuss
2025-01-20 23:47:13 +01:00
parent 0d7aca0060
commit 0a10d136d5
23 changed files with 398 additions and 1260 deletions

View File

@@ -38,6 +38,9 @@
.equ FIRMWARE_VERSION_PATCHLEVEL = 1
;#define COM_ACCEPT_ALL_DEST 1
; ---------------------------------------------------------------------------
; LED
@@ -112,38 +115,8 @@ firmwareStart: rjmp main ; will be overwritten when flashing
main:
cli
; 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
#if 1
; start by setting all ports as inputs and enable internal pull-up resistors
ldi r16, 0xff
clr r17
.ifdef PORTA
out DDRA, r17 ; all input
out PORTA, r16 ; enable pull-up on all
.endif
.ifdef PORTB
out DDRB, r17 ; all input
out PORTB, r16 ; enable pull-up on all
.endif
.ifdef PORTC
out DDRC, r17 ; all input
out PORTC, r16 ; enable pull-up on all
.endif
#endif
rcall systemSetSpeed
; rjmp debugUsart2
rjmp bootLoader ; this routine is in modules/flash/bootloader2.asm
; rjmp debugEchoUart1
rjmp bootLoader ; this routine is in modules/bootloader/main.asm
@@ -151,8 +124,6 @@ main:
; ***************************************************************************
; includes
;.include "modules/uart_bitbang/bytelevel.asm"
;.include "modules/uart_bitbang/packetlevel.asm"
.include "modules/uart_hw/raw_uart1.asm"
.include "modules/com2/crc.asm"
.include "common/crc8.asm"
@@ -160,140 +131,12 @@ main:
.include "common/utils_copy_from_flash.asm"
.include "common/utils_copy_sdram.asm"
.include "modules/flash/defs.asm"
.include "modules/flash/bootloader2.asm"
.include "modules/flash/io.asm"
.include "modules/flash/io_uart1.asm"
.include "modules/flash/flash.asm"
.include "modules/flash/flashprocess.asm"
;.include "modules/flash/recv.asm"
;.include "modules/flash/send.asm"
.include "modules/flash/wait.asm"
;.include "modules/flash/hdl_flash_start.asm"
;.include "modules/flash/hdl_flash_data.asm"
;.include "modules/flash/hdl_flash_end.asm"
;include "modules/flash/flash_rsp.asm"
;include "modules/flash/flash_ready.asm"
#if 0
debugUsart1:
sbi LED_DDR, LED_PINNUM ; out
cbi LED_PORT, LED_PINNUM ; on
ldi r16, 3 ; (19.2Kb/s at 1MHz)
ldi r17, 0
sts UBRR1H, r17
sts UBRR1L, r16
ldi r16, (3<<UCSZ10)
sts UCSR1C, r16
lds r16, UCSR1B
cbr r16, (1<<UDRIE1) ; disable DRE interrupt
sbr r16, (1<<TXEN1) ; enable transmit
sts UCSR1B, r16
; ldi r16, (1<<UDRE1)
; sts UCSR1A, r16
clr r18
debugUsart1_loop:
debugUsart1_loop2:
lds r16, UCSR1A
sbrs r16,UDRE1
rjmp debugUsart1_loop2
; sbr r16, (1<<TXC1)
; sts UCSR1A, r16
sts UDR1, r18
cpi r18, 10
brne debugUsart1_skipLed
clr r18
rcall debugWaitFor100MilliSecs
sbi LED_PIN, LED_PINNUM ; toggle
debugUsart1_skipLed:
inc r18
rjmp debugUsart1_loop
#endif
debugUsart2:
sbi LED_DDR, LED_PINNUM ; out
cbi LED_PORT, LED_PINNUM ; on
ldi r16, 2 ; (19.2Kb/s at 1MHz)
; ldi r16, 25 ; (19.2Kb/s at 8MHz)
ldi r17, 0
sts UBRR1H, r17
sts UBRR1L, r16
ldi r16, (3<<UCSZ10)
sts UCSR1C, r16
lds r16, UCSR1B
cbr r16, (1<<UDRIE1) ; disable DRE interrupt
sbr r16, (1<<TXEN1) ; enable transmit
sts UCSR1B, r16
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall flashProcessWriteFlashReady ; (R16, R17, R18, R19, R20, Y, Z)
debugUsart2_loop:
rcall flashRawSendMsg ; (r16, r17, X)
rcall debugWaitFor100MilliSecs
sbi LED_PIN, LED_PINNUM ; toggle
rjmp debugUsart2_loop
#if 0
debugStop:
cli
sbi LED_SIMPLE_DDR, LED_SIMPLE_PINNUM ; out
cbi LED_SIMPLE_PORT, LED_SIMPLE_PINNUM ; on
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
ldi r18, 0
test_loop1:
ldi r16, 100
test_loop2:
ldi r17, 100
test_loop3:
Utils_WaitNanoSecs 10000, 0, r22
dec r17
brne test_loop3
dec r16
brne test_loop2
sbi LED_SIMPLE_PORTIN, LED_SIMPLE_PINNUM ; toggle
inc r18
mov r19, r18
andi r19, 1
brne test1
sbi COM_ATTN_DDR, COM_ATTN_PIN
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN
rjmp test_loop1
test1:
cbi COM_ATTN_DDR, COM_ATTN_PIN
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN
rjmp test_loop1
#endif
debugWaitFor100MilliSecs:
ldi r16, 10
debugWaitFor10MilliSecs_loop1:
ldi r17, 100
debugWaitFor10MilliSecs_loop2:
rcall Utils_WaitFor100MicroSecs ; 10ms
dec r17
brne debugWaitFor10MilliSecs_loop2
dec r16
brne debugWaitFor10MilliSecs_loop1
ret
.include "modules/bootloader/main.asm"
@@ -316,3 +159,89 @@ systemSetSpeed:
; debug
debugEchoUart1:
cli
; 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 systemSetSpeed
sbi LED_DDR, LED_PINNUM ; out
cbi LED_PORT, LED_PINNUM ; on
; set baudrate
.if clock == 8000000
ldi r16, 25 ; (19.2Kb/s at 8MHz)
ldi r17, 0
.endif
.if clock == 1000000
ldi r16, 3 ; (19.2Kb/s at 1MHz)
ldi r17, 0
.endif
sts UBRR1H, r17
sts UBRR1L, r16
; set character format (asynchronous USART, 8-bit, one stop bit, no parity)
ldi r16, (3<<UCSZ10)
sts UCSR1C, r16
; enable transceiver
lds r16, UCSR1B
; cbr r16, (1<<UDRIE1) ; disable DRE interrupt
ori r16, (1<<RXEN1) | (1<<TXEN1) ; enable transmit and receive
sts UCSR1B, r16
ldi zl, LOW(debugString*2)
ldi zh, HIGH(debugString*2)
rcall debugWriteString
debugEchoUart1_loop:
rcall debugReadByte
sbi LED_PIN, LED_PINNUM ; toggle
rcall debugWriteByte
rjmp debugEchoUart1_loop
debugReadByte:
lds r17, UCSR1A
sbrs r17, RXC1
rjmp debugReadByte
lds r16, UDR1
ret
debugWriteByte:
lds r17, UCSR1A
sbrs r17, UDRE1
rjmp debugWriteByte
; sbr r17, (1<<TXC1)
; sts UCSR1A, r17
sts UDR1, r16
ret
debugWriteString:
lpm r16, Z+
tst r16
breq debugWriteString_done
rcall debugWriteByte
rjmp debugWriteString
debugWriteString_done:
ret
debugString: .db "Hello", 13, 10, 0

View File

@@ -21,8 +21,8 @@
; ***************************************************************************
.equ clock=1000000 ; Define the clock frequency
;.equ clock=8000000 ; Define the clock frequency
;.equ clock=1000000 ; Define the clock frequency
.equ clock=8000000 ; Define the clock frequency
@@ -53,19 +53,19 @@
.equ FIRMWARE_VERSION_PATCHLEVEL = 1
#define MODULES_TIMER
#define MODULES_COM
#define MODULES_COM_WITH_ADDR_PROTO
;#define MODULES_TIMER
;#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 LCD_MINIMAL_FONT
;#define MODULES_SI7021
#define MODULES_STATS
;#define MODULES_STATS
;#define MODULES_CNY70
;#define MODULES_REED
#define MODULES_OWI_MASTER
;#define MODULES_OWI_MASTER
;#define MODULES_DS18B20
;#define MODULES_MOTION
@@ -84,7 +84,7 @@
rjmp BOOTLOADER_ADDR ; 1: RESET Reset vector use this for flashed system
reti ; 2: INT0 External Interrupt Request 0
rjmp uartBitbangIsrPcint0 ; 3: PCINT0 Pin Change Interrupt 0
reti ; 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
@@ -135,75 +135,8 @@ firmwareStart: rjmp main
.include "common/crc8.asm"
.include "modules/basetimer/main.asm"
#ifdef MODULES_TIMER
.include "modules/timer/main.asm"
#endif
#ifdef MODULES_LED
.include "modules/led/main.asm"
#endif
#ifdef MODULES_LED_SIMPLE
.include "modules/led_simple/main.asm"
#endif
#ifdef MODULES_COM
.include "modules/com2/defs.asm"
.include "modules/com2/main.asm"
.include "modules/com2/buffer.asm"
.include "modules/uart_bitbang/defs.asm"
.include "modules/uart_bitbang/main.asm"
.include "modules/uart_bitbang/bytelevel.asm"
.include "modules/uart_bitbang/packetlevel.asm"
#ifdef MODULES_COM_WITH_ADDR_PROTO
.include "modules/comproto/defs.asm"
.include "modules/comproto/main.asm"
.include "modules/comproto/addr.asm"
.include "modules/comproto/msg_recvstats.asm"
.include "modules/comproto/msg_sendstats.asm"
.include "modules/comproto/msg_sysstats.asm"
.include "modules/comproto/msg_memstats.asm"
.include "modules/comproto/msg_pong.asm"
.include "modules/comproto/msg_value.asm"
.include "modules/comproto/msg_device.asm"
.include "modules/comproto/msg_reboot.asm"
#endif
#ifdef MODULES_LCD
.include "modules/com2/screen.asm"
.include "modules/comproto/screen.asm"
#endif
#endif
#ifdef MODULES_TWI_MASTER
.include "modules/twimaster/main.asm"
#endif
#ifdef MODULES_OWI_MASTER
.include "modules/owimaster/main.asm"
#endif
#ifdef MODULES_LCD
.include "modules/lcd/main.asm"
#endif
#ifdef MODULES_SI7021
.include "modules/si7021/main.asm"
#endif
#ifdef MODULES_DS18B20
.include "modules/ds18b20/main.asm"
#endif
#ifdef MODULES_STATS
.include "modules/stats/main.asm"
#endif
#ifdef MODULES_CNY70
.include "modules/cny70/main.asm"
#endif
#ifdef MODULES_REED
.include "modules/reed/main.asm"
#endif
#ifdef MODULES_MOTION
.include "modules/motion/main.asm"
#endif
; test
;#include "modules/uart_irq/defs.asm"
;#include "modules/uart_irq/iface.asm"
;#include "modules/uart_irq/iface1.asm"
; ***************************************************************************
@@ -212,250 +145,95 @@ firmwareStart: rjmp main
.dseg
programRamBegin:
#ifdef MODULES_LCD
screenCounter: .byte 1
#endif
; nothing for now
programRamEnd:
#ifdef MODULES_LCD
sramTimerWriteStats: .byte 2
sramTimerScreen: .byte 2
#endif
#ifdef MODULES_SI7021
sramTimerSI7021Measure: .byte 2
sramTimerSI7021SendTemp: .byte 2
sramTimerSI7021SendHumidity: .byte 2
#endif
#ifdef MODULES_CNY70
sramTimerCny70SendAdc: .byte 2
#endif
#ifdef MODULES_LCD
sramPeriodicalLcdMark: .byte 2
#endif
#ifdef MODULES_DS18B20
sramDs18b20Timer: .byte 2
sramSendDs18b20TempTimer: .byte 2
#endif
; ***************************************************************************
; data in FLASH
.cseg
main:
cli
; 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
; ---------------------------------------------------------------------------
; timer list
; start by setting all ports as inputs and enable internal pull-up resistors
ldi r16, 0xff
clr r17
.ifdef PORTA
out DDRA, r17 ; all input
out PORTA, r16 ; enable pull-up on all
.endif
.ifdef PORTB
out DDRB, r17 ; all input
out PORTB, r16 ; enable pull-up on all
.endif
timerList:
; SRAM variable/counter routine flags secs (0=don't start or restart)
#ifdef MODULES_COM_WITH_ADDR_PROTO
.dw cproAddresModeTimer, CPRO_Address_OnTimer, 0, 0 ; (no restart)
#endif
#ifdef MODULES_STATS
.dw statsSendTimer, Stats_Timer, TIMER_FLAGS_IF_ADDR, 9000 ; every 15m
#endif
#ifdef MODULES_LCD
; .dw sramPeriodicalLcdMark, periodicalLcdMark, 0, 20 ; every 2s
; .dw sramTimerWriteStats, writeStats, 0, 100
.dw sramTimerScreen, printScreen, TIMER_FLAGS_IF_ADDR, 50 ; every 5s
#endif
#ifdef MODULES_SI7021
.dw sramTimerSI7021Measure, SI7021_OnTimer, 0, 300 ; every 30s
.dw sramTimerSI7021SendTemp, sendSI7021Temp, TIMER_FLAGS_IF_ADDR, 600 ; every 60s
.dw sramTimerSI7021SendHumidity, sendSI7021Humidity, TIMER_FLAGS_IF_ADDR, 600 ; every 60s
#endif
#ifdef MODULES_CNY70
.dw sramTimerCny70SendAdc, CNY70_OnTimer, TIMER_FLAGS_IF_ADDR, 50 ; every 5s
#endif
#ifdef MODULES_DS18B20
.dw sramDs18b20Timer, Ds18b20_OnTimer, 0, 300 ; every 30s
.dw sramSendDs18b20TempTimer, sendDs18b20Temp, TIMER_FLAGS_IF_ADDR, 600 ; every 60s
#endif
.dw 0 ; end of list
.ifdef PORTC
out DDRC, r17 ; all input
out PORTC, r16 ; enable pull-up on all
.endif
rcall systemSetSpeed
; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
rcall Utils_SetupUid
rcall LedSimple_Init
sei
main_loop:
; do something
; only modify SE, SM1 and SM0
cli
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
sei ; make sure interrupts really are enabled
sleep ; sleep, wait for interrupt
rjmp main_loop
.include "main_all.asm"
systemSetSpeed:
.if clock == 1000000
ldi r17, 0xd8
ldi r16, (1<<CLKPS1) | (1<<CLKPS0) ; SUT=0, CLKPS=0011b
sts CCP, r17
sts CLKPR, r16
.endif
.if clock == 8000000
ldi r16, (1<<CLKPCE)
ldi r17, 0
out CLKPR, r16
out CLKPR, r17
ldi r17, 0xd8
clr r16 ; SUT=0, CLKPS=0
sts CCP, r17
sts CLKPR, r16
.endif
ret
systemSetBootSpeed:
.if clock == 8000000
ldi r16, (1<<CLKPCE)
ldi r17, (1<<CLKPS1) | (1<<CLKPS0)
out CLKPR, r16
out CLKPR, r17
.endif
ret
; ---------------------------------------------------------------------------
; Called on first time run, i.e. on system start. No arguments, no results.
onSystemStart:
ldi xh, HIGH(programRamBegin)
ldi xl, LOW(programRamBegin)
clr r16
ldi r17, (programRamEnd-programRamBegin)
rcall Utils_FillSram
ret
#ifdef MODULES_LCD
printScreen:
lds r16, screenCounter
tst r16
brne printScreen_l1
rcall CPRO_Screen
rjmp printScreen_counter
printScreen_l1:
cpi r16, 1
brne printScreen_l2
rcall COM2_Screen_RecvStats
rjmp printScreen_counter
printScreen_l2:
; cpi r16, 2
; brne printScreen_l3
; rcall COM2_Screen_SendStats
; rjmp printScreen_counter
printScreen_l3:
; add more screens here
printScreen_counter:
lds r16, screenCounter
inc r16
cpi r16, 2 ; number of screens
brcs printScreen_store
clr r16
printScreen_store:
sts screenCounter, r16
printScreen_end:
ret
;periodicalLcdMark:
; rcall printTimerMark
; ret
;writeStats:
; rcall printSendStats
; ret
#endif
#ifdef MODULES_SI7021
sendSI7021Humidity:
rcall SI7021_SendHumidity
brcs sendSI7021Humidity_okay
; set timer to 1s to retry later
ldi xl, LOW(sramTimerSI7021SendHumidity)
ldi xh, HIGH(sramTimerSI7021SendHumidity)
rjmp Timer_SetValueTo1s
sendSI7021Humidity_okay:
ret
sendSI7021Temp:
rcall SI7021_SendTemp
brcs sendSI7021Temp_okay
; set timer to 1s to retry later
ldi xl, LOW(sramTimerSI7021SendTemp)
ldi xh, HIGH(sramTimerSI7021SendTemp)
rjmp Timer_SetValueTo1s
sendSI7021Temp_okay:
ret
#endif
#ifdef MODULES_DS18B20
sendDs18b20Temp:
rcall Ds18b20_SendTemp
brcs sendDs18b20Temp_okay
; set timer to 1s to retry later
ldi xl, LOW(sramSendDs18b20TempTimer)
ldi xh, HIGH(sramSendDs18b20TempTimer)
rjmp Timer_SetValueTo1s
sendDs18b20Temp_okay:
ret
#endif
; ---------------------------------------------------------------------------
; Called every 100ms. Add your routine calls here. No arguments, no results.
onEvery100ms:
onSystemTimerTick:
#ifdef MODULES_LED_SIMPLE
rcall LedSimple_Every100ms
#endif
#ifdef MODULES_REED
rcall REED_Every100ms
#endif
#ifdef MODULES_MOTION
rcall Motion_Every100ms
#endif
ret
; ---------------------------------------------------------------------------
; @routine onPacketReceived:
;
; Called after a packet was received via COM module. Add your routine calls here.
;
; The packet will be released in any case after return from this call.
;
; @return CFLAG set if message handled, cleared otherwise
; @param X pointer to received buffer
; @clobbers all
onPacketReceived:
#ifdef MODULES_MOTION_LIGHT
rcall MotionLight_OnPacketReceived
brcs onPacketReceived_end
#endif
#ifdef MODULES_SK6812
rcall SK6812_OnPacketReceived
brcs onPacketReceived_end
#endif
#ifdef MODULES_REED
rcall REED_OnPacketReceived
brcs onPacketReceived_end
#endif
#ifdef MODULES_COM
rcall CPRO_OnPacketReceived
brcs onPacketReceived_end
#endif
clc
onPacketReceived_end:
ret
; @end

View File

@@ -33,12 +33,8 @@ main:
; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
rcall systemSetSpeed
rcall initModules
rcall Utils_SetupUid
rcall initModules
rcall initialWait
sei ; Enable interrupts

View File

@@ -26,6 +26,7 @@
twimaster
uart_bitbang
uart_irq
bootloader
</subdirs>
</gwbuild>

View File

@@ -0,0 +1,11 @@
<?xml?>
<gwbuild>
<extradist>
main.asm
</extradist>
</gwbuild>

View File

@@ -9,42 +9,53 @@
; ***************************************************************************
; data
.dseg
flashDataBegin:
flashUid: .byte 4
flashSendBuffer: .byte 32
flashRecvBuffer: .byte FLASH_RECVBUFFER_MAXLEN
flashDataEnd:
; ***************************************************************************
; code
.cseg
FLASH_PROTO_BEGIN:
BOOTLOADER_BEGIN:
bootLoader:
cli
; 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
; start by setting all ports as inputs and enable internal pull-up resistors
ldi r16, 0xff
clr r17
.ifdef PORTA
out DDRA, r17 ; all input
out PORTA, r16 ; enable pull-up on all
.endif
.ifdef PORTB
out DDRB, r17 ; all input
out PORTB, r16 ; enable pull-up on all
.endif
.ifdef PORTC
out DDRC, r17 ; all input
out PORTC, r16 ; enable pull-up on all
.endif
rcall systemSetSpeed
; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
sbi LED_DDR, LED_PINNUM ; out
cbi LED_PORT, LED_PINNUM ; on
ldi r16, 30
rcall flashWaitForMulti100ms
rcall flashReadUidIntoSdram ; R16, X, Y
rcall checkFlash ; (r16, r17, r18, r19, r20, r22, x, y, z)
brcc bootLoader_startFirmware ; no flash process, try to start installed firmware
rcall flashProcess ; received a FLASH START msg, handle flashing
@@ -75,7 +86,7 @@ bootSecRet:
FLASH_PROTO_END:
.equ MODULE_SIZE_FLASH_PROTO = FLASH_PROTO_END-FLASH_PROTO_BEGIN
BOOTLOADER_END:
.equ MODULE_SIZE_BOOTLOADER = BOOTLOADER_END-BOOTLOADER_BEGIN

View File

@@ -3,16 +3,13 @@
<gwbuild>
<extradist>
bootloader.asm
defs.asm
flash.asm
flash_ready.asm
flash_rsp.asm
hdl_flash_data.asm
hdl_flash_end.asm
hdl_flash_start.asm
recv.asm
send.asm
flashprocess.asm
io.asm
io_attn.asm
io_bitbang.asm
io_uart1.asm
wait.asm
</extradist>

View File

@@ -1,5 +1,5 @@
This implements the boot loader. It can be used to flash new firmware to node.
This implements the boot loader. It can be used to flash new firmware to nodes.
How it works

View File

@@ -1,218 +0,0 @@
; ***************************************************************************
; copyright : (C) 2023 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. *
; ***************************************************************************
.equ FLASH_ERROR_NONE = 0
.equ FLASH_ERROR_MSGERROR = 1
.equ FLASH_RECVBUFFER_MAXLEN = 128
.equ FLASH_CMD_FLASH_RSP = 74
.equ FLASH_MSG_OFFS_DESTADDR = 0
.equ FLASH_MSG_OFFS_MSGLEN = 1
.equ FLASH_MSG_OFFS_MSGDATA = 2
.equ FLASH_MSG_OFFS_CMD = 2 ; first at COM2_MSG_OFFS_MSGDATA
.equ FLASH_MSG_OFFS_SRCADDR = 3
.equ FLASH_MSG_OFFS_PAYLOAD = 4 ; payload for the cmd follows here
.equ FLASH_PACKET_DATA_OFFS_ADDR = FLASH_MSG_OFFS_PAYLOAD+0 ; 4 bytes
.equ FLASH_PACKET_DATA_OFFS_DATA = FLASH_MSG_OFFS_PAYLOAD+4 ; n bytes
.equ FLASH_PACKET_START_OFFS_UID = FLASH_MSG_OFFS_PAYLOAD+0 ; 4 bytes
; ***************************************************************************
; data
.dseg
flashDataBegin:
flashUid: .byte 4
flashSendBuffer: .byte 32
flashRecvBuffer: .byte FLASH_RECVBUFFER_MAXLEN
flashDataEnd:
; ***************************************************************************
; code
.cseg
FLASH_PROTO_BEGIN:
bootLoader:
cli ; disable interrupts throughout the whole process
; 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
; start by setting all ports as inputs and enable internal pull-up resistors
ldi r16, 0xff
clr r17
.ifdef PORTA
out DDRA, r17 ; all input
out PORTA, r16 ; enable pull-up on all
.endif
.ifdef PORTB
out DDRB, r17 ; all input
out PORTB, r16 ; enable pull-up on all
.endif
.ifdef PORTC
out DDRC, r17 ; all input
out PORTC, r16 ; enable pull-up on all
.endif
; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
; setup pins and interrupts
cbi COM_DATA_DDR, COM_DATA_PIN ; set TXD port as input
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable internal pullup for TXD
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
sbi LED_DDR, LED_PINNUM ; out
cbi LED_PORT, LED_PINNUM ; on
rcall flashReadUid
ldi xh, HIGH(flashUid)
ldi xl, LOW(flashUid)
st X+, r18
st X+, r19
st X+, r20
st X+, r21
; wait for 3 secs before doing anything else
ldi r16, 30
rcall flashWaitForMulti100ms
rcall bootCheckFlash
brcc bootLoader_startFirmware ; no flash process, try start installed firmware
rcall bootLoaderFlash ; received a FLASH START msg, handle flashing
brcc bootLoader_waitAndRestartBootLoader
; try to start firmware
bootLoader_startFirmware:
cbi LED_PORT, LED_PINNUM ; on
ldi r16, 10
rcall flashWaitForMulti100ms
sbi LED_PORT, LED_PINNUM ; off
ldi r16, 3
rcall flashWaitForMulti100ms
cbi LED_PORT, LED_PINNUM ; on
ldi r16, 10
rcall flashWaitForMulti100ms
sbi LED_PORT, LED_PINNUM ; off
rjmp firmwareStart
bootLoader_waitAndRestartBootLoader:
sbi LED_PORT, LED_PINNUM ; off
ldi r16, 20
rcall flashWaitForMulti100ms
rjmp bootLoader
; ---------------------------------------------------------------------------
; check for incoming flash request
;
; send a FLASH_READY message and wait for about 10s for incoming FLASH_START which is then handled.
;
; IN:
; - R16: message type to receive
; - R17: wait time in 100ms (1=100ms, 2=200ms etc.)
; OUT:
; - CFLAG: set if incoming flash request received, cleared otherwise
; - R16: message type received (if CFLAG set)
; REGS: R16, R17, X, Y, (R1, R2, R18, R19, R20, R21, R22, R24, R25)
bootCheckFlash:
; send flash ready message
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall flashWriteFlashReady ; (R16, R17, R18, R19, R20, Y, Z)
rcall flashSendPacketUntilSuccess ; (R16, R17, R18, R21, R22, R24, R25, X)
bootCheckFlash_loop:
; wait up to 10s for incoming FLASH_START message
ldi r16, CPRO_CMD_FLASH_START
ldi r17, 100 ; 100*100ms=10s
rcall flashWaitForSpecificMessageWithLed ; R2, R16, R17 (R1, R24, R25, X)
brcc bootRet
; either FLASH_START or FLASH_END received
cpi r16, CPRO_CMD_FLASH_START ; not FLASH_START, no flashing requested
brne bootClcRet
; received FLASH_START
rcall flashHandleFlashStart
brcc bootCheckFlash_loop
ret ; ret with CARRY flag set
bootLoaderFlash:
bootLoaderFlash_loop1:
; wait up to 10s for incoming FLASH_DATA message
ldi r16, CPRO_CMD_FLASH_DATA
ldi r17, 100 ; 100*100ms=10s
rcall flashWaitForSpecificMessageWithLed
brcc bootRet
; either FLASH_DATA or FLASH_END received
cpi r16, CPRO_CMD_FLASH_DATA ; not FLASH_DATA, flashing ended/aborted
brne bootSecRet ; FLASH_END received, done
; flash data
rcall flashHandleFlashData
rjmp bootLoaderFlash_loop1
bootLoaderFlash_endReceived:
rjmp flashHandleFlashEnd
bootClcRet:
clc
bootRet:
ret
bootSecRet:
sec
ret
FLASH_PROTO_END:
.equ MODULE_SIZE_FLASH_PROTO = FLASH_PROTO_END-FLASH_PROTO_BEGIN

View File

@@ -1,61 +0,0 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Write a FLASH_READY packet.
;
; IN:
; - X : buffer to write to
; OUT:
; - nothing
; MODIFIED REGS: R16, R18, Y, Z (R17, R19, R20)
flashWriteFlashReady:
ldi r16, 0xff
st X+, r16 ; dest address (unused)
ldi r16, 20 ; msg code+src address+18 payload bytes
st X+, r16 ; msg len
ldi r16, CPRO_CMD_FLASH_READY
st X+, r16 ; msg code
ldi r16, COM2_MAINTENANCE_ADDR
st X+, r16 ; src address
; payload
ldi yh, HIGH(flashUid) ; 4 bytes
ldi yl, LOW(flashUid)
ldi r18, 4
rcall Utils_Copy_SDRAM ; (R17, R18, X, Y)
ldi zl, LOW(devInfoBlock*2) ; 12 bytes
ldi zh, HIGH(devInfoBlock*2)
ldi r18, 12
rcall Utils_CopyFromFlash ; (R16, R18, X, Z)
ldi r16, LOW(PAGESIZE*2) ; 2 bytes
st X+, r16
ldi r16, HIGH(PAGESIZE*2)
st X+, r16
sbiw xh:xl, 22 ; go back to beginning of message
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 23 ; go back to beginning of message
ret

View File

@@ -1,66 +0,0 @@
; ***************************************************************************
; copyright : (C) 2023 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
#if 0
; ---------------------------------------------------------------------------
; Create and send a FLASH RESPONSE packet
;
; IN:
; - R16: response code to send
; OUT:
; - nothing
; REGS: r16, X (R15, R17, R18, R19, R20, R21, R22)
flashSendFlashResponse:
; send flash ready message
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall flashWriteFlashRsp ; (R16, R17, R18, R19, R20)
rjmp flashSendPacketUntilSuccess ; (R15, R16, R17, R21, R22, X)
#endif
; ---------------------------------------------------------------------------
; Write a FLASH_RESPONSE packet.
;
; IN:
; - R16: response code (0 if ok, error code otherwise)
; - X : buffer to write to
; OUT:
; - nothing
; MODIFIED REGS: R16, R17 (R18, R19, R20)
flashWriteFlashRsp:
clr r18
st X+, r18 ; dest address (unused)
ldi r18, 3 ; msg code+src address+one payload byte
st X+, r18 ; msg len
ldi r17, CPRO_CMD_FLASH_RSP
st X+, r17 ; msg code
clr r17
st X+, r17 ; src address (not used)
st X+, r16 ; payload byte
sbiw xh:xl, 5
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 6
ret

View File

@@ -9,6 +9,22 @@
; ***************************************************************************
; data
.dseg
flashDataBegin:
flashUid: .byte 4
flashSendBuffer: .byte 32
flashRecvBuffer: .byte FLASH_RECVBUFFER_MAXLEN
flashDataEnd:
; ***************************************************************************
; code
.cseg
@@ -23,15 +39,16 @@
; @clobbers r16, r20, X, (r17, r18, r19, r22, y, z)
checkFlash:
rcall flashInitIo ; (R16, R17)
rcall flashReadUidIntoSdram ; R16, X, Y
rcall ioRawInit ; (R16, R17)
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall flashProcessWriteFlashReady ; (R16, R17, R18, R19, R20, Y, Z)
rcall flashRawSendMsg ; (r16, r17, X)
rcall ioRawSendMsg ; (r16, r17, X)
ldi r16, CPRO_CMD_FLASH_START
ldi r20, 10 ; wait for up to 10s
rcall flashWaitForGivenMsg ; (r16, r17, r18, r19, r20, r22, X)
rcall ioWaitForGivenMsg ; (r16, r17, r18, r19, r20, r22, X)
brcc checkFlash_end
cpi r16, CPRO_CMD_FLASH_START
@@ -66,8 +83,8 @@ flashProcess:
flashProcess_loop1:
; wait up to 10s for incoming FLASH_DATA message
ldi r16, CPRO_CMD_FLASH_DATA
ldi r20, 5 ; wait for 5s
rcall flashWaitForGivenMsg ; (r16, r17, r18, r19, r20, r22, X)
ldi r20, 5 ; wait for 5s (not used!)
rcall ioWaitForGivenMsg ; (r16, r17, r18, r19, r20, r22, X)
brcc flashProcess_end ; no FLASH_DATA or FLASH_END msg
; either FLASH_DATA or FLASH_END received
ldi xl, LOW(flashRecvBuffer)
@@ -156,17 +173,17 @@ flashProcessHandleFlashData:
ld zh, X+ ; address (high)
adiw xh:xl, 2 ; ignore high bytes, points to first data byte now
push zl
push zh
flashProcessHandleFlashData_loop:
ld r0, X+
ld r1, X+
rcall Flash_WriteIntoPage ; (R15, R16, Z+)
subi r18, 2
brne flashProcessHandleFlashData_loop
pop zh
pop zl
rcall Flash_FinishPage ; (R15, R16, R20)
; push zl
; push zh
;flashProcessHandleFlashData_loop:
; ld r0, X+
; ld r1, X+
; rcall Flash_WriteIntoPage ; (R15, R16, Z+)
; subi r18, 2
; brne flashProcessHandleFlashData_loop
; pop zh
; pop zl
; rcall Flash_FinishPage ; (R15, R16, R20)
clr r16
rjmp flashProcessHandleFlashData_sendResponse
flashProcessHandleFlashData_badData:
@@ -210,7 +227,7 @@ flashProcessSendFlashResponse:
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall flashProcessWriteFlashRsp ; (R16, R17, R18, R19, R20, X)
rjmp flashRawSendMsg ; (R16, R17, X)
rjmp ioRawSendMsg ; (R16, R17, X)
; @end

View File

@@ -1,62 +0,0 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Handle FLASH DATA packet.
;
; IN:
; - X : buffer containing the message
; OUT:
; - CFLAG: set if message is for us, cleared otherwise
; REGS: R0, R1, R15, R16, R17, R18, R19, R20, R21, R24, R25, X, Z
flashHandleFlashData:
adiw xh:xl, FLASH_MSG_OFFS_MSGLEN
ld r18, X ; length (subtract 6
cpi r18, 6 ; cmd(1), src(1), addr(4)
brcs flashHandleFlashData_badData
subi r18, 6 ; remaining length
adiw xh:xl, FLASH_PACKET_DATA_OFFS_ADDR-FLASH_MSG_OFFS_MSGLEN
ld zl, X+ ; address (low)
ld zh, X+ ; address (high)
adiw xh:xl, 2 ; ignore high bytes, points to first data byte now
; rcall Flash_StartPage ; (R0, R1, R16, R20, R24, R25)
push zl
push zh
flashHandleFlashData_loop:
ld r0, X+
ld r1, X+
rcall Flash_WriteIntoPage ; (R15, R16, Z+)
subi r18, 2
brne flashHandleFlashData_loop
pop zh
pop zl
rcall Flash_FinishPage ; (R15, R16, R20)
clr r16
rjmp flashHandleFlashData_sendResponse
flashHandleFlashData_badData:
ldi r16, FLASH_ERROR_MSGERROR
flashHandleFlashData_sendResponse:
rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X)
sec
ret

View File

@@ -1,38 +0,0 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; Handle FLASH END packet.
;
; IN:
; - X : buffer containing the message
; OUT:
; - CFLAG: set if message is for us, cleared otherwise
; REGS: r16, r18. r19. r20, r21, X (R15, R17, R22)
flashHandleFlashEnd:
rcall flashWaitFor100ms
clr r16
rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X)
sec
ret

View File

@@ -1,73 +0,0 @@
; ***************************************************************************
; copyright : (C) 2023 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 flashHandleFlashStart
; Handle FLASH START packet.
;
; @return CFLAG set if message is for us, cleared otherwise
; @param X buffer containing the message
; @clobbers r16, (R15, R17, R18, R19, R20, R21, R22, X)
flashHandleFlashStart:
rcall flashCheckFlashStart
brcc flashHandleFlashStart_notMe
; okay, flash start message is for us
rcall flashWaitFor100ms
clr r16
rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X)
sec
ret
flashHandleFlashStart_notMe:
ret
; @end
; ---------------------------------------------------------------------------
; @routine flashCheckFlashStart
;
; Check whether the UID in the given msg matches our UID.
;
; @return CFLAG set if message is for us, cleared otherwise
; @param X buffer containing the message
; @clobbers r16, r17, r18, X, Y
flashCheckFlashStart:
ldi yh, HIGH(flashUid)
ldi yl, LOW(flashUid)
adiw xh:xl, FLASH_PACKET_START_OFFS_UID
ldi r18, 4
flashCheckFlashStart_loop:
ld r16, X+
ld r17, Y+
cp r16, r17
brne flashCheckFlashStart_notMe
dec r18
brne flashCheckFlashStart_loop
sec
ret
flashCheckFlashStart_notMe:
clc
ret
; @end

View File

@@ -16,7 +16,7 @@
; ---------------------------------------------------------------------------
; @routine flashWaitForGivenMsg
; @routine ioWaitForGivenMsg
; Wait for incoming msg with given command
;
; @return CFLAG set if okay (packet received), cleared on error
@@ -25,28 +25,28 @@
; @param r20 time in seconds to wait for a message
; @clobbers: r16, r17, r20, X (r18, r19, r22)
flashWaitForGivenMsg:
flashWaitForGivenMsg_loop:
ioWaitForGivenMsg:
ioWaitForGivenMsg_loop:
push r16
rcall flashRawWaitForValidMsg ; (r16, r17, r18, r19, r22, X)
rcall ioRawWaitForValidMsg ; (r16, r17, r18, r19, r22, X)
pop r16
brcc flashWaitForGivenMsg_end
brcc ioWaitForGivenMsg_end
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
adiw xh:xl, COM2_MSG_OFFS_CMD
ld r17, X
sbiw xh:xl, COM2_MSG_OFFS_CMD
cp r16, r17
breq flashWaitForGivenMsg_gotIt
breq ioWaitForGivenMsg_gotIt
cpi r16, CPRO_CMD_FLASH_END
breq flashWaitForGivenMsg_gotIt
breq ioWaitForGivenMsg_gotIt
dec r20
brne flashWaitForGivenMsg_loop
brne ioWaitForGivenMsg_loop
clc
rjmp flashWaitForGivenMsg_end
flashWaitForGivenMsg_gotIt:
rjmp ioWaitForGivenMsg_end
ioWaitForGivenMsg_gotIt:
sec
flashWaitForGivenMsg_end:
ioWaitForGivenMsg_end:
ret
; @end

View File

@@ -16,28 +16,52 @@
; ---------------------------------------------------------------------------
; @routine flashWaitForAttnState
; @routine ioWaitForAttnState100ms
;
; @param r16 expected state (0x00 or 0xff)
; @param r17 time to wait for expected state (in milliseconds)
; @clobbers
; @param r17 time to wait for expected state (in 100 ms units)
; @clobbers R17 (R22, R24)
flashWaitForAttnState:
flashWaitForAttnState_loop:
rcall flashWaitForAttnState1ms ; (R22, R24)
brcs flashWaitForAttnState_stateReached
ioWaitForAttnState100ms:
ioWaitForAttnState100ms_loop:
push r17
ldi r17, 100
rcall ioWaitForAttnStateMilliSeconds ; (R22, R24)
pop r17
brcs ioWaitForAttnState100ms_stateReached
dec r17
brne flashWaitForAttnState_loop
brne ioWaitForAttnState100ms_loop
clc
ret
flashWaitForAttnState_stateReached:
ioWaitForAttnState100ms_stateReached:
ret
; @end
; ---------------------------------------------------------------------------
; @routine flashWaitForAttnState1ms
; @routine ioWaitForAttnStateMilliSeconds
;
; @param r16 expected state (0x00 or 0xff)
; @param r17 time to wait for expected state (in milliseconds)
; @clobbers R17 (R22, R24)
ioWaitForAttnStateMilliSeconds:
ioWaitForAttnStateMilliSeconds_loop:
rcall ioWaitForAttnState1ms ; (R22, R24)
brcs ioWaitForAttnStateMilliSeconds_stateReached
dec r17
brne ioWaitForAttnStateMilliSeconds_loop
clc
ret
ioWaitForAttnStateMilliSeconds_stateReached:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioWaitForAttnState1ms
;
; Wait for up to 1ms for ATTN line to reach the given state
;
@@ -45,22 +69,23 @@ flashWaitForAttnState_stateReached:
; @param R16 expected state (0xff for high, 0 for low)
; @clobbers R24 (R22)
flashWaitForAttnState1ms:
ioWaitForAttnState1ms:
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
ldi r24, 100
flashWaitForAttnState1ms_loop:
ioWaitForAttnState1ms_loop:
push r17
in r17, COM_ATTN_INPUT
eor r17, r16
andi r17, (1<<COM_ATTN_PIN)
pop r17
breq flashWaitForAttnState1ms_stateReached
breq ioWaitForAttnState1ms_stateReached
rcall Utils_WaitFor10MicroSecs ; wait for 10us (R22)
dec r24
brne flashWaitForAttnState1ms_loop
rjmp flash_recv_clc_ret
flashWaitForAttnState1ms_stateReached:
brne ioWaitForAttnState1ms_loop
clc
ret
ioWaitForAttnState1ms_stateReached:
sec
ret
; @end

View File

@@ -0,0 +1,87 @@
; ***************************************************************************
; 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.
;
; @clobbers none
ioRawInit:
; setup pins and interrupts
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA port as input
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable internal pullup for TXD
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
ret
;@end
; ---------------------------------------------------------------------------
; @routine ioRawSendMsg
; Send a message
;
; @clobbers X (R16, R17, R21, R22)
ioRawSendMsg:
ioRawSendMsg_loop:
ldi r16, 0xff ; expect ATTN high
ldi r17, 3
rcall ioWaitForAttnState100ms ; wait for up to 300ms
brcs ioRawSendMsg_attnHigh
ret
ioRawSendMsg_attnHigh:
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall uartBitbang_SendPacket ; R16, R22 (R17, R21, X)
brcc ioRawSendMsg_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawWaitForValidMsg
; Wait for valid incoming msg
;
; @return CFLAG set if okay (packet received), cleared on error
; @clobbers:
ioRawWaitForValidMsg:
ldi r16, 0 ; expect ATTN low
ldi r17, 100
rcall ioWaitForAttnState100ms ; wait for up to 10s
brcs ioRawWaitForValidMsg_attnLow
ret
ioRawWaitForValidMsg_attnLow:
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
ldi r16, COM2_MAINTENANCE_ADDR
ldi r17, FLASH_RECVBUFFER_MAXLEN-3
rcall uartBitbang_ReceivePacketIntoBuffer
brcs ioRawWaitForValidMsg_packetReceived
ret
ioRawWaitForValidMsg_packetReceived:
ldi r16, 0xff ; expect ATTN high
ldi r17, 100
rjmp ioWaitForAttnState100ms ; wait for up to 10s
; @end

View File

@@ -17,24 +17,24 @@
; ---------------------------------------------------------------------------
; @routine flashInitIo
; @routine ioRawInit
; Send a message
;
; @clobbers r16, r17
flashInitIo:
ioRawInit:
rjmp UART_HW_Uart1_RawInit ; (R16, R17)
;@end
; ---------------------------------------------------------------------------
; @routine flashRawSendMsg
; @routine ioRawSendMsg
; Send a message
;
; @clobbers r16, r17, X
flashRawSendMsg:
ioRawSendMsg:
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rjmp UART_HW_Uart1_RawSendPacket ; (r16, r17, X)
@@ -43,28 +43,30 @@ flashRawSendMsg:
; ---------------------------------------------------------------------------
; @routine flashRawWaitForValidMsg
; @routine ioRawWaitForValidMsg
; Wait for valid incoming msg
;
; @return CFLAG set if okay (packet received), cleared on error
; @clobbers: r16, r17, r18 (r19, r22, X)
flashRawWaitForValidMsg:
ioRawWaitForValidMsg:
rcall UART_HW_Uart1_EnableRawRecv ; (R16)
flashRawWaitForValidMsg_loop:
ioRawWaitForValidMsg_loop:
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
ldi r16, COM2_MAINTENANCE_ADDR
ldi r17, FLASH_RECVBUFFER_MAXLEN-3
ldi r18, 10 ; 10s
rcall UART_HW_Uart1_RawRecvPacket ; (r16, r17, r18, r19, r22, X)
brcc flashRawWaitForValidMsg_error
brcc ioRawWaitForValidMsg_error
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
rcall com2CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
brcc flashRawWaitForValidMsg_loop ; invalid msg, try next
brcc ioRawWaitForValidMsg_loop ; invalid msg, try next
rcall UART_HW_Uart1_DisableRawRecv ; (R16)
sec
ret
flashRawWaitForValidMsg_error:
ioRawWaitForValidMsg_error:
rcall UART_HW_Uart1_DisableRawRecv ; (R16)
clc
ret

View File

@@ -1,123 +0,0 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; wait for a specific message to arrive within given time, flashing LED
;
; IN:
; - R16: message type to receive
; - R17: wait time in 100ms (1=100ms, 2=200ms etc.)
; OUT:
; - CFLAG: set if msg received (either expected msg or FLASH_END), cleared otherwise
; - R16: message type received (if CFLAG set)
; REGS: R2, R16, R17 (R1, R24, R25, X)
flashWaitForSpecificMessageWithLed:
mov r2, r16
sbi LED_PORT, LED_PINNUM ; off
flashWaitForSpecificMessageWithLed_loop:
sbi LED_PIN, LED_PINNUM ; toggle
mov r16, r2
push r17
ldi r17, 100 ; wait up to 100ms
rcall flashWaitForSpecificMessage ; (R1, R16, R17, R24, R25, X)
pop r17
brcs flashWaitForSpecificMessageWithLed_received
dec r17
brne flashWaitForSpecificMessageWithLed_loop
sbi LED_PORT, LED_PINNUM ; off
rjmp flash_recv_clc_ret ; timeout
flashWaitForSpecificMessageWithLed_received:
sbi LED_PORT, LED_PINNUM ; off
rjmp flash_recv_sec_ret
; ---------------------------------------------------------------------------
; wait for a specific message to arrive within given time.
;
; IN:
; - R16: msg command to wait for
; - R17: time to wait for packet (in milliseconds)
; OUT:
; - CFLAG: set if msg received, cleared on timeout
; - R16 : message type received
; REGS: R1, R16, R17, X (R24, R25)
flashWaitForSpecificMessage:
mov r1, r16 ; expected message type
flashWaitForSpecificMessage_loop0:
; wait for ATTN to go low
flashWaitForSpecificMessage_loop1:
ldi r16, 0 ; wait for low
rcall flashWaitForAttnState1ms ; (R22, R24)
brcs flashWaitForSpecificMessage_isLow
dec r17
brne flashWaitForSpecificMessage_loop1
rjmp flash_recv_clc_ret ; timeout
; receive message
flashWaitForSpecificMessage_isLow: ; is low, receive message, check for msg type
push r17
ldi r16, COM2_MAINTENANCE_ADDR
ldi r17, FLASH_RECVBUFFER_MAXLEN-3
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
rcall uartBitbang_ReceivePacketIntoBuffer
pop r17
brcc flashWaitForSpecificMessage_waitAttnHigh
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
adiw xh:xl, COM2_MSG_OFFS_CMD
ld r16, X
sbiw xh:xl, COM2_MSG_OFFS_CMD
cp r16, r1
breq flashWaitForSpecificMessage_received
cpi r16, CPRO_CMD_FLASH_END
breq flashWaitForSpecificMessage_received
flashWaitForSpecificMessage_waitAttnHigh:
dec r17
breq flash_recv_clc_ret
; wait for ATTN to go high
flashWaitForSpecificMessage_loop2:
ldi r16, 0xff ; wait for high
rcall flashWaitForAttnState1ms ; (R22, R24)
brcs flashWaitForSpecificMessage_isHigh
dec r17
brne flashWaitForSpecificMessage_loop2
rjmp flash_recv_clc_ret ; timeout
flashWaitForSpecificMessage_isHigh:
rjmp flashWaitForSpecificMessage_loop0
flashWaitForSpecificMessage_received: ; R16 contains message type
rjmp flash_recv_sec_ret
flash_recv_clc_ret:
clc
ret
flash_recv_sec_ret:
sec
ret

View File

@@ -1,65 +0,0 @@
; ***************************************************************************
; copyright : (C) 2023 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
; ---------------------------------------------------------------------------
; wait indefinately until ATTN line is high, send packet over wire, retry until successfull
;
; IN:
; - x : ptr to buffer to send
; OUT:
; - nothing
; REGS: (R16, R17, R18, R21, R22, R24, R25, X)
flashSendPacketUntilSuccess:
push xl
push xh
rcall uartBitbang_SendPacket ; (R16, R17, R21, R22, X)
pop xh
pop xl
brcc flashSendPacket_error
ret
flashSendPacket_error:
ldi r16, 3
rcall flashWaitForMulti100ms
rcall flashWaitForAttnHigh ; (R16, R17, R18, R22, R24, R25)
rjmp flashSendPacketUntilSuccess
; ---------------------------------------------------------------------------
; wait indefinately for free ATTN line
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: (R16, R17, R18, R22, R24, R25)
flashWaitForAttnHigh:
rcall uartBitbang_WaitForAttnHigh ; (r17, r22)
brcc flashWaitForAttnHigh_stillLow
ret
flashWaitForAttnHigh_stillLow:
rcall flashWaitDependingOnUid ; (R16, R18, R22, R24, R25)
rjmp flashWaitForAttnHigh

View File

@@ -8,10 +8,6 @@
; ***************************************************************************
.dseg
; uartHw_TtyOn1Interface: .byte UART_HW_IFACE_SIZE
.cseg

View File

@@ -92,8 +92,8 @@ UART_HW_Uart1_RawSendPacket_loop:
UART_HW_Uart1_EnableRawRecv:
lds r16, UCSR1B
cbr r16, (1<<RXCIE1) ; disable RX complete interrupt
sbr r16, (1<<RXEN1) ; enable receive
; cbr r16, (1<<RXCIE1) ; disable RX complete interrupt
ori r16, (1<<RXEN1) ; enable receive
sts UCSR1B, r16
ret
; @end
@@ -109,8 +109,8 @@ UART_HW_Uart1_EnableRawRecv:
UART_HW_Uart1_DisableRawRecv:
lds r16, UCSR1B
cbr r16, (1<<RXCIE1) ; disable RX complete interrupt
cbr r16, (1<<RXEN1) ; disable receive
; cbr r16, (1<<RXCIE1) ; disable RX complete interrupt
andi r16, ~(1<<RXEN1) ; disable receive
sts UCSR1B, r16
ret
; @end
@@ -144,6 +144,7 @@ UART_HW_Uart1_RawRecvPacket:
rcall uartHwUart1RawRecvByte ; (R16, R18, R22)
pop r17 ; pop acceptable COM address from R16 to R17
brcc UART_HW_Uart1_RawRecvPacket_error
#ifndef COM_ACCEPT_ALL_DEST ; accept every destination address
; compare destination address (accept "FF" and own address)
cp r16, r17
@@ -242,7 +243,7 @@ uartHwUart1RawWaitForByte1s_loop:
rcall uartHwUart1RawWaitForByte100ms ; (r18, r22)
pop r18
brcs uartHwUart1RawWaitForByte1s_haveByte
; sbi LED_SIMPLE_PORTIN, LED_SIMPLE_PINNUM ; toggle
sbi LED_SIMPLE_PORTIN, LED_SIMPLE_PINNUM ; toggle
dec r18
brne uartHwUart1RawWaitForByte1s_loop
clc
@@ -306,10 +307,3 @@ uartHwUart1RawWaitForByte1ms_haveByte:
.equ COMIO_DisableRawRecv = UART_HW_Uart1_DisableRawRecv