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 48 : 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