'******************************************************************************* ' ' nuxx Audio Input Switch ' ' Software Version: 1.0-RC (Should work, just need testing on final PCB.) ' For Hardware Version: 1.0 ' ' by Steve Vigneau ' ' http://nuxx.net/wiki/Audio_Input_Switch ' '******************************************************************************* ' ' Notes: ' ' Input count config: ' ' RA5 | RA4 | Input ' (A) | (B) | Count ' -----+-----+------- ' - | - | 2 ' X | - | 3 ' - | X | 4 ' X | X | 5 ' ' Next Button: RA0 ' Previous Button: RA1 ' Mute Button: RA2 ' Mute LED: RC2 ' ' Config A: RA4 ' Config B: RA5 ' ' Input to Pin Mapping: ' - Input 1: RC5 ' - Input 2: RC4 ' - Input 3: RC3 ' - Input 4: RC0 ' - Input 5: RC1 ' ' EEPROM Usage: ' 0x00: Current Input (1-5) ' 0x01: Mute State (0 or 1) ' ' Config: 0x3FC4 (BOD Enabled, MCLR Disabled, WDT Disabled, INT OSC No Clockout) ' '******************************************************************************* ' ' Copyright (c) 2007 Steve Vigneau ' ' Permission is hereby granted, free of charge, to any person obtaining a copy ' of this software and associated documentation files (the "Software"), to deal ' in the Software without restriction, including without limitation the rights ' to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ' copies of the Software, and to permit persons to whom the Software is ' furnished to do so, subject to the following conditions: ' ' The above copyright notice and this permission notice shall be included in ' all copies or substantial portions of the Software. ' ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ' IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ' FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ' AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ' LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ' OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ' THE SOFTWARE. ' '******************************************************************************* program nuxx_audio_input_switch '******************************************************************************* ' ' Global Variables ' '******************************************************************************* dim changetoinput, curinput, inputcount, mutestate, togglemute as byte '******************************************************************************* ' ' Functions, Procedures, and Usage: ' ' readinputcount() ' Reads the two jumpers and returns as a byte how many inputs there are. ' ' selectinput() ' Takes input as byref byte to select which input to toggle. Turns off ' all inputs, waits 100ms, then turns on the selected input. Supports ' inputs 1 through 5. ' ' mute() ' Toggles mute on and off. When toggled on all outputs are silenced and the, ' mute LED pin is brought high. When toggled off the mute LED pin goes low ' and the current input is reinstated via selectinput(). ' ' interrupt() ' Tests which buttons have been pressed and reacts accordingly. ' '******************************************************************************* ' readinputcount() sub function readinputcount as byte if PORTA.5 = 1 then if PORTA.4 = 1 then result = 2 else result = 4 end if else if PORTA.4 = 1 then result = 3 else result = 5 end if end if end sub ' selectinput() sub procedure selectinput(dim byref x as byte) select case x case 1 PORTC = %00000000 ' Turn off all relays delay_ms(100) ' Wait PORTC.5 = 1 ' Turn on Input 1 eeprom_write($00, 1) ' Write Input 1 selection to EEPROM case 2 PORTC = %00000000 delay_ms(100) PORTC.4 = 1 eeprom_write($00, 2) case 3 PORTC = %00000000 delay_ms(100) PORTC.3 = 1 eeprom_write($00, 3) case 4 PORTC = %00000000 delay_ms(100) PORTC.0 = 1 eeprom_write($00, 4) case 5 PORTC = %00000000 delay_ms(100) PORTC.1 = 1 eeprom_write($00, 5) end select end sub ' mute() sub procedure mute select case mutestate case 0 PORTC = %00000000 delay_ms(100) ' For consistency with selectinput() PORTC.2 = 1 ' Turn on Mute LED mutestate = 1 eeprom_write($01, 1) case 1 selectinput(curinput) mutestate = 0 eeprom_write($01, 0) end select end sub ' interrupt() sub procedure interrupt ' Check for Mute button press if PORTA.2 = 0 then INTCON.T0IE = 0 ' Disable TMR0 Interrupt togglemute = 1 changetoinput = 0 end if ' Only read in Next / Prev buttons if not muted if mutestate = 0 then ' Check for Next button press if ((PORTA.0 = 0) and (PORTA.1 = 1)) <> 0 then INTCON.T0IE = 0 if curinput = inputcount then curinput = 1 else curinput = curinput + 1 end if changetoinput = curinput togglemute = 0 end if ' Check for Prev button press if ((PORTA.1 = 0) and (PORTA.0 = 1)) <> 0 then INTCON.T0IE = 0 if curinput = 1 then curinput = inputcount else curinput = curinput - 1 end if changetoinput = curinput togglemute = 0 end if end if INTCON.T0IF = 0 ' Clear TMR0 Overflow Interrupt Flag end sub '******************************************************************************* ' ' main: ' '******************************************************************************* main: CMCON = %00000111 ' Port A as all digital IO WPUA = %00110111 ' Enable Internal Pullups on PORTA<5:4> and PORTA<2:0> TRISA = %00110111 ' PORTA<5:4> and PORTA<2:0> as Inputs TRISC = %00000000 ' PORTC<5:0> as Outputs OPTION_REG = %00000010 ' 1:8 Prescaler for TMR0 TMR0 = 7 ' Preload for 1.999ms between timer interrupts ' Start with nothing to do / known state changetoinput = 0 togglemute = 0 mutestate = 0 ' Read saved input from EEPROM curinput = eeprom_read($00) inputcount = readinputcount() if (curinput > inputcount) or (curinput = 0) then curinput = 1 eeprom_write($00, 1) delay_ms(25) ' Let the EEPROM settle. end if ' Restore previous input or mute state if eeprom_read($01) = 1 then mute() else selectinput(curinput) end if INTCON = %10100000 ' Enable Global and TMR0 Interrupts ' Loop which handles everything while true if ((changetoinput <> 0) and (togglemute = 0)) <> 0 then selectinput(changetoinput) changetoinput = 0 while ((PORTA.0 = 0) or (PORTA.1 = 0) or (PORTA.2 = 0)) <> 0 nop wend delay_ms(70) ' Debounce: 70ms feels nice on dev board TMR0 = 7 INTCON.T0IE = 1 ' Reenable TMR0 Interrupt end if if ((togglemute = 1) and (changetoinput = 0)) <> 0 then mute() togglemute = 0 while ((PORTA.0 = 0) or (PORTA.1 = 0) or (PORTA.2 = 0)) <> 0 nop wend delay_ms(70) TMR0 = 7 INTCON.T0IE = 1 end if wend end.