rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
can.h
Go to the documentation of this file.
1/**
2 * @file can.h
3 *
4 * @date Mar 19, 2020
5 * @author Matthew Kennedy, (c) 2020
6 */
7
8#pragma once
9
10#define HAS_CAN_FRAME (EFI_SIMULATOR || HAL_USE_CAN || EFI_UNIT_TEST)
11
12#if EFI_UNIT_TEST || !EFI_CAN_SUPPORT
13#include "can_mocks.h"
14#endif // EFI_PROD_CODE
15
16#if !EFI_UNIT_TEST
17#include "hal.h"
18#endif // EFI_UNIT_TEST
19
20#if EFI_SIMULATOR || EFI_UNIT_TEST
21// todo: smarter typedef declaration?
22#define TEST_CAN_BUFFER_SIZE 4096
23#endif // EFI_SIMULATOR
24
26
27// Try to recover CAN after following timeout
28#define CAN_RX_TIMEOUT TIME_MS2I(100)
29
30//can tx periodic task cycle time in frequency, 200hz -> 5ms period
31#define CAN_CYCLE_FREQ (200.0f)
32//can tx periodic task cycle time in ms
33#define CAN_CYCLE_PERIOD (CH_CFG_ST_FREQUENCY / CAN_CYCLE_FREQ)
34
35enum class CanInterval : uint16_t {
36 None = 0,
37 _5ms = 1 << 0,
38 _10ms = 1 << 1,
39 _20ms = 1 << 2,
40 _50ms = 1 << 3,
41 _100ms = 1 << 4,
42 _200ms = 1 << 5,
43 _250ms = 1 << 6,
44 _500ms = 1 << 7,
45 _1000ms = 1 << 8,
47};
48
50
51// 11 bit (CAN 2.0A)
52#define IS_EXT_RANGE_ID(id) ((id) >= 2048)
53
54class CanListener;
55class CanSensorBase;
56
57#if EFI_CAN_SUPPORT
58void processCanRxMessage(const size_t busIndex, const CANRxFrame& msg, efitick_t nowNt);
59#endif // EFI_CAN_SUPPORT
60
61void registerCanListener(CanListener& listener);
63
65// TODO: unregisterCanSensor()?
66
67class CanWrite final : public PeriodicController</*TStackSize*/512> {
68public:
69 CanWrite();
70 void PeriodicTask(efitick_t nowNt) override;
71};
72
73// allow using shorthand CI
75
76// logical and/or operators so we can use our enum like an int
77constexpr CI operator |(CI lhs, CI rhs) {
78 using T = std::underlying_type_t<CI>;
79 return static_cast<CI>(static_cast<T>(lhs) | static_cast<T>(rhs));
80}
81
82constexpr CI operator &(CI lhs, CI rhs) {
83 using T = std::underlying_type_t<CI>;
84 return static_cast<CI>(static_cast<T>(lhs) & static_cast<T>(rhs));
85}
86
87constexpr CI& operator |=(CI& lhs, CI rhs) {
88 lhs = lhs | rhs;
89 return lhs;
90}
91
92class CanCycle {
93public:
94 explicit CanCycle(uint32_t cycleCounter200hz)
95 : m_cycleFlags(computeFlags(cycleCounter200hz))
96 {
97 }
98
99 bool isInterval(CanInterval interval) {
100 return CanInterval::None != (m_cycleFlags & interval);
101 }
102
103private:
104 static CanInterval computeFlags(uint32_t cycleCount);
105
107};
108
109// We need these helpers because the frame layout is different on STM32H7
110#ifdef STM32H7XX
111#define CAN_SID(f) ((f).std.SID)
112#define CAN_EID(f) ((f).ext.EID)
113#define CAN_ISX(f) ((f).common.XTD)
114#else
115#define CAN_SID(f) ((f).SID)
116#define CAN_EID(f) ((f).EID)
117#define CAN_ISX(f) ((f).IDE)
118#endif
119
120#define CAN_ID(f) (CAN_ISX(f) ? CAN_EID(f) : CAN_SID(f))
121
void processCanRxMessage(const size_t busIndex, const CANRxFrame &msg, efitick_t nowNt)
Definition can_rx.cpp:227
void registerCanListener(CanListener &listener)
Definition can_rx.cpp:86
constexpr CI & operator|=(CI &lhs, CI rhs)
Definition can.h:87
CanInterval
Definition can.h:35
constexpr CI operator|(CI lhs, CI rhs)
Definition can.h:77
constexpr CI operator&(CI lhs, CI rhs)
Definition can.h:82
void registerCanSensor(CanSensorBase &sensor)
Definition can_rx.cpp:116
void unregisterCanListener(CanListener &listener)
Definition can_rx.cpp:96
void resetCanWriteCycle()
Definition can_tx.cpp:48
Definition can.h:92
const CanInterval m_cycleFlags
Definition can.h:106
CanCycle(uint32_t cycleCounter200hz)
Definition can.h:94
bool isInterval(CanInterval interval)
Definition can.h:99
static CanInterval computeFlags(uint32_t cycleCount)
Definition can_tx.cpp:113
Definition can.h:67
CanWrite()
Definition can_tx.cpp:27
void PeriodicTask(efitick_t nowNt) override
Called periodically. Override this method to do work for your controller.
Definition can_tx.cpp:53
Base class for a controller that needs to run periodically to perform work.
static Lps25Sensor sensor(device)