;Guitar Pickup v1.0 ;Copyright 2003, Nicholas A. Masluk ;Started June 13, 2003 list p=16f627 include p16f627.inc __CONFIG _BODEN_OFF & _CP_ALL & _DATA_CP_ON & _PWRTE_ON & _WDT_ON & _LVP_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT CBLOCK 0x020 TMP0, TMP1 ENDC ;port A connections PK1 equ 0 ;pickup 1 on/off PK2 equ 1 ;pickup 2 on/off PK3 equ 2 ;pickup 3 on/off DEV equ 3 ;device on/off BT1 equ 4 ;button 1, pickup 1 BT2 equ 5 ;button 2, pickup 2 BT3 equ 6 ;button 3, pickup 3 BTF equ 7 ;button 4, serial/parallel final output ;port B connections PHASE1 equ 0 ;phase pickup 1 P_S1 equ 1 ;parallel/serial pickup 1 PHASE2 equ 2 ;phase pickup 2 P_S2 equ 3 ;parallel/serial pickup 1 PHASE3 equ 4 ;phase pickup 3 P_S3 equ 5 ;parallel/serial pickup 1 ; equ 6 P_SF equ 7 ;parallel/serial final output ;start of main code org 0 movlw 0x007 movwf CMCON ;turn comparators off clrf PORTA clrf PORTB bsf STATUS, RP0 ;bank 1 bcf OPTION_REG, PSA ;set prescaler to Timer0, to keep WDT fast movlw 0x0F0 movwf TRISA ;set I/O mode for port A clrf TRISB ;set I/O mode for port B clrf EEADR bsf EECON1, RD ;EEPROM read of first byte, storing last setting on PORTA movf EEDATA, W bcf STATUS, RP0 ;bank 0 movwf PORTA ;put settings into PORTA bsf STATUS, RP0 ;bank 1 incf EEADR bsf EECON1, RD ;read second byte from EEPROM, storing last settings of PORTB bcf STATUS, RP0 ;bank 0 movwf PORTB ;put settings into PORTB main bcf PCON, OSCF ;low speed oscillator 37kHz movlw 0x0F0 clrwdt andwf PORTA btfsc STATUS, Z ;check if any buttons are pressed goto $-3 bsf PCON, OSCF ;fast oscillator 4MHz btfsc PORTA, 4 ;check which button is pressed goto pickup1 ;pickup 1 button pressed btfsc PORTA, 5 goto pickup2 ;pickup 2 button pressed btfsc PORTA, 6 goto pickup3 ;pickup 3 button pressed goto final ;final output button pressed ;10ms delay @ 4MHz processor speed dlay10 movlw 0x019 ;10,001 cycle delay loop movwf TMP1 movlw 0x084 movwf TMP0 decfsz TMP0, F goto $-1 decfsz TMP1, F goto $-5 ;end of delay loop return ;loop which prevents holding down a button from performing more than one action per button press butwait clrwdt call dlay10 ;10ms delay, allow button debounce movf PORTA, W andlw 0x0F0 btfsc STATUS, Z ;check to see if any buttons are pressed return ;if not, allow for a return goto butwait pickup1 bsf PORTA, DEV ;make sure device is on btfsc PORTA, PK1 ;check to see if pickup is on goto polar1 ;if so, proceed to check phase bsf PORTA, PK1 ;if not, turn it on goto ckrules ;then check rules polar1 btfsc PORTB, PHASE1 ;check if phase is reversed goto parser1 bsf PORTB, PHASE1 ;if not, do so goto ckrules ;then check rules parser1 btfsc PORTB, P_S1 ;if so, check if pickup is in parallel or serial mode goto off1 ;if already in serial mode, turn off pickup 1 bsf PORTB, P_S1 ;if in parallel mode, put into serial mode bcf PORTB, PHASE1 ;and put phase back to foward polarity goto ckrules ;then check rules off1 bcf PORTA, PK1 ;turn off pickup1 bcf PORTB, PHASE1 ;put in foward polarity bcf PORTB, P_S1 ;and parallel mode for next time pickup 1 is turned on, and to save power by keeping relays turned off when not in use btfsc PORTA, PK2 ;check to see that at least one of the other pickups are on goto ckrules ;pickup 2 is on, check rules, save settings, then return to main loop btfsc PORTA, PK3 goto ckrules ;pickup 3 is on, check rules, save settings, then return to main loop bcf PORTA, DEV ;if not, turn off device bcf PORTB, P_SF ;turn off final parallel/serial relay goto save ;save settings, and return to main loop (no need to check rules, becasue device is off) pickup2 bsf PORTA, DEV ;make sure device is on btfsc PORTA, PK2 ;check to see if pickup is on goto polar2 ;if so, proceed to check phase bsf PORTA, PK2 ;if not, turn it on goto ckrules ;then check rules polar2 btfsc PORTB, PHASE2 ;check if phase is reversed goto parser2 bsf PORTB, PHASE2 ;if not, do so goto ckrules ;then check rules parser2 btfsc PORTB, P_S2 ;if so, check if pickup is in parallel or serial mode goto off2 ;if already in serial mode, turn off pickup 2 bsf PORTB, P_S2 ;if in parallel mode, put into serial mode bcf PORTB, PHASE2 ;and put phase back to foward polarity goto ckrules ;then check rules off2 bcf PORTA, PK2 ;turn off pickup 2 bcf PORTB, PHASE2 ;put in foward polarity bcf PORTB, P_S2 ;and parallel mode for next time pickup 2 is turned on, and to save power by keeping relays turned off when not in use btfsc PORTA, PK1 ;check to see that at least one of the other pickups are on goto ckrules ;pickup 1 is on, check rules, save settings, then return to main loop btfsc PORTA, PK3 goto ckrules ;pickup 3 is on, check rules, save settings, then return to main loop bcf PORTA, DEV ;if not, turn off device bcf PORTB, P_SF ;turn off final parallel/serial relay goto save ;save settings, and return to main loop (no need to check rules, becasue device is off) pickup3 bsf PORTA, DEV ;make sure device is on btfsc PORTA, PK3 ;check to see if pickup is on goto polar3 ;if so, proceed to check phase bsf PORTA, PK3 ;if not, turn it on goto ckrules ;then check rules polar3 btfsc PORTB, PHASE3 ;check if phase is reversed goto parser3 bsf PORTB, PHASE3 ;if not, do so goto ckrules ;then check rules parser3 btfsc PORTB, P_S3 ;if so, check if pickup is in parallel or serial mode goto off3 ;if already in serial mode, turn off pickup 3 bsf PORTB, P_S3 ;if in parallel mode, put into serial mode bcf PORTB, PHASE3 ;and put phase back to foward polarity goto ckrules ;then check rules off3 bcf PORTA, PK3 ;turn off pickup 3 bcf PORTB, PHASE3 ;put in foward polarity bcf PORTB, P_S3 ;and parallel mode for next time pickup 3 is turned on, and to save power by keeping relays turned off when not in use btfsc PORTA, PK1 ;check to see that at least one of the other pickups are on goto ckrules ;pickup 1 is on, check rules, save settings, then return to main loop btfsc PORTA, PK2 goto ckrules ;pickup 2 is on, check rules, save settings, then return to main loop bcf PORTA, DEV ;if not, turn off device bcf PORTB, P_SF ;turn off final parallel/serial relay goto save ;save settings, and return to main loop (no need to check rules, becasue device is off) final movlw 0x080 xorwf PORTB, F ;toggle P_SF, between parallel and serial mode ;makes sure pickups turned on are not all in parallel or serial mode in conjunction with the final output ; 1) if all on pickups are in parallel mode, final output must be in serial mode ; 2) if all on pickups are in serail mode, final output must be in parallel mode ckrules btfsc PORTB, P_S1 ;test rule 1, if any pickups are in serial mode, rule 1 is ok (pickups can only be in serial mode when turned on) goto test2 btfsc PORTB, P_S2 goto test2 btfsc PORTB, P_S3 goto test2 bsf PORTB, P_SF ;all pickups are in parallel mode, so make sure final output is in serial mode goto save test2 btfss PORTB, P_S1 ;rule 1 passed, check to see if rule 2 is OK goto chk1 ;pickup 1 is in parallel mode, check to see if it is also on cont1 btfss PORTB, P_S2 ;pickup 1 is either serial or off, continue checking goto chk2 ;pickup 2 is in parallel mode, check to see if it is also on cont2 btfss PORTB, P_S3 ;pickups 1 and 2 are either serial or off, check if pickup 3 is serial goto chk3 ;pickup 3 is in parallel mode, check to see if it is also on cont3 bcf PORTB, P_SF ;all pickups are either off or in serial mode, so make sure final output is in parallel mode goto save chk1 btfsc PORTA, PK1 goto save ;if pickup 1 is also on, then rule 2 is OK goto cont1 ;if pickup 1 is off it does not count, so continue checking other pickups chk2 btfsc PORTA, PK2 goto save ;if pickup 2 is also on, then rule 2 is OK goto cont2 ;if pickup 2 is off it does not count, so continue checking other pickups chk3 btfsc PORTA, PK3 goto save ;if pickup 3 is also on, then rule 2 is OK goto cont3 ;if pickup 3 is off it does not count ;saves settings and checks that no buttons are depressed before returning to main loop save movf PORTA, W ;put PORTA settings into W bcf PIR1, EEIF ;clear EEIF flag bsf STATUS, RP0 ;bank 1 clrf EEADR movwf EEDATA ;save PORTA settings in EEPROM bsf EECON1, WREN ;enable write movlw 0x055 movwf EECON2 movlw 0x0AA movwf EECON2 bsf EECON1, WR ;start writing bcf EECON1, WREN ;disable write bcf STATUS, RP0 ;bank0 movf PORTB, W ;put PORTB settings into W btfsc PIR1, EEIF ;wait until write operation is complete before continuing goto $+3 ;continue once write is complete clrwdt goto $-3 bcf PIR1, EEIF ;clear EEIF flag bsf STATUS, RP0 ;bank 1 incf EEADR ;next byte in EEPROM for PORTB settings movwf EEDATA ;put settings into EEPROM bsf EECON1, WREN ;enable write movlw 0x055 movwf EECON2 movlw 0x0AA movwf EECON2 bsf EECON1, WR ;start writing bcf EECON1, WREN ;disable write bcf STATUS, RP0 ;bank0 btfsc PIR1, EEIF ;wait until write operation is complete before continuing goto $+3 ;continue once write is complete clrwdt goto $-3 call butwait ;wait until no buttons are pressed before returning to main loop goto main ;return to main loop end