X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=quantum%2Faudio%2Faudio.c;h=6d6833ec11f178dc1ec1a98fc68b76b4bb2b0390;hb=85688e5b52112c86895171d3dc8b26610480e932;hp=29bad8060b8fdde5a7b380393ba7e5146c099492;hpb=b669d115c2969a58f0ae00f6ae5c2290dba44c03;p=qmk_firmware.git diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c index 29bad8060..6d6833ec1 100644 --- a/quantum/audio/audio.c +++ b/quantum/audio/audio.c @@ -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)); + #define TIMER_3_PERIOD ICR3 + #define TIMER_3_DUTY_CYCLE OCR3A + #define TIMER3_AUDIO_vect TIMER3_COMPA_vect #endif - -#ifdef B5_AUDIO - #define ENABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A |= _BV(COM1A1); - #define DISABLE_AUDIO_COUNTER_1_OUTPUT TCCR1A &= ~(_BV(COM1A1) | _BV(COM1A0)); +#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 - -// Fast PWM Mode Controls - -#ifdef C6_AUDIO +#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 OCR3A + #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 DDRB |= _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 DDRB |= _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 DDRB |= _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,44 +184,43 @@ void audio_init() if (!audio_initialized) { - // Set port PC6 (OC3A and /OC4A) as output - - #ifdef C6_AUDIO - DDRC |= _BV(PORTC6); - #else - DDRC |= _BV(PORTC6); - PORTC &= ~_BV(PORTC6); + // Set audio ports as output + #ifdef CPIN_AUDIO + CPIN_SET_DIRECTION + DISABLE_AUDIO_COUNTER_3_ISR; #endif - - #ifdef B5_AUDIO - DDRB |= _BV(PORTB5); - #else - DDRB |= _BV(PORTB5); - PORTB &= ~_BV(PORTB5); + #ifdef BPIN_AUDIO + BPIN_SET_DIRECTION + DISABLE_AUDIO_COUNTER_1_ISR; #endif - #ifdef C6_AUDIO - DISABLE_AUDIO_COUNTER_3_ISR; - #endif - - #ifdef B5_AUDIO - DISABLE_AUDIO_COUNTER_1_ISR; - #endif + // 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 - // 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) // 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 @@ -195,7 +231,7 @@ void audio_init() if (audio_config.enable) { PLAY_SONG(startup_song); } - + } void stop_all_notes() @@ -207,13 +243,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 +294,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 +330,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) { @@ -429,7 +464,7 @@ ISR(TIMER3_COMPA_vect) note_position++; bool end_of_note = false; if (TIMER_3_PERIOD > 0) { - if (!note_resting) + if (!note_resting) end_of_note = (note_position >= (note_length / TIMER_3_PERIOD * 0xFFFF - 1)); else end_of_note = (note_position >= (note_length)); @@ -477,10 +512,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) { @@ -569,7 +604,7 @@ ISR(TIMER1_COMPA_vect) note_position++; bool end_of_note = false; if (TIMER_1_PERIOD > 0) { - if (!note_resting) + if (!note_resting) end_of_note = (note_position >= (note_length / TIMER_1_PERIOD * 0xFFFF - 1)); else end_of_note = (note_position >= (note_length)); @@ -627,10 +662,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 +683,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 +711,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 +736,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