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_flashstart.h"
|
||||||
#include "aqhome/msg/msg_flashresponse.h"
|
#include "aqhome/msg/msg_flashresponse.h"
|
||||||
#include "aqhome/msg/msg_flashdata.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/hexfile.h"
|
||||||
#include "aqhome/hexfile/flashrecord.h"
|
#include "aqhome/hexfile/flashrecord.h"
|
||||||
|
|
||||||
@@ -39,19 +41,22 @@
|
|||||||
|
|
||||||
#define FLASH_TOOL_MAX_REPEAT 16
|
#define FLASH_TOOL_MAX_REPEAT 16
|
||||||
|
|
||||||
#define DEBUG_FLASH
|
/*#define DEBUG_FLASH*/
|
||||||
|
|
||||||
|
|
||||||
static int _doFlash(GWEN_DB_NODE *dbArgs);
|
static int _doFlash(GWEN_DB_NODE *dbArgs);
|
||||||
static GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp,
|
static GWEN_MSG *_waitForFlashReadyMessageForUid(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp,
|
||||||
unsigned int uid, int timeoutInSeconds);
|
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 _sendFlashStart(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid);
|
||||||
static int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds);
|
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,
|
static int _sendFlashData(GWEN_MSG_ENDPOINT_MGR *emgr,
|
||||||
GWEN_MSG_ENDPOINT *epTcp,
|
GWEN_MSG_ENDPOINT *epTcp,
|
||||||
const AQH_FLASHRECORD *flashRecord,
|
const AQH_FLASHRECORD *flashRecord,
|
||||||
uint16_t pageSize,
|
uint16_t pageSize,
|
||||||
int timeoutInSeconds);
|
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"),
|
||||||
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_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
|
||||||
GWEN_ArgsType_Int, /* type */
|
GWEN_ArgsType_Int, /* type */
|
||||||
@@ -161,6 +177,7 @@ int _doFlash(GWEN_DB_NODE *dbArgs)
|
|||||||
GWEN_MSG_ENDPOINT *epTcp;
|
GWEN_MSG_ENDPOINT *epTcp;
|
||||||
int rv;
|
int rv;
|
||||||
int timeoutInSeconds;
|
int timeoutInSeconds;
|
||||||
|
int doReboot;
|
||||||
const char *s;
|
const char *s;
|
||||||
unsigned int uid;
|
unsigned int uid;
|
||||||
const char *hexFilename;
|
const char *hexFilename;
|
||||||
@@ -171,6 +188,7 @@ int _doFlash(GWEN_DB_NODE *dbArgs)
|
|||||||
|
|
||||||
/* read data */
|
/* read data */
|
||||||
timeoutInSeconds=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 30);
|
timeoutInSeconds=GWEN_DB_GetIntValue(dbArgs, "timeout", 0, 30);
|
||||||
|
doReboot=GWEN_DB_GetIntValue(dbArgs, "reboot", 0, 0);
|
||||||
s=GWEN_DB_GetCharValue(dbArgs, "uid", 0, NULL);
|
s=GWEN_DB_GetCharValue(dbArgs, "uid", 0, NULL);
|
||||||
if (1!=sscanf(s, "%x", &uid)) {
|
if (1!=sscanf(s, "%x", &uid)) {
|
||||||
DBG_ERROR(NULL, "Bad uid \"%s\"", s);
|
DBG_ERROR(NULL, "Bad uid \"%s\"", s);
|
||||||
@@ -215,6 +233,25 @@ int _doFlash(GWEN_DB_NODE *dbArgs)
|
|||||||
return 3;
|
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 */
|
/* wait for FLASH_READY message */
|
||||||
msg=_waitForFlashReadyMessageForUid(emgr, epTcp, uid, timeoutInSeconds);
|
msg=_waitForFlashReadyMessageForUid(emgr, epTcp, uid, timeoutInSeconds);
|
||||||
if (msg==NULL) {
|
if (msg==NULL) {
|
||||||
@@ -259,6 +296,14 @@ int _doFlash(GWEN_DB_NODE *dbArgs)
|
|||||||
flashRecord=AQH_FlashRecord_List_Next(flashRecord);
|
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);
|
GWEN_MsgEndpointMgr_free(emgr);
|
||||||
return 0;
|
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)
|
int _waitForFlashResponseMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG_ENDPOINT *epTcp, int timeoutInSeconds)
|
||||||
{
|
{
|
||||||
GWEN_MSG *msg;
|
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)
|
int _sendFlashStart(GWEN_MSG_ENDPOINT *epTcp, unsigned int uid)
|
||||||
{
|
{
|
||||||
GWEN_MSG *msgNode;
|
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,
|
int _sendFlashData(GWEN_MSG_ENDPOINT_MGR *emgr,
|
||||||
GWEN_MSG_ENDPOINT *epTcp,
|
GWEN_MSG_ENDPOINT *epTcp,
|
||||||
const AQH_FLASHRECORD *flashRecord,
|
const AQH_FLASHRECORD *flashRecord,
|
||||||
|
|||||||
@@ -69,10 +69,10 @@ GWEN_MSG *Utils_WaitForSpecificNodeMessage(GWEN_MSG_ENDPOINT_MGR *emgr, GWEN_MSG
|
|||||||
DBG_INFO(NULL, "Received IPC FORWARD message");
|
DBG_INFO(NULL, "Received IPC FORWARD message");
|
||||||
nodeMsg=AQH_ForwardIpcMsg_GetCopyOfNodeMsg(msg);
|
nodeMsg=AQH_ForwardIpcMsg_GetCopyOfNodeMsg(msg);
|
||||||
if (nodeMsg) {
|
if (nodeMsg) {
|
||||||
DBG_ERROR(AQH_LOGDOMAIN,
|
DBG_INFO(AQH_LOGDOMAIN,
|
||||||
"Received node msg from %d (%d)",
|
"Received node msg from %d (%d)",
|
||||||
AQH_NodeMsg_GetSourceAddress(nodeMsg),
|
AQH_NodeMsg_GetSourceAddress(nodeMsg),
|
||||||
AQH_NodeMsg_GetMsgType(nodeMsg));
|
AQH_NodeMsg_GetMsgType(nodeMsg));
|
||||||
if (AQH_NodeMsg_GetMsgType(nodeMsg)==msgCode && (nodeAddr==0 || AQH_NodeMsg_GetSourceAddress(nodeMsg)==nodeAddr)) {
|
if (AQH_NodeMsg_GetMsgType(nodeMsg)==msgCode && (nodeAddr==0 || AQH_NodeMsg_GetSourceAddress(nodeMsg)==nodeAddr)) {
|
||||||
GWEN_Msg_free(msg);
|
GWEN_Msg_free(msg);
|
||||||
return nodeMsg;
|
return nodeMsg;
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
msg_flashresponse.h
|
msg_flashresponse.h
|
||||||
msg_flashend.h
|
msg_flashend.h
|
||||||
msg_flashdata.h
|
msg_flashdata.h
|
||||||
|
msg_reboot.h
|
||||||
</headers>
|
</headers>
|
||||||
|
|
||||||
|
|
||||||
@@ -106,6 +107,7 @@
|
|||||||
msg_flashresponse.c
|
msg_flashresponse.c
|
||||||
msg_flashend.c
|
msg_flashend.c
|
||||||
msg_flashdata.c
|
msg_flashdata.c
|
||||||
|
msg_reboot.c
|
||||||
</sources>
|
</sources>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "aqhome/msg/msg_flashresponse.h"
|
#include "aqhome/msg/msg_flashresponse.h"
|
||||||
#include "aqhome/msg/msg_flashend.h"
|
#include "aqhome/msg/msg_flashend.h"
|
||||||
#include "aqhome/msg/msg_flashdata.h"
|
#include "aqhome/msg/msg_flashdata.h"
|
||||||
|
#include "aqhome/msg/msg_reboot.h"
|
||||||
|
|
||||||
#include <gwenhywfar/list.h>
|
#include <gwenhywfar/list.h>
|
||||||
#include <gwenhywfar/inherit.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_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_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_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;
|
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_MEMSTATS:
|
||||||
case AQH_MSG_TYPE_SYSSTATS:
|
case AQH_MSG_TYPE_SYSSTATS:
|
||||||
return AQH_MSG_TYPEGROUP_INFO;
|
return AQH_MSG_TYPEGROUP_INFO;
|
||||||
|
|
||||||
case AQH_MSG_TYPE_VALUE:
|
case AQH_MSG_TYPE_VALUE:
|
||||||
case AQH_MSG_TYPE_VALUE2:
|
case AQH_MSG_TYPE_VALUE2:
|
||||||
return AQH_MSG_TYPEGROUP_VALUES;
|
return AQH_MSG_TYPEGROUP_VALUES;
|
||||||
|
|
||||||
case AQH_MSG_TYPE_NEED_ADDRESS:
|
case AQH_MSG_TYPE_NEED_ADDRESS:
|
||||||
case AQH_MSG_TYPE_HAVE_ADDRESS:
|
case AQH_MSG_TYPE_HAVE_ADDRESS:
|
||||||
case AQH_MSG_TYPE_CLAIM_ADDRESS:
|
case AQH_MSG_TYPE_CLAIM_ADDRESS:
|
||||||
case AQH_MSG_TYPE_DENY_ADDRESS:
|
case AQH_MSG_TYPE_DENY_ADDRESS:
|
||||||
case AQH_MSG_TYPE_ADDRESS_RANGE:
|
case AQH_MSG_TYPE_ADDRESS_RANGE:
|
||||||
return AQH_MSG_TYPEGROUP_ADDRESS;
|
return AQH_MSG_TYPEGROUP_ADDRESS;
|
||||||
|
|
||||||
case AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS:
|
case AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS:
|
||||||
return AQH_MSG_TYPEGROUP_ADMIN;
|
return AQH_MSG_TYPEGROUP_ADMIN;
|
||||||
|
|
||||||
case AQH_MSG_TYPE_FLASH_START:
|
case AQH_MSG_TYPE_FLASH_START:
|
||||||
case AQH_MSG_TYPE_FLASH_END:
|
case AQH_MSG_TYPE_FLASH_END:
|
||||||
case AQH_MSG_TYPE_FLASH_READY:
|
case AQH_MSG_TYPE_FLASH_READY:
|
||||||
case AQH_MSG_TYPE_FLASH_DATA:
|
case AQH_MSG_TYPE_FLASH_DATA:
|
||||||
case AQH_MSG_TYPE_FLASH_RSP:
|
case AQH_MSG_TYPE_FLASH_RSP:
|
||||||
|
case AQH_MSG_TYPE_REBOOT_REQ:
|
||||||
|
case AQH_MSG_TYPE_REBOOT_RSP:
|
||||||
return AQH_MSG_TYPEGROUP_FLASH;
|
return AQH_MSG_TYPEGROUP_FLASH;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
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_DEVICE: return "Device";
|
||||||
case AQH_MSG_TYPE_MEMSTATS: return "MemStats";
|
case AQH_MSG_TYPE_MEMSTATS: return "MemStats";
|
||||||
case AQH_MSG_TYPE_SYSSTATS: return "SysStats";
|
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)";
|
default: return "(unknown)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,9 @@
|
|||||||
#define AQH_MSG_TYPE_MEMSTATS 81
|
#define AQH_MSG_TYPE_MEMSTATS 81
|
||||||
#define AQH_MSG_TYPE_SYSSTATS 82
|
#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 */
|
/* internal msg types via NET interface */
|
||||||
#define AQH_MSG_TYPE_NET_SET_ACCEPTED_MSGGROUPS 200
|
#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
|
; main code
|
||||||
|
|
||||||
|
|
||||||
.org 0xd00
|
.org AQHOME_BOOTLOADER_ADDR
|
||||||
|
|
||||||
|
|
||||||
main:
|
main:
|
||||||
@@ -165,6 +165,7 @@ main:
|
|||||||
.include "crc8.asm"
|
.include "crc8.asm"
|
||||||
.include "flash.asm"
|
.include "flash.asm"
|
||||||
.include "flashproto.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)
|
; Reset and interrupt vectors (will be removed as soon as we can flash data over COM)
|
||||||
|
|
||||||
; rjmp main ; Reset vector
|
; 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
|
reti ; EXT_INT0
|
||||||
rjmp com2IsrPcint0 ; PCI0
|
rjmp com2IsrPcint0 ; PCI0
|
||||||
reti ; PCI1
|
reti ; PCI1
|
||||||
@@ -205,6 +205,8 @@ firmwareStart: rjmp main
|
|||||||
|
|
||||||
.include "utils.asm"
|
.include "utils.asm"
|
||||||
.include "crc8.asm"
|
.include "crc8.asm"
|
||||||
|
.include "watchdog.asm"
|
||||||
|
|
||||||
#ifdef MODULES_TIMER
|
#ifdef MODULES_TIMER
|
||||||
.include "timer.asm"
|
.include "timer.asm"
|
||||||
#endif
|
#endif
|
||||||
@@ -223,6 +225,7 @@ firmwareStart: rjmp main
|
|||||||
.include "comproto_pong.asm"
|
.include "comproto_pong.asm"
|
||||||
.include "comproto_values.asm"
|
.include "comproto_values.asm"
|
||||||
.include "comproto_device.asm"
|
.include "comproto_device.asm"
|
||||||
|
.include "comproto_reboot.asm"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef MODULES_TWI_MASTER
|
#ifdef MODULES_TWI_MASTER
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ com2HandleNextPacketInQueue_retNc:
|
|||||||
; - X : pointer to buffer to write to
|
; - X : pointer to buffer to write to
|
||||||
; OUT:
|
; OUT:
|
||||||
; - CFLAG: set if okay, clear otherwise
|
; - 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:
|
COM2_WriteMsgWithCmdAndSrcAddr:
|
||||||
ldi r17, COM2_PAYLOAD_FLAGS_SECONDS
|
ldi r17, COM2_PAYLOAD_FLAGS_SECONDS
|
||||||
|
|||||||
@@ -76,6 +76,12 @@ CPRO_OnPacketReceived:
|
|||||||
brne CPRO_OnPacketReceived_l1
|
brne CPRO_OnPacketReceived_l1
|
||||||
rjmp cproHandlePing
|
rjmp cproHandlePing
|
||||||
CPRO_OnPacketReceived_l1:
|
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
|
#ifdef MODULES_COM_WITH_ADDR_PROTO
|
||||||
rjmp CPRO_Address_OnPacketReceived
|
rjmp CPRO_Address_OnPacketReceived
|
||||||
#else
|
#else
|
||||||
@@ -102,6 +108,39 @@ cproHandlePing_notHandled:
|
|||||||
ret
|
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:
|
CPRO_END:
|
||||||
.equ MODULE_SIZE_CPRO = CPRO_END-CPRO_BEGIN
|
.equ MODULE_SIZE_CPRO = CPRO_END-CPRO_BEGIN
|
||||||
|
|||||||
@@ -39,11 +39,14 @@
|
|||||||
.equ CPRO_CMD_MEMSTATS = 81
|
.equ CPRO_CMD_MEMSTATS = 81
|
||||||
.equ CPRO_CMD_SYSSTATS = 82
|
.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_HAVEADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
|
||||||
.equ CPRO_PACKET_CLAIMADDR_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_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_INITIAL = 10
|
||||||
.equ CPRO_WAITTIME_GETADDR = 130
|
.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_FW_START_ADDRESS_MAIN = 0x0500
|
||||||
|
|
||||||
|
.equ AQHOME_BOOTLOADER_ADDR = 0xd00
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; EEPROM positions
|
; EEPROM positions
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ wait: ; wait for possibly previous SPM to complete
|
|||||||
; OUT:
|
; OUT:
|
||||||
; - R16: byte read
|
; - R16: byte read
|
||||||
; - X: EEPROM Address incremented
|
; - X: EEPROM Address incremented
|
||||||
; MODIFIED REGISTERS: R16
|
; REGS: R16
|
||||||
|
|
||||||
flashReadEepromIncr:
|
flashReadEepromIncr:
|
||||||
sbic EECR, EEPE ; wait for previous write to complete (if any)
|
sbic EECR, EEPE ; wait for previous write to complete (if any)
|
||||||
@@ -208,8 +208,8 @@ flashReadEepromIncr:
|
|||||||
; REGS: R16, X
|
; REGS: R16, X
|
||||||
|
|
||||||
flashReadUid:
|
flashReadUid:
|
||||||
in r15, SREG
|
|
||||||
push r15
|
push r15
|
||||||
|
in r15, SREG
|
||||||
cli
|
cli
|
||||||
ldi xl, LOW(EEPROM_OFFS_UUID)
|
ldi xl, LOW(EEPROM_OFFS_UUID)
|
||||||
ldi xh, HIGH(EEPROM_OFFS_UUID)
|
ldi xh, HIGH(EEPROM_OFFS_UUID)
|
||||||
@@ -221,8 +221,8 @@ flashReadUid:
|
|||||||
mov r20, r16
|
mov r20, r16
|
||||||
rcall flashReadEepromIncr ; (R16)
|
rcall flashReadEepromIncr ; (R16)
|
||||||
mov r21, r16
|
mov r21, r16
|
||||||
|
out SREG, r15
|
||||||
pop r15
|
pop r15
|
||||||
out SREG, r15
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ bootLoader:
|
|||||||
ldi r16, Low(RAMEND)
|
ldi r16, Low(RAMEND)
|
||||||
out SPL, r16 ; init LSB stack pointer
|
out SPL, r16 ; init LSB stack pointer
|
||||||
|
|
||||||
|
; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
|
||||||
|
|
||||||
; setup pins and interrupts
|
; setup pins and interrupts
|
||||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; disable internal pullup for DATA
|
cbi COM_PORT_DATA, COM_PINNUM_DATA ; disable internal pullup for DATA
|
||||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; set DATA port as input
|
cbi COM_DDR_DATA, COM_PINNUM_DATA ; set DATA port as input
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ main:
|
|||||||
.endif
|
.endif
|
||||||
ldi r16, Low(RAMEND)
|
ldi r16, Low(RAMEND)
|
||||||
out SPL, r16 ; init LSB stack pointer
|
out SPL, r16 ; init LSB stack pointer
|
||||||
|
|
||||||
|
rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
|
||||||
|
|
||||||
rcall initModules
|
rcall initModules
|
||||||
|
|
||||||
|
|||||||
@@ -367,13 +367,14 @@ Utils_UpdateSeedInEeprom:
|
|||||||
; Read UID from EEPROM.
|
; Read UID from EEPROM.
|
||||||
;
|
;
|
||||||
; IN:
|
; IN:
|
||||||
|
; - nothing
|
||||||
; OUT:
|
; OUT:
|
||||||
; - R18:R19:R20:R21: UID
|
; - R18:R19:R20:R21: UID
|
||||||
; REGS: R16, X
|
; REGS: R16, X
|
||||||
|
|
||||||
Utils_ReadUid:
|
Utils_ReadUid:
|
||||||
in r15, SREG
|
|
||||||
push r15
|
push r15
|
||||||
|
in r15, SREG
|
||||||
cli
|
cli
|
||||||
ldi xl, LOW(EEPROM_OFFS_UUID)
|
ldi xl, LOW(EEPROM_OFFS_UUID)
|
||||||
ldi xh, HIGH(EEPROM_OFFS_UUID)
|
ldi xh, HIGH(EEPROM_OFFS_UUID)
|
||||||
@@ -385,8 +386,8 @@ Utils_ReadUid:
|
|||||||
mov r20, r16
|
mov r20, r16
|
||||||
rcall Utils_ReadEepromIncr ; (R16)
|
rcall Utils_ReadEepromIncr ; (R16)
|
||||||
mov r21, r16
|
mov r21, r16
|
||||||
|
out SREG, r15
|
||||||
pop r15
|
pop r15
|
||||||
out SREG, r15
|
|
||||||
ret
|
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