Rebooting and flashing a node now works!
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -69,7 +69,7 @@ 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,
|
||||
DBG_INFO(AQH_LOGDOMAIN,
|
||||
"Received node msg from %d (%d)",
|
||||
AQH_NodeMsg_GetSourceAddress(nodeMsg),
|
||||
AQH_NodeMsg_GetMsgType(nodeMsg));
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
msg_flashresponse.h
|
||||
msg_flashend.h
|
||||
msg_flashdata.h
|
||||
msg_reboot.h
|
||||
</headers>
|
||||
|
||||
|
||||
@@ -106,6 +107,7 @@
|
||||
msg_flashresponse.c
|
||||
msg_flashend.c
|
||||
msg_flashdata.c
|
||||
msg_reboot.c
|
||||
</sources>
|
||||
|
||||
|
||||
|
||||
@@ -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 <gwenhywfar/list.h>
|
||||
#include <gwenhywfar/inherit.h>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
135
aqhome/msg/msg_reboot.c
Normal file
135
aqhome/msg/msg_reboot.c
Normal file
@@ -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 <config.h>
|
||||
#endif
|
||||
|
||||
#include "aqhome/msg/msg_reboot.h"
|
||||
#include "aqhome/msg/msg_node.h"
|
||||
|
||||
#include <gwenhywfar/misc.h>
|
||||
#include <gwenhywfar/list.h>
|
||||
#include <gwenhywfar/error.h>
|
||||
#include <gwenhywfar/debug.h>
|
||||
|
||||
#include <gwenhywfar/text.h>
|
||||
|
||||
|
||||
#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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
39
aqhome/msg/msg_reboot.h
Normal file
39
aqhome/msg/msg_reboot.h
Normal file
@@ -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 <aqhome/api.h>
|
||||
#include <aqhome/msg/msg_node.h>
|
||||
|
||||
#include <gwenhywfar/msg.h>
|
||||
#include <gwenhywfar/buffer.h>
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
71
avr/comproto_reboot.asm
Normal file
71
avr/comproto_reboot.asm
Normal file
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
;.equ AQHOME_FW_START_ADDRESS_MAIN = 0x0500
|
||||
|
||||
.equ AQHOME_BOOTLOADER_ADDR = 0xd00
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; EEPROM positions
|
||||
|
||||
@@ -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
|
||||
pop r15
|
||||
out SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -41,6 +41,8 @@ main:
|
||||
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
|
||||
|
||||
rcall Utils_SetupUid
|
||||
|
||||
@@ -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
|
||||
pop r15
|
||||
out SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
|
||||
|
||||
|
||||
42
avr/watchdog.asm
Normal file
42
avr/watchdog.asm
Normal file
@@ -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<<WDE) | (1<<WDP0) ; about 32ms period
|
||||
out WDTCSR, r16
|
||||
ret
|
||||
|
||||
|
||||
|
||||
watchdogOff:
|
||||
wdr ; reset WDT
|
||||
in r16, WDTCSR
|
||||
ori r16, (1<<WDCE)|(1<<WDE)
|
||||
push r15
|
||||
in r15, SREG
|
||||
cli
|
||||
out WDTCSR, r16
|
||||
ldi r16, (0<<WDE) ; Turn off WDT
|
||||
out WDTCSR, r16
|
||||
out SREG, r15
|
||||
pop r15
|
||||
ret
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user