2 Incheckningar

Upphovsman SHA1 Meddelande Datum
  kevin 5008c67002 app/picadae_api.py, picadae_shell.py : Added set/get_hold_delay(). Fixed shell._read(). 3 år sedan
  kevin 78e533a61f tiny/i2c_timer_pwm.c : Added hold delay and other changes to validate operation after logic analyzer analysis. 3 år sedan
3 ändrade filer med 148 tillägg och 65 borttagningar
  1. 29
    2
      control/app/picadae_api.py
  2. 23
    21
      control/app/picadae_shell.py
  3. 96
    42
      control/tiny/i2c_timer_pwm.c

+ 29
- 2
control/app/picadae_api.py Visa fil

16
     setReadAddr  = 4
16
     setReadAddr  = 4
17
     writeOp      = 5
17
     writeOp      = 5
18
     writeTableOp = 6
18
     writeTableOp = 6
19
-    invalidOp    = 7
19
+    holdDelayOp  = 7
20
+    invalidOp    = 8
20
     
21
     
21
 
22
 
22
 class TinyRegAddr(Enum):
23
 class TinyRegAddr(Enum):
36
     kPwmDivAddr      = 13
37
     kPwmDivAddr      = 13
37
     kStateAddr       = 14
38
     kStateAddr       = 14
38
     kErrorCodeAddr   = 15
39
     kErrorCodeAddr   = 15
40
+    kMaxAllowTmrAddr = 16
41
+    kDelayCoarseAddr = 17
42
+    kDelayFineAddr   = 18
39
 
43
 
40
 class TinyConst(Enum):
44
 class TinyConst(Enum):
41
     kRdRegSrcId    = TinyRegAddr.kRdRegAddrAddr.value    # 0
45
     kRdRegSrcId    = TinyRegAddr.kRdRegAddrAddr.value    # 0
184
         return self.write_tiny_reg( self._pitch_to_i2c_addr( midi_pitch ), op_code, argL )                          
188
         return self.write_tiny_reg( self._pitch_to_i2c_addr( midi_pitch ), op_code, argL )                          
185
 
189
 
186
     def set_read_addr( self, i2c_addr, mem_id, addr ):
190
     def set_read_addr( self, i2c_addr, mem_id, addr ):
191
+        # mem_id: 0=reg_array 1=vel_table 2=eeprom
187
         return self.write_tiny_reg(i2c_addr, TinyOp.setReadAddr.value,[ mem_id, addr ])
192
         return self.write_tiny_reg(i2c_addr, TinyOp.setReadAddr.value,[ mem_id, addr ])
188
                 
193
                 
189
     def read_request( self, i2c_addr, reg_addr, byteOutN ):
194
     def read_request( self, i2c_addr, reg_addr, byteOutN ):
246
         return self.call_op( midi_pitch, TinyOp.noteOffOp.value,
251
         return self.call_op( midi_pitch, TinyOp.noteOffOp.value,
247
                            [0] )  # TODO: sending a dummy byte because we can't handle sending a command with no data bytes.
252
                            [0] )  # TODO: sending a dummy byte because we can't handle sending a command with no data bytes.
248
 
253
 
254
+    def set_hold_delay( self, midi_pitch, pulse_usec ):
255
+        return  self.call_op( midi_pitch, TinyOp.holdDelayOp.value, list(self._usec_to_coarse_and_fine(pulse_usec)) )
256
+
257
+    def get_hold_delay( self, midi_pitch, time_out_ms=250 ):
258
+
259
+        res = self.block_on_picadae_read_reg( midi_pitch, TinyRegAddr.kDelayCoarseAddr.value, byteOutN=2, time_out_ms=time_out_ms )
260
+
261
+        if len(res.value) == 2:
262
+            res.value = [ self.prescaler_usec*255*res.value[0] + self.prescaler_usec*res.value[1] ]
263
+        
264
+        return res
265
+        
266
+    
249
     def set_velocity_map( self, midi_pitch, midi_vel, pulse_usec ):
267
     def set_velocity_map( self, midi_pitch, midi_vel, pulse_usec ):
