Hello Bret,
Beyond your documentation in the .zips, can you send an example of Bulk transactions using C (I'm using a very old version of MSVC V1.52 compiled for DOS)? I'm booting MSDOS-622 (totally non-windows env) and using your USBUHCIL driver to communicate with an I2C programming module. Using "USBUHCIL Descriptors 2", I can see the module, end points for in/out, etc.
I can read the DeviceId, VendorId, etc., but I cannot seem to make a bulk transfer work. The LED on the device blinks when I send data but I'm obviously missing something here.
The device vendor has given me a command set to read the device software version back but I always read null. I've tried many variations of this but still null.
Thanks,
-jeff
Example of my code:
in main.........
GetDeviceInfo(0,2); //works, get device info, VendorID, DeviceID, on hub port
//host to device
strcpy(deviceData,"SendBuffer[0]:=1;");
dataSize=strlen(deviceData);
UsbTalk(0,0,2,dataSize,deviceData,cbakAddrPtr);
//host to device
strcpy(deviceData,"SendBuffer[1]:=$F0;");
dataSize=strlen(deviceData);
UsbTalk(0,0,2,dataSize,deviceData,cbakAddrPtr);
//device to host
strcpy(deviceData,'\0');
UsbTalk(1,0,2,1,deviceData,cbakAddrPtr);
printf("USBTALK : %s - %s\n",deviceData,cbakAddrPtr);
.....
//send transaction Host to Device
int UsbTalk(int Direction, int HostIndex, int DeviceIndex, int numBytes, char *deviceData, char *cbakAddrPtr)
{
int ReturnValue; //Return value from Subroutine Calls
int AXRegister; //Return AX Register
int BXRegister; //Return BX Register
int CXRegister; //Return CX Register
int DXRegister; //Return DX Register
//clear data at dataAddrPtr
//strcpy(dataAddrPtr,deviceData);
//set Schedule structure
Int14RequestPtr->I14RRequestType = I14RRTDoBulk; //Request Type = 0x97 Schedule Bulk Transaction
Int14RequestPtr->I14RHostIndex = HostIndex; //Host Index
Int14RequestPtr->I14RDeviceAddress = DeviceIndex; //DeviceIndex
Int14RequestPtr->I14REndPoint = 2; //Device endpoint
Int14RequestPtr->I14RTimeout = 50; //5 second timeout
//Int14RequestPtr->I14RDataAddrSeg = _FP_SEG(deviceData); //address of send data
Int14RequestPtr->I14RDataAddrOff = _FP_OFF(deviceData); //address of send data
//Int14RequestPtr->I14RCallBackAddrSeg = _FP_SEG(cbakAddrPtr); //address of call back data
//Int14RequestPtr->I14RCallBackAddrOff = _FP_OFF(cbakAddrPtr); //address of call back data
Int14RequestPtr->I14RUserPktID = 0x0; //value to return in BX on notification
//set USB data direction and size
if(Direction==1)
{
//device to host
Int14RequestPtr->I14RFlags = I14RFlagIn; //data direction Device to Host
Int14RequestPtr->I14RDataSize = numBytes; //bytes to Transfer (0-65535)
strcpy(deviceData,'\0');
} else
{
//host to device
Int14RequestPtr->I14RFlags = I14RFlagOut; //data direction Host to Device
Int14RequestPtr->I14RDataSize = strlen(deviceData); //bytes to Transfer (0-65535)
//strcpy(dataAddrPtr,deviceData);
}
//send the request interrupt
ReturnValue = Int14SendRequest(&AXRegister, &BXRegister, &CXRegister, &DXRegister);
//if error
if(ReturnValue != 0)
{
printf("\nDataOut Error: %d\n",ReturnValue);
printf("AX:%x\n",(AXRegister));
printf("BX:%x\n",(BXRegister));
printf("CX:%x\n",(CXRegister));
printf("DX:%x\n",(DXRegister));
return 1;
}
//if device to host
//if(Direction==1) strcpy(deviceData,dataAddrPtr);
//clear dataAddrPtr
//strcpy(dataAddrPtr,'\0');
//show debug info
printf("Direction : %d\n",Direction);
printf("HostIndex : %d\n",HostIndex);
printf("DeviceIndex: %d\n",DeviceIndex);
printf("NumBytes : %d\n",numBytes);
//printf("DataAddrPtr: %x\n",&dataAddrPtr); //shows pointer address
printf("Device Data: %s\n",deviceData); //shows data at pointer address
printf("DDAddress : %x\n",&deviceData);
return 0;
}
/==========================================================================
// Send a "standard" Int 14h Request to a USB Driver
//==========================================================================
int Int14SendRequest
(
int *AXRegister, //CPU AX Register
int *BXRegister, //CPU BX Register
int *CXRegister, //CPU CX Register
int *DXRegister //CPU DX Register
)
{
static union REGS Regs;
Regs.x.ax = I14AXDoFunction; //AX = 5001 (Do Function)
Regs.x.bx = I14BXInput; //BX = US
Regs.x.cx = I14CXInput; //CX = B!
Regs.x.dx = FP_OFF(Int14RequestPtr); //DS:[DX] = Request Structure
int86(0x14,&Regs,&Regs); //Do Int 14h (USB Request)
*AXRegister = Regs.x.ax; //Set return AX
*BXRegister = Regs.x.bx; //Set return BX
*CXRegister = Regs.x.cx; //Set return CX
*DXRegister = Regs.x.dx; //Set return DX
//debug display
if(Regs.x.ax)
{
printf("\nInt14SendRequest\n");
printf("AX:%x\n",Regs.x.ax);
printf("BX:%x\n",Regs.x.bx);
printf("CX:%x\n",Regs.x.cx);
printf("DX:%x\n",Regs.x.dx);
}
return (Regs.x.ax); //Set return function value
}
//--------------------------------------------------------------------------
//Issue Get Host Hardware Info Request
//--------------------------------------------------------------------------
int GetDeviceInfo(int HostIndex, int DeviceIndex) //USB Host Index, Device Index on USB Host Index
{
int ReturnValue; //Return value from Subroutine Calls
int AXRegister; //Return AX Register
int BXRegister; //Return BX Register
int CXRegister; //Return CX Register
int DXRegister; //Return DX Register
Int14RequestPtr->I14RRequestType = I14RRTGetDvcClassInfo; //Request Type
Int14RequestPtr->I14RHostIndex = HostIndex; //Host Index
Int14RequestPtr->I14RDeviceAddress = DeviceIndex; //DeviceIndex
ReturnValue = Int14SendRequest(&AXRegister, &BXRegister, &CXRegister, &DXRegister);
//if error
if(ReturnValue != 0)
{
printf("\nWriteHostClass Error\n");
printf("AX:%x\n",(AXRegister));
printf("BX:%x\n",(BXRegister));
printf("CX:%x\n",(CXRegister));
printf("DX:%x\n",(DXRegister));
return 0;
}
//no error, print USB type
//printf("\nGetDeviceInfo(Host:%d Device:%d)\n",HostIndex,DeviceIndex);
printf("\nHost:%d Device:%d Class:%x SubClass:%x Proto:%x USB:V%x.%x",HostIndex,DeviceIndex,
(BXRegister & 0xF),(BXRegister & 0xF0),(CXRegister & 0xF),(CXRegister>>8 & 0xF),(CXRegister>>12 & 0xF));
//get VendorID and DeviceID
Int14RequestPtr->I14RRequestType = I14RRTGetDvcVendInfo; //Request Type
Int14SendRequest(&AXRegister, &BXRegister, &CXRegister, &DXRegister);
if(ReturnValue != 0)
{
printf("\nDevice ID Error\n");
printf("AX:%x\n",(AXRegister));
printf("BX:%x\n",(BXRegister));
printf("CX:%x\n",(CXRegister));
printf("DX:%x\n",(DXRegister));
return 0;
} else
{
printf(" VenID:%x DevID:%x\n",BXRegister,CXRegister);
}
//get Device Status
Int14RequestPtr->I14RRequestType = I14RRTGetDvcStatus; //Request Type
Int14SendRequest(&AXRegister, &BXRegister, &CXRegister, &DXRegister);
if(ReturnValue != 0)
{
printf("\nGetDeviceStatus Error\n");
printf("AX:%x\n",(AXRegister));
printf("BX:%x\n",(BXRegister));
printf("CX:%x\n",(CXRegister));
printf("DX:%x\n",(DXRegister));
return 0;
} else
{
printf(" Config:%x Bad:%x Resetting:%x Error:%x\n",
(BXRegister & 0xff), //Write device current configuration data
(BXRegister >> 8 & 0x1), //set if device is bad during enumeration
(BXRegister >> 14 & 0x1), //set if device is still resetting
(DXRegister)); //error number if device enumeration error
}
return ReturnValue;
}