Line data Source code
1 : // Copyright 2024 Accenture. 2 : 3 : /** 4 : * Contains Cpp2CAN CanFlex2Transceiver 5 : * \file CanFlex2Transceiver.h 6 : * \ingroup transceiver 7 : */ 8 : #pragma once 9 : 10 : #include <async/Async.h> 11 : #include <async/util/Call.h> 12 : #include <bsp/can/canTransceiver/CanPhy.h> 13 : #include <bsp/power/IEcuPowerStateController.h> 14 : #include <bsp/timer/SystemTimer.h> 15 : #include <can/FlexCANDevice.h> 16 : #include <can/canframes/CANFrame.h> 17 : #include <can/canframes/ICANFrameSentListener.h> 18 : #include <can/framemgmt/IFilteredCANFrameSentListener.h> 19 : #include <can/transceiver/AbstractCANTransceiver.h> 20 : #include <etl/deque.h> 21 : #include <etl/uncopyable.h> 22 : #include <io/Io.h> 23 : #include <lifecycle/AsyncLifecycleComponent.h> 24 : 25 : #include <platform/estdint.h> 26 : 27 : namespace bios 28 : { 29 : /** 30 : * CAN transceiver. 31 : * \see AbstractCANTransceiver 32 : * \see FlexCANDevice 33 : * \see common::AbstractTimeout 34 : */ 35 : class CanFlex2Transceiver 36 : : public ::can::AbstractCANTransceiver 37 : , public ::etl::uncopyable 38 : { 39 : public: 40 : CanFlex2Transceiver( 41 : ::async::ContextType context, 42 : uint8_t busId, 43 : FlexCANDevice::Config const& devConfig, 44 : CanPhy& Phy, 45 : IEcuPowerStateController& powerStateController); 46 : 47 : ::can::ICanTransceiver::ErrorCode init() override; 48 : ::can::ICanTransceiver::ErrorCode open(::can::CANFrame const& frame) override; 49 : ::can::ICanTransceiver::ErrorCode open() override; 50 : 51 : ::can::ICanTransceiver::ErrorCode close() override; 52 : 53 : void shutdown() override; 54 : 55 : ::can::ICanTransceiver::ErrorCode write(can::CANFrame const& frame) override; 56 : 57 : ::can::ICanTransceiver::ErrorCode 58 : write(can::CANFrame const& frame, can::ICANFrameSentListener& listener) override; 59 : 60 : ErrorCode mute() override; 61 : 62 : ErrorCode unmute() override; 63 : 64 : /** 65 : * Checks if the CAN device associated with the transceiver has woken up. 66 : */ 67 2 : bool wokenUp() { return fFlexCANDevice.wokenUp(); } 68 : 69 1 : uint32_t getBaudrate() const override { return fFlexCANDevice.getBaudrate(); } 70 : 71 : /** 72 : * \return the Hardware Queue Timeout. 73 : */ 74 : uint16_t getHwQueueTimeout() const override; 75 : 76 : /** 77 : * \return ID of first frame seen after open() or resetFirstFrame() or INVALID_FRAME_ID. 78 : */ 79 : virtual uint16_t getFirstFrameId() const; 80 : 81 : /** 82 : * Resets information about the first frame, the next frame received will be the first frame 83 : */ 84 : virtual void resetFirstFrame(); 85 : 86 : /** 87 : * Checks if the CAN transceiver is receiving data. 88 : */ 89 6 : virtual bool getRxAlive() const 90 : { 91 6 : if (_state == State::MUTED) 92 : { 93 3 : return ((fRxAlive) || (fFlexCANDevice.getFirstCanId() != 0)); 94 : } 95 : else 96 : { 97 3 : return fRxAlive; 98 : } 99 : } 100 : 101 : /** 102 : * \return the count of overrun events that have occurred in the CAN transceiver. 103 : */ 104 : uint32_t getOverrunCount() const { return fOverrunCount; } 105 : 106 : /** 107 : * cyclicTask() 108 : * 109 : * Called periodically. 110 : * Checks transceiver error pins and bus state. 111 : * Notifies state change and phy error listeners. 112 : */ 113 : void cyclicTask(); 114 : 115 : /** 116 : * Processes the receive queue of the CAN device. 117 : */ 118 : void receiveTask(); 119 : 120 : /** 121 : * Handles sending of further frames if the transmit queue is not yet empty. 122 : */ 123 : void canFrameSentCallback(); 124 : void canFrameSentAsyncCallback(); 125 : 126 : /** 127 : * Calls the Receive ISR 128 : * \return the number of frames received 129 : */ 130 1 : static uint8_t receiveInterrupt(uint8_t const transceiverIndex) 131 : { 132 1 : return fpCanTransceivers[transceiverIndex]->fFlexCANDevice.receiveISR( 133 2 : fpCanTransceivers[transceiverIndex]->_filter.getRawBitField()); 134 : } 135 : 136 : /** 137 : * Calls the Transmit ISR 138 : */ 139 1 : static void transmitInterrupt(uint8_t const transceiverIndex) 140 : { 141 1 : fpCanTransceivers[transceiverIndex]->fFlexCANDevice.transmitISR(); 142 1 : } 143 : 144 : /** 145 : * \return a list of all CanFlex2Transceiver 146 : */ 147 1 : static CanFlex2Transceiver** getAllCanFlex2Transceivers() { return fpCanTransceivers; } 148 : 149 : private: 150 : /** polling time */ 151 : static uint32_t const ERROR_POLLING_TIMEOUT = 10; 152 : 153 : struct TxJobWithCallback 154 : { 155 18 : TxJobWithCallback(::can::ICANFrameSentListener& listener, ::can::CANFrame const& frame) 156 18 : : _listener(listener), _frame(frame) 157 18 : {} 158 : 159 : ::can::ICANFrameSentListener& _listener; 160 : ::can::CANFrame const& _frame; 161 : }; 162 : 163 : using TxQueue = ::etl::deque<TxJobWithCallback, 3>; 164 : 165 : static CanFlex2Transceiver* fpCanTransceivers[8]; 166 : FlexCANDevice::Config const& fdevConfig; 167 : FlexCANDevice fFlexCANDevice; 168 : bool fIsPhyErrorPresent; 169 : 170 : uint16_t fTxOfflineErrors; 171 : uint32_t fOverrunCount; 172 : uint32_t fFramesSentCount; 173 : 174 : TxQueue fTxQueue; 175 : 176 : bool fFirstFrameNotified; 177 : bool fRxAlive; 178 : 179 : ::async::ContextType const _context; 180 : ::async::Function _cyclicTask; 181 : ::async::TimeoutType _cyclicTaskTimeout; 182 : ::async::Function _canFrameSent; 183 : 184 : ::can::ICanTransceiver::ErrorCode 185 : write(::can::CANFrame const& frame, ::can::ICANFrameSentListener* pListener); 186 : 187 17 : void notifyRegisteredSentListener(::can::CANFrame const& frame) { notifySentListeners(frame); } 188 : }; 189 : 190 : } // namespace bios