Program hangs on BSF

Thread Starter

geoffers

Joined Oct 25, 2010
487
Hi all,
I've a interesting quirk in a program on a pic 18f2523. Its in what is now quite a large program. In a subroutine I have this:

BTFSS STATUS,Z
BSF PUMPF, 1

Simple enough I thought, however it causes my program to hang (in a I2C communication waiting for a start)

If I change it to;

BTFSS STATUS,Z
CALL BITSET


BITSET BSF PUMPF,1
RETLW 0

All is well! I've checked I haven't mapped the file to a sfr and made sure its in the right bank. Ok I've got a way round it but it seems to me the first should work? Any ideas?
Cheers Geoff
 

JohnInTX

Joined Jun 26, 2012
4,787
What you have is functionally the same but CALLing BITSET takes a little more time to execute (and to skip, too) than the inline version. Maybe you have a tight timing condition that needs the extra Tcycs of calling the routine?

What is PUMPF?
 

ErnieM

Joined Apr 24, 2011
8,377
If memory serves me correctly a call takes two instruction cycles, so you can introduce the same delay by adding two NOP instructions between the bit test and the bit set.

WHY you would need such a delay entails knowing a bit more about the code and perhaps the circuit too.
 

Thread Starter

geoffers

Joined Oct 25, 2010
487
If memory serves me correctly a call takes two instruction cycles, so you can introduce the same delay by adding two NOP instructions between the bit test and the bit set.

WHY you would need such a delay entails knowing a bit more about the code and perhaps the circuit too.
 

Thread Starter

geoffers

Joined Oct 25, 2010
487
Whoops didn't mean to quote that! Thanks for the replies.
Funny thing is the program hangs without the routine being called (I think!). Pumpf is a user file for flags, the routine is managing files in a i2c eeprom. Would the btfss not just skip a nop if I put two in?
Cheers Geoff
 

Papabravo

Joined Feb 24, 2006
21,225
The two instructions you have showm cannot create a hang waiting for a condition that will never occur. Either the BSF instruction is executed or not depending on on the Z flag. We need more context.
 

Thread Starter

geoffers

Joined Oct 25, 2010
487
Hi all,
Thanks for the replies, I am now I must say completely baffled! I got the pickit 2 debugger on the job, put a breakpoint in at the start of the offending routine, the program doesn't call the routine before it hangs.
Here is the code around it;

MILKROUND CALL ETOP ;GET DATA FROM EEPROM

MOVF datai,W

BTFSS STATUS,Z
BSF PUMPF,1

MOVF datai,W

BTFSC STATUS,Z
CALL REMOVE

Even stranger is if I leave my bit set routine in the program it doesn't hang even if I don't call it?
I've just tried Ernies nop, if I put it before the first BTFSS STATUS,Z all is well.
Could there be a bug in the assembler, the routine appears to affect my program with out being called. I've even checked the breakpoint works by calling the routine, it does!! The program hangs while its trying to create a start condition on the I2C bus. Or doesn't the only change being a nop? :eek:
Cheers Geoff
 

Papabravo

Joined Feb 24, 2006
21,225
I still can't see the looping structure that would be the signature behavior of a program that was hung. I see multiple linear execution paths depending weather datai is zero or non zero. Why don't we focus on the instructions you've exposed to us as the source of the problem before going off to other issues.

Does the code fragment behave when datai is zero?
Does the code fragment behave when datai is non-zero?
Dose it misbehave regardless of being zero or non-zero
 

Thread Starter

geoffers

Joined Oct 25, 2010
487
Thanks for the replies,
This is the thing that's puzzling me, I've had this program running in various different forms but with the same basic structure, its been going literaly 24/7 for the last 18 months or so (feeding my calves :)) with very few problems. So I decide its time to polish things up a bit code wise.
I add the;
BTFSS STATUS,Z
BSF PUMPF,1
As papabravo says there is no loop to hang, with the debugger I can see its hanging at:

bstart_wait
btfss PIR1,SSPIF ; Check if operation completed
bra bstart_wait ; If not, keep checking

return

Which is a loop where it can hang, it hangs here with out calling the routine I've changed, which seems like it shouldn't be possible, take those two lines out it works, add a nop it works, add the subroutine to set that bit it works. All without calling what I've changed?? I've tried changing which file I use as PUMPF and must have programmed the chip a dozen times or more alternating having those two lines in or not, its consistant. I've used just under half the program memory, are there any boundries I could have crossed, I should be satisfied I can make it work I know but there must be something amis.