250
         coarse,fine = self._usec_to_coarse_and_fine( pulse_usec )
268
         coarse,fine = self._usec_to_coarse_and_fine( pulse_usec )
251
         src         = TinyConst.kWrAddrFl.value | TinyConst.kWrTableDstId.value
269
         src         = TinyConst.kWrAddrFl.value | TinyConst.kWrTableDstId.value
258
 
276
 
259
     def set_pwm_duty( self, midi_pitch, duty_cycle_pct ):
277
     def set_pwm_duty( self, midi_pitch, duty_cycle_pct ):
260
         if 0 <= duty_cycle_pct and duty_cycle_pct <= 100:
278
         if 0 <= duty_cycle_pct and duty_cycle_pct <= 100:
261
-            duty_cycle_pct = 100.0 - duty_cycle_pct
279
+            # duty_cycle_pct = 100.0 - duty_cycle_pct
262
             return self.call_op( midi_pitch, TinyOp.setPwmOp.value, [ int( duty_cycle_pct * 255.0 /100.0 )])
280
             return self.call_op( midi_pitch, TinyOp.setPwmOp.value, [ int( duty_cycle_pct * 255.0 /100.0 )])
263
         else:
281
         else:
264
             return Result(msg="Duty cycle (%f) out of range 0-100." % (duty_cycle_pct))
282
             return Result(msg="Duty cycle (%f) out of range 0-100." % (duty_cycle_pct))
279
     def get_pwm_div( self, midi_pitch, time_out_ms=250 ):
297
     def get_pwm_div( self, midi_pitch, time_out_ms=250 ):
280
         return self.block_on_picadae_read_reg( midi_pitch, TinyRegAddr.kPwmDivAddr.value, time_out_ms=time_out_ms )
298
         return self.block_on_picadae_read_reg( midi_pitch, TinyRegAddr.kPwmDivAddr.value, time_out_ms=time_out_ms )
281
 
299
 
300
+    def set_pwm_div( self, midi_pitch, div, time_out_ms=250 ):
301
+        res = self.get_pwm_duty( midi_pitch )
302
+        if res:
303
+            duty = res.value[0]
304
+            res = self.get_pwm_freq( midi_pitch )
305
+            if res:
306
+                res = self.call_op( midi_pitch, TinyOp.setPwmOp.value, [ int(duty), int(res.value[0]), int(div) ])
307
+        return res
308
+    
282
     def write_table( self, midi_pitch, time_out_ms=250 ):
309
     def write_table( self, midi_pitch, time_out_ms=250 ):
283
         # TODO: sending a dummy byte because we can't handle sending a command with no data bytes.
310
         # TODO: sending a dummy byte because we can't handle sending a command with no data bytes.
284
         return self.call_op( midi_pitch, TinyOp.writeTableOp.value,[0])
311
         return self.call_op( midi_pitch, TinyOp.writeTableOp.value,[0])

+ 23
- 21
control/app/picadae_shell.py Visa fil

10
     def __init__( self, cfg ):
10
     def __init__( self, cfg ):
11
         self.p      = None
11
         self.p      = None
