User | Revision | Line number | New contents of line |
mbed714 |
0:d616ece2d859
|
1
|
|
mbed714 |
0:d616ece2d859
|
2
|
/*
|
mbed714 |
0:d616ece2d859
|
3
|
Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
|
mbed714 |
0:d616ece2d859
|
4
|
|
mbed714 |
0:d616ece2d859
|
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
mbed714 |
0:d616ece2d859
|
6
|
of this software and associated documentation files (the "Software"), to deal
|
mbed714 |
0:d616ece2d859
|
7
|
in the Software without restriction, including without limitation the rights
|
mbed714 |
0:d616ece2d859
|
8
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
mbed714 |
0:d616ece2d859
|
9
|
copies of the Software, and to permit persons to whom the Software is
|
mbed714 |
0:d616ece2d859
|
10
|
furnished to do so, subject to the following conditions:
|
mbed714 |
0:d616ece2d859
|
11
|
|
mbed714 |
0:d616ece2d859
|
12
|
The above copyright notice and this permission notice shall be included in
|
mbed714 |
0:d616ece2d859
|
13
|
all copies or substantial portions of the Software.
|
mbed714 |
0:d616ece2d859
|
14
|
|
mbed714 |
0:d616ece2d859
|
15
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
mbed714 |
0:d616ece2d859
|
16
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
mbed714 |
0:d616ece2d859
|
17
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
mbed714 |
0:d616ece2d859
|
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
mbed714 |
0:d616ece2d859
|
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
mbed714 |
0:d616ece2d859
|
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
mbed714 |
0:d616ece2d859
|
21
|
THE SOFTWARE.
|
mbed714 |
0:d616ece2d859
|
22
|
*/
|
mbed714 |
0:d616ece2d859
|
23
|
|
mbed714 |
0:d616ece2d859
|
24
|
#include "UsbEndpoint.h"
|
mbed714 |
0:d616ece2d859
|
25
|
|
mbed714 |
0:d616ece2d859
|
26
|
#include "UsbDevice.h"
|
mbed714 |
0:d616ece2d859
|
27
|
|
mbed714 |
0:d616ece2d859
|
28
|
#include "usb_mem.h"
|
mbed714 |
0:d616ece2d859
|
29
|
|
mbed714 |
0:d616ece2d859
|
30
|
#include "netCfg.h"
|
mbed714 |
0:d616ece2d859
|
31
|
#if NET_USB
|
mbed714 |
0:d616ece2d859
|
32
|
|
mbed714 |
0:d616ece2d859
|
33
|
//#define __DEBUG
|
mbed714 |
0:d616ece2d859
|
34
|
#include "dbg/dbg.h"
|
mbed714 |
0:d616ece2d859
|
35
|
|
mbed714 |
0:d616ece2d859
|
36
|
UsbEndpoint::UsbEndpoint( UsbDevice* pDevice, uint8_t ep, bool dir, UsbEndpointType type, uint16_t size, int addr /*= -1*/ ) : m_pDevice(pDevice), m_result(true), m_status((int)USBERR_OK), m_len(0), m_pBufStartPtr(NULL),
|
mbed714 |
0:d616ece2d859
|
37
|
m_pCbItem(NULL), m_pCbMeth(NULL), m_pNextEp(NULL)
|
mbed714 |
0:d616ece2d859
|
38
|
{
|
mbed714 |
0:d616ece2d859
|
39
|
//Insert into Eps list
|
mbed714 |
0:d616ece2d859
|
40
|
//FIXME: Assert that no USB interrupt is triggered meanwhile
|
mbed714 |
0:d616ece2d859
|
41
|
if(m_pHeadEp)
|
mbed714 |
0:d616ece2d859
|
42
|
{
|
mbed714 |
0:d616ece2d859
|
43
|
m_pNextEp = m_pHeadEp;
|
mbed714 |
0:d616ece2d859
|
44
|
m_pHeadEp = this;
|
mbed714 |
0:d616ece2d859
|
45
|
}
|
mbed714 |
0:d616ece2d859
|
46
|
else
|
mbed714 |
0:d616ece2d859
|
47
|
{
|
mbed714 |
0:d616ece2d859
|
48
|
m_pNextEp = NULL;
|
mbed714 |
0:d616ece2d859
|
49
|
m_pHeadEp = this;
|
mbed714 |
0:d616ece2d859
|
50
|
}
|
mbed714 |
0:d616ece2d859
|
51
|
|
mbed714 |
0:d616ece2d859
|
52
|
m_pEd = (volatile HCED*)usb_get_ed();
|
mbed714 |
0:d616ece2d859
|
53
|
|
mbed714 |
0:d616ece2d859
|
54
|
m_pTdHead = (volatile HCTD*)usb_get_td();
|
mbed714 |
0:d616ece2d859
|
55
|
m_pTdTail = (volatile HCTD*)usb_get_td();
|
mbed714 |
0:d616ece2d859
|
56
|
|
mbed714 |
0:d616ece2d859
|
57
|
//printf("\r\n--m_pEd = %p--\r\n", m_pEd);
|
mbed714 |
0:d616ece2d859
|
58
|
DBG("m_pEd = %p\n", m_pEd);
|
mbed714 |
0:d616ece2d859
|
59
|
DBG("m_pTdHead = %p\n", m_pTdHead);
|
mbed714 |
0:d616ece2d859
|
60
|
DBG("m_pTdTail = %p\n", m_pTdTail);
|
mbed714 |
0:d616ece2d859
|
61
|
|
mbed714 |
0:d616ece2d859
|
62
|
//Init Ed & Td
|
mbed714 |
0:d616ece2d859
|
63
|
//printf("\r\n--Ep Init--\r\n");
|
mbed714 |
0:d616ece2d859
|
64
|
memset((void*)m_pEd, 0, sizeof(HCED));
|
mbed714 |
0:d616ece2d859
|
65
|
//printf("\r\n--Td Init--\r\n");
|
mbed714 |
0:d616ece2d859
|
66
|
|
mbed714 |
0:d616ece2d859
|
67
|
memset((void*)m_pTdHead, 0, sizeof(HCTD));
|
mbed714 |
0:d616ece2d859
|
68
|
memset((void*)m_pTdTail, 0, sizeof(HCTD));
|
mbed714 |
0:d616ece2d859
|
69
|
|
mbed714 |
0:d616ece2d859
|
70
|
if(addr == -1)
|
mbed714 |
0:d616ece2d859
|
71
|
addr = pDevice->m_addr;
|
mbed714 |
0:d616ece2d859
|
72
|
|
mbed714 |
0:d616ece2d859
|
73
|
//Setup Ed
|
mbed714 |
0:d616ece2d859
|
74
|
//printf("\r\n--Ep Setup--\r\n");
|
mbed714 |
0:d616ece2d859
|
75
|
m_pEd->Control = addr | /* USB address */
|
mbed714 |
0:d616ece2d859
|
76
|
((ep & 0x7F) << 7) | /* Endpoint address */
|
mbed714 |
0:d616ece2d859
|
77
|
(type!=USB_CONTROL?((dir?2:1) << 11):0) | /* direction : Out = 1, 2 = In */
|
mbed714 |
0:d616ece2d859
|
78
|
(size << 16); /* MaxPkt Size */
|
mbed714 |
0:d616ece2d859
|
79
|
|
mbed714 |
0:d616ece2d859
|
80
|
m_dir = dir;
|
mbed714 |
0:d616ece2d859
|
81
|
m_setup = false;
|
mbed714 |
0:d616ece2d859
|
82
|
m_type = type;
|
mbed714 |
0:d616ece2d859
|
83
|
|
mbed714 |
0:d616ece2d859
|
84
|
m_pEd->TailTd = m_pEd->HeadTd = (uint32_t) m_pTdTail; //Empty TD list
|
mbed714 |
0:d616ece2d859
|
85
|
|
mbed714 |
0:d616ece2d859
|
86
|
DBG("Before link\n");
|
mbed714 |
0:d616ece2d859
|
87
|
|
mbed714 |
0:d616ece2d859
|
88
|
//printf("\r\n--Ep Reg--\r\n");
|
mbed714 |
0:d616ece2d859
|
89
|
//Append Ed to Ed list
|
mbed714 |
0:d616ece2d859
|
90
|
volatile HCED* prevEd;
|
mbed714 |
0:d616ece2d859
|
91
|
switch( m_type )
|
mbed714 |
0:d616ece2d859
|
92
|
{
|
mbed714 |
0:d616ece2d859
|
93
|
case USB_CONTROL:
|
mbed714 |
0:d616ece2d859
|
94
|
prevEd = (volatile HCED*) LPC_USB->HcControlHeadED;
|
mbed714 |
0:d616ece2d859
|
95
|
break;
|
mbed714 |
0:d616ece2d859
|
96
|
case USB_BULK:
|
mbed714 |
0:d616ece2d859
|
97
|
default:
|
mbed714 |
0:d616ece2d859
|
98
|
prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
|
mbed714 |
0:d616ece2d859
|
99
|
break;
|
mbed714 |
0:d616ece2d859
|
100
|
}
|
mbed714 |
0:d616ece2d859
|
101
|
|
mbed714 |
0:d616ece2d859
|
102
|
DBG("prevEd is %p\n", prevEd);
|
mbed714 |
0:d616ece2d859
|
103
|
|
mbed714 |
0:d616ece2d859
|
104
|
if(prevEd)
|
mbed714 |
0:d616ece2d859
|
105
|
{
|
mbed714 |
0:d616ece2d859
|
106
|
DBG("prevEd set\n")
|
mbed714 |
0:d616ece2d859
|
107
|
|
mbed714 |
0:d616ece2d859
|
108
|
while(prevEd->Next)
|
mbed714 |
0:d616ece2d859
|
109
|
{
|
mbed714 |
0:d616ece2d859
|
110
|
DBG("prevEd->Next = %08x\n", prevEd->Next);
|
mbed714 |
0:d616ece2d859
|
111
|
prevEd = (volatile HCED*) prevEd->Next;
|
mbed714 |
0:d616ece2d859
|
112
|
}
|
mbed714 |
0:d616ece2d859
|
113
|
prevEd->Next = (uint32_t) m_pEd;
|
mbed714 |
0:d616ece2d859
|
114
|
|
mbed714 |
0:d616ece2d859
|
115
|
}
|
mbed714 |
0:d616ece2d859
|
116
|
else
|
mbed714 |
0:d616ece2d859
|
117
|
{
|
mbed714 |
0:d616ece2d859
|
118
|
switch( m_type )
|
mbed714 |
0:d616ece2d859
|
119
|
{
|
mbed714 |
0:d616ece2d859
|
120
|
case USB_CONTROL:
|
mbed714 |
0:d616ece2d859
|
121
|
LPC_USB->HcControlHeadED = (uint32_t) m_pEd;
|
mbed714 |
0:d616ece2d859
|
122
|
break;
|
mbed714 |
0:d616ece2d859
|
123
|
case USB_BULK:
|
mbed714 |
0:d616ece2d859
|
124
|
default:
|
mbed714 |
0:d616ece2d859
|
125
|
LPC_USB->HcBulkHeadED = (uint32_t) m_pEd;
|
mbed714 |
0:d616ece2d859
|
126
|
break;
|
mbed714 |
0:d616ece2d859
|
127
|
}
|
mbed714 |
0:d616ece2d859
|
128
|
}
|
mbed714 |
0:d616ece2d859
|
129
|
|
mbed714 |
0:d616ece2d859
|
130
|
DBG("Ep init\n");
|
mbed714 |
0:d616ece2d859
|
131
|
}
|
mbed714 |
0:d616ece2d859
|
132
|
|
mbed714 |
0:d616ece2d859
|
133
|
UsbEndpoint::~UsbEndpoint()
|
mbed714 |
0:d616ece2d859
|
134
|
{
|
mbed714 |
0:d616ece2d859
|
135
|
//Remove from Eps list
|
mbed714 |
0:d616ece2d859
|
136
|
//FIXME: Assert that no USB interrupt is triggered meanwhile
|
mbed714 |
0:d616ece2d859
|
137
|
if(m_pHeadEp != this)
|
mbed714 |
0:d616ece2d859
|
138
|
{
|
mbed714 |
0:d616ece2d859
|
139
|
UsbEndpoint* prevEp = m_pHeadEp;
|
mbed714 |
0:d616ece2d859
|
140
|
while(prevEp->m_pNextEp != this)
|
mbed714 |
0:d616ece2d859
|
141
|
prevEp = prevEp->m_pNextEp;
|
mbed714 |
0:d616ece2d859
|
142
|
prevEp->m_pNextEp = m_pNextEp;
|
mbed714 |
0:d616ece2d859
|
143
|
}
|
mbed714 |
0:d616ece2d859
|
144
|
else
|
mbed714 |
0:d616ece2d859
|
145
|
{
|
mbed714 |
0:d616ece2d859
|
146
|
m_pHeadEp = m_pNextEp;
|
mbed714 |
0:d616ece2d859
|
147
|
}
|
mbed714 |
0:d616ece2d859
|
148
|
|
mbed714 |
0:d616ece2d859
|
149
|
m_pEd->Control |= ED_SKIP; //Skip this Ep in queue
|
mbed714 |
0:d616ece2d859
|
150
|
|
mbed714 |
0:d616ece2d859
|
151
|
//Remove from queue
|
mbed714 |
0:d616ece2d859
|
152
|
volatile HCED* prevEd;
|
mbed714 |
0:d616ece2d859
|
153
|
switch( m_type )
|
mbed714 |
0:d616ece2d859
|
154
|
{
|
mbed714 |
0:d616ece2d859
|
155
|
case USB_CONTROL:
|
mbed714 |
0:d616ece2d859
|
156
|
prevEd = (volatile HCED*) LPC_USB->HcControlHeadED;
|
mbed714 |
0:d616ece2d859
|
157
|
break;
|
mbed714 |
0:d616ece2d859
|
158
|
case USB_BULK:
|
mbed714 |
0:d616ece2d859
|
159
|
default:
|
mbed714 |
0:d616ece2d859
|
160
|
prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
|
mbed714 |
0:d616ece2d859
|
161
|
break;
|
mbed714 |
0:d616ece2d859
|
162
|
}
|
mbed714 |
0:d616ece2d859
|
163
|
if( m_pEd == prevEd )
|
mbed714 |
0:d616ece2d859
|
164
|
{
|
mbed714 |
0:d616ece2d859
|
165
|
switch( m_type )
|
mbed714 |
0:d616ece2d859
|
166
|
{
|
mbed714 |
0:d616ece2d859
|
167
|
case USB_CONTROL:
|
mbed714 |
0:d616ece2d859
|
168
|
LPC_USB->HcControlHeadED = m_pEd->Next;
|
mbed714 |
0:d616ece2d859
|
169
|
break;
|
mbed714 |
0:d616ece2d859
|
170
|
case USB_BULK:
|
mbed714 |
0:d616ece2d859
|
171
|
default:
|
mbed714 |
0:d616ece2d859
|
172
|
LPC_USB->HcBulkHeadED = m_pEd->Next;
|
mbed714 |
0:d616ece2d859
|
173
|
break;
|
mbed714 |
0:d616ece2d859
|
174
|
}
|
mbed714 |
0:d616ece2d859
|
175
|
LPC_USB->HcBulkHeadED = m_pEd->Next;
|
mbed714 |
0:d616ece2d859
|
176
|
}
|
mbed714 |
0:d616ece2d859
|
177
|
else
|
mbed714 |
0:d616ece2d859
|
178
|
{
|
mbed714 |
0:d616ece2d859
|
179
|
while( prevEd->Next != (uint32_t) m_pEd )
|
mbed714 |
0:d616ece2d859
|
180
|
{
|
mbed714 |
0:d616ece2d859
|
181
|
prevEd = (volatile HCED*) prevEd->Next;
|
mbed714 |
0:d616ece2d859
|
182
|
}
|
mbed714 |
0:d616ece2d859
|
183
|
prevEd->Next = m_pEd->Next;
|
mbed714 |
0:d616ece2d859
|
184
|
}
|
mbed714 |
0:d616ece2d859
|
185
|
|
mbed714 |
0:d616ece2d859
|
186
|
//
|
mbed714 |
0:d616ece2d859
|
187
|
usb_free_ed((volatile byte*)m_pEd);
|
mbed714 |
0:d616ece2d859
|
188
|
|
mbed714 |
0:d616ece2d859
|
189
|
usb_free_td((volatile byte*)m_pTdHead);
|
mbed714 |
0:d616ece2d859
|
190
|
usb_free_td((volatile byte*)m_pTdTail);
|
mbed714 |
0:d616ece2d859
|
191
|
}
|
mbed714 |
0:d616ece2d859
|
192
|
|
mbed714 |
0:d616ece2d859
|
193
|
void UsbEndpoint::setNextToken(uint32_t token) //Only for control Eps
|
mbed714 |
0:d616ece2d859
|
194
|
{
|
mbed714 |
0:d616ece2d859
|
195
|
switch(token)
|
mbed714 |
0:d616ece2d859
|
196
|
{
|
mbed714 |
0:d616ece2d859
|
197
|
case TD_SETUP:
|
mbed714 |
0:d616ece2d859
|
198
|
m_dir = false;
|
mbed714 |
0:d616ece2d859
|
199
|
m_setup = true;
|
mbed714 |
0:d616ece2d859
|
200
|
break;
|
mbed714 |
0:d616ece2d859
|
201
|
case TD_IN:
|
mbed714 |
0:d616ece2d859
|
202
|
m_dir = true;
|
mbed714 |
0:d616ece2d859
|
203
|
m_setup = false;
|
mbed714 |
0:d616ece2d859
|
204
|
break;
|
mbed714 |
0:d616ece2d859
|
205
|
case TD_OUT:
|
mbed714 |
0:d616ece2d859
|
206
|
m_dir = false;
|
mbed714 |
0:d616ece2d859
|
207
|
m_setup = false;
|
mbed714 |
0:d616ece2d859
|
208
|
break;
|
mbed714 |
0:d616ece2d859
|
209
|
}
|
mbed714 |
0:d616ece2d859
|
210
|
}
|
mbed714 |
0:d616ece2d859
|
211
|
|
mbed714 |
0:d616ece2d859
|
212
|
UsbErr UsbEndpoint::transfer(volatile uint8_t* buf, uint32_t len)
|
mbed714 |
0:d616ece2d859
|
213
|
{
|
mbed714 |
0:d616ece2d859
|
214
|
if(!m_result)
|
mbed714 |
0:d616ece2d859
|
215
|
return USBERR_BUSY; //The previous trasnfer is not completed
|
mbed714 |
0:d616ece2d859
|
216
|
//FIXME: We should be able to queue the next transfer, still needs to be implemented
|
mbed714 |
0:d616ece2d859
|
217
|
|
mbed714 |
0:d616ece2d859
|
218
|
if( !m_pDevice->connected() )
|
mbed714 |
0:d616ece2d859
|
219
|
return USBERR_DISCONNECTED;
|
mbed714 |
0:d616ece2d859
|
220
|
|
mbed714 |
0:d616ece2d859
|
221
|
m_result = false;
|
mbed714 |
0:d616ece2d859
|
222
|
|
mbed714 |
0:d616ece2d859
|
223
|
volatile uint32_t token = (m_setup?TD_SETUP:(m_dir?TD_IN:TD_OUT));
|
mbed714 |
0:d616ece2d859
|
224
|
|
mbed714 |
0:d616ece2d859
|
225
|
volatile uint32_t td_toggle;
|
mbed714 |
0:d616ece2d859
|
226
|
if (m_type == USB_CONTROL)
|
mbed714 |
0:d616ece2d859
|
227
|
{
|
mbed714 |
0:d616ece2d859
|
228
|
if (m_setup)
|
mbed714 |
0:d616ece2d859
|
229
|
{
|
mbed714 |
0:d616ece2d859
|
230
|
td_toggle = TD_TOGGLE_0;
|
mbed714 |
0:d616ece2d859
|
231
|
}
|
mbed714 |
0:d616ece2d859
|
232
|
else
|
mbed714 |
0:d616ece2d859
|
233
|
{
|
mbed714 |
0:d616ece2d859
|
234
|
td_toggle = TD_TOGGLE_1;
|
mbed714 |
0:d616ece2d859
|
235
|
}
|
mbed714 |
0:d616ece2d859
|
236
|
}
|
mbed714 |
0:d616ece2d859
|
237
|
else
|
mbed714 |
0:d616ece2d859
|
238
|
{
|
mbed714 |
0:d616ece2d859
|
239
|
td_toggle = 0;
|
mbed714 |
0:d616ece2d859
|
240
|
}
|
mbed714 |
0:d616ece2d859
|
241
|
|
mbed714 |
0:d616ece2d859
|
242
|
//Swap Tds
|
mbed714 |
0:d616ece2d859
|
243
|
volatile HCTD* pTdSwap;
|
mbed714 |
0:d616ece2d859
|
244
|
pTdSwap = m_pTdTail;
|
mbed714 |
0:d616ece2d859
|
245
|
m_pTdTail = m_pTdHead;
|
mbed714 |
0:d616ece2d859
|
246
|
m_pTdHead = pTdSwap;
|
mbed714 |
0:d616ece2d859
|
247
|
|
mbed714 |
0:d616ece2d859
|
248
|
m_pTdHead->Control = (TD_ROUNDING |
|
mbed714 |
0:d616ece2d859
|
249
|
token |
|
mbed714 |
0:d616ece2d859
|
250
|
TD_DELAY_INT(0) |//7
|
mbed714 |
0:d616ece2d859
|
251
|
td_toggle |
|
mbed714 |
0:d616ece2d859
|
252
|
TD_CC);
|
mbed714 |
0:d616ece2d859
|
253
|
|
mbed714 |
0:d616ece2d859
|
254
|
m_pTdTail->Control = 0;
|
mbed714 |
0:d616ece2d859
|
255
|
m_pTdHead->CurrBufPtr = (uint32_t) buf;
|
mbed714 |
0:d616ece2d859
|
256
|
m_pBufStartPtr = buf;
|
mbed714 |
0:d616ece2d859
|
257
|
m_pTdTail->CurrBufPtr = 0;
|
mbed714 |
0:d616ece2d859
|
258
|
m_pTdHead->Next = (uint32_t) m_pTdTail;
|
mbed714 |
0:d616ece2d859
|
259
|
m_pTdTail->Next = 0;
|
mbed714 |
0:d616ece2d859
|
260
|
m_pTdHead->BufEnd = (uint32_t)(buf + (len - 1));
|
mbed714 |
0:d616ece2d859
|
261
|
m_pTdTail->BufEnd = 0;
|
mbed714 |
0:d616ece2d859
|
262
|
|
mbed714 |
0:d616ece2d859
|
263
|
m_pEd->HeadTd = (uint32_t)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002); //Carry bit
|
mbed714 |
0:d616ece2d859
|
264
|
m_pEd->TailTd = (uint32_t)m_pTdTail;
|
mbed714 |
0:d616ece2d859
|
265
|
|
mbed714 |
0:d616ece2d859
|
266
|
//DBG("m_pEd->HeadTd = %08x\n", m_pEd->HeadTd);
|
mbed714 |
0:d616ece2d859
|
267
|
|
mbed714 |
0:d616ece2d859
|
268
|
if(m_type == USB_CONTROL)
|
mbed714 |
0:d616ece2d859
|
269
|
{
|
mbed714 |
0:d616ece2d859
|
270
|
LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF;
|
mbed714 |
0:d616ece2d859
|
271
|
LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_CLE; //Enable control list
|
mbed714 |
0:d616ece2d859
|
272
|
}
|
mbed714 |
0:d616ece2d859
|
273
|
else //USB_BULK
|
mbed714 |
0:d616ece2d859
|
274
|
{
|
mbed714 |
0:d616ece2d859
|
275
|
LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
|
mbed714 |
0:d616ece2d859
|
276
|
LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE; //Enable bulk list
|
mbed714 |
0:d616ece2d859
|
277
|
}
|
mbed714 |
0:d616ece2d859
|
278
|
|
mbed714 |
0:d616ece2d859
|
279
|
//m_done = false;
|
mbed714 |
0:d616ece2d859
|
280
|
m_len = len;
|
mbed714 |
0:d616ece2d859
|
281
|
|
mbed714 |
0:d616ece2d859
|
282
|
return USBERR_PROCESSING;
|
mbed714 |
0:d616ece2d859
|
283
|
|
mbed714 |
0:d616ece2d859
|
284
|
}
|
mbed714 |
0:d616ece2d859
|
285
|
|
mbed714 |
0:d616ece2d859
|
286
|
int UsbEndpoint::status()
|
mbed714 |
0:d616ece2d859
|
287
|
{
|
mbed714 |
0:d616ece2d859
|
288
|
if( !m_pDevice->connected() )
|
mbed714 |
0:d616ece2d859
|
289
|
{
|
mbed714 |
0:d616ece2d859
|
290
|
if(!m_result)
|
mbed714 |
0:d616ece2d859
|
291
|
onCompletion();
|
mbed714 |
0:d616ece2d859
|
292
|
m_result = true;
|
mbed714 |
0:d616ece2d859
|
293
|
return (int)USBERR_DISCONNECTED;
|
mbed714 |
0:d616ece2d859
|
294
|
}
|
mbed714 |
0:d616ece2d859
|
295
|
else if( !m_result )
|
mbed714 |
0:d616ece2d859
|
296
|
{
|
mbed714 |
0:d616ece2d859
|
297
|
return (int)USBERR_PROCESSING;
|
mbed714 |
0:d616ece2d859
|
298
|
}
|
mbed714 |
0:d616ece2d859
|
299
|
/*else if( m_done )
|
mbed714 |
0:d616ece2d859
|
300
|
{
|
mbed714 |
0:d616ece2d859
|
301
|
return (int)USBERR_OK;
|
mbed714 |
0:d616ece2d859
|
302
|
}*/
|
mbed714 |
0:d616ece2d859
|
303
|
else
|
mbed714 |
0:d616ece2d859
|
304
|
{
|
mbed714 |
0:d616ece2d859
|
305
|
return m_status;
|
mbed714 |
0:d616ece2d859
|
306
|
}
|
mbed714 |
0:d616ece2d859
|
307
|
}
|
mbed714 |
0:d616ece2d859
|
308
|
|
mbed714 |
0:d616ece2d859
|
309
|
void UsbEndpoint::updateAddr(int addr)
|
mbed714 |
0:d616ece2d859
|
310
|
{
|
mbed714 |
0:d616ece2d859
|
311
|
DBG("m_pEd->Control = %08x\n", m_pEd->Control);
|
mbed714 |
0:d616ece2d859
|
312
|
m_pEd->Control &= ~0x7F;
|
mbed714 |
0:d616ece2d859
|
313
|
m_pEd->Control |= addr;
|
mbed714 |
0:d616ece2d859
|
314
|
DBG("m_pEd->Control = %08x\n", m_pEd->Control);
|
mbed714 |
0:d616ece2d859
|
315
|
}
|
mbed714 |
0:d616ece2d859
|
316
|
|
mbed714 |
0:d616ece2d859
|
317
|
void UsbEndpoint::updateSize(uint16_t size)
|
mbed714 |
0:d616ece2d859
|
318
|
{
|
mbed714 |
0:d616ece2d859
|
319
|
DBG("m_pEd->Control = %08x\n", m_pEd->Control);
|
mbed714 |
0:d616ece2d859
|
320
|
m_pEd->Control &= ~0x3FF0000;
|
mbed714 |
0:d616ece2d859
|
321
|
m_pEd->Control |= (size << 16);
|
mbed714 |
0:d616ece2d859
|
322
|
DBG("m_pEd->Control = %08x\n", m_pEd->Control);
|
mbed714 |
0:d616ece2d859
|
323
|
}
|
mbed714 |
0:d616ece2d859
|
324
|
|
mbed714 |
0:d616ece2d859
|
325
|
#if 0 //For doc only
|
mbed714 |
0:d616ece2d859
|
326
|
template <class T>
|
mbed714 |
0:d616ece2d859
|
327
|
void UsbEndpoint::setOnCompletion( T* pCbItem, void (T::*pCbMeth)() )
|
mbed714 |
0:d616ece2d859
|
328
|
{
|
mbed714 |
0:d616ece2d859
|
329
|
m_pCbItem = (CDummy*) pCbItem;
|
mbed714 |
0:d616ece2d859
|
330
|
m_pCbMeth = (void (CDummy::*)()) pCbMeth;
|
mbed714 |
0:d616ece2d859
|
331
|
}
|
mbed714 |
0:d616ece2d859
|
332
|
#endif
|
mbed714 |
0:d616ece2d859
|
333
|
|
mbed714 |
0:d616ece2d859
|
334
|
void UsbEndpoint::onCompletion()
|
mbed714 |
0:d616ece2d859
|
335
|
{
|
mbed714 |
0:d616ece2d859
|
336
|
//DBG("Transfer completed\n");
|
mbed714 |
0:d616ece2d859
|
337
|
if( m_pTdHead->Control >> 28 )
|
mbed714 |
0:d616ece2d859
|
338
|
{
|
mbed714 |
0:d616ece2d859
|
339
|
DBG("TD Failed with condition code %01x\n", m_pTdHead->Control >> 28 );
|
mbed714 |
0:d616ece2d859
|
340
|
m_status = (int)USBERR_TDFAIL;
|
mbed714 |
0:d616ece2d859
|
341
|
}
|
mbed714 |
0:d616ece2d859
|
342
|
else if( m_pEd->HeadTd & 0x1 )
|
mbed714 |
0:d616ece2d859
|
343
|
{
|
mbed714 |
0:d616ece2d859
|
344
|
m_pEd->HeadTd = m_pEd->HeadTd & ~0x1;
|
mbed714 |
0:d616ece2d859
|
345
|
DBG("\r\nHALTED!!\r\n");
|
mbed714 |
0:d616ece2d859
|
346
|
m_status = (int)USBERR_HALTED;
|
mbed714 |
0:d616ece2d859
|
347
|
}
|
mbed714 |
0:d616ece2d859
|
348
|
else if( (m_pEd->HeadTd & ~0xF) == (uint32_t) m_pTdTail )
|
mbed714 |
0:d616ece2d859
|
349
|
{
|
mbed714 |
0:d616ece2d859
|
350
|
//Done
|
mbed714 |
0:d616ece2d859
|
351
|
int len;
|
mbed714 |
0:d616ece2d859
|
352
|
//DBG("m_pTdHead->CurrBufPtr = %08x, m_pBufStartPtr=%08x\n", m_pTdHead->CurrBufPtr, (uint32_t) m_pBufStartPtr);
|
mbed714 |
0:d616ece2d859
|
353
|
if(m_pTdHead->CurrBufPtr)
|
mbed714 |
0:d616ece2d859
|
354
|
len = m_pTdHead->CurrBufPtr - (uint32_t) m_pBufStartPtr;
|
mbed714 |
0:d616ece2d859
|
355
|
else
|
mbed714 |
0:d616ece2d859
|
356
|
len = m_len;
|
mbed714 |
0:d616ece2d859
|
357
|
/*if(len == 0) //Packet transfered completely
|
mbed714 |
0:d616ece2d859
|
358
|
len = m_len;*/
|
mbed714 |
0:d616ece2d859
|
359
|
//m_done = true;
|
mbed714 |
0:d616ece2d859
|
360
|
DBG("Transfered %d bytes\n", len);
|
mbed714 |
0:d616ece2d859
|
361
|
m_status = len;
|
mbed714 |
0:d616ece2d859
|
362
|
}
|
mbed714 |
0:d616ece2d859
|
363
|
else
|
mbed714 |
0:d616ece2d859
|
364
|
{
|
mbed714 |
0:d616ece2d859
|
365
|
DBG("Unknown error...\n");
|
mbed714 |
0:d616ece2d859
|
366
|
m_status = (int)USBERR_ERROR;
|
mbed714 |
0:d616ece2d859
|
367
|
}
|
mbed714 |
0:d616ece2d859
|
368
|
m_result = true;
|
mbed714 |
0:d616ece2d859
|
369
|
if(m_pCbItem && m_pCbMeth)
|
mbed714 |
0:d616ece2d859
|
370
|
(m_pCbItem->*m_pCbMeth)();
|
mbed714 |
0:d616ece2d859
|
371
|
}
|
mbed714 |
0:d616ece2d859
|
372
|
|
mbed714 |
0:d616ece2d859
|
373
|
void UsbEndpoint::sOnCompletion(uint32_t pTd)
|
mbed714 |
0:d616ece2d859
|
374
|
{
|
mbed714 |
0:d616ece2d859
|
375
|
if(!m_pHeadEp)
|
mbed714 |
0:d616ece2d859
|
376
|
return;
|
mbed714 |
0:d616ece2d859
|
377
|
do
|
mbed714 |
0:d616ece2d859
|
378
|
{
|
mbed714 |
0:d616ece2d859
|
379
|
//DBG("sOnCompletion (pTd = %08x)\n", pTd);
|
mbed714 |
0:d616ece2d859
|
380
|
UsbEndpoint* pEp = m_pHeadEp;
|
mbed714 |
0:d616ece2d859
|
381
|
do
|
mbed714 |
0:d616ece2d859
|
382
|
{
|
mbed714 |
0:d616ece2d859
|
383
|
if((uint32_t)pEp->m_pTdHead == pTd)
|
mbed714 |
0:d616ece2d859
|
384
|
{
|
mbed714 |
0:d616ece2d859
|
385
|
pEp->onCompletion();
|
mbed714 |
0:d616ece2d859
|
386
|
break;
|
mbed714 |
0:d616ece2d859
|
387
|
}
|
mbed714 |
0:d616ece2d859
|
388
|
} while(pEp = pEp->m_pNextEp);
|
mbed714 |
0:d616ece2d859
|
389
|
} while( pTd = (uint32_t)( ((HCTD*)pTd)->Next ) ); //Go around the Done queue
|
mbed714 |
0:d616ece2d859
|
390
|
}
|
mbed714 |
0:d616ece2d859
|
391
|
|
mbed714 |
0:d616ece2d859
|
392
|
UsbEndpoint* UsbEndpoint::m_pHeadEp = NULL;
|
mbed714 |
0:d616ece2d859
|
393
|
|
mbed714 |
0:d616ece2d859
|
394
|
#endif
|