halx_driver
読み取り中…
検索中…
一致する文字列を見つけられません
amt22.hpp
[詳解]
1#pragma once
2
3#include <array>
4#include <cstdint>
5#include <optional>
6#include <utility>
7
8#include <stm32cubemx_helper/context.hpp>
9#include <stm32cubemx_helper/device.hpp>
10
11#include <halx/core.hpp>
12#include <halx/rtos.hpp>
13
14namespace halx::driver {
15
16enum class Amt22Resolution : uint8_t {
17 BIT_12 = 12,
18 BIT_14 = 14,
19};
20
21template <SPI_HandleTypeDef *Handle> class Amt22 {
22public:
23 Amt22(GPIO_TypeDef *cs_port, uint16_t cs_pin, Amt22Resolution resolution)
24 : cs_port_{cs_port}, cs_pin_{cs_pin}, resolution_{resolution} {
25 HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET);
26 stm32cubemx_helper::set_context<Handle, Amt22>(this);
27 HAL_SPI_RegisterCallback(
28 Handle, HAL_SPI_TX_RX_COMPLETE_CB_ID, [](SPI_HandleTypeDef *hspi) {
29 auto amt22 = stm32cubemx_helper::get_context<Handle, Amt22>();
30 amt22->tx_rx_sem_.release();
31 });
32 }
33
35 HAL_SPI_Abort_IT(Handle);
36 HAL_SPI_UnRegisterCallback(Handle, HAL_SPI_TX_RX_COMPLETE_CB_ID);
37 stm32cubemx_helper::set_context<Handle, Amt22>(nullptr);
38 HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET);
39 }
40
41 std::optional<uint16_t> read_position() {
42 std::array<uint8_t, 2> command{0x00, 0x00};
43 auto res = send_command(command);
44 if (!res) {
45 return std::nullopt;
46 }
47 return ((*res)[0] << 8 | (*res)[1]) &
48 ((1 << std::to_underlying(resolution_)) - 1);
49 }
50
51 std::optional<int16_t> read_turns() {
52 std::array<uint8_t, 4> command{0x00, 0xA0, 0x00, 0x00};
53 auto res = send_command(command);
54 if (!res) {
55 return std::nullopt;
56 }
57 int16_t turns = ((*res)[2] << 8 | (*res)[3]) & 0x3FFF;
58 if (turns & 0x2000) {
59 turns |= 0xC000;
60 }
61 return turns;
62 }
63
65 std::array<uint8_t, 2> command{0x00, 0x70};
66 return send_command(command).has_value();
67 }
68
69 bool reset() {
70 std::array<uint8_t, 2> command{0x00, 0x60};
71 return send_command(command).has_value();
72 }
73
74private:
75 GPIO_TypeDef *cs_port_;
76 uint16_t cs_pin_;
77 rtos::Semaphore tx_rx_sem_{1, 1};
78 Amt22Resolution resolution_;
79
80 template <size_t N>
81 std::optional<std::array<uint8_t, N>>
82 send_command(const std::array<uint8_t, N> &command) {
83 std::array<uint8_t, N> buf;
84 HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_RESET);
85 for (size_t i = 0; i < N; ++i) {
86 tx_rx_sem_.acquire(0);
87 if (HAL_SPI_TransmitReceive_IT(Handle, &command[i], &buf[i],
88 sizeof(uint8_t))) {
89 HAL_SPI_Abort_IT(Handle);
90 return std::nullopt;
91 }
92 if (!tx_rx_sem_.acquire(1)) {
93 HAL_SPI_Abort_IT(Handle);
94 return std::nullopt;
95 }
96 }
97 HAL_GPIO_WritePin(cs_port_, cs_pin_, GPIO_PIN_SET);
98 for (size_t i = 0; i < N; i += 2) {
99 if (!test_checksum(buf[i], buf[i + 1])) {
100 return std::nullopt;
101 }
102 }
103 return buf;
104 }
105
106 static inline bool test_checksum(uint8_t l, uint8_t h) {
107 bool k1 = !(bit(h, 5) ^ bit(h, 3) ^ bit(h, 1) ^ bit(l, 7) ^ bit(l, 5) ^
108 bit(l, 3) ^ bit(l, 1));
109 bool k0 = !(bit(h, 4) ^ bit(h, 2) ^ bit(h, 0) ^ bit(l, 6) ^ bit(l, 4) ^
110 bit(l, 2) ^ bit(l, 0));
111 return (k1 == bit(h, 7)) && (k0 == bit(h, 6));
112 }
113
114 static inline bool bit(uint8_t x, uint8_t i) { return ((x >> i) & 1) == 1; }
115};
116
117} // namespace halx::driver
~Amt22()
Definition amt22.hpp:34
Amt22(GPIO_TypeDef *cs_port, uint16_t cs_pin, Amt22Resolution resolution)
Definition amt22.hpp:23
std::optional< int16_t > read_turns()
Definition amt22.hpp:51
bool reset()
Definition amt22.hpp:69
bool set_zero_point()
Definition amt22.hpp:64
std::optional< uint16_t > read_position()
Definition amt22.hpp:41
Definition amt21.hpp:10
Amt22Resolution
Definition amt22.hpp:16
@ BIT_14
Definition amt21.hpp:14
@ BIT_12
Definition amt21.hpp:13