2024-02-16 17:43:42 +01:00

216 lines
4.2 KiB
C++

/**
* @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 <sta/config.hpp>
#ifdef STA_CAN_BUS_ENABLE
#include <sta/bus/can/controller.hpp>
#include <sta/devices/stm32/can.hpp>
#include <sta/rtos/c_api/can_msg.h>
#include <sta/proto/isotp/transmitter.hpp>
#include <sta/proto/isotp/receiver.hpp>
#include <sta/time.hpp>
#include <cstdint>
/**
* @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 <sta/config.hpp>"
#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 <sta/config.hpp>"
#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();
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_;
IsotpTransmitter tx_;
IsotpReceiver rx_;
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