Line data Source code
1 : // Copyright 2024 Accenture.
2 :
3 : /**
4 : * Contains class ICanTransceiver.
5 : * \file ICanTransceiver.h
6 : * \ingroup transceiver
7 : */
8 : #pragma once
9 :
10 : #include "can/transceiver/ICANTransceiverStateListener.h"
11 :
12 : #include <platform/estdint.h>
13 :
14 : namespace can
15 : {
16 : class CANFrame;
17 : class CanTransportLayer;
18 : class FrameDispatcher;
19 : class ICANFrameListener;
20 : class ICANFrameSentListener;
21 : class IFilteredCANFrameSentListener;
22 :
23 : /**
24 : * Cpp2Can Can Transceiver base interface
25 : *
26 : * \see AbstractCANTransceiver for a base HW independent implementation.
27 : *
28 : * \section Statemachine
29 : * A subclass of ICanTransceiver has to implement the following
30 : * statemachine. Initial state shall be CLOSED.
31 : *
32 : * <table border=1 bordercolor="black">
33 : * <tr>
34 : * <th>state</th><th>method called</th><th>follow state</th>
35 : * </tr>
36 : * <tr>
37 : * <td>CLOSED</td><td>init()</td><td>INITIALIZED</td>
38 : * </tr>
39 : * <tr>
40 : * <td>INITIALIZED</td><td>open()</td><td>OPEN</td>
41 : * </tr>
42 : * <tr>
43 : * <td>OPEN</td><td>close()</td><td>CLOSED</td>
44 : * </tr>
45 : * <tr>
46 : * <td>OPEN</td><td>mute()</td><td>MUTED</td>
47 : * </tr>
48 : * <tr>
49 : * <td>MUTED</td><td>unmute()</td><td>OPEN</td>
50 : * </tr>
51 : * <tr>
52 : * <td>MUTED</td><td>close()</td><td>CLOSED</td>
53 : * </tr>
54 : * </table>
55 : */
56 : class ICanTransceiver
57 : {
58 : protected:
59 58 : ICanTransceiver() = default;
60 :
61 : public:
62 : ICanTransceiver(ICanTransceiver const&) = delete;
63 : ICanTransceiver& operator=(ICanTransceiver const&) = delete;
64 :
65 : /**
66 : * All ErrorCodes used by CanTransceivers
67 : */
68 : enum class ErrorCode : uint8_t
69 : {
70 : /** Everything OK */
71 : CAN_ERR_OK,
72 : /** Transmission failed */
73 : CAN_ERR_TX_FAIL,
74 : /** Hw queue was full */
75 : CAN_ERR_TX_HW_QUEUE_FULL,
76 : /** Transceiver was offline when trying to transmit */
77 : CAN_ERR_TX_OFFLINE,
78 : /** Transceiver is in an illegal state for the requested operation */
79 : CAN_ERR_ILLEGAL_STATE,
80 : /** The list of possible listeners is full */
81 : CAN_ERR_NO_MORE_LISTENERS_POSSIBLE,
82 : /** The requested baudrate is not supported */
83 : CAN_ERR_UNSUPPORTED_BAUDRATE,
84 : /** Transceiver could not be initialized */
85 : CAN_ERR_INIT_FAILED
86 : };
87 :
88 : /**
89 : * States used by CanTransceivers
90 : */
91 : enum class State : uint8_t
92 : {
93 : /** Transceiver is closed */
94 : CLOSED,
95 : /** Transceivers hardware is initialized */
96 : INITIALIZED,
97 : /** Transceiver is waking up bus participants */
98 : WAKING,
99 : /** Transceiver is open */
100 : OPEN,
101 : /** Transceiver does not send but receive */
102 : MUTED
103 : };
104 :
105 : enum
106 : {
107 : /** Size of receive queue */
108 : RX_QUEUE_SIZE = 32,
109 : /** Lowspeed baudrate is 100 kBit/s */
110 : BAUDRATE_LOWSPEED = 100000,
111 : /** Highspeed baudrate is 500 kBit/s */
112 : BAUDRATE_HIGHSPEED = 500000,
113 : INVALID_FRAME_ID = 0xFFFF
114 : };
115 :
116 : /**
117 : * Initializes the transceivers hardware and enables the transceiver
118 : * to write CANFrames but not to receive them.
119 : * \pre getState() == CLOSED
120 : * \post getState() == INITIALIZED
121 : * \return
122 : * - CAN_ERR_OK: transition executed
123 : * - CAN_ERR_ILLEGAL_STATE: method was called in wrong state
124 : */
125 : virtual ErrorCode init() = 0;
126 :
127 : /**
128 : * Called before finally shutting down, used to clean up e.g. pending timeouts.
129 : */
130 : virtual void shutdown() = 0;
131 :
132 : /**
133 : * Sets the transceiver to a status ready for transmission and reception under the
134 : * restriction, that no other frame will be sent before frame frame.
135 : * When the frame is transmitted, the state must be set to OPEN, e.g.
136 : * in a tx callback function.
137 : * If this functionality is not required, the function shall assert to inhibit
138 : * unwanted usage.
139 : * \param frame frame to transmit during wake up phase
140 : * \pre getState() == INITIALIZED
141 : * \post getState() == WAKING
142 : * \return
143 : * - CAN_ERR_OK: transition executed
144 : * - CAN_ERR_ILLEGAL_STATE: method was called in wrong state
145 : */
146 : virtual ErrorCode open(CANFrame const& frame) = 0;
147 :
148 : /**
149 : * Sets the transceiver to a status ready for transmission and reception
150 : * \pre getState() == INITIALIZED
151 : * \post getState() == OPEN
152 : * \return
153 : * - CAN_ERR_OK: transition executed
154 : * - CAN_ERR_ILLEGAL_STATE: method was called in wrong state
155 : */
156 : virtual ErrorCode open() = 0;
157 :
158 : /**
159 : * Stops the transceiver and shuts down hardware disabling both
160 : * reception and transmission
161 : * \pre getState() == OPEN
162 : * \post getState() == CLOSED
163 : * \return
164 : * - CAN_ERR_OK: transition executed
165 : * - CAN_ERR_ILLEGAL_STATE: method was called in wrong state
166 : */
167 : virtual ErrorCode close() = 0;
168 :
169 : /**
170 : * Sets the transceiver to a state able to receive CANFrames but
171 : * unable to transmit
172 : * \pre getState() == OPEN
173 : * \post getState() == MUTED
174 : * \return
175 : * - CAN_ERR_OK: transition executed
176 : * - CAN_ERR_ILLEGAL_STATE: method was called in wrong state
177 : */
178 : virtual ErrorCode mute() = 0;
179 :
180 : /**
181 : * Enables sending CANFrames again after CANTransceiver has been muted
182 : * \pre getState() == MUTED
183 : * \post getState() == OPEN
184 : * \return
185 : * - CAN_ERR_OK: transition executed
186 : * - CAN_ERR_ILLEGAL_STATE: method was called in wrong state
187 : */
188 : virtual ErrorCode unmute() = 0;
189 :
190 : /**
191 : * \return internal state of transceiver
192 : * \see State
193 : */
194 : virtual State getState() const = 0;
195 :
196 : /**
197 : * \return baudrate of transceiver
198 : */
199 : virtual uint32_t getBaudrate() const = 0;
200 :
201 : /**
202 : * \return The timeout after which the hw-queue will be empty again.
203 : * The value is computed from baudrate and queue depth.
204 : */
205 : virtual uint16_t getHwQueueTimeout() const = 0;
206 :
207 : /**
208 : * Writes a CANFrame to Can bus
209 : * \param frame frame to transmit
210 : * \return
211 : * - CAN_ERR_OK: transmission was successful
212 : * - CAN_ERR_TX_HW_QUEUE_FULL: tx-hardware-queue is full
213 : * - CAN_ERR_TX_OFFLINE: transceiver was offline while trying to transmit
214 : * - CAN_ERR_TX_FAIL: transmission failed with unspecified error
215 : * - CAN_ERR_ILLEGAL_STATE: method was called in wrong state
216 : *
217 : * \pre getState() == INITIALIZED || OPEN
218 : *
219 : * \section Timing
220 : * A call to this method is non-blocking,
221 : * i.e. it immediately returns an error if e.g. the hw-queue is full
222 : * and relies on the calling task to retry the transmission.
223 : */
224 : virtual ErrorCode write(CANFrame const& frame) = 0;
225 :
226 : /**
227 : * As other write() method with additional listener for
228 : * callbacks once sent.
229 : */
230 : virtual ErrorCode write(CANFrame const& frame, ICANFrameSentListener& listener) = 0;
231 :
232 : /**
233 : * Adds an ICANFrameListener to listener list
234 : * \param canFrameListener listener to register
235 : *
236 : * This method might contains a critical section and uses Suspend-/ResumeOSInterrupts.
237 : *
238 : * \attention
239 : * The filter of canFrameListener shall be merged into the transceivers rx-filter.
240 : * It must be configured before adding the listener!
241 : */
242 : virtual void addCANFrameListener(ICANFrameListener& listener) = 0;
243 :
244 : /**
245 : * Adds a listener to the front of the receiver list.
246 : * \see addCANFrameListener
247 : * Using this method makes sure that the added listener is notified first
248 : * of a incoming CANFrame.
249 : */
250 : virtual void addVIPCANFrameListener(ICANFrameListener& listener) = 0;
251 :
252 : /**
253 : * Removes an ICANFrameListener from listener list
254 : * \param canFrameListener listener to remove
255 : *
256 : * This method might contain a critical section and uses Suspend-/ResumeOSInterrupts.
257 : *
258 : * \attention
259 : * The elements of canFrameListeners filter will not be removed from
260 : * the transceivers rx-filter.
261 : */
262 : virtual void removeCANFrameListener(ICANFrameListener& listener) = 0;
263 :
264 : /**
265 : * \return busId of transceiver
266 : */
267 : virtual uint8_t getBusId() const = 0;
268 :
269 : /**
270 : * adds an addCANFrameSentListener to listener list
271 : * \param listener listener to register
272 : *
273 : * \attention
274 : * The filter of listener is merged into the transceivers rx-filter.
275 : * It must be configured before adding the listener!
276 : */
277 : virtual void addCANFrameSentListener(IFilteredCANFrameSentListener& listener) = 0;
278 :
279 : /**
280 : * removes an ICANFrameListener from listener list
281 : * \param listener listener to remove
282 : *
283 : * \note
284 : * The elements of listener filter will not be removed from
285 : * the transceivers rx-filter.
286 : */
287 : virtual void removeCANFrameSentListener(IFilteredCANFrameSentListener& listener) = 0;
288 :
289 : /**
290 : * Get the hardware state of the CAN transceiver.
291 : * \return state hardware state of the CAN transceiver
292 : */
293 : virtual ICANTransceiverStateListener::CANTransceiverState getCANTransceiverState() const = 0;
294 :
295 : /**
296 : * Sets the transceivers ICANTransceiverStateListener.
297 : * \param pListener ICANTransceiverStateListener to notify when an error
298 : * occurs.
299 : */
300 : virtual void setStateListener(ICANTransceiverStateListener& listener) = 0;
301 :
302 : virtual void removeStateListener() = 0;
303 : };
304 :
305 : } // namespace can
|