12
         self.parseD = {
12
         self.parseD = {
13
-            'q':{ "func":None,           "minN":0,  "maxN":0, "help":"quit"},
14
-            '?':{ "func":"_help",        "minN":0,  "maxN":0, "help":"Print usage text."},
15
-            'w':{ "func":"_write",       "minN":-1, "maxN":-1,"help":"write <i2c_addr> <reg_addr> <data0> ... <dataN>"},
16
-            'r':{ "func":"_read",        "minN":4,  "maxN":4, "help":"read  <i2c_addr> <src> <reg_addr> <byteN>"},
17
-            'v':{ "func":"note_on_vel",  "minN":2,  "maxN":2, "help":"note-on <pitch> <vel>"},
18
-            'u':{ "func":"note_on_us",   "minN":2,  "maxN":3, "help":"note-on <pitch> <usec> <prescale> (1=1, 2=8, 3=64,(4)=256 16us, 5=1024)"},
19
-            'o':{ "func":"note_off",     "minN":1,  "maxN":1, "help":"note-off <pitch>"},
20
-            'T':{ "func":"set_vel_map",  "minN":3,  "maxN":3, "help":"table <pitch> <vel> <usec>"},
21
-            't':{ "func":"get_vel_map",  "minN":2,  "maxN":2, "help":"table <pitch> <vel>"},
22
-            'D':{ "func":"set_pwm_duty", "minN":2,  "maxN":4, "help":"duty <pitch> <percent> {<hz> {<div>}} " },
23
-            'd':{ "func":"get_pwm_duty", "minN":1,  "maxN":1, "help":"duty <pitch>"},
24
-            'F':{ "func":"set_pwm_freq", "minN":2,  "maxN":2, "help":"freq <pitch> <hz> 254=~123Hz"},
25
-            'f':{ "func":"get_pwm_freq", "minN":1,  "maxN":1, "help":"freq <pitch>"},
26
-            'I':{ "func":"set_pwm_div",  "minN":2,  "maxN":2, "help":"div <pitch> <div> div:2=2,3=4,4=8,5=16,6=32,7=64,8=128,9=256,(10)=512 32us, 11=1024,12=2048,13=4096,14=8192,15=16384"},
27
-            'i':{ "func":"get_pwm_div",  "minN":1,  "maxN":1, "help":"div <pitch>"},
28
-            'W':{ "func":"write_table",  "minN":1,  "maxN":1, "help":"write_table <pitch>"},
29
-            'N':{ "func":"make_note",    "minN":3,  "maxN":3, "help":"note <pitch> <atkUs> <durMs>"},
30
-            'S':{ "func":"make_seq",     "minN":5,  "maxN":5, "help":"seq  <pitch> <atkUs> <durMs> <deltaUs> <note_count>"}, 
31
-            'L':{ "func":"set_log_level","minN":1,  "maxN":1, "help":"log <level> (0-1)."}
13
+            'q':{ "func":None,             "minN":0,  "maxN":0, "help":"quit"},
14
+            '?':{ "func":"_help",          "minN":0,  "maxN":0, "help":"Print usage text."},
15
+            'w':{ "func":"_write",         "minN":-1, "maxN":-1,"help":"write <i2c_addr> <reg_addr> <data0> ... <dataN>"},
16
+            'r':{ "func":"_read",          "minN":4,  "maxN":4, "help":"read  <i2c_addr> <src> <reg_addr> <byteN>   src: 0=reg_array 1=vel_table 2=eeprom"},
17
+            'v':{ "func":"note_on_vel",    "minN":2,  "maxN":2, "help":"note-on <pitch> <vel>"},
18
+            'u':{ "func":"note_on_us",     "minN":2,  "maxN":3, "help":"note-on <pitch> <usec> <prescale> (1=1, 2=8 .5us, 3=64 4us,(4)=256 16us, 5=1024 64us)"},
19
+            'o':{ "func":"note_off",       "minN":1,  "maxN":1, "help":"note-off <pitch>"},
20
+            'T':{ "func":"set_vel_map",    "minN":3,  "maxN":3, "help":"table <pitch> <vel> <usec>"},
21
+            't':{ "func":"get_vel_map",    "minN":2,  "maxN":2, "help":"table <pitch> <vel>"},
22
+            'D':{ "func":"set_pwm_duty",   "minN":2,  "maxN":4, "help":"duty <pitch> <percent> {<hz> {<div>}} " },
23
+            'd':{ "func":"get_pwm_duty",   "minN":1,  "maxN":1, "help":"duty <pitch>"},
24
+            'H':{ "func":"set_hold_delay", "minN":2,  "maxN":2, "help":"hold delay <pitch> <usec>"},
25
+            'h':{ "func":"get_hold_delay", "minN":1,  "maxN":1, "help":"hold delay <pitch>"},
26
+            'F':{ "func":"set_pwm_freq",   "minN":2,  "maxN":2, "help":"pwm freq <pitch> <hz> 254=~123Hz"},
27
+            'f':{ "func":"get_pwm_freq",   "minN":1,  "maxN":1, "help":"pwm freq <pitch>"},
28
+            'I':{ "func":"set_pwm_div",    "minN":2,  "maxN":2, "help":"pwm div <pitch> <div> div:2=2,3=4,4=8,(5)=16 1us,6=32,7=64,8=128,9=256,10=512 32us, 11=1024,12=2048,13=4096,14=8192,15=16384"},
29
+            'i':{ "func":"get_pwm_div",    "minN":1,  "maxN":1, "help":"pwm div <pitch>"},
30
+            'W':{ "func":"write_table",    "minN":1,  "maxN":1, "help":"write_table <pitch>"},
31
+            'N':{ "func":"make_note",      "minN":3,  "maxN":3, "help":"note <pitch> <atkUs> <durMs>"},
32
+            'S':{ "func":"make_seq",       "minN":5,  "maxN":5, "help":"seq  <pitch> <atkUs> <durMs> <deltaUs> <note_count>"}, 
33
+            'L':{ "func":"set_log_level",  "minN":1,  "maxN":1, "help":"log <level> (0-1)."}
32
             }
34
             }
