1
0
Fork 0

Added support for audio using pins C4, C5, B6, B7

This commit is contained in:
Michael L. Walker 2018-04-12 08:16:35 -07:00 committed by Jack Humbert
parent 5319667c55
commit 22215a0e92
3 changed files with 137 additions and 78 deletions

View file

@ -35,44 +35,81 @@
// Timer Abstractions
// -----------------------------------------------------------------------------
// TIMSK3 - Timer/Counter #3 Interrupt Mask Register
// Turn on/off 3A interputs, stopping/enabling the ISR calls
#ifdef C6_AUDIO
//Currently we support timers 1 and 3 used at the sime time, channels A-C,
//pins PB5, PB6, PB7, PC4, PC5, and PC6
#if defined(C6_AUDIO)
#define CPIN_AUDIO
#define CPIN_SET_DIRECTION DDRC |= _BV(PORTC6);
#define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3A)
#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3A)
#endif
#ifdef B5_AUDIO
#define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A)
#define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
#endif
// TCCR3A: Timer/Counter #3 Control Register
// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
#ifdef C6_AUDIO
#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3A1);
#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0));
#endif
#ifdef B5_AUDIO
#define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1);
#define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
#endif
// Fast PWM Mode Controls
#ifdef C6_AUDIO
#define TIMER_3_PERIOD ICR3
#define TIMER_3_DUTY_CYCLE OCR3A
#define TIMER3_AUDIO_vect TIMER3_COMPA_vect
#endif
#if defined(C5_AUDIO)
#define CPIN_AUDIO
#define CPIN_SET_DIRECTION DDRC |= _BV(PORTC5);
#define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3B1) | (0 << COM3B0) | (1 << WGM31) | (0 << WGM30);
#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3B)
#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3B)
#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3B1);
#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3B1) | _BV(COM3B0));
#define TIMER_3_PERIOD ICR3
#define TIMER_3_DUTY_CYCLE OCR3B
#define TIMER3_AUDIO_vect TIMER3_COMPB_vect
#endif
#if defined(C4_AUDIO)
#define CPIN_AUDIO
#define CPIN_SET_DIRECTION DDRC |= _BV(PORTC4);
#define INIT_AUDIO_COUNTER_3 TCCR3A = (0 << COM3C1) | (0 << COM3C0) | (1 << WGM31) | (0 << WGM30);
#define ENABLE_AUDIO_COUNTER_3_ISR TIMSK3 |= _BV(OCIE3C)
#define DISABLE_AUDIO_COUNTER_3_ISR TIMSK3 &= ~_BV(OCIE3C)
#define ENABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A |= _BV(COM3C1);
#define DISABLE_AUDIO_COUNTER_3_OUTPUT TCCR3A &= ~(_BV(COM3C1) | _BV(COM3C0));
#define TIMER_3_PERIOD ICR3
#define TIMER_3_DUTY_CYCLE OCR3C
#define TIMER3_AUDIO_vect TIMER3_COMPC_vect
#endif
#ifdef B5_AUDIO
#if defined(B5_AUDIO)
#define BPIN_AUDIO
#define BPIN_SET_DIRECTION DDRC |= _BV(PORTB5);
#define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
#define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1A)
#define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1A)
#define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1);
#define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0));
#define TIMER_1_PERIOD ICR1
#define TIMER_1_DUTY_CYCLE OCR1A
#define TIMER1_AUDIO_vect TIMER1_COMPA_vect
#endif
#if defined(B6_AUDIO)
#define BPIN_AUDIO
#define BPIN_SET_DIRECTION DDRC |= _BV(PORTB6);
#define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10);
#define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1B)
#define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1B)
#define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1B1);
#define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1B1) | _BV(COM1B0));
#define TIMER_1_PERIOD ICR1
#define TIMER_1_DUTY_CYCLE OCR1B
#define TIMER1_AUDIO_vect TIMER1_COMPB_vect
#endif
#if defined(B7_AUDIO)
#define BPIN_AUDIO
#define BPIN_SET_DIRECTION DDRC |= _BV(PORTB7);
#define INIT_AUDIO_COUNTER_1 TCCR1A = (0 << COM1C1) | (0 << COM1C0) | (1 << WGM11) | (0 << WGM10);
#define ENABLE_AUDIO_COUNTER_1_ISR TIMSK1 |= _BV(OCIE1C)
#define DISABLE_AUDIO_COUNTER_1_ISR TIMSK1 &= ~_BV(OCIE1C)
#define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1C1);
#define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1C1) | _BV(COM1C0));
#define TIMER_1_PERIOD ICR1
#define TIMER_1_DUTY_CYCLE OCR1C
#define TIMER1_AUDIO_vect TIMER1_COMPC_vect
#endif
// -----------------------------------------------------------------------------
@ -147,47 +184,51 @@ void audio_init()
if (!audio_initialized) {
// Set port PC6 (OC3A and /OC4A) as output
#ifdef C6_AUDIO
DDRC |= _BV(PORTC6);
//#else
// DDRC |= _BV(PORTC6); // Why is PC6 being set as output low, if C6_audio isn't defined?
// PORTC &= ~_BV(PORTC6);
// Set audio ports as output
#ifdef CPIN_AUDIO
CPIN_SET_DIRECTION
#endif
#ifdef BPIN_AUDIO
BPIN_SET_DIRECTION
#endif
#ifdef B5_AUDIO
DDRB |= _BV(PORTB5);
//#else
// DDRB |= _BV(PORTB5); // Same as with PC6
// PORTB &= ~_BV(PORTB5);
#endif
#ifdef C6_AUDIO
#ifdef CPIN_AUDIO
DISABLE_AUDIO_COUNTER_3_ISR;
#endif
#ifdef B5_AUDIO
#ifdef BPIN_AUDIO
DISABLE_AUDIO_COUNTER_1_ISR;
#endif
// TCCR3A / TCCR3B: Timer/Counter #3 Control Registers
// Compare Output Mode (COM3An) = 0b00 = Normal port operation, OC3A disconnected from PC6
// Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14 (Period = ICR3, Duty Cycle = OCR3A)
// TCCR3A / TCCR3B: Timer/Counter #3 Control Registers TCCR3A/TCCR3B, TCCR1A/TCCR1B
// Compare Output Mode (COM3An and COM1An) = 0b00 = Normal port operation
// OC3A -- PC6
// OC3B -- PC5
// OC3C -- PC4
// OC1A -- PB5
// OC1B -- PB6
// OC1C -- PB7
// Waveform Generation Mode (WGM3n) = 0b1110 = Fast PWM Mode 14. Period = ICR3, Duty Cycle OCR3A)
// OCR3A - PC6
// OCR3B - PC5
// OCR3C - PC4
// OCR1A - PB5
// OCR1B - PB6
// OCR1C - PB7
// Clock Select (CS3n) = 0b010 = Clock / 8
#ifdef C6_AUDIO
TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
#ifdef CPIN_AUDIO
INIT_AUDIO_COUNTER_3
TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
TIMER_3_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
TIMER_3_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre);
#endif
#ifdef B5_AUDIO
TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
#ifdef BPIN_AUDIO
INIT_AUDIO_COUNTER_1
TCCR1B = (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
TIMER_1_PERIOD = (uint16_t)(((float)F_CPU) / (440 * CPU_PRESCALER));
TIMER_1_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (440 * CPU_PRESCALER)) * note_timbre);
#endif
#endif
audio_initialized = true;
}
@ -207,13 +248,12 @@ void stop_all_notes()
}
voices = 0;
#ifdef C6_AUDIO
#ifdef CPIN_AUDIO
DISABLE_AUDIO_COUNTER_3_ISR;
DISABLE_AUDIO_COUNTER_3_OUTPUT;
#endif
#ifdef B5_AUDIO
#ifdef BPIN_AUDIO
DISABLE_AUDIO_COUNTER_1_ISR;
DISABLE_AUDIO_COUNTER_1_OUTPUT;
#endif
@ -259,11 +299,11 @@ void stop_note(float freq)
voice_place = 0;
}
if (voices == 0) {
#ifdef C6_AUDIO
#ifdef CPIN_AUDIO
DISABLE_AUDIO_COUNTER_3_ISR;
DISABLE_AUDIO_COUNTER_3_OUTPUT;
#endif
#ifdef B5_AUDIO
#ifdef BPIN_AUDIO
DISABLE_AUDIO_COUNTER_1_ISR;
DISABLE_AUDIO_COUNTER_1_OUTPUT;
#endif
@ -295,15 +335,15 @@ float vibrato(float average_freq) {
#endif
#ifdef C6_AUDIO
ISR(TIMER3_COMPA_vect)
#ifdef CPIN_AUDIO
ISR(TIMER3_AUDIO_vect)
{
float freq;
if (playing_note) {
if (voices > 0) {
#ifdef B5_AUDIO
#ifdef BPIN_AUDIO
float freq_alt = 0;
if (voices > 1) {
if (polyphony_rate == 0) {
@ -477,10 +517,10 @@ ISR(TIMER3_COMPA_vect)
}
#endif
#ifdef B5_AUDIO
ISR(TIMER1_COMPA_vect)
#ifdef BPIN_AUDIO
ISR(TIMER1_AUDIO_vect)
{
#if defined(B5_AUDIO) && !defined(C6_AUDIO)
#if defined(BPIN_AUDIO) && !defined(CPIN_AUDIO)
float freq = 0;
if (playing_note) {
@ -627,10 +667,10 @@ void play_note(float freq, int vol) {
}
if (audio_config.enable && voices < 8) {
#ifdef C6_AUDIO
#ifdef CPIN_AUDIO
DISABLE_AUDIO_COUNTER_3_ISR;
#endif
#ifdef B5_AUDIO
#ifdef BPIN_AUDIO
DISABLE_AUDIO_COUNTER_1_ISR;
#endif
@ -648,12 +688,12 @@ void play_note(float freq, int vol) {
voices++;
}
#ifdef C6_AUDIO
#ifdef CPIN_AUDIO
ENABLE_AUDIO_COUNTER_3_ISR;
ENABLE_AUDIO_COUNTER_3_OUTPUT;
#endif
#ifdef B5_AUDIO
#ifdef C6_AUDIO
#ifdef BPIN_AUDIO
#ifdef CPIN_AUDIO
if (voices > 1) {
ENABLE_AUDIO_COUNTER_1_ISR;
ENABLE_AUDIO_COUNTER_1_OUTPUT;
@ -676,10 +716,10 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
if (audio_config.enable) {
#ifdef C6_AUDIO
#ifdef CPIN_AUDIO
DISABLE_AUDIO_COUNTER_3_ISR;
#endif
#ifdef B5_AUDIO
#ifdef BPIN_AUDIO
DISABLE_AUDIO_COUNTER_1_ISR;
#endif
@ -701,12 +741,12 @@ void play_notes(float (*np)[][2], uint16_t n_count, bool n_repeat)
note_position = 0;
#ifdef C6_AUDIO
#ifdef CPIN_AUDIO
ENABLE_AUDIO_COUNTER_3_ISR;
ENABLE_AUDIO_COUNTER_3_OUTPUT;
#endif
#ifdef B5_AUDIO
#ifndef C6_AUDIO
#ifdef BPIN_AUDIO
#ifndef CPIN_AUDIO
ENABLE_AUDIO_COUNTER_1_ISR;
ENABLE_AUDIO_COUNTER_1_OUTPUT;
#endif