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