From 3ba3d4e4133263a0df01560b3e6624539db71810 Mon Sep 17 00:00:00 2001 From: Unknown Date: Sat, 22 Sep 2018 18:50:05 -0400 Subject: [PATCH] Allow for different baud rates by adjusting prescaler and time quanta --- Firmware/Board/v3/Src/can.c | 8 ++-- Firmware/MotorControl/main.cpp | 2 - Firmware/communication/interface_can.cpp | 60 ++++++++++++++++-------- Firmware/communication/interface_can.hpp | 3 ++ 4 files changed, 48 insertions(+), 25 deletions(-) diff --git a/Firmware/Board/v3/Src/can.c b/Firmware/Board/v3/Src/can.c index fc7bf388..d4cff30a 100644 --- a/Firmware/Board/v3/Src/can.c +++ b/Firmware/Board/v3/Src/can.c @@ -63,11 +63,11 @@ void MX_CAN1_Init(void) { hcan1.Instance = CAN1; - hcan1.Init.Prescaler = 7; + hcan1.Init.Prescaler = 8; hcan1.Init.Mode = CAN_MODE_NORMAL; - hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; - hcan1.Init.TimeSeg1 = CAN_BS1_6TQ; - hcan1.Init.TimeSeg2 = CAN_BS2_5TQ; + hcan1.Init.SyncJumpWidth = CAN_SJW_4TQ; + hcan1.Init.TimeSeg1 = CAN_BS1_16TQ; + hcan1.Init.TimeSeg2 = CAN_BS2_4TQ; hcan1.Init.TimeTriggeredMode = DISABLE; hcan1.Init.AutoBusOff = DISABLE; hcan1.Init.AutoWakeUp = ENABLE; diff --git a/Firmware/MotorControl/main.cpp b/Firmware/MotorControl/main.cpp index 3b91e075..af9682d5 100644 --- a/Firmware/MotorControl/main.cpp +++ b/Firmware/MotorControl/main.cpp @@ -23,8 +23,6 @@ SystemStats_t system_stats_ = { 0 }; Axis *axes[AXIS_COUNT]; ODriveCAN *odCAN; - - typedef Config< BoardConfig_t, CANConfig_t, diff --git a/Firmware/communication/interface_can.cpp b/Firmware/communication/interface_can.cpp index 6709daa5..985b33f6 100644 --- a/Firmware/communication/interface_can.cpp +++ b/Firmware/communication/interface_can.cpp @@ -45,57 +45,79 @@ ODriveCAN::ODriveCAN(CAN_HandleTypeDef *handle, CANConfig_t &config) config_{config} { } -static void can_server_thread_wrapper(void* ctx){ - reinterpret_cast(ctx)->can_server_thread(); - reinterpret_cast(ctx)->thread_id_valid_ = false; +static void can_server_thread_wrapper(void *ctx) { + reinterpret_cast(ctx)->can_server_thread(); + reinterpret_cast(ctx)->thread_id_valid_ = false; } void ODriveCAN::can_server_thread() { for (;;) { - osDelay(1000); + osDelay(10); } } bool ODriveCAN::start_can_server() { HAL_StatusTypeDef status; + set_baud_rate(config_.baud); + status = HAL_CAN_Init(handle_); + if (status != HAL_OK) + return false; + status = HAL_CAN_Start(handle_); if (status != HAL_OK) return false; status = HAL_CAN_ActivateNotification(handle_, - CAN_IT_TX_MAILBOX_EMPTY | - CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING | /* we probably only want this */ - CAN_IT_RX_FIFO0_FULL | CAN_IT_RX_FIFO1_FULL | - CAN_IT_RX_FIFO0_OVERRUN | CAN_IT_RX_FIFO1_OVERRUN | - CAN_IT_WAKEUP | CAN_IT_SLEEP_ACK | - CAN_IT_ERROR_WARNING | CAN_IT_ERROR_PASSIVE | - CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE | - CAN_IT_ERROR); + CAN_IT_TX_MAILBOX_EMPTY | + CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_RX_FIFO1_MSG_PENDING | /* we probably only want this */ + CAN_IT_RX_FIFO0_FULL | CAN_IT_RX_FIFO1_FULL | + CAN_IT_RX_FIFO0_OVERRUN | CAN_IT_RX_FIFO1_OVERRUN | + CAN_IT_WAKEUP | CAN_IT_SLEEP_ACK | + CAN_IT_ERROR_WARNING | CAN_IT_ERROR_PASSIVE | + CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE | + CAN_IT_ERROR); if (status != HAL_OK) return false; osThreadDef(can_server_thread_def, can_server_thread_wrapper, osPriorityNormal, 0, 512); thread_id_ = osThreadCreate(osThread(can_server_thread_def), this); thread_id_valid_ = true; - + return true; } -void ODriveCAN::set_baud_rate(uint32_t baudRate){ - switch(baudRate){ - case CAN_BAUD_125K: +void ODriveCAN::set_baud_rate(uint32_t baudRate) { + switch (baudRate) { + case CAN_BAUD_125K: + handle_->Init.Prescaler = 21; // 16 TQ's + handle_->Init.TimeSeg1 = CAN_BS1_12TQ; + handle_->Init.TimeSeg2 = CAN_BS2_3TQ; + config_.baud = baudRate; + break; case CAN_BAUD_250K: + handle_->Init.Prescaler = 8; // 21 TQ's + handle_->Init.TimeSeg1 = CAN_BS1_16TQ; + handle_->Init.TimeSeg2 = CAN_BS2_4TQ; + config_.baud = baudRate; + break; case CAN_BAUD_500K: + handle_->Init.Prescaler = 4; // 21 TQ's + handle_->Init.TimeSeg1 = CAN_BS1_16TQ; + handle_->Init.TimeSeg2 = CAN_BS2_4TQ; + config_.baud = baudRate; case CAN_BAUD_1000K: - config_.baud = baudRate; // baudRate is a valid CAN baud + handle_->Init.Prescaler = 2; // 21 TQ's + handle_->Init.TimeSeg1 = CAN_BS1_16TQ; + handle_->Init.TimeSeg2 = CAN_BS2_4TQ; + config_.baud = baudRate; break; default: - break; // baudRate is invalid, so do nothing + break; // baudRate is invalid, so do nothing } } -void ODriveCAN::set_node_id(uint8_t nodeID){ +void ODriveCAN::set_node_id(uint8_t nodeID) { // Allow for future nodeID validation by making this a set function config_.node_id = nodeID; } \ No newline at end of file diff --git a/Firmware/communication/interface_can.hpp b/Firmware/communication/interface_can.hpp index 35b7c3b3..2403023e 100644 --- a/Firmware/communication/interface_can.hpp +++ b/Firmware/communication/interface_can.hpp @@ -5,6 +5,9 @@ #include #include "fibre/protocol.hpp" +#define CAN_CLK_HZ (42000000) +#define CAN_CLK_MHZ (42) + struct { uint32_t id; bool isExt;