vusbd11un.c
4.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*HEADER******************************************************************
**************************************************************************
***
*** Copyright (c) 2001-2002 ARC International.
*** All rights reserved
***
*** This software embodies materials and concepts which are
*** confidential to ARC International and is made
*** available solely pursuant to the terms of a written license
*** agreement with ARC International
***
*** File: vusbd11.c
***
*** Comments:
*** This file contains the low-level VUSB1.1 routines.
***
**************************************************************************
*END*********************************************************************/
#include "os_bb.h"
#include "osint.h"
#include "../host.h"
/*FUNCTION*----------------------------------------------------------------
*
* Function Name : _usb_dci_vusb11_unstall_endpoint
* Returned Value : None
* Comments :
* Unstalls and endpoint and clears out its BDTs
*
*END*--------------------------------------------------------------------*/
void _usb_dci_vusb11_unstall_endpoint
(
/* [IN] Handle to the USB device */
_usb_device_handle handle,
/* [IN] Endpoint to clear */
uint_8 ep
)
{
USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;
usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
usb_dev_ptr->XDSEND[ep].CTL &= ~VUSB_EP_CTRL_STALL;
usb_dev_ptr->XDRECV[ep].CTL &= ~VUSB_EP_CTRL_STALL;
_usb_dci_vusb11_cancel_transfer(handle, USB_SEND, ep);
_usb_dci_vusb11_cancel_transfer(handle, USB_RECV, ep);
/* clear stall bit */
usb_dev_ptr->ENDPT_REGS[ep] &= ~VUSB_EP_CTRL_STALL;
return;
}
/*FUNCTION*----------------------------------------------------------------
*
* Function Name : _usb_dci_vusb11_cancel_transfer
* Returned Value : None
* Comments :
* Cancels the BDTs on the specified endpoint in the specified direction.
*
*END*--------------------------------------------------------------------*/
void _usb_dci_vusb11_cancel_transfer
(
/* [IN] Handle to the USB device */
_usb_device_handle handle,
/* [IN] Direction to cancel */
uint_8 direction,
/* [IN] Endpoint to cancel */
uint_8 ep
)
{
USB_DEV_STATE_STRUCT_PTR usb_dev_ptr;
XD_STRUCT_PTR pxd;
BDT_STRUCT_PTR BDT_PTR;
BDT_STRUCT copy_bdt;
usb_dev_ptr = (USB_DEV_STATE_STRUCT_PTR)handle;
//PRINTF("dev_cancel_transfer: ep %d, dir %d\n", ep, direction);
if (direction == USB_SEND) {
pxd = &usb_dev_ptr->XDSEND[ep];
} else {
pxd = &usb_dev_ptr->XDRECV[ep];
}
/* If packet pending:
** If 2 packets pending, dont toggle ODDEVEN
** If OWNS bit is set, disable ep reset owns toggle next oddeven
** .
*/
if (pxd->PACKETPENDING == 1) {
BDT_PTR = &usb_dev_ptr->USB_BDT_PAGE[ep][direction]\
[VUSB_TOGGLE_BIT(pxd->NEXTODDEVEN)];
_usb_bdt_copy_swab_d(BDT_PTR, ©_bdt);
if (copy_bdt.REGISTER.BDTCTL & VUSB_BDT_OWNS_BIT) {
//PRINTF("dev_cancel_transfer: one pkt pending, clear BDT 0x%x\n", BDT_PTR);
/* clear current BDT for this direction */
VUSB_CLEAR_CURRENT_BDT(©_bdt, pxd);
_usb_bdt_copy_swab_d(©_bdt, BDT_PTR);
pxd->NEXTODDEVEN = VUSB_TOGGLE_BIT(pxd->NEXTODDEVEN);
}
}
if (pxd->PACKETPENDING == 2) {
BDT_PTR = &usb_dev_ptr->USB_BDT_PAGE[ep][direction][pxd->NEXTODDEVEN];
_usb_bdt_copy_swab_d(BDT_PTR, ©_bdt);
if (copy_bdt.REGISTER.BDTCTL & VUSB_BDT_OWNS_BIT) {
/* clear current BDT for this direction */
//PRINTF("dev_cancel_transfer: two pkt pending, clear BDT 0x%x\n", BDT_PTR);
VUSB_CLEAR_CURRENT_BDT(©_bdt, pxd);
_usb_bdt_copy_swab_d(©_bdt, BDT_PTR);
}
BDT_PTR = &usb_dev_ptr->USB_BDT_PAGE[ep][direction]\
[VUSB_TOGGLE_BIT(pxd->NEXTODDEVEN)];
_usb_bdt_copy_swab_d(BDT_PTR, ©_bdt);
if (copy_bdt.REGISTER.BDTCTL & VUSB_BDT_OWNS_BIT) {
//PRINTF("dev_cancel_transfer: two pkt pending, clear BDT 0x%x\n", BDT_PTR);
VUSB_CLEAR_CURRENT_BDT(©_bdt, pxd);
_usb_bdt_copy_swab_d(©_bdt, BDT_PTR);
}
}
/* clear owns bit and flag as dequeued */
pxd->BDTCTL = (uint_8)VUSB_BDT_DEQUEUED;
/*
** Check the endpoint control register image to see if the endpoint
** is disabled or stalled, and update the status byte.
*/
if (pxd->CTL & VUSB_ENDPT_STALL_BIT) {
usb_dev_ptr->XDRECV[ep].STATUS = USB_STATUS_STALLED;
} else {
pxd->STATUS = USB_STATUS_IDLE;
} /* Endif */
return;
}