|
@@ -44,8 +44,9 @@ enum
|
44
|
44
|
kNoteOff_Op = 3, // Turn off note 5
|
45
|
45
|
kSetReadAddr_Op = 4, // Set a read addr. 6 {<src>} {<addr>} } src: 0=reg 1=table 2=eeprom
|
46
|
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,6 +73,10 @@ enum
|
72
|
73
|
kState_idx = 14, // 1=attk 2=hold
|
73
|
74
|
kError_Code_idx = 15, // Error Code
|
74
|
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
|
80
|
kMax_idx
|
76
|
81
|
};
|
77
|
82
|
|
|
@@ -99,12 +104,16 @@ volatile uint8_t ctl_regs[] =
|
99
|
104
|
4, // 10 (1-5) 4=16us per tick
|
100
|
105
|
|
101
|
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
|
110
|
0, // 14 state flags 1=attk 2=hold (read/only)
|
106
|
111
|
0, // 15 (0-255) Error bit field
|
107
|
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
|
119
|
// These registers are saved to Eeprom
|
|
@@ -208,6 +217,34 @@ volatile uint8_t hold_state = 0; // state=0 hold should not be set, state=1 hol
|
208
|
217
|
#define clear_hold() PORTB &= ~(_BV(HOLD_PIN))
|
209
|
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
|
248
|
// Use the current tmr0 ctl_reg[] values to set the timer to the starting state.
|
212
|
249
|
void tmr0_reset()
|
213
|
250
|
{
|
|
@@ -216,7 +253,11 @@ void tmr0_reset()
|
216
|
253
|
PORTB |= _BV(ATTK_PIN); // set the attack pin
|
217
|
254
|
clear_hold(); // clear the hold pin
|
218
|
255
|
hold_state = 0;
|
|
256
|
+
|
|
257
|
+ tmr0_state = 1;
|
|
258
|
+ OCR0A = 0xff;
|
219
|
259
|
|
|
260
|
+ /*
|
220
|
261
|
// if a coarse count exists then go into coarse mode
|
221
|
262
|
if( ctl_regs[kTmr_Coarse_idx] > 0 )
|
222
|
263
|
{
|
|
@@ -228,6 +269,7 @@ void tmr0_reset()
|
228
|
269
|
tmr0_state = 2;
|
229
|
270
|
OCR0A = ctl_regs[kTmr_Fine_idx];
|
230
|
271
|
}
|
|
272
|
+ */
|
231
|
273
|
|
232
|
274
|
TCNT0 = 0;
|
233
|
275
|
TIMSK |= _BV(OCIE0A); // enable the timer interrupt
|
|
@@ -237,32 +279,50 @@ ISR(TIMER0_COMPA_vect)
|
237
|
279
|
{
|
238
|
280
|
switch( tmr0_state )
|
239
|
281
|
{
|
240
|
|
- case 0:
|
241
|
|
- // timer is disabled
|
|
282
|
+ case 0: // timer disabled
|
242
|
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
|
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
|
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
|
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,9 +330,11 @@ ISR(TIMER0_COMPA_vect)
|
270
|
330
|
void tmr0_init()
|
271
|
331
|
{
|
272
|
332
|
TIMSK &= ~_BV(OCIE0A); // Disable interrupt TIMER1_OVF
|
|
333
|
+ TCCR0A = 0; // Set the timer control registers to their default value
|
|
334
|
+ TCCR0B = 0;
|
273
|
335
|
TCCR0A |= 0x02; // CTC mode
|
274
|
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,27 +359,24 @@ void pwm1_update()
|
297
|
359
|
// At this point TCNT1 is reset to 0, new OCR1B values are latched from temp. loctaion to OCR1B
|
298
|
360
|
ISR(TIMER1_OVF_vect)
|
299
|
361
|
{
|
300
|
|
- clear_hold();
|
|
362
|
+ set_hold();
|
301
|
363
|
}
|
302
|
364
|
|
303
|
365
|
// Called when TCNT1 == OCR1B
|
304
|
366
|
ISR(TIMER1_COMPB_vect)
|
305
|
367
|
{
|
306
|
|
- if(hold_state)
|
307
|
|
- set_hold();
|
|
368
|
+ clear_hold();
|
308
|
369
|
}
|
309
|
370
|
|
310
|
371
|
|
311
|
372
|
void pwm1_init()
|
312
|
373
|
{
|
313
|
|
- TIMSK &= ~(_BV(OCIE1B) + _BV(TOIE1)); // Disable interrupts
|
314
|
|
-
|
315
|
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
|
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
|
380
|
pwm1_update();
|
322
|
381
|
|
323
|
382
|
}
|
|
@@ -462,14 +521,6 @@ void on_receive( uint8_t byteN )
|
462
|
521
|
for(i=0; i<stack_idx && i<3; ++i)
|
463
|
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
|
524
|
pwm1_update();
|
474
|
525
|
break;
|
475
|
526
|
|
|
@@ -496,9 +547,7 @@ void on_receive( uint8_t byteN )
|
496
|
547
|
break;
|
497
|
548
|
|
498
|
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
|
551
|
break;
|
503
|
552
|
|
504
|
553
|
case kSetReadAddr_Op:
|
|
@@ -518,6 +567,11 @@ void on_receive( uint8_t byteN )
|
518
|
567
|
case kWriteTable_Op:
|
519
|
568
|
write_table();
|
520
|
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
|
|