📄 usbhost.c
字号:
reset_the_device();
while (!g_powerOn)
TaskSleep(&delay_enum);
TaskSleep(&delay_after_poweron);
VPRINT("USB HOST: Printer powered on\n");
}
enumOK = FALSE;
for (i = 0; g_powerOn && !g_powerWasOff && i < 10; i++) {
enumOK = USB_enumerate();
if (enumOK)
break;
VPRINT("USB_Host_Task: Failed to enumerate; retry %d...\n", i+1);
TaskSleep(&delay_enum);
}
if (enumOK) {
/*
* New device detected and was assigned a USB address. Now set
* configuration, interface, assign endpoints.
*/
if (USB_GetConfiguration()) {
if (StillImage.Config) {
Uint32 dpsConnect;
intcount = -1;
if (USB_DoConfiguration(&StillImage)) {
usb_host.DeviceReady = TRUE;
PASSTHROUGH_UNBLOCK
doPictbridge(StillImage.ep_in_pksize,
StillImage.ep_out_pksize,
StillImage.ep_intr_pksize,
StillImage.ep_intr_pollms);
}
/*
* doPictbridge() should not return until either the
* device is disconnected (omDPSCONNECTED == DPSNONE)
* or the device does not support PictBridge
* (omDPSCONNECTED == DPSERROR).
*/
OMgetEnum(omDPSCONNECTED, OMCURRENT, &dpsConnect);
if (dpsConnect != DPSNONE) {
if (g_powerOn || !g_powerWasOff) {
VPRINT("PTP device but not PictBridge\n");
}
USB_UnsupportedDevice();
}
}
else if (MassStorage.Config) {
#ifdef MSCLASS_HOST_PASSTHROUGH
if (USB_DoConfiguration(&MassStorage)) {
Uint32 rstatus;
Uint8 GetMaxLUN[8] = {0xA1, 0xFE, 0, 0, 3, 0, 1, 0};
static TimeVal poll_delay = {2, 0};
/* Enable interrupts */
*regINT_ENB = INTR_TOK_DNE | INTR_ERROR |
INTR_STALL | INTR_USB_RST;
GetMaxLUN[wIndex_low] = MassStorage.iface;
MassStorage.MaxLUN = 0;
if (!USB_device_request(GetMaxLUN)) {
PASSTHROUGH_UNBLOCK
return FALSE;
}
if (USB_Request(&rstatus) == USBH_DONE)
MassStorage.MaxLUN = dev_request_buffer[0];
else if (_CODE(rstatus) != USBH_STALL) {
VPRINT("bad return from GetMaxLUN\n");
PASSTHROUGH_UNBLOCK
return FALSE;
}
VPRINT("Max LUN %d, (code %s)\n",
MassStorage.MaxLUN,
(_CODE(rstatus)==USBH_STALL) ?"STALL" : "DONE");
*regINT_ENB = INTR_ERROR | INTR_USB_RST;
usb_host.DeviceReady = TRUE;
PASSTHROUGH_UNBLOCK
while (usb_host.DeviceReady) {
TaskSleep(&poll_delay);
}
}
else {
PASSTHROUGH_UNBLOCK
}
#else
if (g_powerOn || !g_powerWasOff) {
VPRINT("Mass Storage Class not supported\n");
}
USB_UnsupportedDevice();
#endif
}
else {
/* Device is none of above */
if (g_powerOn || !g_powerWasOff) {
VPRINT("Unknown device class not supported\n");
}
USB_UnsupportedDevice();
}
}
else {
/* Device had trouble after enumeration */
if (g_powerOn || !g_powerWasOff) {
VPRINT("FAILED AFTER ENUMERATION, RESET\n");
}
USB_UnsupportedDevice();
PASSTHROUGH_UNBLOCK
}
}
else {
/* Device is none of above (if printer powered on) */
if (g_powerOn || !g_powerWasOff) {
VPRINT("FAILED AFTER ENUMERATION, RESET\n");
}
USB_UnsupportedDevice();
PASSTHROUGH_UNBLOCK
}
}
}
static Boolean USB_enumerate(void)
{
Uint32 rstatus;
int length, pksize;
static Uint8 SetAddress[8] = {0, 5, 1, 0, 0, 0, 0, 0};
VPRINT("USB_HOST READY:\n");
usb_host.cur_pipe = NULL;
usb_host.USB_addr = 0;
usb_host.inx = 0;
usb_host.outx = 0;
usb_host.tick = 0;
usb_host.state = NO_REQUEST;
usb_host.reset_required = TRUE;
usb_host.DeviceReady = FALSE;
/* Disable ep0 */
*regEP0CTL = ENDPT_DISABLE;
/* Reset the device */
reset_the_device();
/* Enable attach interrupt */
*regINT_ENB = INTR_ATTACH;
/* Enable host mode but don't start generating SOFs */
*regCTL = CTRL_HOST_NO_SOF;
if (USB_Request(&rstatus) != USBH_ATTACH) {
VPRINT("FAILED - NOT ATTACHED\n");
return FALSE;
}
/* Get out if power was turned off or cycled waiting for ATTACH interrupt */
if (!g_powerOn || g_powerWasOff)
return FALSE;
/* Reset the device a second time */
reset_the_device();
/* Device is now plugged in, enable all errors */
*regERR_ENB = 0xff;
/* Delay for the debounce interval */
TaskSleep(&debounce_delay);
/* Check if low-speed device */
if ((*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE)) == 0) {
USB_UnsupportedDevice();
return FALSE;
}
/* Check if the device has detached */
if ((*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE)) != CTRL_JSTATE) {
VPRINT("process_attached NO DEVICE - ctrl_status %02x\n", *regCTL);
return FALSE;
}
DBPRINT("ATTACHED\n");
/**************************************************************************/
/*
* Set SOF threshold so we are guaranteed to have enough time for
* any transaction to complete (including ACK or NAK) without reaching
* the time to send the next Start-of-frame packet.
*/
*regSOF_THLD = SOF_THRESHOLD;
/* Enable ep0 configured as CNTRL endpoint */
*regEP0CTL = ENDPT_CNTL_0;
/* Enable host mode and start generating SOFs */
*regCTL = CTRL_HOST_SOF;
/* Enable the token-done, error, STALL and RESET interrupts */
*regINT_ENB = INTR_TOK_DNE | INTR_ERROR | INTR_STALL | INTR_USB_RST;
/* Get first 8 bytes of the device descriptor */
length = USB_GetDescriptor(DEVICE_TYPE, 0, &DeviceDesc, 8);
if (length < 8)
return FALSE;
/**************************************************************************/
/* Reset the device */
reset_the_device();
/**************************************************************************/
/* Validate size and descriptor type of device descriptor */
pipe[0].pksize = pksize = dev_request_buffer[7];
DBPRINT("Set CNTRL pksize %d\n", pipe[0].pksize);
if (pipe[0].pksize < 8 ||
pipe[0].pksize > 64 ||
(pipe[0].pksize & (pipe[0].pksize - 1)) || /* must be power of 2 */
dev_request_buffer[0] != 0x12 ||
dev_request_buffer[1] != 1 )
{
VPRINT("GetDevDesc BAD\n");
return FALSE;
}
/**************************************************************************/
/* Enable attach interrupt */
*regINT_ENB = INTR_ATTACH;
if (USB_Request(&rstatus) != USBH_ATTACH) {
VPRINT("FAILED - NOT ATTACHED (2)\n");
return FALSE;
}
/* As above (restore after device reset) */
*regSOF_THLD = SOF_THRESHOLD;
*regEP0CTL = ENDPT_CNTL_0;
*regCTL = CTRL_HOST_SOF;
/* Enable the token done, error, stall and RESET interrupts */
*regINT_ENB = INTR_TOK_DNE | INTR_ERROR | INTR_STALL | INTR_USB_RST;
/**************************************************************************/
/* Set address to USB address 1 */
DBPRINT("SET ADDRESS, threshold %d\n", *regSOF_THLD);
if (!USB_device_request(SetAddress))
return FALSE;
if (USB_Request(&rstatus) != USBH_DONE) {
VPRINT("bad return from SetAddress\n");
return FALSE;
}
usb_host.USB_addr = 1;
*regADDR = 1;
DBPRINT("SET ADDRESS COMPLETE\n");
return TRUE;
}
static void USB_UnsupportedDevice(void)
{
static TimeVal delay_500msec = {0, 500*1000};
/* If power is off (or printer powering down) don't report error */
if (!g_powerOn || g_powerWasOff)
return;
/* Turn on front-panel message */
OMsetEnum(omDPSCONNECTED, OMCURRENT, DPSERROR);
/* Report Low Speed Device for debug purposes */
if (!(*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE))) {
VPRINT("LOW SPEED not supported - ctrl_status %02x\n", *regCTL);
}
while ((*regCTL & (CTRL_SINGLE_END0 | CTRL_JSTATE)) != CTRL_SINGLE_END0) {
TaskSleep(&delay_500msec);
}
VPRINT("Unsupported device unplugged %02x\n", *regCTL);
/* Turn off front-panel message */
OMsetEnum(omDPSCONNECTED, OMCURRENT, DPSNONE);
}
static Boolean USB_GetConfiguration(void)
{
Uint16 length, i, config_length;
Uint8 Config_no, EndPointCount;
Uint8 bf[512];
Boolean gotIface;
#if USBH_VERBOSE
Uint16 lang_id;
#endif
EndPointCount = 0;
/* Get full 18 bytes of the device descriptor */
DBPRINT("Get full DEVICE DESC addr %d\n", *regADDR);
length = USB_GetDescriptor(DEVICE_TYPE, 0, &DeviceDesc, sizeof(DEVICE_DESC));
if (length < 18)
return FALSE;
length = USB_GetDescriptor(CONFIGURATION_TYPE, 0, &ConfigDesc, sizeof(CONFIG_DESC));
if (length < sizeof(CONFIG_DESC)) {
VPRINT("CONFIG DESC FAILED: length %d\n", length);
return FALSE;
}
/*********************/
/* Device Descriptor */
/*********************/
#if USBH_VERBOSE
length = USB_GetString(0, 0);
if (length < 2)
return FALSE;
lang_id = ((Uint16)dev_request_buffer[WLANGID0_HIGH] << 8) |
(Uint16)dev_request_buffer[WLANGID0_LOW];
if (DeviceDesc.bManufacturer) {
PSPRINTF("\n\nManufacturer: ");
USB_PrintString(DeviceDesc.bManufacturer, lang_id);
}
if (DeviceDesc.bProduct) {
PSPRINTF("Product: ");
USB_PrintString(DeviceDesc.bProduct, lang_id);
}
if (DeviceDesc.iSerialNumber) {
PSPRINTF("Serial no.: ");
USB_PrintString(DeviceDesc.iSerialNumber, lang_id);
}
PSPRINTF("Supports USB %x.%02x\n",
DeviceDesc.bcdUSB_high, DeviceDesc.bcdUSB_low);
PSPRINTF("Class: %02x, Subclass %02x, Protocol %02x\n",
DeviceDesc.bDeviceClass, DeviceDesc.bDeviceSubclass,
DeviceDesc.bDeviceProtocol);
PSPRINTF("VID: %02x%02x, PID %02x%02x\n",
DeviceDesc.idVendor_high, DeviceDesc.idVendor_low,
DeviceDesc.idProduct_high, DeviceDesc.idProduct_low);
PSPRINTF("Device release: %x.%02x\n",
DeviceDesc.bcdDevice_high, DeviceDesc.bcdDevice_low);
PSPRINTF("No. of configurations: %d\n", DeviceDesc.bNumConfigurations);
#endif
config_length = ConfigDesc.wTotalLength_high*256 +
ConfigDesc.wTotalLength_low;
length = USB_GetDescriptor(CONFIGURATION_TYPE, 0, bf, config_length);
if (length < config_length) {
VPRINT("CONFIG DESC FAILED: length %d vs. expected %d\n",
length, config_length);
return FALSE;
}
gotIface = FALSE;
i = 0;
Config_no = 0;
MassStorage.needClass = TRUE;
MassStorage.Config = 0;
StillImage.needClass = TRUE;
StillImage.Config = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -