; *************************************************************************** ; 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