Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32 Can implementation; DemoCan Example #110

Merged
merged 25 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9c7736b
Remove pywin32 from requirements.txt
samparent97 Apr 16, 2024
e458ae9
Fix mcal target includes
samparent97 Apr 16, 2024
2525418
Remove -e from echo command into makefile
samparent97 Apr 16, 2024
0fe707e
WIP: building democan with stm32
samparent97 Apr 16, 2024
7acb363
Add foo and bar demo can projects
samparent97 Apr 17, 2024
220034d
Remove print
samparent97 Apr 17, 2024
1dc453c
Add postbuild to raspi platform
samparent97 Apr 18, 2024
473483a
Revert postbuild change
samparent97 Apr 18, 2024
c1e8723
Remove all uneeded info for demo can dbc
samparent97 Apr 20, 2024
55cbc74
Add Dashboard enable to ioc
samparent97 Apr 20, 2024
cd62aeb
Move tick blocking to project specific binding
samparent97 Apr 20, 2024
9aa67e4
Add tick timestamp to rx messages
samparent97 Apr 20, 2024
4be595f
Add temp debug msg
samparent97 Apr 20, 2024
85e9a0e
Remove os lib from cmake for can demo projects
samparent97 Apr 20, 2024
858211d
Remove line added by clangd
samparent97 Apr 20, 2024
9bf1c7c
Fix missing start var
samparent97 Apr 20, 2024
75d8f8c
Update main.cc
samparent97 Apr 20, 2024
dcbfa55
Remove debug msg
samparent97 Apr 20, 2024
e9aac80
Remove iostream import
samparent97 Apr 20, 2024
e2f8d78
Remove os remenants
samparent97 Apr 20, 2024
cd1f433
Fix all clang format checks
samparent97 Apr 20, 2024
d2d870e
build: :construction_worker: Improve the CubeMX autogeneration code. …
BlakeFreer Apr 21, 2024
3184622
Various fixes
samparent97 Apr 21, 2024
3665ed2
Fix postbuild
samparent97 Apr 21, 2024
b27b381
Move the delay in projects
samparent97 Apr 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions firmware/cmake/generate_cubemx.mk
samparent97 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,20 @@ CUBEMX_GEN_SCRIPT = cubemx_script.txt
# Makefile, i.e. whenever IOC_FILE has been updated but new code has not been
# generated.

Makefile: $(IOC_FILE)
# Create an file containing commands to generate the cubemx code.
echo "config load \"$(IOC_FILE)\"" > $(CUBEMX_GEN_SCRIPT)
echo "project generate ./" >> $(CUBEMX_GEN_SCRIPT)
echo "exit" >> $(CUBEMX_GEN_SCRIPT)
.PHONY: Makefile
samparent97 marked this conversation as resolved.
Show resolved Hide resolved

# GenerateCubeMx: $(IOC_FILE)
# # Create an file containing commands to generate the cubemx code.
# echo "config load \"$(IOC_FILE)\"" > $(CUBEMX_GEN_SCRIPT)
# echo "project generate ./" >> $(CUBEMX_GEN_SCRIPT)
# echo "exit" >> $(CUBEMX_GEN_SCRIPT)

# Run the cubemx program to generate code.
java -jar "$(CUBEMX_PATH)" -q "$(CUBEMX_GEN_SCRIPT)"
# # Run the cubemx program to generate code.
# java -jar "$(CUBEMX_PATH)" -q "$(CUBEMX_GEN_SCRIPT)"

rm $(CUBEMX_GEN_SCRIPT)
# rm $(CUBEMX_GEN_SCRIPT)

Makefile: $(IOC_FILE)
# Add a recipe for building the sources to objects without linking them.
# This is used by build_cubemx.cmake
echo "" >> Makefile
Expand All @@ -34,4 +37,4 @@ Makefile: $(IOC_FILE)
# This is used by build_cubemx.cmake
echo "" >> Makefile
echo "%.value:" >> Makefile
echo -e "\t@echo \$$(\$$*)" >> Makefile
echo "\t@echo \$$(\$$*)" >> Makefile
105 changes: 42 additions & 63 deletions firmware/dbcs/DEMO_CAN.dbc
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,52 @@ VERSION ""


