tutrcos
読み取り中…
検索中…
一致する文字列を見つけられません
can.hpp
[詳解]
1#pragma once
2
3#include "main.h"
4
5#include <array>
6#include <cstddef>
7#include <cstdint>
8
9#include "tutrcos/core.hpp"
10#include "tutrcos/utility.hpp"
11
12#include "can_base.hpp"
13
14namespace tutrcos {
15namespace peripheral {
16
17class CAN : public CANBase {
18public:
19 CAN(CAN_HandleTypeDef *hcan, size_t rx_queue_size = 64)
20 : hcan_{hcan}, rx_queue_{rx_queue_size} {
21 auto can =
22 std::find(get_instances().begin(), get_instances().end(), nullptr);
23 TUTRCOS_VERIFY(can != get_instances().end());
24 *can = this;
25
26 CAN_FilterTypeDef filter{};
27 filter.FilterIdHigh = 0;
28 filter.FilterIdLow = 0;
29 filter.FilterMaskIdHigh = 0;
30 filter.FilterMaskIdLow = 0;
31 filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;
32 filter.FilterBank = 0;
33#ifdef CAN2
34 if (hcan_->Instance == CAN2) {
35 filter.FilterBank = 14;
36 }
37#endif
38 filter.FilterMode = CAN_FILTERMODE_IDMASK;
39 filter.FilterScale = CAN_FILTERSCALE_32BIT;
40 filter.FilterActivation = ENABLE;
41 filter.SlaveStartFilterBank = 14;
42
43 TUTRCOS_VERIFY(HAL_CAN_ConfigFilter(hcan_, &filter) == HAL_OK);
44 TUTRCOS_VERIFY(HAL_CAN_ActivateNotification(
45 hcan_, CAN_IT_RX_FIFO0_MSG_PENDING) == HAL_OK);
46 TUTRCOS_VERIFY(HAL_CAN_Start(hcan_) == HAL_OK);
47 }
48
49 ~CAN() {
50 TUTRCOS_VERIFY(HAL_CAN_Stop(hcan_) == HAL_OK);
51 auto can = std::find(get_instances().begin(), get_instances().end(), this);
52 TUTRCOS_VERIFY(can != get_instances().end());
53 *can = nullptr;
54 }
55
56 bool transmit(const Message &msg, uint32_t timeout) override {
57 CAN_TxHeaderTypeDef tx_header{};
58 switch (msg.id_type) {
60 tx_header.StdId = msg.id;
61 tx_header.IDE = CAN_ID_STD;
62 break;
64 tx_header.ExtId = msg.id;
65 tx_header.IDE = CAN_ID_EXT;
66 break;
67 }
68 tx_header.RTR = CAN_RTR_DATA;
69 tx_header.DLC = msg.dlc;
70 tx_header.TransmitGlobalTime = DISABLE;
71
72 uint32_t tx_mailbox;
73
74 uint32_t start = core::Kernel::get_ticks();
75 while (HAL_CAN_GetTxMailboxesFreeLevel(hcan_) == 0) {
76 uint32_t elapsed = core::Kernel::get_ticks() - start;
77 if (elapsed >= timeout) {
78 return false;
79 }
81 }
82 return HAL_CAN_AddTxMessage(hcan_, &tx_header, msg.data.data(),
83 &tx_mailbox) == HAL_OK;
84 }
85
86 bool receive(Message &msg, uint32_t timeout) override {
87 return rx_queue_.pop(msg, timeout);
88 }
89
90 CAN_HandleTypeDef *get_hal_handle() { return hcan_; }
91
92private:
93 CAN_HandleTypeDef *hcan_;
94 core::Queue<Message> rx_queue_;
95
96 static inline std::array<CAN *, 20> &get_instances() {
97 static std::array<CAN *, 20> instances{};
98 return instances;
99 }
100
101 friend void ::HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
102};
103
104} // namespace peripheral
105} // namespace tutrcos
static uint32_t get_ticks()
Definition kernel.hpp:14
Definition queue.hpp:13
bool pop(T &value, uint32_t timeout)
Definition queue.hpp:33
static void delay(uint32_t ticks)
Definition thread.hpp:32
Definition can_base.hpp:10
Definition can.hpp:17
bool receive(Message &msg, uint32_t timeout) override
Definition can.hpp:86
bool transmit(const Message &msg, uint32_t timeout) override
Definition can.hpp:56
CAN(CAN_HandleTypeDef *hcan, size_t rx_queue_size=64)
Definition can.hpp:19
CAN_HandleTypeDef * get_hal_handle()
Definition can.hpp:90
~CAN()
Definition can.hpp:49
Definition kernel.hpp:7
Definition can_base.hpp:17
uint32_t id
Definition can_base.hpp:19
uint8_t dlc
Definition can_base.hpp:20
IDType id_type
Definition can_base.hpp:18
std::array< uint8_t, 8 > data
Definition can_base.hpp:21
#define TUTRCOS_VERIFY(expr)
Definition utility.hpp:16