Software on PIC will come in loop after disconnect USB connection


Closed Thread
Results 1 to 16 of 16
  1. #1
    Join Date
    Sep 2007
    Posts
    9

    Default Software on PIC will come in loop after disconnect USB connection

    My application is connected via USB to a PC. Within my application I'm using a 18F2550 PIC. A status change of a I/O will be send via USB to PC.

    The code which I'm using for outgoing:

    USBwriteStatus:
    USBService ' Must service USB regularly
    USBOUT 3, USBBUFFER ,CNT_UIT, USBWRITESTATUS
    RETURN

    The problem is when I disconnect the USB cable it seems that the the PIC program commes in an unendless loop of "USBwriteStatus. I have mode some modifications, see below, however this will still not solve the problem.

    USBwriteStatus:
    USBService ' Must service USB regularly
    USBOUT 3, USBBUFFER ,CNT_UIT, exitusbwritestatus
    exitusbwritestatus:
    RETURN

    When I'm taking this SUB out of my application everything works also without USB connection to PC.

    Is there somebody who knows what I'm doing wrong?
    Is it possible to see the status of the USB connection (connect/disconnect) before calling the SUB USBwriteStatus.

  2. #2
    Join Date
    Jul 2003
    Posts
    2,405

    Default

    Hi Ronald,

    There's a very simple solution to this. Assign a single I/O-pin as the USB bus-attach input.

    Here's how;

    ground --100k resistor----PIC input pin ----4.7k resistor----+V from USB connector.

    When the USB cable is plugged in, the input will see +V from the USB port. When the USB
    cable is removed, it will see ground.

    Don't attempt to send/receive any data until you see +V on the USB bus-attach input pin.
    Very simple. Very effective.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  3. #3
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    257

    Default

    Bruce,

    Thats a great tip, (although I havent seen this problem come up before).

    I'm wondering if this would be concidered a fail safe "Design Rule" and should be implemented into all USB PIC based circuits?

    Cheers
    Squib

  4. #4
    Join Date
    Jul 2003
    Posts
    2,405

    Default

    Hi Squib,

    I can't take credit for the idea. It's an option on the Microchip USB development board, and
    in the USB C firmware.

    There's no reason to enable the USB module if it's not attached, so it's not a bad idea to
    add in.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  5. #5
    Join Date
    Sep 2007
    Posts
    9

    Default

    Hi Bruce, thank you for your almost exelent and simple sollution. Almost exelent because it will cost me 1 I/O and I don't have one I/O left. I have made a mistake because after testing this code again it was working.

    USBwriteStatus:
    USBService
    USBOUT 3, USBBUFFER ,CNT_UIT, exitusbwritestatus
    exitusbwritestatus:
    RETURN

    However this sollution has a disadvantage because when the outgoing USBBuffer is full it will also goto "exitusbwritestatus" without sending the information via USB, so some status information from PIC to PC will be lost.

  6. #6
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    You should be able to determine if it's plugged-in or not by monitoring the usb_device_state variable.
    Code:
    usb_device_state   VAR BYTE EXT
    CONFIGURED_STATE   CON EXT
    
    IF (usb_device_state = CONFIGURED_STATE) THEN
        ; OK to send
    ELSE
        ; Detached or Enumerating, don't try to send.
    ENDIF
    DT

  7. #7
    Join Date
    Sep 2007
    Posts
    9

    Default

    Hi Darrel, I've tried it however it is not working. I've used the following.

    IF (usb_device_state = CONFIGURED_STATE) THEN
    high dataled
    ELSE
    low dataled
    ENDIF

    During USB connection the dataled is on. However the status of the dataled will not change when the USB cable will be disconnected. When I connect the cable in, for short time the dataled will be turned off and within about 300msec it will be turned on. I think that the Led will be turned off during enumeration.

    Do I something wrong why it is not working?

  8. #8
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Hi Ronald,

    I've done something similar before, but I didn't have a USB breadboard handy at the time I replied.

    I've dug out the old mister_e usbdemo breadboard.
    Blown off the dust with a half a can of "Dust-Off" ...

    ... and am taking a look.

    Hoping I can figure it out.

    DT

  9. #9
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    257

    Default

    Ditto, Doesn't work for me either...

    Cheers
    Squib

  10. #10
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Quote Originally Posted by Squibcakes View Post
    Ditto, Doesn't work for me either...

    Cheers
    Squib
    That's right. Kick him while he's Down.

    Working on it.

    DT

  11. #11
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Yup, you 2 were right. It only picked up the Plugged, not the un-plugged state.

    After a bit of re-thinking, ...
    This seems to work pretty good.

    The way it works is by watching the IDLEIF and SOFIF interrupt flags.
    IDLEIF is triggered if the USB buss is idle for more than 3ms.
    SOFIF is the Start-Of-Frame flag, which is a good indication of buss activity.

    If it sees a SOFIF it sets the Plugged bit, and if it sees an IDLEIF flag it clears the Plugged bit.
    Then in the Main loop you can use that flag to stop sending data if not Plugged.

    This example uses Interrupts, but you can do the same thing without interrupts, just be sure to check for the flags before servicing USB.
    The example turns on LED1 when Plugged, and toggles a second LED to show that the Main loop keeps executing when un-plugged.
    Code:
    DEFINE OSC 48          
    CLEAR
    
    INCLUDE "DT_INTS-18.bas"    ' Base Interrupt System
    
    ASM
    INT_LIST  macro    ; IntSource,          Label,  Type, ResetFlag?
            INT_Handler    USB_INT,  _DoUSBService,   ASM,  yes
        endm
        INT_CREATE               ; Creates the interrupt processor
    endasm
    
    UIE     VAR BYTE EXT
    UEIE    VAR BYTE EXT
    UIR     VAR BYTE EXT
    IDLEIF  VAR UIR.4
    SOFIF   VAR UIR.6
    Plugged VAR BIT 
    
    LED1    VAR  PORTB.0 : LOW LED1
    LED2    VAR  PORTC.1 : LOW LED2
    
    
    USBBufferCount  Var Byte
    DataToSend      var byte[8]
    USBBufferCount = 8
    
    pause 500 ' initialise USB...
    usbinit
    usbservice
    UIE = $7F
    UEIE = $9F
    @   INT_ENABLE  USB_INT
    
    ;----[Main program starts here]-----------------------------------------------
    Main:
        LED1 = Plugged        ; LED1 indicates OK to Send
        IF Plugged then       ; if bus available, transmit data
            USBOut 1, DataToSend, USBBufferCount, Main  
        ENDIF
        toggle LED2           ; blink LED2 to show Main Loop is still running
        pause 100    
    goto Main                                     
    
    ;----[USB Interrupt Handler]--------------------------------------------------
    DoUSBService:
        IF IDLEIF THEN Plugged = 0
        IF SOFIF  THEN Plugged = 1
        usbservice
    @   INT_RETURN
    HTH,
    DT

  12. #12
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    257

    Default

    Hi DT,

    Great! I tried this one and it works. Good one.

    However, I've tried to incorp. it into an existing program and it doesn't work.

    Your code seems to indicate that the USBSERVICE routine is continually called by the USB_int handler. How often does this interrupt? Only when it is plugged / unplugged or all the time?

    The problem is that I'm servicing the USBSERVICE through a 1msec Timer1 interrupt handler and trying to read the flags in that interrupt but they don't set.

    Code:
    '---[TMR1 - interrupt handler]---------------------------------------------------
    USB_SERVICE:                    ' COMES HERE 1msec TO SERVICE THE USB PORT
            
         T1CON.0 = 0                ' TURN OFF TIMER                 
            TMR1L = COUNTER1.byte0  ' RELOAD TIMER  LOW
            TMR1H = COUNTER1.byte1  ' RELOAD TIMER HIGH
            IF IDLEIF THEN Plugged = 0
            IF SOFIF  THEN Plugged = 1
            USBService	            ' KEEP USB ALIVE
         T1CON.0 = 1                ' TURN ON TIMER
        
        
    @ INT_RETURN
    The way I see it is that SOFIF should always be set since I'm servicing USB every 1 msec untill I disconnect the USB cable.

    I would do away with the Timer1 Interrupt altogether and use USB_INT but how often does the USB_int get called?


    Cheers
    Squib
    Last edited by Squibcakes; - 24th October 2007 at 01:51.

  13. #13
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Using the USB_INT source is much more efficient than using a 1ms timer.

    During Enumeration it may only be a few microseconds between interrupts, and there are a lot of them. Consequently, it connects to the PC much faster.

    But during normal operation, it drops to about every 10-20 milliseconds, although that depends on the polling time set up in the descriptor.

    When the cable is un-plugged, you don't get any USB interrupts at all (after the IDLE int).

    Plus using the USB_INT frees up a Timer.

    ADDED:
    But that doesn't explain why the Plugged example above doesn't work with the Timer Interrupts. It should work.

    Are there any other USBSERVICE statements in the program?
    There should only be 1.
    DT

  14. #14
    Join Date
    Oct 2003
    Location
    Australia
    Posts
    257

    Cool

    DT,

    What you say makes sense and I like the fact that it frees up a Timer.

    I found in my original program that I missed (during a cut and paste) the section where you loaded UIE and UEIE with values... which would explain why it wasn't running with my timer ints....

    The whole point of this exercise is to "error trap" the pic for any unforseen conditions, eg I've seen the PIC hang sometimes when shutting down pc coms programs that don't close the port nicely. Hopefully this will stamp that one out. LOL

    Now, since you have all the answers, do you have tonight's Lotto Numbers by any chance?

    Cheers
    Squib

  15. #15
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Quote Originally Posted by Squibcakes View Post
    ... do you have tonight's Lotto Numbers by any chance? ...
    Oh sure ... Here's the numbers for California's Super Lotto Plus, for all future draws.
    Just come back here before each game for the new numbers.



    Of course it would have been better, had you asked for "tonight's Winning Lotto Numbers"!

    DT

  16. #16
    Join Date
    Aug 2003
    Posts
    985

    Default

    Lol,
    NVM. if the game is played long enough, they'll win at some stage.

Similar Threads

  1. Simple USB Comms Problem
    By awmt102 in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 6th January 2010, 20:17
  2. Using input from Switch to control a loop
    By MrRoboto in forum mel PIC BASIC
    Replies: 9
    Last Post: - 2nd February 2009, 05:02
  3. Reading a slave USB with a pic
    By pcaccia in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 25th October 2008, 12:00
  4. Two USB devices with same software, easyHID
    By Josuetas in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 31st October 2007, 06:19
  5. PIC 2 PIC wireless connection
    By MegaADY in forum General
    Replies: 1
    Last Post: - 24th June 2004, 01:46

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts