USB: URB_FUNCTION_GET_CURRENT_FRAME_NUMBER

Hello,

I’m developing a Windows driver for a device running with USB 2.0 under
Highspeed.

I have some strange suspicion that the current frame number I got via
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER is not correct, it’s value looks
like it is “one too high”.

To check this I did some measurements (just for testing!! :wink: ):

In my driver I detect a USB StartOfFrame by calling
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER in a loop until the frame number
changes (change of frame number indicates a SOF, at least more or less
exact …). Then I send some data on the USB bus with a bulk OUT transfer.
I recorded the data with my USB analyzer - here I have the frame number,
too. The result was that frame numbers are always different!!! And: The
one from the USB Analyzer is the smaller one! In other words: The data are
on the USB bus before I have sent them within my driver. Ok, and this
simply can’t be true … So I think that something is wrong in the way I
send
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER or with the number I get back from.
But what??

Btw: Both the URB_FUNCTION_GET_CURRENT_FRAME_NUMBER’s and the USB
analyzer’s frame number is zero based.

Has anybody seen something similar? Any explanation?
Or am I doing some things that should never ever be done?

Thanx for every hint!

regards
Olav

Instead of sending a URB, trying using the direct function as exported
by the usb core. Send a IRP_MJ_PNP/IRP_MN_QUERY_INTERFACE with an
interface buffer of USB_BUS_INTERFACE_USBDI_V0, interface guid of
USB_BUS_INTERFACE_USBDI_GUID and a version of USB_BUSIF_USBDI_VERSION_0
(all found in usbbusif.h) If you don’t know how to send a QI to the
core, look it up in the DDK. The toaster sample also demonstrates how
to send a QI down the stack. The QueryBusTime will return the current
frame number.

The data returned from the direct function call might not be any better,
but it is another piece of information for you to be able to use.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Olav
Sent: Wednesday, May 04, 2005 4:55 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] USB: URB_FUNCTION_GET_CURRENT_FRAME_NUMBER

Hello,

I’m developing a Windows driver for a device running with USB 2.0 under
Highspeed.

I have some strange suspicion that the current frame number I got via
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER is not correct, it’s value looks
like it is “one too high”.

To check this I did some measurements (just for testing!! :wink: ):

In my driver I detect a USB StartOfFrame by calling
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER in a loop until the frame number
changes (change of frame number indicates a SOF, at least more or less
exact …). Then I send some data on the USB bus with a bulk OUT
transfer.
I recorded the data with my USB analyzer - here I have the frame number,
too. The result was that frame numbers are always different!!! And: The
one from the USB Analyzer is the smaller one! In other words: The data
are
on the USB bus before I have sent them within my driver. Ok, and this
simply can’t be true … So I think that something is wrong in the way I
send
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER or with the number I get back
from.
But what??

Btw: Both the URB_FUNCTION_GET_CURRENT_FRAME_NUMBER’s and the USB
analyzer’s frame number is zero based.

Has anybody seen something similar? Any explanation?
Or am I doing some things that should never ever be done?

Thanx for every hint!

regards
Olav


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hello Doron,
hello all,

first of all thank you for your help!

I tried to use “QueryBusTime” retrieved from “USB_BUS_INTERFACE_USBDI_V0”,
but it returns the same value as I got by sending the URB.
Additionally I changed the firmware to get the USB frame number when the
transfer (a short packet containing my test data only) is received on the
card’s USB controller - it shows the same frame and micro frame number as
my USB analyzer does (e.g. driver’s frame nbr is 1188 before sending,
firmware and USB analyzer show 1187,7 (frame nbr, micro frame nbr) after
receiption), so one more indication that the problem is somewhere on the
PC side …

Olav

Subject: RE: USB: URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
From: “Doron Holan”
Date: Wed, 4 May 2005 09:17:00 -0700
X-Message-Number: 10

Instead of sending a URB, trying using the direct function as exported
by the usb core. Send a IRP_MJ_PNP/IRP_MN_QUERY_INTERFACE with an
interface buffer of USB_BUS_INTERFACE_USBDI_V0, interface guid of
USB_BUS_INTERFACE_USBDI_GUID and a version of USB_BUSIF_USBDI_VERSION_0
(all found in usbbusif.h) If you don’t know how to send a QI to the
core, look it up in the DDK. The toaster sample also demonstrates how
to send a QI down the stack. The QueryBusTime will return the current
frame number.

