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 #include "periodic_thread_controller.h"
21
22 // Try to recover CAN after following timeout
23 #define CAN_RX_TIMEOUT TIME_MS2I(100)
24
25 //can tx periodic task cycle time in frequency, 200hz -> 5ms period
26 #define CAN_CYCLE_FREQ (200.0f)
27 //can tx periodic task cycle time in ms
28 #define CAN_CYCLE_PERIOD (CH_CFG_ST_FREQUENCY / CAN_CYCLE_FREQ)
29
30 enum class CanInterval : uint16_t {
31 None = 0,
32 _5ms = 1 << 0,
33 _10ms = 1 << 1,
34 _20ms = 1 << 2,
35 _50ms = 1 << 3,
36 _100ms = 1 << 4,
37 _200ms = 1 << 5,
38 _250ms = 1 << 6,
39 _500ms = 1 << 7,
40 _1000ms = 1 << 8,
41 _MAX_Cycle = _1000ms,
42 };
43
44 void resetCanWriteCycle();
45
46 // 11 bit (CAN 2.0A)
47 #define IS_EXT_RANGE_ID(id) ((id) >= 2048)
48
49 class CanListener;
50 class CanSensorBase;
51
52 #if EFI_CAN_SUPPORT
53 void processCanRxMessage(const size_t busIndex, const CANRxFrame& msg, efitick_t nowNt);
54 #endif // EFI_CAN_SUPPORT
55
56 void registerCanListener(CanListener& listener);
57 void unregisterCanListener(CanListener& listener);
58
59 void registerCanSensor(CanSensorBase& sensor);
60 // TODO: unregisterCanSensor()?
61
62 class CanWrite final : public PeriodicController</*TStackSize*/512> {
63 public:
64 CanWrite();
65 void PeriodicTask(efitick_t nowNt) override;
66 };
67
68 // allow using shorthand CI
69 using CI = CanInterval;
70
71 // logical and/or operators so we can use our enum like an int
72 8 constexpr CI operator |(CI lhs, CI rhs) {
73 using T = std::underlying_type_t<CI>;
74 8 return static_cast<CI>(static_cast<T>(lhs) | static_cast<T>(rhs));
75 }
76
77 1 constexpr CI operator &(CI lhs, CI rhs) {
78 using T = std::underlying_type_t<CI>;
79 1 return static_cast<CI>(static_cast<T>(lhs) & static_cast<T>(rhs));
80 }
81
82 8 constexpr CI& operator |=(CI& lhs, CI rhs) {
83 8 lhs = lhs | rhs;
84 8 return lhs;
85 }
86
87 class CanCycle {
88 public:
89 1 explicit CanCycle(uint32_t cycleCounter200hz)
90 1 : m_cycleFlags(computeFlags(cycleCounter200hz))
91 {
92 1 }
93
94 1 bool isInterval(CanInterval interval) {
95 1 return CanInterval::None != (m_cycleFlags & interval);
96 }
97
98 private:
99 static CanInterval computeFlags(uint32_t cycleCount);
100
101 const CanInterval m_cycleFlags;
102 };
103
104 // We need these helpers because the frame layout is different on STM32H7
105 #ifdef STM32H7XX
106 #define CAN_SID(f) ((f).std.SID)
107 #define CAN_EID(f) ((f).ext.EID)
108 #define CAN_ISX(f) ((f).common.XTD)
109 #else
110 #define CAN_SID(f) ((f).SID)
111 #define CAN_EID(f) ((f).EID)
112 #define CAN_ISX(f) ((f).IDE)
113 #endif
114
115 #define CAN_ID(f) (CAN_ISX(f) ? CAN_EID(f) : CAN_SID(f))
116
117