33
 
35
 
34
     def _help( self, _=None ):
36
     def _help( self, _=None ):
40
     def _write( self, argL ):
42
     def _write( self, argL ):
41
         return self.p.write(argL[0], argL[1], argL[2:])
43
         return self.p.write(argL[0], argL[1], argL[2:])
42
     
44
     
43
-    def _read( self, argL ):
44
-        return self.p.block_on_picadae_read(argL[0], argL[1], argL[2], argL[3])
45
+    def _read( self, i2c_addr, src_id, reg_addr, byteN ):
46
+        return self.p.block_on_picadae_read(i2c_addr, src_id, reg_addr, byteN)
45
         
47
         
46
     def _syntaxError( self, msg ):
48
     def _syntaxError( self, msg ):
47
         print("Syntax Error: " + msg )
49
         print("Syntax Error: " + msg )

+ 96
- 42
control/tiny/i2c_timer_pwm.c Visa fil

44
  kNoteOff_Op        =  3,  // Turn off note         5
44
  kNoteOff_Op        =  3,  // Turn off note         5
45
  kSetReadAddr_Op    =  4,  // Set a read addr.      6 {<src>} {<addr>} }  src: 0=reg 1=table 2=eeprom
45
  kSetReadAddr_Op    =  4,  // Set a read addr.      6 {<src>} {<addr>} }  src: 0=reg 1=table 2=eeprom
46
  kWrite_Op          =  5,  // Set write             7 {<addrfl|src> {addr}  {<value0> ... {<valueN>}}  addrFl:0x80  src: 4=reg 5=table 6=eeprom
46
  kWrite_Op          =  5,  // Set write             7 {<addrfl|src> {addr}  {<value0> ... {<valueN>}}  addrFl:0x80  src: 4=reg 5=table 6=eeprom
47
- kWriteTable_Op     =  6,  // Write table to EEprom 9 
48
- kInvalid_Op        =  7   //                                             
47
+ kWriteTable_Op     =  6,  // Write table to EEprom 9
48
+ kHoldDelay_Op      =  7,  // Set hold delay          {<coarse> {<fine>}}
49
+ kInvalid_Op        =  8   //                                             
49
 };
50
 };
50
 
51
 
51
 
52
 
72
  kState_idx          = 14, // 1=attk 2=hold
73
  kState_idx          = 14, // 1=attk 2=hold
73
  kError_Code_idx     = 15, // Error Code
74
  kError_Code_idx     = 15, // Error Code
74
  kMax_Coarse_Tmr_idx = 16, // Max. allowable coarse timer value
75
  kMax_Coarse_Tmr_idx = 16, // Max. allowable coarse timer value
76
+
77
+ kDelay_Coarse_idx   = 17, // (17,18)=2000 (0,6)=100
78
+ kDelay_Fine_idx     = 18,
79
+ 
75
  kMax_idx
80
  kMax_idx
76
 };
81
 };
77
 
82
 