The data returned from the direct function call might not be any better,
but it is another piece of information for you to be able to use.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Olav
Sent: Wednesday, May 04, 2005 4:55 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] USB: URB_FUNCTION_GET_CURRENT_FRAME_NUMBER

Hello,

I’m developing a Windows driver for a device running with USB 2.0 under
Highspeed.

I have some strange suspicion that the current frame number I got via
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER is not correct, it’s value looks
like it is “one too high”.

To check this I did some measurements (just for testing!! :wink: ):

In my driver I detect a USB StartOfFrame by calling
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER in a loop until the frame number
changes (change of frame number indicates a SOF, at least more or less
exact …). Then I send some data on the USB bus with a bulk OUT
transfer.
I recorded the data with my USB analyzer - here I have the frame number,
too. The result was that frame numbers are always different!!! And: The
one from the USB Analyzer is the smaller one! In other words: The data
are
on the USB bus before I have sent them within my driver. Ok, and this
simply can’t be true … So I think that something is wrong in the way I
send
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER or with the number I get back
from.
But what??

Btw: Both the URB_FUNCTION_GET_CURRENT_FRAME_NUMBER’s and the USB
analyzer’s frame number is zero based.

Has anybody seen something similar? Any explanation?
Or am I doing some things that should never ever be done?

Thanx for every hint!

regards
Olav


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=3D256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

----------------------------------------------------------------------

I asked someone who works on the USB stack and they referred to the EHCI
spec. I hope that helps.

d

http://www.intel.com/technology/usb/download/ehci-r10.pdf

EHCI Revision 1.0 3/12/2002

4.5 Periodic Schedule Frame Boundaries vs Bus Frame Boundaries

The USB Specification Revision 2.0 requires that the frame boundaries
(SOF frame number changes) of the high-speed bus and the full- and
low-speed bus(s) below USB 2.0 Hubs be strictly aligned. Super-imposed
on this requirement is that USB 2.0 Hubs manage full- and low-speed
transactions via a micro-frame pipeline (see start- (SS) and complete-
(CS) splits illustrated in Figure 4-6). A simple, direct projection of
the frame boundary model into the host controller interface schedule
architecture creates tension (complexity for both hardware and
software) between the frame boundaries and the scheduling mechanisms
required to service the full- and low-speed transaction translator
periodic pipelines.

The simple projection, as Figure 4-6 illustrates, introduces
frame-boundary wrap conditions for scheduling on both the beginning and
end of a frame. In order to reduce the complexity for hardware and
software, the host controller is required to implement a one micro-frame
phase shift for its view of frame boundaries. The phase shift eliminates
the beginning of frame and frame-wrap scheduling boundary conditions.

The implementation of this phase shift requires that the host controller
use one register value for accessing the periodic frame list and another
value for the frame number value included in the SOF token. These two
values are separate, but tightly coupled. The periodic frame list is
accessed via the Frame List Index Register
(FRINDEX) documented in Section 2.3.4 and initially illustrated in
Section 4.4. Bits FRINDEX[2:0], represent the micro-frame number. The
SOF value is coupled to the value of FRINDEX[13:3]. Both FRINDEX[13:3]
and the SOF value are incremented based on FRINDEX[2:0]. It is required
that the SOF value be delayed from the FRINDEX value by one micro-frame.
The one micro-frame delay yields host controller periodic schedule and
bus frame boundary relationship as illustrated in Figure 4-7. This
adjustment allows software to trivially schedule the periodic start and
complete-split transactions for fulland low-speed periodic endpoints,
using the natural alignment of the periodic schedule interface. The
reasons for selecting this phase-shift are beyond the scope of this
specification.

Figure 4-7 illustrates how periodic schedule data structures relate to
schedule frame boundaries and bus frame boundaries. To aid the
presentation, two terms are defined. The host controller’s view of the
1- millisecond boundaries is called H-Frames. The high-speed bus’s view
of the 1-millisecond boundaries is called B-Frames.

H-Frame boundaries for the host controller correspond to increments of
FRINDEX[13:3]. Micro-frame numbers for the H-Frame are tracked by
FRINDEX[2:0]. B-Frame boundaries are visible on the high-speed bus via
changes in the SOF token’s frame number. Micro-frame numbers on the
high-speed bus are only derived from the SOF token’s frame number (i.e.
the high-speed bus will see eight SOFs with the same USB 2.0 frame
number value). H-Frames and B-Frames have the fixed relationship (i.e.
B-Frames lag H-Frames by one micro-frame time) illustrated in Figure
4-7.

The host controller’s periodic schedule is naturally aligned to
H-Frames. Software schedules transactions for full- and low-speed
periodic endpoints relative the H-Frames. The result is these
transactions execute on the high-speed bus at exactly the right time for
the USB 2.0 Hub periodic pipeline.

As described in Section 2.3.4, the SOF Value can be implemented as a
shadow register (in this example, called SOFV), which lags the FRINDEX
register bits [13:3] by one micro-frame count. Table 4-6 illustrates the
required relationship between the value of FRINDEX and the value of
SOFV. This lag behavior can be accomplished by incrementing
FRINDEX[13:3] based on carry-out on the 7 to 0 increment of FRINDEX[2:0]
and incrementing SOFV based on the transition of 0 to 1 of FRINDEX[2:0].

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Olav
Sent: Friday, May 06, 2005 5:00 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] USB: URB_FUNCTION_GET_CURRENT_FRAME_NUMBER

Hello Doron,
hello all,

first of all thank you for your help!

I tried to use “QueryBusTime” retrieved from
“USB_BUS_INTERFACE_USBDI_V0”,
but it returns the same value as I got by sending the URB.
Additionally I changed the firmware to get the USB frame number when the
transfer (a short packet containing my test data only) is received on
the
card’s USB controller - it shows the same frame and micro frame number
as
my USB analyzer does (e.g. driver’s frame nbr is 1188 before sending,
firmware and USB analyzer show 1187,7 (frame nbr, micro frame nbr) after
receiption), so one more indication that the problem is somewhere on the
PC side …

Olav

Subject: RE: USB: URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
From: “Doron Holan”
Date: Wed, 4 May 2005 09:17:00 -0700
X-Message-Number: 10

Instead of sending a URB, trying using the direct function as exported
by the usb core. Send a IRP_MJ_PNP/IRP_MN_QUERY_INTERFACE with an
interface buffer of USB_BUS_INTERFACE_USBDI_V0, interface guid of
USB_BUS_INTERFACE_USBDI_GUID and a version of USB_BUSIF_USBDI_VERSION_0
(all found in usbbusif.h) If you don’t know how to send a QI to the
core, look it up in the DDK. The toaster sample also demonstrates how
to send a QI down the stack. The QueryBusTime will return the current
frame number.

The data returned from the direct function call might not be any better,
but it is another piece of information for you to be able to use.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Olav
Sent: Wednesday, May 04, 2005 4:55 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] USB: URB_FUNCTION_GET_CURRENT_FRAME_NUMBER

Hello,

I’m developing a Windows driver for a device running with USB 2.0 under
Highspeed.

I have some strange suspicion that the current frame number I got via
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER is not correct, it’s value looks
like it is “one too high”.

To check this I did some measurements (just for testing!! :wink: ):

In my driver I detect a USB StartOfFrame by calling
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER in a loop until the frame number
changes (change of frame number indicates a SOF, at least more or less
exact …). Then I send some data on the USB bus with a bulk OUT
transfer.
I recorded the data with my USB analyzer - here I have the frame number,
too. The result was that frame numbers are always different!!! And: The
one from the USB Analyzer is the smaller one! In other words: The data
are
on the USB bus before I have sent them within my driver. Ok, and this
simply can’t be true … So I think that something is wrong in the way I
send
URB_FUNCTION_GET_CURRENT_FRAME_NUMBER or with the number I get back
from.
But what??

Btw: Both the URB_FUNCTION_GET_CURRENT_FRAME_NUMBER’s and the USB
analyzer’s frame number is zero based.

Has anybody seen something similar? Any explanation?
Or am I doing some things that should never ever be done?

Thanx for every hint!

regards
Olav


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=3D256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

----------------------------------------------------------------------


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

Hello Doron,

thank you very much for your hint to chapter 4.5 of the EHCI spec!
With the assumption that I get on the PC side the frame counter value used
for periodic scheduling (which is one micro frame different to the bus
frame counter, visible e.g. with the USB analyzer) I can explain the
things that caused our trouble!

