Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
57 changes: 33 additions & 24 deletions include/can_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,15 @@ class ICAN
virtual void RegisterRXMessage(ICANRXMessage &msg) = 0;

virtual void Tick() = 0;

enum class ErrorStatus
{
ERROR_ACTIVE,
ERROR_PASSIVE,
BUS_OFF
};

virtual ErrorStatus GetErrorStatus() = 0;
};

/**
Expand Down Expand Up @@ -486,7 +495,7 @@ class MultiplexedSignalGroup : public std::array<ICANSignal *, num_signals>, pub
{
public:
template <typename... Ts>
MultiplexedSignalGroup(uint64_t multiplexor_value, Ts &... signals)
MultiplexedSignalGroup(uint64_t multiplexor_value, Ts &...signals)
: std::array<ICANSignal *, num_signals>{&signals...}
{
static_assert(sizeof...(signals) == num_signals, "Wrong number of signals passed into SignalGroup.");
Expand All @@ -495,7 +504,7 @@ class MultiplexedSignalGroup : public std::array<ICANSignal *, num_signals>, pub
}

template <typename... Ts>
MultiplexedSignalGroup(bool always_active, uint64_t multiplexor_value, Ts &... signals)
MultiplexedSignalGroup(bool always_active, uint64_t multiplexor_value, Ts &...signals)
: std::array<ICANSignal *, num_signals>{&signals...}
{
static_assert(sizeof...(signals) == num_signals, "Wrong number of signals passed into SignalGroup.");
Expand Down Expand Up @@ -533,7 +542,7 @@ class CANTXMessage : public ICANTXMessage
uint8_t length,
uint32_t period,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: can_interface_{can_interface},
message_{id, extended_id, length, std::array<uint8_t, 8>()},
transmit_timer_{period, [this]() { this->EncodeAndSend(); }, VirtualTimer::Type::kRepeating},
Expand All @@ -554,7 +563,7 @@ class CANTXMessage : public ICANTXMessage
* @param signals The ICANSignals contained in the message
*/
CANTXMessage(
ICAN &can_interface, uint32_t id, uint8_t length, uint32_t period, ICANSignal &signal_1, Ts &... signals)
ICAN &can_interface, uint32_t id, uint8_t length, uint32_t period, ICANSignal &signal_1, Ts &...signals)
: CANTXMessage(can_interface, id, false, length, period, signal_1, signals...)
{
}
Expand All @@ -579,7 +588,7 @@ class CANTXMessage : public ICANTXMessage
uint32_t period,
VirtualTimerGroup &timer_group,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: CANTXMessage(can_interface, id, extended_id, length, period, signal_1, signals...)
{
timer_group.AddTimer(transmit_timer_);
Expand All @@ -604,7 +613,7 @@ class CANTXMessage : public ICANTXMessage
uint32_t period,
VirtualTimerGroup &timer_group,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: CANTXMessage(can_interface, id, false, length, period, timer_group, signal_1, signals...)
{
}
Expand Down Expand Up @@ -666,7 +675,7 @@ class MultiplexedCANTXMessage : public ICANTXMessage
uint32_t period,
std::array<MultiplexorType, num_multiplexors_to_transmit> multiplexor_values_to_transmit,
ITypedCANSignal<MultiplexorType> &multiplexor,
Ts &... signal_groups)
Ts &...signal_groups)
: can_interface_{can_interface},
message_{id, extended_id, length, std::array<uint8_t, 8>()},
#if !defined(NATIVE) // workaround for unit tests
Expand Down Expand Up @@ -709,7 +718,7 @@ class MultiplexedCANTXMessage : public ICANTXMessage
uint32_t period,
std::array<MultiplexorType, num_multiplexors_to_transmit> multiplexor_values_to_transmit,
ITypedCANSignal<MultiplexorType> &multiplexor,
Ts &... signal_groups)
Ts &...signal_groups)
: MultiplexedCANTXMessage(
can_interface, id, false, length, period, multiplexor_values_to_transmit, multiplexor, signal_groups...)
{
Expand Down Expand Up @@ -739,7 +748,7 @@ class MultiplexedCANTXMessage : public ICANTXMessage
VirtualTimerGroup &timer_group,
std::array<MultiplexorType, num_multiplexors_to_transmit> multiplexor_values_to_transmit,
ITypedCANSignal<MultiplexorType> &multiplexor,
Ts &... signal_groups)
Ts &...signal_groups)
: MultiplexedCANTXMessage(can_interface,
id,
extended_id,
Expand Down Expand Up @@ -776,7 +785,7 @@ class MultiplexedCANTXMessage : public ICANTXMessage
VirtualTimerGroup &timer_group,
std::array<MultiplexorType, num_multiplexors_to_transmit> multiplexor_values_to_transmit,
ITypedCANSignal<MultiplexorType> &multiplexor,
Ts &... signal_groups)
Ts &...signal_groups)
: MultiplexedCANTXMessage(can_interface,
id,
false,
Expand Down Expand Up @@ -893,7 +902,7 @@ class PGNCANTXMessage : public ICANTXMessage
uint8_t length,
uint32_t period,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: can_interface_{can_interface},
message_{id, length, std::array<uint8_t, 8>()},
transmit_timer_{period, [this]() { this->EncodeAndSend(); }, VirtualTimer::Type::kRepeating},
Expand Down Expand Up @@ -921,7 +930,7 @@ class PGNCANTXMessage : public ICANTXMessage
uint32_t period,
VirtualTimerGroup &timer_group,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: PGNCANTXMessage(can_interface, id, length, period, signal_1, signals...)
{
timer_group.AddTimer(transmit_timer_);
Expand Down Expand Up @@ -972,7 +981,7 @@ class CANRXMessage : public ICANRXMessage
std::function<uint32_t(void)> get_millis,
std::function<void(void)> callback_function,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: can_interface_{can_interface},
id_{id},
get_millis_{get_millis},
Expand All @@ -988,7 +997,7 @@ class CANRXMessage : public ICANRXMessage
uint32_t id,
std::function<uint32_t(void)> get_millis,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: CANRXMessage{can_interface, id, get_millis, nullptr, signal_1, signals...}
{
}
Expand All @@ -1001,13 +1010,13 @@ class CANRXMessage : public ICANRXMessage
uint32_t id,
std::function<void(void)> callback_function,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: CANRXMessage{can_interface, id, []() { return millis(); }, callback_function, signal_1, signals...}
{
}

template <typename... Ts>
CANRXMessage(ICAN &can_interface, uint32_t id, ICANSignal &signal_1, Ts &... signals)
CANRXMessage(ICAN &can_interface, uint32_t id, ICANSignal &signal_1, Ts &...signals)
: CANRXMessage{can_interface, id, []() { return millis(); }, nullptr, signal_1, signals...}
{
}
Expand Down Expand Up @@ -1075,7 +1084,7 @@ class MultiplexedCANRXMessage : public ICANRXMessage
std::function<uint32_t(void)> get_millis,
std::function<void(void)> callback_function,
ITypedCANSignal<MultiplexorType> &multiplexor,
Ts &... signal_groups)
Ts &...signal_groups)
: can_interface_{can_interface},
id_{id},
get_millis_{get_millis},
Expand All @@ -1102,7 +1111,7 @@ class MultiplexedCANRXMessage : public ICANRXMessage
uint32_t id,
std::function<uint32_t(void)> get_millis,
ITypedCANSignal<MultiplexorType> &multiplexor,
Ts &... signal_groups)
Ts &...signal_groups)
: MultiplexedCANRXMessage{can_interface, id, get_millis, nullptr, multiplexor, signal_groups...}
{
}
Expand All @@ -1115,7 +1124,7 @@ class MultiplexedCANRXMessage : public ICANRXMessage
uint32_t id,
std::function<void(void)> callback_function,
ITypedCANSignal<MultiplexorType> &multiplexor,
Ts &... signal_groups)
Ts &...signal_groups)
: MultiplexedCANRXMessage{
can_interface, id, []() { return millis(); }, callback_function, multiplexor, signal_groups...}
{
Expand All @@ -1125,7 +1134,7 @@ class MultiplexedCANRXMessage : public ICANRXMessage
MultiplexedCANRXMessage(ICAN &can_interface,
uint32_t id,
ITypedCANSignal<MultiplexorType> &multiplexor,
Ts &... signal_groups)
Ts &...signal_groups)
: MultiplexedCANRXMessage{can_interface, id, []() { return millis(); }, nullptr, multiplexor, signal_groups...}
{
}
Expand Down Expand Up @@ -1226,7 +1235,7 @@ class PGNCANRXMessage : public ICANRXMessage
std::function<uint32_t(void)> get_millis,
std::function<void(void)> callback_function,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: can_interface_{can_interface},
id_{id},
get_millis_{get_millis},
Expand All @@ -1242,7 +1251,7 @@ class PGNCANRXMessage : public ICANRXMessage
PGNCANMessage::ExtendedId id,
std::function<uint32_t(void)> get_millis,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: PGNCANRXMessage{can_interface, id, get_millis, nullptr, signal_1, signals...}
{
}
Expand All @@ -1255,13 +1264,13 @@ class PGNCANRXMessage : public ICANRXMessage
PGNCANMessage::ExtendedId id,
std::function<void(void)> callback_function,
ICANSignal &signal_1,
Ts &... signals)
Ts &...signals)
: PGNCANRXMessage{can_interface, id, []() { return millis(); }, callback_function, signal_1, signals...}
{
}

