diff --git a/avr/flashproto.asm b/avr/flashproto.asm index 3dbbc51..69d1f27 100644 --- a/avr/flashproto.asm +++ b/avr/flashproto.asm @@ -10,8 +10,7 @@ .equ FLASH_ERROR_NONE = 0 -.equ FLASH_ERROR_BAD_MSGNUM = 1 -.equ FLASH_ERROR_BAD_ADDR = 2 +.equ FLASH_ERROR_MSGERROR = 1 .equ FLASH_CMD_FLASH_RSP = 74 @@ -24,10 +23,10 @@ .equ FLASH_MSG_OFFS_PAYLOAD = 4 ; payload for the cmd follows here -.equ FLASH_PACKET_DATA_OFFS_ADDR = FLASH_MSG_OFFS_PAYLOAD+0 ; 2 bytes -.equ FLASH_PACKET_DATA_OFFS_DATA = FLASH_MSG_OFFS_PAYLOAD+2 ; n bytes - +.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 ; *************************************************************************** @@ -100,17 +99,24 @@ bootLoader: sbi PORTA, PORTA3 ; LED off - ; wait up to 10s for incoming FLASH_START message - ldi r16, CPRO_CMD_FLASH_START - ldi r17, 100 ; 100*100ms=10s - rcall flashWaitForSpecificMessageWithLed - brcc bootLoader_startFirmware - - ; either FLASH_START or FLASH_END received - cpi r16, CPRO_CMD_FLASH_START ; not FLASH_START, no flashing requested - brne bootLoader_startFirmware - ; receive and flash new firmware - +bootLoader_loop1: + ; wait up to 10s for incoming FLASH_START message + ldi r16, CPRO_CMD_FLASH_START + ldi r17, 100 ; 100*100ms=10s + rcall flashWaitForSpecificMessageWithLed + brcc bootLoader_startFirmware + + ; either FLASH_START or FLASH_END received + cpi r16, CPRO_CMD_FLASH_START ; not FLASH_START, no flashing requested + brne bootLoader_startFirmware + ; receive and flash new firmware + + rcall flashHandleFlashStart + brcc bootLoader_loop1 + ; received a FLASH START msg, handle flashing + rcall bootLoaderFlash + brcc bootLoader_waitAndRestartBootLoader + ; try to start firmware bootLoader_startFirmware: sbi PORTA, PORTA3 ; LED off @@ -129,9 +135,38 @@ bootLoader_startFirmware: push r20 push r21 ret +bootLoader_waitAndRestartBootLoader: + sbi PORTA, PORTA3 ; LED off + ldi r16, 20 + rcall flashWaitForMulti100ms + rjmp bootLoader + + +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 bootLoaderFlash_error + + ; either FLASH_DATA or FLASH_END received + cpi r16, CPRO_CMD_FLASH_DATA ; not FLASH_DATA, flashing ended/aborted + brne bootLoaderFlash_end + ; flash data + rcall flashHandleFlashData + rjmp bootLoaderFlash_loop1 +bootLoaderFlash_end: + sec + ret +bootLoaderFlash_error: + clc + ret + + ; --------------------------------------------------------------------------- ; wait for a specific message to arrive within given time, flashing LED ; @@ -180,10 +215,8 @@ flashWaitForSpecificMessageWithLed_received: flashWaitForSpecificMessage: mov r1, r16 ; expected message type - - ; wait for ATTN to go low - flashWaitForSpecificMessage_loop0: + ; wait for ATTN to go low flashWaitForSpecificMessage_loop1: ldi r16, 0 ; wait for low rcall flashWaitForAttnState1ms ; (R22, R24) @@ -191,7 +224,6 @@ flashWaitForSpecificMessage_loop1: dec r17 brne flashWaitForSpecificMessage_loop1 rjmp flashWaitForSpecificMessage_timeout - ; receive message flashWaitForSpecificMessage_isLow: ; is low, receive message, check for msg type push r17 @@ -214,7 +246,6 @@ flashWaitForSpecificMessage_isLow: ; is low, receive message, check for flashWaitForSpecificMessage_waitAttnHigh: dec r17 breq flashWaitForSpecificMessage_timeout - ; wait for ATTN to go high flashWaitForSpecificMessage_loop2: ldi r16, 0xff ; wait for high @@ -226,7 +257,6 @@ flashWaitForSpecificMessage_loop2: flashWaitForSpecificMessage_isHigh: rjmp flashWaitForSpecificMessage_loop0 - flashWaitForSpecificMessage_received: ; R16 contains message type sec ret @@ -428,13 +458,13 @@ flashWriteFlashRsp: ; MODIFIED REGS: R16, Z (R17, R18, R19, R20) flashWriteFlashReady: - clr r16 + ldi r16, 0xff st X+, r16 ; dest address (unused) ldi r16, 12 ; msg code+src address+ten payload bytes st X+, r16 ; msg len ldi r16, CPRO_CMD_FLASH_READY st X+, r16 ; msg code - clr r16 + ldi r16, COM2_MAINTENANCE_ADDR st X+, r16 ; src address (not used) ; payload lds r16, flashUid @@ -466,9 +496,106 @@ flashWriteFlashReady: +; --------------------------------------------------------------------------- +; Handle FLASH START 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) + +flashHandleFlashStart: + lds r18, flashUid + lds r19, flashUid+1 + lds r20, flashUid+2 + lds r21, flashUid+3 + adiw xh:xl, FLASH_PACKET_START_OFFS_UID + ld r16, X+ + cp r16, r18 + brne flashHandleFlashStart_notMe + ld r16, X+ + cp r16, r19 + brne flashHandleFlashStart_notMe + ld r16, X+ + cp r16, r20 + brne flashHandleFlashStart_notMe + ld r16, X + cp r16, r21 + brne flashHandleFlashStart_notMe + ; okay, flash start message is for us + rcall flashWaitFor100ms + rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X) + sec + ret +flashHandleFlashStart_notMe: + clc + ret +; --------------------------------------------------------------------------- +; 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 + cpi r18, 2+2+4 ; dest, msglen + cmd, src + addr + brcs flashHandleFlashData_badData + subi r18, 2+2+4 ; 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 + + cbi PORTA, PORTA2 ; on (debug) + rcall Flash_StartPage ; (R0, R1, R15, 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) + sbi PORTA, PORTA2 ; off (debug) + 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 + + + +; --------------------------------------------------------------------------- +; 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) + clr r16 + rcall flashWriteFlashRsp ; (R16, R17, R18, R19, R20) + rjmp flashSendPacketUntilSuccess ; (R15, R16, R17, R21, R22, X) +