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