cogeniac
Starting Member
- Total Posts : 32
- Reward points : 0
- Joined: 2017/02/04 19:50:39
- Location: 0
- Status: offline
Re: IOC Issue using PIC 16LF18346
2021/01/09 07:44:40
(permalink)
OK. I did some experiments, and I am more confused. Here is the main program and the setup subroutine. I have bolded the code that involves IOC. There are other segments of code that have been commented out where I was trying various things to get the the IOC to work. This morning I tried commenting out all of the code that I had added to try to get IOC to work (down in the setup routine). After realizing that I needed to enable both positive edge and negative edge IOC to get all of the encoder states, it seems to work as is. Strangely, however, for the last 2-3 days it did not throw any interrupts with the code as it is here. It was only after I cleared the IOCCF flags and read PORTC that it started to work. The negative edge detection is required since the encoder sequence is 0x00, 0x01, 0x03, 0x02, 0x00, so the last two transitions were being missed. But I had turned the knob multiple times and gotten no interrupts.. so I'm not sure what was going on. It works now though. ;****************************************************************************** ; main program ; Loops through a cyle that disables interrupts, reads PORT A, ; enables the interrupts, and waits about 10 msec for a knob turn or an I2C ; write. If either of these occurs, it then services the approriate ; interrupt. ;****************************************************************************** PSECT main,class=CODE,delta=2 main: movlb 0x00 ;Switch to Bank 0 bcf INTCON,7 ;Disable all interrupts during setup - bit 7=GIE bcf INTCON,6 ;Disable all interrupts during setup PAGESEL setup call setup PAGESEL $ MainLoop: ;*******************This loop continues until there is an interrupt bsf INTCON,7 ;Enable all interrupts bsf INTCON,6 ;Enable all peripheral interrupts movf intCounter,w ;Put intCounter value in w - set up to determine if intCounter has any set bits addlw 0xff ;add 0xFF to w btfss STATUS,0 ;If any bits were set there will have been a carry in the above add goto MainLoop ;If not, then go to the start ;*************** This section determines what interrupt occurred based on what was set by the ISR ;THIS SECTION IS HERE TO CAPTURE MULTIPLE INTERRUPTS AND THE SYSTEM STATE AT EACH> I AM CURRENTLY NOT USING IT ; PAGESEL getState ; call getState ;If so, then get the data for the oldest interrupt (top of the arrays) ; PAGESEL $ movlb 0x00 ;Switch to Bank 0 (in case we were not there already) PAGESEL SSP1Handler btfsc intFlag,0 ;If intFlag Bit 0 is clear then interrupt was not SSP1 call SSP1Handler ;If intFlag Bit 0 is set then interrupt was SSP1 I2C PAGESEL SSP2Handler btfsc intFlag,1 ;If intFlag Bit 1 is clear then interrupt was not SSP2 call SSP2Handler ;If intFlag Bit 1 is set then interrupt was SSP2 I2C (RPI Command) btfsc intFlag,2 ;If intFlag Bit 2 is clear then interrupt was not a knob turn? call KnobHandler ;If Knob, then go handle the knob change movf intCounter,w ;Put intCounter value in w - set up to determine if intCounter has any set bits sublw 00000000B ;subtract w from zero btfss STATUS,0 ;If the interrupt counter is zero (no borrow), skip and go the start decf intCounter ;Otherwise decrement the interrupt counter and go to the start goto MainLoop ;****************************************************************************** ; NOTE THE PIN ASSIGNMENTS IN THIS DESCRIPTION ARE DIFFEREN THAN WHAT IS ON THE BOARD> THIS IS FOR THE NEXT BOARD ITERATION> CURRENTLY WE ARE ONLY LOOKING AT ENCODER INPUTS ON RC0 and RC1 ; Setup Code to initialize program variables and peripheral registers ; and setup the MSSP for I2C ; Ports: ; Bidirectional Ports: ; RB4=I2C-SDA1 RB5=I2C-SCL1, ; RB6=I2C-SDA2,RB7=I2C-SCL2 ; Input Ports: ; RC0=I-Vol, RC1=Q-Vol (encoder inputs) ; RC2=I-Src, RC3=Q-Src (encoder inputs) ; RC4=I-Bal, RC5=Q-Bal (encoder inputs) ; RC6=I-EQ, RC7=Q-EQ (encoder inputs) ; ; Output Ports: ; RA2=fSetA RA3=fSetB (Audio Clock Control Buts) ; RA4=GPIO request I2C read by RPI ; RA5=DAC Mute (XSMT) ; ; Unused Ports: ; RA3: to avoid MCLR issue with debugger ;****************************************************************************** setup: ;****************************************************************************** ; Disable Peripheral modules ;****************************************************************************** ; movlb 0x12 ; movlw 0xFF ; movwf PMD1 ;Disable timer modules ; movwf PMD2 ;Disable DAC and Comparator modules ; movwf PMD3 ;Disable PWM modules ; movwf PMD5 ;Disable Signal modulator module ; movlw 00100000B ; movwf PMD4 ;Enable MSSP1 and MSSP2, Disable UART ; movlw 01000110B ; movwf PMD0 ;Enable IOC Module, disable FVR, NVM and clock reference ;****************************************************************************** ;Disable the analog inputs ;****************************************************************************** ; movlb 0x00 movlw 0xFF ; movwf PORTC ; clrf PORTA ; clrf PORTB ; clrf PORTC ; movlb 0x02 ; clrf LATA ; clrf LATB ; clrf LATC movlb 0x03 ;select Bank 3 clrf ANSELA ;clear the analog input bits clrf ANSELB ;clear the analog input bits clrf ANSELC ;clear the analog input bits ;****************************************************************************** ; Set the tri-state registers to configure I/O pins ;****************************************************************************** movlb 0x01 ;select Bank 1 movlw 0x3F movwf TRISA ;Set Port A TRIS bits to all input movlw 0x03 movwf TRISC ;Set PortC pins 0 and 1 as input, 2-7 as output ;****************************************************************************** ; Configure the bidirectional pins for the SSP (I2C) RB4-RB7 ;****************************************************************************** ; movlb 0x0D ;select bank 13 movlw 00011001B movwf RB4PPS ;Set RB4 as SDA1 input movlw 00011011B movwf RB5PPS ;Set RB5 as SDA2 input movlw 00011000B movwf RB6PPS ;Set RB6 as SCL1 input movlw 00011010B movwf RB7PPS ;Set RB7 as SCL2 input movlw 00001110B movwf SSP1CLKPPS ;Set SSP1 SCL input to RB6 movlw 00001100B movwf SSP1DATPPS ;Set SSP1 SDA input to RB4 movlw 00001111B movwf SSP2CLKPPS ;Set SSP2 SCL input to RB7 movlw 00001101B movwf SSP2DATPPS ;Set SSP2 SCL input to RB5 ;****************************************************************************** movlb 0x04 ;select Bank 4 movlw 0xFF movwf WPUA ;enable weak pullups on port A movwf WPUB ;enable weak pullups on port B movlw 0x03 movwf WPUC ;enable weak pullups on port C RC0 and RC1 ; clrf SSP1STAT ;Clear SSP 1 status register ;******************************* movlb 0x01 ; Switch to Bank 1 clrf PIE0 ;Disable all peripheral interrupts clrf PIE1 clrf PIE2 bsf PIE0,4 ;Enable IOC interrupts ; bsf PIE1,3 ;Enable SSP1 interripts ; bsf PIE2,3 ;Enable SSP2 interripts ;******************************* movlb 0x07 ;select Bank 7 movlw 00111111B movwf IOCAP ;Enable positive IOC on PORTA RA0-RA5 movwf IOCAN ;Enable negative IOC on PORTC RAO-RA5 movlw 00000011B movwf IOCCP ;Enable positive IOC on PORTC, RC0 & RC1 movwf IOCCN ;Enable negative IOC on PORTC, RC0 & RC1 ;******************************* movlb 0x00 ;Select bank 0 ; clrf FSR0L clrf PIR0 ;Clear the interrupt flags clrf PIR1 clrf PIR2 clrf PIR3 clrf PIR4 ; movf PORTC THIS WAS IN THE CODE THAT WORKED, BUT I AM NOT SURE IT IS NECESSARY ;movlb 0x07 ;clrf IOCAF ;clrf IOCBF ;clrf IOCCF ; movf PORTC clrf intCounter ;clear the interrupt counter clrf intFlag ;Clear the Interrupt Flag clrf knbTemp2 clrf newKnobState clrf knobState clrf knobFlag clrf intFlag clrf FSRsave clrf STATUSsave clrf WREGsave return
|
cogeniac
Starting Member
- Total Posts : 32
- Reward points : 0
- Joined: 2017/02/04 19:50:39
- Location: 0
- Status: offline
Re: IOC Issue using PIC 16LF18346
2021/01/13 10:45:27
(permalink)
OK, so I had the IOC working reliably, but the program was not detecting the correct encoder. After some mucking around, I realized that I was not initializing the variable with the encoder states at the start (I was just clearing it, but not reading the ports and setting it up properly). So I added a PORTA and PORTC read just before entering the main loop. This should have simply put the state of the encoders into the variable (Note there is some messiness to this, since with my current encoder test board, the encoders are not all on the same port, so I have to mess with the bit positions a bit. That will change in the next iteration). After doing this, the IOC function again refused to cooperate...It worked fine until I added these port reads, and now it doesn't work with or without them! There is obviously still something I do not understand about properly activating the IOC function. Here is the currently non-working code, including the ISR and the setup routines. Again the IOC initialization sections are bold. ;******************************************************************************; ; ISR Interrupt Service Routine: responds to I2C notifications and ; encoder input knob interrupts;;****************************************************************************** ;ISR: movlb 0x00 bcf INTCON,7 ;Disable all interrupts bcf INTCON,6 ;Disable all peripheral interrupts incf intCounter ;increment the interrupt counter clrf intFlag ;Clear the interrupt flag so we can set it later for this interrupt btfss PIR1,3 ;Is this a SSP1 interrupt? goto SSP2Interrupt ;No, go see if it was an I2C slave read bcf PIR1,3 ;Yes, Clear the SSP1 interrupt flag bsf intFlag,0 ;Set intFlag bit 0 so we know that the interrupt was SSP1 goto ISRDone SSP2Interrupt: btfss PIR2,3 ;Is this a SSP2 interrupt? goto KnbTurn ;No, go figure out which knob turned bcf PIR2,3 ;Yes, Clear the SSP2 interrupt flag bsf intFlag,1 ;Set intFlag bit 1 so we know that the interrupt was SSP2 goto ISRDoneKnbTurn: bcf PIR0,0 ;clear the IOC peripheral interrupt flag movf PORTA,w ;read the PORTA pins (also clears the port for next interrupt) movlb 0x07 ;select bank 7 clrf IOCAF ;clear the Port A interrupt flags movlb 0x00 ;select bank 0 movwf newKnobState ;save the current encoder states movlw 0x3F ;mask off only lower 6 bits -the IQ bits on RA0-RA5 andwf newKnobState,1 movf PORTC,w ;read the PORTC pins (also clears the port for next interrupt) movlb 0x07 ;select bank 7 clrf IOCCF ;clear the Port C interrupt flag movlb 0x00 ;select bank 0 movwf knbTemp2 ;save the PORTC state movlw 0000011B ;mask to capture I-Q bits of PORTC (bits 0 & 1) andwf knbTemp2,1 ;Capture bits 0 and 1 of PORTC ; This set of shifts is necessary because we are currently using RC0 and RC1 for the EQ inputs ; so we need to move them intot he right bit positions to create newKnobState rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positons 1 and 2 rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 2 and 3 rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 3 and 4 rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 4 and 5 rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 5 and 6 rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 6 and 7 ;XOR the old and new knob states to determine what changed movf knbTemp2,w iorwf newKnobState,w ;add the PORTC bits (originally 0 & 1, now 6 and 7) into newKnobState to make a full 8-bit word xorwf knobState,w ;XOR old and new knob states (will set one of the bits corresponding to the knob that changed) movwf knobFlag ;set the knob flag (will have one of the bits corresponding to the turned knob set) bsf intFlag,2 ;set the interrupt flag to a knob turnISRDone: RETFIE ;Return from interrupt;******************************************************************************; main program; Loops through a cyle that disables interrupts, reads PORT A,; enables the interrupts, and waits about 10 msec for a knob turn or an I2C; write. If either of these occurs, it then services the approriate ; interrupt. ;******************************************************************************PSECT main,class=CODE,delta=2main: movlb 0x00 ;Switch to Bank 0 bcf INTCON,7 ;Disable all interrupts during setup - bit 7=GIE bcf INTCON,6 ;Disable all interrupts during setup PAGESEL setup call setup PAGESEL $;Capture the initial encoder state THIS IS THE NEW CODE> THE IOC NOW DOESN"T WORK WITH OR WITHOUT THIS CODE; movf PORTA,w ;read the PORTA pins; movwf knobState ;save the current encoder states; movlw 0x3F ;mask off only lower 6 bits -the IQ bits; andwf knobState,1 ; movf PORTC,w ;read the PORTC pins ; movwf knbTemp2 ;save the PORTC state; movlw 0000011B ;mask to capture I-Q bits of PORTC (bits 0 & 1); andwf knbTemp2,1 ;Capture bits 0 and 1 of PORTC; rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positons 1 and 2; rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 2 and 3; rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 3 and 4; rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 4 and 5; rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 5 and 6; rlf knbTemp2,1 ;Rotate original bits 0 and 1 into bit positions 6 and 7; movf knbTemp2; iorwf knobState,1 ;add the PORTC bits (originally 0 & 1, now 6 and 7) into newKnobState to make a full 8-bit word MainLoop: ;*******************This loop continues until there is an interrupt bsf INTCON,7 ;Enable all interrupts bsf INTCON,6 ;Enable all peripheral interrupts movf intCounter,w ;set up to determine if intCounter has any set bits addlw 0xff ;add 0xFF to w btfss STATUS,0 ;If any bits were set there will have been a carry in the above add goto MainLoop ;If not, then go to the start ;*********This section determines what interrupt occurred based on how intFlag was set by the ISR movlb 0x00 ;Switch to Bank 0 (in case we were not there already) PAGESEL SSP1Handler btfsc intFlag,0 ;If intFlag Bit 0 is clear then interrupt was not SSP1 call SSP1Handler ;If intFlag Bit 0 is set then interrupt was SSP1 I2C PAGESEL SSP2Handler btfsc intFlag,1 ;If intFlag Bit 1 is clear then interrupt was not SSP2 call SSP2Handler ;If intFlag Bit 1 is set then interrupt was SSP2 I2C (RPI Command) btfsc intFlag,2 ;If intFlag Bit 2 is clear then interrupt was not a knob turn? PAGESEL KnobHandler call KnobHandler ;If Knob, then go handle the knob change movf intCounter,w ;set up to determine if intCounter has any setbits sublw 00000000B ;subtract w from zero btfss STATUS,0 ;If the interrupt counter is zero (no borrow), skip and go the start decf intCounter ;Otherwise decrement the interrupt counter and go to the start goto MainLoop;******************************************************************************;; Setup Code to initialize program variables and peripheral registers; and setup the MSSP for I2C; Ports: ; Bidirectional Ports:; RB4=I2C-SDA1 RB5=I2C-SCL1, ; RB6=I2C-SDA2,RB7=I2C-SCL2; Output Ports:; RA2=fSetA RA3=fSetB (Audio Clock Control Buts); RA4=GPIO request I2C read by RPI; RA5=DAC Mute (XSMT);; Unused Ports:; RA3: to avoid MCLR issue with debugger ;Input Ports:; RA2=I-Vol, RA1=Q-Vol (encoder inputs); RA0=I-Src, RA3=Q-Src (encoder inputs); RA4=I-Bal, RA5=Q-Bal (encoder inputs); RC0=I-EQ, RC1=Q-EQ (encoder inputs);******************************************************************************setup: movlb 0x03 ;select Bank 3 clrf ANSELA ;clear the analog input bits clrf ANSELB ;clear the analog input bits clrf ANSELC ;clear the analog input bits;******************************************************************************; Set the tri-state registers to configure I/O pins;****************************************************************************** movlb 0x01 ;select Bank 1 movlw 0x3F movwf TRISA ;Set Port A TRIS bits to all input movlw 0x03 movwf TRISC ;Set PortC pins 0 and 1 as input, 2-7 as output;******************************************************************************; Configure the bidirectional pins for the SSP (I2C) RB4-RB7;******************************************************************************; movlb 0x0D ;select bank 13 movlw 00011001B movwf RB4PPS ;Set RB4 as SDA1 input movlw 00011011B movwf RB5PPS ;Set RB5 as SDA2 input movlw 00011000B movwf RB6PPS ;Set RB6 as SCL1 input movlw 00011010B movwf RB7PPS ;Set RB7 as SCL2 input movlw 00001110B movwf SSP1CLKPPS ;Set SSP1 SCL input to RB6 movlw 00001100B movwf SSP1DATPPS ;Set SSP1 SDA input to RB4 movlw 00001111B movwf SSP2CLKPPS ;Set SSP2 SCL input to RB7 movlw 00001101B movwf SSP2DATPPS ;Set SSP2 SCL input to RB5;****************************************************************************** movlb 0x04 ;select Bank 4 movlw 0xFF movwf WPUA ;enable weak pullups on port A movwf WPUB ;enable weak pullups on port B movlw 0x03 movwf WPUC ;enable weak pullups on port C RC0 and RC1; clrf SSP1STAT ;clear SSP 1 status register; clrf SSP2STAT ;clear SSP 1 status register;****************************************************************************** movlb 0x01 ;Switch to Bank 1 clrf PIE0 ;Disable all peripheral interrupts clrf PIE1 clrf PIE2 bsf PIE0,4 ;Enable IOC interrupts; bsf PIE1,3 ;Enable SSP1 interripts; bsf PIE2,3 ;Enable SSP2 interripts;****************************************************************************** movlb 0x07 ;select Bank 7 movlw 00111111B movwf IOCAP ;Enable positive IOC on PORTA RA0-RA5 movwf IOCAN ;Enable negative IOC on PORTA RA0-RA5 movlw 00000011B movwf IOCCP ;Enable positive IOC on PORTC, RC0 & RC1 movwf IOCCN ;Enable negative IOC on PORTA RC0 & RC1;****************************************************************************** movlb 0x00 ;Select bank 0 clrf PIR0 ;Clear the interrupt flags clrf PIR1 clrf PIR2 clrf PIR3 clrf PIR4; movlb 0x07 ;I HAVE TRIED THIS WITH AND WITHOUT THE CLEARING OF THE IOCxF REGISTERS; clrf IOCAF; clrf IOCBF; clrf IOCCF ;****************************************************************************** movlb 0x00 clrf intCounter ;clear the interrupt counter clrf intFlag ;Clear the interrupt type flag clrf newKnobState clrf knobFlag return;;******************************************************************************; KnobHandler subroutine to determine which knob was turned, ; and in which direction,and implement the corresponding change;******************************************************************************; KnobHandler: nop ;Figure out which knob turned movlb 0x00 ;select Bank 0 btfsc knobFlag,0 ;test bit 0, if set, then turn was volume knob goto VolKnob ;go handle volume knob btfsc knobFlag,1 ;if bit 0 clear, test bit 1, ;if bit 1 set, then turn was volume knob goto VolKnob ;go handle volume knob ;otherwise go test src knob btfsc knobFlag,2 ;test bit 2, if set, then turn was Source knob goto SrcKnob btfsc knobFlag,3 ;if bit 2 clear, test bit 3, ;if bit 3 set, then turn was Source knob goto SrcKnob ;go handle source knob btfsc knobFlag,4 ;if bit 3 clear, test bit 4, ;if bit 4 set, then turn was Balance knob goto BalKnob ;go handle balance knob btfsc knobFlag,5 ;if bit 4 clear, test bit 5, ;if bit 5 set, then turn was balance knob goto BalKnob ;go handle balance knob btfsc knobFlag,6 ;if bit 5 clear, test bit 6, ;if bit 6 set, then turn was EQ knob goto EQKnob ;go handle balance knob btfsc knobFlag,7 ;if bit 6 clear, test bit 7, ;if bit 7 set, then turn was EQ knob goto EQKnob ;go handle EQ knob return ;otherwise return, (error)SrcKnob: nop ;Determine CW or CCW Direction for Source Knob movlw 0x0C ;Mask for source knob bits andwf knobState,1 ;mask off only src bits in prior knob state andwf newKnobState,0 ;mask off only src bits in current knob state movwf knbTemp ;save the new state in temp variable btfsc knbTemp,3 ;If bit 3 is clear, then skip bsf knbTemp,1 ;If bit 3 is set, then set bit 1, to prepare for circular left shift rlf knbTemp,1 ;shift new state (newKnobState) bits left (if Bit 1 was set then it rotates [font="'courier new', courier"]in to bit 2 as Bit 3) movf knbTemp,w xorwf knobState,0 ;xor the new -in W- and prior knob state values movwf knbTemp btfsc knbTemp,3 ;if bit 3 is set, then turn was clockwise, so skip and increment source goto SrcDec ;otherwise turn was CCW, go decrement source;THE REST OF THIS JUST REACTS TO VARIOUS KNOB TURNS ;*******************************************************************************;; Source is defined by srcCount variable as follows: ; ; totSrc=0x05; srcCount=0x00 Analog Input srcReg 2D 0x00 rxReg 0D 0x00 ; srcCount=0x01 RPI Input srcReg 2D 0x01 rxReg 0D 0x00; srcCount=0x02 TOS-1 srcReg 2D 0x02 rxReg 0D 0x00; srcCount=0x03 TOS-2 srcReg 2D 0x02 rxReg 0D 0x01; srcCount=0x04 S/PDIF-1 srcReg 2D 0x02 rxReg 0D 0x02; srcCount=0x05 S/PDIF-2 srcReg 2D 0x02 rxReg 0D 0x03;; Note: Analog input (from the ADC) goes to input Port A on the ASRC (via I2S); RPI input goes to inout Port B on the ASRC (via I2S); The other PCM inputs are via the ASRC DIR. ; So selection of these different sources are handled by ; different functions and registers inthe ASRC.; SrcInc: movf srcCount,w ;check to see if source is at max subwf totSrc,0 movf srcRoll1,w ;load rollover value (0xFF minus Source Total) btfss STATUS,2 addwf srcCount,1 ;if so, then rollover to 0xFF incf srcCount,1 ;increment the source counter - goes to zero ;if srcRoll1 was added, otherwise just increments goto setSrc ;jump to the source set codeSrcDec: movlw 0x00 subwf srcCount,0 ;check to see if source is at min movf srcRoll2,w btfss STATUS,2 addwf srcCount,1 ;if so, then rollover to srcTot+1, srcRoll2 decf srcCount,1 ;decrement the source counter - either decrements ;within range, or rolls under from 0 to srcTotsetSrc: RETURN; movf srcCount,w ;preset the srcCount to add later if necesary; clrf srcCtlReg ;preset SRC control reg (2D) input to ASRC Port A "00000000"; movlw 0x0D ;Add 0x0D to scrCount, to see if the value is 3 or more; addlw srcCount ;if value is over 2, then carry bit will be set; btfss STATUS,0 ;check to see if carry is set (srcCount>2) ;; goto DIRSet ;if so, go set up the DIR; addwf srcCtlReg ;if not, then add the value of srcCount to srcCtlReg ;to set it to '00000000" (ASRC Port A) or "00000001" (ASRC Port B); bsf portA1Reg,6 ;set the mute bit in Port A #1 reg; bcf LATC,5 ;Clear RC5 to Set XSMT(RC5) to zero for DAC soft mute; call ASRCportA1Send ;Send the data to the ASRC to mute Port A; call ASRCsrcSend ; send the value of srcCtlReg to the ASRC to set the source; bcf portA1Reg,6 ;clear the mute bit in portA1Reg "00101001" for DIR, "00101011" for SRC; call ASRCportA1Send ;Send the data to the ASRC to unmute; call RPISend ;Update the RPI ; clrf knobFlag ;clear knobFlag for next interrupt; bsf LATC,5 ;Set RC5 to Set XSMT(RC5) to one to un-mute DAC; bsf LATC,4 ;Set RC4 high to notify the RPI of a need to send data; return ;done!DIRSet: clrf rxReg ;Initialize the rxReg value to zero movlw 0x02 subwf rxReg,f ;Set the rxReg value to correspond to srcCount-2 movlw 00000010B ;set the SRC source to DIR bsf portA1Reg,6 ;set the mute bit in Port A #1 reg bcf LATC,5 ;Clear RC5 to Set XSMT(RC5) to zero for DAC soft mute; call ASRCportA1Send ;Send the data to the ASRC to mute Port A; call ASRCsrcSend ;send the data to the ASRC to set SRC to DIR; call ASRCDIRSend ;send the data to the ASRC to set DIR to selected input bcf portA1Reg,6 ;clear the mute bit in portA1Reg "00101001" for DIR, "00101011" for SRCcall ASRCDIRSend ;Send the DIR data to the ASRC; call ASRCportA1Send ;Send the data to the ASRC to unmute; call RPISend ;Update the RPI clrf knobFlag ;clear knobFlag for next interrupt bsf LATC,5 ;Set RC5 to Set XSMT(RC5) to one to un-mute DAC bsf LATC,4 ;Set RC4 high to notify the RPI of a need to send data returnVolKnob: nop ;Determine CW or CCW Direction movlw 0x03 ;Mask for volume knob bits andwf knobState,1 ;mask off only vol bits in prior knob state andwf newKnobState,0 ;mask off only vol bits in current knob state movwf knbTemp ;save the new state in temp variable btfsc knbTemp,1 ;If bit 1 is set, then skip bsf STATUS,0 ;If bit 1 is set, then set carry bit in STATUS rlf knbTemp,1 ;shift new state (newKnobState) bits left (if Carry was set then it rotates in to bit 0 as Bit 1) movf knbTemp,w xorwf knobState,0 ;xor the new -in W- and prior knob state values movwf knbTemp btfsc knbTemp,1 ;if bit 1 is set, then turn was clockwise, so skip and increment goto VolDec ;otherwise turn was CCW, go decrement,VolInc: movf volMax,w ;check to see if volume is at max subwf volA,0 btfsc STATUS,2 goto NoVolChng ;if so, do nothing and return bcf volFlag,0 ;clear the volume flag (for increment) incf volA incf volB incf volC incf volD; call DACVolSend ;go update DAC1 to change the volume; call RPISend ;go update the RPI clrf knobFlag ;clear knobFlag for next interrupt movlw 0x04 ;Set RC3 high addwf LATC ;Write the value to the port to notify the RPI of a need to send data returnVolDec: movlw 0xFF addwf volA,0 ;check to see if volume is at min btfss STATUS,0 goto NoVolChng ;if so, do nothing and return bsf volFlag,0 ;set volFlag (for decrement) decf volA decf volB decf volC decf volD; call DACVolSend ;go update DAC1 to change the volume; call RPISend ;go update the RPI clrf knobFlag ;clear knobFlag for next interrupt movlw 0x04 ;Set RC3 high addwf LATC ;Write the value to the port to notify the RPI of a need to send data returnNoVolChng: clrf knobFlag ;clear knobFlag for next interrupt returnBalKnob: nop ;Determine CW or CCW Direction movlw 0x30 ;Mask for Balance knob bits andwf knobState,1 ;mask off only bal bits in prior knob state andwf newKnobState,0 ;mask off only bal bits in current knob state movwf knbTemp ;save the new state in temp variable btfsc knbTemp,5 ;If bit 5 is clear, then skip bsf knbTemp,3 ;If bit 5 is set, then set bit 3, to prepare for circular left shift rlf knbTemp,1 ;shift new state (newKnobState) bits left (if Bit 5 was set then it rotates in to bit 4 as Bit 5) movf knbTemp,w xorwf knobState,0 ;xor the new -in W- and prior knob state values movwf knbTemp btfsc knbTemp,5 ;if bit 5 is set, then turn was clockwise, so skip and increment balance goto BalDec ;otherwise turn was CCW, go decrement,BalInc: movf volMax,w ;check to see if volume is at max subwf volB,0 btfsc STATUS,0 goto NoBalChng ;if so, do nothing and return incf Bal,1 ;increment the balance value (so it can be saved for later in the RPI incf volB,1 ;and increase the VolB level by one step incf volD,1 ;and increase the VolD level by one step; call DACVolSend ;go update DAC1 to change the volume; call RPISend ;go update the RPI clrf knobFlag ;clear knobFlag for next interrupt movlw 0x04 ;Set RC3 high addwf LATC ;Write the value to the port to notify the RPI of a need to send data returnBalDec: movlw 0xFF addwf volB,0 ;check to see if volume B is at min btfss STATUS,0 goto NoBalChng ;if so, do nothing and return incf Bal,1 ;Otherwise increment the balance value movf Bal,w decf volB,1 ;and reduce the VolB level by one step decf volD,1 ;and reduce the VolD level by one step; call DACVolSend ;go update DAC1 to change the volume;; call RPISend ;go update the RPI clrf knobFlag ;clear knobFlag for next interrupt movlw 0x04 ;Set RC3 high addwf LATC ;Write the value to the port to notify the RPI of a need to send data returnNoBalChng: clrf knobFlag ;clear knobFlag for next interrupt returnEQKnob: nop ;Determine CW or CCW Direction movlw 0xC0 ;Mask for EQ knob bits andwf knobState,1 ;mask off only src bits in prior knob state andwf newKnobState,0 ;mask off only src bits in current knob state movwf knbTemp ;save the new state in temp variable btfsc knbTemp,3 ;If bit 7 is clear, then skip bsf knbTemp,1 ;If bit 7 is set, then set bit 5, to prepare for circular left shift rlf knbTemp,1 ;shift new state (newKnobState) bits left (if Bit 5 was set then it rotates in to bit 6 as Bit 7) movf knbTemp,w xorwf knobState,0 ;xor the new -in W- and prior knob state values movwf knbTemp btfsc knbTemp,7 ;if bit 7 is set, then turn was clockwise, so skip and increment EQ goto EQDec ;otherwise turn was CCW, go decrement EQEQInc: movf volMax,w ;check to see if volume is at max subwf volB,0 btfsc STATUS,2 goto NoEQChng ;if so, do nothing and return incf Equal,1 ;increment the balance value to save inthe RPI incf volC,1 ;and increase the VolC level by one step incf volD,1 ;and increase the VolD level by one step; call DACVolSend ;go update DACs to change the volume; call RPISend ;go update the RPI clrf knobFlag ;clear knobFlag for next interrupt movlw 0x04 ;Set RC3 high addwf LATC ;Write the value to the port to notify the RPI of a need to send data returnEQDec: movlw 0xFF addwf volC,0 ;check to see if volume B is at min btfss STATUS,0 goto NoEQChng ;if so, do nothing and return incf Equal,1 ;Otherwise increment the balance value movf Equal,w decf volC,1 ;and reduce the VolC level by one step decf volD,1 ;and reduce the VolD level by one step; call DACVolSend ;go update DACs to change the volume; call RPISend ;go update the RPI clrf knobFlag ;clear knobFlag for next interrupt movlw 0x04 ;Set RC3 high addwf LATC ;Write the value to the port to notify the RPI of a need to send data returnNoEQChng: clrf knobFlag ;clear knobFlag for next interrupt return;;******************************************************************************; SSP2_Handler;******************************************************************************;SSP2Handler: return;;******************************************************************************; SSP1_Handler;******************************************************************************;SSP1Handler: return;******************************************************************************;END
post edited by cogeniac - 2021/01/13 13:11:24
|