template <typename... Ts>
PGNCANRXMessage(ICAN &can_interface, PGNCANMessage::ExtendedId id, ICANSignal &signal_1, Ts &... signals)
PGNCANRXMessage(ICAN &can_interface, PGNCANMessage::ExtendedId id, ICANSignal &signal_1, Ts &...signals)
: PGNCANRXMessage{can_interface, id, []() { return millis(); }, nullptr, signal_1, signals...}
{
}
Expand Down
2 changes: 2 additions & 0 deletions include/esp_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ class ESPCAN : public ICAN

void Tick() override;

ErrorStatus GetErrorStatus() override;

private:
static std::vector<ICANRXMessage *> rx_messages_;
twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(GPIO_NUM_5, GPIO_NUM_4, TWAI_MODE_NORMAL);
Expand Down
2 changes: 2 additions & 0 deletions include/teensy_can.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class TeensyCAN : public ICAN

void Tick() override;

ErrorStatus GetErrorStatus() override;

private:
static std::vector<ICANRXMessage *> rx_messages_;
CAN_message_t message_t{};
Expand Down
21 changes: 21 additions & 0 deletions src/esp_can.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,25 @@ void ESPCAN::Tick()
}
}

ICAN::ErrorStatus ESPCAN::GetErrorStatus()
{
twai_status_info_t status;
twai_get_status_info(&status);

// ref:
// https://docs.espressif.com/projects/esp-idf/en/v4.2.2/esp32s2/api-reference/peripherals/twai.html#error-states-and-counters
if (status.tx_error_counter < 128 && status.rx_error_counter < 128)
{
return ICAN::ErrorStatus::ERROR_ACTIVE;
}
else if (status.tx_error_counter >= 128 || status.rx_error_counter >= 128)
{
return ICAN::ErrorStatus::ERROR_PASSIVE;
}
else if (status.tx_error_counter >= 256)
{
return ICAN::ErrorStatus::BUS_OFF;
}
}

