From b167180b914b8910b1f4fbd0ee9b3a9dd2d7e8bf Mon Sep 17 00:00:00 2001 From: Michael Ehrenreich Date: Sun, 28 Mar 2021 01:37:14 +0100 Subject: [PATCH] Update CAN for multi-board support --- can.c | 34 ++++----------------- can.h | 37 ++++++++++++++--------- can_feedc0de.cpp | 79 +++++++++++++++++++++++++++++++++--------------- can_feedc0de.h | 33 ++++++++++++++------ main.cpp | 15 ++++++--- 5 files changed, 119 insertions(+), 79 deletions(-) diff --git a/can.c b/can.c index 581c42b..d93d9ba 100644 --- a/can.c +++ b/can.c @@ -91,28 +91,6 @@ static uint8_t dlc_to_len(uint32_t dlc) return dlc; } -/** - * @brief Main program. - * @param None - * @retval None - */ -void can_test(void) -{ - TxHeader.DLC = 2; - TxHeader.StdId = 0x321; - - /* Set the data to be transmitted */ - TxData[0] = ubKeyNumber + 1; - TxData[1] = 0xAD; - - /* Start the Transmission process */ - if (HAL_CAN_AddTxMessage(&CanHandle, &TxHeader, TxData, &TxMailbox) != HAL_OK) - { - /* Transmission request Error */ - Error_Handler(); - } -} - void can_tx(uint16_t id, const uint8_t* data, uint8_t len) { TxHeader.StdId = id; @@ -123,7 +101,7 @@ void can_tx(uint16_t id, const uint8_t* data, uint8_t len) } /* Start the Transmission process */ - if (HAL_CAN_AddTxMessage(&CanHandle, &TxHeader, (uint8_t*)data, &TxMailbox) != HAL_OK) + if (HAL_CAN_AddTxMessage(&CanHandle, &TxHeader, (uint8_t *)data, &TxMailbox) != HAL_OK) { /* Transmission request Error */ Error_Handler(); @@ -147,7 +125,7 @@ static void __NO_RETURN Error_Handler(void) * @param None * @retval None */ -void can_config(void) +void can_init(void) { CAN_FilterTypeDef sFilterConfig; @@ -180,9 +158,9 @@ void can_config(void) sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK; sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT; sFilterConfig.FilterIdHigh = 0x0000; - sFilterConfig.FilterIdLow = 0x0310; + sFilterConfig.FilterIdLow = CAN_ID_BOARD | (BOARD_INDEX << 4) | CAN_DIRECTION_STW_TO_BOARD; sFilterConfig.FilterMaskIdHigh = 0x0000; - sFilterConfig.FilterMaskIdLow = 0x07F8; + sFilterConfig.FilterMaskIdLow = 0x07F1; sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0; sFilterConfig.FilterActivation = ENABLE; sFilterConfig.SlaveStartFilterBank = 14; @@ -259,8 +237,8 @@ static void CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *CanHandle) } if (RxHeader.IDE == CAN_ID_STD && - (RxHeader.StdId == CAN_ID_COMMAND_STW_TO_BACK || - RxHeader.StdId == CAN_ID_FEEDBACK_STW_TO_BACK)) + (RxHeader.StdId == CAN_ID_COMMAND_STW_TO_BOARD(BOARD_INDEX) || + RxHeader.StdId == CAN_ID_FEEDBACK_STW_TO_BOARD(BOARD_INDEX))) { can_feedc0de_handle_frame(RxHeader.StdId, RxData, dlc_to_len(RxHeader.DLC)); } diff --git a/can.h b/can.h index 02ad8f4..857cbea 100644 --- a/can.h +++ b/can.h @@ -1,28 +1,37 @@ #pragma once -#define CAN_ID_COMMAND_STW_TO_BACK 0x311 -#define CAN_ID_COMMAND_BACK_TO_STW 0x312 -#define CAN_ID_COMMAND_STW_TO_FRONT 0x315 -#define CAN_ID_COMMAND_FRONT_TO_STW 0x316 +#define BOARD_INDEX 0 -#define CAN_ID_FEEDBACK_STW_TO_BACK 0x319 -#define CAN_ID_FEEDBACK_BACK_TO_STW 0x31A -#define CAN_ID_FEEDBACK_STW_TO_FRONT 0x31D -#define CAN_ID_FEEDBACK_FRONT_TO_STW 0x31E +#define CAN_ID_BOARD 0x300 -#define CAN_ID_HB_BACK_TO_STW 0x331 -#define CAN_ID_HB_FRONT_TO_STW 0x333 +#define CAN_SUBID_COMMAND 0x000 +#define CAN_SUBID_FEEDBACK 0x002 +#define CAN_SUBID_RESERVED0 0x004 +#define CAN_SUBID_RESERVED1 0x006 +#define CAN_SUBID_RESERVED2 0x008 +#define CAN_SUBID_RESERVED3 0x00a +#define CAN_SUBID_RESERVED4 0x00c +#define CAN_SUBID_RESERVED5 0x00e +#define CAN_DIRECTION_STW_TO_BOARD 0x000 +#define CAN_DIRECTION_BOARD_TO_STW 0x001 + +#define CAN_ID_COMMAND_STW_TO_BOARD(board_index) \ + (CAN_ID_BOARD | ((board_index) << 4) | CAN_SUBID_COMMAND | CAN_DIRECTION_STW_TO_BOARD) +#define CAN_ID_COMMAND_BOARD_TO_STW(board_index) \ + (CAN_ID_BOARD | ((board_index) << 4) | CAN_SUBID_COMMAND | CAN_DIRECTION_BOARD_TO_STW) +#define CAN_ID_FEEDBACK_STW_TO_BOARD(board_index) \ + (CAN_ID_BOARD | ((board_index) << 4) | CAN_SUBID_FEEDBACK | CAN_DIRECTION_STW_TO_BOARD) +#define CAN_ID_FEEDBACK_BOARD_TO_STW(board_index) \ + (CAN_ID_BOARD | ((board_index) << 4) | CAN_SUBID_FEEDBACK | CAN_DIRECTION_BOARD_TO_STW) #ifdef __cplusplus extern "C" { #endif -void can_config(void); -void can_test(void); -void can_tx(uint16_t id, const uint8_t* data, uint8_t len); - +void can_init(void); +void can_tx(uint16_t address, const uint8_t* data, uint8_t len); #ifdef __cplusplus } diff --git a/can_feedc0de.cpp b/can_feedc0de.cpp index 7f30651..f7ae43c 100644 --- a/can_feedc0de.cpp +++ b/can_feedc0de.cpp @@ -2,6 +2,7 @@ #include #include +#include "config.h" #include "protocol.h" #include "can_fc.h" @@ -10,60 +11,90 @@ static_assert((sizeof(Command) + FC_CHUNK_SIZE - 1) / FC_CHUNK_SIZE < 15); -void CANFeedc0de::poll() +template +void CANFeedc0de::poll() { - if (feedc0de_fcs.tx_pending()) - feedc0de_fcs.tx(); - - if (feedc0de_fcr.ack_pending()) - feedc0de_fcr.ack(); + feedc0de_fcs.tx(); + feedc0de_fcr.ack(); } -void CANFeedc0de::send_feedback(const Feedback& in) +template +void CANFeedc0de::send(const Sent& in) { - feedback = in; - feedc0de_fcs.reset(((uint8_t*)&feedback) + 2, sizeof(feedback) - 4); + sent = in; + feedc0de_fcs.reset(((uint8_t*)&sent) + 2, sizeof(sent) - 4); } -bool CANFeedc0de::get_command(Command& out) +template +bool CANFeedc0de::get(Received& out) { if (!feedc0de_fcr.transfer_finished()) return false; - out = command; - feedc0de_fcr.reset(((uint8_t*)&command) + 2, sizeof(command) - 4); + out = received; + feedc0de_fcr.reset(((uint8_t*)&received) + 2, sizeof(received) - 4); return true; } -void CANFeedc0de::handle_frame(uint16_t id, uint8_t* frame, uint8_t len) +template +bool CANFeedc0de::handle_frame(uint16_t id, uint8_t* frame, uint8_t len) { - switch (id) + if (id == fcs_rx_can_id) { - case CAN_ID_FEEDBACK_STW_TO_BACK: feedc0de_fcs.handle_frame(frame, len); - break; - case CAN_ID_COMMAND_STW_TO_BACK: - feedc0de_fcr.handle_frame(frame, len); - break; - default: - Error_Handler(); + return true; } + else if (id == fcr_rx_can_id) + { + feedc0de_fcr.handle_frame(frame, len); + return true; + } + + return false; } +#ifdef CAN_FEEDCODE_STW +template class CANFeedc0de; + extern "C" { void can_feedc0de_handle_frame(uint16_t id, uint8_t* frame, uint8_t len) { - extern CANFeedc0de can_feedc0de; - can_feedc0de.handle_frame(id, frame, len); + extern CANFeedc0de can_instances[NUM_BOARDS_MAX]; + + bool handled = false; + for (size_t i = 0; i < NUM_BOARDS_MAX; i++) + { + if (can_instances[i].handle_frame(id, frame, len)) + handled = true; + } + + if (!handled) + Error_Handler(); +} + +} + +#else +template class CANFeedc0de; + +extern "C" +{ + +void can_feedc0de_handle_frame(uint16_t id, uint8_t* frame, uint8_t len) +{ + extern CANFeedc0de can_feedc0de; + if (!can_feedc0de.handle_frame(id, frame, len)) + Error_Handler(); } void can_feedc0de_poll() { - extern CANFeedc0de can_feedc0de; + extern CANFeedc0de can_feedc0de; can_feedc0de.poll(); } } +#endif diff --git a/can_feedc0de.h b/can_feedc0de.h index f80cf39..f484bd0 100644 --- a/can_feedc0de.h +++ b/can_feedc0de.h @@ -4,19 +4,34 @@ #include #include "protocol.h" #include "can_fc.h" + +template class CANFeedc0de { public: - void poll(); - void handle_frame(uint16_t id, uint8_t* frame, uint8_t len); - void send_feedback(const Feedback& in); - bool get_command(Command& out); -private: - Command command; - Feedback feedback; + CANFeedc0de(uint16_t fcs_tx_can_id, uint16_t fcs_rx_can_id, + uint16_t fcr_tx_can_id, uint16_t fcr_rx_can_id) + : fcs_rx_can_id(fcs_rx_can_id), + fcr_rx_can_id(fcr_rx_can_id), + feedc0de_fcs(fcs_tx_can_id), + feedc0de_fcr(fcr_tx_can_id, (uint8_t *)&received + 2, sizeof(received) - 4) + { + }; - FCSender feedc0de_fcs = FCSender(CAN_ID_FEEDBACK_BACK_TO_STW); - FCReceiver feedc0de_fcr = FCReceiver(CAN_ID_COMMAND_BACK_TO_STW, ((uint8_t *)&command) + 2, sizeof(command) - 4); + void poll(); + bool handle_frame(uint16_t id, uint8_t* frame, uint8_t len); + void send(const Sent& in); + bool get(Received& out); + +private: + Sent sent; + Received received; + + uint16_t fcs_rx_can_id; + uint16_t fcr_rx_can_id; + + FCSender feedc0de_fcs; + FCReceiver feedc0de_fcr; }; extern "C" diff --git a/main.cpp b/main.cpp index 11f7f63..1bb0c77 100644 --- a/main.cpp +++ b/main.cpp @@ -38,7 +38,12 @@ extern const P rtP_Left; // default settings defined in BLDC_controller_data.c #include "can.h" #include "can_feedc0de.h" -CANFeedc0de can_feedc0de; +CANFeedc0de can_feedc0de( + CAN_ID_FEEDBACK_BOARD_TO_STW(BOARD_INDEX), + CAN_ID_FEEDBACK_STW_TO_BOARD(BOARD_INDEX), + CAN_ID_COMMAND_BOARD_TO_STW(BOARD_INDEX), + CAN_ID_COMMAND_STW_TO_BOARD(BOARD_INDEX) +); #endif @@ -234,7 +239,9 @@ int main() #ifndef FEATURE_CAN HAL_UART_Receive_DMA(&huart2, (uint8_t *)&command, sizeof(command)); -#endif +#endif // FEATURE_CAN + +#endif // MOTOR_TEST for (;;) { HAL_Delay(DELAY_IN_MAIN_LOOP); //delay in ms @@ -1062,7 +1069,7 @@ void parseCommand() bool any_parsed{false}; #ifdef FEATURE_CAN - any_parsed = can_feedc0de.get_command(command); + any_parsed = can_feedc0de.get(command); #else for (int i = 0; i < 1; i++) { @@ -1161,7 +1168,7 @@ void sendFeedback() feedback.checksum = calculateChecksum(feedback); #ifdef FEATURE_CAN - can_feedc0de.send_feedback(feedback); + can_feedc0de.send(feedback); #else UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN; UART_DMA_CHANNEL->CNDTR = sizeof(feedback);