99
    4,                // 10 (1-5)    4=16us per tick
104
    4,                // 10 (1-5)    4=16us per tick
100
    
105
    
101
  127,                // 11 (0-255)  Pwm Duty cycle
106
  127,                // 11 (0-255)  Pwm Duty cycle
102
- 254,                // 12 (0-255)  Pwm Frequency  (123 Hz)
103
-  10,                // 13 (0-15)   Pwm clock div 
107
+ 255,                // 12 (0-255)  Pwm Frequency  (123 Hz)
108
+   5,                // 13 (0-15)   Pwm clock div 
104
    
109
    
105
    0,                // 14 state flags 1=attk   2=hold  (read/only)
110
    0,                // 14 state flags 1=attk   2=hold  (read/only)
106
    0,                // 15 (0-255)  Error bit field
111
    0,                // 15 (0-255)  Error bit field
107
    14,               // 16 (0-255) Max allowable coarse timer count
112
    14,               // 16 (0-255) Max allowable coarse timer count
113
+
114
+   0,                // 17 (0-255) Hold coarse delay  
115
+   6               // 18 (0-255) Hold fine delay    0,6=100us 0,124=2000us w/ 16us Tmr0 tick
116
+   
108
 };
117
 };
109
 
118
 
110
 // These registers are saved to Eeprom
119
 // These registers are saved to Eeprom
208
 #define clear_hold() PORTB &= ~(_BV(HOLD_PIN))
217
 #define clear_hold() PORTB &= ~(_BV(HOLD_PIN))
209
 #define set_hold()   PORTB |= _BV(HOLD_PIN)
218
 #define set_hold()   PORTB |= _BV(HOLD_PIN)
210
 
219
 
220
+
221
+void hold_begin()
222
+{
223
+  hold_state = 1;
224
+  
225
+  // Reset the PWM counter to to OCR1C (PWM TOP) so that it immediately triggers
226
+  // set_hold() and latches any new value for OCR1B (See: 12.2.2 Timer/Counter1 in PWM Mode)
227
+  // If this is not done and OCR1B was modified the first pulse will have the incorrect length.
228
+  TCNT1   = ctl_regs[kPwm_Freq_idx];  
229
+  TIMSK  |= _BV(OCIE1B) + _BV(TOIE1);    // PWM interupt Enable interrupts
230
+
231
+  TCCR1  |= ctl_regs[ kPwm_Div_idx];     // 32us period (512 divider) prescaler
232
+  GTCCR  |= _BV(PSR1);                   // Force the pre-scale to be latched by setting PSR1
233
+  
234
+}
235
+
236
+void hold_end()
237
+{
238
+  clear_hold();
239
+  TIMSK  &= ~_BV(OCIE0A);                // Clear timer interrupt (shouldn't be necessary but doesn't hurt on during note-off message)
240
+  TIMSK  &= ~(_BV(OCIE1B) + _BV(TOIE1)); // PWM interupt disable interrupts
241
+
242
+  TCCR1  = 0;              // Stop the PWM timer by setting the pre-scale to 0
243
+  GTCCR  |= _BV(PSR1);     // Force the pre-scale to be latched by setting PSR1
244
+  
245
+  hold_state = 0;
246
+}
247
+
211
 // Use the current tmr0 ctl_reg[] values to set the timer to the starting state.
248
 // Use the current tmr0 ctl_reg[] values to set the timer to the starting state.
212
 void tmr0_reset()
249
 void tmr0_reset()
