|
@@ -12,6 +12,8 @@ class TinyOp(Enum):
|
12
|
12
|
noteOffOp = 3
|
13
|
13
|
setReadAddr = 4
|
14
|
14
|
writeOp = 5
|
|
15
|
+ setModeOp = 6
|
|
16
|
+ invalidOp = 7
|
15
|
17
|
|
16
|
18
|
|
17
|
19
|
class TinyRegAddr(Enum):
|
|
@@ -33,14 +35,14 @@ class TinyRegAddr(Enum):
|
33
|
35
|
kErrorCodeAddr = 15
|
34
|
36
|
|
35
|
37
|
class TinyConst(Enum):
|
36
|
|
- kRdRegSrcId = TinyRegAddr.kRdRegAddrAddr # 0
|
37
|
|
- kRdTableSrcId = TinyRegAddr.kRdTableAddrAddr # 1
|
38
|
|
- kRdEESrcId = TinyRegAddr.kRdEEAddrAddr # 2
|
|
38
|
+ kRdRegSrcId = TinyRegAddr.kRdRegAddrAddr.value # 0
|
|
39
|
+ kRdTableSrcId = TinyRegAddr.kRdTableAddrAddr.value # 1
|
|
40
|
+ kRdEESrcId = TinyRegAddr.kRdEEAddrAddr.value # 2
|
39
|
41
|
|
40
|
|
- kWrRegDstId = TinyRegAddr.kWrRegAddrAddr # 4
|
41
|
|
- kWrTableDstId = TinyRegAddr.kWrTableAddrAddr # 5
|
42
|
|
- kWrEEDstId = TinyRegAddr.kWrEEAddrAddr # 6
|
43
|
|
- kWrAddrFl = 0x08 # first avail bit above kWrEEAddr
|
|
42
|
+ kWrRegDstId = TinyRegAddr.kWrRegAddrAddr.value # 4
|
|
43
|
+ kWrTableDstId = TinyRegAddr.kWrTableAddrAddr.value # 5
|
|
44
|
+ kWrEEDstId = TinyRegAddr.kWrEEAddrAddr.value # 6
|
|
45
|
+ kWrAddrFl = 0x08 # first avail bit above kWrEEAddr
|
44
|
46
|
|
45
|
47
|
class SerialMsgId(Enum):
|
46
|
48
|
QUIT_MSG = 0xffff
|
|
@@ -174,6 +176,10 @@ class Picadae:
|
174
|
176
|
def write( self, i2c_addr, reg_addr, byteL ):
|
175
|
177
|
return self._send( 'w', i2c_addr, reg_addr, [ len(byteL) ] + byteL )
|
176
|
178
|
|
|
179
|
+ def call_op( self, midi_pitch, op_code, argL ):
|
|
180
|
+ return self.write( self._pitch_to_i2c_addr( midi_pitch ), op_code, argL )
|
|
181
|
+
|
|
182
|
+
|
177
|
183
|
def set_read_addr( self, i2c_addr, mem_id, addr ):
|
178
|
184
|
return self. write(i2c_addr, TinyOp.setReadAddr.value,[ mem_id, addr ])
|
179
|
185
|
|
|
@@ -205,9 +211,11 @@ class Picadae:
|
205
|
211
|
|
206
|
212
|
|
207
|
213
|
|
208
|
|
- def block_on_picadae_read( self, i2c_addr, mem_id, reg_addr, argL, byteOutN, time_out_ms ):
|
|
214
|
+ def block_on_picadae_read( self, midi_pitch, mem_id, reg_addr, byteOutN, time_out_ms ):
|
209
|
215
|
|
210
|
|
- result = self.set_read_addr( i2c_addr, mem_id, reg_addr )
|
|
216
|
+ i2c_addr = self._pitch_to_i2c_addr( midi_pitch )
|
|
217
|
+
|
|
218
|
+ result = self.set_read_addr( i2c_addr, mem_id, reg_addr )
|
211
|
219
|
|
212
|
220
|
if result:
|
213
|
221
|
result = self.read_request( i2c_addr, TinyOp.setReadAddr.value, byteOutN )
|
|
@@ -216,39 +224,40 @@ class Picadae:
|
216
|
224
|
result = self.block_on_serial_read( byteOutN, time_out_ms )
|
217
|
225
|
|
218
|
226
|
return result
|
219
|
|
-
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+ def block_on_picadae_read_reg( self, midi_pitch, reg_addr, byteOutN=1, time_out_ms=250 ):
|
|
230
|
+ return self.block_on_picadae_read( midi_pitch,
|
|
231
|
+ TinyRegAddr.kRdRegAddrAddr.value,
|
|
232
|
+ reg_addr,
|
|
233
|
+ byteOutN,
|
|
234
|
+ time_out_ms )
|
220
|
235
|
|
221
|
236
|
def note_on_vel( self, midi_pitch, midi_vel ):
|
222
|
|
- return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
223
|
|
- TinyOp.noteOnVelOp.value,
|
224
|
|
- [self._validate_vel(midi_vel)] )
|
225
|
|
-
|
|
237
|
+ return self.call_op( midi_pitch, TinyOp.noteOnVelOp.value, [self._validate_vel(midi_vel)] )
|
|
238
|
+
|
226
|
239
|
def note_on_us( self, midi_pitch, pulse_usec ):
|
227
|
|
- return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
228
|
|
- TinyOp.noteOnUsecOp.value,
|
229
|
|
- list(self._usec_to_coarse_and_fine(pulse_usec)) )
|
|
240
|
+ return self.call_op( midi_pitch, TinyOp.noteOnUsecOp.value, list(self._usec_to_coarse_and_fine(pulse_usec)) )
|
230
|
241
|
|
231
|
242
|
def note_off( self, midi_pitch ):
|
232
|
|
- return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
233
|
|
- TinyOp.noteOffOp.value,
|
|
243
|
+ return self.call_op( midi_pitch, TinyOp.noteOffOp.value,
|
234
|
244
|
[0] ) # TODO: sending a dummy byte because we can't handle sending a command with no data bytes.
|
235
|
245
|
|
236
|
246
|
def set_velocity_map( self, midi_pitch, midi_vel, pulse_usec ):
|
237
|
|
- pass
|
|
247
|
+ coarse,fine = self._usec_to_coarse_and_fine( pulse_usec )
|
|
248
|
+ src = TinyConst.kWrAddrFl.value | TinyConst.kWrTableDstId.value
|
|
249
|
+ addr = midi_vel*2
|
|
250
|
+ return self.call_op( midi_pitch, TinyOp.writeOp.value, [ src, addr, coarse, fine ] )
|
238
|
251
|
|
239
|
252
|
def get_velocity_map( self, midi_pitch, midi_vel, time_out_ms=250 ):
|
240
|
|
- pass
|
|
253
|
+ byteOutN = 2
|
|
254
|
+ return self.block_on_picadae_read( midi_pitch, TinyConst.kRdTableSrcId.value, midi_vel*2, byteOutN, time_out_ms )
|
241
|
255
|
|
242
|
256
|
def set_pwm_duty( self, midi_pitch, duty_cycle_pct ):
|
243
|
|
- return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
244
|
|
- TinyOp.setPwmOp.value,
|
245
|
|
- [ int( duty_cycle_pct * 255.0 /100.0 )])
|
|
257
|
+ return self.call_op( midi_pitch, TinyOp.setPwmOp.value, [ int( duty_cycle_pct * 255.0 /100.0 )])
|
246
|
258
|
|
247
|
259
|
def get_pwm_duty( self, midi_pitch, time_out_ms=250 ):
|
248
|
|
- return self.block_on_picadae_read( self._pitch_to_i2c_addr( midi_pitch ),
|
249
|
|
- TinyRegAddr.kRdRegAddrAddr.value,
|
250
|
|
- TinyRegAddr.kPwmDutyAddr.value,
|
251
|
|
- [], 1, time_out_ms )
|
|
260
|
+ return self.block_on_picadae_read_reg( midi_pitch, TinyRegAddr.kPwmDutyAddr.value, time_out_ms=time_out_ms )
|
252
|
261
|
|
253
|
262
|
def set_pwm_freq( self, midi_pitch, freq_div_id ):
|
254
|
263
|
# pwm frequency divider 1=1,2=8,3=64,4=256,5=1024
|
|
@@ -256,15 +265,14 @@ class Picadae:
|
256
|
265
|
pass
|
257
|
266
|
|
258
|
267
|
def get_pwm_freq( self, midi_pitch, time_out_ms=250 ):
|
259
|
|
- return self.block_on_picadae_read( self._pitch_to_i2c_addr( midi_pitch ),
|
260
|
|
- TinyRegAddr.kRdRegAddrAddr.value,
|
261
|
|
- TinyRegAddr.kPwmFreqAddr.value,
|
262
|
|
- [], 1, time_out_ms )
|
263
|
|
-
|
264
|
|
- def set_flags( self, midi_pitch, flags ):
|
265
|
|
- return self.write( self._pitch_to_i2c_addr( midi_pitch ),
|
266
|
|
- TinyOp.writeOp.value,
|
267
|
|
- [ 12, 14, flags ])
|
|
268
|
+ return self.block_on_picadae_read_reg( midi_pitch, TinyRegAddr.kPwmFreqAddr.value, time_out_ms=time_out_ms )
|
|
269
|
+
|
|
270
|
+ def set_mode( self, midi_pitch, mode ):
|
|
271
|
+ # TODO validate mode value
|
|
272
|
+ return self.call_op( midi_pitch, TinyOp.setModeOp.value, [ mode ] )
|
|
273
|
+
|
|
274
|
+ def get_mode( self, midi_pitch, time_out_ms=250 ):
|
|
275
|
+ return self.block_on_picadae_read_reg( midi_pitch, TinyRegAddr.kModeAddr.value, time_out_ms=time_out_ms )
|
268
|
276
|
|
269
|
277
|
def make_note( self, midi_pitch, atk_us, dur_ms ):
|
270
|
278
|
# TODO: handle error on note_on_us()
|