• AVR Freaks

Hot!IOC Issue on PIC 16LF18346 Has Returned

Author
cogeniac
Starting Member
  • Total Posts : 32
  • Reward points : 0
  • Joined: 2017/02/04 19:50:39
  • Location: 0
  • Status: offline
2021/01/14 16:39:12 (permalink)
4 (1)

IOC Issue on PIC 16LF18346 Has Returned

I thought I had this solved, but the IOC gremlin is back. Sorry for re-starting this topic...
 
I am using the PIC to read the outputs of a set of I-Q encoders. I have the encoders connected to RA0-RA5, and RC0 and RC1 (this will change to RC0-RC7 in a future version, which will simplify some of the code..but for now it is fixed by the encoder/PIC interface board). 
 
When it was working, I found that the code was identifying the incorrect encoder because I was not initializing the state properly. I added a port read prior to entering the main loop, and this killed the IOC function. There is obviously something I do not understand about this. 
 
I am running the 16LF18346 on a Curiosity debugger board operating with MPLABX. The code is PIC-AS. 
 
When it is running, I can see the PORTC pins change as I rotate the encoder connected to PORTC. I can also see that the PIE0 IOCIE bit is set, the RC0 and RC1 pins of the IOCCP and IOCCN registers are set, and PEIE, and GIE are set. 
I have a break point in the ISR, but rotating the encoder never causes the program to interrupt and get into the ISR. 
 
I have read things about reading the ports causing changes in the interrupt, and it was working before I added the additional port reads, but I am not sure if that's really the issue. 
 
Is there some other thing that needs to be configured to make this work?
 
Here is the currently non-working code. The IOC stuff is set up in the setup subroutine. I have left out the ISR for clarity.

 
 
 
;******************************************************************************
; 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 $
                           ;Capture the initial encoder state
    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
 ; movlb 0x07
 ; movlw 0xFF
 ; movwf IOCAF
 ; clrf IOCAF
 ; movwf IOCCF
 ; clrf IOCCF
 ; movlb 0x00
 
 
 
;*******************This loop continues until there is an interrupt
MainLoop:                   
    bsf INTCON,6          ;Enable all peripheral interrupts
    bsf INTCON,7          ;Enable all 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 how intFlag was set by the ISR
; 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?
    PAGESEL KnobHandler
    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
 
 
 
;******************************************************************************
;
; 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:
; 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)
;Output Ports:
; RC2=fSetA RC3=fSetB
; RC4=RPII2Ccall
; RC5= DACMute
;******************************************************************************
setup:
;******************************************************************************
; Disable Peripheral modules  NOT CURRENTLY BEING USED
;******************************************************************************
; 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 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
; movlb 0x02
; movf LATA,w           ;read the ports
; movf LATB,w
; movf LATC,w
;******************************************************************************
; 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 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 0x00
clrf intCounter         ;Clear the interrupt counter
clrf intFlag            ;Clear the interrupt type flag
clrf newKnobState       ;clear the knob state
clrf knobFlag           ;clear knob type flag
clrf fSetA 
clrf fSetB
clrf RPII2Ccall
clrf DACMute
return
 
 
 

 
post edited by cogeniac - 2021/01/14 16:42:44
#1

