@@ -122,6 +122,7 @@ def __init__(self, i2c, address=_DRV2605_ADDR):
122
122
# Default to internal trigger mode and TS2200 A library.
123
123
self .mode = MODE_INTTRIG
124
124
self .library = LIBRARY_TS2200A
125
+ self ._sequence = _DRV2605_Sequence (self )
125
126
126
127
def _read_u8 (self , address ):
127
128
# Read an 8-bit unsigned value from the specified 8-bit address.
@@ -196,6 +197,18 @@ def library(self, val):
196
197
raise ValueError ('Library must be a value within 0-6!' )
197
198
self ._write_u8 (_DRV2605_REG_LIBRARY , val )
198
199
200
+ @property
201
+ def sequence (self ):
202
+ """List-like sequence of waveform effects.
203
+ Get or set an effect waveform for slot 0-6 by indexing the sequence
204
+ property with the slot number. A slot must be set to either an Effect()
205
+ or Pause() class. See the datasheet for a complete table of effect ID
206
+ values and the associated waveform / effect.
207
+
208
+ E.g. 'slot_0_effect = drv.sequence[0]', 'drv.sequence[0] = Effect(88)'
209
+ """
210
+ return self ._sequence
211
+
199
212
def set_waveform (self , effect_id , slot = 0 ):
200
213
"""Select an effect waveform for the specified slot (default is slot 0,
201
214
but up to 7 effects can be combined with slot values 0 to 6). See the
@@ -219,3 +232,100 @@ def use_LRM(self):
219
232
"""Use a linear resonance actuator motor."""
220
233
feedback = self ._read_u8 (_DRV2605_REG_FEEDBACK )
221
234
self ._write_u8 (_DRV2605_REG_FEEDBACK , feedback | 0x80 )
235
+
236
+
237
+
238
+ class Effect :
239
+ """DRV2605 waveform sequence effect."""
240
+ def __init__ (self , effect_id ):
241
+ self ._effect_id = 0
242
+ # pylint: disable=invalid-name
243
+ self .id = effect_id
244
+
245
+ @property
246
+ def raw_value (self ):
247
+ """Raw effect ID."""
248
+ return self ._effect_id
249
+
250
+ @property
251
+ # pylint: disable=invalid-name
252
+ def id (self ):
253
+ """Effect ID."""
254
+ return self ._effect_id
255
+
256
+ @id .setter
257
+ # pylint: disable=invalid-name
258
+ def id (self , effect_id ):
259
+ """Set the effect ID."""
260
+ if not 0 <= effect_id <= 123 :
261
+ raise ValueError ('Effect ID must be a value within 0-123!' )
262
+ self ._effect_id = effect_id
263
+
264
+ def __repr__ (self ):
265
+ return "{}({})" .format (type (self ).__qualname__ , self .id )
266
+
267
+
268
+
269
+ class Pause :
270
+ """DRV2605 waveform sequence timed delay."""
271
+ def __init__ (self , duration ):
272
+ # Bit 7 must be set for a slot to be interpreted as a delay
273
+ self ._duration = 0x80
274
+ self .duration = duration
275
+
276
+ @property
277
+ def raw_value (self ):
278
+ """Raw pause duration."""
279
+ return self ._duration
280
+
281
+ @property
282
+ def duration (self ):
283
+ """Pause duration in seconds."""
284
+ # Remove wait time flag bit and convert duration to seconds
285
+ return (self ._duration & 0x7f ) / 100.0
286
+
287
+ @duration .setter
288
+ def duration (self , duration ):
289
+ """Set the pause duration in seconds."""
290
+ if not 0.0 <= duration <= 1.27 :
291
+ raise ValueError ('Pause duration must be a value within 0.0-1.27!' )
292
+ # Add wait time flag bit and convert duration to centiseconds
293
+ self ._duration = 0x80 | round (duration * 100.0 )
294
+
295
+ def __repr__ (self ):
296
+ return "{}({})" .format (type (self ).__qualname__ , self .duration )
297
+
298
+
299
+
300
+ class _DRV2605_Sequence :
301
+ """Class to enable List-like indexing of the waveform sequence slots."""
302
+ def __init__ (self , DRV2605_instance ):
303
+ self ._drv2605 = DRV2605_instance
304
+
305
+ def __setitem__ (self , slot , effect ):
306
+ """Write an Effect or Pause to a slot."""
307
+ if not 0 <= slot <= 6 :
308
+ raise IndexError ('Slot must be a value within 0-6!' )
309
+ if not isinstance (effect , (Effect , Pause )):
310
+ raise TypeError ('Effect must be either an Effect() or Pause()!' )
311
+ # pylint: disable=protected-access
312
+ self ._drv2605 ._write_u8 (_DRV2605_REG_WAVESEQ1 + slot , effect .raw_value )
313
+
314
+ def __getitem__ (self , slot ):
315
+ """Read an effect ID from a slot. Returns either a Pause or Effect class."""
316
+ if not 0 <= slot <= 6 :
317
+ raise IndexError ('Slot must be a value within 0-6!' )
318
+ # pylint: disable=protected-access
319
+ slot_contents = self ._drv2605 ._read_u8 (_DRV2605_REG_WAVESEQ1 + slot )
320
+ if slot_contents & 0x80 :
321
+ return Pause ((slot_contents & 0x7f ) / 100.0 )
322
+ return Effect (slot_contents )
323
+
324
+ def __iter__ (self ):
325
+ """Return an iterator over the waveform sequence slots."""
326
+ for slot in range (0 , 7 ):
327
+ yield self [slot ]
328
+
329
+ def __repr__ (self ):
330
+ """Return a string representation of all slot's effects."""
331
+ return repr ([effect for effect in self ])
0 commit comments