IOCTL_ADAPT_SEND_NON_EP0_DIRECT

CYUSB3

IOCTL_ADAPT_SEND_NON_EP0_DIRECT

Top Previous Next

Description

 

This IOCTL is used to request Bulk, Interrupt or Isochronous data transfers across corresponding USB device endpoints.

 

The DeviceIoControl call requires two buffer parameters. For this command, the first buffer must contain a properly initialized SINGLE_TRANSFER structure.

 

The SINGLE_TRANSFER fields of BufferOffset and BufferLength should be set to 0 for this command.

 

The second buffer is for the actual transfer data. For an OUT endpoint, this will contain the data headed to the USB device. For an IN endpoint, this buffer will hold the data that is received from the device.

 

Special ISOC Constraints

 

The endpoint maximum transfer size and buffer length parameter must both be a multiple of the endpoint's MaxPacketSize.

 

For ISOC transfers on a device operating at High speed or Super Speed, the following constraints apply to this command:

 

1) The buffer length parameter (bufLen in the below examples) must also be a multiple of the endpoint's MaxPacketSize * 8. Please also note that last packet is allow to send with partial size(less than Max packet) for both super and high speed Isochronous transfer.

2) For Super speed Isochronous endpoint only , if device define the MaxBurst in the super speed endpoint companion descriptor then Maxburst should be used to calculate the packet size=(MaxpacketSize * (MaxBurst+1)). This packet length data will be sent over one micro frame interval.

 

 

The SINGLE_TRANSFER structure must be followed by additional space sufficient to hold the PACKET_INFO structures for the transfer (see examples #2 and #3, below).

 

 

Example #1 (Bulk and Interrupt endpoints)

 

 

PUCHAR CCyUSBEndPoint::BeginDirectXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov)

{

 

if ( hDevice == INVALID_HANDLE_VALUE ) return NULL;

int iXmitBufSize = sizeof (SINGLE_TRANSFER);

PUCHAR pXmitBuf = new UCHAR[iXmitBufSize];

ZeroMemory (pXmitBuf, iXmitBufSize);

 

PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER) pXmitBuf;

pTransfer->ucEndpointAddress = Address;

pTransfer->IsoPacketLength = 0;

pTransfer->BufferOffset = 0;

pTransfer->BufferLength = 0;

DWORD dwReturnBytes;

DeviceIoControl (hDevice,

     IOCTL_ADAPT_SEND_NON_EP0_DIRECT,

     pXmitBuf, iXmitBufSize,

     buf, bufLen,

     &dwReturnBytes, ov);

 

// Note that this method leaves pXmitBuf allocated.  It will get deleted in

// FinishDataXfer.

LastError = GetLastError();

return pXmitBuf;

}

 

Example #2 (ISOC endpoints)

 

PUCHAR CCyIsocEndPoint::BeginDirectXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov)

{

if ( hDevice == INVALID_HANDLE_VALUE ) return NULL;

int pkts = bufLen / MaxPktSize; // Number of packets implied by bufLen & pktSize

if (bufLen % MaxPktSize) pkts++;

if (pkts == 0) return NULL;

int iXmitBufSize = sizeof (SINGLE_TRANSFER) + (pkts * sizeof(ISO_PACKET_INFO));

UCHAR *pXmitBuf = new UCHAR[iXmitBufSize];

ZeroMemory (pXmitBuf, iXmitBufSize);

PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER) pXmitBuf;

pTransfer->ucEndpointAddress = Address;

pTransfer->IsoPacketOffset = sizeof (SINGLE_TRANSFER);

pTransfer->IsoPacketLength = pkts * sizeof(ISO_PACKET_INFO);

pTransfer->BufferOffset = 0;

pTransfer->BufferLength = 0;

DWORD dwReturnBytes = 0;

DeviceIoControl (hDevice,

     IOCTL_ADAPT_SEND_NON_EP0_DIRECT,

     pXmitBuf, iXmitBufSize,

     buf, bufLen,

     &dwReturnBytes, ov);

// Note that this method leaves pXmitBuf allocated.  It will get deleted in

// FinishDataXfer.

LastError = GetLastError();

return pXmitBuf;

}

 

Example #3 (ISOC endpoints)

 

 

PUCHAR CCyIsocEndPoint::BeginDirectXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov)

{

if ( hDevice == INVALID_HANDLE_VALUE ) return NULL;

int pkts = bufLen / MaxPktSize; // Number of packets implied by bufLen & pktSize

if (bufLen % MaxPktSize) pkts++;

if (pkts == 0) return NULL;

int iXmitBufSize = sizeof (SINGLE_TRANSFER) + (pkts * sizeof(ISO_PACKET_INFO));

UCHAR *pXmitBuf = new UCHAR[iXmitBufSize];

ZeroMemory (pXmitBuf, iXmitBufSize);

PSINGLE_TRANSFER pTransfer = (PSINGLE_TRANSFER) pXmitBuf;

pTransfer->ucEndpointAddress = Address;

pTransfer->IsoPacketOffset = sizeof (SINGLE_TRANSFER);

pTransfer->IsoPacketLength = pkts * sizeof(ISO_PACKET_INFO);

pTransfer->IsoParams.isoId = USB_ISO_ID;

pTransfer->IsoParams.isoCmd = USB_ISO_CMD_ASAP;

pTransfer->IsoParams.ulParam1 = 0;

DWORD dwReturnBytes = 0;

DeviceIoControl (hDevice,

           IOCTL_ADAPT_SEND_NON_EP0_DIRECT,

           pXmitBuf, iXmitBufSize,

           buf, bufLen,

           &dwReturnBytes, ov);

 

// Note that this method leaves pXmitBuf allocated.  It will get deleted in

// FinishDataXfer.

LastError = GetLastError();

return pXmitBuf;

}