#endif
35 changes: 34 additions & 1 deletion src/teensy_can.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ bool TeensyCAN<bus_num>::SendMessage(CANMessage &msg)
}

template <uint8_t bus_num>
_MB_ptr TeensyCAN<bus_num>::ProcessMessage = [](const CAN_message_t &msg) {
_MB_ptr TeensyCAN<bus_num>::ProcessMessage = [](const CAN_message_t &msg)
{
std::array<uint8_t, 8> msg_data{};
memcpy(msg_data.data(), msg.buf, 8);
CANMessage received_message{static_cast<uint32_t>(msg.id), msg.len, msg_data};
Expand All @@ -101,4 +102,36 @@ _MB_ptr TeensyCAN<bus_num>::ProcessMessage = [](const CAN_message_t &msg) {
rx_messages_[i]->DecodeSignals(received_message);
}
};

template <uint8_t bus_num>
ICAN::ErrorStatus TeensyCAN<bus_num>::GetErrorStatus()
{
CAN_error_t err;
// Repeated code due to limitations of C++11, look into alternatives without repeated code
if (bus_num == 2)
{
can_bus_2.error(err, false);
}
else if (bus_num == 3)
{
can_bus_3.error(err, false);
}
else
{
can_bus_1.error(err, false);
}

if (err.FLT_CONF == "Error Active")
{
return ICAN::ErrorStatus::ERROR_ACTIVE;
}
else if (err.FLT_CONF == "Error Passive")
{
return ICAN::ErrorStatus::ERROR_PASSIVE;
}
else if (err.FLT_CONF == "Bus off")
{
return ICAN::ErrorStatus::BUS_OFF;
}
}
#endif