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