tutrcos
読み取り中…
検索中…
一致する文字列を見つけられません
fdcan.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 FDCAN : public CANBase {
18public:
19 FDCAN(FDCAN_HandleTypeDef *hfdcan, size_t rx_queue_size = 64)
20 : hfdcan_{hfdcan}, rx_queue_{rx_queue_size} {
21 auto fdcan =
22 std::find(get_instances().begin(), get_instances().end(), nullptr);
23 TUTRCOS_VERIFY(fdcan != get_instances().end());
24 *fdcan = this;
25
26 TUTRCOS_VERIFY(HAL_FDCAN_ActivateNotification(
27 hfdcan_, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) == HAL_OK);
28 TUTRCOS_VERIFY(HAL_FDCAN_Start(hfdcan_) == HAL_OK);
29 }
30
32 TUTRCOS_VERIFY(HAL_FDCAN_Stop(hfdcan_) == HAL_OK);
33 auto fdcan =
34 std::find(get_instances().begin(), get_instances().end(), this);
35 TUTRCOS_VERIFY(fdcan != get_instances().end());
36 *fdcan = nullptr;
37 }
38
39 bool transmit(const Message &msg, uint32_t timeout) override {
40 FDCAN_TxHeaderTypeDef tx_header{};
41 tx_header.Identifier = msg.id;
42 switch (msg.id_type) {
44 tx_header.IdType = FDCAN_STANDARD_ID;
45 break;
47 tx_header.IdType = FDCAN_EXTENDED_ID;
48 break;
49 }
50 tx_header.TxFrameType = FDCAN_DATA_FRAME;
51 switch (msg.dlc) {
52 case 0:
53 tx_header.DataLength = FDCAN_DLC_BYTES_0;
54 break;
55 case 1:
56 tx_header.DataLength = FDCAN_DLC_BYTES_1;
57 break;
58 case 2:
59 tx_header.DataLength = FDCAN_DLC_BYTES_2;
60 break;
61 case 3:
62 tx_header.DataLength = FDCAN_DLC_BYTES_3;
63 break;
64 case 4:
65 tx_header.DataLength = FDCAN_DLC_BYTES_4;
66 break;
67 case 5:
68 tx_header.DataLength = FDCAN_DLC_BYTES_5;
69 break;
70 case 6:
71 tx_header.DataLength = FDCAN_DLC_BYTES_6;
72 break;
73 case 7:
74 tx_header.DataLength = FDCAN_DLC_BYTES_7;
75 break;
76 case 8:
77 tx_header.DataLength = FDCAN_DLC_BYTES_8;
78 break;
79 }
80 tx_header.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
81 tx_header.BitRateSwitch = FDCAN_BRS_OFF;
82 tx_header.FDFormat = FDCAN_CLASSIC_CAN;
83 tx_header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
84 tx_header.MessageMarker = 0;
85
86 uint32_t start = core::Kernel::get_ticks();
87 while (HAL_FDCAN_GetTxFifoFreeLevel(hfdcan_) == 0) {
88 uint32_t elapsed = core::Kernel::get_ticks() - start;
89 if (elapsed >= timeout) {
90 return false;
91 }
93 }
94 return HAL_FDCAN_AddMessageToTxFifoQ(hfdcan_, &tx_header,
95 msg.data.data()) == HAL_OK;
96 }
97
98 bool receive(Message &msg, uint32_t timeout) override {
99 return rx_queue_.pop(msg, timeout);
100 }
101
102 FDCAN_HandleTypeDef *get_hal_handle() { return hfdcan_; }
103
104private:
105 FDCAN_HandleTypeDef *hfdcan_;
106 core::Queue<Message> rx_queue_;
107
108 static inline std::array<FDCAN *, 20> &get_instances() {
109 static std::array<FDCAN *, 20> instances{};
110 return instances;
111 }
112
113 friend void ::HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan,
114 uint32_t RxFifo0ITs);
115};
116
117} // namespace peripheral
118} // 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 fdcan.hpp:17
~FDCAN()
Definition fdcan.hpp:31
FDCAN_HandleTypeDef * get_hal_handle()
Definition fdcan.hpp:102
bool transmit(const Message &msg, uint32_t timeout) override
Definition fdcan.hpp:39
FDCAN(FDCAN_HandleTypeDef *hfdcan, size_t rx_queue_size=64)
Definition fdcan.hpp:19
bool receive(Message &msg, uint32_t timeout) override
Definition fdcan.hpp:98
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