Update CAN for multi-board support
This commit is contained in:
34
can.c
34
can.c
@ -91,28 +91,6 @@ static uint8_t dlc_to_len(uint32_t dlc)
|
|||||||
return 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)
|
void can_tx(uint16_t id, const uint8_t* data, uint8_t len)
|
||||||
{
|
{
|
||||||
TxHeader.StdId = id;
|
TxHeader.StdId = id;
|
||||||
@ -123,7 +101,7 @@ void can_tx(uint16_t id, const uint8_t* data, uint8_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Start the Transmission process */
|
/* 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 */
|
/* Transmission request Error */
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
@ -147,7 +125,7 @@ static void __NO_RETURN Error_Handler(void)
|
|||||||
* @param None
|
* @param None
|
||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void can_config(void)
|
void can_init(void)
|
||||||
{
|
{
|
||||||
CAN_FilterTypeDef sFilterConfig;
|
CAN_FilterTypeDef sFilterConfig;
|
||||||
|
|
||||||
@ -180,9 +158,9 @@ void can_config(void)
|
|||||||
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
|
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
|
||||||
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
|
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
|
||||||
sFilterConfig.FilterIdHigh = 0x0000;
|
sFilterConfig.FilterIdHigh = 0x0000;
|
||||||
sFilterConfig.FilterIdLow = 0x0310;
|
sFilterConfig.FilterIdLow = CAN_ID_BOARD | (BOARD_INDEX << 4) | CAN_DIRECTION_STW_TO_BOARD;
|
||||||
sFilterConfig.FilterMaskIdHigh = 0x0000;
|
sFilterConfig.FilterMaskIdHigh = 0x0000;
|
||||||
sFilterConfig.FilterMaskIdLow = 0x07F8;
|
sFilterConfig.FilterMaskIdLow = 0x07F1;
|
||||||
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
|
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
|
||||||
sFilterConfig.FilterActivation = ENABLE;
|
sFilterConfig.FilterActivation = ENABLE;
|
||||||
sFilterConfig.SlaveStartFilterBank = 14;
|
sFilterConfig.SlaveStartFilterBank = 14;
|
||||||
@ -259,8 +237,8 @@ static void CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *CanHandle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (RxHeader.IDE == CAN_ID_STD &&
|
if (RxHeader.IDE == CAN_ID_STD &&
|
||||||
(RxHeader.StdId == CAN_ID_COMMAND_STW_TO_BACK ||
|
(RxHeader.StdId == CAN_ID_COMMAND_STW_TO_BOARD(BOARD_INDEX) ||
|
||||||
RxHeader.StdId == CAN_ID_FEEDBACK_STW_TO_BACK))
|
RxHeader.StdId == CAN_ID_FEEDBACK_STW_TO_BOARD(BOARD_INDEX)))
|
||||||
{
|
{
|
||||||
can_feedc0de_handle_frame(RxHeader.StdId, RxData, dlc_to_len(RxHeader.DLC));
|
can_feedc0de_handle_frame(RxHeader.StdId, RxData, dlc_to_len(RxHeader.DLC));
|
||||||
}
|
}
|
||||||
|
37
can.h
37
can.h
@ -1,28 +1,37 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define CAN_ID_COMMAND_STW_TO_BACK 0x311
|
#define BOARD_INDEX 0
|
||||||
#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 CAN_ID_FEEDBACK_STW_TO_BACK 0x319
|
#define CAN_ID_BOARD 0x300
|
||||||
#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_HB_BACK_TO_STW 0x331
|
#define CAN_SUBID_COMMAND 0x000
|
||||||
#define CAN_ID_HB_FRONT_TO_STW 0x333
|
#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
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void can_config(void);
|
void can_init(void);
|
||||||
void can_test(void);
|
void can_tx(uint16_t address, const uint8_t* data, uint8_t len);
|
||||||
void can_tx(uint16_t id, const uint8_t* data, uint8_t len);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "can_fc.h"
|
#include "can_fc.h"
|
||||||
|
|
||||||
@ -10,60 +11,90 @@
|
|||||||
|
|
||||||
static_assert((sizeof(Command) + FC_CHUNK_SIZE - 1) / FC_CHUNK_SIZE < 15);
|
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();
|
feedc0de_fcs.tx();
|
||||||
|
|
||||||
if (feedc0de_fcr.ack_pending())
|
|
||||||
feedc0de_fcr.ack();
|
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;
|
sent = in;
|
||||||
feedc0de_fcs.reset(((uint8_t*)&feedback) + 2, sizeof(feedback) - 4);
|
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())
|
if (!feedc0de_fcr.transfer_finished())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
out = command;
|
out = received;
|
||||||
feedc0de_fcr.reset(((uint8_t*)&command) + 2, sizeof(command) - 4);
|
feedc0de_fcr.reset(((uint8_t*)&received) + 2, sizeof(received) - 4);
|
||||||
|
|
||||||
return true;
|
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);
|
feedc0de_fcs.handle_frame(frame, len);
|
||||||
break;
|
return true;
|
||||||
case CAN_ID_COMMAND_STW_TO_BACK:
|
|
||||||
feedc0de_fcr.handle_frame(frame, len);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Error_Handler();
|
|
||||||
}
|
}
|
||||||
|
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"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
|
||||||
void can_feedc0de_handle_frame(uint16_t id, uint8_t* frame, uint8_t len)
|
void can_feedc0de_handle_frame(uint16_t id, uint8_t* frame, uint8_t len)
|
||||||
{
|
{
|
||||||
extern CANFeedc0de can_feedc0de;
|
extern CANFeedc0de<Command, Feedback> can_instances[NUM_BOARDS_MAX];
|
||||||
can_feedc0de.handle_frame(id, frame, len);
|
|
||||||
|
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()
|
void can_feedc0de_poll()
|
||||||
{
|
{
|
||||||
extern CANFeedc0de can_feedc0de;
|
extern CANFeedc0de<Feedback, Command> can_feedc0de;
|
||||||
can_feedc0de.poll();
|
can_feedc0de.poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -4,19 +4,34 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "can_fc.h"
|
#include "can_fc.h"
|
||||||
|
|
||||||
|
template <class Sent, class Received>
|
||||||
class CANFeedc0de
|
class CANFeedc0de
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void poll();
|
CANFeedc0de(uint16_t fcs_tx_can_id, uint16_t fcs_rx_can_id,
|
||||||
void handle_frame(uint16_t id, uint8_t* frame, uint8_t len);
|
uint16_t fcr_tx_can_id, uint16_t fcr_rx_can_id)
|
||||||
void send_feedback(const Feedback& in);
|
: fcs_rx_can_id(fcs_rx_can_id),
|
||||||
bool get_command(Command& out);
|
fcr_rx_can_id(fcr_rx_can_id),
|
||||||
private:
|
feedc0de_fcs(fcs_tx_can_id),
|
||||||
Command command;
|
feedc0de_fcr(fcr_tx_can_id, (uint8_t *)&received + 2, sizeof(received) - 4)
|
||||||
Feedback feedback;
|
{
|
||||||
|
};
|
||||||
|
|
||||||
FCSender feedc0de_fcs = FCSender(CAN_ID_FEEDBACK_BACK_TO_STW);
|
void poll();
|
||||||
FCReceiver feedc0de_fcr = FCReceiver(CAN_ID_COMMAND_BACK_TO_STW, ((uint8_t *)&command) + 2, sizeof(command) - 4);
|
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"
|
extern "C"
|
||||||
|
15
main.cpp
15
main.cpp
@ -38,7 +38,12 @@ extern const P rtP_Left; // default settings defined in BLDC_controller_data.c
|
|||||||
#include "can.h"
|
#include "can.h"
|
||||||
#include "can_feedc0de.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
|
#endif
|
||||||
|
|
||||||
@ -234,7 +239,9 @@ int main()
|
|||||||
|
|
||||||
#ifndef FEATURE_CAN
|
#ifndef FEATURE_CAN
|
||||||
HAL_UART_Receive_DMA(&huart2, (uint8_t *)&command, sizeof(command));
|
HAL_UART_Receive_DMA(&huart2, (uint8_t *)&command, sizeof(command));
|
||||||
#endif
|
#endif // FEATURE_CAN
|
||||||
|
|
||||||
|
#endif // MOTOR_TEST
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
HAL_Delay(DELAY_IN_MAIN_LOOP); //delay in ms
|
HAL_Delay(DELAY_IN_MAIN_LOOP); //delay in ms
|
||||||
@ -1062,7 +1069,7 @@ void parseCommand()
|
|||||||
bool any_parsed{false};
|
bool any_parsed{false};
|
||||||
|
|
||||||
#ifdef FEATURE_CAN
|
#ifdef FEATURE_CAN
|
||||||
any_parsed = can_feedc0de.get_command(command);
|
any_parsed = can_feedc0de.get(command);
|
||||||
#else
|
#else
|
||||||
for (int i = 0; i < 1; i++)
|
for (int i = 0; i < 1; i++)
|
||||||
{
|
{
|
||||||
@ -1161,7 +1168,7 @@ void sendFeedback()
|
|||||||
feedback.checksum = calculateChecksum(feedback);
|
feedback.checksum = calculateChecksum(feedback);
|
||||||
|
|
||||||
#ifdef FEATURE_CAN
|
#ifdef FEATURE_CAN
|
||||||
can_feedc0de.send_feedback(feedback);
|
can_feedc0de.send(feedback);
|
||||||
#else
|
#else
|
||||||
UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN;
|
UART_DMA_CHANNEL->CCR &= ~DMA_CCR_EN;
|
||||||
UART_DMA_CHANNEL->CNDTR = sizeof(feedback);
|
UART_DMA_CHANNEL->CNDTR = sizeof(feedback);
|
||||||
|
Reference in New Issue
Block a user