Update CAN for multi-board support

This commit is contained in:
Michael Ehrenreich
2021-03-28 01:37:14 +01:00
parent 67defc0450
commit b167180b91
5 changed files with 119 additions and 79 deletions

34
can.c
View File

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

37
can.h
View File

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

View File

@ -2,6 +2,7 @@
#include <cstddef>
#include <cstring>
#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 <class Sent, class Received>
void CANFeedc0de<Sent, Received>::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 <class Sent, class Received>
void CANFeedc0de<Sent, Received>::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 <class Sent, class Received>
bool CANFeedc0de<Sent, Received>::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 <class Sent, class Received>
bool CANFeedc0de<Sent, Received>::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<Command, Feedback>;
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<Command, Feedback> 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<Feedback, Command>;
extern "C"
{
void can_feedc0de_handle_frame(uint16_t id, uint8_t* frame, uint8_t len)
{
extern CANFeedc0de<Feedback, Command> can_feedc0de;
if (!can_feedc0de.handle_frame(id, frame, len))
Error_Handler();
}
void can_feedc0de_poll()
{
extern CANFeedc0de can_feedc0de;
extern CANFeedc0de<Feedback, Command> can_feedc0de;
can_feedc0de.poll();
}
}
#endif

View File

@ -4,19 +4,34 @@
#include <cstdint>
#include "protocol.h"
#include "can_fc.h"
template <class Sent, class Received>
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"

View File

@ -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<Feedback, Command> 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);