Rebooting and flashing a node now works!

This commit is contained in:
Martin Preuss
2023-04-21 23:38:44 +02:00
parent 76e58b6fec
commit 97016b21b9
20 changed files with 468 additions and 14 deletions

View File

@@ -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,

View File

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

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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)";
}
}

View File

@@ -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
View 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
View 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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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

View File

@@ -29,6 +29,7 @@
;.equ AQHOME_FW_START_ADDRESS_MAIN = 0x0500
.equ AQHOME_BOOTLOADER_ADDR = 0xd00
; ---------------------------------------------------------------------------
; EEPROM positions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

42
avr/watchdog.asm Normal file
View 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