1
1
// coding: utf-8
2
2
/*
3
3
* Copyright (c) 2021, Raphael Lehmann
4
+ * Copyright (c) 2021, Thomas Sommer
4
5
*
5
6
* This file is part of the modm project.
6
7
*
19
20
20
21
#include < array>
21
22
#include < tuple>
23
+ #include < modm/ui/graphic/display.hpp>
24
+ #include < modm/ui/shape/point.hpp>
22
25
23
26
namespace modm
24
27
{
25
28
26
29
// / \ingroup modm_driver_touch2046
27
30
struct touch2046 {
28
- enum class Orientation {
29
- Normal,
30
- // ...
31
+ enum class Control : uint8_t
32
+ {
33
+ START = Bit7, // 1: Marks the control byte
34
+
35
+ A2 = Bit6, // see enum class ChDiff / ChSingleEnd
36
+ A1 = Bit5,
37
+ A0 = Bit4,
38
+
39
+ MODE = Bit3, // see enum class Mode
40
+ REF = Bit2, // see enum class Reference
41
+
42
+ PD1 = Bit1, // see enum class PowerDown
43
+ PD0 = Bit0,
44
+ };
45
+ MODM_FLAGS8 (Control);
46
+
47
+ // Valid when Control::MODE is 0
48
+ enum class ChDiff : uint8_t
49
+ {
50
+ Z1 = int (Control::A0) | int (Control::A1),
51
+ Z2 = int (Control::A2),
52
+ X = int (Control::A0) | int (Control::A2),
53
+ Y = int (Control::A0)
54
+ };
55
+ typedef Configuration<Control_t, ChDiff, 0b111'0000 > ChDiff_t;
56
+
57
+ // Valid when Control::MODE is 1
58
+ enum class ChSingleEnd : uint8_t
59
+ {
60
+ TEMP0 = 0 ,
61
+ Y = int (Control::A0),
62
+ VBAT = int (Control::A1),
63
+ Z1 = int (Control::A0) | int (Control::A1),
64
+ Z2 = int (Control::A2),
65
+ X = int (Control::A0) | int (Control::A2),
66
+ AUX = int (Control::A0) | int (Control::A1),
67
+ TEMP1 = int (Control::A0) | int (Control::A1) | int (Control::A2)
68
+ };
69
+ typedef Configuration<Control_t, ChSingleEnd, 0b111'0000 > ChSingleEnd_t;
70
+
71
+ enum class Mode : uint8_t
72
+ {
73
+ Res_12Bit = 0 ,
74
+ Res_8Bit = int (Control::MODE)
75
+ };
76
+ typedef Configuration<Control_t, Mode, 0b1 , 3 > Mode_t;
77
+
78
+ enum class Reference : uint8_t
79
+ {
80
+ Differential = 0 ,
81
+ SingleEnded = int (Control::REF)
82
+ };
83
+ typedef Configuration<Control_t, Reference, 0b1 , 2 > Reference_t;
84
+
85
+ enum class PowerDown : uint8_t
86
+ {
87
+ Auto = 0 ,
88
+ RefOff_AdcOn = int (Control::PD0),
89
+ RefOn_AdcOff = int (Control::PD1),
90
+ AlwaysOn = int (Control::PD0) | int (Control::PD1)
31
91
};
92
+ typedef Configuration<Control_t, PowerDown, 0b11 , 0 > PowerDown_t;
93
+
32
94
33
95
/* *
34
96
* Calibration values are used to calculate touch point
35
97
* from raw values.
36
98
*
37
- * \ref FactorX and \ref FactorY scaled by 1000000 to avoid float
38
- * arithmetic. E.g. to get a factor of 0.75 \ref FactorX has to be
39
- * set to 750'000.
40
- *
41
99
* isTouched() = bool(Z > ThresholdZ)
42
100
*
43
101
* X = (rawX * FactorX / 1000000) + OffsetX
44
102
* limited to [0, MaxX]
45
103
* Y = (rawY * FactorY / 1000000) + OffsetY
46
104
* limited to [0, MaxY]
47
- *
48
- * Orientation (rotation, mirror) are applied after the
49
- * above operations.
50
105
*/
106
+
51
107
struct Calibration
52
108
{
109
+ int32_t FactorX = 24 ;
53
110
int16_t OffsetX = 0 ;
111
+ int32_t FactorY = 24 ;
54
112
int16_t OffsetY = 0 ;
55
- int32_t FactorX = 1'000'000 ;
56
- int32_t FactorY = 1'000'000 ;
57
- uint16_t MaxX = 240 ;
58
- uint16_t MaxY = 320 ;
59
- uint16_t ThresholdZ = 1500 ;
60
- Orientation orientation = Orientation::Normal;
113
+ uint16_t ThresholdZ = 1000 ;
61
114
};
62
115
};
63
116
64
117
/* *
65
118
* \ingroup modm_driver_touch2046
66
- * \author Raphael Lehmann
119
+ * \author Raphael Lehmann, Thomas Sommer
67
120
*
68
121
* Datasheet TSC2046: https://www.ti.com/lit/ds/symlink/tsc2046.pdf
69
122
*/
70
- template < class SpiMaster , class Cs >
123
+ template < class SpiMaster , class Cs , Resolution R >
71
124
class Touch2046 : public touch2046 , public modm ::SpiDevice< SpiMaster >, protected modm::NestedResumable<3 >
72
125
{
73
126
public:
127
+ using Orientation = modm::graphic::Orientation;
128
+
74
129
/* *
75
130
* Set calibration data
76
131
*
@@ -81,14 +136,6 @@ class Touch2046 : public touch2046, public modm::SpiDevice< SpiMaster >, protect
81
136
cal = calibration;
82
137
}
83
138
84
- /* *
85
- * Get raw X, Y and Z values
86
- *
87
- * \return Position and intensity of touch point. Full int16_t range.
88
- */
89
- modm::ResumableResult<std::tuple<uint16_t ,uint16_t ,uint16_t >>
90
- getRawValues ();
91
-
92
139
/* *
93
140
* Is screen touched?
94
141
*
@@ -98,36 +145,57 @@ class Touch2046 : public touch2046, public modm::SpiDevice< SpiMaster >, protect
98
145
isTouched ();
99
146
100
147
/* *
101
- * Get touch position
148
+ * Get touch position as tuple
102
149
*
103
150
* \return Position (X, Y) of touch point.
104
151
*/
105
152
modm::ResumableResult<std::tuple<uint16_t ,uint16_t >>
106
153
getTouchPosition ();
107
154
155
+ /* *
156
+ * Get touch position as modm::shape::Point
157
+ *
158
+ * \return Point of touch point.
159
+ */
160
+ modm::ResumableResult<modm::shape::Point >
161
+ getTouchPoint ();
162
+
163
+ void setOrientation (Orientation orientation)
164
+ { this ->orientation = orientation; }
165
+
166
+ Orientation getOrientation () const
167
+ { return orientation; }
168
+
108
169
private:
109
- static constexpr uint8_t MeasureZ1 = 0xB1 ;
110
- static constexpr uint8_t MeasureZ2 = 0xC1 ;
111
- static constexpr uint8_t MeasureX = 0xD1 ;
112
- static constexpr uint8_t MeasureY = 0x91 ;
113
- static constexpr uint8_t Powerdown = 0b1111'1100 ;
114
- static constexpr std::array<uint8_t , 17 > bufferWrite = {
115
- MeasureZ1, 0x00 ,
116
- MeasureZ2, 0x00 ,
117
- MeasureY, 0x00 ,
118
- MeasureX, 0x00 ,
119
- MeasureY, 0x00 ,
120
- MeasureX, 0x00 ,
121
- MeasureY, 0x00 ,
122
- (MeasureX & Powerdown), 0x00 ,
123
- 0x00 };
124
- std::array<uint16_t , 9 > bufferRead = {};
170
+ modm::ResumableResult<void >
171
+ updateZ ();
172
+
173
+ modm::ResumableResult<void >
174
+ updateXY ();
175
+
176
+ static constexpr Control_t Measure = Control::START | Mode_t(Mode::Res_12Bit)
177
+ | Reference_t(Reference::Differential) | PowerDown_t(PowerDown::RefOff_AdcOn);
178
+
179
+ static constexpr std::array<uint16_t , 8 > bufferWrite = {
180
+ (Measure | ChDiff_t (ChDiff::Z1)).value ,
181
+ ((Measure | ChDiff_t (ChDiff::Z2)) & ~PowerDown_t::mask ()).value ,
182
+ (Measure | ChDiff_t (ChDiff::X)).value ,
183
+ (Measure | ChDiff_t (ChDiff::Y)).value ,
184
+ (Measure | ChDiff_t (ChDiff::X)).value ,
185
+ (Measure | ChDiff_t (ChDiff::Y)).value ,
186
+ (Measure | ChDiff_t (ChDiff::X)).value ,
187
+ ((Measure | ChDiff_t (ChDiff::Y)) & ~PowerDown_t::mask ()).value
188
+ };
189
+ std::array<uint16_t , 7 > bufferRead = {};
125
190
191
+ public:
126
192
uint16_t x = 0 ;
127
193
uint16_t y = 0 ;
128
194
uint16_t z = 0 ;
129
195
130
196
Calibration cal;
197
+
198
+ Orientation orientation = Orientation::Portrait90;
131
199
};
132
200
133
201
} // modm namespace
0 commit comments