Also keep it simple, why are you storing variables in different banks without needing so? It only adds bank switching mess.
Did a bit of work, though incomplete, I think it will work better, follow program flow.
You still need to implement timer2 init, DecimalPoint, MeasureUnit, and probably other fixes.
All BANKSEL should be checked out. I have not taken extreme care of all bank switching.
But shows the idea, and the way to avoid unwanted/undefined behavior.
List
cblock 0x20 ;0x20 thru 0x6F are GP RAM in Bank0
timeout
bit_count
data_count
d5 ;read data, sign bit
d6 ; " ,MSD (BCD)
d7 ; " ,BCD
d8 ; " ,BCD
d9 ; " ,BCD
d10 ; " ,BCD
d11 ; " ,LSD (BCD)
d12 ; " ,decimal point
d13 ; " ,units (0x0=mm, 0x8=inch)
endc
IOCIF_init ;(IOCIF=INTCON,0) on positive edge of Mitutoyo clock (Clk_in)
BANKSEL IOCAN ;
bsf IOCAN,Clk_in ;RA4 negative edge |B7
clrf IOCAF ;clear all IOC flags |B7
clrf INTCON ;INTCON,IOCIE ;enable IOC |B?
FSR0_init
movlw high(d5) ;Mitutoyo little endian MSByte has lowest number |B7
movwf FSR0H ;used same endian here |B7
movlw low(d5) ; |B7
movwf FSR0L ; |B7
Main
movlw low(d5) ;initialize FSR0 for new data |B7
movwf FSR0L ;
BANKSEL LATA ;
bsf LATA,Req ;request data (short !REQ to ground) |B2
call GetData ; |B2
btfsc timeout,1 ;Check if timeout ocurred
bra Timeout
call ClrDisplay ; |B7
call Printf ; |B7
call ClrData ;returns |B7
bra Main
GetData
movlw 8 ;init values
movwf bit_count
movlw 13
clrf data_count
GetNibble
call GetClk ;Wait for clock
btfsc timeout,1 ;Check if timeout ocurred
return ;Timeout ocurred
movfw PORTC ;Read PORTC
iorwf INDF0,f ;OR value with current nibble data
decfsz bit_count,f ;Check if nibble is done
bra GotNibble ;Done
rrf INDF0,f ;Not done. Rotate right, make room for next bit (Data is stored in the 4 MSB)
bra GetNibble ;Continue
ParseNibble
swapf INDF0,flag ;Swap nibbles
movlw 10 ;Subtract 10
subwf data_count,w ;To the data count
btfsc STATUS,C ;Check for carry bit (If set, we already received more than 4 nibbles, not header)
bra Check_header ;Less than 5 bytes received, check for good header
movlw 9 ;This is not header, subtract 9
subwf data_count,w ;To the data count
btfss STATUS,Z ;Check for zero bit
bra CheckData ;Not sign data, skip
movlw 0x20 ;This is d5, Sign data. Load ASCII "Space" into w
addwf INDF0,f ;Add to sign data (Convert to space, or later to '-' symbol)
movlw 0 ;Preload w with 0 for the next step
btfsc INDF0,0 ;Check for sign LSB (Now it would be 0x21)
movlw 0xC ;Override w with 0xC, convert to '-' symbol by adding 0xC (0=x21->0x2D)
addwf INF0,f ;Update symbol data
bra Nibble_OK ;Done
CheckData
movlw 2 ;Subtract 2
subwf data_count,w ;To the data count
btfsc STATUS,C ;Check for carry bit (If set, we already received more than 4 digits)
bra DecimaPoint ;This is decimal point
movlw 1 ;Subtract 1
subwf data_count,w ;To the data count
btfsc STATUS,C ;Check for carry bit (If set, we already received more than 4 digits)
bra MeasureUnit
DecimalPoint
;blah blah
bra ParseDone ;Done
MeasureUnit
;blah blah
bra ParseDone ;Done
movlw 0x30 ;Add 0x30
addwf INF0,f ;To current data, to convert to ASCII
Nibble_OK
incf FSR0L,f ;point to next data
bra ParseDone ;Done
Check_header
movlw 0xF ;Subtract 0xF <--- For non-inverted data input.
subwf INDF0,w ;From current nibble <--- For non-inverted data input.
movfw INDF0 ;Read nibble <--- For inverted data input.
btfss STATUS,Z ;check for zero bit (We should have received 0xF, header nibble)
bra Nibble_OK ;OK, Receive next nibble
call SetTimeout ;Bad header data, trigger a timeout
return ;Return to main
GotNibble
bra ParseNibble
ParseDone
decfsz data_count,f ;Decrease data count, got all 13 nibbles?
bra NextNibble ;No, continue
movlb 0 ;Yes
return ;
GetClk
clrf IOCAF ;Get ready to detect next bit |B7
clrf TMR2,f ;Clear the counter
clrf timeout,f ;Clear the timeout flag
bcf PIR,TMR2IF ;Clear timer flag
btfsc IOCAF, Clk_in ;check clock flag for next bit |B7
return ;Got bit
btfss PIR,TMR2IF ;Check for timer overflow (Timeout)
bra GetClk ;No timeout, keep waiting
SetTimeout
bsf timeout,1 ;Set timeout flag
return ;Timeout ocurred
Timeout
BANKSEL LATA ;
bcf LATA,Req ;Release request data
BANKSEL TMR2 ;
clrf TMR2,f ;Clear the counter
bcf PIR,TMR2IF ;Clear timer flag
Timeout_wait
btfsc PIR,TMR2IF ;Check for timer overflow (Timeout)
bra Main ;Timeout done, restart
btfss IOCAF, Clk_in ;Not done, check if clock flag is set
bra Timeout_wait ;Clock flag not set, keep waiting
clrf TMR2,f ;Got clock signal! Clear the counter (Reset the timeout wait)
bcf PIR,TMR2IF ;Clear timer flag
clrf IOCAF ;Get ready to detect next bit
bra Timeout_wait ;Keep waiting
END