123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- #pragma once
- #include <AP_HAL/AP_HAL.h>
- #if AP_UAVCAN_SLCAN_ENABLED
- #include <AP_UAVCAN/AP_UAVCAN.h>
- #include "AP_HAL/utility/RingBuffer.h"
- #define SLCAN_BUFFER_SIZE 200
- #define SLCAN_RX_QUEUE_SIZE 64
- #define SLCAN_DRIVER_INDEX 2
- class SLCANRouter;
- namespace SLCAN {
- /**
- * Driver error codes.
- * These values can be returned from driver functions negated.
- */
- static const int16_t ErrUnknown = 1000; ///< Reserved for future use
- static const int16_t ErrNotImplemented = 1001; ///< Feature not implemented
- static const int16_t ErrInvalidBitRate = 1002; ///< Bit rate not supported
- static const int16_t ErrLogic = 1003; ///< Internal logic error
- static const int16_t ErrUnsupportedFrame = 1004; ///< Frame not supported (e.g. RTR, CAN FD, etc)
- static const int16_t ErrMsrInakNotSet = 1005; ///< INAK bit of the MSR register is not 1
- static const int16_t ErrMsrInakNotCleared = 1006; ///< INAK bit of the MSR register is not 0
- static const int16_t ErrBitRateNotDetected = 1007; ///< Auto bit rate detection could not be finished
- static const int16_t ErrFilterNumConfigs = 1008; ///< Auto bit rate detection could not be finished
- class CANManager;
- /**
- * RX queue item.
- * The application shall not use this directly.
- */
- struct CanRxItem {
- uint64_t utc_usec;
- uavcan::CanFrame frame;
- uavcan::CanIOFlags flags;
- CanRxItem() :
- utc_usec(0), flags(0)
- {
- }
- };
- class CAN: public AP_HAL::CAN {
- friend class CANManager;
- friend class ::SLCANRouter;
- struct TxItem {
- uavcan::MonotonicTime deadline;
- uavcan::CanFrame frame;
- bool pending;
- bool loopback;
- bool abort_on_error;
- TxItem() :
- pending(false), loopback(false), abort_on_error(false)
- {
- }
- };
- enum {
- NumTxMailboxes = 3
- };
- enum {
- NumFilters = 14
- };
- uint32_t bitrate_;
- virtual int16_t send(const uavcan::CanFrame& frame, uavcan::MonotonicTime tx_deadline,
- uavcan::CanIOFlags flags) override;
- virtual int16_t receive(uavcan::CanFrame& out_frame, uavcan::MonotonicTime& out_ts_monotonic,
- uavcan::UtcTime& out_ts_utc, uavcan::CanIOFlags& out_flags) override;
- int16_t reportFrame(const uavcan::CanFrame& frame, bool loopback, uint64_t timestamp_usec);
- virtual int16_t configureFilters(const uavcan::CanFilterConfig* filter_configs, uint16_t num_configs) override
- {
- //TODO: possibly check at the first serial read
- return 0;
- }
- virtual uint16_t getNumFilters() const override
- {
- return NumFilters;
- }
- /**
- * Total number of hardware failures and other kinds of errors (e.g. queue overruns).
- * May increase continuously if the interface is not connected to the bus.
- */
- virtual uint64_t getErrorCount() const override
- {
- return 0;
- }
- const char* processCommand(char* cmd);
- bool push_Frame(uavcan::CanFrame &frame);
- bool handle_FrameRTRStd(const char* cmd);
- bool handle_FrameRTRExt(const char* cmd);
- bool handle_FrameDataStd(const char* cmd);
- bool handle_FrameDataExt(const char* cmd);
- void reader();
- inline void addByte(const uint8_t byte);
- bool initialized_;
- bool _port_initialised;
- char buf_[SLCAN_BUFFER_SIZE + 1];
- int16_t pos_ = 0;
- AP_HAL::UARTDriver *_port = nullptr;
- ObjectBuffer<CanRxItem> rx_queue_;
- uint8_t self_index_;
- HAL_Semaphore rx_sem_;
- unsigned _pending_frame_size = 0;
- const uint32_t _serial_lock_key = 0x53494442;
- bool _close = true;
- public:
- CAN(uint8_t self_index, uint8_t rx_queue_capacity):
- self_index_(self_index), rx_queue_(rx_queue_capacity), _port_initialised(false)
- {
- UAVCAN_ASSERT(self_index_ < CAN_STM32_NUM_IFACES);
- }
- enum {
- MaxRxQueueCapacity = 254
- };
- enum OperatingMode {
- NormalMode, SilentMode
- };
- int init(const uint32_t bitrate, const OperatingMode mode, AP_HAL::UARTDriver* port);
- bool begin(uint32_t bitrate) override
- {
- if (init(bitrate, OperatingMode::NormalMode, nullptr) == 0) {
- bitrate_ = bitrate;
- initialized_ = true;
- }
- else {
- initialized_ = false;
- }
- return initialized_;
- }
- void end() override
- {
- }
- void reset() override;
- int32_t tx_pending() override
- {
- return _port->tx_pending() ? 0:-1;
- }
- int32_t available() override
- {
- return _port->available() ? 0:-1;
- }
- bool is_initialized() override
- {
- return initialized_;
- }
- bool closed()
- {
- return _close;
- }
- bool pending_frame_sent();
- bool isRxBufferEmpty(void);
- bool canAcceptNewTxFrame() const;
- };
- class CANManager: public AP_HAL::CANManager, public uavcan::ICanDriver {
- bool initialized_;
- CAN driver_;
- uint8_t _ifaces_num = 1;
- virtual int16_t select(uavcan::CanSelectMasks& inout_masks,
- const uavcan::CanFrame* (&pending_tx)[uavcan::MaxCanIfaces], uavcan::MonotonicTime blocking_deadline) override;
- uavcan::CanSelectMasks makeSelectMasks(const uavcan::CanFrame* (&pending_tx)[uavcan::MaxCanIfaces]);
- thread_t *_irq_handler_ctx = nullptr;
- public:
- CANManager()
- : AP_HAL::CANManager(this), initialized_(false), driver_(SLCAN_DRIVER_INDEX, SLCAN_RX_QUEUE_SIZE)
- { }
- /**
- * Whether at least one iface had at least one successful IO since previous call of this method.
- * This is designed for use with iface activity LEDs.
- */
- //bool hadActivity();
- static CANManager *from(AP_HAL::CANManager *can)
- {
- return static_cast<CANManager*>(can);
- }
- bool begin(uint32_t bitrate, uint8_t can_number) override;
- /*
- Test if CAN manager is ready and initialized
- return false - CAN manager not initialized
- true - CAN manager is initialized
- */
- bool is_initialized() override;
- void initialized(bool val) override;
- virtual CAN* getIface(uint8_t iface_index) override
- {
- return &driver_;
- }
- virtual uint8_t getNumIfaces() const override
- {
- return _ifaces_num;
- }
- void reader_trampoline(void);
- };
- }
- #include <AP_HAL_ChibiOS/CANSerialRouter.h>
- #endif // AP_UAVCAN_SLCAN_ENABLED
|