From d727f63dc43e3d8737bd01ffc4da2a8921ff3064 Mon Sep 17 00:00:00 2001 From: Local user Date: Wed, 6 May 2026 23:13:04 -0600 Subject: [PATCH 01/24] test --- CanAutoNode/CanAutoNode.hpp | 8 ++++---- CanAutoNode/CanAutoNodeDaughter.cpp | 4 ++-- CanAutoNode/CanAutoNodeMotherboard.cpp | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CanAutoNode/CanAutoNode.hpp b/CanAutoNode/CanAutoNode.hpp index 0e0f2de..6ee9e74 100644 --- a/CanAutoNode/CanAutoNode.hpp +++ b/CanAutoNode/CanAutoNode.hpp @@ -18,7 +18,7 @@ #include constexpr uint32_t MAX_NODES_IN_NETWORK = 100; -constexpr uint8_t MAX_LOG_TYPES_PER_NODE = 5; +constexpr uint8_t MAX_LOG_TYPES_PER_NODE = 9; constexpr uint8_t MAX_NAME_STR_LEN = 20; constexpr uint8_t MAX_JOIN_ATTEMPTS = 8; // Max 2047 for 11-bit standard FDCAN, max 536,870,911 for extended FDCAN. @@ -29,9 +29,9 @@ constexpr uint16_t MAX_CAN_ID = 2047; constexpr uint16_t JOIN_REQUEST_ID = 0; constexpr uint16_t ACK_ID = 1; constexpr uint16_t UPDATE_ID = 2; -constexpr uint16_t KICK_REQUEST_ID = 3; -constexpr uint16_t HEARTBEAT_ID = 4; -constexpr uint16_t MAX_RESERVED_CAN_ID = 4; // Make sure to update if adding a new reserved ID +constexpr uint16_t KICK_REQUEST_ID = 4; +constexpr uint16_t HEARTBEAT_ID = 5; +constexpr uint16_t MAX_RESERVED_CAN_ID = 5; // Make sure to update if adding a new reserved ID #ifdef CANAUTONODEDEBUG diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 4b2673b..15a5703 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -145,7 +145,7 @@ bool CanAutoNodeDaughter::CheckForUpdate() { if(GetCurrentState() != WAITING_FOR_UPDATE) { return false; } - uint8_t msg[64] = {123}; + uint8_t msg[128] = {123}; while(controller->ReceiveLogIndexFromRXBuf(msg, UPDATE_ID)) { @@ -278,7 +278,7 @@ CanAutoNodeDaughter::CanAutoNodeDaughter(FDCAN_HandleTypeDef *fdcan, const LogIn //controller->RegisterFilterRXFIFO(0, MAX_RESERVED_CAN_ID); - FDCanController::LogInitStruct reservedLogs[] = {{64,JOIN_REQUEST_ID},{64,ACK_ID},{64,UPDATE_ID},{64,KICK_REQUEST_ID},{64,HEARTBEAT_ID}}; + FDCanController::LogInitStruct reservedLogs[] = {{64,JOIN_REQUEST_ID},{64,ACK_ID},{65,UPDATE_ID},{64,KICK_REQUEST_ID},{64,HEARTBEAT_ID}}; controller->RegisterLogs(reservedLogs, sizeof(reservedLogs)/sizeof(reservedLogs[0])); diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index f47266c..43f867a 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -117,7 +117,7 @@ CanAutoNodeMotherboard::CanAutoNodeMotherboard(FDCAN_HandleTypeDef *fdcan) { //controller->RegisterFilterRXFIFO(0, MAX_RESERVED_CAN_ID); memset(heartbeatGracePeriod,0x00,sizeof(heartbeatGracePeriod)); - FDCanController::LogInitStruct reservedLogs[] = {{64,JOIN_REQUEST_ID},{64,ACK_ID},{64,UPDATE_ID},{64,KICK_REQUEST_ID},{64,HEARTBEAT_ID}}; + FDCanController::LogInitStruct reservedLogs[] = {{64,JOIN_REQUEST_ID},{64,ACK_ID},{65,UPDATE_ID},{64,KICK_REQUEST_ID},{64,HEARTBEAT_ID}}; controller->RegisterLogs(reservedLogs, sizeof(reservedLogs)/sizeof(reservedLogs[0])); } @@ -297,6 +297,7 @@ bool CanAutoNodeMotherboard::SendFullUpdate() { #endif return false; } + HAL_Delay(50); #ifdef CANAUTONODEDEBUG SOAR_PRINT("Sent daughter update frame %d/%d\n",i+1,nodesInNetwork); #endif From 9b1dee55681a93716514d1d5d989eaf78f272033 Mon Sep 17 00:00:00 2001 From: Local user Date: Thu, 7 May 2026 00:00:01 -0600 Subject: [PATCH 02/24] please --- CanAutoNode/CanAutoNode.cpp | 2 +- CanAutoNode/CanAutoNodeDaughter.cpp | 4 ++-- CanAutoNode/CanAutoNodeMotherboard.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CanAutoNode/CanAutoNode.cpp b/CanAutoNode/CanAutoNode.cpp index 4113232..d8c4894 100644 --- a/CanAutoNode/CanAutoNode.cpp +++ b/CanAutoNode/CanAutoNode.cpp @@ -157,7 +157,7 @@ bool CanAutoNode::SendHeartbeat() { uint8_t msg[sizeof(HeartbeatInfo)] = {}; memcpy(msg,&beat,sizeof(msg)); - return controller->SendByLogIndex(msg, HEARTBEAT_ID); + return controller->SendByMsgID(msg, sizeof (msg), HEARTBEAT_ID); //return controller->SendByMsgID(msg, sizeof(msg), HEARTBEAT_ID); } diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 15a5703..96d8a89 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -173,7 +173,7 @@ bool CanAutoNodeDaughter::ProcessMessage() { } uint8_t msg[64] = {}; bool gotOne = false; - while(controller->ReceiveLogIndexFromRXBuf(msg, KICK_REQUEST_ID)) { + while(controller->ReceiveLogIndexFromRXBuf(msg, KICK_REQUEST_ID - 1)) { gotOne = true; UniqueBoardID kickedBoard = MsgToData(msg); @@ -202,7 +202,7 @@ bool CanAutoNodeDaughter::ProcessMessage() { ChangeState( WAITING_FOR_UPDATE); gotOne = true; } - while(controller->ReceiveLogIndexFromRXBuf(msg, HEARTBEAT_ID)) { + while(controller->ReceiveLogIndexFromRXBuf(msg, HEARTBEAT_ID - 1)) { if(MsgToData(msg) == Motherboard.uniqueID) { diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 43f867a..9f6d545 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -328,7 +328,7 @@ bool CanAutoNodeMotherboard::Heartbeat() { HAL_Delay(1); uint8_t out[64]; uint32_t id = 0; - if(controller->ReceiveLogIndexFromRXBuf(out, HEARTBEAT_ID)) { + if(controller->ReceiveLogIndexFromRXBuf(out, HEARTBEAT_ID-1)) { UniqueBoardID responseID = MsgToData(out); From 6c976164df2aca873525b021470bc828b81535fc Mon Sep 17 00:00:00 2001 From: Local user Date: Thu, 7 May 2026 00:15:07 -0600 Subject: [PATCH 03/24] please help --- CanAutoNode/CanAutoNodeDaughter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 96d8a89..dd84b15 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -209,6 +209,7 @@ bool CanAutoNodeDaughter::ProcessMessage() { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Received heartbeat\n"); #endif + HAL_Delay(thisNode.uniqueID.u2 % 100); SendHeartbeat(); } gotOne = true; From 14255d961a8b497ee54f2f34302bc87519b5ef32 Mon Sep 17 00:00:00 2001 From: Local user Date: Thu, 7 May 2026 00:25:56 -0600 Subject: [PATCH 04/24] gelp --- CanAutoNode/CanAutoNodeDaughter.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index dd84b15..729b290 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -204,14 +204,19 @@ bool CanAutoNodeDaughter::ProcessMessage() { } while(controller->ReceiveLogIndexFromRXBuf(msg, HEARTBEAT_ID - 1)) { + UniqueBoardID u = MsgToData(msg); + for (uint16_t i = 0; i < nodesInNetwork; i++) { + if(daughterNodes[nodesInNetwork].uniqueID == u) { + break; + } + } - if(MsgToData(msg) == Motherboard.uniqueID) { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Received heartbeat\n"); #endif HAL_Delay(thisNode.uniqueID.u2 % 100); SendHeartbeat(); - } + gotOne = true; } From 9fea982c4aa74f16e040d70bb14f210ceabd27cd Mon Sep 17 00:00:00 2001 From: Local user Date: Thu, 7 May 2026 19:07:45 -0600 Subject: [PATCH 05/24] sa t al rme apsk po amimr pakf peo poil --- CanAutoNode/CanAutoNode.cpp | 2 +- CanAutoNode/CanAutoNode.hpp | 19 +++++++++++++------ CanAutoNode/CanAutoNodeDaughter.cpp | 24 +++++++++++------------- CanAutoNode/CanAutoNodeMotherboard.cpp | 16 ++++++++-------- CanAutoNode/CanAutoNodeMotherboard.hpp | 2 +- 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/CanAutoNode/CanAutoNode.cpp b/CanAutoNode/CanAutoNode.cpp index d8c4894..cebf686 100644 --- a/CanAutoNode/CanAutoNode.cpp +++ b/CanAutoNode/CanAutoNode.cpp @@ -157,7 +157,7 @@ bool CanAutoNode::SendHeartbeat() { uint8_t msg[sizeof(HeartbeatInfo)] = {}; memcpy(msg,&beat,sizeof(msg)); - return controller->SendByMsgID(msg, sizeof (msg), HEARTBEAT_ID); + return controller->SendByMsgID(msg, sizeof (msg), HEARTBEAT_CAN_ID); //return controller->SendByMsgID(msg, sizeof(msg), HEARTBEAT_ID); } diff --git a/CanAutoNode/CanAutoNode.hpp b/CanAutoNode/CanAutoNode.hpp index 6ee9e74..58981bb 100644 --- a/CanAutoNode/CanAutoNode.hpp +++ b/CanAutoNode/CanAutoNode.hpp @@ -26,13 +26,20 @@ constexpr uint8_t MAX_JOIN_ATTEMPTS = 8; constexpr uint16_t MAX_CAN_ID = 2047; // Reserved CAN IDs -constexpr uint16_t JOIN_REQUEST_ID = 0; -constexpr uint16_t ACK_ID = 1; -constexpr uint16_t UPDATE_ID = 2; -constexpr uint16_t KICK_REQUEST_ID = 4; -constexpr uint16_t HEARTBEAT_ID = 5; +constexpr uint16_t JOIN_REQUEST_CAN_ID = 0; +constexpr uint16_t ACK_CAN_ID = 1; +constexpr uint16_t UPDATE_CAN_ID = 2; +constexpr uint16_t KICK_REQUEST_CAN_ID = 4; +constexpr uint16_t HEARTBEAT_CAN_ID = 5; constexpr uint16_t MAX_RESERVED_CAN_ID = 5; // Make sure to update if adding a new reserved ID +constexpr uint16_t JOIN_REQUEST_RLOG_INDEX = 0; +constexpr uint16_t ACK_RLOG_INDEX = 1; +constexpr uint16_t UPDATE_RLOG_INDEX = 2; +constexpr uint16_t KICK_REQUEST_RLOG_INDEX = 3; +constexpr uint16_t HEARTBEAT_RLOG_INDEX = 4; +constexpr uint16_t MAX_RESERVED_RLOG_INDEX = 4; // Make sure to update if adding a new reserved ID + #ifdef CANAUTONODEDEBUG //#include "Task.hpp" @@ -123,7 +130,7 @@ class CanAutoNode { char nodeName[MAX_NAME_STR_LEN]; - uint16_t startingLogIndexOnMotherboard = MAX_RESERVED_CAN_ID+1; + uint16_t startingLogIndexOnMotherboard = MAX_RESERVED_RLOG_INDEX+1; bool operator==(const Node&) const = default; bool operator!=(const Node&) const = default; diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 729b290..241a5a0 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -79,7 +79,7 @@ bool CanAutoNodeDaughter::RequestToJoinNetwork() { uint8_t msg[sizeof(JoinRequest)]; DataToMsg(request, msg); - return controller->SendByMsgID(msg, sizeof(msg), JOIN_REQUEST_ID); + return controller->SendByMsgID(msg, sizeof(msg), JOIN_REQUEST_CAN_ID); } CanAutoNodeDaughter::~CanAutoNodeDaughter() { @@ -99,7 +99,7 @@ bool CanAutoNodeDaughter::CheckForAcknowledgement() { } uint8_t msg[64] = {123}; - while(controller->ReceiveLogIndexFromRXBuf(msg, ACK_ID)) { + while(controller->ReceiveLogIndexFromRXBuf(msg, ACK_RLOG_INDEX)) { acknowledgementStatus incomingStatus = static_cast(msg[0]); @@ -108,7 +108,7 @@ bool CanAutoNodeDaughter::CheckForAcknowledgement() { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Good ACK!\n"); #endif - controller->DiscardLog(KICK_REQUEST_ID); // So we don't immediately get kicked on rejoining after a daughter reset + controller->DiscardLog(KICK_REQUEST_RLOG_INDEX); // So we don't immediately get kicked on rejoining after a daughter reset ChangeState(WAITING_FOR_UPDATE); return true; @@ -147,7 +147,7 @@ bool CanAutoNodeDaughter::CheckForUpdate() { } uint8_t msg[128] = {123}; - while(controller->ReceiveLogIndexFromRXBuf(msg, UPDATE_ID)) { + while(controller->ReceiveLogIndexFromRXBuf(msg, UPDATE_RLOG_INDEX)) { return ReceiveUpdate(msg); @@ -171,9 +171,9 @@ bool CanAutoNodeDaughter::ProcessMessage() { if(GetCurrentState() != READY) { return false; } - uint8_t msg[64] = {}; + uint8_t msg[128] = {}; bool gotOne = false; - while(controller->ReceiveLogIndexFromRXBuf(msg, KICK_REQUEST_ID - 1)) { + while(controller->ReceiveLogIndexFromRXBuf(msg, KICK_REQUEST_RLOG_INDEX)) { gotOne = true; UniqueBoardID kickedBoard = MsgToData(msg); @@ -193,7 +193,7 @@ bool CanAutoNodeDaughter::ProcessMessage() { ChangeState(WAITING_FOR_UPDATE); gotOne = true; } - while(controller->ReceiveLogIndexFromRXBuf(msg, JOIN_REQUEST_ID)) { + while(controller->ReceiveLogIndexFromRXBuf(msg, JOIN_REQUEST_RLOG_INDEX)) { #ifdef CANAUTONODEDEBUG @@ -202,7 +202,7 @@ bool CanAutoNodeDaughter::ProcessMessage() { ChangeState( WAITING_FOR_UPDATE); gotOne = true; } - while(controller->ReceiveLogIndexFromRXBuf(msg, HEARTBEAT_ID - 1)) { + while(controller->ReceiveLogIndexFromRXBuf(msg, HEARTBEAT_RLOG_INDEX)) { UniqueBoardID u = MsgToData(msg); for (uint16_t i = 0; i < nodesInNetwork; i++) { @@ -282,9 +282,7 @@ CanAutoNodeDaughter::CanAutoNodeDaughter(FDCAN_HandleTypeDef *fdcan, const LogIn } - //controller->RegisterFilterRXFIFO(0, MAX_RESERVED_CAN_ID); - - FDCanController::LogInitStruct reservedLogs[] = {{64,JOIN_REQUEST_ID},{64,ACK_ID},{65,UPDATE_ID},{64,KICK_REQUEST_ID},{64,HEARTBEAT_ID}}; + FDCanController::LogInitStruct reservedLogs[] = {{64,JOIN_REQUEST_CAN_ID},{64,ACK_CAN_ID},{sizeof(Node)+1,UPDATE_CAN_ID},{64,KICK_REQUEST_CAN_ID},{64,HEARTBEAT_CAN_ID}}; controller->RegisterLogs(reservedLogs, sizeof(reservedLogs)/sizeof(reservedLogs[0])); @@ -301,7 +299,7 @@ bool CanAutoNodeDaughter::SendMessageToMotherboardByLogID(uint16_t logID, const return false; } //printf("sending to motherboard log index %d\n",logID); - return controller->SendByLogIndex(msg, logID+MAX_RESERVED_CAN_ID+1); + return controller->SendByLogIndex(msg, logID+MAX_RESERVED_RLOG_INDEX+1); } /* Handle receiving part of an update, updating internal node references and changing state when ready. @@ -380,7 +378,7 @@ bool CanAutoNodeDaughter::ReadMessageByLogIndex(uint8_t logIndex, return false; } uint16_t logSize = determinedLogs[logIndex].byteLength; - return ReadMessageFromRXBuf(logIndex+MAX_RESERVED_CAN_ID+1, logSize, out, outLen); + return ReadMessageFromRXBuf(logIndex+MAX_RESERVED_RLOG_INDEX+1, logSize, out, outLen); } diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 9f6d545..197fd27 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -65,7 +65,7 @@ bool CanAutoNodeMotherboard::KickNode(UniqueBoardID uniqueBoardID) { heartbeatGracePeriod[foundIndex] = heartbeatGracePeriod[nodesInNetwork]; } - if(!controller->SendByMsgID((uint8_t*)(&uniqueBoardID), sizeof(uniqueBoardID), KICK_REQUEST_ID)) { + if(!controller->SendByMsgID((uint8_t*)(&uniqueBoardID), sizeof(uniqueBoardID), KICK_REQUEST_CAN_ID)) { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Tried to kick node, but failed to send! (Attempted to kick "); PrintBoardID(uniqueBoardID); @@ -114,10 +114,10 @@ bool CanAutoNodeMotherboard::KickNode(uint16_t slotNumber) { CanAutoNodeMotherboard::CanAutoNodeMotherboard(FDCAN_HandleTypeDef *fdcan) { controller = new FDCanController(fdcan,nullptr,0); callbackcontroller = controller; - //controller->RegisterFilterRXFIFO(0, MAX_RESERVED_CAN_ID); + memset(heartbeatGracePeriod,0x00,sizeof(heartbeatGracePeriod)); - FDCanController::LogInitStruct reservedLogs[] = {{64,JOIN_REQUEST_ID},{64,ACK_ID},{65,UPDATE_ID},{64,KICK_REQUEST_ID},{64,HEARTBEAT_ID}}; + FDCanController::LogInitStruct reservedLogs[] = {{64,JOIN_REQUEST_CAN_ID},{64,ACK_CAN_ID},{sizeof(Node)+1,UPDATE_CAN_ID},{64,KICK_REQUEST_CAN_ID},{64,HEARTBEAT_CAN_ID}}; controller->RegisterLogs(reservedLogs, sizeof(reservedLogs)/sizeof(reservedLogs[0])); } @@ -132,7 +132,7 @@ bool CanAutoNodeMotherboard::CheckForJoinRequest() { uint32_t id = 0; - while(controller->ReceiveLogIndexFromRXBuf(msg, JOIN_REQUEST_ID)) { + while(controller->ReceiveLogIndexFromRXBuf(msg, JOIN_REQUEST_CAN_ID)) { return ReceiveJoinRequest(msg); @@ -260,7 +260,7 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { bool CanAutoNodeMotherboard::SendAck(acknowledgementStatus status) { uint8_t msg[] = {static_cast(status)}; - return controller->SendByMsgID(msg, sizeof(msg), ACK_ID); + return controller->SendByMsgID(msg, sizeof(msg), ACK_CAN_ID); } @@ -278,7 +278,7 @@ bool CanAutoNodeMotherboard::SendFullUpdate() { msgFromNode(thisNode, msg+1); msg[0] = CAN_UPDATE_MOTHERBOARD; - if(!controller->SendByMsgID(msg, sizeof(msg), UPDATE_ID)) { + if(!controller->SendByMsgID(msg, sizeof(msg), UPDATE_CAN_ID)) { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Failed to send motherboard update frame!\n"); #endif @@ -291,7 +291,7 @@ bool CanAutoNodeMotherboard::SendFullUpdate() { for(uint16_t i = 0; i < nodesInNetwork; i++) { msgFromNode(daughterNodes[i], msg+1); msg[0] = (i == nodesInNetwork-1) ? CAN_UPDATE_LAST_DAUGHTER : CAN_UPDATE_DAUGHTER; - if(!controller->SendByMsgID(msg, sizeof(msg), UPDATE_ID)) { + if(!controller->SendByMsgID(msg, sizeof(msg), UPDATE_CAN_ID)) { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Tried but failed to send daughter update frame!\n"); #endif @@ -328,7 +328,7 @@ bool CanAutoNodeMotherboard::Heartbeat() { HAL_Delay(1); uint8_t out[64]; uint32_t id = 0; - if(controller->ReceiveLogIndexFromRXBuf(out, HEARTBEAT_ID-1)) { + if(controller->ReceiveLogIndexFromRXBuf(out, HEARTBEAT_RLOG_INDEX)) { UniqueBoardID responseID = MsgToData(out); diff --git a/CanAutoNode/CanAutoNodeMotherboard.hpp b/CanAutoNode/CanAutoNodeMotherboard.hpp index 576a6eb..11bab27 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.hpp +++ b/CanAutoNode/CanAutoNodeMotherboard.hpp @@ -44,7 +44,7 @@ class CanAutoNodeMotherboard : public CanAutoNode { uint32_t lastHeartbeatTick = 0; - uint16_t nextFreeMotherboardLogIndex = 0; + uint16_t nextFreeMotherboardLogIndex = MAX_RESERVED_RLOG_INDEX+1; Node* recentlyJoined[MAX_NODES_IN_NETWORK]; uint16_t recentlyJoinedNum = 0; From d609695aff14fcc6ca24d9476d4943e7ecfb175a Mon Sep 17 00:00:00 2001 From: Local user Date: Fri, 8 May 2026 21:06:56 -0600 Subject: [PATCH 06/24] alright --- CanAutoNode/CanAutoNodeDaughter.cpp | 6 ++++++ CanAutoNode/CanAutoNodeMotherboard.cpp | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 241a5a0..b477a7b 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -119,6 +119,12 @@ bool CanAutoNodeDaughter::CheckForAcknowledgement() { #endif return false; + case ACK_BOARD_ALREADY_EXISTS: +#ifdef CANAUTONODEDEBUG + SOAR_PRINT("Already exists somehow!\n"); +#endif + return false; + default: // invalid ack ChangeState(ERROR); diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 197fd27..1da2f2c 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -167,6 +167,7 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { if(request.uniqueID == thisAlreadyExistingNode.uniqueID) { // already have this board somehow SendAck(ACK_BOARD_ALREADY_EXISTS); + KickNode(request.uniqueID); return false; } @@ -211,7 +212,7 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { if(foundRoom) { // found no issues - SendAck(ACK_GOOD); + #ifdef CANAUTONODEDEBUG SOAR_PRINT("Adding new node at ID range [%d,%d)\n",bestStartingFreeCANID,bestStartingFreeCANID+requiredTotalCANIDs); #endif @@ -240,6 +241,7 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { newNode.startingLogIndexOnMotherboard = nextFreeMotherboardLogIndex; nextFreeMotherboardLogIndex += request.numberOfLogs; + SendAck(ACK_GOOD); HAL_Delay(50); return SendFullUpdate(); From 58dcb779f925ce319320b9d0ed0e1b2717666f0d Mon Sep 17 00:00:00 2001 From: Local user Date: Fri, 8 May 2026 23:36:35 -0600 Subject: [PATCH 07/24] no --- CanAutoNode/CanAutoNode.hpp | 6 +++++- CanAutoNode/CanAutoNodeDaughter.cpp | 2 +- CanAutoNode/CanAutoNodeMotherboard.cpp | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CanAutoNode/CanAutoNode.hpp b/CanAutoNode/CanAutoNode.hpp index 58981bb..a7fb5cb 100644 --- a/CanAutoNode/CanAutoNode.hpp +++ b/CanAutoNode/CanAutoNode.hpp @@ -11,7 +11,11 @@ /* * Define this to enable debug prints across the driver. Uses SOAR_PRINT. */ -//#define CANAUTONODEDEBUG +#define CANAUTONODEDEBUG + +#ifdef CANAUTONODEDEBUG +#include "SystemDefines.hpp" +#endif #include "FDCan.h" #include diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index b477a7b..8b6e3ce 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -212,7 +212,7 @@ bool CanAutoNodeDaughter::ProcessMessage() { UniqueBoardID u = MsgToData(msg); for (uint16_t i = 0; i < nodesInNetwork; i++) { - if(daughterNodes[nodesInNetwork].uniqueID == u) { + if(daughterNodes[i].uniqueID == u) { break; } } diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 1da2f2c..85fb175 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -435,7 +435,7 @@ bool CanAutoNodeMotherboard::ReadMessageFromDaughterByLogIndex( } } #ifdef CANAUTONODEDEBUG - SOAR_PRINT("No node with that ID!\n"); + //SOAR_PRINT("No node with that ID!\n"); #endif return false; From ed7cfb739aa45527f946cef80f4bff92adc271d7 Mon Sep 17 00:00:00 2001 From: Local user Date: Fri, 8 May 2026 23:48:11 -0600 Subject: [PATCH 08/24] =?UTF-8?q?added=20some=20mercy=20for=20extra=20hear?= =?UTF-8?q?tbeats=20=F0=9F=AB=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CanAutoNode/CanAutoNodeMotherboard.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 85fb175..5f1bee9 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -323,7 +323,7 @@ bool CanAutoNodeMotherboard::Heartbeat() { - bool received[nodesInNetwork]; + uint8_t received[nodesInNetwork]; memset(received,0,sizeof(received)); for(uint16_t i = 0; i < 1000; i++) { @@ -342,8 +342,8 @@ bool CanAutoNodeMotherboard::Heartbeat() { #endif for(int node = 0; node < nodesInNetwork; node++) { if(daughterNodes[node].uniqueID == responseID) { - if(received[node]) { - // received multiple heartbeats from the same node? + if(received[node]++ > 2) { + // received 3 or more heartbeats from the same node? #ifdef CANAUTONODEDEBUG SOAR_PRINT("Received multiple heartbeats from "); PrintBoardID(responseID); @@ -354,7 +354,7 @@ bool CanAutoNodeMotherboard::Heartbeat() { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Found the source of this heartbeat at %d!\n",node); #endif - received[node] = true; + foundResponder = true; break; } From ffe220ba3dd0641ac65f5f1b260d6a501d349d45 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 00:00:48 -0600 Subject: [PATCH 09/24] added some grace and a way for daughters to exit the error state --- CanAutoNode/CanAutoNodeDaughter.cpp | 7 +++++++ CanAutoNode/CanAutoNodeDaughter.hpp | 2 ++ CanAutoNode/CanAutoNodeMotherboard.cpp | 6 +++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 8b6e3ce..d32102a 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -391,3 +391,10 @@ bool CanAutoNodeDaughter::ReadMessageByLogIndex(uint8_t logIndex, uint16_t CanAutoNodeDaughter::GetSizeOfLog(uint8_t logIndex) const { return determinedLogs[logIndex].byteLength; } + +bool CanAutoNodeDaughter::ExitErrorState() { + if(GetCurrentState() != CanAutoNodeDaughter::ERROR) { + return false; + } + ChangeState(CanAutoNodeDaughter::UNINITIALIZED); +} diff --git a/CanAutoNode/CanAutoNodeDaughter.hpp b/CanAutoNode/CanAutoNodeDaughter.hpp index 3cb6b54..64f45e6 100644 --- a/CanAutoNode/CanAutoNodeDaughter.hpp +++ b/CanAutoNode/CanAutoNodeDaughter.hpp @@ -63,6 +63,8 @@ class CanAutoNodeDaughter : public CanAutoNode { uint16_t GetSizeOfLog(uint8_t logIndex) const; + bool ExitErrorState(); + protected: diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 5f1bee9..1e43262 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -236,7 +236,7 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { daughterNodes[nodesInNetwork] = newNode; recentlyJoined[recentlyJoinedNum++] = &daughterNodes[nodesInNetwork]; controller->RegisterLogs(newLogs, request.numberOfLogs); - heartbeatGracePeriod[nodesInNetwork] = 0; + heartbeatGracePeriod[nodesInNetwork] = 3; nodesInNetwork++; newNode.startingLogIndexOnMotherboard = nextFreeMotherboardLogIndex; nextFreeMotherboardLogIndex += request.numberOfLogs; @@ -396,7 +396,11 @@ bool CanAutoNodeMotherboard::Heartbeat() { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Received no heartbeat from "); PrintBoardID(daughterNodes[i].uniqueID); + if(heartbeatGracePeriod[i] > 0) { + SOAR_PRINT(", but it had grace!\n"); + } else { SOAR_PRINT(", kicking\n"); + } #endif if(heartbeatGracePeriod[i] > 0) { heartbeatGracePeriod[i]--; From ba25344bd6950b5697efcab047cb9d5f0d81508b Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 00:36:54 -0600 Subject: [PATCH 10/24] im hungry --- CanAutoNode/CanAutoNodeDaughter.cpp | 6 ++---- CanAutoNode/CanAutoNodeMotherboard.cpp | 1 + 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index d32102a..7ea6525 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -211,10 +211,8 @@ bool CanAutoNodeDaughter::ProcessMessage() { while(controller->ReceiveLogIndexFromRXBuf(msg, HEARTBEAT_RLOG_INDEX)) { UniqueBoardID u = MsgToData(msg); - for (uint16_t i = 0; i < nodesInNetwork; i++) { - if(daughterNodes[i].uniqueID == u) { - break; - } + if(u != Motherboard.uniqueID) { + break; } #ifdef CANAUTONODEDEBUG diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 1e43262..5b54397 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -290,6 +290,7 @@ bool CanAutoNodeMotherboard::SendFullUpdate() { SOAR_PRINT("Sent motherboard update frame\n"); #endif + HAL_Delay(50); for(uint16_t i = 0; i < nodesInNetwork; i++) { msgFromNode(daughterNodes[i], msg+1); msg[0] = (i == nodesInNetwork-1) ? CAN_UPDATE_LAST_DAUGHTER : CAN_UPDATE_DAUGHTER; From 83382d0a537f406eaa3edf07143b573c47a7e437 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 11:23:47 -0600 Subject: [PATCH 11/24] added heartbeat direction for better --- CanAutoNode/CanAutoNode.cpp | 2 +- CanAutoNode/CanAutoNode.hpp | 6 ++++++ CanAutoNode/CanAutoNodeDaughter.cpp | 6 +++--- CanAutoNode/CanAutoNodeDaughter.hpp | 4 ++++ CanAutoNode/CanAutoNodeMotherboard.cpp | 3 ++- CanAutoNode/CanAutoNodeMotherboard.hpp | 4 ++++ 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/CanAutoNode/CanAutoNode.cpp b/CanAutoNode/CanAutoNode.cpp index cebf686..2839e46 100644 --- a/CanAutoNode/CanAutoNode.cpp +++ b/CanAutoNode/CanAutoNode.cpp @@ -154,7 +154,7 @@ bool CanAutoNode::SendHeartbeat() { HeartbeatInfo beat; beat.senderBoardID = thisNode.uniqueID; - + beat.dir = GetDir(); uint8_t msg[sizeof(HeartbeatInfo)] = {}; memcpy(msg,&beat,sizeof(msg)); return controller->SendByMsgID(msg, sizeof (msg), HEARTBEAT_CAN_ID); diff --git a/CanAutoNode/CanAutoNode.hpp b/CanAutoNode/CanAutoNode.hpp index a7fb5cb..041dd82 100644 --- a/CanAutoNode/CanAutoNode.hpp +++ b/CanAutoNode/CanAutoNode.hpp @@ -144,6 +144,11 @@ class CanAutoNode { static_assert(sizeof(Node) <= 64, "Node entries must be at most 64 bytes large. Try reducing MAX_LOGS"); struct HeartbeatInfo { + enum DIRECTION { + INVAL, + FROM_MOTH, + TO_MOTH + } dir; UniqueBoardID senderBoardID; }; @@ -190,6 +195,7 @@ class CanAutoNode { bool ReadMessageFromRXBuf(uint8_t logIndex, uint16_t logSize, uint8_t* out, uint16_t outLen); + virtual HeartbeatInfo::DIRECTION GetDir() const = 0; private: CanAutoNode(const CanAutoNode &other) = delete; diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 7ea6525..a41f729 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -210,15 +210,15 @@ bool CanAutoNodeDaughter::ProcessMessage() { } while(controller->ReceiveLogIndexFromRXBuf(msg, HEARTBEAT_RLOG_INDEX)) { - UniqueBoardID u = MsgToData(msg); - if(u != Motherboard.uniqueID) { + HeartbeatInfo hi = MsgToData(msg); + if(hi.dir != hi.FROM_MOTH) { break; } #ifdef CANAUTONODEDEBUG SOAR_PRINT("Received heartbeat\n"); #endif - HAL_Delay(thisNode.uniqueID.u2 % 100); + HAL_Delay(thisNode.canIDRange.start*13 % 100); SendHeartbeat(); gotOne = true; diff --git a/CanAutoNode/CanAutoNodeDaughter.hpp b/CanAutoNode/CanAutoNodeDaughter.hpp index 64f45e6..cada598 100644 --- a/CanAutoNode/CanAutoNodeDaughter.hpp +++ b/CanAutoNode/CanAutoNodeDaughter.hpp @@ -83,6 +83,10 @@ class CanAutoNodeDaughter : public CanAutoNode { bool ReceiveUpdate(const uint8_t* msg); + HeartbeatInfo::DIRECTION GetDir() const override { + return HeartbeatInfo::TO_MOTH; + } + uint32_t tickLastReceivedUpdatePart = 0; LogInit logsToInit[MAX_LOG_TYPES_PER_NODE]; diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 5b54397..83d4d3b 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -330,7 +330,7 @@ bool CanAutoNodeMotherboard::Heartbeat() { for(uint16_t i = 0; i < 1000; i++) { HAL_Delay(1); uint8_t out[64]; - uint32_t id = 0; + if(controller->ReceiveLogIndexFromRXBuf(out, HEARTBEAT_RLOG_INDEX)) { @@ -468,5 +468,6 @@ uint16_t CanAutoNodeMotherboard::GetNamesOfNewlyJoinedBoards(char(*outputArr)[MA } memcpy(recentlyJoined,&recentlyJoined[recentlyJoinedNum-num],(num)*sizeof(Node*)); recentlyJoinedNum -= num; + return num; } diff --git a/CanAutoNode/CanAutoNodeMotherboard.hpp b/CanAutoNode/CanAutoNodeMotherboard.hpp index 11bab27..010e259 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.hpp +++ b/CanAutoNode/CanAutoNodeMotherboard.hpp @@ -42,6 +42,10 @@ class CanAutoNodeMotherboard : public CanAutoNode { bool CheckForJoinRequest(); + HeartbeatInfo::DIRECTION GetDir() const override { + return HeartbeatInfo::FROM_MOTH; + } + uint32_t lastHeartbeatTick = 0; uint16_t nextFreeMotherboardLogIndex = MAX_RESERVED_RLOG_INDEX+1; From c450db31a202717fde65d4b3462e0959bf4eebf2 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 12:36:27 -0600 Subject: [PATCH 12/24] fixed bad heartbeat receive on motherboard --- CanAutoNode/CanAutoNodeMotherboard.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 83d4d3b..6976a79 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -318,12 +318,17 @@ bool CanAutoNodeMotherboard::Heartbeat() { this->lastHeartbeatTick = HAL_GetTick(); + if(nodesInNetwork == 0) { // there's nobody here, just don't + return true; + } + if(!SendHeartbeat()) { return false; } + uint8_t received[nodesInNetwork]; memset(received,0,sizeof(received)); @@ -333,8 +338,8 @@ bool CanAutoNodeMotherboard::Heartbeat() { if(controller->ReceiveLogIndexFromRXBuf(out, HEARTBEAT_RLOG_INDEX)) { - - UniqueBoardID responseID = MsgToData(out); + HeartbeatInfo hi = MsgToData(out); + UniqueBoardID responseID = hi.senderBoardID; bool foundResponder = false; #ifdef CANAUTONODEDEBUG SOAR_PRINT("Got a heartbeat from "); From 9d387ed17a12ae20e542e1737246ed14dc12de74 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 12:50:44 -0600 Subject: [PATCH 13/24] separated mother-daughter dir com can id --- CanAutoNode/CanAutoNode.cpp | 2 +- CanAutoNode/CanAutoNode.hpp | 1 + CanAutoNode/CanAutoNodeDaughter.cpp | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CanAutoNode/CanAutoNode.cpp b/CanAutoNode/CanAutoNode.cpp index 2839e46..9a27661 100644 --- a/CanAutoNode/CanAutoNode.cpp +++ b/CanAutoNode/CanAutoNode.cpp @@ -177,7 +177,7 @@ bool CanAutoNode::SendMessageToDaughterByLogIndex(UniqueBoardID boardID, for(uint16_t i = 0; i < nodesInNetwork; i++) { const Node& thisDaughter = daughterNodes[i]; if(thisDaughter.uniqueID == boardID) { - return controller->SendByMsgID(msg, thisDaughter.logSizesInBytes[logIndex], thisDaughter.logOffsetsInCANIDs[logIndex]+thisDaughter.canIDRange.start); + return controller->SendByMsgID(msg, thisDaughter.logSizesInBytes[logIndex], thisDaughter.logOffsetsInCANIDs[logIndex]+thisDaughter.canIDRange.start+SEND_RECEIVE_ID_SPLIT_AMOUNT); } } return false; diff --git a/CanAutoNode/CanAutoNode.hpp b/CanAutoNode/CanAutoNode.hpp index 041dd82..47cc95b 100644 --- a/CanAutoNode/CanAutoNode.hpp +++ b/CanAutoNode/CanAutoNode.hpp @@ -44,6 +44,7 @@ constexpr uint16_t KICK_REQUEST_RLOG_INDEX = 3; constexpr uint16_t HEARTBEAT_RLOG_INDEX = 4; constexpr uint16_t MAX_RESERVED_RLOG_INDEX = 4; // Make sure to update if adding a new reserved ID +constexpr uint16_t SEND_RECEIVE_ID_SPLIT_AMOUNT = MAX_CAN_ID/2; #ifdef CANAUTONODEDEBUG //#include "Task.hpp" diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index a41f729..469991d 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -302,8 +302,10 @@ bool CanAutoNodeDaughter::SendMessageToMotherboardByLogID(uint16_t logID, const if(GetCurrentState() != READY) { return false; } + uint16_t txid = determinedLogs[logID].startingMsgID - SEND_RECEIVE_ID_SPLIT_AMOUNT; //printf("sending to motherboard log index %d\n",logID); - return controller->SendByLogIndex(msg, logID+MAX_RESERVED_RLOG_INDEX+1); + //return controller->SendByLogIndex(msg, logID+MAX_RESERVED_RLOG_INDEX+1); + return controller->SendByMsgID(msg, determinedLogs[logID].byteLength, txid); } /* Handle receiving part of an update, updating internal node references and changing state when ready. @@ -338,7 +340,7 @@ bool CanAutoNodeDaughter::ReceiveUpdate(const uint8_t *msg) { uint16_t canid = receivedNode.canIDRange.start; for(uint16_t i = 0; i < numLogs; i++) { uint16_t requiredIDs = (logsToInit[i].sizeInBytes-1)/64+1; - determinedLogs[i] = {logsToInit[i].sizeInBytes, canid}; + determinedLogs[i] = {logsToInit[i].sizeInBytes, canid+SEND_RECEIVE_ID_SPLIT_AMOUNT}; canid += requiredIDs; #ifdef CANAUTONODEDEBUG SOAR_PRINT("Registering log %d at canid %d byte size %d\n",i,determinedLogs[i].startingMsgID,determinedLogs[i].byteLength); From 0bf48daef86e37ecf4c714105087c65415ae4d0c Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 13:40:10 -0600 Subject: [PATCH 14/24] daughters now make sure to exhaust the whole heartbeat queue --- CanAutoNode/CanAutoNodeDaughter.cpp | 2 +- CanAutoNode/CanAutoNodeMotherboard.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 469991d..5b5f81d 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -212,7 +212,7 @@ bool CanAutoNodeDaughter::ProcessMessage() { HeartbeatInfo hi = MsgToData(msg); if(hi.dir != hi.FROM_MOTH) { - break; + continue; } #ifdef CANAUTONODEDEBUG diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 6976a79..cb7208e 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -166,7 +166,7 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { if(request.uniqueID == thisAlreadyExistingNode.uniqueID) { // already have this board somehow - SendAck(ACK_BOARD_ALREADY_EXISTS); + //SendAck(ACK_BOARD_ALREADY_EXISTS); KickNode(request.uniqueID); return false; } From 6b5c54d7f1b46f6aab19dda6b378a74569e35d97 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 14:46:18 -0600 Subject: [PATCH 15/24] faster heartbeat checking, ack checking for other boards joining --- CanAutoNode/CanAutoNodeDaughter.cpp | 14 ++++++++++++++ CanAutoNode/CanAutoNodeMotherboard.cpp | 16 ++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 5b5f81d..d832f97 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -208,6 +208,20 @@ bool CanAutoNodeDaughter::ProcessMessage() { ChangeState( WAITING_FOR_UPDATE); gotOne = true; } + + while(controller->ReceiveLogIndexFromRXBuf(msg, ACK_RLOG_INDEX)) { + + +#ifdef CANAUTONODEDEBUG + SOAR_PRINT("Saw an ack, presumably for another board\n"); +#endif + acknowledgementStatus incomingStatus = static_cast(msg[0]); + if(incomingStatus != ACK_GOOD && GetCurrentState() == WAITING_FOR_UPDATE) { + ChangeState( READY); + } + + gotOne = true; + } while(controller->ReceiveLogIndexFromRXBuf(msg, HEARTBEAT_RLOG_INDEX)) { HeartbeatInfo hi = MsgToData(msg); diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index cb7208e..70eb869 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -166,8 +166,13 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { if(request.uniqueID == thisAlreadyExistingNode.uniqueID) { // already have this board somehow - //SendAck(ACK_BOARD_ALREADY_EXISTS); - KickNode(request.uniqueID); +#ifdef CANAUTONODEDEBUG + SOAR_PRINT("But it already exists!\n"); +#endif + SendAck(ACK_BOARD_ALREADY_EXISTS); + HAL_Delay(10); + SendFullUpdate(); + //KickNode(request.uniqueID); return false; } @@ -332,8 +337,10 @@ bool CanAutoNodeMotherboard::Heartbeat() { uint8_t received[nodesInNetwork]; memset(received,0,sizeof(received)); - for(uint16_t i = 0; i < 1000; i++) { - HAL_Delay(1); + uint32_t last = HAL_GetTick(); + uint16_t i = 0; + while(HAL_GetTick()-last < 1000){ + i++; uint8_t out[64]; if(controller->ReceiveLogIndexFromRXBuf(out, HEARTBEAT_RLOG_INDEX)) { @@ -395,6 +402,7 @@ bool CanAutoNodeMotherboard::Heartbeat() { if(i > 10 && nodesInNetwork == 0) { return true; // don't bother waiting the whole timeout when there are no daughter nodes, we just want to see if there are any out-of-network responders } + } for(size_t i = 0; i < nodesInNetwork; i++) { From df9095d1c832a74ec25cab6e19365c26fbbad090 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 14:57:35 -0600 Subject: [PATCH 16/24] hopefully fix daughters giving up and exploding when another board tries and fails to join --- CanAutoNode/CanAutoNodeDaughter.cpp | 12 ++++++++++++ CanAutoNode/CanAutoNodeMotherboard.cpp | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index d832f97..8c3ce98 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -153,6 +153,18 @@ bool CanAutoNodeDaughter::CheckForUpdate() { } uint8_t msg[128] = {123}; + // at this point the ack should have already been sent if it was this board joining, + // so if this hits that means another board in the network tried joining or was kicked + // if the motherboard doesnt like the new board, dont even bother + while(controller->ReceiveLogIndexFromRXBuf(msg, ACK_RLOG_INDEX)) { + acknowledgementStatus incomingStatus = static_cast(msg[0]); + if(acknowledgementStatus != ACK_GOOD) { + ChangeState(READY); + return true; + } + + } + while(controller->ReceiveLogIndexFromRXBuf(msg, UPDATE_RLOG_INDEX)) { diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 70eb869..da6364c 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -171,7 +171,7 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { #endif SendAck(ACK_BOARD_ALREADY_EXISTS); HAL_Delay(10); - SendFullUpdate(); + //SendFullUpdate(); //KickNode(request.uniqueID); return false; } From 8e8e9337c6ac0b431d0520e82687d657adf7fcb5 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 14:59:14 -0600 Subject: [PATCH 17/24] actually make the last one build properyl --- CanAutoNode/CanAutoNodeDaughter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 8c3ce98..a4ed0f1 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -158,7 +158,7 @@ bool CanAutoNodeDaughter::CheckForUpdate() { // if the motherboard doesnt like the new board, dont even bother while(controller->ReceiveLogIndexFromRXBuf(msg, ACK_RLOG_INDEX)) { acknowledgementStatus incomingStatus = static_cast(msg[0]); - if(acknowledgementStatus != ACK_GOOD) { + if(incomingStatus != ACK_GOOD) { ChangeState(READY); return true; } @@ -423,4 +423,5 @@ bool CanAutoNodeDaughter::ExitErrorState() { return false; } ChangeState(CanAutoNodeDaughter::UNINITIALIZED); + return true; } From 1b681ffe935773ae5d994ae9e2aef5ef44bde615 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 15:04:32 -0600 Subject: [PATCH 18/24] dbg print --- CanAutoNode/CanAutoNodeDaughter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index a4ed0f1..a40a871 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -158,11 +158,16 @@ bool CanAutoNodeDaughter::CheckForUpdate() { // if the motherboard doesnt like the new board, dont even bother while(controller->ReceiveLogIndexFromRXBuf(msg, ACK_RLOG_INDEX)) { acknowledgementStatus incomingStatus = static_cast(msg[0]); +#ifdef CANAUTONODEDEBUG + SOAR_PRINT("even though we waiting for an update we got an ack of %d\n",incomingStatus); +#endif if(incomingStatus != ACK_GOOD) { ChangeState(READY); return true; } + + } while(controller->ReceiveLogIndexFromRXBuf(msg, UPDATE_RLOG_INDEX)) { From 5888831d6616d6647aed49b9db14fa05f30a13c1 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 15:27:50 -0600 Subject: [PATCH 19/24] this time for sure --- CanAutoNode/CanAutoNodeDaughter.cpp | 9 +++++++++ CanAutoNode/CanAutoNodeDaughter.hpp | 1 + CanAutoNode/CanAutoNodeMotherboard.cpp | 5 ++++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index a4ed0f1..a4275d3 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -61,6 +61,7 @@ bool CanAutoNodeDaughter::TryRequestingJoiningNetwork() { */ bool CanAutoNodeDaughter::RequestToJoinNetwork() { + lastDetectedJoinRequest = thisNode.uniqueID; JoinRequest request; request.uniqueID = thisNode.uniqueID; request.boardType = thisNode.boardType; @@ -176,6 +177,13 @@ bool CanAutoNodeDaughter::CheckForUpdate() { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Update timed out!\n"); #endif + if(lastDetectedJoinRequest != UniqueBoardID{0} && lastDetectedJoinRequest != thisNode.uniqueID) { +#ifdef CANAUTONODEDEBUG + SOAR_PRINT("but its ok since that join request wasnt even mine :)\n"); +#endif + ChangeState(READY); + return false; + } ChangeState(ERROR); } return false; @@ -217,6 +225,7 @@ bool CanAutoNodeDaughter::ProcessMessage() { #ifdef CANAUTONODEDEBUG SOAR_PRINT("Saw a join request from another board\n"); #endif + lastDetectedJoinRequest = MsgToData(msg).uniqueID; ChangeState( WAITING_FOR_UPDATE); gotOne = true; } diff --git a/CanAutoNode/CanAutoNodeDaughter.hpp b/CanAutoNode/CanAutoNodeDaughter.hpp index cada598..f54a186 100644 --- a/CanAutoNode/CanAutoNodeDaughter.hpp +++ b/CanAutoNode/CanAutoNodeDaughter.hpp @@ -95,6 +95,7 @@ class CanAutoNodeDaughter : public CanAutoNode { FDCanController::LogInitStruct determinedLogs[MAX_LOG_TYPES_PER_NODE]; bool initializedLogs = false; + UniqueBoardID lastDetectedJoinRequest = {0}; // const uint8_t boardType; // const IDRange idRange; diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index da6364c..766d397 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -169,10 +169,13 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { #ifdef CANAUTONODEDEBUG SOAR_PRINT("But it already exists!\n"); #endif + //HAL_Delay(20); SendAck(ACK_BOARD_ALREADY_EXISTS); - HAL_Delay(10); + //HAL_Delay(10); //SendFullUpdate(); + //HAL_Delay(50); //KickNode(request.uniqueID); + //SendFullUpdate(); return false; } From 66156c1667210425d4dd291b7b77ff4510182895 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 16:50:11 -0600 Subject: [PATCH 20/24] -now kicks repeat join boards for faster recovery on daughter reset --- CanAutoNode/CanAutoNodeMotherboard.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 766d397..d986b05 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -173,8 +173,8 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { SendAck(ACK_BOARD_ALREADY_EXISTS); //HAL_Delay(10); //SendFullUpdate(); - //HAL_Delay(50); - //KickNode(request.uniqueID); + HAL_Delay(10); + KickNode(request.uniqueID); //SendFullUpdate(); return false; } From 1e2f5935ba23a8ed6a97d090f9b548e713669102 Mon Sep 17 00:00:00 2001 From: Local user Date: Sat, 9 May 2026 17:32:02 -0600 Subject: [PATCH 21/24] - fixed daughter node on motherboard index setting with multiple boards --- CanAutoNode/CanAutoNode.hpp | 4 ++-- CanAutoNode/CanAutoNodeMotherboard.cpp | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CanAutoNode/CanAutoNode.hpp b/CanAutoNode/CanAutoNode.hpp index 47cc95b..ff627c3 100644 --- a/CanAutoNode/CanAutoNode.hpp +++ b/CanAutoNode/CanAutoNode.hpp @@ -11,7 +11,7 @@ /* * Define this to enable debug prints across the driver. Uses SOAR_PRINT. */ -#define CANAUTONODEDEBUG +//#define CANAUTONODEDEBUG #ifdef CANAUTONODEDEBUG #include "SystemDefines.hpp" @@ -44,7 +44,7 @@ constexpr uint16_t KICK_REQUEST_RLOG_INDEX = 3; constexpr uint16_t HEARTBEAT_RLOG_INDEX = 4; constexpr uint16_t MAX_RESERVED_RLOG_INDEX = 4; // Make sure to update if adding a new reserved ID -constexpr uint16_t SEND_RECEIVE_ID_SPLIT_AMOUNT = MAX_CAN_ID/2; +constexpr uint16_t SEND_RECEIVE_ID_SPLIT_AMOUNT = 0; #ifdef CANAUTONODEDEBUG //#include "Task.hpp" diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index d986b05..258543e 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -241,13 +241,14 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { thisID += (request.logSizesInBytes[i]-1)/64+1; } + newNode.startingLogIndexOnMotherboard = nextFreeMotherboardLogIndex; + nextFreeMotherboardLogIndex += request.numberOfLogs; daughterNodes[nodesInNetwork] = newNode; recentlyJoined[recentlyJoinedNum++] = &daughterNodes[nodesInNetwork]; controller->RegisterLogs(newLogs, request.numberOfLogs); heartbeatGracePeriod[nodesInNetwork] = 3; nodesInNetwork++; - newNode.startingLogIndexOnMotherboard = nextFreeMotherboardLogIndex; - nextFreeMotherboardLogIndex += request.numberOfLogs; + SendAck(ACK_GOOD); From 58224b7f9156ef2b585106124de36be741df22a6 Mon Sep 17 00:00:00 2001 From: Local user Date: Mon, 11 May 2026 20:48:00 -0600 Subject: [PATCH 22/24] cleanup, limit defines adjustment for smaller node sizes --- CanAutoNode/CanAutoNode.cpp | 19 --- CanAutoNode/CanAutoNode.hpp | 9 +- CanAutoNode/CanAutoNodeDaughter.cpp | 102 +++++------ CanAutoNode/CanAutoNodeDaughter.hpp | 9 - CanAutoNode/CanAutoNodeMotherboard.cpp | 223 +++++++++++-------------- CanAutoNode/CanAutoNodeMotherboard.hpp | 4 +- 6 files changed, 141 insertions(+), 225 deletions(-) diff --git a/CanAutoNode/CanAutoNode.cpp b/CanAutoNode/CanAutoNode.cpp index 9a27661..e33ab43 100644 --- a/CanAutoNode/CanAutoNode.cpp +++ b/CanAutoNode/CanAutoNode.cpp @@ -8,8 +8,6 @@ #include #include - - CanAutoNode::~CanAutoNode() { } @@ -44,9 +42,7 @@ bool CanAutoNode::IDRangesOverlap(IDRange a, IDRange b) { * @return Node represented by the bytes. */ CanAutoNode::Node CanAutoNode::nodeFromMsg(const uint8_t *msg) { - return MsgToData(msg); - } /* Converts a 32-bit integer into a byte sequence (big-endian). @@ -62,10 +58,7 @@ void CanAutoNode::shift32to8(uint32_t in, uint8_t *out) { * @param msgout Pointer to output buffer. Must be as long as a Node struct. */ void CanAutoNode::msgFromNode(Node node, uint8_t *msgout) { - memcpy(msgout,&node,sizeof(Node)); - - } CanAutoNode::CanAutoNode() { @@ -92,7 +85,6 @@ bool CanAutoNode::SendMessageToDaughterBoardByCANIDOffset(UniqueBoardID boardID, } } return false; - } /* Sends a message starting at a given CAN ID, regardless of which board has claimed it. @@ -132,7 +124,6 @@ bool CanAutoNode::SendMessageToAllBoardsOfTypeByLogIndex(uint8_t boardType, } } return foundOne; - } #ifdef CANAUTONODEDEBUG @@ -151,15 +142,12 @@ void CanAutoNode::PrintBoardID(CanAutoNode::UniqueBoardID id) { * @return true if successfully sent. */ bool CanAutoNode::SendHeartbeat() { - HeartbeatInfo beat; beat.senderBoardID = thisNode.uniqueID; beat.dir = GetDir(); uint8_t msg[sizeof(HeartbeatInfo)] = {}; memcpy(msg,&beat,sizeof(msg)); return controller->SendByMsgID(msg, sizeof (msg), HEARTBEAT_CAN_ID); - //return controller->SendByMsgID(msg, sizeof(msg), HEARTBEAT_ID); - } /* Sends a message to a daughter board by a log index on that daughter board. Can be called from @@ -241,7 +229,6 @@ bool CanAutoNode::ReadMessageFromRXBuf(uint8_t logIndex, uint16_t logSize, uint8 memcpy(out,paddedOut,logSize); return true; } - #ifdef CANAUTONODEDEBUG //SOAR_PRINT("Buffer large enough, attempting read...\n"); #endif @@ -263,16 +250,13 @@ bool CanAutoNode::BoardExistsWithName(const char* name) { uint16_t CanAutoNode::GetNamesOfAllBoards(char(* outputArr)[MAX_NAME_STR_LEN], uint16_t outputArrayLen) { uint16_t num = 0; strncpy(outputArr[num++],thisNode.nodeName,MAX_NAME_STR_LEN); - // for(uint16_t i = 0; i < nodesInNetwork; i++) { strncpy(outputArr[num++],daughterNodes[i].nodeName,MAX_NAME_STR_LEN); if(num >= outputArrayLen) { break; } } - return num; - } uint16_t CanAutoNode::GetIDsOfAllBoards(CanAutoNode::UniqueBoardID* outputArr, uint16_t outputArrayLen) { @@ -284,9 +268,7 @@ uint16_t CanAutoNode::GetIDsOfAllBoards(CanAutoNode::UniqueBoardID* outputArr, u break; } } - return num; - } CanAutoNode::UniqueBoardID CanAutoNode::GetIDOfBoardWithName(const char* name) { @@ -314,7 +296,6 @@ uint16_t CanAutoNode::GetNumberOfLogIndicesInBoard(UniqueBoardID board) { } } return 0; - } uint16_t CanAutoNode::GetSizeOfLogIndexInBoard(UniqueBoardID board, uint16_t logindex) { diff --git a/CanAutoNode/CanAutoNode.hpp b/CanAutoNode/CanAutoNode.hpp index ff627c3..ed2d161 100644 --- a/CanAutoNode/CanAutoNode.hpp +++ b/CanAutoNode/CanAutoNode.hpp @@ -21,9 +21,9 @@ #include #include -constexpr uint32_t MAX_NODES_IN_NETWORK = 100; +constexpr uint32_t MAX_NODES_IN_NETWORK = 20; constexpr uint8_t MAX_LOG_TYPES_PER_NODE = 9; -constexpr uint8_t MAX_NAME_STR_LEN = 20; +constexpr uint8_t MAX_NAME_STR_LEN = 10; constexpr uint8_t MAX_JOIN_ATTEMPTS = 8; // Max 2047 for 11-bit standard FDCAN, max 536,870,911 for extended FDCAN. // See transceiver and board capabilities before changing. @@ -61,7 +61,6 @@ class CanAutoNode { CanAutoNode(CanAutoNode &&other) = delete; CanAutoNode& operator=(const CanAutoNode &other) = delete; - enum updateType { CAN_UPDATE_DAUGHTER, CAN_UPDATE_LAST_DAUGHTER, @@ -82,7 +81,6 @@ class CanAutoNode { bool operator==(const UniqueBoardID&) const = default; bool operator!=(const UniqueBoardID&) const = default; - }; bool SendMessageToDaughterByLogIndex(UniqueBoardID boardID, uint8_t logIndex, const uint8_t* msg); @@ -139,7 +137,6 @@ class CanAutoNode { bool operator==(const Node&) const = default; bool operator!=(const Node&) const = default; - }; static_assert(sizeof(Node) <= 64, "Node entries must be at most 64 bytes large. Try reducing MAX_LOGS"); @@ -197,10 +194,10 @@ class CanAutoNode { bool ReadMessageFromRXBuf(uint8_t logIndex, uint16_t logSize, uint8_t* out, uint16_t outLen); virtual HeartbeatInfo::DIRECTION GetDir() const = 0; + private: CanAutoNode(const CanAutoNode &other) = delete; - }; #endif /* AUTONODE_CANAUTONODE_HPP_ */ diff --git a/CanAutoNode/CanAutoNodeDaughter.cpp b/CanAutoNode/CanAutoNodeDaughter.cpp index 3112168..75ad767 100644 --- a/CanAutoNode/CanAutoNodeDaughter.cpp +++ b/CanAutoNode/CanAutoNodeDaughter.cpp @@ -2,8 +2,6 @@ #include - - /* Gets the state of this daughter board. * @return The current state. */ @@ -19,13 +17,13 @@ bool CanAutoNodeDaughter::TryRequestingJoiningNetwork() { if(GetCurrentState() != UNINITIALIZED) { return false; } - srand(GetThisBoardUniqueID().u1); + srand(GetThisBoardUniqueID().u2 ^ GetThisBoardUniqueID().u1 ^ GetThisBoardUniqueID().u0); uint16_t tries = 0; while(1) { if(!RequestToJoinNetwork()) { #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Failed try %d/%d\n",tries+1,MAX_JOIN_ATTEMPTS); + SOAR_PRINT("Failed try %d/%d\n",tries+1,MAX_JOIN_ATTEMPTS); #endif HAL_Delay(rand()%500+100); tries++; @@ -36,24 +34,23 @@ bool CanAutoNodeDaughter::TryRequestingJoiningNetwork() { ChangeState(REQUESTED_FAILED_WAITING_TO_RETRY); } else { #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Successfully sent request\n"); + SOAR_PRINT("Successfully sent request\n"); #endif ChangeState(REQUESTED_WAITING_FOR_RESPONSE); HAL_Delay(rand()%500+100); if(CheckForAcknowledgement()) { #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Received good ACK\n"); + SOAR_PRINT("Received good ACK\n"); #endif return true; } else { #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Non good ACK received\n"); + SOAR_PRINT("Non good ACK received\n"); #endif ChangeState(REQUESTED_FAILED_WAITING_TO_RETRY); } } } - } /* Send a request to join the network on the reserved join request CAN ID. @@ -83,13 +80,15 @@ bool CanAutoNodeDaughter::RequestToJoinNetwork() { return controller->SendByMsgID(msg, sizeof(msg), JOIN_REQUEST_CAN_ID); } +// you shouldn't be deleting this anyway but at least dont leak memory CanAutoNodeDaughter::~CanAutoNodeDaughter() { - + if(controller) { + delete controller; + } } - -/* Exhausts the FIFO until any acknowledgment is received. - * return true if a good acknowledgment is found. +/* @brief Exhausts the FIFO until any acknowledgment is received. + * @return true if a good acknowledgment is found. */ bool CanAutoNodeDaughter::CheckForAcknowledgement() { if(GetCurrentState() != REQUESTED_WAITING_FOR_RESPONSE) { @@ -98,16 +97,15 @@ bool CanAutoNodeDaughter::CheckForAcknowledgement() { #endif return false; } - uint8_t msg[64] = {123}; + uint8_t msg[64] = {0}; while(controller->ReceiveLogIndexFromRXBuf(msg, ACK_RLOG_INDEX)) { - acknowledgementStatus incomingStatus = static_cast(msg[0]); switch(incomingStatus) { case ACK_GOOD: #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Good ACK!\n"); + SOAR_PRINT("Good ACK!\n"); #endif controller->DiscardLog(KICK_REQUEST_RLOG_INDEX); // So we don't immediately get kicked on rejoining after a daughter reset ChangeState(WAITING_FOR_UPDATE); @@ -116,13 +114,13 @@ bool CanAutoNodeDaughter::CheckForAcknowledgement() { case ACK_NO_ROOM: ChangeState(ERROR); #ifdef CANAUTONODEDEBUG - SOAR_PRINT("No room!\n"); + SOAR_PRINT("No room!\n"); #endif return false; case ACK_BOARD_ALREADY_EXISTS: #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Already exists somehow!\n"); + SOAR_PRINT("Already exists somehow!\n"); #endif return false; @@ -130,29 +128,28 @@ bool CanAutoNodeDaughter::CheckForAcknowledgement() { // invalid ack ChangeState(ERROR); #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Invalid ACK!\n"); + SOAR_PRINT("Invalid ACK!\n"); #endif return false; } - } #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Didn't receive any ACK\n"); + SOAR_PRINT("Didn't receive any ACK\n"); #endif // not received return false; } -/* Exhausts the FIFO until an update is found, or an update is partly received and times out. - * return true if successfully received update. +/* @brief Exhausts the FIFO until an update is found, or an update is partly received and times out. + * @return true if successfully received update. */ bool CanAutoNodeDaughter::CheckForUpdate() { if(GetCurrentState() != WAITING_FOR_UPDATE) { return false; } - uint8_t msg[128] = {123}; + uint8_t msg[128] = {0}; // at this point the ack should have already been sent if it was this board joining, // so if this hits that means another board in the network tried joining or was kicked @@ -160,22 +157,16 @@ bool CanAutoNodeDaughter::CheckForUpdate() { while(controller->ReceiveLogIndexFromRXBuf(msg, ACK_RLOG_INDEX)) { acknowledgementStatus incomingStatus = static_cast(msg[0]); #ifdef CANAUTONODEDEBUG - SOAR_PRINT("even though we waiting for an update we got an ack of %d\n",incomingStatus); + SOAR_PRINT("even though we waiting for an update we got an ack of %d\n",incomingStatus); #endif if(incomingStatus != ACK_GOOD) { ChangeState(READY); return true; } - - - } while(controller->ReceiveLogIndexFromRXBuf(msg, UPDATE_RLOG_INDEX)) { - - return ReceiveUpdate(msg); - } // not received if(HAL_GetTick() - tickLastReceivedUpdatePart > 1000) { @@ -184,18 +175,17 @@ bool CanAutoNodeDaughter::CheckForUpdate() { #endif if(lastDetectedJoinRequest != UniqueBoardID{0} && lastDetectedJoinRequest != thisNode.uniqueID) { #ifdef CANAUTONODEDEBUG - SOAR_PRINT("but its ok since that join request wasnt even mine :)\n"); + SOAR_PRINT("but its ok since that join request wasnt even mine :)\n"); #endif - ChangeState(READY); - return false; + ChangeState(READY); + return false; } ChangeState(ERROR); } return false; - } -/* Exhausts the FIFO until kick, join, or heartbeat is encountered while ready. +/* @brief Exhausts the FIFO until kick, join, or heartbeat is encountered while ready. * @return true if any are found. */ bool CanAutoNodeDaughter::ProcessMessage() { @@ -226,7 +216,6 @@ bool CanAutoNodeDaughter::ProcessMessage() { } while(controller->ReceiveLogIndexFromRXBuf(msg, JOIN_REQUEST_RLOG_INDEX)) { - #ifdef CANAUTONODEDEBUG SOAR_PRINT("Saw a join request from another board\n"); #endif @@ -237,7 +226,6 @@ bool CanAutoNodeDaughter::ProcessMessage() { while(controller->ReceiveLogIndexFromRXBuf(msg, ACK_RLOG_INDEX)) { - #ifdef CANAUTONODEDEBUG SOAR_PRINT("Saw an ack, presumably for another board\n"); #endif @@ -256,15 +244,13 @@ bool CanAutoNodeDaughter::ProcessMessage() { } #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Received heartbeat\n"); + SOAR_PRINT("Received heartbeat\n"); #endif - HAL_Delay(thisNode.canIDRange.start*13 % 100); - SendHeartbeat(); + HAL_Delay(thisNode.canIDRange.start*13 % 100); + SendHeartbeat(); gotOne = true; } - - return gotOne; } @@ -293,8 +279,6 @@ void CanAutoNodeDaughter::ChangeState(daughterState target) { thisNode.canIDRange = {0,0}; break; - - default: break; } @@ -309,8 +293,8 @@ void CanAutoNodeDaughter::ChangeState(daughterState target) { */ CanAutoNodeDaughter::CanAutoNodeDaughter(FDCAN_HandleTypeDef *fdcan, const LogInit *logs, uint16_t numLogs, uint8_t boardType, uint8_t slotNumber, const char* readableName) { - controller = new FDCanController(fdcan,nullptr,0); + controller = new FDCanController(fdcan,nullptr,0); memcpy(logsToInit,logs,numLogs*sizeof(LogInit)); this->numLogs = numLogs; callbackcontroller = controller; @@ -325,11 +309,9 @@ CanAutoNodeDaughter::CanAutoNodeDaughter(FDCAN_HandleTypeDef *fdcan, const LogIn memset(this->thisNode.nodeName,0x00,MAX_NAME_STR_LEN); } - FDCanController::LogInitStruct reservedLogs[] = {{64,JOIN_REQUEST_CAN_ID},{64,ACK_CAN_ID},{sizeof(Node)+1,UPDATE_CAN_ID},{64,KICK_REQUEST_CAN_ID},{64,HEARTBEAT_CAN_ID}}; controller->RegisterLogs(reservedLogs, sizeof(reservedLogs)/sizeof(reservedLogs[0])); - } /* Sends a message to the motherboard by the log index. @@ -343,8 +325,6 @@ bool CanAutoNodeDaughter::SendMessageToMotherboardByLogID(uint16_t logID, const return false; } uint16_t txid = determinedLogs[logID].startingMsgID - SEND_RECEIVE_ID_SPLIT_AMOUNT; - //printf("sending to motherboard log index %d\n",logID); - //return controller->SendByLogIndex(msg, logID+MAX_RESERVED_RLOG_INDEX+1); return controller->SendByMsgID(msg, determinedLogs[logID].byteLength, txid); } @@ -366,47 +346,44 @@ bool CanAutoNodeDaughter::ReceiveUpdate(const uint8_t *msg) { if(receivedNode.uniqueID != thisNode.uniqueID) { this->daughterNodes[this->nodesInNetwork++] = receivedNode; #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Received update for someone else... initializedLogs: %d, numLogs: %d, according to the update numLogs: %d\n",initializedLogs,numLogs,receivedNode.numberOfLogs); + SOAR_PRINT("Received update for someone else... initializedLogs: %d, numLogs: %d, according to the update numLogs: %d\n",initializedLogs,numLogs,receivedNode.numberOfLogs); #endif } else { this->thisNode = receivedNode; #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Received update for me... initializedLogs: %d, numLogs: %d, according to the update numLogs: %d\n",initializedLogs,numLogs,receivedNode.numberOfLogs); + SOAR_PRINT("Received update for me... initializedLogs: %d, numLogs: %d, according to the update numLogs: %d\n",initializedLogs,numLogs,receivedNode.numberOfLogs); #endif if(!initializedLogs) { uint16_t canid = receivedNode.canIDRange.start; for(uint16_t i = 0; i < numLogs; i++) { uint16_t requiredIDs = (logsToInit[i].sizeInBytes-1)/64+1; - determinedLogs[i] = {logsToInit[i].sizeInBytes, canid+SEND_RECEIVE_ID_SPLIT_AMOUNT}; + determinedLogs[i] = {logsToInit[i].sizeInBytes, (uint16_t)(canid+SEND_RECEIVE_ID_SPLIT_AMOUNT)}; canid += requiredIDs; #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Registering log %d at canid %d byte size %d\n",i,determinedLogs[i].startingMsgID,determinedLogs[i].byteLength); + SOAR_PRINT("Registering log %d at canid %d byte size %d\n",i,determinedLogs[i].startingMsgID,determinedLogs[i].byteLength); #endif - } controller->RegisterLogs(determinedLogs, numLogs); - initializedLogs = true; } - } #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Received a daughter update part for "); - PrintBoardID(receivedNode.uniqueID); - SOAR_PRINT("\n"); + SOAR_PRINT("Received a daughter update part for "); + PrintBoardID(receivedNode.uniqueID); + SOAR_PRINT("\n"); #endif break; case CAN_UPDATE_MOTHERBOARD: this->Motherboard = receivedNode; #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Received a motherboard update part for "); - PrintBoardID(receivedNode.uniqueID); - SOAR_PRINT("\n"); + SOAR_PRINT("Received a motherboard update part for "); + PrintBoardID(receivedNode.uniqueID); + SOAR_PRINT("\n"); #endif break; @@ -425,7 +402,6 @@ bool CanAutoNodeDaughter::ReadMessageByLogIndex(uint8_t logIndex, } uint16_t logSize = determinedLogs[logIndex].byteLength; return ReadMessageFromRXBuf(logIndex+MAX_RESERVED_RLOG_INDEX+1, logSize, out, outLen); - } uint16_t CanAutoNodeDaughter::GetSizeOfLog(uint8_t logIndex) const { diff --git a/CanAutoNode/CanAutoNodeDaughter.hpp b/CanAutoNode/CanAutoNodeDaughter.hpp index f54a186..a49e8c8 100644 --- a/CanAutoNode/CanAutoNodeDaughter.hpp +++ b/CanAutoNode/CanAutoNodeDaughter.hpp @@ -21,8 +21,6 @@ class CanAutoNodeDaughter : public CanAutoNode { ERROR }; - //CanAutoNodeDaughter(FDCanController* contr, uint16_t msgIDsToRequestStartID, uint16_t msgIDsToRequestAmount); - CanAutoNodeDaughter(FDCAN_HandleTypeDef *fdcan, const LogInit *logs, uint16_t numLogs, uint8_t boardType, uint8_t slotNumber, const char* readableName); ~CanAutoNodeDaughter(); @@ -31,10 +29,8 @@ class CanAutoNodeDaughter : public CanAutoNode { CanAutoNodeDaughter(const CanAutoNodeDaughter &) = delete; CanAutoNodeDaughter &operator=(const CanAutoNodeDaughter &) = delete; - const daughterState GetCurrentState() const; - bool TryRequestingJoiningNetwork(); bool CheckCANCommands() override { @@ -67,10 +63,8 @@ class CanAutoNodeDaughter : public CanAutoNode { protected: - void ChangeState(daughterState target); -// uint32_t uniqueBoardID = HAL_GetDEVID(); Node Motherboard = {0}; bool CheckForAcknowledgement(); bool CheckForUpdate(); @@ -97,9 +91,6 @@ class CanAutoNodeDaughter : public CanAutoNode { bool initializedLogs = false; UniqueBoardID lastDetectedJoinRequest = {0}; -// const uint8_t boardType; -// const IDRange idRange; - }; #endif diff --git a/CanAutoNode/CanAutoNodeMotherboard.cpp b/CanAutoNode/CanAutoNodeMotherboard.cpp index 258543e..ef217cd 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.cpp +++ b/CanAutoNode/CanAutoNodeMotherboard.cpp @@ -10,8 +10,6 @@ bool CanAutoNodeMotherboard::KickNode(UniqueBoardID uniqueBoardID) { bool exists = false; uint16_t foundIndex = 0; - - for(uint16_t i = 0; i < nodesInNetwork; i++) { const Node& thisNode = daughterNodes[i]; if(thisNode.uniqueID == uniqueBoardID) { @@ -28,42 +26,37 @@ bool CanAutoNodeMotherboard::KickNode(UniqueBoardID uniqueBoardID) { SOAR_PRINT(")\nNow just forcing send kick\n"); #endif - - - - //return true; } else { - // to get rid of this node, first we will identify the MOTHERBOARD log indexes to remove ON THE MOTHERBOARD - uint8_t indicesToRemove[daughterNodes[foundIndex].numberOfLogs]; - for(uint8_t i = 0; i < daughterNodes[foundIndex].numberOfLogs; i++) { - indicesToRemove[i] = daughterNodes[foundIndex].startingLogIndexOnMotherboard+i; - } - controller->RemoveLogIndices(indicesToRemove, sizeof(indicesToRemove)/sizeof(indicesToRemove[0])); - nextFreeMotherboardLogIndex -= daughterNodes[foundIndex].numberOfLogs; - - // next, we shall update all other nodes to shift their motherboard log index offsets down to fill in the gap. - // this change will be reflected to all remaining daughters in the upcoming update - // note that this does not reassign can ids. this is fine, now that this node is gone its space in the - //can address space is freed and can be reassigned. i dont care about fragmentation, if you are connecting and kicking over 2000 nodes in a random order, there is some other problem - for(uint8_t i = 0; i < nodesInNetwork; i++) { - if(i != foundIndex && daughterNodes[i].startingLogIndexOnMotherboard > daughterNodes[foundIndex].startingLogIndexOnMotherboard) { - daughterNodes[i].startingLogIndexOnMotherboard -= daughterNodes[foundIndex].numberOfLogs; + // to get rid of this node, first we will identify the MOTHERBOARD log indexes to remove ON THE MOTHERBOARD + uint8_t indicesToRemove[daughterNodes[foundIndex].numberOfLogs]; + for(uint8_t i = 0; i < daughterNodes[foundIndex].numberOfLogs; i++) { + indicesToRemove[i] = daughterNodes[foundIndex].startingLogIndexOnMotherboard+i; + } + controller->RemoveLogIndices(indicesToRemove, sizeof(indicesToRemove)/sizeof(indicesToRemove[0])); + nextFreeMotherboardLogIndex -= daughterNodes[foundIndex].numberOfLogs; + + // next, we shall update all other nodes to shift their motherboard log index offsets down to fill in the gap. + // this change will be reflected to all remaining daughters in the upcoming update + // note that this does not reassign can ids. this is fine, now that this node is gone its space in the + //can address space is freed and can be reassigned. i dont care about fragmentation, if you are connecting and kicking over 2000 nodes in a random order, there is some other problem + for(uint8_t i = 0; i < nodesInNetwork; i++) { + if(i != foundIndex && daughterNodes[i].startingLogIndexOnMotherboard > daughterNodes[foundIndex].startingLogIndexOnMotherboard) { + daughterNodes[i].startingLogIndexOnMotherboard -= daughterNodes[foundIndex].numberOfLogs; + } } - } - - // now actually remove the kicked node - daughterNodes[foundIndex] = daughterNodes[--nodesInNetwork]; + // now actually remove the kicked node + daughterNodes[foundIndex] = daughterNodes[--nodesInNetwork]; - for(uint16_t i = 0; i < recentlyJoinedNum; i++) { - if(recentlyJoined[i]->uniqueID == uniqueBoardID) { - recentlyJoined[i] = recentlyJoined[--recentlyJoinedNum]; - break; + for(uint16_t i = 0; i < recentlyJoinedNum; i++) { + if(recentlyJoined[i]->uniqueID == uniqueBoardID) { + recentlyJoined[i] = recentlyJoined[--recentlyJoinedNum]; + break; + } } - } - heartbeatGracePeriod[foundIndex] = heartbeatGracePeriod[nodesInNetwork]; + heartbeatGracePeriod[foundIndex] = heartbeatGracePeriod[nodesInNetwork]; } if(!controller->SendByMsgID((uint8_t*)(&uniqueBoardID), sizeof(uniqueBoardID), KICK_REQUEST_CAN_ID)) { #ifdef CANAUTONODEDEBUG @@ -74,12 +67,11 @@ bool CanAutoNodeMotherboard::KickNode(UniqueBoardID uniqueBoardID) { return false; } #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Kicked node ("); - PrintBoardID(uniqueBoardID); - SOAR_PRINT(")\n"); + SOAR_PRINT("Kicked node ("); + PrintBoardID(uniqueBoardID); + SOAR_PRINT(")\n"); #endif - return SendFullUpdate(); } @@ -131,15 +123,11 @@ bool CanAutoNodeMotherboard::CheckForJoinRequest() { uint8_t msg[64] = {123}; uint32_t id = 0; - while(controller->ReceiveLogIndexFromRXBuf(msg, JOIN_REQUEST_CAN_ID)) { - return ReceiveJoinRequest(msg); - } // not received return false; - } /* Attempts to incorporate a new node into the network. Will assign the new node a @@ -150,7 +138,6 @@ bool CanAutoNodeMotherboard::CheckForJoinRequest() { */ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { - JoinRequest request = MsgToData(msg); #ifdef CANAUTONODEDEBUG SOAR_PRINT("Received a join request from "); @@ -167,21 +154,15 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { if(request.uniqueID == thisAlreadyExistingNode.uniqueID) { // already have this board somehow #ifdef CANAUTONODEDEBUG - SOAR_PRINT("But it already exists!\n"); + SOAR_PRINT("But it already exists!\n"); #endif - //HAL_Delay(20); SendAck(ACK_BOARD_ALREADY_EXISTS); - //HAL_Delay(10); - //SendFullUpdate(); HAL_Delay(10); KickNode(request.uniqueID); - //SendFullUpdate(); return false; } - } - // Finding smallest possible gap to fit the newly requested ID range into Node sortedNodes[nodesInNetwork]; memcpy(sortedNodes,daughterNodes,sizeof(sortedNodes)); @@ -200,6 +181,9 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { for(uint16_t i = 0; i < nodesInNetwork; i++) { const Node& thisNode = sortedNodes[i]; uint16_t thisAmountOfRoom = thisNode.canIDRange.start-previousEnd; + if(thisNode.canIDRange.start < previousEnd) { + thisAmountOfRoom = 0; + } if(thisAmountOfRoom < bestAmountOfRoom && thisAmountOfRoom >= requiredTotalCANIDs) { bestAmountOfRoom = thisAmountOfRoom; @@ -217,10 +201,8 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { foundRoom = true; } - if(foundRoom) { // found no issues - #ifdef CANAUTONODEDEBUG SOAR_PRINT("Adding new node at ID range [%d,%d)\n",bestStartingFreeCANID,bestStartingFreeCANID+requiredTotalCANIDs); #endif @@ -239,7 +221,6 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { newNode.logOffsetsInCANIDs[i] = thisID - bestStartingFreeCANID; newNode.logSizesInBytes[i] = request.logSizesInBytes[i]; thisID += (request.logSizesInBytes[i]-1)/64+1; - } newNode.startingLogIndexOnMotherboard = nextFreeMotherboardLogIndex; nextFreeMotherboardLogIndex += request.numberOfLogs; @@ -249,9 +230,7 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { heartbeatGracePeriod[nodesInNetwork] = 3; nodesInNetwork++; - SendAck(ACK_GOOD); - HAL_Delay(50); return SendFullUpdate(); } else { @@ -261,7 +240,6 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { #endif return false; } - } /* Sends an acknowledgment to the network. @@ -269,13 +247,10 @@ bool CanAutoNodeMotherboard::ReceiveJoinRequest(uint8_t* msg) { * @return true if successfully sent. */ bool CanAutoNodeMotherboard::SendAck(acknowledgementStatus status) { - uint8_t msg[] = {static_cast(status)}; return controller->SendByMsgID(msg, sizeof(msg), ACK_CAN_ID); - } - /* Sends a full list of all nodes in the network to all nodes. Serves to keep * daughter nodes up-to-date with the network contents. * Sends in multiple frames, where each frame contains one node preceded by a status byte, @@ -291,7 +266,7 @@ bool CanAutoNodeMotherboard::SendFullUpdate() { if(!controller->SendByMsgID(msg, sizeof(msg), UPDATE_CAN_ID)) { #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Failed to send motherboard update frame!\n"); + SOAR_PRINT("Failed to send motherboard update frame!\n"); #endif return false; } @@ -305,7 +280,7 @@ bool CanAutoNodeMotherboard::SendFullUpdate() { msg[0] = (i == nodesInNetwork-1) ? CAN_UPDATE_LAST_DAUGHTER : CAN_UPDATE_DAUGHTER; if(!controller->SendByMsgID(msg, sizeof(msg), UPDATE_CAN_ID)) { #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Tried but failed to send daughter update frame!\n"); + SOAR_PRINT("Tried but failed to send daughter update frame!\n"); #endif return false; } @@ -316,7 +291,6 @@ bool CanAutoNodeMotherboard::SendFullUpdate() { } return true; - } /* Sends a heartbeat, then monitors for responses. Will wait up to one second. @@ -335,9 +309,6 @@ bool CanAutoNodeMotherboard::Heartbeat() { return false; } - - - uint8_t received[nodesInNetwork]; memset(received,0,sizeof(received)); @@ -349,95 +320,92 @@ bool CanAutoNodeMotherboard::Heartbeat() { if(controller->ReceiveLogIndexFromRXBuf(out, HEARTBEAT_RLOG_INDEX)) { - HeartbeatInfo hi = MsgToData(out); - UniqueBoardID responseID = hi.senderBoardID; - bool foundResponder = false; + HeartbeatInfo hi = MsgToData(out); + UniqueBoardID responseID = hi.senderBoardID; + bool foundResponder = false; #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Got a heartbeat from "); - PrintBoardID(responseID); - SOAR_PRINT(", there are %d daughter nodes in the network\n",nodesInNetwork); + SOAR_PRINT("Got a heartbeat from "); + PrintBoardID(responseID); + SOAR_PRINT(", there are %d daughter nodes in the network\n",nodesInNetwork); #endif - for(int node = 0; node < nodesInNetwork; node++) { - if(daughterNodes[node].uniqueID == responseID) { - if(received[node]++ > 2) { - // received 3 or more heartbeats from the same node? + for(int node = 0; node < nodesInNetwork; node++) { + if(daughterNodes[node].uniqueID == responseID) { + if(received[node]++ > 2) { + // received 3 or more heartbeats from the same node? #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Received multiple heartbeats from "); - PrintBoardID(responseID); - SOAR_PRINT(", kicking\n"); + SOAR_PRINT("Received multiple heartbeats from "); + PrintBoardID(responseID); + SOAR_PRINT(", kicking\n"); #endif - KickNode(responseID); - } + KickNode(responseID); + } #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Found the source of this heartbeat at %d!\n",node); + SOAR_PRINT("Found the source of this heartbeat at %d!\n",node); #endif - foundResponder = true; - break; - } + foundResponder = true; + break; } - bool gotAllOfThem = true; - for(uint8_t j = 0; j < nodesInNetwork; j++) { - if(!received[j]) { - gotAllOfThem = false; - break; - } + } + bool gotAllOfThem = true; + for(uint8_t j = 0; j < nodesInNetwork; j++) { + if(!received[j]) { + gotAllOfThem = false; + break; } + } - if(!foundResponder) { - // ??? a node that wasn't in the network just responded to the heartbeat? get out + if(!foundResponder) { + // ??? a node that wasn't in the network just responded to the heartbeat? get out #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Received heartbeat from unrecognized node "); - PrintBoardID(responseID); - SOAR_PRINT(", kicking\n"); + SOAR_PRINT("Received heartbeat from unrecognized node "); + PrintBoardID(responseID); + SOAR_PRINT(", kicking\n"); #endif - KickNode(responseID); - } - - - if(gotAllOfThem) { - return true; // just leave early, we got all the responses - } - - + KickNode(responseID); + } + if(gotAllOfThem) { + return true; // just leave early, we got all the responses + } } if(i > 10 && nodesInNetwork == 0) { return true; // don't bother waiting the whole timeout when there are no daughter nodes, we just want to see if there are any out-of-network responders } - } for(size_t i = 0; i < nodesInNetwork; i++) { if(!received[i]) { // Found a node that never responded to the heartbeat #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Received no heartbeat from "); - PrintBoardID(daughterNodes[i].uniqueID); - if(heartbeatGracePeriod[i] > 0) { - SOAR_PRINT(", but it had grace!\n"); - } else { - SOAR_PRINT(", kicking\n"); - } + SOAR_PRINT("Received no heartbeat from "); + PrintBoardID(daughterNodes[i].uniqueID); + if(heartbeatGracePeriod[i] > 0) { + SOAR_PRINT(", but it had grace!\n"); + } else { + SOAR_PRINT(", kicking\n"); + } #endif - if(heartbeatGracePeriod[i] > 0) { - heartbeatGracePeriod[i]--; - } else { - KickNode(daughterNodes[i].uniqueID); - } + if(heartbeatGracePeriod[i] > 0) { + heartbeatGracePeriod[i]--; + } else { + KickNode(daughterNodes[i].uniqueID); + } } } return true; - } +/* @brief Gets the nuumber of ticks since the last time a heartbeat was sent. + * @return Ticks + */ uint32_t CanAutoNodeMotherboard::GetTicksSinceLastHeartbeat() const { return HAL_GetTick() - lastHeartbeatTick; } -/* - * Reads an incoming message from a daughter node on a given log index. +/* @brief Reads an incoming message from a daughter node on a given log index. + * @return true on success. */ bool CanAutoNodeMotherboard::ReadMessageFromDaughterByLogIndex( UniqueBoardID daughter, uint8_t logIndex, uint8_t *out, @@ -447,27 +415,23 @@ bool CanAutoNodeMotherboard::ReadMessageFromDaughterByLogIndex( const Node& thisNode = daughterNodes[i]; if(thisNode.uniqueID == daughter) { - if(logIndex >= thisNode.numberOfLogs) { + if(logIndex >= thisNode.numberOfLogs) { #ifdef CANAUTONODEDEBUG - SOAR_PRINT("Cannot read log index %d from daughter with max index %d",logIndex,thisNode.numberOfLogs); + SOAR_PRINT("Cannot read log index %d from daughter with max index %d",logIndex,thisNode.numberOfLogs); #endif - return false; - } + return false; + } return ReadMessageFromRXBuf(thisNode.startingLogIndexOnMotherboard+logIndex, thisNode.logSizesInBytes[logIndex], out, outSize); } } -#ifdef CANAUTONODEDEBUG - //SOAR_PRINT("No node with that ID!\n"); -#endif - return false; + return false; } /* Returns an array of name strings of any boards that joined the network since the last call of this function. * @param outputArr A pointer to an array of char arrays to store the names. * @param outputBufferLen For safety, will not write more entries than this to the output. * @return The number of nodes returned in the array. - * */ uint16_t CanAutoNodeMotherboard::GetNamesOfNewlyJoinedBoards(char(*outputArr)[MAX_NAME_STR_LEN], uint16_t outputBufferLen) { @@ -481,10 +445,15 @@ uint16_t CanAutoNodeMotherboard::GetNamesOfNewlyJoinedBoards(char(*outputArr)[MA if(i >= outputBufferLen) { break; } - } memcpy(recentlyJoined,&recentlyJoined[recentlyJoinedNum-num],(num)*sizeof(Node*)); recentlyJoinedNum -= num; return num; } + +CanAutoNodeMotherboard::~CanAutoNodeMotherboard() { + if(controller) { + delete controller; + } +} diff --git a/CanAutoNode/CanAutoNodeMotherboard.hpp b/CanAutoNode/CanAutoNodeMotherboard.hpp index 010e259..0a8bcb4 100644 --- a/CanAutoNode/CanAutoNodeMotherboard.hpp +++ b/CanAutoNode/CanAutoNodeMotherboard.hpp @@ -8,9 +8,11 @@ class CanAutoNodeMotherboard : public CanAutoNode { public: - CanAutoNodeMotherboard(FDCAN_HandleTypeDef *fdcan); + ~CanAutoNodeMotherboard(); + CanAutoNodeMotherboard() = delete; + bool CheckCANCommands() override { return CheckForJoinRequest(); } From add244a876f682db170999a9b45c8cc83741a9b4 Mon Sep 17 00:00:00 2001 From: Local user Date: Mon, 11 May 2026 21:14:54 -0600 Subject: [PATCH 23/24] now packs can structs to avoid compiler flags potentially causing issues between boards --- CanAutoNode/CanAutoNode.hpp | 8 ++++++++ CanAutoNode/LogTypes/DAQLogs.hpp | 8 ++++++++ CanAutoNode/LogTypes/LogStructs.hpp | 8 ++++++++ CanAutoNode/LogTypes/RPBLogs.hpp | 7 ++++++- 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/CanAutoNode/CanAutoNode.hpp b/CanAutoNode/CanAutoNode.hpp index ed2d161..462bea3 100644 --- a/CanAutoNode/CanAutoNode.hpp +++ b/CanAutoNode/CanAutoNode.hpp @@ -12,6 +12,7 @@ * Define this to enable debug prints across the driver. Uses SOAR_PRINT. */ //#define CANAUTONODEDEBUG +#define PACK_NETWORKLEVEL_CAN_STRUCTS #ifdef CANAUTONODEDEBUG #include "SystemDefines.hpp" @@ -120,6 +121,9 @@ class CanAutoNode { bool operator!=(const IDRange&) const = default; }; +#ifdef PACK_NETWORKLEVEL_CAN_STRUCTS +#pragma pack(push,1) +#endif struct Node { IDRange canIDRange; UniqueBoardID uniqueID = {0}; @@ -160,6 +164,10 @@ class CanAutoNode { uint8_t logSizesInBytes[MAX_LOG_TYPES_PER_NODE]; }; +#ifdef PACK_NETWORKLEVEL_CAN_STRUCTS +#pragma pack(pop) +#endif + static_assert(sizeof(JoinRequest) <= 64, "Join request entries must be at most 64 bytes large. Try reducing MAX_LOGS"); FDCanController* controller = nullptr; diff --git a/CanAutoNode/LogTypes/DAQLogs.hpp b/CanAutoNode/LogTypes/DAQLogs.hpp index c323fbf..5c3ea97 100644 --- a/CanAutoNode/LogTypes/DAQLogs.hpp +++ b/CanAutoNode/LogTypes/DAQLogs.hpp @@ -11,11 +11,19 @@ #include "LogStructs.hpp" #include "CanAutoNodeDaughter.hpp" +#ifdef PACK_CAN_STRUCTS +#pragma pack(push,1) +#endif // Custom Data Types struct DAQ_AIR_BRAKES_COMMAND { bool airBrakesGo; }; + +#ifdef PACK_CAN_STRUCTS +#pragma pack(pop) +#endif + // Add CAN logs here in the order you want them #define DAQ_LOGS_X \ X(CanImuData6Axis) \ diff --git a/CanAutoNode/LogTypes/LogStructs.hpp b/CanAutoNode/LogTypes/LogStructs.hpp index db0d134..2d79423 100644 --- a/CanAutoNode/LogTypes/LogStructs.hpp +++ b/CanAutoNode/LogTypes/LogStructs.hpp @@ -8,6 +8,11 @@ #ifndef LOGSTRUCTS_HPP_ #define LOGSTRUCTS_HPP_ +#define PACK_CAN_STRUCTS + +#ifdef PACK_CAN_STRUCTS +#pragma pack(push,1) +#endif // Possible IMU structs struct CanImuData9Axis { uint32_t accel_x; @@ -47,5 +52,8 @@ struct CanMagData { uint32_t mag_y; uint32_t mag_z; }; +#ifdef PACK_CAN_STRUCTS +#pragma pack(pop) +#endif #endif /* LOGSTRUCTS_HPP_ */ diff --git a/CanAutoNode/LogTypes/RPBLogs.hpp b/CanAutoNode/LogTypes/RPBLogs.hpp index 2963fe8..927eee2 100644 --- a/CanAutoNode/LogTypes/RPBLogs.hpp +++ b/CanAutoNode/LogTypes/RPBLogs.hpp @@ -11,7 +11,9 @@ #include "LogStructs.hpp" #include "CanAutoNodeDaughter.hpp" - +#ifdef PACK_CAN_STRUCTS +#pragma pack(push,1) +#endif // Custom Data Types struct RPB_CAMERA_POWER_COMMAND { uint8_t camera; @@ -35,6 +37,9 @@ struct RPB_FROM_DAQ_AIR_BRAKES_LEVEL { uint8_t level; }; +#ifdef PACK_CAN_STRUCTS +#pragma pack(pop) +#endif // Add CAN logs here in the order you want them #define RPB_CAN_LOGS \ X(RPB_CAMERA_POWER_COMMAND) \ From 369f508060a1a9f24fa4785f6289ab076b83fe6b Mon Sep 17 00:00:00 2001 From: Local user Date: Thu, 14 May 2026 22:55:52 -0600 Subject: [PATCH 24/24] packing macros, sol logs --- CanAutoNode/CanAutoNode.hpp | 2 +- CanAutoNode/LogTypes/LogStructs.hpp | 2 +- CanAutoNode/LogTypes/SOLLogs.hpp | 49 +++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 CanAutoNode/LogTypes/SOLLogs.hpp diff --git a/CanAutoNode/CanAutoNode.hpp b/CanAutoNode/CanAutoNode.hpp index 462bea3..c055498 100644 --- a/CanAutoNode/CanAutoNode.hpp +++ b/CanAutoNode/CanAutoNode.hpp @@ -12,7 +12,7 @@ * Define this to enable debug prints across the driver. Uses SOAR_PRINT. */ //#define CANAUTONODEDEBUG -#define PACK_NETWORKLEVEL_CAN_STRUCTS +//#define PACK_NETWORKLEVEL_CAN_STRUCTS #ifdef CANAUTONODEDEBUG #include "SystemDefines.hpp" diff --git a/CanAutoNode/LogTypes/LogStructs.hpp b/CanAutoNode/LogTypes/LogStructs.hpp index 2d79423..a45d061 100644 --- a/CanAutoNode/LogTypes/LogStructs.hpp +++ b/CanAutoNode/LogTypes/LogStructs.hpp @@ -8,7 +8,7 @@ #ifndef LOGSTRUCTS_HPP_ #define LOGSTRUCTS_HPP_ -#define PACK_CAN_STRUCTS +//#define PACK_CAN_STRUCTS #ifdef PACK_CAN_STRUCTS #pragma pack(push,1) diff --git a/CanAutoNode/LogTypes/SOLLogs.hpp b/CanAutoNode/LogTypes/SOLLogs.hpp new file mode 100644 index 0000000..5f1d31c --- /dev/null +++ b/CanAutoNode/LogTypes/SOLLogs.hpp @@ -0,0 +1,49 @@ +/* + * CanStructs.hpp + * + * Created on: May 2, 2026 + * Author: Local user + */ + +#ifndef SOLLOGS_HPP_ +#define SOLLOGS_HPP_ + +#include "LogStructs.hpp" +#include "CanAutoNodeDaughter.hpp" + +#ifdef PACK_CAN_STRUCTS +#pragma pack(push,1) +#endif +// Custom Data Types +struct SOL_POWER_COMMAND { + enum SOLENOID { + SOL_30W_A, + SOL_30W_B, + SOL_30W_C, + SOL_30W_D, + SOL_15W_A, + SOL_15W_B, + + } sol; + bool powerOn; +}; + +#ifdef PACK_CAN_STRUCTS +#pragma pack(pop) +#endif + +// Add CAN logs here in the order you want them +#define SOL_CAN_LOGS \ + X(SOL_POWER_COMMAND) + +#define X(x) sizeof(x), +const CanAutoNodeDaughter::LogInit SOL_Init[] = {SOL_CAN_LOGS}; +#undef X + +#define X(x) _ ## x ## _LOGINDEX, +enum SOL_LogIndexes {SOL_CAN_LOGS SOL_COUNT} ; +#undef X + + +#undef struct +#endif /* SOLLOGS_HPP_ */