Line data Source code
1 : // Copyright 2024 Accenture.
2 :
3 : /**
4 : * Contains class AbstractCANTransceiver.
5 : * \file AbstractCANTransceiver.h
6 : * \ingroup transceiver
7 : */
8 : #pragma once
9 :
10 : #include "can/canframes/CANFrame.h"
11 : #include "can/framemgmt/AbstractBitFieldFilteredCANFrameListener.h"
12 : #include "can/framemgmt/AbstractIntervalFilteredCANFrameListener.h"
13 : #include "can/framemgmt/IFilteredCANFrameSentListener.h"
14 : #include "can/transceiver/ICANTransceiverStateListener.h"
15 : #include "can/transceiver/ICanTransceiver.h"
16 :
17 : #include <etl/intrusive_forward_list.h>
18 : #include <etl/intrusive_list.h>
19 :
20 : #include <platform/estdint.h>
21 :
22 : namespace can
23 : {
24 : class ICANFrameSentListener;
25 : class IFilteredCANFrameSentListener;
26 : class FrameDispatcher;
27 : class CanTransportLayer;
28 :
29 : /**
30 : * Cpp2CAN AbstractCANTransceiver
31 : * \class AbstractCANTransceiver
32 : *
33 : *
34 : * An AbstractCANTransceiver is the common hardware independent base class for
35 : * CAN Transceiver classes. This base implementation or the ICanTransceiver interface
36 : * shall be used in all applications to avoid HW dependencies.
37 : *
38 : * This abstract class implements the HW independent methods.
39 : *
40 : * \section Reception
41 : * An implementation of AbstractCANTransceiver has to fill a CANFrame object
42 : * with the data of the received can frame and then call
43 : * notifyListeners() with the received CANFrame which distributes it to all
44 : * listeners, i.e. to all listeners whose filter match the id of fRxFrame.
45 : *
46 : */
47 : class AbstractCANTransceiver : public ICanTransceiver
48 : {
49 : public:
50 : /**
51 : * constructor
52 : * \param busId busId of MultiChannelCanTransceiver
53 : * \post getState() == CLOSED
54 : */
55 : explicit AbstractCANTransceiver(uint8_t busId);
56 :
57 : /**
58 : * \return internal state of transceiver
59 : * \see State
60 : */
61 : State getState() const override;
62 :
63 : /**
64 : * adds an ICANFrameListener to listener list
65 : * \param canFrameListener listener to register
66 : *
67 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts.
68 : *
69 : * \attention
70 : * The filter of canFrameListener is merged into the transceivers rx-filter.
71 : * It must be configured before adding the listener!
72 : */
73 : void addCANFrameListener(ICANFrameListener& listener) override;
74 :
75 : /**
76 : * Adds a listener to the front of the receiver list.
77 : * \see addCANFrameListener
78 : * Using this method makes sure that the added listener is notified first
79 : * of a incoming CANFrame.
80 : */
81 : void addVIPCANFrameListener(ICANFrameListener& listener) override;
82 :
83 : /**
84 : * removes an ICANFrameListener from listener list
85 : * \param canFrameListener listener to remove
86 : *
87 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts.
88 : *
89 : * \note
90 : * The elements of canFrameListeners filter will not be removed from
91 : * the transceivers rx-filter.
92 : */
93 : void removeCANFrameListener(ICANFrameListener& listener) override;
94 :
95 : /**
96 : * adds an addCANFrameSentListener to listener list
97 : * \param listener listener to register
98 : *
99 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts.
100 : *
101 : * \attention
102 : * The filter of listener is merged into the transceivers rx-filter.
103 : * It must be configured before adding the listener!
104 : */
105 : void addCANFrameSentListener(IFilteredCANFrameSentListener& listener) override;
106 :
107 : /**
108 : * removes an ICANFrameListener from listener list
109 : * \param listener listener to remove
110 : *
111 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts.
112 : *
113 : * \note
114 : * The elements of listener filter will not be removed from
115 : * the transceivers rx-filter.
116 : */
117 : void removeCANFrameSentListener(IFilteredCANFrameSentListener& listener) override;
118 :
119 : /**
120 : * \return busId of transceiver
121 : */
122 1 : uint8_t getBusId() const override { return _busId; }
123 :
124 : /**
125 : * Get the hardware state of the CAN transceiver.
126 : * \return state hardware state of the CAN transceiver
127 : */
128 1 : ICANTransceiverStateListener::CANTransceiverState getCANTransceiverState() const override
129 : {
130 1 : return _transceiverState;
131 : }
132 :
133 : /**
134 : * Sets the transceivers ICANTransceiverStateListener.
135 : * \param pListener ICANTransceiverStateListener to notify when an error
136 : * occurs. 0L if no class needs to be notified.
137 : */
138 1 : void setStateListener(ICANTransceiverStateListener& listener) override
139 : {
140 1 : _stateListener = &listener;
141 1 : }
142 :
143 1 : void removeStateListener() override { _stateListener = nullptr; }
144 :
145 : protected:
146 : void setState(State newState);
147 :
148 : bool isInState(State state) const;
149 :
150 : /**
151 : * Notifies all appropriate listeners about the reception of a CANFrame.
152 : * \param frame CANFrame that will be passed to all listeners
153 : */
154 : void notifyListeners(CANFrame const& frame);
155 :
156 : void notifySentListeners(can::CANFrame const& frame);
157 :
158 : /**
159 : * Notifies the attached ICANTransceiverStateListener that a phy error occurred
160 : */
161 3 : void notifyStateListenerWithPhyError()
162 : {
163 3 : if (_stateListener != nullptr)
164 : {
165 1 : _stateListener->phyErrorOccurred(*this);
166 : }
167 3 : }
168 :
169 : /**
170 : * Notifies the attached ICANTransceiverStateListener with a given
171 : * state
172 : * \param state new can transceiver state.
173 : */
174 : void notifyStateListenerWithState(ICANTransceiverStateListener::CANTransceiverState state);
175 :
176 : protected:
177 : BitFieldFilter _filter;
178 : ::etl::intrusive_list<ICANFrameListener, ::etl::bidirectional_link<0>> _listeners;
179 : IFilteredCANFrameSentListener* _sentListener;
180 : ::etl::intrusive_forward_list<IFilteredCANFrameSentListener, ::etl::forward_link<0>>
181 : _sentListeners;
182 : /** baudrate of transceiver */
183 : uint32_t _baudrate;
184 : /** internal State */
185 : State _state;
186 : uint8_t _busId;
187 : ICANTransceiverStateListener* _stateListener;
188 : ICANTransceiverStateListener::CANTransceiverState _transceiverState;
189 : };
190 :
191 6 : inline ICanTransceiver::State AbstractCANTransceiver::getState() const { return _state; }
192 :
193 2 : inline void AbstractCANTransceiver::setState(ICanTransceiver::State const newState)
194 : {
195 2 : _state = newState;
196 2 : }
197 :
198 2 : inline bool AbstractCANTransceiver::isInState(ICanTransceiver::State const state) const
199 : {
200 2 : return (_state == state);
201 : }
202 :
203 6 : inline void AbstractCANTransceiver::notifyStateListenerWithState(
204 : ICANTransceiverStateListener::CANTransceiverState const state)
205 : {
206 6 : if (_stateListener != nullptr)
207 : {
208 1 : _stateListener->canTransceiverStateChanged(*this, state);
209 : }
210 6 : }
211 :
212 : } // namespace can
|