View Full Version : Help needed in undertanding USB Poll.

1st October 2012, 14:53
I am trying to integrate USB into my P-RTOS system using the 18F46J50

Initially, I go though an enumerate process which polls the USB until it gets a connection (USB_tConnected = 1).
Once I have a connection I start a keep alive timer which calls USBPoll every 10mSecs.
This is the code for the keep alive timer:

SpikeRC2 ' Debug - Generate a short pulse so I can monitor Polling with a scope.
USBPoll ' Keep the connection alive
If USB_tConnected = 0 Then ' if we still have lost the connection
OSSignalBinSem E_USBDetached ' Signal Detached (P-RTOS event)
OSStopCycTmr C_USBPoll ' Stop keep alive timer

With the code above I get one spike then it stops.
I am assuming when USB_tConnected = 0 then it is not connected.

Looking at USB_MemAlloc USB_tConnected is aliased to Status.0. In the manual, Status.0 in the USB context is mentioned in USBIn/USBOut. I assume in a poll is should return Status.0 as a 1 whereas to monitor the USB dp ram available I need to look for a 0. If I reverse it and test for USB_tConnected = 1 polling continues and I can see my spike every 10 mSecs until I get the Connected beep from windows at which point the whole program crashes.

It seems that USBPoll never returns USB_tConnected = 1 state except for the first poll during enumeration.

I am using a Software stack - could this have an effect.

What am I missing or is this not the way to keep a USB connection alive.

1st October 2012, 16:37
Further to this I have tried adding a simple USBPoll to the Mouse demo:

Device = 18F46J50 ' Choose a device with on-board full speed USB
Declare Xtal = 48 ' Set the oscillator speed to 48MHz (using a 12MHz crystal)
Declare Optimiser_Level = 2
Declare Dead_Code_Remove = On

Include "Mouse_Descriptor.inc" ' Include the HID mouse descriptors and the USB routines

Dim Buffer[4] As Byte
Dim Loop_Count As Byte
Dim Position As Byte

Symbol Carry_Flag = STATUS.0 ' Set if microcontroller does not have control over the DP Buffer

' The main program loop starts here
TRISA = 0001 ' All Port A Bit 0 input, all other bits Outputs
TRISB = 000000 ' All Port B Outputs
TRISC = 000000 ' Set port C to output except RX
Hserial_Baud = 9600 ' Set baud rate for USART 1

OSCTUNEbits_PLLEN = 1 ' Enable the device's PLL
DelayMS 10 ' Wait for things to stabilise
Clear Buffer ' Clear the buffer before we start

USBInit ' Initialise USB
Repeat ' \
USBPoll ' Wait for the USB interface to become attached
Until USB_tConnected = 1 Or USB_tConfigured = 1 ' /

HRSOut "Polling at 10 mSec"

While 1 = 1
DelayMS 10
If USB_tConnected = 0 Or USB_tConnected = 0 Then
HRSOut "disconnected"

This is essentially the Mouse code with the Mouse move taken out, replaced by a USBPoll.

This fails to compile with the error __USBPoll symbol not previously defined.

It seems unless USBOut is called somewhere in the code it will not compile. Is this correct behaviour as it is very confusing.

1st October 2012, 16:54
I also notice that when running a near virgin version of the Mouse Demo whilst it works...
ISIS reports [PIC18 MEMORY] PC= 0x0708. Indirection address [FSR0 = 0x0708]. Indirection address [FSR0=0x0708], W=1] for PLUSW2 register is outside data memory. Zero returned.

The only change I made to it was to change the device from 26J45 to 46J45.

According to ISIS the error occurred in PDS\Includes\sources\USB_DEV.inc at a line
cpfslt PRODL ' Find the amount of bytes to send this time.

1st October 2012, 20:41
Having reached the conclusion that the only way to use USBPoll in a loop, how should I detect disconnect.
Is it adequate to declare the connection lost after "N" attempts or is there another way?
I implemented this approach but even after 400 Polls it still hadn't maintained the connection.
After about 2-3 seconds the Polling stopped. It seems to stop at this point regardless of the number of Polls being allowed.
I placed the code inside the USBPoll Loop. See below...

Clear USBPollCount
Inc USBPollCount
If USBPollCount = 400 Then
OSSignalBinSem E_USBDetached ' Send a message that I have lost the connection
OSStopCycTmr C_USBPoll ' Stop this routine
Until USB_tConnected = 1

3rd October 2012, 08:50
Not getting any feedback on this, perhaps I am not asking the right question.

The only way USBPoll will work seems to be in a loop which tests for Status.0 = 1 after issuing a USBPoll.
This means that the process is blocking, so if a connection is subsequently lost, the program will hang in that loop.

How is it possible to detect when this situation occurs so that the polling can be stopped thus unblocking the program?

3rd October 2012, 13:45
There is a flag you can test once its connected to tell is the connection has been lost.

Symbol IDLE_IF = UIR.4 ' Idle Detect Interrupt bit
Symbol SUSPND_USB = UCON.1 ' Suspend USB bit

If IDLE_IF = 1 Then ; Turn off all current drawing hardware
GpsEnable = GPSPowerOff
SUSPND_USB = 1 ; Shut down the USB
@ Sleep ; and put the pic to sleep

But I have not found it to be 100% reliable

3rd October 2012, 20:24
Thanks, I'll have a play. I have added a stop USB facility which stops the USB successfully but I can't restart it again.

3rd October 2012, 21:16
Thanks, I'll have a play. I have added a stop USB facility which stops the USB successfully but I can't restart it again.

I remember someone (I think it was Joe captain) that you need to physically unplug the USB and plug it in again to retsart it again. Never explored too much about USB so I cannot help further.

4th October 2012, 12:49
Can't get it to work at all with the current USB code. See link (http://www.protonbasic.co.uk/showthread.php/67983-USB-Suspend)