-
-
Notifications
You must be signed in to change notification settings - Fork 113
/
Copy pathChsc6540.cs
155 lines (130 loc) · 4.66 KB
/
Chsc6540.cs
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Device.I2c;
namespace Iot.Device.Chsc6540
{
/// <summary>
/// Chsc6540 touch screen.
/// </summary>
public class Chsc6540 : IDisposable
{
private const int MaxX = 320;
private const int MaxY = 280;
private I2cDevice _i2cDevice;
private byte[] _data = new byte[2];
private byte[] _readBuffer;
/// <summary>
/// <see cref="Chsc6540"/> I2C address.
/// </summary>
public const byte DefaultI2cAddress = 0x2E;
/// <summary>
/// Creates a new instance of the Chsc6540.
/// </summary>
/// <param name="i2cDevice">The I2C device used for communication.</param>
public Chsc6540(I2cDevice i2cDevice)
{
_i2cDevice = i2cDevice ?? throw new ArgumentException();
// create read buffer
_readBuffer = new byte[11];
}
/// <summary>
/// Sets the interrupt mode.
/// </summary>
/// <param name="modeLow">True to have int low when extending the report point otherwise when reporting point is not extended.</param>
public void SetInterruptMode(bool modeLow) => WriteByte(Register.InteruptOn, (byte)(modeLow ? 0x05A : 0x00));
/// <summary>
/// Gets the number of points detected.
/// </summary>
/// <returns>Number of points detected.</returns>
public byte GetNumberPoints() => ReadByte(Register.TD_STATUS);
/// <summary>
/// Read a <see cref="DoublePoints"/> from the controller.
/// </summary>
/// <returns>A <see cref="DoublePoints"/>.</returns>
public DoublePoints GetDoublePoints()
{
DoublePoints pt = new();
Read(Register.TD_STATUS, _readBuffer);
//Point pt = new();
if (_readBuffer[0] > 0 && _readBuffer[0] <= 2)
{
// touch reports 1 or 2 points so OK to process
// according to M5Stack driver no point trying to read the "weight" and
// "size" properties or using the built-in gestures as they are not working
int tempX = ((_readBuffer[1] << 8)
| _readBuffer[2]) & 0x0fff;
int tempY = ((_readBuffer[3] << 8)
| _readBuffer[4]) & 0x0fff;
// sanity check
if(tempX >= MaxX || tempY >= MaxY)
{
// invalid data, done here
return pt;
}
// fill point 1
pt.Point1 = new Point()
{
X = tempX,
Y = tempY
};
// check for touch left
if ((_readBuffer[3] >> 4) > 0)
{
pt.Point1.Event = Event.LiftUp;
}
else
{
pt.Point1.Event = Event.PressDown;
}
if (_readBuffer[0] == 2)
{
tempX = ((_readBuffer[7] << 8)
| _readBuffer[8]) & 0x0fff;
tempY = ((_readBuffer[9] << 8)
| _readBuffer[10]) & 0x0fff;
// sanity check
if (tempX < MaxX && tempY < MaxY)
{
// valid data for point 2
pt.Point2 = new Point()
{
X = tempX,
Y = tempY,
};
// check for touch left
if ((_readBuffer[3] >> 4) > 0)
{
pt.Point2.Event = Event.LiftUp;
}
}
}
}
return pt;
}
/// <summary>
/// Cleanup.
/// </summary>
public void Dispose()
{
_i2cDevice?.Dispose();
_i2cDevice = null!;
}
private byte ReadByte(Register reg)
{
_i2cDevice.WriteByte((byte)reg);
return _i2cDevice.ReadByte();
}
private void WriteByte(Register reg, byte data)
{
_data[0] = (byte)reg;
_data[1] = data;
_i2cDevice.Write(_data);
}
private void Read(Register reg, SpanByte data)
{
_i2cDevice.WriteByte((byte)reg);
_i2cDevice.Read(data);
}
}
}