GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 12 / 0 / 12
Functions: 100.0% 5 / 0 / 5
Branches: -% 0 / 0 / 0
Decisions: -% 0 / - / 0

firmware/controllers/can/can.h
Line Branch Decision Exec Source
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
25 #include "periodic_thread_controller.h"
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
35 enum 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,
46 _MAX_Cycle = _1000ms,
47 };
48
49 void resetCanWriteCycle();
50
51 // 11 bit (CAN 2.0A)
52 #define IS_EXT_RANGE_ID(id) ((id) >= 2048)
53
54 class CanListener;
55 class CanSensorBase;
56
57 #if EFI_CAN_SUPPORT
58 void processCanRxMessage(const size_t busIndex, const CANRxFrame& msg, efitick_t nowNt);
59 #endif // EFI_CAN_SUPPORT
60
61 void registerCanListener(CanListener& listener);
62 void unregisterCanListener(CanListener& listener);
63
64 void registerCanSensor(CanSensorBase& sensor);
65 // TODO: unregisterCanSensor()?
66
67 class CanWrite final : public PeriodicController</*TStackSize*/512> {
68 public:
69 CanWrite();
70 void PeriodicTask(efitick_t nowNt) override;
71 };
72
73 // allow using shorthand CI
74 using CI = CanInterval;
75
76 // logical and/or operators so we can use our enum like an int
77 8 constexpr CI operator |(CI lhs, CI rhs) {
78 using T = std::underlying_type_t<CI>;
79 8 return static_cast<CI>(static_cast<T>(lhs) | static_cast<T>(rhs));
80 }
81
82 1 constexpr CI operator &(CI lhs, CI rhs) {
83 using T = std::underlying_type_t<CI>;
84 1 return static_cast<CI>(static_cast<T>(lhs) & static_cast<T>(rhs));
85 }
86
87 8 constexpr CI& operator |=(CI& lhs, CI rhs) {
88 8 lhs = lhs | rhs;
89 8 return lhs;
90 }
91
92 class CanCycle {
93 public:
94 1 explicit CanCycle(uint32_t cycleCounter200hz)
95 1 : m_cycleFlags(computeFlags(cycleCounter200hz))
96 {
97 1 }
98
99 1 bool isInterval(CanInterval interval) {
100 1 return CanInterval::None != (m_cycleFlags & interval);
101 }
102
103 private:
104 static CanInterval computeFlags(uint32_t cycleCount);
105
106 const CanInterval m_cycleFlags;
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
122