📄 usbio.c
字号:
/* usbio.c - Nereid USB Monitor / USB Input/Output * Copyright (C) 2003 Tachibana Eriko * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdio.h>#include <stdlib.h>#include <sys/iocs.h>#include "include/nereid_usb.h"#include "include/usbdef.h"#include "include/binary.h"#include "usbio.h"#include "usbmon.h"#include "usbdesc.h"#include "usbinfo.h"#include "util.h"/* Functions */static void print_usb_status (int stat);static int wait_command_done (int check_bit);static int setup_transfer (int devadr, SetupData* pSetup, unsigned char* pData, int payload, DevSpeed speed);/* ---------------------------------------------------------------------- *//* 僗僥乕僞僗傪庢摼偡傞 *//* 曉抣: 0乣0xffff=惉岟(僗僥乕僞僗) -1=僄儔乕 */intGetStatus (setupType type, int devadr, setupRecipient rec, int wIndex, int payload, DevSpeed speed){ SetupData setup = { DIR_DEVICE2HOST + type + rec, REQ_GET_STATUS, swap_w (0), swap_w (wIndex), swap_w (GET_STATUS_DATA_SIZE), }; unsigned char stat[GET_STATUS_DATA_SIZE]; int rc; if ((rc = setup_transfer (devadr, &setup, stat, payload, speed)) < 0) return rc; return read_wp ((unsigned short*) stat);}/* 婡擻傪柍岠偵偡傞 *//* 曉抣: 0=惉岟 -1=僄儔乕 */intClearFeature (setupType type, int devadr, setupRecipient rec, int wValue, int wIndex, int payload, DevSpeed speed){ SetupData setup = { DIR_HOST2DEVICE + type + rec, REQ_CLEAR_FEATURE, swap_w (wValue), swap_w (wIndex), swap_w (0), }; return setup_transfer (devadr, &setup, NULL, payload, speed);}/* Get Bus State ... USB1.x 愱梡 *//* GET_STATE 帺懱傕 Hub 僋儔僗愱梡 *//* See: usb11.pdf P.270 [11.16.2.3] Get Bus State *//* 僶僗忬懺傪庢摼偡傞 *//* 曉抣: (-1 側傜僄儔乕) */intGetState (setupType type, int devadr, int wIndex, int payload, DevSpeed speed){ SetupData setup = { DIR_DEVICE2HOST + type + REC_OTHER, HUB_GET_STATE, swap_w (0), swap_w (wIndex), swap_w (GET_STATE_DATA_SIZE), }; unsigned char stat[GET_STATE_DATA_SIZE]; int rc; if ((rc = setup_transfer (devadr, &setup, stat, payload, speed)) < 0) return rc; return stat[0];}/* 婡擻傪桳岠偵偡傞 *//* 曉抣: 0=惉岟 -1=僄儔乕 */intSetFeature (setupType type, int devadr, setupRecipient rec, int wValue, int wIndex, int payload, DevSpeed speed){ SetupData setup = { DIR_HOST2DEVICE + type + rec, REQ_SET_FEATURE, swap_w (wValue), swap_w (wIndex), swap_w (0), }; return setup_transfer (devadr, &setup, NULL, payload, speed);}/* 僨僶僀僗傾僪儗僗傪愝掕偡傞 *//* 曉抣: 0=惉岟 -1=僄儔乕 */intSetAddress (setupType type, int devadr, int payload, DevSpeed speed){ SetupData setup = { DIR_HOST2DEVICE + type + REC_DEVICE, REQ_SET_ADDRESS, swap_w (devadr), swap_w (0), swap_w (0), }; return setup_transfer (0, &setup, NULL, payload, speed);}/* 僨僗僋儕僾僞傪庢摼偡傞 *//* 曉抣: 庴怣偟偨僶僀僩悢(-1 側傜僄儔乕) */intGetDescriptor (setupType type, int devadr, int wValue, int wIndex, int wLen, void* pDesc, int payload, DevSpeed speed){ SetupData setup = { DIR_DEVICE2HOST + type + REC_DEVICE, REQ_GET_DESCRIPTOR, swap_w (wValue), swap_w (wIndex), swap_w (wLen), }; return setup_transfer (devadr, &setup, (unsigned char*) pDesc, payload, speed);}/* 昗弨僨僗僋儕僾僞傪庢摼偡傞 */intGetDesc0 (int devadr, int wValue, int wLen, void* pDesc, int payload, DevSpeed speed){ SetupData setup = { DIR_DEVICE2HOST + TYPE_STANDARD + REC_DEVICE, REQ_GET_DESCRIPTOR, swap_w (wValue), swap_w (0), swap_w (wLen), }; return setup_transfer (devadr, &setup, (unsigned char*) pDesc, payload, speed);}/* 僨僗僋儕僾僞傪愝掕偡傞 *//* 曉抣: 憲怣偟偨僶僀僩悢(-1 側傜僄儔乕) */intSetDescriptor (setupType type, int devadr, int wValue, int wIndex, int wLen, void* pDesc, int payload, DevSpeed speed){ SetupData setup = { DIR_HOST2DEVICE + type + REC_DEVICE, REQ_SET_DESCRIPTOR, swap_w (wValue), swap_w (wIndex), swap_w (wLen), }; return setup_transfer (devadr, &setup, (unsigned char*) pDesc, payload, speed);}/* 尰嵼偺僐儞僼傿僊儏儗乕僔儑儞斣崋傪庢摼偡傞 *//* 曉抣: 0乣255=惉岟(僐儞僼傿僊儏儗乕僔儑儞斣崋) -1=僄儔乕 */intGetConfiguration (setupType type, int devadr, int payload, DevSpeed speed){ SetupData setup = { DIR_DEVICE2HOST + type + REC_DEVICE, REQ_GET_CONFIGURATION, swap_w (0), swap_w (0), swap_w (GET_CONFIGURATION_DATA_SIZE), }; unsigned char confno[GET_CONFIGURATION_DATA_SIZE]; int rc; if ((rc = setup_transfer (devadr, &setup, confno, payload, speed)) < 0) return rc; return confno[0];}/* 僐儞僼傿僊儏儗乕僔儑儞傪愝掕偡傞 *//* 曉抣: 0=惉岟 -1=僄儔乕 */intSetConfiguration (setupType type, int devadr, int confno, int payload, DevSpeed speed){ SetupData setup = { DIR_HOST2DEVICE + type + REC_DEVICE, REQ_SET_CONFIGURATION, swap_w (confno), swap_w (0), swap_w (0), }; return setup_transfer (devadr, &setup, NULL, payload, speed);}/* 尰嵼偺僀儞僞乕僼僃乕僗愝掕傪庢摼偡傞 *//* 曉抣: 0乣255=惉岟(僀儞僞乕僼僃乕僗斣崋) -1=僄儔乕 */intGetInterface (setupType type, int devadr, int wIndex, int payload, DevSpeed speed){ SetupData setup = { DIR_DEVICE2HOST + type + REC_DEVICE, REQ_GET_INTERFACE, swap_w (0), swap_w (wIndex), swap_w (1), }; unsigned char intfno[GET_INTERFACE_DATA_SIZE]; int rc; if ((rc = setup_transfer (devadr, &setup, intfno, payload, speed)) < 0) return rc; return intfno[0];}/* 僀儞僞乕僼僃乕僗傪愝掕偡傞 *//* 曉抣: 0=惉岟 -1=僄儔乕 */intSetInterface (setupType type, int devadr, int wValue, int wIndex, int payload, DevSpeed speed){ SetupData setup = { DIR_HOST2DEVICE + TYPE_STANDARD + REC_DEVICE, REQ_SET_INTERFACE, swap_w (wValue), swap_w (wIndex), swap_w (0), }; return setup_transfer (devadr, &setup, NULL, payload, speed);}/* 摨婜僼儗乕儉傪庢摼偡傞 *//* 曉抣: 0乣0xffff=惉岟(僼儗乕儉斣崋) -1=僄儔乕 */intSynchFrame (setupType type, int devadr, int wIndex, int payload, DevSpeed speed){ SetupData setup = { DIR_DEVICE2HOST + type + REC_ENDPOINT, REQ_SYNCH_FRAME, swap_w (0), swap_w (wIndex), swap_w (SYNCH_FRAME_DATA_SIZE), }; unsigned char frameno[SYNCH_FRAME_DATA_SIZE]; int rc; if ((rc = setup_transfer (devadr, &setup, frameno, payload, speed)) < 0) return rc; return read_wp ((unsigned short*) frameno);}/* ---------------------------------------------------------------------- *//* USB 偵愙懕偝傟偰偄傞婡婍偺懍搙傪敾暿偡傞 */DevSpeedUsbDetectSpeed (void){ DevSpeed speed = SPEED_UNKNOWN; int stat1, stat2 = 0; /* 儕僙僢僩 */ UsbReset (); DELAYMS (15); SL811Write (SL811_InterruptEnableRegister, b0110_0011); /* bit6=1: USB Reset/Resume 妱傝崬傒 桳岠 */ /* bit5=1: USB Insert/Remove 妱傝崬傒 桳岠 */ /* bit1=1: USB-B 廔椆妱傝崬傒 桳岠 */ /* bit0=1: USB-A 廔椆妱傝崬傒 桳岠 */ /* Set SOF high counter, no change D+/D- */ SL811Write (SL811_SOFCounterHigh_ControlRegister2, 0b1010_1110); SL811Write (SL811_ControlRegister1, b0100_1000); /* bit6=1: 旕僒僗儁儞僪 */ /* bit5=0: Full Speed */ /* bit4=0, bit3=1: USB Reset...D+ & D- Low State */ /* bit2=0: EOF2 婜娫偺僷働僢僩揮憲 Enable */ /* bit0=0: 僴乕僪僂僃傾 SOF Disable */ /* Disable USB transfer operation and SOF */ SL811Write (SL811_ControlRegister1, 0); /* Set SOF high counter, no change D+/D- */ SL811Write (SL811_SOFCounterHigh_ControlRegister2, 0b1010_1110); /* Clear SL811H mode and setup normal operation */ SL811Write (SL811_ControlRegister1, b0100_1000); /* Delay for H/W stablize */ DELAYMS (10); /* Disable USB transfer operation and SOF */ SL811Write (SL811_ControlRegister1, 0); DELAYMS (1); /* Read Interrupt Status */ stat1 = SL811Read (SL811_InterruptStatusRegister); /* Checking full or low speed */ if (stat1 & SL811_INT_INS) { SL811Write (SL811_InterruptStatusRegister, 0xff); stat2 = SL811Read (SL811_InterruptStatusRegister); if ((stat2 & SL811_INT_RESET) == 0) { if (stat2 & SL811_INT_D) /* Full Speed */ { speed = FULL_SPEED; /* Setup Master and Low Speed direct and SOF Counter high = 0x2e */ SL811Write (SL811_SOFCounterHigh_ControlRegister2, b1010_1110); /* bit7=1: Master 儌乕僪 */ /* bit6=0: D+/D- 嬌惈捠忢 */ /* bit5-0: SOF High Counter */ /* SOF Counter Low = 0xe0; 1ms interval */ SL811Write (SL811_SOFCounterLow, 0xe0); /* Setup 48MHz and SOF enable */ SL811Write (SL811_ControlRegister1, b0000_0101); /* bit6=0: 旕僒僗儁儞僪 */ /* bit5=0: Full Speed */ /* bit4=0, bit3=0: 捠忢摦嶌 */ /* bit2=1: EOF2 婜娫偺僷働僢僩揮憲 Disable */ /* bit0=1: 僴乕僪僂僃傾 SOF Enable */ } else /* Low Speed */ { speed = LOW_SPEED; /* Setup Master and Low Speed direct and SOF Counter high = 0x2e */ SL811Write (SL811_SOFCounterHigh_ControlRegister2, b1110_1110); /* bit7=1: Master 儌乕僪 */ /* bit6=1: D+/D- 嬌惈斀揮 */ /* bit5-0: SOF High Counter */ /* SOF Counter Low = 0xe0; 1ms interval */ SL811Write (SL811_SOFCounterLow, 0xe0); /* SOF Counter High/Low = 0x2ee0 = 12000, 12MHz / 12000 = 1000Hz */ /* Setup 6MHz and EOP enable */ SL811Write (SL811_ControlRegister1, b0010_0001); /* bit6=0: 旕僒僗儁儞僪 */ /* bit5=1: Low Speed */ /* bit4=0, bit3=0: 捠忢摦嶌 */ /* bit2=0: EOF2 婜娫偺僷働僢僩揮憲 Enable */ /* bit0=1: 僴乕僪僂僃傾 SOF Enable */ } } } SL811Write (SL811_A_HostPID_DeviceEndpoint, 0x50); /* bit7-4: PID Information */ /* bit3-0: Endpoint Address */ SL811Write (SL811_A_HostDeviceAddress, 0); /* bit6-0: Device Address */ /* start genarate SOF or EOP */ SL811Write (SL811_A_HostControlRegister, SL811_ARM); /* bit7=0: 僾儕傾儞僽儖僷働僢僩傪憲怣偟側偄 */ /* bit6=0: Data0 */ /* bit5=0: SOF 揮憲側偟 */ /* bit4=0: 旕 Isochronous 揮憲 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -