@@ -89,9 +89,9 @@ freq_hop_sel_t selfcap_freq_hops[3u] = {DEF_SELFCAP_HOP_FREQS};
89
89
* the elements of this structure. DO NOT modify any of the input values
90
90
* directly in this structure.
91
91
*/
92
- static touch_selfcap_config_t selfcap_config = {
93
- DEF_SELFCAP_NUM_CHANNELS , /* Self Cap number of channels. */
94
- DEF_SELFCAP_NUM_SENSORS , /* Self Cap number of sensors. */
92
+ touch_selfcap_config_t selfcap_config = {
93
+ 0 , /* Self Cap number of channels. */
94
+ 0 , /* Self Cap number of sensors. */
95
95
DEF_SELFCAP_NUM_ROTORS_SLIDERS , /* Self Cap number of rotors and
96
96
* sliders. */
97
97
@@ -181,58 +181,87 @@ touch_config_t touch_config = {
181
181
DEF_TOUCH_PTC_ISR_LVL , /* PTC interrupt level. */
182
182
};
183
183
184
- bool ptc_initialized = false;
184
+ nativeio_touchin_obj_t * active_touchin_obj [DEF_SELFCAP_NUM_CHANNELS ];
185
+
185
186
void common_hal_nativeio_touchin_construct (nativeio_touchin_obj_t * self ,
186
187
const mcu_pin_obj_t * pin ) {
187
188
if (!pin -> has_touch ) {
188
189
// No ADC function on that pin
189
190
nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "pin %q does not have touch capabilities" , pin -> name ));
190
191
}
191
192
192
- touch_ret_t status ;
193
- if (!ptc_initialized ) {
194
- /* Setup and enable generic clock source for PTC module. */
195
- struct system_gclk_chan_config gclk_chan_conf ;
196
- system_gclk_chan_get_config_defaults (& gclk_chan_conf );
197
- gclk_chan_conf .source_generator = GCLK_GENERATOR_1 ;
198
- system_gclk_chan_set_config (PTC_GCLK_ID , & gclk_chan_conf );
199
- system_gclk_chan_enable (PTC_GCLK_ID );
200
- system_apb_clock_set_mask (SYSTEM_CLOCK_APB_APBC , PM_APBCMASK_PTC );
201
-
202
- /* Initialize touch library for Self Cap operation. */
203
- status = touch_selfcap_sensors_init_with_rs_table (& touch_config ,
204
- PRIV_SELFCAP_RS_TABLE_INIT , PRIV_NM_TABLE_INIT ,
205
- PRIV_FREQ_AUTO_TUNE_CHK , PRIV_MOIS_TOLERANCE_CHK );
206
- if (status != TOUCH_SUCCESS ) {
207
- nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "Touch init failed (%d)" , status ));
193
+ if (selfcap_config .num_channels > 0 ) {
194
+ // Deinit the touch sensor, we're going to reinitialize it.
195
+ touch_selfcap_sensors_deinit ();
196
+
197
+ // Remove holes in the active list from sensors that may have been
198
+ // disabled.
199
+ int first_hole = -1 ;
200
+ for (int i = 0 ; i < selfcap_config .num_channels ; i ++ ) {
201
+ if (active_touchin_obj [i ] == NULL && first_hole == -1 ) {
202
+ first_hole = i ;
203
+ } else if (active_touchin_obj [i ] != NULL && first_hole != -1 ) {
204
+ active_touchin_obj [first_hole ] = active_touchin_obj [i ];
205
+ first_hole = i ;
206
+ }
208
207
}
209
- ptc_initialized = true;
210
- }
211
- // Map Y line to channel. Boards can switch the order.
212
- int channel ;
213
- for (channel = 0 ; channel < DEF_SELFCAP_NUM_CHANNELS ; channel ++ ) {
214
- if (selfcap_y_nodes [channel ] == Y (pin -> touch_y_line )) {
215
- break ;
208
+ if (first_hole > -1 ) {
209
+ selfcap_config .num_channels = first_hole ;
210
+ selfcap_config .num_sensors = first_hole ;
216
211
}
217
212
}
218
- if (channel == DEF_SELFCAP_NUM_CHANNELS ) {
219
- nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "Pin %q on this board does not have touch capabilities" , pin -> name ));
220
- }
221
- status = touch_selfcap_sensor_config (SENSOR_TYPE_KEY , channel , channel ,
222
- NO_AKS_GROUP , 10u , HYST_25 , RES_8_BIT , & self -> sensor_id );
213
+
214
+ // Add our sensor to the end of the list.
215
+ self -> pin = pin ;
216
+ selfcap_y_nodes [selfcap_config .num_channels ++ ] = Y (pin -> touch_y_line );
217
+ active_touchin_obj [selfcap_config .num_sensors ++ ] = self ;
218
+
219
+ /* Setup and enable generic clock source for PTC module. */
220
+ struct system_gclk_chan_config gclk_chan_conf ;
221
+ system_gclk_chan_get_config_defaults (& gclk_chan_conf );
222
+ gclk_chan_conf .source_generator = GCLK_GENERATOR_1 ;
223
+ system_gclk_chan_set_config (PTC_GCLK_ID , & gclk_chan_conf );
224
+ system_gclk_chan_enable (PTC_GCLK_ID );
225
+ system_apb_clock_set_mask (SYSTEM_CLOCK_APB_APBC , PM_APBCMASK_PTC );
226
+
227
+ touch_ret_t status ;
228
+ /* Initialize touch library for Self Cap operation. */
229
+ status = touch_selfcap_sensors_init_with_rs_table (& touch_config ,
230
+ PRIV_SELFCAP_RS_TABLE_INIT , PRIV_NM_TABLE_INIT ,
231
+ PRIV_FREQ_AUTO_TUNE_CHK , PRIV_MOIS_TOLERANCE_CHK );
223
232
if (status != TOUCH_SUCCESS ) {
224
- nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "Touch pad config failed (%d)" , status ));
233
+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "Touch init failed (%d)" , status ));
234
+ }
235
+ for (int i = 0 ; i < selfcap_config .num_channels ; i ++ ) {
236
+ status = touch_selfcap_sensor_config (SENSOR_TYPE_KEY , i , i ,
237
+ NO_AKS_GROUP , 10u , HYST_25 , RES_8_BIT , & active_touchin_obj [i ]-> sensor_id );
238
+ if (status != TOUCH_SUCCESS ) {
239
+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "Touch pad config failed (%d)" , status ));
240
+ }
225
241
}
226
242
status = touch_selfcap_sensors_calibrate (AUTO_TUNE_RSEL );
227
243
if (status != TOUCH_SUCCESS ) {
228
244
nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "Touch pad calibration failed (%d)" , status ));
229
245
}
230
246
231
- self -> pin = pin ;
247
+ // Run a measurement to get calibrated.
248
+ common_hal_nativeio_touchin_get_value (self );
232
249
}
233
250
251
+ // This may get called twice, once on exit or deinit and once from the finaliser
252
+ // (__del__). We need the finaliser to reduce the chance of us writing to memory
253
+ // we no longer own because we keep track of Python pointers in active_touchin_obj.
234
254
void common_hal_nativeio_touchin_deinit (nativeio_touchin_obj_t * self ) {
235
255
touch_selfcap_sensor_disable (self -> sensor_id );
256
+ // Remove ourselves from the list of active objects. We don't change the
257
+ // selfcap settings at all because we don't want to reinit now. Instead,
258
+ // we'll collect blank spots later on reinit.
259
+ for (int i = 0 ; i < DEF_SELFCAP_NUM_CHANNELS ; i ++ ) {
260
+ if (active_touchin_obj [i ] == self ) {
261
+ active_touchin_obj [i ] = NULL ;
262
+ break ;
263
+ }
264
+ }
236
265
}
237
266
238
267
volatile bool touch_read_ready = false;
@@ -263,12 +292,15 @@ bool common_hal_nativeio_touchin_get_value(nativeio_touchin_obj_t *self) {
263
292
264
293
while (!touch_read_ready && ticks_ms - start_ticks < 1000 ) {
265
294
// wait
295
+ #ifdef MICROPY_VM_HOOK_LOOP
296
+ MICROPY_VM_HOOK_LOOP
297
+ #endif
266
298
}
267
299
}
268
300
269
301
if (touch_acq_status & TOUCH_BURST_AGAIN ) {
270
302
nlr_raise (mp_obj_new_exception_msg (& mp_type_OSError , "Touch read failed" ));
271
303
}
272
304
273
- return (p_selfcap_measure_data -> p_sensor_states [self -> sensor_id / 8 ] & (1 << (self -> sensor_id % 8 ))) == 1 ;
305
+ return (p_selfcap_measure_data -> p_sensor_states [self -> sensor_id / 8 ] & (1 << (self -> sensor_id % 8 ))) != 0 ;
274
306
}
0 commit comments