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