NS_ :
NS_DESC_
CM_
BA_DEF_
BA_
VAL_
CAT_DEF_
CAT_
FILTER
BA_DEF_DEF_
EV_DATA_
ENVVAR_DATA_
SGTYPE_
SGTYPE_VAL_
BA_DEF_SGTYPE_
BA_SGTYPE_
SIG_TYPE_REF_
VAL_TABLE_
SIG_GROUP_
SIG_VALTYPE_
SIGTYPE_VALTYPE_
BO_TX_BU_
BA_DEF_REL_
BA_REL_
BA_DEF_DEF_REL_
BU_SG_REL_
BU_EV_REL_
BU_BO_REL_
SG_MUL_VAL_
NS_DESC_
CM_
BA_DEF_
BA_
VAL_
CAT_DEF_
CAT_
FILTER
BA_DEF_DEF_
EV_DATA_
ENVVAR_DATA_
SGTYPE_
SGTYPE_VAL_
BA_DEF_SGTYPE_
BA_SGTYPE_
SIG_TYPE_REF_
VAL_TABLE_
SIG_GROUP_
SIG_VALTYPE_
SIGTYPE_VALTYPE_
BO_TX_BU_
BA_DEF_REL_
BA_REL_
BA_DEF_DEF_REL_
BU_SG_REL_
BU_EV_REL_
BU_BO_REL_
SG_MUL_VAL_

BS_:

BU_: FOO BAR


BO_ 940 TempSensors: 8 FOO
SG_ Sensor1 : 54|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor2 : 44|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor3 : 34|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor4 : 24|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor5 : 14|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor6 : 4|10@1- (0.2,0) [0|0] "degC" BAR

BO_ 581 VehicleInfo: 8 BAR
SG_ WheelSpeed : 26|32@0+ (0.00390625,0) [0|250.996] "km/h" FOO
SG_ RequestedSpeed : 3|24@0+ (0.00390625,0) [0|250.996] "km/h" FOO


CM_ BO_ 940 "Temperature Sensor Values";
CM_ BO_ 581 "Pack Contactor States";
CM_ SG_ 581 WheelSpeed "Wheel-Based Vehicle Speed: Speed of the vehicle as calculated from wheel or tailshaft speed.";
BA_DEF_ SG_ "SPN" INT 0 524287;
BA_DEF_ BO_ "VFrameFormat" ENUM "StandardCAN","ExtendedCAN","reserved","J1939PG";
BA_DEF_ "DatabaseVersion" STRING ;
BA_DEF_ "BusType" STRING ;
BA_DEF_ "ProtocolType" STRING ;
BA_DEF_ "DatabaseCompiler" STRING ;
BA_DEF_DEF_ "SPN" 0;
BA_DEF_DEF_ "VFrameFormat" "J1939PG";
BA_DEF_DEF_ "DatabaseVersion" "DEMO PLUS";
BA_DEF_DEF_ "BusType" "";
BA_DEF_DEF_ "ProtocolType" "";
BA_DEF_DEF_ "DatabaseCompiler" "";
BA_ "ProtocolType" "J1939";
BA_ "BusType" "CAN";
BA_ "DatabaseCompiler" "CSS ELECTRONICS (WWW.CSSELECTRONICS.COM)";
BA_ "DatabaseVersion" "1.0.0";
BA_ "VFrameFormat" BO_ 2364540158 3;
BA_ "VFrameFormat" BO_ 2566844926 3;
BA_ "SPN" SG_ 2364540158 EngineSpeed 190;
BA_ "SPN" SG_ 2566844926 WheelBasedVehicleSpeed 84;
SG_ Sensor1 : 54|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor2 : 44|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor3 : 34|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor4 : 24|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor5 : 14|10@1- (0.2,0) [0|0] "degC" BAR
SG_ Sensor6 : 4|10@1- (0.2,0) [0|0] "degC" BAR

BO_ 941 TempSensorsReply: 8 BAR
SG_ Sensor1 : 54|10@1- (0.2,0) [0|0] "degC" FOO
SG_ Sensor2 : 44|10@1- (0.2,0) [0|0] "degC" FOO
SG_ Sensor3 : 34|10@1- (0.2,0) [0|0] "degC" FOO
SG_ Sensor4 : 24|10@1- (0.2,0) [0|0] "degC" FOO
SG_ Sensor5 : 14|10@1- (0.2,0) [0|0] "degC" FOO
SG_ Sensor6 : 4|10@1- (0.2,0) [0|0] "degC" FOO
6 changes: 5 additions & 1 deletion firmware/mcal/raspi/PostBuild.cmake
samparent97 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# empty
# add_custom_command(
# TARGET main
# POST_BUILD
# COMMAND mv ./build/${PROJECT}/raspi/main ${PROJECT}
# )
19 changes: 15 additions & 4 deletions firmware/mcal/raspi/periph/can.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <unistd.h>

#include <chrono>
#include <cstdint>
#include <cstring>
#include <iostream>
Expand All @@ -26,7 +28,9 @@ namespace mcal::raspi::periph {

class CanBase : public shared::periph::CanBase {
public:
CanBase(std::string can_iface) : iface_(can_iface){};
CanBase(std::string can_iface) : iface_(can_iface) {
program_start_ = std::chrono::steady_clock::now();
};

void Setup() {
// Create a socket
Expand Down Expand Up @@ -94,6 +98,15 @@ class CanBase : public shared::periph::CanBase {
std::mutex queue_mtx_;
std::thread reader_thread_;

std::chrono::steady_clock::time_point program_start_;

inline uint32_t get_tick() {
std::chrono::milliseconds elapsed_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - program_start_);
return static_cast<uint32_t>(elapsed_ms.count());
}

void StartReading() {
struct can_frame frame;

Expand All @@ -109,9 +122,7 @@ class CanBase : public shared::periph::CanBase {
rawMsg.header.id = frame.can_id;
rawMsg.header.data_len = frame.can_dlc;
rawMsg.header.is_extended_frame = frame.can_id & CAN_EFF_FLAG;

std::cout << "Can base frame " << std::hex << rawMsg.header.id
<< " data len " << rawMsg.header.data_len << std::endl;
rawMsg.tick_timestamp = get_tick();

std::copy(frame.data, frame.data + kMaxMsgBytes, rawMsg.data);

Expand Down
2 changes: 1 addition & 1 deletion firmware/mcal/stm32f767/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ add_library(mcal-stm32f767 INTERFACE)
add_subdirectory(periph)
add_subdirectory(os)

target_include_directories(mcal-stm32f767 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/..)
target_include_directories(mcal-stm32f767 INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/../..)

target_link_libraries(mcal-stm32f767 INTERFACE shared)
3 changes: 3 additions & 0 deletions firmware/mcal/stm32f767/os/tick.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@

#pragma once

#include <sys/types.h>

#include <cstdint>

#include "cmsis_os2.h"
#include "shared/os/os.h"
#include "shared/os/tick.h"
#include "stm32f7xx_hal.h"

// TODO: Add comments and handle errors more robustly
namespace os {
Expand Down
142 changes: 142 additions & 0 deletions firmware/mcal/stm32f767/periph/can.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/// @author Samuel Parent
/// @date 2023-01-12

#pragma once

#include <bits/ranges_base.h>
#include <sys/_stdint.h>

#include <cstddef>

#include "shared/comms/can/raw_can_msg.h"
#include "shared/periph/can.h"
#include "shared/util/data_structures/circular_queue.h"
#include "stm32f7xx_hal.h"
#include "stm32f7xx_hal_can.h"

namespace mcal::stm32f767::periph {

class CanBase : public shared::periph::CanBase {
public:
CanBase(CAN_HandleTypeDef* hcan) : hcan_(hcan){};

void Setup() {
HAL_CAN_ActivateNotification(hcan_, kCanRxActiveInterruptFifo0);
HAL_CAN_Start(hcan_);
}

void Send(const shared::can::RawCanMsg& can_tx_msg) override {
uint32_t tx_mailboxes_free_level =
HAL_CAN_GetTxMailboxesFreeLevel(hcan_);
if (tx_mailboxes_free_level < 1) {
dropped_tx_frames_ += 1;
return;
}

CAN_TxHeaderTypeDef stm_tx_header =
pack_stm_tx_header(can_tx_msg.header);

HAL_CAN_AddTxMessage(hcan_, &stm_tx_header, can_tx_msg.data,
&tx_mailbox_addr_);
}

void ReadQueue(shared::can::RawCanMsg can_rx_msgs[], size_t len) override {
uint16_t msg_idx = 0;
{
while (!can_queue_.is_empty() && (msg_idx < len)) {
can_rx_msgs[msg_idx] = can_queue_.Dequeue();
msg_idx++;
}
}
}

void AddRxMessageToQueue() {
if (can_queue_.is_full()) {
dropped_rx_frames_ += 1;
return;
}

uint32_t fifo0_fill_level =
HAL_CAN_GetRxFifoFillLevel(hcan_, kCanRxFifo0);
if (fifo0_fill_level == 0) {
false_add_rx_msg_to_queue_ += 1;
return;
}

CAN_RxHeaderTypeDef stm_rx_header;
shared::can::RawCanMsg raw_rx_msg;

raw_rx_msg.tick_timestamp = get_tick_ms();

HAL_CAN_GetRxMessage(hcan_, kCanRxFifo0, &stm_rx_header,
raw_rx_msg.data);

raw_rx_msg.header = unpack_stm_rx_header(stm_rx_header);

can_queue_.Enqueue(raw_rx_msg);
}

private:
static constexpr uint8_t kMaxMsgBytes = 8;
static constexpr size_t kMsgQueueLen = 20;
static constexpr uint32_t kCanRxFifo0 = CAN_RX_FIFO0;
samparent97 marked this conversation as resolved.
Show resolved Hide resolved
static constexpr uint32_t kCanRxActiveInterruptFifo0 =
CAN_IT_RX_FIFO0_MSG_PENDING;

static constexpr CAN_TxHeaderTypeDef pack_stm_tx_header(
const shared::can::CanHeader& header) {
CAN_TxHeaderTypeDef ret_stm_tx_header;

// Set frame id based on standard or extended frame id
if (header.is_extended_frame) {
ret_stm_tx_header.IDE = CAN_ID_EXT;
ret_stm_tx_header.ExtId = header.id;
} else {
ret_stm_tx_header.IDE = CAN_ID_STD;
ret_stm_tx_header.StdId = header.id;
}

// Sending a data frame
ret_stm_tx_header.RTR = CAN_RTR_DATA;

// Set data length
ret_stm_tx_header.DLC = header.data_len;

return ret_stm_tx_header;
}

static constexpr shared::can::CanHeader unpack_stm_rx_header(
const CAN_RxHeaderTypeDef& stm_rx_header) {
shared::can::CanHeader ret_rx_header;

if (stm_rx_header.IDE == CAN_ID_EXT) {
ret_rx_header.is_extended_frame = true;
ret_rx_header.id = stm_rx_header.ExtId;
} else { // Otherwise assume standard ID
ret_rx_header.is_extended_frame = false;
ret_rx_header.id = stm_rx_header.StdId;
}

ret_rx_header.data_len = static_cast<uint8_t>(stm_rx_header.DLC);

return ret_rx_header;
}

inline uint32_t get_tick_ms() {
return HAL_GetTick() * HAL_GetTickFreq();
}

/// @todo broadcast these over a can message
uint32_t dropped_tx_frames_ = 0;
uint32_t dropped_rx_frames_ = 0;
uint32_t false_add_rx_msg_to_queue_ = 0;

CAN_HandleTypeDef* hcan_;
uint32_t tx_mailbox_addr_ = 0;

/// @todo make this an etl lockable queue.
shared::util::CircularQueue<shared::can::RawCanMsg, kMsgQueueLen>
can_queue_{};
};

} // namespace mcal::stm32f767::periph
2 changes: 1 addition & 1 deletion firmware/mcal/windows/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
add_library(mcal-windows INTERFACE)

target_include_directories(mcal-windows INTERFACE ${SMAKE_CURRENT_SOURCE_DIR}/..)
target_include_directories(mcal-windows INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/../..)

add_subdirectory(periph)
target_link_libraries(mcal-windows INTERFACE shared)
Loading
Loading