2
2
import micropython # NOQA
3
3
import machine # NOQA
4
4
import pointer_framework
5
- import _thread
6
- import spi as _spi
5
+ import time
6
+ import array
7
7
8
8
9
9
_INT_ON_PD0_BIT = const (0x01 )
12
12
_VREF_ON_PD1_BIT = const (0x02 )
13
13
_VREF_OFF_PD1_BIT = const (0x00 )
14
14
15
-
16
15
_CMD_X_READ = const (0xD0 )
17
16
_CMD_Y_READ = const (0x90 )
18
17
_MIN_RAW_COORD = const (10 )
@@ -33,31 +32,37 @@ class XPT2046(pointer_framework.PointerDriver):
33
32
def __init__ (
34
33
self ,
35
34
spi_bus ,
36
- freq = 1000000 ,
37
- cs = - 1 ,
38
- interrupt = - 1 ,
35
+ cs = None ,
36
+ interrupt = None ,
39
37
vref_on = False ,
40
38
press_threshold = 400 ,
41
39
touch_cal = None
42
40
):
43
41
super ().__init__ (touch_cal = touch_cal )
44
- self ._trans_mv = _spi .get_dma_buffer (1 )
45
- self ._recv_mv = _spi .get_dma_buffer (2 )
42
+ self ._trans_buf = bytearray (2 )
43
+ self ._trans_mv = memoryview (self ._trans_buf )
44
+
45
+ self ._recv_buf = bytearray (2 )
46
+ self ._recv_mv = memoryview (self ._recv_buf )
46
47
47
- self ._on_schedule_ref = self ._on_schedule
48
48
self ._press_threshold = press_threshold
49
+ self .__read_last = False
50
+ self .__int_running = False
51
+
52
+ if interrupt is not None :
53
+ self ._on_schedule_ref = self ._on_schedule
54
+ self .__last_coords = array .array ('i' , [- 1 , 0 , 0 ])
49
55
50
- if interrupt != - 1 :
51
56
PD0_BIT = _INT_ON_PD0_BIT
52
57
interrupt = machine .Pin (interrupt , machine .Pin .IN )
58
+
53
59
interrupt .irq (
54
60
trigger = machine .Pin .IRQ_FALLING ,
55
61
handler = self ._on_interrupt
56
62
)
57
63
58
- self ._set_mode_event () # NOQA
64
+ self ._set_mode_event ()
59
65
else :
60
- interrupt = None
61
66
PD0_BIT = _INT_OFF_PD0_BIT
62
67
63
68
self ._interrupt = interrupt
@@ -77,73 +82,96 @@ def __init__(
77
82
# self._AUX_IN = const(0xE6)
78
83
# self._TEMP0 = const(0x86)
79
84
# self._TEMP1 = const(0xF6)
80
-
81
- self ._spi = _spi .Device (
82
- spi_bus = spi_bus ,
83
- freq = freq ,
84
- cs = cs
85
- )
86
-
87
- self ._lock = _thread .allocate_lock ()
85
+ self ._spi = spi_bus
86
+ if cs is not None :
87
+ self .__cs = machine .Pin (cs , machine .Pin .OUT )
88
+ self .__cs .value (1 )
89
+ else :
90
+ self .__cs = None
88
91
89
92
def _read_reg (self , reg ):
90
- self ._lock .acquire ()
93
+ self ._trans_buf [0 ] = reg
94
+ self ._recv_buf [0 ] = 0x00
95
+ self ._recv_buf [1 ] = 0x00
91
96
92
- def _callback ( * _ ) :
93
- self ._lock . release ( )
97
+ if self . __cs is not None :
98
+ self .__cs . value ( 0 )
94
99
95
- self ._recv_mv [0 ] = 0x00
96
- self ._recv_mv [1 ] = 0x00
97
- self ._spi .comm (
98
- cmd = reg ,
99
- cmd_bits = 8 ,
100
- rx_data = self ._recv_mv ,
101
- callback = _callback
102
- )
100
+ self ._spi .write_readinto (self ._trans_mv , self ._recv_mv )
103
101
104
- self ._lock .acquire ()
105
- self ._lock .release ()
106
- return (self ._recv_mv [0 ] << 8 ) | self ._recv_mv [1 ]
102
+ if self .__cs is not None :
103
+ self .__cs .value (1 )
104
+
105
+ return (self ._recv_buf [0 ] << 8 ) | self ._recv_buf [1 ]
107
106
108
107
def _on_schedule (self , * _ ):
108
+ self .__read_last = True
109
109
self .read ()
110
110
111
- def _on_interrupt (self , _ ):
112
- micropython .schedule (self ._on_schedule_ref , None )
111
+ def _on_interrupt (self , pin ):
112
+ if not pin .value () and not self .__int_running :
113
+ self .__int_running = True
114
+
115
+ coords = self ._get_coords ()
116
+ if coords is not None :
117
+ (
118
+ self .__last_coords [0 ],
119
+ self .__last_coords [1 ],
120
+ self .__last_coords [2 ]
121
+ ) = coords
122
+ micropython .schedule (self ._on_schedule_ref , None )
123
+
124
+ time .sleep_ms (100 )
125
+ elif pin .value () and self .__int_running :
126
+ time .sleep_ms (100 ) # Debounce rising edge
127
+ self .__int_running = False # Unlock interrupt
113
128
114
129
def _get_coords (self ):
115
- z1 = self ._read_reg (self ._Z_VALUE_1 )
116
- z2 = self ._read_reg (self ._Z_VALUE_2 )
130
+ if self .__read_last and not self .__int_running :
131
+ self .__read_last = False
132
+ if self .__last_coords [0 ] == - 1 :
133
+ return None
134
+
135
+ state = self .__last_coords [0 ]
136
+ x = self .__last_coords [1 ]
137
+ y = self .__last_coords [2 ]
138
+
139
+ self .__last_coords [0 ] = - 1
140
+ else :
141
+ z1 = self ._read_reg (self ._Z_VALUE_1 )
142
+ z2 = self ._read_reg (self ._Z_VALUE_2 )
117
143
118
- z = (z1 >> 3 ) + (_MAX_RAW_COORD - (z2 >> 3 ))
144
+ z = (z1 >> 3 ) + (_MAX_RAW_COORD - (z2 >> 3 ))
119
145
120
- if z < self ._press_threshold :
121
- return None
146
+ if z < self ._press_threshold :
147
+ return None
122
148
123
- # dump first reading
124
- self ._read_reg (self ._X_POSITION )
149
+ # dump first reading
150
+ self ._read_reg (self ._X_POSITION )
125
151
126
- x_points = []
127
- y_points = []
152
+ x_points = []
153
+ y_points = []
128
154
129
- for _ in range (3 ):
130
- x = self ._read_reg (self ._X_POSITION ) >> 3
131
- y = self ._read_reg (self ._Y_POSITION ) >> 3
155
+ for _ in range (3 ):
156
+ x = self ._read_reg (self ._X_POSITION ) >> 3
157
+ y = self ._read_reg (self ._Y_POSITION ) >> 3
132
158
133
- if (
134
- (_MIN_RAW_COORD <= x <= _MAX_RAW_COORD ) or
135
- (_MIN_RAW_COORD <= y <= _MAX_RAW_COORD )
136
- ):
137
- x = int ((x / float (_MAX_RAW_COORD )) * self ._orig_width ) # NOQA
138
- y = int ((y / float (_MAX_RAW_COORD )) * self ._orig_height ) # NOQA
159
+ if (
160
+ (_MIN_RAW_COORD <= x <= _MAX_RAW_COORD ) or
161
+ (_MIN_RAW_COORD <= y <= _MAX_RAW_COORD )
162
+ ):
163
+ x = int ((x / float (_MAX_RAW_COORD )) * self ._orig_width )
164
+ y = int ((y / float (_MAX_RAW_COORD )) * self ._orig_height )
139
165
140
- x_points .append (x )
141
- y_points .append (y )
166
+ x_points .append (x )
167
+ y_points .append (y )
142
168
143
- if x_points and y_points :
144
- x = int (sum (x_points ) / len (x_points ))
145
- y = int (sum (y_points ) / len (y_points ))
169
+ if x_points and y_points :
170
+ x = int (sum (x_points ) / len (x_points ))
171
+ y = int (sum (y_points ) / len (y_points ))
146
172
147
- return self .PRESSED , x , y
173
+ state = self .PRESSED
174
+ else :
175
+ return None
148
176
149
- return None
177
+ return state , x , y
0 commit comments