213
 {
250
 {
216
   PORTB                |= _BV(ATTK_PIN);   // set the attack pin
253
   PORTB                |= _BV(ATTK_PIN);   // set the attack pin
217
   clear_hold();                            // clear the hold pin
254
   clear_hold();                            // clear the hold pin
218
   hold_state = 0;
255
   hold_state = 0;
256
+
257
+  tmr0_state = 1;
258
+  OCR0A      = 0xff;
219
   
259
   
260
+  /*
220
   // if a coarse count exists then go into coarse mode 
261
   // if a coarse count exists then go into coarse mode 
221
   if( ctl_regs[kTmr_Coarse_idx] > 0 )
262
   if( ctl_regs[kTmr_Coarse_idx] > 0 )
222
   {
263
   {
228
     tmr0_state = 2;
269
     tmr0_state = 2;
229
     OCR0A     = ctl_regs[kTmr_Fine_idx];
270
     OCR0A     = ctl_regs[kTmr_Fine_idx];
230
   }
271
   }
272
+  */
231
   
273
   
232
   TCNT0  = 0;
274
   TCNT0  = 0;
233
   TIMSK |= _BV(OCIE0A);     // enable the timer interrupt
275
   TIMSK |= _BV(OCIE0A);     // enable the timer interrupt
237
 {
279
 {
238
   switch( tmr0_state )
280
   switch( tmr0_state )
239
   {
281
   {
240
-    case 0:
241
-      // timer is disabled
282
+    case 0: // timer disabled
242
       break;
283
       break;
243
 
284
 
244
-    case 1: 
245
-      // coarse mode
246
-      if( ++tmr0_coarse_cur >= ctl_regs[kTmr_Coarse_idx] )
285
+    case 1: // attack coarse mode
286
+      // Note: the '+1' here is necessary to absorb an interrupt which is occurring
287
+      // for an unknown reason.  It must have something to do with resetting the
288
+      // OCIE0A interrupt because it doesn't occur on the hold delay coarse timing.
289
+      if( ++tmr0_coarse_cur >= ctl_regs[kTmr_Coarse_idx]+1 )
247
       {
290
       {
248
-        tmr0_state  = 2;
249
-        OCR0A     = ctl_regs[kTmr_Fine_idx];        
291
+        tmr0_state = 2;
292
+        OCR0A      = ctl_regs[kTmr_Fine_idx];        
250
       }
293
       }
251
       break;
294
       break;
252
 
295
 
253
-    case 2:
254
-      // fine mode
255
-
256
-      // This marks the end of a timer period 
257
-
296
+    case 2: // attack fine mode
258
       clear_attack();
297
       clear_attack();
259
 
298
 
260
-      TCNT1      = 0;   // reset the PWM counter to 0
261
-      hold_state = 1;   // enable the hold output
262
-      TIMSK  |= _BV(OCIE1B) + _BV(TOIE1);  // PWM interupt Enable interrupts          
263
-      TIMSK &= ~_BV(OCIE0A);               // clear timer interrupt
264
-      
299
+      // if a coarse delay count exists then go into coarse mode 
300
+      if( ctl_regs[kDelay_Coarse_idx] > 0 )
301
+      {
302
+        tmr0_state      = 3;
303
+        tmr0_coarse_cur = 0;
304
+        OCR0A           = 0xff;
305
+      }
306
+      else // otherwise go into fine mode
307
+      {
308
+        tmr0_state = 4;
309
+        OCR0A      = ctl_regs[kDelay_Fine_idx];
310
+      }
311
+      break;
312
+
313
+    case 3: // coarse hold delay
314
+      if( ++tmr0_coarse_cur >= ctl_regs[kDelay_Coarse_idx] )
315
+      {
316
+        tmr0_state = 4;
317
+        OCR0A      = ctl_regs[kDelay_Fine_idx];        
318
+      }      
265
       break;
319
       break;
320
+      
321
+    case 4: // hold delay end
322
+      TIMSK      &= ~_BV(OCIE0A);    // clear timer interrupt
323
+      tmr0_state  = 0;
324
+      hold_begin();
325
+      break;      
266
   }
326
   }
267
 }
327
 }
268
 
328
 
270
 void tmr0_init()
330
 void tmr0_init()
271
 {
331
 {
272
   TIMSK  &= ~_BV(OCIE0A);                 // Disable interrupt TIMER1_OVF
332
   TIMSK  &= ~_BV(OCIE0A);                 // Disable interrupt TIMER1_OVF
333
+  TCCR0A = 0;                             // Set the timer control registers to their default value
334
+  TCCR0B = 0;
273
   TCCR0A  |=  0x02;                       // CTC mode
335
   TCCR0A  |=  0x02;                       // CTC mode
274
   TCCR0B  |= ctl_regs[kTmr_Prescale_idx]; // set the prescaler
336
   TCCR0B  |= ctl_regs[kTmr_Prescale_idx]; // set the prescaler
275
-  GTCCR   |= _BV(PSR0);                   // Set the pre-scaler to the selected value
337
+  GTCCR   |= _BV(PSR0);                   // Trigger the pre-scaler to be reset to the selected value
276
 }
338
 }
277
 
339
 
278
 
340
 
297
 // At this point TCNT1 is reset to 0, new OCR1B values are latched from temp. loctaion to OCR1B
359
 // At this point TCNT1 is reset to 0, new OCR1B values are latched from temp. loctaion to OCR1B
298
 ISR(TIMER1_OVF_vect)
360
 ISR(TIMER1_OVF_vect)
299
 {
361
 {
300
-  clear_hold();
362
+  set_hold();
301
 }
363
 }
302
 
364
 
303
 // Called when TCNT1 == OCR1B
365
 // Called when TCNT1 == OCR1B
304
 ISR(TIMER1_COMPB_vect)
366
 ISR(TIMER1_COMPB_vect)
305
 {
367
 {
306
-  if(hold_state)
307
-    set_hold();
368
+  clear_hold();
308
 }
369
 }
309
 
370
 
310
 
371
 
311
 void pwm1_init()
372
 void pwm1_init()
312
 {
373
 {
313
-  TIMSK  &= ~(_BV(OCIE1B) + _BV(TOIE1));    // Disable interrupts
314
-  
315
   DDRB   |=  _BV(HOLD_DIR);  // setup PB3 as output
374
   DDRB   |=  _BV(HOLD_DIR);  // setup PB3 as output
316
-
317
-  TCCR1  |= ctl_regs[ kPwm_Div_idx];    // 32us period (512 divider) prescaler
375
+  
376
+  TCCR1 = 0; // Set the control registers to their default
377
+  GTCCR = 0;
318
   GTCCR  |= _BV(PWM1B);    // Enable PWM B and disconnect output pins
378
   GTCCR  |= _BV(PWM1B);    // Enable PWM B and disconnect output pins
319
-  GTCCR  |= _BV(PSR1);     // Set the pre-scaler to the selected value
320
-
379
+  
321
   pwm1_update();
380
   pwm1_update();
322
 
381
 
323
 }
382
 }
462
       for(i=0; i<stack_idx && i<3; ++i)
521
       for(i=0; i<stack_idx && i<3; ++i)
463
         ctl_regs[ kPwm_Duty_idx + i ] = stack[i];
522
         ctl_regs[ kPwm_Duty_idx + i ] = stack[i];
464
 
523
 
465
-      // if the PWM prescaler was changed
466
-      if( i == 3 )
467
-      {
468
-        cli();
469
-        pwm1_init();
470
-        sei();
471
-      }
472
-      
473
       pwm1_update();
524
       pwm1_update();
474
       break;
525
       break;
475
 
526
 
496
       break;
547
       break;
497
 
548
 
498
     case kNoteOff_Op:
549
     case kNoteOff_Op:
499
-      TIMSK  &= ~_BV(OCIE0A);                // clear timer interrupt (shouldn't be necessary)
500
-      //TIMSK  &= ~(_BV(OCIE1B) + _BV(TOIE1)); // PWM interupt disable interrupts
501
-      hold_state = 0;
550
+      hold_end();
502
       break;
551
       break;
503
 
552
 
504
     case kSetReadAddr_Op:
553
     case kSetReadAddr_Op:
518
     case kWriteTable_Op:
567
     case kWriteTable_Op:
519
       write_table();
568
       write_table();
520
       break;
569
       break;
570
+
571
+    case kHoldDelay_Op:
572
+      for(i=0; i<stack_idx && i<2; ++i)
573
+        ctl_regs[ kDelay_Coarse_idx + i ] = stack[i];
574
+      
521
   }
575
   }
522
 }
576
 }
523
 
577
 

Laddar…
Avbryt
Spara