11// coding: utf-8
22/*
33 * Copyright (c) 2021, Raphael Lehmann
4+ * Copyright (c) 2021, Thomas Sommer
45 *
56 * This file is part of the modm project.
67 *
1011 */
1112// ----------------------------------------------------------------------------
1213
13- #ifndef MODM_TOUCH2046_HPP
14- #define MODM_TOUCH2046_HPP
14+ #pragma once
15+
16+ #include < array>
17+ #include < tuple>
1518
1619#include < modm/architecture/interface/spi_device.hpp>
1720#include < modm/architecture/interface/gpio.hpp>
1821#include < modm/processing/resumable.hpp>
22+ #include < modm/ui/graphic/display.hpp>
1923
20- #include < array>
21- #include < tuple>
24+ using namespace modm ::shape;
2225
2326namespace modm
2427{
2528
2629// / \ingroup modm_driver_touch2046
2730struct 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)
3154 };
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)
91+ };
92+ typedef Configuration<Control_t, PowerDown, 0b11 , 0 > PowerDown_t;
93+
3294
3395 /* *
3496 * Calibration values are used to calculate touch point
3597 * from raw values.
3698 *
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- *
4199 * isTouched() = bool(Z > ThresholdZ)
42100 *
43101 * X = (rawX * FactorX / 1000000) + OffsetX
44102 * limited to [0, MaxX]
45103 * Y = (rawY * FactorY / 1000000) + OffsetY
46104 * limited to [0, MaxY]
47- *
48- * Orientation (rotation, mirror) are applied after the
49- * above operations.
50105 */
106+
51107 struct Calibration
52108 {
109+ int32_t FactorX = 24 ;
53110 int16_t OffsetX = 0 ;
111+ int32_t FactorY = 24 ;
54112 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 ;
61114 };
62115};
63116
64117/* *
65118 * \ingroup modm_driver_touch2046
66- * \author Raphael Lehmann
119+ * \author Raphael Lehmann, Thomas Sommer
67120 *
68121 * Datasheet TSC2046: https://www.ti.com/lit/ds/symlink/tsc2046.pdf
69122 */
70- template < class SpiMaster , class Cs >
123+ template < class SpiMaster , class Cs , Size R >
71124class Touch2046 : public touch2046 , public modm ::SpiDevice< SpiMaster >, protected modm::NestedResumable<3 >
72125{
73126public:
127+ using Orientation = modm::graphic::Orientation;
128+
74129 /* *
75130 * Set calibration data
76131 *
@@ -81,14 +136,6 @@ class Touch2046 : public touch2046, public modm::SpiDevice< SpiMaster >, protect
81136 cal = calibration;
82137 }
83138
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-
92139 /* *
93140 * Is screen touched?
94141 *
@@ -98,40 +145,58 @@ class Touch2046 : public touch2046, public modm::SpiDevice< SpiMaster >, protect
98145 isTouched ();
99146
100147 /* *
101- * Get touch position
148+ * Get touch position as tuple
102149 *
103150 * \return Position (X, Y) of touch point.
104151 */
105152 modm::ResumableResult<std::tuple<uint16_t ,uint16_t >>
106153 getTouchPosition ();
107154
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+
108169private:
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 = {};
125190
191+ public:
126192 uint16_t x = 0 ;
127193 uint16_t y = 0 ;
128194 uint16_t z = 0 ;
129195
130196 Calibration cal;
131- };
132197
133- } // modm namespace
134-
135- # include " touch2046_impl.hpp "
198+ Orientation orientation = Orientation::Portrait90;
199+ };
200+ } // namespace modm
136201
137- #endif // MODM_TOUCH2046_HPP
202+ #include " touch2046_impl.hpp "
0 commit comments