diff --git a/apps/aqhome-tool/flash.c b/apps/aqhome-tool/flash.c index dd4269c..bc0a71c 100644 --- a/apps/aqhome-tool/flash.c +++ b/apps/aqhome-tool/flash.c @@ -21,6 +21,8 @@ #include "aqhome/msg/msg_flashstart.h" #include "aqhome/msg/msg_flashresponse.h" #include "aqhome/msg/msg_flashdata.h" +#include "aqhome/msg/msg_flashend.h" +#include "aqhome/msg/msg_reboot.h" #include "aqhome/hexfile/hexfile.h" #include "aqhome/hexfile/flashrecord.h" @@ -39,19 +41,22 @@ #define FLASH_TOOL_MAX_REPEAT 16 -#define DEBUG_FLASH +/*#define DEBUG_FLASH*/ static int _doFlash(GWEN_DB_NODE *dbArgs); static GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, unsigned int uid, int timeoutInSeconds); +static int _sendRebootRequest(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid); static int _sendFlashStart(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid); static int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds); +static int _waitForRebootResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds); static int _sendFlashData(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, const AQH_FLASHRECORD *flashRecord, uint16_t pageSize, int timeoutInSeconds); +static int _sendFlashEnd(GWEN_MSG_ENDPOINT *epTcp, int reason); @@ -115,6 +120,17 @@ int AQH_Tool_Flash(GWEN_DB_NODE *dbGlobalArgs, int argc, char **argv) I18S("Specify timeout in seconds for PONG response"), I18S("Specify timeout in seconds for PONG response") }, + { + 0, /* flags */ + GWEN_ArgsType_Int, /* type */ + "reboot", /* name */ + 0, /* minnum */ + 1, /* maxnum */ + "R", /* short option */ + NULL, /* long option */ + I18S("Request node reboot before trying to flash"), + I18S("Request node reboot before trying to flash") + }, { GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */ GWEN_ArgsType_Int, /* type */ @@ -161,6 +177,7 @@ int _doFlash(GWEN_DB_NODE *dbArgs) GWEN_MSG_ENDPOINT *epTcp; int rv; int timeoutInSeconds; + int doReboot; const char *s; unsigned int uid; const char *hexFilename; @@ -171,6 +188,7 @@ int _doFlash(GWEN_DB_NODE *dbArgs) /* read data */ timeoutInSeconds=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 30); + doReboot=GWEN_DB_GetIntValue(dbArgs, "reboot", 0, 0); s=GWEN_DB_GetCharValue(dbArgs, "uid", 0, NULL); if (1!=sscanf(s, "%x", &uid)) { DBG_ERROR(NULL, "Bad uid \"%s\"", s); @@ -215,6 +233,25 @@ int _doFlash(GWEN_DB_NODE *dbArgs) return 3; } + if (doReboot) { + /* send REBOOT_REQUEST message */ + DBG_INFO(NULL, "Sending REBOOT REQUEST message"); + rv=_sendRebootRequest(epTcp, uid); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + GWEN_MsgEndpointMgr_free(emgr); + return 3; + } + + rv=_waitForRebootResponseMessage(emgr, epTcp, timeoutInSeconds); + if (rv!=0) { + DBG_INFO(NULL, "Bad or no reboot response received (%d).", rv); + GWEN_MsgEndpointMgr_free(emgr); + return 3; + } + DBG_INFO(NULL, "REBOOT_RESPONSE message received"); + } + /* wait for FLASH_READY message */ msg=_waitForFlashReadyMessageForUid(emgr, epTcp, uid, timeoutInSeconds); if (msg==NULL) { @@ -259,6 +296,14 @@ int _doFlash(GWEN_DB_NODE *dbArgs) flashRecord=AQH_FlashRecord_List_Next(flashRecord); } + rv=_sendFlashEnd(epTcp, 0); + if (rv<0) { + DBG_INFO(NULL, "here (%d)", rv); + GWEN_MsgEndpointMgr_free(emgr); + return 4; + } + + GWEN_MsgEndpointMgr_free(emgr); return 0; } @@ -295,6 +340,21 @@ GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ +int _waitForRebootResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds) +{ + GWEN_MSG *msg; + + msg=Utils_WaitForSpecificNodeMessage(emgr, epTcp, AQH_MSG_TYPE_REBOOT_RSP, 0, timeoutInSeconds); + if (msg==NULL) { + DBG_INFO(NULL, "No REBOOT_RSP message received."); + return GWEN_ERROR_IO; + } + GWEN_Msg_free(msg); + return 0; +} + + + int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds) { GWEN_MSG *msg; @@ -312,6 +372,25 @@ int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT +int _sendRebootRequest(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid) +{ + GWEN_MSG *msgNode; + GWEN_MSG *msgOut; + + msgNode=AQH_RebootRequestMsg_new(0, 0xff, AQH_MSG_TYPE_REBOOT_REQ, uid); + if (msgNode==NULL) { + DBG_ERROR(NULL, "Error creating message"); + return GWEN_ERROR_GENERIC; + } + + msgOut=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(msgNode), GWEN_Msg_GetBytesInBuffer(msgNode)); + GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); + GWEN_Msg_free(msgNode); + return 0; +} + + + int _sendFlashStart(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid) { GWEN_MSG *msgNode; @@ -331,6 +410,25 @@ int _sendFlashStart(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid) +int _sendFlashEnd(GWEN_MSG_ENDPOINT *epTcp, int reason) +{ + GWEN_MSG *msgNode; + GWEN_MSG *msgOut; + + msgNode=AQH_FlashEndMsg_new(0, 0xc1, AQH_MSG_TYPE_FLASH_END, reason); + if (msgNode==NULL) { + DBG_ERROR(NULL, "Error creating message"); + return GWEN_ERROR_GENERIC; + } + + msgOut=AQH_ForwardIpcMsg_new(AQH_MSGTYPE_IPC_FORWARD, GWEN_Msg_GetConstBuffer(msgNode), GWEN_Msg_GetBytesInBuffer(msgNode)); + GWEN_MsgEndpoint_AddSendMessage(epTcp, msgOut); + GWEN_Msg_free(msgNode); + return 0; +} + + + int _sendFlashData(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, const AQH_FLASHRECORD *flashRecord, diff --git a/apps/aqhome-tool/utils.c b/apps/aqhome-tool/utils.c index 04f60cb..cdd69ad 100644 --- a/apps/aqhome-tool/utils.c +++ b/apps/aqhome-tool/utils.c @@ -69,10 +69,10 @@ GWEN_MSG *Utils_WaitForSpecificNodeMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG DBG_INFO(NULL, "Received IPC FORWARD message"); nodeMsg=AQH_ForwardIpcMsg_GetCopyOfNodeMsg(msg); if (nodeMsg) { - DBG_ERROR(AQH_LOGDOMAIN, - "Received node msg from %d (%d)", - AQH_NodeMsg_GetSourceAddress(nodeMsg), - AQH_NodeMsg_GetMsgType(nodeMsg)); + DBG_INFO(AQH_LOGDOMAIN, + "Received node msg from %d (%d)", + AQH_NodeMsg_GetSourceAddress(nodeMsg), + AQH_NodeMsg_GetMsgType(nodeMsg)); if (AQH_NodeMsg_GetMsgType(nodeMsg)==msgCode && (nodeAddr==0 || AQH_NodeMsg_GetSourceAddress(nodeMsg)==nodeAddr)) { GWEN_Msg_free(msg); return nodeMsg; diff --git a/aqhome/msg/0BUILD b/aqhome/msg/0BUILD index 6e5b74e..1c9e706 100644 --- a/aqhome/msg/0BUILD +++ b/aqhome/msg/0BUILD @@ -68,6 +68,7 @@ msg_flashresponse.h msg_flashend.h msg_flashdata.h + msg_reboot.h @@ -106,6 +107,7 @@ msg_flashresponse.c msg_flashend.c msg_flashdata.c + msg_reboot.c diff --git a/aqhome/msg/endpoint_log.c b/aqhome/msg/endpoint_log.c index 0fe0045..30c4e78 100644 --- a/aqhome/msg/endpoint_log.c +++ b/aqhome/msg/endpoint_log.c @@ -32,6 +32,7 @@ #include "aqhome/msg/msg_flashresponse.h" #include "aqhome/msg/msg_flashend.h" #include "aqhome/msg/msg_flashdata.h" +#include "aqhome/msg/msg_reboot.h" #include #include @@ -149,6 +150,8 @@ void _logMessage(GWEN_MSG_ENDPOINT *ep, const GWEN_MSG *msg) case AQH_MSG_TYPE_FLASH_RSP: AQH_FlashResponseMsg_DumpToBuffer(msg, dbuf, "received"); break; case AQH_MSG_TYPE_FLASH_END: AQH_FlashEndMsg_DumpToBuffer(msg, dbuf, "received"); break; case AQH_MSG_TYPE_FLASH_DATA: AQH_FlashDataMsg_DumpToBuffer(msg, dbuf, "received"); break; + case AQH_MSG_TYPE_REBOOT_REQ: AQH_RebootRequestMsg_DumpToBuffer(msg, dbuf, "received"); break; + case AQH_MSG_TYPE_REBOOT_RSP: AQH_RebootResponseMsg_DumpToBuffer(msg, dbuf, "received"); break; default: AQH_NodeMsg_DumpToBuffer(msg, dbuf, "received"); break; } } diff --git a/aqhome/msg/msg_node.c b/aqhome/msg/msg_node.c index 5d65764..23b89a6 100644 --- a/aqhome/msg/msg_node.c +++ b/aqhome/msg/msg_node.c @@ -199,23 +199,30 @@ uint32_t AQH_NodeMsg_GetMsgGroup(uint8_t msgType) case AQH_MSG_TYPE_MEMSTATS: case AQH_MSG_TYPE_SYSSTATS: return AQH_MSG_TYPEGROUP_INFO; + case AQH_MSG_TYPE_VALUE: case AQH_MSG_TYPE_VALUE2: return AQH_MSG_TYPEGROUP_VALUES; + case AQH_MSG_TYPE_NEED_ADDRESS: case AQH_MSG_TYPE_HAVE_ADDRESS: case AQH_MSG_TYPE_CLAIM_ADDRESS: case AQH_MSG_TYPE_DENY_ADDRESS: case AQH_MSG_TYPE_ADDRESS_RANGE: return AQH_MSG_TYPEGROUP_ADDRESS; + case AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS: return AQH_MSG_TYPEGROUP_ADMIN; + case AQH_MSG_TYPE_FLASH_START: case AQH_MSG_TYPE_FLASH_END: case AQH_MSG_TYPE_FLASH_READY: case AQH_MSG_TYPE_FLASH_DATA: case AQH_MSG_TYPE_FLASH_RSP: + case AQH_MSG_TYPE_REBOOT_REQ: + case AQH_MSG_TYPE_REBOOT_RSP: return AQH_MSG_TYPEGROUP_FLASH; + default: return 0; } @@ -287,6 +294,8 @@ const char *AQH_NodeMsg_MsgTypeToChar(uint8_t i) case AQH_MSG_TYPE_DEVICE: return "Device"; case AQH_MSG_TYPE_MEMSTATS: return "MemStats"; case AQH_MSG_TYPE_SYSSTATS: return "SysStats"; + case AQH_MSG_TYPE_REBOOT_REQ: return "RebootRequest"; + case AQH_MSG_TYPE_REBOOT_RSP: return "RebootResponse"; default: return "(unknown)"; } } diff --git a/aqhome/msg/msg_node.h b/aqhome/msg/msg_node.h index 9779b16..ad62b54 100644 --- a/aqhome/msg/msg_node.h +++ b/aqhome/msg/msg_node.h @@ -51,6 +51,9 @@ #define AQH_MSG_TYPE_MEMSTATS 81 #define AQH_MSG_TYPE_SYSSTATS 82 +#define AQH_MSG_TYPE_REBOOT_REQ 90 +#define AQH_MSG_TYPE_REBOOT_RSP 91 + /* internal msg types via NET interface */ #define AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS 200 diff --git a/aqhome/msg/msg_reboot.c b/aqhome/msg/msg_reboot.c new file mode 100644 index 0000000..97e4bb9 --- /dev/null +++ b/aqhome/msg/msg_reboot.c @@ -0,0 +1,135 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "aqhome/msg/msg_reboot.h" +#include "aqhome/msg/msg_node.h" + +#include +#include +#include +#include + +#include + + +#define AQH_MSG_OFFS_REBOOT_UID 0 /* 4 bytes */ + +#define AQH_MSG_REBOOT_MINSIZE (AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_REBOOT_UID+4) + + + +static GWEN_MSG *_rebootMsg_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint32_t uid); +static uint32_t _getUid(const GWEN_MSG *msg); +static void _rebootMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText, const char *cmd); + + + + + +GWEN_MSG *AQH_RebootRequestMsg_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint32_t uid) +{ + return _rebootMsg_new(srcAddr, destAddr, code, uid); +} + + + +uint32_t AQH_RebootRequestMsg_GetUid(const GWEN_MSG *msg) +{ + return _getUid(msg); +} + + + +void AQH_RebootRequestMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText) +{ + _rebootMsg_DumpToBuffer(msg, dbuf, sText, "REBOOT_REQUEST"); +} + + + + + +GWEN_MSG *AQH_RebootResponseMsg_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint32_t uid) +{ + return _rebootMsg_new(srcAddr, destAddr, code, uid); +} + + + +uint32_t AQH_RebootResponseMsg_GetUid(const GWEN_MSG *msg) +{ + return _getUid(msg); +} + + + +void AQH_RebootResponseMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText) +{ + _rebootMsg_DumpToBuffer(msg, dbuf, sText, "REBOOT_RESPONSE"); +} + + + + + +GWEN_MSG *_rebootMsg_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint32_t uid) +{ + GWEN_MSG *msg; + uint8_t *ptr; + int rv; + + msg=AQH_NodeMsg_new(destAddr, srcAddr, code, 4, NULL); + ptr=GWEN_Msg_GetBuffer(msg)+AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_REBOOT_UID; + + *(ptr++)=uid & 0xff; /* uid */ + *(ptr++)=(uid>>8) & 0xff; + *(ptr++)=(uid>>16) & 0xff; + *(ptr++)=(uid>>24) & 0xff; + + + rv=AQH_NodeMsg_AddChecksum(msg); + if (rv<0) { + DBG_INFO(AQH_LOGDOMAIN, "here (%d)", rv); + GWEN_Msg_free(msg); + return NULL; + } + + return msg; +} + + + +uint32_t _getUid(const GWEN_MSG *msg) +{ + return GWEN_Msg_GetUint32At(msg, AQH_MSG_OFFS_ALL_DATA_BEGIN+AQH_MSG_OFFS_REBOOT_UID, 0); +} + + + +void _rebootMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText, const char *cmd) +{ + if (GWEN_Msg_GetBytesInBuffer(msg)>=AQH_MSG_REBOOT_MINSIZE) { + GWEN_Buffer_AppendArgs(dbuf, + "0x%02x->0x%02x: %s %s (uid=0x%08x)\n", + AQH_NodeMsg_GetSourceAddress(msg), + AQH_NodeMsg_GetDestAddress(msg), + cmd, + sText, + _getUid(msg)); + } +} + + + + + + diff --git a/aqhome/msg/msg_reboot.h b/aqhome/msg/msg_reboot.h new file mode 100644 index 0000000..ca93b0d --- /dev/null +++ b/aqhome/msg/msg_reboot.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * This file is part of the project AqHome. + * AqHome (c) by 2023 Martin Preuss, all rights reserved. + * + * The license for this file can be found in the file COPYING which you + * should have received along with this file. + ****************************************************************************/ + +#ifndef AQH_MSG_NODE_REBOOT_H +#define AQH_MSG_NODE_REBOOT_H + + +#include +#include + +#include +#include + + +AQHOME_API GWEN_MSG *AQH_RebootRequestMsg_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint32_t uid); + +AQHOME_API uint32_t AQH_RebootRequestMsg_GetUid(const GWEN_MSG *msg); + +AQHOME_API void AQH_RebootRequestMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText); + + + +AQHOME_API GWEN_MSG *AQH_RebootResponseMsg_new(uint8_t srcAddr, uint8_t destAddr, uint8_t code, uint32_t uid); + +AQHOME_API uint32_t AQH_RebootResponseMsg_GetUid(const GWEN_MSG *msg); + +AQHOME_API void AQH_RebootResponseMsg_DumpToBuffer(const GWEN_MSG *msg, GWEN_BUFFER *dbuf, const char *sText); + + + +#endif + + + diff --git a/avr/att84_base.asm b/avr/att84_base.asm index 4540de9..6e5ff05 100644 --- a/avr/att84_base.asm +++ b/avr/att84_base.asm @@ -147,7 +147,7 @@ firmwareStart: rjmp main ; will be overwritten when flashing ; main code -.org 0xd00 +.org AQHOME_BOOTLOADER_ADDR main: @@ -165,6 +165,7 @@ main: .include "crc8.asm" .include "flash.asm" .include "flashproto.asm" +.include "watchdog.asm" diff --git a/avr/att84_temp1.asm b/avr/att84_temp1.asm index 78df466..dd983f9 100644 --- a/avr/att84_temp1.asm +++ b/avr/att84_temp1.asm @@ -175,7 +175,7 @@ ; Reset and interrupt vectors (will be removed as soon as we can flash data over COM) ; rjmp main ; Reset vector - rjmp 0xd00 ; Reset vector ; use this for flashed system + rjmp AQHOME_BOOTLOADER_ADDR ; Reset vector ; use this for flashed system reti ; EXT_INT0 rjmp com2IsrPcint0 ; PCI0 reti ; PCI1 @@ -205,6 +205,8 @@ firmwareStart: rjmp main .include "utils.asm" .include "crc8.asm" +.include "watchdog.asm" + #ifdef MODULES_TIMER .include "timer.asm" #endif @@ -223,6 +225,7 @@ firmwareStart: rjmp main .include "comproto_pong.asm" .include "comproto_values.asm" .include "comproto_device.asm" + .include "comproto_reboot.asm" #endif #endif #ifdef MODULES_TWI_MASTER diff --git a/avr/com2.asm b/avr/com2.asm index 64e5ae1..f80db51 100644 --- a/avr/com2.asm +++ b/avr/com2.asm @@ -167,7 +167,7 @@ com2HandleNextPacketInQueue_retNc: ; - X : pointer to buffer to write to ; OUT: ; - CFLAG: set if okay, clear otherwise -; MODIFIED REGS: R16, R17, X, Y (R3, R4, R15, R16, R17, R18, R19, R20, R21) +; REGS: R16, R17, X, Y (R3, R4, R15, R16, R17, R18, R19, R20, R21) COM2_WriteMsgWithCmdAndSrcAddr: ldi r17, COM2_PAYLOAD_FLAGS_SECONDS diff --git a/avr/comproto.asm b/avr/comproto.asm index 4bc7f0f..bf4de70 100644 --- a/avr/comproto.asm +++ b/avr/comproto.asm @@ -76,6 +76,12 @@ CPRO_OnPacketReceived: brne CPRO_OnPacketReceived_l1 rjmp cproHandlePing CPRO_OnPacketReceived_l1: +#ifndef BASE_SYSTEM + cpi r16, CPRO_CMD_REBOOT_REQUEST + brne CPRO_OnPacketReceived_l2 + rjmp cproHandleReboot +#endif +CPRO_OnPacketReceived_l2: #ifdef MODULES_COM_WITH_ADDR_PROTO rjmp CPRO_Address_OnPacketReceived #else @@ -102,6 +108,39 @@ cproHandlePing_notHandled: ret +; --------------------------------------------------------------------------- +; Compare the UID from a message against out own UID. +; +;IN: +; - X: pointer to UID in a message to compare against out own uid +; OUT: +; - CFLAG set if matches, cleared otherwise +; REGS: r16, r18, r19, r20, r21, X + +cproCheckUidInMsg: + push xl + push xh + rcall Utils_ReadUid + pop xh + pop xl + ld r16, X+ + cp r16, r18 + brne cproCheckUidInMsg_notMe + ld r16, X+ + cp r16, r19 + brne cproCheckUidInMsg_notMe + ld r16, X+ + cp r16, r20 + brne cproCheckUidInMsg_notMe + ld r16, X+ + cp r16, r21 + brne cproCheckUidInMsg_notMe + sec + ret +cproCheckUidInMsg_notMe: + clc + ret + CPRO_END: .equ MODULE_SIZE_CPRO = CPRO_END-CPRO_BEGIN diff --git a/avr/comproto_defs.asm b/avr/comproto_defs.asm index 75c2d4f..39ce2af 100644 --- a/avr/comproto_defs.asm +++ b/avr/comproto_defs.asm @@ -39,11 +39,14 @@ .equ CPRO_CMD_MEMSTATS = 81 .equ CPRO_CMD_SYSSTATS = 82 +.equ CPRO_CMD_REBOOT_REQUEST = 90 +.equ CPRO_CMD_REBOOT_RESPONSE = 91 + .equ CPRO_PACKET_HAVEADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4 .equ CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4 .equ CPRO_PACKET_DENYADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4 - +.equ CPRO_PACKET_REBOOTREQ_OFFS_UID = COM2_MSG_OFFS_PAYLOAD+0 .equ CPRO_WAITTIME_INITIAL = 10 .equ CPRO_WAITTIME_GETADDR = 130 diff --git a/avr/comproto_reboot.asm b/avr/comproto_reboot.asm new file mode 100644 index 0000000..6480b1e --- /dev/null +++ b/avr/comproto_reboot.asm @@ -0,0 +1,71 @@ +; *************************************************************************** +; 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 reboot request +; +; IN: +; - X : buffer containing the received packet +; OUT: +; - nothing +; REGS: + +cproHandleReboot: + adiw xh:xl, CPRO_PACKET_REBOOTREQ_OFFS_UID + rcall cproCheckUidInMsg + brcc cproHandleReboot_notHandled + sbiw xh:xl, CPRO_PACKET_REBOOTREQ_OFFS_UID+4 + adiw xh:xl, COM2_MSG_OFFS_SRCADDR + ld r16, x + cpi r16, 0xff + breq cproHandleReboot_notHandled ; dont handle src address 255 +cproHandleReboot_loop1: + push r16 + ldi xl, LOW(com2SendBuffer) + ldi xh, HIGH(com2SendBuffer) + rcall CPRO_WriteRebootResponse + rcall COM2_SendPacket + pop r16 + brcc cproHandleReboot_loop1 + + ; directly call bootloader + cli + rjmp AQHOME_BOOTLOADER_ADDR +cproHandleReboot_notHandled: + clc + ret + + + +; --------------------------------------------------------------------------- +; Write a Reboot Response packet. +; +; IN: +; - R16: destination address +; - X : buffer to write to +; OUT: +; - nothing +; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21) + +CPRO_WriteRebootResponse: + ldi r18, CPRO_CMD_REBOOT_RESPONSE + rjmp COM2_WriteMsgWithCmdAndSrcAddr ; R3, R4, R15, R16, R17, R18, R19, R20, R21, X + + + diff --git a/avr/defs.asm b/avr/defs.asm index 35d075b..b0fc0d3 100644 --- a/avr/defs.asm +++ b/avr/defs.asm @@ -29,6 +29,7 @@ ;.equ AQHOME_FW_START_ADDRESS_MAIN = 0x0500 +.equ AQHOME_BOOTLOADER_ADDR = 0xd00 ; --------------------------------------------------------------------------- ; EEPROM positions diff --git a/avr/flash.asm b/avr/flash.asm index a9fb61f..5b6eb62 100644 --- a/avr/flash.asm +++ b/avr/flash.asm @@ -183,7 +183,7 @@ wait: ; wait for possibly previous SPM to complete ; OUT: ; - R16: byte read ; - X: EEPROM Address incremented -; MODIFIED REGISTERS: R16 +; REGS: R16 flashReadEepromIncr: sbic EECR, EEPE ; wait for previous write to complete (if any) @@ -208,8 +208,8 @@ flashReadEepromIncr: ; REGS: R16, X flashReadUid: - in r15, SREG push r15 + in r15, SREG cli ldi xl, LOW(EEPROM_OFFS_UUID) ldi xh, HIGH(EEPROM_OFFS_UUID) @@ -221,8 +221,8 @@ flashReadUid: mov r20, r16 rcall flashReadEepromIncr ; (R16) mov r21, r16 + out SREG, r15 pop r15 - out SREG, r15 ret diff --git a/avr/flashproto.asm b/avr/flashproto.asm index f3162e8..ddb47be 100644 --- a/avr/flashproto.asm +++ b/avr/flashproto.asm @@ -69,6 +69,8 @@ bootLoader: ldi r16, Low(RAMEND) out SPL, r16 ; init LSB stack pointer +; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot) + ; setup pins and interrupts cbi COM_PORT_DATA, COM_PINNUM_DATA ; disable internal pullup for DATA cbi COM_DDR_DATA, COM_PINNUM_DATA ; set DATA port as input diff --git a/avr/main.asm b/avr/main.asm index 52c20fb..2de9df6 100644 --- a/avr/main.asm +++ b/avr/main.asm @@ -40,6 +40,8 @@ main: .endif ldi r16, Low(RAMEND) out SPL, r16 ; init LSB stack pointer + + rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot) rcall initModules diff --git a/avr/utils.asm b/avr/utils.asm index 02b9b35..a99d20f 100644 --- a/avr/utils.asm +++ b/avr/utils.asm @@ -367,13 +367,14 @@ Utils_UpdateSeedInEeprom: ; Read UID from EEPROM. ; ; IN: +; - nothing ; OUT: ; - R18:R19:R20:R21: UID ; REGS: R16, X Utils_ReadUid: - in r15, SREG push r15 + in r15, SREG cli ldi xl, LOW(EEPROM_OFFS_UUID) ldi xh, HIGH(EEPROM_OFFS_UUID) @@ -385,8 +386,8 @@ Utils_ReadUid: mov r20, r16 rcall Utils_ReadEepromIncr ; (R16) mov r21, r16 + out SREG, r15 pop r15 - out SREG, r15 ret diff --git a/avr/watchdog.asm b/avr/watchdog.asm new file mode 100644 index 0000000..1398b83 --- /dev/null +++ b/avr/watchdog.asm @@ -0,0 +1,42 @@ +; *************************************************************************** +; 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 + + +watchdogOn: + in r16, WDTCSR + ori r16, (1<