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>
1922
20- #include < array>
21- #include < tuple>
23+ #include < modm/ui/display/graphic_display.hpp>
2224
2325namespace modm
2426{
2527
2628// / \ingroup modm_driver_touch2046
2729struct touch2046 {
28- enum class Orientation {
29- Normal,
30- // ...
30+ enum class Control : uint8_t
31+ {
32+ START = Bit7, // 1: Marks the control byte
33+
34+ A2 = Bit6, // see enum class ChDiff / ChSingleEnd
35+ A1 = Bit5,
36+ A0 = Bit4,
37+
38+ MODE = Bit3, // see enum class Mode
39+ REF = Bit2, // see enum class Reference
40+
41+ PD1 = Bit1, // see enum class PowerDown
42+ PD0 = Bit0,
43+ };
44+ MODM_FLAGS8 (Control);
45+
46+ // Valid when Control::MODE is 0
47+ enum class ChDiff : uint8_t
48+ {
49+ Z1 = int (Control::A0) | int (Control::A1),
50+ Z2 = int (Control::A2),
51+ X = int (Control::A0) | int (Control::A2),
52+ Y = int (Control::A0)
3153 };
54+ typedef Configuration<Control_t, ChDiff, 0b111'0000 > ChDiff_t;
55+
56+ // Valid when Control::MODE is 1
57+ enum class ChSingleEnd : uint8_t
58+ {
59+ TEMP0 = 0 ,
60+ Y = int (Control::A0),
61+ VBAT = int (Control::A1),
62+ Z1 = int (Control::A0) | int (Control::A1),
63+ Z2 = int (Control::A2),
64+ X = int (Control::A0) | int (Control::A2),
65+ AUX = int (Control::A0) | int (Control::A1),
66+ TEMP1 = int (Control::A0) | int (Control::A1) | int (Control::A2)
67+ };
68+ typedef Configuration<Control_t, ChSingleEnd, 0b111'0000 > ChSingleEnd_t;
69+
70+ enum class Mode : uint8_t
71+ {
72+ Res_12Bit = 0 ,
73+ Res_8Bit = int (Control::MODE)
74+ };
75+ typedef Configuration<Control_t, Mode, 0b1 , 3 > Mode_t;
76+
77+ enum class Reference : uint8_t
78+ {
79+ Differential = 0 ,
80+ SingleEnded = int (Control::REF)
81+ };
82+ typedef Configuration<Control_t, Reference, 0b1 , 2 > Reference_t;
83+
84+ enum class PowerDown : uint8_t
85+ {
86+ Auto = 0 ,
87+ RefOff_AdcOn = int (Control::PD0),
88+ RefOn_AdcOff = int (Control::PD1),
89+ AlwaysOn = int (Control::PD0) | int (Control::PD1)
90+ };
91+ typedef Configuration<Control_t, PowerDown, 0b11 , 0 > PowerDown_t;
92+
3293
3394 /* *
3495 * Calibration values are used to calculate touch point
3596 * from raw values.
3697 *
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- *
4198 * isTouched() = bool(Z > ThresholdZ)
4299 *
43100 * X = (rawX * FactorX / 1000000) + OffsetX
44101 * limited to [0, MaxX]
45102 * Y = (rawY * FactorY / 1000000) + OffsetY
46103 * limited to [0, MaxY]
47- *
48- * Orientation (rotation, mirror) are applied after the
49- * above operations.
50104 */
105+
51106 struct Calibration
52107 {
108+ int32_t FactorX = 24 ;
53109 int16_t OffsetX = 0 ;
110+ int32_t FactorY = 24 ;
54111 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;
112+ uint16_t ThresholdZ = 1000 ;
61113 };
62114};
63115
64116/* *
65117 * \ingroup modm_driver_touch2046
66- * \author Raphael Lehmann
118+ * \author Raphael Lehmann, Thomas Sommer
67119 *
68120 * Datasheet TSC2046: https://www.ti.com/lit/ds/symlink/tsc2046.pdf
69121 */
70- template < class SpiMaster , class Cs >
122+ template < class SpiMaster , class Cs , int16_t Width, int16_t Height >
71123class Touch2046 : public touch2046 , public modm ::SpiDevice< SpiMaster >, protected modm::NestedResumable<3 >
72124{
73125public:
126+ Touch2046 ();
127+
128+ using Orientation = modm::glcd::Orientation;
129+
74130 /* *
75131 * Set calibration data
76132 *
@@ -81,14 +137,6 @@ class Touch2046 : public touch2046, public modm::SpiDevice< SpiMaster >, protect
81137 cal = calibration;
82138 }
83139
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-
92140 /* *
93141 * Is screen touched?
94142 *
@@ -98,40 +146,58 @@ class Touch2046 : public touch2046, public modm::SpiDevice< SpiMaster >, protect
98146 isTouched ();
99147
100148 /* *
101- * Get touch position
149+ * Get touch position as tuple
102150 *
103151 * \return Position (X, Y) of touch point.
104152 */
105153 modm::ResumableResult<std::tuple<uint16_t ,uint16_t >>
106154 getTouchPosition ();
107155
156+ /* *
157+ * Get touch position as modm::glcd::Point
158+ *
159+ * \return Point of touch point.
160+ */
161+ modm::ResumableResult<modm::glcd::Point>
162+ getTouchPoint ();
163+
164+ void setOrientation (Orientation orientation)
165+ { this ->orientation = orientation; }
166+
167+ Orientation getOrientation () const
168+ { return orientation; }
169+
108170private:
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 = {};
171+ modm::ResumableResult<void >
172+ updateZ ();
173+
174+ modm::ResumableResult<void >
175+ updateXY ();
176+
177+ static constexpr Control_t Measure = Control::START | Mode_t(Mode::Res_12Bit)
178+ | Reference_t(Reference::Differential) | PowerDown_t(PowerDown::RefOff_AdcOn);
179+
180+ static constexpr std::array<uint16_t , 8 > bufferWrite = {
181+ (Measure | ChDiff_t (ChDiff::Z1)).value ,
182+ ((Measure | ChDiff_t (ChDiff::Z2)) & ~PowerDown_t::mask ()).value ,
183+ (Measure | ChDiff_t (ChDiff::X)).value ,
184+ (Measure | ChDiff_t (ChDiff::Y)).value ,
185+ (Measure | ChDiff_t (ChDiff::X)).value ,
186+ (Measure | ChDiff_t (ChDiff::Y)).value ,
187+ (Measure | ChDiff_t (ChDiff::X)).value ,
188+ ((Measure | ChDiff_t (ChDiff::Y)) & ~PowerDown_t::mask ()).value
189+ };
190+ std::array<uint16_t , 7 > bufferRead = {};
125191
192+ public:
126193 uint16_t x = 0 ;
127194 uint16_t y = 0 ;
128195 uint16_t z = 0 ;
129196
130197 Calibration cal;
131- };
132198
133- } // modm namespace
134-
135- # include " touch2046_impl.hpp "
199+ Orientation orientation = Orientation::Portrait90;
200+ };
201+ } // namespace modm
136202
137- #endif // MODM_TOUCH2046_HPP
203+ #include " touch2046_impl.hpp "
0 commit comments