12 Replies Related Threads

    1and0
    Access is Denied
    • Total Posts : 12108
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/14 17:10:49 (permalink)
    0
    cogeniac
    I thought I had this solved, but the IOC gremlin is back. Sorry for re-starting this topic...

    Do NOT start another thread on the same topic -- https://www.microchip.com/forums/m1162550.aspx
     
    cogeniac
    I am using the PIC to read the outputs of a set of I-Q encoders. I have the encoders connected to RA0-RA5, and RC0 and RC1 (this will change to RC0-RC7 in a future version, which will simplify some of the code..but for now it is fixed by the encoder/PIC interface board). 
     
    When it was working, I found that the code was identifying the incorrect encoder because I was not initializing the state properly. I added a port read prior to entering the main loop, and this killed the IOC function. There is obviously something I do not understand about this. 

    Here's how I'd efficiently read an encoder  https://www.microchip.com...FindPost/1096341  which requires no state table and no memory of previous state.


    Anyway, I don't have time to study your code in details, but here's one observation regarding your code:

        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

        ; snipped

        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

    An easier way to test if a variable has any set bits is to test it for Zero, not the Carry. Also, it's more readable to use symbol names for the bits, such as C, Z, PEIE, GIE, etc.
     
    #2
    cogeniac
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2017/02/04 19:50:39
    • Location: 0
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/14 18:01:06 (permalink)
    0
    1and0
     
    Here's how I'd efficiently read an encoder  https://www.microchip.com...FindPost/1096341  which requires no state table and no memory of previous state.


    Anyway, I don't have time to study your code in details, but here's one observation regarding your code:

        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

        ; snipped

        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

    An easier way to test if a variable has any set bits is to test it for Zero, not the Carry. Also, it's more readable to use symbol names for the bits, such as C, Z, PEIE, GIE, etc.
     

    The link you posted is dead. 
    Why is it easier to test for zero than carry? 
    Does the STATUS register change with operations like MOVF name, STATUS? Otherwise you still need to do some arithmetic operation to affect the status bits. 
    #3
    ric
    Super Member
    • Total Posts : 29951
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/14 18:07:50 (permalink)
    +1 (1)
    cogeniac
    The link you posted is dead.

    Looks like th eforum mangled the link. Try:
    https://www.microchip.com/forums/FindPost/1096341
     

    Why is it easier to test for zero than carry?

    Because the Z flag is set as soon as you move the value into W.
     

    Does the STATUS register change with operations like MOVF name,

    Yes, as documented in the instruction set table in the datasheet.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #4
    cogeniac
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2017/02/04 19:50:39
    • Location: 0
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/14 18:43:39 (permalink)
    0
    Thanks ric.
     
    BTW following 1 and 0's suggestion...the PIC-AS assembler doesn't recognize register bit names 
     
    It likes btfss  STATUS,2, but not btfss STATUS,Z   
     
    It complains that Z is not a defined symbol. 
    #5
    ric
    Super Member
    • Total Posts : 29951
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/14 19:03:50 (permalink)
    0
    That's a pain, and should be rectified.
    In the meantime, you could fix that with
    Z EQU 2

    at the start of your source.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #6
    1and0
    Access is Denied
    • Total Posts : 12108
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/14 19:43:26 (permalink)
    +1 (1)
    Agree it's a pain, comparing to MPASM. ;)  For PIC-AS, it's
    STATUS,STATUS_Z_POSN

     
    <edit> PIC-AS is wordy and verbose. The "full" syntax is:
    BANKMASK(STATUS), STATUS_Z_POSN

     
    post edited by 1and0 - 2021/01/14 19:55:33
    #7
    1and0
    Access is Denied
    • Total Posts : 12108
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/14 21:02:56 (permalink)
    +1 (1)
    ... or you can use
    btfss   ZERO

    ;)
     
    Personally, I'd use this
    #define skpz    btfss    STATUS, STATUS_Z_POSN

    post edited by 1and0 - 2021/01/14 21:04:30
    #8
    cogeniac
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2017/02/04 19:50:39
    • Location: 0
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/15 09:54:03 (permalink)
    0
    I changed it to this: 
     
    movf   intCounter, w
    btfsc   STATUS,2
     
    Works a charm. 
     
    For some reason the IOC is now working. I think it is an issue with the debugger. I restarted it, and reset the brake points, and now I stop in the ISR when I turn a knob. 
    post edited by cogeniac - 2021/01/15 10:06:07
    #9
    1and0
    Access is Denied
    • Total Posts : 12108
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/15 10:59:17 (permalink)
    0
    cogeniac
    I changed it to this: 
     
    movf   intCounter, w

    Replace that with this
    movf    intCounter

    or this
    movf    intCounter, f

    so not to affect the WREG when testing for Zero.
    #10
    cogeniac
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2017/02/04 19:50:39
    • Location: 0
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/15 11:23:25 (permalink)
    +1 (1)
    OK. That's even cleaner. 
    Thanks!
     
    Still chasing some funky logic that may be related to this. I can accurately get the program to identify the proper encoder and the direction it turned when I increment it. But when I decrement it, for some reason I get extra bits in the wrong place, and then end up handling the wrong encoder. Probably some left over bits from some other operation getting into my flag files. 
     
    This may be old news, but I found that if you take the new state of I and Q, and rotate the bits, so I becomes Q, and Q becomes I, and then XOR this with the old state, the higher order bit of the result is 1 if the turn was CW and is 0 if the turn was CCW. 
     
    #11
    mpgmike
    Super Member
    • Total Posts : 533
    • Reward points : 0
    • Joined: 2014/01/23 17:27:06
    • Location: NJ
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/15 16:37:21 (permalink)
    +1 (1)
    I find myself griping quite a bit about the new PIC-AS and I'm more determined than ever now!

    I don't need the world to know my name, but I want to live a life so all my great-grandchildren proudly remember me.
    #12
    cogeniac
    Starting Member
    • Total Posts : 32
    • Reward points : 0
    • Joined: 2017/02/04 19:50:39
    • Location: 0
    • Status: offline
    Re: IOC Issue on PIC 16LF18346 Has Returned 2021/01/15 16:45:26 (permalink)
    0
    mpgmike
    I find myself griping quite a bit about the new PIC-AS and I'm more determined than ever now!


    It is definitely pickier and clunkier than MPASM...
    #13
    Jump to:
    © 2021 APG vNext Commercial Version 4.5