Once again thank you very much for your help!

kind regards
Olav

Subject: RE: USB: URB_FUNCTION_GET_CURRENT_FRAME_NUMBER
From: “Doron Holan”
Date: Fri, 6 May 2005 09:46:01 -0700
X-Message-Number: 20

I asked someone who works on the USB stack and they referred to the EHCI
spec. I hope that helps.

d

http://www.intel.com/technology/usb/download/ehci-r10.pdf

EHCI Revision 1.0 3/12/2002

4.5 Periodic Schedule Frame Boundaries vs Bus Frame Boundaries

The USB Specification Revision 2.0 requires that the frame boundaries
(SOF frame number changes) of the high-speed bus and the full- and
low-speed bus(s) below USB 2.0 Hubs be strictly aligned. Super-imposed
on this requirement is that USB 2.0 Hubs manage full- and low-speed
transactions via a micro-frame pipeline (see start- (SS) and complete-
(CS) splits illustrated in Figure 4-6). A simple, direct projection of
the frame boundary model into the host controller interface schedule
architecture creates tension (complexity for both hardware and
software) between the frame boundaries and the scheduling mechanisms
required to service the full- and low-speed transaction translator
periodic pipelines.

The simple projection, as Figure 4-6 illustrates, introduces
frame-boundary wrap conditions for scheduling on both the beginning and
end of a frame. In order to reduce the complexity for hardware and
software, the host controller is required to implement a one micro-frame
phase shift for its view of frame boundaries. The phase shift eliminates
the beginning of frame and frame-wrap scheduling boundary conditions.

The implementation of this phase shift requires that the host controller
use one register value for accessing the periodic frame list and another
value for the frame number value included in the SOF token. These two
values are separate, but tightly coupled. The periodic frame list is
accessed via the Frame List Index Register
(FRINDEX) documented in Section 2.3.4 and initially illustrated in
Section 4.4. Bits FRINDEX[2:0], represent the micro-frame number. The
SOF value is coupled to the value of FRINDEX[13:3]. Both FRINDEX[13:3]
and the SOF value are incremented based on FRINDEX[2:0]. It is required
that the SOF value be delayed from the FRINDEX value by one micro-frame.
The one micro-frame delay yields host controller periodic schedule and
bus frame boundary relationship as illustrated in Figure 4-7. This
adjustment allows software to trivially schedule the periodic start and
complete-split transactions for fulland low-speed periodic endpoints,
using the natural alignment of the periodic schedule interface. The
reasons for selecting this phase-shift are beyond the scope of this
specification.

Figure 4-7 illustrates how periodic schedule data structures relate to
schedule frame boundaries and bus frame boundaries. To aid the
presentation, two terms are defined. The host controller’s view of the
1- millisecond boundaries is called H-Frames. The high-speed bus’s view
of the 1-millisecond boundaries is called B-Frames.

H-Frame boundaries for the host controller correspond to increments of
FRINDEX[13:3]. Micro-frame numbers for the H-Frame are tracked by
FRINDEX[2:0]. B-Frame boundaries are visible on the high-speed bus via
changes in the SOF token’s frame number. Micro-frame numbers on the
high-speed bus are only derived from the SOF token’s frame number (i.e.
the high-speed bus will see eight SOFs with the same USB 2.0 frame
number value). H-Frames and B-Frames have the fixed relationship (i.e.
B-Frames lag H-Frames by one micro-frame time) illustrated in Figure
4-7.

The host controller’s periodic schedule is naturally aligned to
H-Frames. Software schedules transactions for full- and low-speed
periodic endpoints relative the H-Frames. The result is these
transactions execute on the high-speed bus at exactly the right time for
the USB 2.0 Hub periodic pipeline.

As described in Section 2.3.4, the SOF Value can be implemented as a
shadow register (in this example, called SOFV), which lags the FRINDEX
register bits [13:3] by one micro-frame count. Table 4-6 illustrates the
required relationship between the value of FRINDEX and the value of
SOFV. This lag behavior can be accomplished by incrementing
FRINDEX[13:3] based on carry-out on the 7 to 0 increment of FRINDEX[2:0]
and incrementing SOFV based on the transition of 0 to 1 of FRINDEX[2:0].