/** * @file * @brief Public interface for CAN driver thread. */ #ifndef STA_RTOS_SYSTEM_CAN_BUS_HPP #define STA_RTOS_SYSTEM_CAN_BUS_HPP /** * @defgroup STA_RTOS_CanBus CAN driver * @ingroup STA_RTOS_API * @brief CAN bus system task. * * Check @ref STA_RTOS_BuildConfig for configuration options. */ #ifdef DOXYGEN /** * @brief Enable module. * * @ingroup STA_RTOS_BuildConfig */ # define STA_CAN_BUS_ENABLE #endif // DOXYGEN #include #ifdef STA_CAN_BUS_ENABLE #include #include #include #include #include #include #include /** * @def STA_RTOS_CAN_BUS_MAX_FILTER * @brief Set maximum number of usable filters. * * @ingroup STA_RTOS_BuildConfig */ #ifndef STA_RTOS_CAN_BUS_MAX_FILTER # error "Must set STA_RTOS_CAN_BUS_MAX_FILTER in " #endif // STA_RTOS_CAN_BUS_MAX_FILTER /** * @def STA_RTOS_CAN_BUS_MAX_PAYLOAD_SIZE * @brief Set maximum payload size. * * @ingroup STA_RTOS_BuildConfig */ #ifndef STA_RTOS_CAN_BUS_MAX_PAYLOAD_SIZE # error "Must set STA_RTOS_CAN_BUS_MAX_PAYLOAD_SIZE in " #endif // STA_RTOS_CAN_BUS_MAX_PAYLOAD_SIZE /** * @ingroup STA_RTOS_CanBus * @{ */ /** * @brief CAN frame available. */ #define STA_RTOS_CAN_FLAG_MSG_AVAIL 0x1U /** * @brief Send CAN message. */ #define STA_RTOS_CAN_FLAG_MSG_SEND 0x1U << 1 /** * @brief CAN data message in queue. */ #define STA_RTOS_CAN_FLAG_DATA_QUEUED 0x1U << 2 /** * @brief CAN system message in queue. */ #define STA_RTOS_CAN_FLAG_SYS_QUEUED 0x1U << 3 /** * @brief Show ISOTP statistics. */ #define STA_RTOS_CAN_FLAG_SHOW_STATS 0x1U << 4 /** * @brief CAN SID bits used for system messages. */ #define STA_CAN_SID_SYS_BITS UINT32_C(0x3) #define STA_RTOS_CAN_ANY STA_RTOS_CAN_FLAG_MSG_AVAIL | STA_RTOS_CAN_FLAG_MSG_AVAIL | STA_RTOS_CAN_FLAG_DATA_QUEUED | STA_RTOS_CAN_FLAG_SYS_QUEUED | STA_RTOS_CAN_FLAG_SHOW_STATS /** @} */ namespace sta { namespace rtos { /** * @ingroup STA_RTOS_CanBus * @{ */ /** * @brief Initialize CAN bus. */ void initCanBus(); /** * @brief Return CAN_HandleTypeDef for use in CAN system task. * * Implementation must be provided by application. */ extern CAN_HandleTypeDef * getCanController(); /** @} */ } // namespace rtos } // namespace sta namespace sta { class AlpakaCanBus { public: using SysMsgHandler = void (*)(const CanRxHeader &, const uint8_t *); using DataMsgHandler = void (*)(const IsotpMessage &); static const uint8_t FIFO_SYS = 0; static const uint8_t FIFO_DATA = 1; public: AlpakaCanBus(CanController * controller, TimeMsFn timeMs, SysMsgHandler sysMsgHandler, DataMsgHandler dataMsgHandler); /** * @brief Send system message. * * @param msg Message */ void send(const CanSysMsg & msg); /** * @brief Send data message. * * @param msg Message */ void send(const CanDataMsg & msg); /** * @brief Process transmissions. * * Call regularly to advance transmission. */ void processTx(); /** * @brief Process received CAN messages. */ void processRx(); /** * @brief Display ISOTP TX/RX statistics. */ void showStatistics(); IsotpTransmitter tx_; IsotpReceiver rx_; private: /** * @brief Configure CAN filters. */ void setupSubscriptions(); /** * @brief Handle received data message CAN frames. * * @param header CAN frame header * @param payload Payload buffer */ void receiveDataFrame(const CanRxHeader & header, const uint8_t * payload); private: CanController * controller_; SysMsgHandler handleSysMsg_; DataMsgHandler handleDataMsg_; }; } // namespace sta namespace debug { /** * @brief Output CAN frame ID to UART. * * @param id Frame ID */ void printFrameID(const sta::CanFrameId & id); /** * @brief Output CAN frame payload to UART. * * @param payload Payload buffer * @param size Payload size */ void printPayloadHex(const uint8_t * payload, uint8_t size); } // namespace debug #endif // STA_CAN_BUS_ENABLE #endif // STA_RTOS_SYSTEM_CAN_BUS_HPP