Program hangs on BSF

Discussion in 'Embedded Systems and Microcontrollers' started by geoffers, Dec 10, 2014.

  1. geoffers

    Thread Starter Active Member

    Oct 25, 2010
    239
    6
    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
     
  2. JohnInTX

    Moderator

    Jun 26, 2012
    2,341
    1,024
    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?
     
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    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.
     
  4. geoffers

    Thread Starter Active Member

    Oct 25, 2010
    239
    6
     
  5. geoffers

    Thread Starter Active Member

    Oct 25, 2010
    239
    6
    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
     
  6. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    Um, yeah, it would. So try putting them BEFORE the bit test.
     
  7. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,676
    899
    Can you please post a few lines around the BTFSS, both before and after (at least 3 after)?

    John
     
  8. Papabravo

    Expert

    Feb 24, 2006
    10,136
    1,786
    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.
     
  9. geoffers

    Thread Starter Active Member

    Oct 25, 2010
    239
    6
    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
     
  10. Papabravo

    Expert

    Feb 24, 2006
    10,136
    1,786
    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
     
  11. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,386
    1,605
    The assembler does NOT have a bug.
     
  12. geoffers

    Thread Starter Active Member

    Oct 25, 2010
    239
    6
    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
     
  13. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,676
    899
    Deleted. Answer was wrong.

    John
     
    Last edited: Dec 11, 2014
  14. Papabravo

    Expert

    Feb 24, 2006
    10,136
    1,786
    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.
     
    geoffers likes this.
  15. BobTPH

    Active Member

    Jun 5, 2013
    782
    114
    If things change when inserting / removing code that is not executed, a likely cause is program page errors.

    bob
     
    geoffers likes this.
  16. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    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.
     
    geoffers likes this.
  17. Papabravo

    Expert

    Feb 24, 2006
    10,136
    1,786
    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
     
  18. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    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.
     
  19. geoffers

    Thread Starter Active Member

    Oct 25, 2010
    239
    6
    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
     
  20. jpanhalt

    AAC Fanatic!

    Jan 18, 2008
    5,676
    899
    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
     
Loading...