-
Notifications
You must be signed in to change notification settings - Fork 0
/
analog_in.h
96 lines (74 loc) · 2.67 KB
/
analog_in.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*!
* @file analogin_dma_stream.h v1.0
* @Copyright © 2021 Kazushi Kurasawa
* @date 2023.08.10
*
* Released under the MIT license.
* see https://opensource.org/licenses/MIT
*/
#ifndef MSLH_ANALOG_IN_H
#define MSLH_ANALOG_IN_H
/**
* @warning
* STM32CubeMXでのADC設定必須項目
* Resolution : 12 bits (15 ADC Clock cycles)
* Data Alignment: : Right alignment
* Scan Conversion Mode : Enable
* Continuous Conversion Mode : Disable
* Discontinuous Conversion Mode : Enable
* Number Of Discontinuous Conversions : 1 (ADCの数ではく"1"固定)
* DMA Continuous Requests : Disable
* End Of Conversion Selection : EOC flag at the end of single channel conversion
* Number Of Conversion : 仕様する距離ADCの数("Rank"では変換するセンサの数だけ設定する)
*/
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include "arm_math.h"
#include "adc.h"
namespace mslh {
class AnalogIn {
public:
AnalogIn(const uint32_t adc_rank): _adc_rank(adc_rank), _adc_value(0) {}
inline uint16_t read() { return _adc_value; }
private:
const uint32_t _adc_rank;
uint16_t _adc_value;
friend class AnalogInUpdater;
};
class AnalogInUpdater
{
public:
template <typename... AnalogIns>
AnalogInUpdater(ADC_HandleTypeDef &hadc, AnalogIns &...analog_ins): _hadc(hadc) {
std::vector<std::reference_wrapper<AnalogIn>> temp_analog_ins{analog_ins...};
sortAndVerify(temp_analog_ins);
_analog_in = temp_analog_ins; // rank順にソートした配列
}
void update() {
for(AnalogIn &value : _analog_in) {
HAL_ADC_Start(&_hadc);
if(HAL_ADC_PollForConversion(&_hadc, 1) != HAL_OK) Error_Handler();
value._adc_value = HAL_ADC_GetValue(&_hadc);
}
}
private:
void sortAndVerify(std::vector<std::reference_wrapper<AnalogIn>> &analog_ins)
{
// _adc_rank の順番に従ってソート
std::sort( analog_ins.begin(), analog_ins.end(), [](const AnalogIn &a, const AnalogIn &b) {
return a._adc_rank < b._adc_rank; } );
// Rankが1から始まり連続した整数値でないときにエラーとなる
for (size_t i = 0; i < analog_ins.size(); ++i) {
if (analog_ins[i].get()._adc_rank != i + 1) {
// ここでエラー処理
Error_Handler();
}
}
}
ADC_HandleTypeDef &_hadc;
std::vector<std::reference_wrapper<AnalogIn>> _analog_in;
};
} // namespace mslh
#endif // MSLH_ANALOG_IN_H