Thanks again Geoff
 

Papabravo

Joined Feb 24, 2006
21,225
Thanks for the replies,
This is the thing that's puzzling me, I've had this program running in various different forms but with the same basic structure, its been going literaly 24/7 for the last 18 months or so (feeding my calves :)) with very few problems. So I decide its time to polish things up a bit code wise.
I add the;
BTFSS STATUS,Z
BSF PUMPF,1
As papabravo says there is no loop to hang, with the debugger I can see its hanging at:

bstart_wait
btfss PIR1,SSPIF ; Check if operation completed
bra bstart_wait ; If not, keep checking

return

Which is a loop where it can hang, it hangs here with out calling the routine I've changed, which seems like it shouldn't be possible, take those two lines out it works, add a nop it works, add the subroutine to set that bit it works. All without calling what I've changed?? I've tried changing which file I use as PUMPF and must have programmed the chip a dozen times or more alternating having those two lines in or not, its consistant. I've used just under half the program memory, are there any boundries I could have crossed, I should be satisfied I can make it work I know but there must be something amis.

Thanks again Geoff
Now we are getting somwhere. The loop at bstart_wait is checking a single condition in a very tight loop, and this situation is called deadlock. Proper practice is to always check 2 or more conditions in any potential infinite loop. If you don't have two conditions then invent a timer that you can check. When the timer expires, you know there is a hardware fault caused by some, as yet unknown condition. At this point you can run a diagnostic, recovery, or RESET routine. Is the SSPIF for the Synchronous Serial Port really the bit you want? Is PIR1 really the register you want? Is SSPIF actually the correct definition for PIR1 on your particular PIC? I thought this was I2C.
 

takao21203

Joined Apr 28, 2012
3,702
I2C can hang up, program a timeout, power it through IO + do a cold restart of the chip.

It hangs up either when you dont meet the timing or when there's an erroneous sigal on the bus, its clear that happens if waiting loops are used.

You must have code that handles an unplugged I2C chip + detects it as well, not just a total reset.
 

Papabravo

Joined Feb 24, 2006
21,225
It comes back to me now. If the I2C protocol gets interfered with by another master or a device that drags either SDA or SCL low when it is not supposed to, it will hose the device that is trying to communicate. We had an idiot engineer who insisted on running the SDA and SCL through an FPGA to make PC board routing easier. He never could debug his bidirectional buffer algorithm inside the FPGA. After 5 PCB turns, I drove a stake in the ground and threatened to quit if the I2C lines kept going through the FPGA. I got my way and the I2C devices worked flawlessly after that.

http://www.wadia.com/en-us/products/121
 

takao21203

Joined Apr 28, 2012
3,702
i've done it with 16f59 + XC8, and in assempler some years ago.

Now of course, using 18F or PIC32, if the chip is removed, it is handled/recognized. It cant hang on error condition of any kind.
 

Thread Starter

geoffers

Joined Oct 25, 2010
487
Hi all,
Thanks for all the replies and advice, I can see putting a timer in for the I2C wait is a good idea, I've been fiddling with it this morning and wonder if I've had a page error or programming error with my Pickit 2, it was consistantly giving me the same problem, now after a shut down and reconnect it seems to be working as I expected it to!
I'm sorry to have bothered folks with something that seems to have 'fixed' itself, but as always I've learnt something:). Has anyone else had odd occurances like this?
Cheers Geoff
 

jpanhalt

Joined Jan 18, 2008
11,087
It is embarrassing to admit, but I had a problem like that this year.

The program worked fine until I added a subroutine. The subroutine worked fine in isolation and the whole program simulated fine. The problem seemed to be related to physical things, like a ZIF socket and so forth. When I discovered how to reproduce it, the problem was located in the program and fixed. None of those physical things nor subroutine were involved at all. One of the variables was whether I fondled the MCU, which was apparently enough to either charge or discharge some pins, and then the program would sometimes start and run properly for hours. It could even be turned off and on in that period and still work. But, if it was turned off, let sit all night, then restart gave the lockup again. That was the first sign I had that led me to the solution.

If your problem is just a one-time event, there is probably nothing you can do about it except worry. If you get into a situation where the problem recurs, then you have a chance to solve it, even if there is still an element of unpredictability to it.

John
 
Top