📄 usbch9.c
字号:
volatile Uint32 index_done; /* index of data already sent */
} card_table;
static volatile Boolean card_active;
static volatile Boolean card_usingFIFO = FALSE;
static volatile Boolean card_needsFIFO = FALSE;
#endif /* MEMORY_CARD_READER */
#if SCANNER_EPS
static volatile Boolean USB_SCAN_TaskSleeping;
static volatile Uint32 USB_SCAN_TaskTick;
static volatile Boolean scan_usingFIFO = FALSE;
#endif
/* long_packet_pool: pool of long packets for sending data back to the host */
static OUT_PACKET *long_packet_pool;
/* short_packet_pool: pool of short packets for sending data back to the host */
static OUT_PACKET *short_packet_pool;
/* hid_packet_pool: pool of packets for sending HID data back to the host */
static OUT_PACKET *hid_packet_pool;
/* NOTE: MEMORY ALLOCATION IS CURRENTLY STATIC */
static Uint8 long_pool_memory[LONG_PACKET_CNT * sizeof(OUT_PACKET) + 4];
static Uint8 short_pool_memory[SHORT_PACKET_CNT * sizeof(OUT_PACKET_SHORT) + 4];
static Uint8 hid_pool_memory[HID_PACKET_CNT * sizeof(OUT_PACKET_HID) + 4];
static Uint8 prn_rbuff[USB_PRINT_BUFF_SIZE + 4];
#if SCANNER_EPS
static Uint8 scn_rbuff[USB_SCAN_BUFF_SIZE + 4];
#endif
#if DEBUG_EPS
static Uint8 dbg_rbuff[USB_DEBUG_BUFF_SIZE + 4];
#endif
#ifdef MEMORY_CARD_READER
static Uint8 mem_rbuff[USB_CARD_BUFF_SIZE + 4];
#endif
/*
* Index of currently selected alternate interface; -1 if alternate interface
* has not yet been negotiated.
*/
static volatile int alt_interface_no;
/* USB test mode flag (0 means test mode off) */
static volatile Uint16 test_mode_index;
static Boolean CableConnected = FALSE;
/******************************************************************************/
/* Local procedure prototypes: */
static void service_ep0(Uint8 ep, Boolean setup, Uint32 length);
static void GetStatus(void);
static void ClearFeature(void);
static void SetFeature(Boolean setup);
static void SetAddress(Boolean setup);
static void GetDescriptor(void);
static void SetConfig(void);
static void GetInterface(void);
static void SetInterface(void);
static void SetIfaceNo(Uint8 alt_setting);
static void service_EPn_OUT(Uint8 ep_index, Boolean setup, Uint32 length);
static Uint8 GetPrinterStatus(void);
static Boolean ReadEPn(volatile Uint8 *ep_status, EP_RECV *ep, Uint8 ep_index,
Uint8 **ptr1, Uint32 *cnt1, Uint8 **ptr2, Uint32 *cnt2);
static void ConsumeEPn(EP_RECV *ep, Uint8 ep_index,
volatile Uint8 *ep_status, Uint32 nbytes);
static Boolean WriteEPn(volatile Uint8 *ep_status, Uint8 ep_index,
Uint8 *buffer, Uint16 nbytes);
/*
* Default endpoint service routine - Should never be called.
*/
static void service_default(Uint8 ep, Boolean setup, Uint32 length)
{
USB_ASSERT(0);
}
/******************************************************************************/
/* U S B I N T E R R U P T S E R V I C E R O U T I N E S */
/******************************************************************************/
/**************************************************************************
*
* Function Name: FlushOutput
* Comments:
* Return output packets to pools.
*
**************************************************************************/
static void FlushOutput(Uint8 ep_send)
{
OUT_PACKET *packet;
Uint8 ep_no = ep_send/2;
packet = outpacketHead[ep_no];
while (packet) {
outpacketHead[ep_no] = packet->next;
packet->next = *packet->home_pool;
*packet->home_pool = packet;
packet = outpacketHead[ep_no];
}
}
/**************************************************************************
*
* Function Name: USB_deconfigure_current_interface
* Comments:
* Called to deconfigure previously configured endpoints due to a "set
* configuration" or "set interface" request, or a reset. This may also be
* called from vusbd20.c due to a USB reset.
*
* If at any step things are taking too long (hardware taking too long to
* flush endpoints, and/or is hung), the USB_ForceReset flag is set and
* USB_task is un-suspended to do the job without causing interrupt latencies.
*
**************************************************************************/
void USB_deconfigure_current_interface(void)
{
if (alt_interface_no >= 0) {
/* If read was in progress and partially complete, update inx index */
if (prn_recv.request_active) {
dQH_STRUCT *qhead = usb_state.EP_QUEUE_HEAD_PTR + PRN_RECV;
if (qhead->CURR_DTD_PTR) {
prn_recv.inx = prn_recv.request_index +
prn_recv.request_length -
(qhead->SIZE_IOC_INT_STS >> 16);
}
}
USB_ISR_deinit_endpoint(PRN_RECV);
USB_ISR_deinit_endpoint(PRN_SEND);
/* Set status of all endpoints > 0 to inactive/unconfigured. */
prn_status = EP_UNCONF; prn_recv.request_active = FALSE;
prn_recv.full_flag = FALSE;
prn_recv.limit = prn_recv.max_buff_size = USB_RCV_PRINT_LIMIT;
/* Return any queued output buffers to their home pools. */
FlushOutput(PRN_SEND);
#if SCANNER_EPS
if (scn_recv.request_active) {
dQH_STRUCT *qhead = usb_state.EP_QUEUE_HEAD_PTR + SCN_RECV;
if (qhead->CURR_DTD_PTR) {
scn_recv.inx = scn_recv.request_index +
scn_recv.request_length -
(qhead->SIZE_IOC_INT_STS >> 16);
}
}
USB_ISR_deinit_endpoint(SCN_RECV);
USB_ISR_deinit_endpoint(SCN_SEND);
scn_status = EP_UNCONF; scn_recv.request_active = FALSE;
scn_recv.full_flag = FALSE;
scn_recv.limit = scn_recv.max_buff_size = USB_RCV_SCAN_LIMIT;
/*
* Scanner is special case since we don't own memory buffers.
* if the scan application needs to know when the buffer has
* been sent, supply the USBConsumeWriteScan() function and
* enable this code to be compiled.
*/
while (scan_outx != scan_inx) {
CONSUME_WRITE_SCAN(scan_table[scan_outx].data);
scan_table[scan_outx].length = 0;
scan_table[scan_outx].data = NULL;
scan_table[scan_outx].index_req = 0;
scan_table[scan_outx].index_done = 0;
#if USB_ENA_SCN_FLUSH
scan_table[scan_outx].null_req = FALSE;
#endif
if (++scan_outx >= SCAN_TABLE_SIZE)
scan_outx = 0;
}
scan_inx = scan_outx = 0;
scan_active = FALSE;
#endif /* SCANNER_EPS */
#if DEBUG_EPS
if (dbg_recv.request_active) {
dQH_STRUCT *qhead = usb_state.EP_QUEUE_HEAD_PTR + DBG_RECV;
if (qhead->CURR_DTD_PTR) {
dbg_recv.inx = dbg_recv.request_index +
dbg_recv.request_length -
(qhead->SIZE_IOC_INT_STS >> 16);
}
}
USB_ISR_deinit_endpoint(DBG_RECV);
USB_ISR_deinit_endpoint(DBG_SEND);
dbg_status = EP_UNCONF; dbg_recv.request_active = FALSE;
dbg_recv.full_flag = FALSE;
dbg_recv.limit = dbg_recv.max_buff_size = USB_RCV_DEBUG_LIMIT;
FlushOutput(DBG_SEND);
#endif /* DEBUG_EPS */
USB_ISR_deinit_endpoint(HID_SEND);
hid_status = EP_UNCONF;
FlushOutput(HID_SEND);
#ifdef MEMORY_CARD_READER
if (mem_recv.request_active) {
dQH_STRUCT *qhead = usb_state.EP_QUEUE_HEAD_PTR + MEM_RECV;
if (qhead->CURR_DTD_PTR) {
mem_recv.inx = mem_recv.request_index +
mem_recv.request_length -
(qhead->SIZE_IOC_INT_STS >> 16);
}
}
USB_ISR_deinit_endpoint(MEM_RECV);
USB_ISR_deinit_endpoint(MEM_SEND);
mem_status = EP_UNCONF; mem_recv.request_active = FALSE;
mem_recv.full_flag = FALSE;
mem_recv.limit = mem_recv.max_buff_size = USB_RCV_CARD_LIMIT;
/* memory card reader is also special case */
card_active = FALSE;
if (DoNotRemoveFlashMemory) {
USB_TaskTick++;
if (USB_TaskSleeping) {
USB_TaskSleeping = FALSE;
USB_WakeUpUSB_Task();
}
}
TaskSemSignal(USB_CARD_Semaphore);
#endif /* MEMORY_CARD_READER */
#if SCANNER_EPS
USB_SCAN_TaskTick++;
if (USB_SCAN_TaskSleeping) {
USB_SCAN_TaskSleeping = FALSE;
TaskSemSignal(USB_SCAN_Semaphore);
}
#endif /* SCANNER_EPS */
alt_interface_no = -1;
}
}
/**************************************************************************
*
* Function Name: USB_speed_change
* Comments:
* Called if speed detection USB status bit set.
*
**************************************************************************/
void USB_speed_change(void)
{
if (usb_state.SPEED == USB_DEV_HIGH_SPEED) { /* 1 */
USB_STATUS_MSK_SET(SPEED_MASK, HIGH_SPEED);
USB20_HighSpeed = TRUE;
}
else if (usb_state.SPEED == USB_DEV_FULL_SPEED) { /* 2 */
USB_STATUS_MSK_SET(SPEED_MASK, FULL_SPEED);
USB20_HighSpeed = FALSE;
}
}
/**************************************************************************
*
* Function Name: CheckEP
* Comments:
* Check if endpoint is valid and/or configured. Stall if not.
*
**************************************************************************/
static Boolean CheckEP(Uint8 endpoint)
{
Uint8 status = 0;
/* stall if not configured */
switch (endpoint & USB_STATUS_ENDPOINT_NUMBER_MASK) {
case PRN_EP:
status = prn_status;
break;
#if SCANNER_EPS
case SCN_EP:
status = scn_status;
break;
#endif
case HID_EP:
status = hid_status;
break;
#ifdef MEMORY_CARD_READER
case MEM_EP:
status = mem_status;
break;
#endif
#if DEBUG_EPS
case DBG_EP:
status = dbg_status;
break;
#endif
}
if (status & EP_CONFIG)
return FALSE;
STALL_ENDPOINT_0;
return TRUE;
}
/**************************************************************************
*
* Function Name: ISRStartEndpointRead
* Comments:
* Called to start next read from endpoint from ISR routine.
*
**************************************************************************/
static void ISRStartEndpointRead(Uint8 ep_index, EP_RECV *ep)
{
Uint32 length;
USB_ASSERT(!ep->request_active);
/* Compute space available left in input buffer (multiple of 512). */
if (ep->outx <= ep->inx) {
length = (ep->max_buff_size - ep->inx) & PACKET_SIZE_MASK;
/*
* If there is still room at the end, keep the limit at the
* end so that outx won't turn the corner too soon.
*/
if (length)
ep->limit = ep->max_buff_size;
else {
/*
* No more room at the end so mark this as the limit. But only
* wrap inx back to the beginning if outx isn't at zero also.
*/
ep->limit = ep->inx;
if (ep->outx) {
ep->inx = 0;
length = (ep->outx - 1) & PACKET_SIZE_MASK;
}
}
}
else
length = (ep->outx - ep->inx - 1) & PACKET_SIZE_MASK;
/* If there is room, start next read. */
if (length) {
if (length > VUSB_EP_MAX_LENGTH_TRANSFER)
length = VUSB_EP_MAX_LENGTH_TRANSFER;
ep->request_index = ep->inx;
ep->request_length = length;
ep->full_flag = FALSE;
ep->request_active = TRUE;
USB_ISR_io_request(ep_index, &ep->buffer[ep->inx], length);
}
else {
/* I/O must be restarted by task, set flag. */
ep->full_flag = TRUE;
ep->request_active = FALSE;
}
}
/**************************************************************************
*
* Function Name: service_ep0
* Comments:
* Called upon a completed endpoint 0 transfer. Setup data
* have already been copied to the local setup buffer, "usb_setup".
*
**************************************************************************/
static void service_ep0(Uint8 ep, Boolean setup, Uint32 length)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -