📄 usb20hw.c
字号:
* Transfer complete. Call the endpoint service function
* for the endpoint.
*/
USBserviceEP[ep_index](ep_index, FALSE,
dTD->LENGTH -
(dTD->SIZE_IOC_STS >> 16));
/*
* Get the address of the next dTD, if any, masking
* off the Terminal Flag in low-order bit, and update
* Endpoint dTD Head table entry.
*/
next_dTD = (dDT_STRUCT *)(dTD->NEXT & ~DTD_TERM_BIT);
usb_state.EP_DTD_HEADS[ep_index] = next_dTD;
/* Move the dTD to the free dTD pool. */
dTD->NEXT = (Uint32)usb_state.DTD_POOL;
usb_state.DTD_POOL = dTD;
dTD = next_dTD;
}
}
}
}
}
}
/**************************************************************************
*
* Function Name : USB_ISR_process_reset
* Returned Value : None
* Comments :
* Services reset interrupt.
*
**************************************************************************/
static void USB_ISR_process_reset(void)
{
Uint32 endpt_bits, lpcnt, i;
dDT_STRUCT *dTD;
/* Set the address back to zero. */
usb_opreg->DEVICE_ADDR = 0;
usb_state.DEVICE_ADDRESS = 0;
usb_state.USB_STATE = USB_STATE_DEFAULT;
/* Clear all the setup token semaphores. */
endpt_bits = usb_opreg->ENDPT_SETUP_STAT;
usb_opreg->ENDPT_SETUP_STAT = endpt_bits;
/* Clear all the endpoint complete status bits. */
endpt_bits = usb_opreg->ENDPTCOMPLETE;
usb_opreg->ENDPTCOMPLETE = endpt_bits;
for (lpcnt = 0; lpcnt < HW_LOOP_CNT; lpcnt++) {
/* Wait until all ENDPTPRIME bits cleared. */
if (usb_opreg->ENDPTPRIME == 0)
break;
}
if (usb_opreg->ENDPTPRIME == 0) {
/*
* Flush all endpoints:
* NOTE: There is a caveat in the manual that flushing may take a
* large amount of time AND SHOULD NOT BE DONE AT INTERRUPT LEVEL!
* Also, we are warned that a transfer may be in progress at the time
* of the flush request and to avoid obvious problems, the flush is
* ignored and must be repeated. This should not be an issue for
* normal resets; only if something bad is happening.
*/
/* Write 1s to the Flush register. */
usb_opreg->ENDPTFLUSH = 0xFFFFFFFF;
for (lpcnt = 0; lpcnt < HW_LOOP_CNT; lpcnt++) {
/* Wait until all bits are reset. */
if (usb_opreg->ENDPTFLUSH == 0) {
/* All done, now reinitialize endpoints and dTD pool. */
for (i = 0; i < 2 * USB_MAX_ENDPOINTS; i++) {
/* Initially no endpoints are initialized. */
usb_state.EP_INIT[i] = FALSE;
/* Initialize all device queue heads. */
usb_state.EP_QUEUE_HEAD_PTR[i].NEXT_DTD_PTR = DTD_TERM_BIT;
usb_state.EP_DTD_HEADS[i] = NULL;
}
/* Enqueue all the dTDs into the free pool. */
usb_state.DTD_POOL = NULL;
dTD = usb_state.DTD_ALIGNED_BASE_PTR;
for (i = 0; i < DTD_POOL_CNT; i++, dTD++) {
/* Move the dTD to the free dTD pool. */
dTD->NEXT = (Uint32)usb_state.DTD_POOL;
usb_state.DTD_POOL = dTD;
}
USB_init_endpoint(EP0_RECV, EP0_PKT_SIZE,
USB_CONTROL_ENDPOINT, 0);
USB_init_endpoint(EP0_SEND, EP0_PKT_SIZE,
USB_CONTROL_ENDPOINT, 0);
return;
}
}
}
/* Not successful; defer to task reset. */
USB_ForceReset = RESET_SW;
}
/**************************************************************************
*
* Function Name : USB_task_process_reset
* Returned Value : None
* Comments :
* Services reset interrupt at task level.
*
**************************************************************************/
void USB_task_process_reset(void)
{
Uint32 endpt_bits, lpcnt, i;
dDT_STRUCT *dTD;
/* Let ISR know that reset is in progress so it won't try an ISR reset. */
if (!USB_ForceReset)
USB_ForceReset = RESET_SW;
/* Set the address back to zero. */
usb_opreg->DEVICE_ADDR = 0;
usb_state.DEVICE_ADDRESS = 0;
usb_state.USB_STATE = USB_STATE_DEFAULT;
/* Clear all the setup token semaphores. */
endpt_bits = usb_opreg->ENDPT_SETUP_STAT;
usb_opreg->ENDPT_SETUP_STAT = endpt_bits;
/* Clear all the endpoint complete status bits. */
endpt_bits = usb_opreg->ENDPTCOMPLETE;
usb_opreg->ENDPTCOMPLETE = endpt_bits;
for (lpcnt = 0; lpcnt < HW_LOOP_LIMIT; lpcnt++) {
/* Wait until all ENDPTPRIME bits cleared. */
if (usb_opreg->ENDPTPRIME == 0)
break;
}
if (USB_ForceReset != RESET_HW && usb_opreg->ENDPTPRIME == 0) {
/*
* Flush all endpoints:
* NOTE: There is a caveat in the manual that flushing may take a
* large amount of time AND SHOULD NOT BE DONE AT INTERRUPT LEVEL!
* Also, we are warned that a transfer may be in progress at the time
* of the flush request and to avoid obvious problems, the flush is
* ignored and must be repeated.
*/
for (lpcnt = 0; lpcnt < HW_LOOP_LIMIT; lpcnt++) {
/* Write 1s to the Flush register. */
usb_opreg->ENDPTFLUSH = 0xFFFFFFFF;
for (i = 0; i < HW_LOOP_CNT; i++) {
/* Wait until all bits are reset. */
if (usb_opreg->ENDPTFLUSH == 0)
break;
}
if (usb_opreg->ENDPTFLUSH == 0) {
/* All done, now reinitialize endpoints > 0 and dTD pool. */
for (i = 2; i < 2 * USB_MAX_ENDPOINTS; i++) {
/* Initially no endpoints are initialized. */
usb_state.EP_INIT[i] = FALSE;
}
for (i = 0; i < 2 * USB_MAX_ENDPOINTS; i++) {
/* Initialize all device queue heads. */
usb_state.EP_QUEUE_HEAD_PTR[i].NEXT_DTD_PTR = DTD_TERM_BIT;
usb_state.EP_DTD_HEADS[i] = NULL;
}
/* Enqueue all the dTDs into the free pool. */
usb_state.DTD_POOL = NULL;
dTD = usb_state.DTD_ALIGNED_BASE_PTR;
for (i = 0; i < DTD_POOL_CNT; i++, dTD++) {
/* Move the dTD to the free dTD pool. */
dTD->NEXT = (Uint32)usb_state.DTD_POOL;
usb_state.DTD_POOL = dTD;
}
USB_ForceReset = NO_RESET;
return;
}
}
}
/* Hardware failed; try to reset it and reinitialize data base. */
USB_chip_and_data_base_initialize();
}
/**************************************************************************
*
* Function Name : USB_shutdown
* Returned Value : None
* Comments :
* Shuts down the VUSB_HS Device.
*
**************************************************************************/
void USB_shutdown(void)
{
/* Disable Device Mode. */
usb_opreg->USB_MODE &= ~VUSB_MODE_CTRL_MODE_DEV;
/* Disable interrupts. */
usb_opreg->USB_INTR &= ~(VUSB_INTERRUPT_BITS);
/* Reset the Run the bit in the command register to stop VUSB. */
usb_opreg->USB_CMD &= ~VUSB_CMD_RUN_STOP;
}
/**************************************************************************
*
* Function Name : USB_ISR_set_address
* Returned Value : None
* Comments :
* Sets the newly assigned device address.
*
**************************************************************************/
void USB_ISR_set_address(Uint8 address)
{
/* The address bits are passed in bits 31-25. Set the address. */
usb_opreg->DEVICE_ADDR = ((Uint32)address << VUSB_ADDRESS_BIT_SHIFT);
}
/**************************************************************************
*
* Function Name : USB_ISR_get_endpoint_status
* Returned Value : endpoint status bit0 :: STALL
* Comments :
* Gets the endpoint status.
*
**************************************************************************/
Uint8 USB_ISR_get_endpoint_status(Uint8 ep_num)
{
ep_num &= 0xf;
return ((usb_opreg->ENDPTCTRLX[ep_num] & VUSB_EPCTRL_EP_STALL) ? 1 : 0);
}
/**************************************************************************
*
* Function Name : USB_ISR_set_endpoint_status
* Returned Value : None
* Comments :
* Sets the endpoint registers, i.e., set/clear ENDPOINT_HALT.
*
**************************************************************************/
void USB_ISR_set_endpoint_status(Uint8 ep_num, Uint8 stall)
{
Uint8 tx;
tx = ep_num & 0x80;
ep_num &= 0x0f;
if (!ep_num) {
if (stall)
usb_opreg->ENDPTCTRLX[0] |= VUSB_EPCTRL_EP_STALL;
else
usb_opreg->ENDPTCTRLX[0] &= ~VUSB_EPCTRL_EP_STALL;
}
else if (stall) {
if (tx)
usb_opreg->ENDPTCTRLX[ep_num] |= VUSB_EPCTRL_TX_EP_STALL;
else
usb_opreg->ENDPTCTRLX[ep_num] |= VUSB_EPCTRL_RX_EP_STALL;
}
else {
if (tx) {
usb_opreg->ENDPTCTRLX[ep_num] |= VUSB_EPCTRL_TX_DATA_TOGGLE_RST;
usb_opreg->ENDPTCTRLX[ep_num] &= ~VUSB_EPCTRL_TX_EP_STALL;
}
else {
usb_opreg->ENDPTCTRLX[ep_num] |= VUSB_EPCTRL_RX_DATA_TOGGLE_RST;
usb_opreg->ENDPTCTRLX[ep_num] &= ~VUSB_EPCTRL_RX_EP_STALL;
}
}
}
/**************************************************************************
*
* Function Name : USB_ISR_set_test_mode
* Returned Value : None
* Comments :
* Sets/resets the test mode.
*
**************************************************************************/
void USB_ISR_set_test_mode(Uint16 test_mode)
{
usb_opreg->ENDPTCTRLX[0] |= VUSB_EPCTRL_TX_DATA_TOGGLE_RST;
if (test_mode == USB_TEST_MODE_TEST_PACKET)
USB_ISR_io_request(EP0_SEND, (void *)test_packet,
USB_TEST_MODE_PACKET_LENGTH);
usb_opreg->PORTSCX[0] |= (Uint32)test_mode << 8;
/* Hang up in ISR next time in. */
TestModeLock = TRUE;
}
#ifdef NOT_IMPLEMENTED
/*
* The following is for "documentation" purposes if there is some need in
* the future.
*/
/**************************************************************************
*
* Function Name : USB_process_resume
* Returned Value : None
* Comments :
* Process Resume event.
*
**************************************************************************/
/* NOT CALLED and NOT COMPLETE - should not be called at interrupt level. */
void USB_assert_resume(void)
{
Uint32 i, temp;
/* Assert the Resume signal. */
usb_opreg->PORTSCX[0] |= VUSB_PORTSCX_PORT_FORCE_RESUME;
/* Keep it asserted for 20 ms. */
for (i = 0; i < USB_RESUME_ASSERTION_PERIOD; i++) {
temp = (usb_opreg->USB_FRINDEX & VUSB_FRINDEX_MS_MASK);
while (temp == (usb_opreg->USB_FRINDEX & VUSB_FRINDEX_MS_MASK))
{
}
/* 1 millisecond complete. */
}
/* Deassert the Resume. */
usb_opreg->PORTSCX[0] &= ~VUSB_PORTSCX_PORT_FORCE_RESUME;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -