Line data Source code
1 : // Copyright 2024 Accenture. 2 : 3 : /** 4 : * Contains class AbstractCANTransceiver. 5 : * \file AbstractCANTransceiver.h 6 : * \ingroup transceiver 7 : */ 8 : #pragma once 9 : 10 : #include "can/canframes/CANFrame.h" 11 : #include "can/framemgmt/AbstractBitFieldFilteredCANFrameListener.h" 12 : #include "can/framemgmt/AbstractIntervalFilteredCANFrameListener.h" 13 : #include "can/framemgmt/IFilteredCANFrameSentListener.h" 14 : #include "can/transceiver/ICANTransceiverStateListener.h" 15 : #include "can/transceiver/ICanTransceiver.h" 16 : 17 : #include <etl/intrusive_forward_list.h> 18 : #include <etl/intrusive_list.h> 19 : 20 : #include <platform/estdint.h> 21 : 22 : namespace can 23 : { 24 : class ICANFrameSentListener; 25 : class IFilteredCANFrameSentListener; 26 : class FrameDispatcher; 27 : class CanTransportLayer; 28 : 29 : /** 30 : * Cpp2CAN AbstractCANTransceiver 31 : * \class AbstractCANTransceiver 32 : * 33 : * 34 : * An AbstractCANTransceiver is the common hardware independent base class for 35 : * CAN Transceiver classes. This base implementation or the ICanTransceiver interface 36 : * shall be used in all applications to avoid HW dependencies. 37 : * 38 : * This abstract class implements the HW independent methods. 39 : * 40 : * \section Reception 41 : * An implementation of AbstractCANTransceiver has to fill a CANFrame object 42 : * with the data of the received can frame and then call 43 : * notifyListeners() with the received CANFrame which distributes it to all 44 : * listeners, i.e. to all listeners whose filter match the id of fRxFrame. 45 : * 46 : */ 47 : class AbstractCANTransceiver : public ICanTransceiver 48 : { 49 : public: 50 : /** 51 : * constructor 52 : * \param busId busId of MultiChannelCanTransceiver 53 : * \post getState() == CLOSED 54 : */ 55 : explicit AbstractCANTransceiver(uint8_t busId); 56 : 57 : /** 58 : * \return internal state of transceiver 59 : * \see State 60 : */ 61 : State getState() const override; 62 : 63 : /** 64 : * adds an ICANFrameListener to listener list 65 : * \param canFrameListener listener to register 66 : * 67 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts. 68 : * 69 : * \attention 70 : * The filter of canFrameListener is merged into the transceivers rx-filter. 71 : * It must be configured before adding the listener! 72 : */ 73 : void addCANFrameListener(ICANFrameListener& listener) override; 74 : 75 : /** 76 : * Adds a listener to the front of the receiver list. 77 : * \see addCANFrameListener 78 : * Using this method makes sure that the added listener is notified first 79 : * of a incoming CANFrame. 80 : */ 81 : void addVIPCANFrameListener(ICANFrameListener& listener) override; 82 : 83 : /** 84 : * removes an ICANFrameListener from listener list 85 : * \param canFrameListener listener to remove 86 : * 87 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts. 88 : * 89 : * \note 90 : * The elements of canFrameListeners filter will not be removed from 91 : * the transceivers rx-filter. 92 : */ 93 : void removeCANFrameListener(ICANFrameListener& listener) override; 94 : 95 : /** 96 : * adds an addCANFrameSentListener to listener list 97 : * \param listener listener to register 98 : * 99 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts. 100 : * 101 : * \attention 102 : * The filter of listener is merged into the transceivers rx-filter. 103 : * It must be configured before adding the listener! 104 : */ 105 : void addCANFrameSentListener(IFilteredCANFrameSentListener& listener) override; 106 : 107 : /** 108 : * removes an ICANFrameListener from listener list 109 : * \param listener listener to remove 110 : * 111 : * This method contains a critical section and uses Suspend-/ResumeOSInterrupts. 112 : * 113 : * \note 114 : * The elements of listener filter will not be removed from 115 : * the transceivers rx-filter. 116 : */ 117 : void removeCANFrameSentListener(IFilteredCANFrameSentListener& listener) override; 118 : 119 : /** 120 : * \return busId of transceiver 121 : */ 122 1 : uint8_t getBusId() const override { return _busId; } 123 : 124 : /** 125 : * Get the hardware state of the CAN transceiver. 126 : * \return state hardware state of the CAN transceiver 127 : */ 128 1 : ICANTransceiverStateListener::CANTransceiverState getCANTransceiverState() const override 129 : { 130 1 : return _transceiverState; 131 : } 132 : 133 : /** 134 : * Sets the transceivers ICANTransceiverStateListener. 135 : * \param pListener ICANTransceiverStateListener to notify when an error 136 : * occurs. 0L if no class needs to be notified. 137 : */ 138 1 : void setStateListener(ICANTransceiverStateListener& listener) override 139 : { 140 1 : _stateListener = &listener; 141 1 : } 142 : 143 1 : void removeStateListener() override { _stateListener = nullptr; } 144 : 145 : protected: 146 : void setState(State newState); 147 : 148 : bool isInState(State state) const; 149 : 150 : /** 151 : * Notifies all appropriate listeners about the reception of a CANFrame. 152 : * \param frame CANFrame that will be passed to all listeners 153 : */ 154 : void notifyListeners(CANFrame const& frame); 155 : 156 : void notifySentListeners(can::CANFrame const& frame); 157 : 158 : /** 159 : * Notifies the attached ICANTransceiverStateListener that a phy error occurred 160 : */ 161 3 : void notifyStateListenerWithPhyError() 162 : { 163 3 : if (_stateListener != nullptr) 164 : { 165 1 : _stateListener->phyErrorOccurred(*this); 166 : } 167 3 : } 168 : 169 : /** 170 : * Notifies the attached ICANTransceiverStateListener with a given 171 : * state 172 : * \param state new can transceiver state. 173 : */ 174 : void notifyStateListenerWithState(ICANTransceiverStateListener::CANTransceiverState state); 175 : 176 : protected: 177 : BitFieldFilter _filter; 178 : ::etl::intrusive_list<ICANFrameListener, ::etl::bidirectional_link<0>> _listeners; 179 : IFilteredCANFrameSentListener* _sentListener; 180 : ::etl::intrusive_forward_list<IFilteredCANFrameSentListener, ::etl::forward_link<0>> 181 : _sentListeners; 182 : /** baudrate of transceiver */ 183 : uint32_t _baudrate; 184 : /** internal State */ 185 : State _state; 186 : uint8_t _busId; 187 : ICANTransceiverStateListener* _stateListener; 188 : ICANTransceiverStateListener::CANTransceiverState _transceiverState; 189 : }; 190 : 191 2 : inline ICanTransceiver::State AbstractCANTransceiver::getState() const { return _state; } 192 : 193 2 : inline void AbstractCANTransceiver::setState(ICanTransceiver::State const newState) 194 : { 195 2 : _state = newState; 196 : } 197 : 198 2 : inline bool AbstractCANTransceiver::isInState(ICanTransceiver::State const state) const 199 : { 200 2 : return (_state == state); 201 : } 202 : 203 6 : inline void AbstractCANTransceiver::notifyStateListenerWithState( 204 : ICANTransceiverStateListener::CANTransceiverState const state) 205 : { 206 6 : if (_stateListener != nullptr) 207 : { 208 1 : _stateListener->canTransceiverStateChanged(*this, state); 209 : } 210 6 : } 211 : 212 : } // namespace can