1 |
27 |
unneback |
//==========================================================================
|
2 |
|
|
//
|
3 |
|
|
// usbs_upd985xx.c
|
4 |
|
|
//
|
5 |
|
|
// Driver for the NEC uPD985xx USB device
|
6 |
|
|
//
|
7 |
|
|
//==========================================================================
|
8 |
|
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
9 |
|
|
// -------------------------------------------
|
10 |
|
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
11 |
|
|
// Copyright (C) 2002 Bart Veer
|
12 |
|
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
13 |
|
|
//
|
14 |
|
|
// eCos is free software; you can redistribute it and/or modify it under
|
15 |
|
|
// the terms of the GNU General Public License as published by the Free
|
16 |
|
|
// Software Foundation; either version 2 or (at your option) any later version.
|
17 |
|
|
//
|
18 |
|
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
19 |
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
20 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
21 |
|
|
// for more details.
|
22 |
|
|
//
|
23 |
|
|
// You should have received a copy of the GNU General Public License along
|
24 |
|
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
25 |
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
26 |
|
|
//
|
27 |
|
|
// As a special exception, if other files instantiate templates or use macros
|
28 |
|
|
// or inline functions from this file, or you compile this file and link it
|
29 |
|
|
// with other works to produce a work based on this file, this file does not
|
30 |
|
|
// by itself cause the resulting work to be covered by the GNU General Public
|
31 |
|
|
// License. However the source code for this file must still be made available
|
32 |
|
|
// in accordance with section (3) of the GNU General Public License.
|
33 |
|
|
//
|
34 |
|
|
// This exception does not invalidate any other reasons why a work based on
|
35 |
|
|
// this file might be covered by the GNU General Public License.
|
36 |
|
|
//
|
37 |
|
|
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
38 |
|
|
// at http://sources.redhat.com/ecos/ecos-license/
|
39 |
|
|
// -------------------------------------------
|
40 |
|
|
//####ECOSGPLCOPYRIGHTEND####
|
41 |
|
|
//==========================================================================
|
42 |
|
|
//#####DESCRIPTIONBEGIN####
|
43 |
|
|
//
|
44 |
|
|
// Author(s): bartv
|
45 |
|
|
// Contributors: bartv
|
46 |
|
|
// Date: 2001-05-22
|
47 |
|
|
//
|
48 |
|
|
// This code implements support for the on-chip USB port on the NEC
|
49 |
|
|
// uPD985xx family of processors. The code has been developed on the
|
50 |
|
|
// uPD98503 and may or may not work on other members of the uPD985xx
|
51 |
|
|
// family.
|
52 |
|
|
//
|
53 |
|
|
//####DESCRIPTIONEND####
|
54 |
|
|
//==========================================================================
|
55 |
|
|
|
56 |
|
|
#include <cyg/infra/cyg_type.h>
|
57 |
|
|
#include <cyg/infra/cyg_ass.h>
|
58 |
|
|
#include <cyg/infra/cyg_trac.h>
|
59 |
|
|
#include <cyg/infra/diag.h>
|
60 |
|
|
|
61 |
|
|
#include <pkgconf/hal_mips_upd985xx.h>
|
62 |
|
|
#include <pkgconf/devs_usb_upd985xx.h>
|
63 |
|
|
|
64 |
|
|
#include <cyg/hal/drv_api.h>
|
65 |
|
|
#include <cyg/hal/hal_arch.h>
|
66 |
|
|
#include <cyg/hal/hal_io.h>
|
67 |
|
|
#include <cyg/hal/hal_cache.h>
|
68 |
|
|
#include <cyg/error/codes.h>
|
69 |
|
|
|
70 |
|
|
#include <cyg/io/usb/usb.h>
|
71 |
|
|
#include <cyg/io/usb/usbs.h>
|
72 |
|
|
|
73 |
|
|
// For memcpy()
|
74 |
|
|
#include <string.h>
|
75 |
|
|
|
76 |
|
|
// ----------------------------------------------------------------------------
|
77 |
|
|
// Toplevel FIXME's.
|
78 |
|
|
//
|
79 |
|
|
// The device supports remote wakeups, but this driver does not. Note that
|
80 |
|
|
// the device GET_STATUS, SET_FEATURE and CLEAR_FEATURE operations are
|
81 |
|
|
// affected by remote wakeup support.
|
82 |
|
|
|
83 |
|
|
// ----------------------------------------------------------------------------
|
84 |
|
|
// Debugging-related odds and ends.
|
85 |
|
|
#if 0
|
86 |
|
|
# define DBG(a) diag_printf a
|
87 |
|
|
#else
|
88 |
|
|
# define DBG(a)
|
89 |
|
|
#endif
|
90 |
|
|
|
91 |
|
|
// ----------------------------------------------------------------------------
|
92 |
|
|
// Hardware definitions.
|
93 |
|
|
//
|
94 |
|
|
// The NEC uPD985Xx on-chip USB device provides the following:
|
95 |
|
|
//
|
96 |
|
|
// endpoint 0 - control messages only
|
97 |
|
|
// endpoint 1 - isochronous transmits
|
98 |
|
|
// endpoint 2 - isochronous receives
|
99 |
|
|
// endpoint 3 - bulk transmits
|
100 |
|
|
// endpoint 4 - bulk receives
|
101 |
|
|
// endpoint 5 - interrupt transmits
|
102 |
|
|
// endpoint 6 - interrupt receives
|
103 |
|
|
|
104 |
|
|
// All acess to the USB controller registers goes via the IBUS, which
|
105 |
|
|
// always runs little-endian. Hence when the CPU is running
|
106 |
|
|
// little-endian no extra work is needed, but when running big-endian
|
107 |
|
|
// all register updates involve swapping.
|
108 |
|
|
#ifdef CYGPKG_HAL_MIPS_LSBFIRST
|
109 |
|
|
# define IBUS_SWAP32(_a_) (_a_)
|
110 |
|
|
# define IBUS_SWAPPTR(_type_, _a_) (_a_)
|
111 |
|
|
#else
|
112 |
|
|
# error IBUS_SWAP32() needs to be defined and tested
|
113 |
|
|
#endif
|
114 |
|
|
|
115 |
|
|
// Move an address to kseg1. Or'ing in the relevant bits means
|
116 |
|
|
// that this macro will work even if the specified address is
|
117 |
|
|
// already in kseg1
|
118 |
|
|
#define MIPS_TO_UNCACHED(_a_) ((void*)(((cyg_uint32)(_a_)) | MIPS_KSEG1_BASE))
|
119 |
|
|
|
120 |
|
|
// For now access the various registers directly. A structure might
|
121 |
|
|
// be marginally more inefficient in that if a function accesses
|
122 |
|
|
// several registers this could be handled by a single base plus
|
123 |
|
|
// offsets, rather than by separate addresses.
|
124 |
|
|
#define USBS_REGISTER(_a_) ((volatile cyg_uint32*)(MIPS_IO_BASE + UPD985XX_SYSUSB_OFF + (_a_)))
|
125 |
|
|
#define USBS_ADDRREG(_type_, _a_) ((_type_* volatile*)(MIPS_IO_BASE + UPD985XX_SYSUSB_OFF + (_a_)))
|
126 |
|
|
|
127 |
|
|
#define USBS_GMR USBS_REGISTER(0x0000)
|
128 |
|
|
#define USBS_VER USBS_REGISTER(0x0004)
|
129 |
|
|
#define USBS_GSR1 USBS_REGISTER(0x0010)
|
130 |
|
|
#define USBS_IMR1 USBS_REGISTER(0x0014)
|
131 |
|
|
#define USBS_GSR2 USBS_REGISTER(0x0018)
|
132 |
|
|
#define USBS_IMR2 USBS_REGISTER(0x001C)
|
133 |
|
|
#define EP0_CR USBS_REGISTER(0x0020)
|
134 |
|
|
#define EP1_CR USBS_REGISTER(0x0024)
|
135 |
|
|
#define EP2_CR USBS_REGISTER(0x0028)
|
136 |
|
|
#define EP3_CR USBS_REGISTER(0x002C)
|
137 |
|
|
#define EP4_CR USBS_REGISTER(0x0030)
|
138 |
|
|
#define EP5_CR USBS_REGISTER(0x0034)
|
139 |
|
|
#define EP6_CR USBS_REGISTER(0x0038)
|
140 |
|
|
#define USBS_CMR USBS_REGISTER(0x0040)
|
141 |
|
|
#define USBS_CA USBS_ADDRREG(void, 0x0044)
|
142 |
|
|
#define USBS_TEPSR USBS_REGISTER(0x0048)
|
143 |
|
|
#define USBS_RP0IR USBS_REGISTER(0x0050)
|
144 |
|
|
#define USBS_RP0AR USBS_ADDRREG(RxBufferDescriptor, 0x0054)
|
145 |
|
|
#define USBS_RP1IR USBS_REGISTER(0x0058)
|
146 |
|
|
#define USBS_RP1AR USBS_ADDRREG(RxBufferDescriptor, 0x005C)
|
147 |
|
|
#define USBS_RP2IR USBS_REGISTER(0x0060)
|
148 |
|
|
#define USBS_RP2AR USBS_ADDRREG(RxBufferDescriptor, 0x0064)
|
149 |
|
|
#define USBS_TMSA USBS_ADDRREG(TxMailbox, 0x0070)
|
150 |
|
|
#define USBS_TMBA USBS_ADDRREG(TxMailbox, 0x0074)
|
151 |
|
|
#define USBS_TMRA USBS_ADDRREG(TxMailbox, 0x0078)
|
152 |
|
|
#define USBS_TMWA USBS_ADDRREG(TxMailbox, 0x007C)
|
153 |
|
|
#define USBS_RMSA USBS_ADDRREG(RxMailbox, 0x0080)
|
154 |
|
|
#define USBS_RMBA USBS_ADDRREG(RxMailbox, 0x0084)
|
155 |
|
|
#define USBS_RMRA USBS_ADDRREG(RxMailbox, 0x0088)
|
156 |
|
|
#define USBS_RMWA USBS_ADDRREG(RxMailbox, 0x008C)
|
157 |
|
|
|
158 |
|
|
// There are additional counter registers from offset 0x100 onwards.
|
159 |
|
|
// These registers are not used by the driver, and anyway may not be
|
160 |
|
|
// available on all hardware.
|
161 |
|
|
|
162 |
|
|
// The General Mode register USBS_GMR
|
163 |
|
|
#define USBS_GMR_VT (0x01 << 23)
|
164 |
|
|
#define USBS_GMR_FA_MASK (0x7F << 16)
|
165 |
|
|
#define USBS_GMR_FA_SHIFT 16
|
166 |
|
|
#define USBS_GMR_SOFINTVL_MASK (0x00FF << 8)
|
167 |
|
|
#define USBS_GMR_SOFINTVL_SHIFT 8
|
168 |
|
|
#define USBS_GMR_SOFINTVL_DEFAULT_VALUE (0x18 << 8)
|
169 |
|
|
#define USBS_GMR_AU (0x01 << 2)
|
170 |
|
|
#define USBS_GMR_LE (0x01 << 1)
|
171 |
|
|
#define USBS_GMR_RR (0x01 << 0)
|
172 |
|
|
|
173 |
|
|
// The Frame Number/Version register
|
174 |
|
|
#define USBS_VER_UVER_MASK (0x0FFFF << 16)
|
175 |
|
|
#define USBS_VER_UVER_SHIFT 16
|
176 |
|
|
#define USBS_VER_UFNR_MASK (0x03FF << 0)
|
177 |
|
|
#define USBS_VER_UFNR_SHIFT 0
|
178 |
|
|
|
179 |
|
|
// General status register 1
|
180 |
|
|
#define USBS_GSR1_GSR2 (0x01 << 31)
|
181 |
|
|
#define USBS_GSR1_TMF (0x01 << 23)
|
182 |
|
|
#define USBS_GSR1_RMF (0x01 << 22)
|
183 |
|
|
#define USBS_GSR1_RPE2 (0x01 << 21)
|
184 |
|
|
#define USBS_GSR1_RPE1 (0x01 << 20)
|
185 |
|
|
#define USBS_GSR1_RPE0 (0x01 << 19)
|
186 |
|
|
#define USBS_GSR1_RPA2 (0x01 << 18)
|
187 |
|
|
#define USBS_GSR1_RPA1 (0x01 << 17)
|
188 |
|
|
#define USBS_GSR1_RPA0 (0x01 << 16)
|
189 |
|
|
#define USBS_GSR1_DER (0x01 << 10)
|
190 |
|
|
#define USBS_GSR1_EP2FO (0x01 << 9)
|
191 |
|
|
#define USBS_GSR1_EP1FU (0x01 << 8)
|
192 |
|
|
#define USBS_GSR1_EP6RF (0x01 << 7)
|
193 |
|
|
#define USBS_GSR1_EP5TF (0x01 << 6)
|
194 |
|
|
#define USBS_GSR1_EP4RF (0x01 << 5)
|
195 |
|
|
#define USBS_GSR1_EP3TF (0x01 << 4)
|
196 |
|
|
#define USBS_GSR1_EP2RF (0x01 << 3)
|
197 |
|
|
#define USBS_GSR1_EP1TF (0x01 << 2)
|
198 |
|
|
#define USBS_GSR1_EP0RF (0x01 << 1)
|
199 |
|
|
#define USBS_GSR1_EP0TF (0x01 << 0)
|
200 |
|
|
|
201 |
|
|
// The Interrupt mask 1 bits correspond to the GSR1 bits above
|
202 |
|
|
|
203 |
|
|
// General status register 2
|
204 |
|
|
#define USBS_GSR2_FW (0x01 << 21)
|
205 |
|
|
#define USBS_GSR2_IFN (0x01 << 20)
|
206 |
|
|
#define USBS_GSR2_IEA (0x01 << 19)
|
207 |
|
|
#define USBS_GSR2_URSM (0x01 << 18)
|
208 |
|
|
#define USBS_GSR2_URST (0x01 << 17)
|
209 |
|
|
#define USBS_GSR2_USPD (0x01 << 16)
|
210 |
|
|
#define USBS_GSR2_EP2OS (0x01 << 7)
|
211 |
|
|
#define USBS_GSR2_EP2ED (0x01 << 6)
|
212 |
|
|
#define USBS_GSR2_EP2ND (0x01 << 5)
|
213 |
|
|
#define USBS_GSR2_EP1NT (0x01 << 4)
|
214 |
|
|
#define USBS_GSR2_EP1ET (0x01 << 3)
|
215 |
|
|
#define USBS_GSR2_EP1ND (0x01 << 2)
|
216 |
|
|
#define USBS_GSR2_ES (0x01 << 1)
|
217 |
|
|
#define USBS_GSR2_SL (0x01 << 0)
|
218 |
|
|
|
219 |
|
|
// Interrupt mask 2 bits correspond to GSR2
|
220 |
|
|
|
221 |
|
|
// Endpoint control registers.
|
222 |
|
|
// EP0 - control messages
|
223 |
|
|
#define EP0_CR_EP0EN (0x01 << 31)
|
224 |
|
|
#define EP0_CR_ISS (0x01 << 20)
|
225 |
|
|
#define EP0_CR_INAK (0x01 << 19)
|
226 |
|
|
#define EP0_CR_OSS (0x01 << 18)
|
227 |
|
|
#define EP0_CR_NHSK0 (0x01 << 17)
|
228 |
|
|
#define EP0_CR_ONAK (0x01 << 16)
|
229 |
|
|
#define EP0_CR_MAXP0_MASK (0x7F << 0)
|
230 |
|
|
#define EP0_CR_MAXP0_SHIFT 0
|
231 |
|
|
|
232 |
|
|
// EP1 - isochronous transmits
|
233 |
|
|
#define EP1_CR_EP1EN (0x01 << 31)
|
234 |
|
|
#define EP1_CR_TM1 (0x01 << 19)
|
235 |
|
|
#define EP1_CR_TM1_MASK (0x01 << 19)
|
236 |
|
|
#define EP1_CR_TM1_SZLP (0x00 << 19)
|
237 |
|
|
#define EP1_CR_TM1_NZLP (0x01 << 19)
|
238 |
|
|
#define EP1_CR_MAXP1_MASK (0x3FF << 0)
|
239 |
|
|
#define EP1_CR_MAXP1_SHIFT 0
|
240 |
|
|
|
241 |
|
|
// EP2 - isochronous receives
|
242 |
|
|
#define EP2_CR_EP2EN (0x01 << 31)
|
243 |
|
|
#define EP2_CR_RM2_MASK (0x03 << 19)
|
244 |
|
|
#define EP2_CR_RM2_NORMAL (0x00 << 19)
|
245 |
|
|
#define EP2_CR_RM2_ASSEMBLE (0x02 << 19)
|
246 |
|
|
#define EP2_CR_RM2_SEPARATE (0x03 << 19)
|
247 |
|
|
#define EP2_CR_MAXP2_MASK (0x3FF << 0)
|
248 |
|
|
#define EP2_CR_MAXP2_SHIFT 0
|
249 |
|
|
|
250 |
|
|
// EP3 - bulk transmits
|
251 |
|
|
#define EP3_CR_EP3EN (0x01 << 31)
|
252 |
|
|
#define EP3_CR_TM3 (0x01 << 19)
|
253 |
|
|
#define EP3_CR_TM3_MASK (0x01 << 19)
|
254 |
|
|
#define EP3_CR_TM3_SZLP (0x00 << 19)
|
255 |
|
|
#define EP3_CR_TM3_NZLP (0x01 << 19)
|
256 |
|
|
#define EP3_CR_SS3 (0x01 << 18)
|
257 |
|
|
#define EP3_CR_NAK3 (0x01 << 16)
|
258 |
|
|
#define EP3_CR_MAXP3_MASK (0x7F << 0)
|
259 |
|
|
#define EP3_CR_MAXP3_SHIFT 0
|
260 |
|
|
|
261 |
|
|
// EP4 - bulk receives
|
262 |
|
|
#define EP4_CR_EP4EN (0x01 << 31)
|
263 |
|
|
#define EP4_CR_RM4_MASK (0x03 << 19)
|
264 |
|
|
#define EP4_CR_RM4_NORMAL (0x00 << 19)
|
265 |
|
|
#define EP4_CR_RM4_ASSEMBLE (0x02 << 19)
|
266 |
|
|
#define EP4_CR_RM4_SEPARATE (0x03 << 19)
|
267 |
|
|
#define EP4_CR_SS4 (0x01 << 18)
|
268 |
|
|
#define EP4_CR_NHSK4 (0x01 << 17)
|
269 |
|
|
#define EP4_CR_NAK4 (0x01 << 16)
|
270 |
|
|
#define EP4_CR_MAXP4_MASK (0x7F << 0)
|
271 |
|
|
#define EP4_CR_MAXP4_SHIFT 0
|
272 |
|
|
|
273 |
|
|
// EP5 - interrupt transmits
|
274 |
|
|
#define EP5_CR_EP5EN (0x01 << 31)
|
275 |
|
|
#define EP5_CR_FM (0x01 << 19)
|
276 |
|
|
#define EP5_CR_SS5 (0x01 << 18)
|
277 |
|
|
#define EP5_CR_NAK5 (0x01 << 16)
|
278 |
|
|
#define EP5_CR_MAXP5_MASK (0x7F << 0)
|
279 |
|
|
#define EP5_CR_MAXP5_SHIFT 0
|
280 |
|
|
|
281 |
|
|
// EP6 - interrupt receives
|
282 |
|
|
#define EP6_CR_EP6EN (0x01 << 31)
|
283 |
|
|
#define EP6_CR_SS6 (0x01 << 18)
|
284 |
|
|
#define EP6_CR_NHSK6 (0x01 << 17)
|
285 |
|
|
#define EP6_CR_NAK6 (0x01 << 16)
|
286 |
|
|
#define EP6_CR_MAXP6_MASK (0x7F << 0)
|
287 |
|
|
#define EP6_CR_MAXP6_SHIFT 0
|
288 |
|
|
|
289 |
|
|
// Some bits which can be applied to multiple transmit or receive
|
290 |
|
|
// endpoint control registers, thus avoiding unnecessary code
|
291 |
|
|
// duplication. These will not work for the isochronous endpoints
|
292 |
|
|
// because those are just too special.
|
293 |
|
|
#define EPtx_CR_EpxEN (0x01 << 31)
|
294 |
|
|
#define EPtx_CR_SSx (0x01 << 18)
|
295 |
|
|
#define EPtx_CR_NAKx (0x01 << 16)
|
296 |
|
|
#define EPtx_CR_MAXPx_MASK (0x7F << 0)
|
297 |
|
|
#define EPtx_CR_MAXPx_SHIFT 0
|
298 |
|
|
|
299 |
|
|
#define EPrx_CR_EPxEN (0x01 << 31)
|
300 |
|
|
#define EPrx_CR_SSx (0x01 << 18)
|
301 |
|
|
#define EPrx_CR_NHSKx (0x01 << 17)
|
302 |
|
|
#define EPrx_CR_NAKx (0x01 << 16)
|
303 |
|
|
#define EPrx_CR_MAXPx_MASK (0x7F << 0)
|
304 |
|
|
#define EPrx_CR_MAXPx_SHIFT 0
|
305 |
|
|
|
306 |
|
|
// USB command register
|
307 |
|
|
#define USBS_CMR_BUSY (0x01 << 31)
|
308 |
|
|
#define USBS_CMR_COMMAND_MASK (0x07 << 24)
|
309 |
|
|
#define USBS_CMR_COMMAND_SHIFT 24
|
310 |
|
|
#define USBS_CMR_COMMAND_TX_EP0 (0x00 << 24)
|
311 |
|
|
#define USBS_CMR_COMMAND_TX_EP1 (0x01 << 24)
|
312 |
|
|
#define USBS_CMR_COMMAND_TX_EP3 (0x02 << 24)
|
313 |
|
|
#define USBS_CMR_COMMAND_TX_EP5 (0x03 << 24)
|
314 |
|
|
#define USBS_CMR_COMMAND_ADD_POOL0 (0x04 << 24)
|
315 |
|
|
#define USBS_CMR_COMMAND_ADD_POOL1 (0x05 << 24)
|
316 |
|
|
#define USBS_CMR_COMMAND_ADD_POOL2 (0x06 << 24)
|
317 |
|
|
#define USBS_CMR_SIZE_MASK (0x0FFFF << 0)
|
318 |
|
|
#define USBS_CMR_SIZE_SHIFT 0
|
319 |
|
|
|
320 |
|
|
// TX Endpoint status
|
321 |
|
|
#define USBS_TEPSR_EP5TS_MASK (0x03 << 24)
|
322 |
|
|
#define USBS_TEPSR_EP5TS_SHIFT 24
|
323 |
|
|
#define USBS_TEPSR_EP5TS_IDLE (0x00 << 24)
|
324 |
|
|
#define USBS_TEPSR_EP5TS_ONE (0x01 << 24)
|
325 |
|
|
#define USBS_TEPSR_EP5TS_TWO (0x02 << 24)
|
326 |
|
|
#define USBS_TEPSR_EP3TS_MASK (0x03 << 16)
|
327 |
|
|
#define USBS_TEPSR_EP3TS_SHIFT 16
|
328 |
|
|
#define USBS_TEPSR_EP3TS_IDLE (0x00 << 16)
|
329 |
|
|
#define USBS_TEPSR_EP3TS_ONE (0x01 << 16)
|
330 |
|
|
#define USBS_TEPSR_EP3TS_TWO (0x02 << 16)
|
331 |
|
|
#define USBS_TEPSR_EP1TS_MASK (0x03 << 8)
|
332 |
|
|
#define USBS_TEPSR_EP1TS_SHIFT 8
|
333 |
|
|
#define USBS_TEPSR_EP1TS_IDLE (0x00 << 8)
|
334 |
|
|
#define USBS_TEPSR_EP1TS_ONE (0x01 << 8)
|
335 |
|
|
#define USBS_TEPSR_EP1TS_TWO (0x02 << 8)
|
336 |
|
|
#define USBS_TEPSR_EP0TS_MASK (0x03 << 0)
|
337 |
|
|
#define USBS_TEPSR_EP0TS_SHIFT 0
|
338 |
|
|
#define USBS_TEPSR_EP0TS_IDLE (0x00 << 0)
|
339 |
|
|
#define USBS_TEPSR_EP0TS_ONE (0x01 << 0)
|
340 |
|
|
#define USBS_TEPSR_EP0TS_TWO (0x02 << 0)
|
341 |
|
|
|
342 |
|
|
// Receive pools. The RP0IR, RP1IR and RP2IR registers
|
343 |
|
|
// all use the same bits.
|
344 |
|
|
#define USBS_RPxIR_AL_MASK (0x07 << 28)
|
345 |
|
|
#define USBS_RPxIR_AL_SHIFT 28
|
346 |
|
|
#define USBS_RPxIR_AL_NONE (0 << 28)
|
347 |
|
|
#define USBS_RPxIR_RNOD_MASK (0x0FFFF << 0)
|
348 |
|
|
#define USBS_RPxIR_RNOD_SHIFT 0
|
349 |
|
|
|
350 |
|
|
// The other registers do not have special bits.
|
351 |
|
|
|
352 |
|
|
// Data transfers involve buffer descriptors and mailboxes. The
|
353 |
|
|
// relevant data structures and fields need to be defined. For now
|
354 |
|
|
// assume 32-bit mode of operation, i.e. there will be no padding
|
355 |
|
|
// between two successive 32-bit entities
|
356 |
|
|
|
357 |
|
|
// A transmit packet directory consists of up to 255 buffer
|
358 |
|
|
// descriptors. Each buffer descriptor specifies a buffer and a size
|
359 |
|
|
// of up to 64K.
|
360 |
|
|
|
361 |
|
|
typedef struct TxBufferDescriptor {
|
362 |
|
|
cyg_uint32 control;
|
363 |
|
|
void* buffer;
|
364 |
|
|
} TxBufferDescriptor;
|
365 |
|
|
|
366 |
|
|
#define TXBUFDESC_CTRL_LAST (0x01 << 31)
|
367 |
|
|
#define TXBUFDESC_CTRL_BUFDESC_MASK (0x01 << 30)
|
368 |
|
|
#define TXBUFDESC_CTRL_BUFDESC_SHIFT 30
|
369 |
|
|
#define TXBUFDESC_CTRL_BUFDESC_LINK (0x00 << 30)
|
370 |
|
|
#define TXBUFDESC_CTRL_BUFDESC_BUFDESC (0x01 << 30)
|
371 |
|
|
#define TXBUFDESC_CTRL_SIZE_MASK (0x0FFFF << 0)
|
372 |
|
|
#define TXBUFDESC_CTRL_SIZE_SHIFT 0
|
373 |
|
|
|
374 |
|
|
// The result of a transmit operation gets written to a mailbox
|
375 |
|
|
// structure in memory.
|
376 |
|
|
typedef struct TxMailbox {
|
377 |
|
|
cyg_uint32 status;
|
378 |
|
|
} TxMailbox;
|
379 |
|
|
|
380 |
|
|
#define TXMBOX_STATUS_IBUS_ERROR (0x01 << 10)
|
381 |
|
|
#define TXMBOX_STATUS_UNDERRUN (0x01 << 9)
|
382 |
|
|
#define TXMBOX_STATUS_MODE_MASK (0x01 << 8)
|
383 |
|
|
#define TXMBOX_STATUS_MODE_SHIFT 8
|
384 |
|
|
#define TXMBOX_STATUS_MODE_SZLP (0x00 << 8)
|
385 |
|
|
#define TXMBOX_STATUS_MODE_NZLP (0x01 << 8)
|
386 |
|
|
#define TXMBOX_STATUS_EPN_MASK (0x07 << 0)
|
387 |
|
|
#define TXMBOX_STATUS_EPN_SHIFT 0
|
388 |
|
|
#define TXMBOX_STATUS_EPN_EP0 (0x00 << 0)
|
389 |
|
|
#define TXMBOX_STATUS_EPN_EP1 (0x02 << 0)
|
390 |
|
|
#define TXMBOX_STATUS_EPN_EP3 (0x04 << 0)
|
391 |
|
|
#define TXMBOX_STATUS_EPN_EP5 (0x06 << 0)
|
392 |
|
|
|
393 |
|
|
// Now for receive operations. This involves adding buffer descriptors
|
394 |
|
|
// to one of three pools. The pools are managed by registers.
|
395 |
|
|
typedef struct RxBufferDescriptor {
|
396 |
|
|
cyg_uint32 control;
|
397 |
|
|
void* buffer;
|
398 |
|
|
} RxBufferDescriptor;
|
399 |
|
|
|
400 |
|
|
#define RXBUFDESC_CTRL_LAST (0x01 << 31)
|
401 |
|
|
#define RXBUFDESC_CTRL_BUFDESC_MASK (0x01 << 30)
|
402 |
|
|
#define RXBUFDESC_CTRL_BUFDESC_SHIFT 30
|
403 |
|
|
#define RXBUFDESC_CTRL_BUFDESC_LINK (0x00 << 30)
|
404 |
|
|
#define RXBUFDESC_CTRL_BUFDESC_BUFDESC (0x01 << 30)
|
405 |
|
|
#define RXBUFDESC_CTRL_SIZE_MASK (0x0FFFF << 0)
|
406 |
|
|
#define RXBUFDESC_CTRL_SIZE_SHIFT 0
|
407 |
|
|
|
408 |
|
|
typedef struct RxMailbox {
|
409 |
|
|
cyg_uint32 status;
|
410 |
|
|
void* address;
|
411 |
|
|
} RxMailbox;
|
412 |
|
|
|
413 |
|
|
#define RXMBOX_STATUS_EPN_MASK (0x07 << 29)
|
414 |
|
|
#define RXMBOX_STATUS_EPN_SHIFT 29
|
415 |
|
|
#define RXMBOX_STATUS_EPN_EP0 (0x01 << 29)
|
416 |
|
|
#define RXMBOX_STATUS_EPN_EP2 (0x03 << 29)
|
417 |
|
|
#define RXMBOX_STATUS_EPN_EP4 (0x05 << 29)
|
418 |
|
|
#define RXMBOX_STATUS_EPN_EP6 (0x07 << 29)
|
419 |
|
|
#define RXMBOX_STATUS_CORRUPTION (0x01 << 25)
|
420 |
|
|
#define RXMBOX_STATUS_IBUS_ERROR (0x01 << 24)
|
421 |
|
|
#define RXMBOX_STATUS_SETUP_MASK (0x01 << 23)
|
422 |
|
|
#define RXMBOX_STATUS_SETUP_SHIFT 23
|
423 |
|
|
#define RXMBOX_STATUS_SETUP_NORMAL (0x00 << 23)
|
424 |
|
|
#define RXMBOX_STATUS_SETUP_SETUP (0x01 << 23)
|
425 |
|
|
#define RXMBOX_STATUS_OVERRUN (0x01 << 22)
|
426 |
|
|
#define RXMBOX_STATUS_DATA_TOGGLE (0x01 << 21)
|
427 |
|
|
#define RXMBOX_STATUS_CRC (0x01 << 20)
|
428 |
|
|
#define RXMBOX_STATUS_BIT_STUFFING (0x01 << 19)
|
429 |
|
|
#define RXMBOX_STATUS_64K (0x01 << 18)
|
430 |
|
|
#define RXMBOX_STATUS_MODE_MASK (0x03 << 16)
|
431 |
|
|
#define RXMBOX_STATUS_MODE_SHIFT 16
|
432 |
|
|
#define RXMBOX_STATUS_MODE_NORMAL (0x00 << 16)
|
433 |
|
|
#define RXMBOX_STATUS_MODE_NORMAL2 (0x01 << 16)
|
434 |
|
|
#define RXMBOX_STATUS_MODE_ASSEMBLE (0x02 << 16)
|
435 |
|
|
#define RXMBOX_STATUS_MODE_SEPARATE (0x03 << 16)
|
436 |
|
|
#define RXMBOX_STATUS_SIZE_MASK (0x0FFFF << 0)
|
437 |
|
|
#define RXMBOX_STATUS_SIZE_SHIFT 0
|
438 |
|
|
|
439 |
|
|
|
440 |
|
|
// ----------------------------------------------------------------------------
|
441 |
|
|
// Hardware work around - see NEC erratum S1, CPU to IBUS write restriction.
|
442 |
|
|
// Reading back from the USB device after every write prevents any problems.
|
443 |
|
|
// Strictly speaking it is only necessary to do this after every three
|
444 |
|
|
// writes, but if there is concurrent ethernet activity then doing it
|
445 |
|
|
// after eveyr write is safer. The frame number/version register seems
|
446 |
|
|
// like a good one to read back from.
|
447 |
|
|
|
448 |
|
|
#ifdef CYGIMP_DEVS_USB_UPD985XX_IBUS_WRITE_LIMIT
|
449 |
|
|
# define FLUSH_IBUS() \
|
450 |
|
|
CYG_MACRO_START \
|
451 |
|
|
(void)*USBS_VER; \
|
452 |
|
|
CYG_MACRO_END
|
453 |
|
|
|
454 |
|
|
#else
|
455 |
|
|
# define FLUSH_IBUS() CYG_EMPTY_STATEMENT
|
456 |
|
|
#endif
|
457 |
|
|
|
458 |
|
|
// ----------------------------------------------------------------------------
|
459 |
|
|
// Static data. There is a data structure for each endpoint. The
|
460 |
|
|
// implementation is essentially a private class that inherits from
|
461 |
|
|
// common classes for control and data endpoints, but device drivers
|
462 |
|
|
// are supposed to be written in C so some ugliness is required.
|
463 |
|
|
//
|
464 |
|
|
// Devtab entries are defined in usbs_upd985xx_data.cxx to make sure
|
465 |
|
|
// that the linker does not garbage-collect them.
|
466 |
|
|
|
467 |
|
|
// Support for the interrupt handling code.
|
468 |
|
|
static cyg_interrupt usbs_upd985xx_intr_data;
|
469 |
|
|
static cyg_handle_t usbs_upd985xx_intr_handle;
|
470 |
|
|
|
471 |
|
|
// The various bits in the two interrupt status registers are read-once,
|
472 |
|
|
// i.e. reading the register clears the bits. Since much of the processing
|
473 |
|
|
// is deferred to DSR level, it is necessary to keep track of pending
|
474 |
|
|
// interrupts in separate variables. If another interrupt happens during
|
475 |
|
|
// DSR processing, these variables will be updated. The main DSR loops
|
476 |
|
|
// until there are no interesting bits left. Interrupts have to be
|
477 |
|
|
// disabled briefly when clearing bits.
|
478 |
|
|
static volatile cyg_uint32 usbs_upd985xx_gsr1 = 0;
|
479 |
|
|
static volatile cyg_uint32 usbs_upd985xx_gsr2 = 0;
|
480 |
|
|
|
481 |
|
|
// Many of the interrupt bits are of no interest and it is convenient
|
482 |
|
|
// to mask them out in the ISR, thus avoiding unnecessary dsr
|
483 |
|
|
// invocations.
|
484 |
|
|
static cyg_uint32 usbs_upd985xx_gsr1_mask = 0;
|
485 |
|
|
static cyg_uint32 usbs_upd985xx_gsr2_mask = 0;
|
486 |
|
|
|
487 |
|
|
// Sizes for the receive and transmit mboxes.
|
488 |
|
|
// NOTE: it is not clear what the optimal size for these
|
489 |
|
|
// mailboxes is. For receives maybe one per rx endpoint,
|
490 |
|
|
// plus a spare. For transmits maybe just two, since only
|
491 |
|
|
// one transmit at a time is supported. Mailboxes are
|
492 |
|
|
// relatively small, so for now four each should be ok.
|
493 |
|
|
#define RXMBOX_COUNT 4
|
494 |
|
|
#define TXMBOX_COUNT 4
|
495 |
|
|
|
496 |
|
|
// There is one instance of this data structure. It is allocated
|
497 |
|
|
// in kseg0 cached memory, but during initialization a separate
|
498 |
|
|
// pointer value is set to the kseg1 uncached equivalent. This
|
499 |
|
|
// makes it easier to point the hardware at uncached memory without
|
500 |
|
|
// having to worry about cache line boundaries everywhere.
|
501 |
|
|
|
502 |
|
|
typedef struct uncached_data {
|
503 |
|
|
// This partial cacheline does not actually store any data.
|
504 |
|
|
// However it ensures that the data does not share a cacheline
|
505 |
|
|
// with some other static, with updates to that other static
|
506 |
|
|
// causing funny side effects on the uncached data. There is a
|
507 |
|
|
// memory optimisation of subtracting sizeof(RxMailbox.status),
|
508 |
|
|
// i.e. exploit knowledge of alignment.
|
509 |
|
|
unsigned char cacheline_start[HAL_DCACHE_LINE_SIZE - sizeof(cyg_uint32)];
|
510 |
|
|
|
511 |
|
|
RxMailbox rx_mboxes[RXMBOX_COUNT];
|
512 |
|
|
TxMailbox tx_mboxes[TXMBOX_COUNT];
|
513 |
|
|
|
514 |
|
|
// For transmits a single buffer descriptor per endpoint suffices.
|
515 |
|
|
// If transmit locking is enabled then actually a single buffer
|
516 |
|
|
// descriptor for the whole system would suffice.
|
517 |
|
|
TxBufferDescriptor ep0_tx_bufdesc;
|
518 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
519 |
|
|
TxBufferDescriptor ep3_tx_bufdesc;
|
520 |
|
|
#endif
|
521 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
522 |
|
|
TxBufferDescriptor ep5_tx_bufdesc;
|
523 |
|
|
#endif
|
524 |
|
|
|
525 |
|
|
|
526 |
|
|
// More buffer descriptors are needed than might be expected, see
|
527 |
|
|
// the start_rx routines.
|
528 |
|
|
RxBufferDescriptor ep0_rx_bufdescs[4];
|
529 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
530 |
|
|
RxBufferDescriptor ep4_rx_bufdescs[8];
|
531 |
|
|
#endif
|
532 |
|
|
|
533 |
|
|
|
534 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
535 |
|
|
// Space for the start and end of a transfer, avoiding problems
|
536 |
|
|
// with invalidating partial cache lines.
|
537 |
|
|
unsigned char ep4_head[HAL_DCACHE_LINE_SIZE];
|
538 |
|
|
unsigned char ep4_tail[HAL_DCACHE_LINE_SIZE];
|
539 |
|
|
#endif
|
540 |
|
|
|
541 |
|
|
// The "big" buffers come last, reducing the offsets for the previous
|
542 |
|
|
// structures. It is not clear this really matters for MIPS.
|
543 |
|
|
//
|
544 |
|
|
// Endpoint 0 receive and transmit buffers. A transmit buffer is
|
545 |
|
|
// convenient because the hardware pretty much expects all of the
|
546 |
|
|
// data to be in contiguous memory, as opposed to the normal eCos
|
547 |
|
|
// USB driver model with refill buffers etc. An alternative
|
548 |
|
|
// implementation would keep the data in separate areas but would
|
549 |
|
|
// require lots of TxBufferDescriptors, so in memory terms the
|
550 |
|
|
// overheads of a single transmit buffer are not as big as might
|
551 |
|
|
// seem. It might be possible to get things working eight bytes
|
552 |
|
|
// at a time since the hardware appears to depend on zero-byte
|
553 |
|
|
// terminating packets in places, but that has not been attempted.
|
554 |
|
|
//
|
555 |
|
|
// A separate receive buffer is useful because it can be placed in
|
556 |
|
|
// uncached memory, avoiding the need for invalidation and
|
557 |
|
|
// worrying about other data in the cache lines. Note that this
|
558 |
|
|
// buffer may also get used for endpoint 6 interrupt receives
|
559 |
|
|
// because the two endpoints share a single pool.
|
560 |
|
|
unsigned char ep0_rx_buffer[CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE];
|
561 |
|
|
unsigned char ep0_tx_buffer[CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE];
|
562 |
|
|
|
563 |
|
|
// Another cacheline to prevent overlap with other statics.
|
564 |
|
|
// This has to be full-sized since the previous field is only byte-aligned.
|
565 |
|
|
unsigned char cacheline_end[HAL_DCACHE_LINE_SIZE];
|
566 |
|
|
} uncached_data;
|
567 |
|
|
|
568 |
|
|
// This data structure is quite large so making it all uninitialized
|
569 |
|
|
// means a potentially big saving in ROM-booting systems. This
|
570 |
|
|
// requires additional effort by the endpoint initialization routines.
|
571 |
|
|
static uncached_data cached_copy;
|
572 |
|
|
|
573 |
|
|
static uncached_data* uncached = (uncached_data*)0;
|
574 |
|
|
|
575 |
|
|
// Endpoint 0. See the description below.
|
576 |
|
|
|
577 |
|
|
static void usbs_upd985xx_ep0_start(usbs_control_endpoint*);
|
578 |
|
|
static void usbs_upd985xx_poll(usbs_control_endpoint*);
|
579 |
|
|
|
580 |
|
|
typedef struct ep0_impl {
|
581 |
|
|
usbs_control_endpoint common;
|
582 |
|
|
cyg_bool rx_expecting_data;
|
583 |
|
|
cyg_bool rx_indicator_valid;
|
584 |
|
|
RxMailbox rx_indicator;
|
585 |
|
|
cyg_bool tx_indicator_valid;
|
586 |
|
|
TxMailbox tx_indicator;
|
587 |
|
|
cyg_bool tx_needs_zero_transfer;
|
588 |
|
|
cyg_uint32 tx_size;
|
589 |
|
|
} ep0_impl;
|
590 |
|
|
|
591 |
|
|
static ep0_impl ep0 = {
|
592 |
|
|
common:
|
593 |
|
|
{
|
594 |
|
|
state: USBS_STATE_POWERED, // The hardware does not distinguish between detached, attached and powered.
|
595 |
|
|
enumeration_data: (usbs_enumeration_data*) 0,
|
596 |
|
|
start_fn: &usbs_upd985xx_ep0_start,
|
597 |
|
|
poll_fn: &usbs_upd985xx_poll,
|
598 |
|
|
interrupt_vector: CYGNUM_HAL_INTERRUPT_USB,
|
599 |
|
|
control_buffer: { 0, 0, 0, 0, 0, 0, 0, 0 },
|
600 |
|
|
state_change_fn: (void (*)(usbs_control_endpoint*, void*, usbs_state_change, int)) 0,
|
601 |
|
|
state_change_data: (void*) 0,
|
602 |
|
|
standard_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
|
603 |
|
|
standard_control_data: (void*) 0,
|
604 |
|
|
class_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
|
605 |
|
|
class_control_data: (void*) 0,
|
606 |
|
|
vendor_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
|
607 |
|
|
vendor_control_data: (void*) 0,
|
608 |
|
|
reserved_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
|
609 |
|
|
reserved_control_data: (void*) 0,
|
610 |
|
|
buffer: (unsigned char*) 0,
|
611 |
|
|
buffer_size: 0,
|
612 |
|
|
fill_buffer_fn: (void (*)(usbs_control_endpoint*)) 0,
|
613 |
|
|
fill_data: (void*) 0,
|
614 |
|
|
fill_index: 0,
|
615 |
|
|
complete_fn: (usbs_control_return (*)(usbs_control_endpoint*, int)) 0
|
616 |
|
|
},
|
617 |
|
|
rx_expecting_data: false,
|
618 |
|
|
rx_indicator_valid: false,
|
619 |
|
|
rx_indicator: { 0, (void*) 0 },
|
620 |
|
|
tx_indicator_valid: false,
|
621 |
|
|
tx_indicator: { 0 },
|
622 |
|
|
tx_needs_zero_transfer: 0
|
623 |
|
|
};
|
624 |
|
|
|
625 |
|
|
extern usbs_control_endpoint usbs_upd985xx_ep0 __attribute__((alias ("ep0")));
|
626 |
|
|
|
627 |
|
|
// Endpoint 1, isochronous transmits. This endpoint is not yet
|
628 |
|
|
// supported. Although the interface for bulk transmits should be
|
629 |
|
|
// mostly re-usable, there are some additional error conditions if
|
630 |
|
|
// either the host or the target fails to achieve the desired
|
631 |
|
|
// throughput.
|
632 |
|
|
|
633 |
|
|
// Endpoint 2, isochronous receives. Not yet supported for now, just
|
634 |
|
|
// like endpoint 1.
|
635 |
|
|
|
636 |
|
|
// Endpoints 3 and 5 can share some code.
|
637 |
|
|
#if defined(CYGPKG_DEVS_USB_UPD985XX_EP3) || defined(CYGPKG_DEVS_USB_UPD985XX_EP5)
|
638 |
|
|
// Endpoint 3, bulk transmits, and endpoint 5, either interrupt transmits
|
639 |
|
|
// or emulation of bulk transmits. The hardware does most
|
640 |
|
|
// of the work.
|
641 |
|
|
typedef struct ep35_impl {
|
642 |
|
|
usbs_tx_endpoint common;
|
643 |
|
|
cyg_bool tx_indicator_valid;
|
644 |
|
|
TxMailbox tx_indicator;
|
645 |
|
|
int send_command;
|
646 |
|
|
volatile cyg_uint32* cr;
|
647 |
|
|
TxBufferDescriptor* tx_bufdesc;
|
648 |
|
|
} ep35_impl;
|
649 |
|
|
|
650 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
651 |
|
|
static void ep3_start_tx(usbs_tx_endpoint*);
|
652 |
|
|
static void ep3_set_halted(usbs_tx_endpoint*, cyg_bool);
|
653 |
|
|
|
654 |
|
|
static ep35_impl ep3 = {
|
655 |
|
|
common: {
|
656 |
|
|
start_tx_fn: &ep3_start_tx,
|
657 |
|
|
set_halted_fn: &ep3_set_halted,
|
658 |
|
|
complete_fn: (void (*)(void*, int)) 0,
|
659 |
|
|
complete_data: (void*) 0,
|
660 |
|
|
buffer: (const unsigned char*) 0,
|
661 |
|
|
buffer_size: 0,
|
662 |
|
|
halted: 0,
|
663 |
|
|
},
|
664 |
|
|
tx_indicator_valid: false,
|
665 |
|
|
tx_indicator: { 0 },
|
666 |
|
|
send_command: USBS_CMR_COMMAND_TX_EP3,
|
667 |
|
|
cr: EP3_CR,
|
668 |
|
|
tx_bufdesc: 0 // Needs run-time initialization
|
669 |
|
|
};
|
670 |
|
|
|
671 |
|
|
extern usbs_tx_endpoint usbs_upd985xx_ep3 __attribute__ ((alias ("ep3")));
|
672 |
|
|
# endif
|
673 |
|
|
|
674 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
675 |
|
|
static void ep5_start_tx(usbs_tx_endpoint*);
|
676 |
|
|
static void ep5_set_halted(usbs_tx_endpoint*, cyg_bool);
|
677 |
|
|
|
678 |
|
|
static ep35_impl ep5 = {
|
679 |
|
|
common: {
|
680 |
|
|
start_tx_fn: &ep5_start_tx,
|
681 |
|
|
set_halted_fn: &ep5_set_halted,
|
682 |
|
|
complete_fn: (void (*)(void*, int)) 0,
|
683 |
|
|
complete_data: (void*) 0,
|
684 |
|
|
buffer: (const unsigned char*) 0,
|
685 |
|
|
buffer_size: 0,
|
686 |
|
|
halted: 0,
|
687 |
|
|
},
|
688 |
|
|
tx_indicator_valid: false,
|
689 |
|
|
tx_indicator: { 0 },
|
690 |
|
|
send_command: USBS_CMR_COMMAND_TX_EP5,
|
691 |
|
|
cr: EP5_CR,
|
692 |
|
|
tx_bufdesc: 0 // Needs run-time initialization
|
693 |
|
|
};
|
694 |
|
|
|
695 |
|
|
extern usbs_tx_endpoint usbs_upd985xx_ep5 __attribute__ ((alias ("ep5")));
|
696 |
|
|
# endif
|
697 |
|
|
#endif
|
698 |
|
|
|
699 |
|
|
|
700 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
701 |
|
|
// Endpoint 4, bulk receives. Again the hardware does the hard work.
|
702 |
|
|
// Receive pool 2 is reserved for this endpoint.
|
703 |
|
|
|
704 |
|
|
typedef struct ep4_impl {
|
705 |
|
|
usbs_rx_endpoint common;
|
706 |
|
|
cyg_uint32 head_size;
|
707 |
|
|
cyg_uint32 direct_size;
|
708 |
|
|
cyg_uint32 tail_size;
|
709 |
|
|
cyg_bool rx_indicator_valid;
|
710 |
|
|
RxMailbox rx_indicator;
|
711 |
|
|
cyg_int32 tail_index;
|
712 |
|
|
} ep4_impl;
|
713 |
|
|
|
714 |
|
|
static void ep4_start_rx(usbs_rx_endpoint*);
|
715 |
|
|
static void ep4_set_halted(usbs_rx_endpoint*, cyg_bool);
|
716 |
|
|
|
717 |
|
|
static ep4_impl ep4 = {
|
718 |
|
|
common: {
|
719 |
|
|
start_rx_fn: &ep4_start_rx,
|
720 |
|
|
set_halted_fn: &ep4_set_halted,
|
721 |
|
|
complete_fn: (void (*)(void*, int)) 0,
|
722 |
|
|
complete_data: (void*) 0,
|
723 |
|
|
buffer: (unsigned char*) 0,
|
724 |
|
|
buffer_size: 0,
|
725 |
|
|
halted: 0,
|
726 |
|
|
},
|
727 |
|
|
rx_indicator_valid: false,
|
728 |
|
|
rx_indicator: { 0, (void*) 0 },
|
729 |
|
|
tail_index: -1
|
730 |
|
|
};
|
731 |
|
|
|
732 |
|
|
extern usbs_rx_endpoint usbs_upd985xx_ep4 __attribute__((alias ("ep4")));
|
733 |
|
|
#endif
|
734 |
|
|
|
735 |
|
|
// Endpoint 6, interrupt receives. Not yet implemented. There may
|
736 |
|
|
// be conflicts because the hardware is shared with endpoint 0.
|
737 |
|
|
|
738 |
|
|
// ----------------------------------------------------------------------------
|
739 |
|
|
// Mailbox support.
|
740 |
|
|
//
|
741 |
|
|
// The transmit and receive mailboxes are shared between the
|
742 |
|
|
// appropriate endpoints. This causes some complications if e.g.
|
743 |
|
|
// transmits on several endpoints complete at the same time. For
|
744 |
|
|
// example the tx mailbox might contain send indicators for endpoints
|
745 |
|
|
// 3 and 0, but the DSR code will process endpoint 0 before endpoint
|
746 |
|
|
// 3.
|
747 |
|
|
//
|
748 |
|
|
// This device driver works on the basis that there can be only one
|
749 |
|
|
// transmit and/or receive in progress for any given endpoint, so the
|
750 |
|
|
// relevant information can be extracted from the mailbox and put into
|
751 |
|
|
// the per-endpoint structures. The routines below can be used to
|
752 |
|
|
// move data from the mailboxes. They will be called in DSR context
|
753 |
|
|
// so there is no need to worry about locking.
|
754 |
|
|
|
755 |
|
|
static void
|
756 |
|
|
drain_tx_mailbox(void)
|
757 |
|
|
{
|
758 |
|
|
TxMailbox* tmra = IBUS_SWAPPTR(TxMailbox, *USBS_TMRA);
|
759 |
|
|
TxMailbox* tmwa = IBUS_SWAPPTR(TxMailbox, *USBS_TMWA);
|
760 |
|
|
if (tmra != tmwa) {
|
761 |
|
|
do {
|
762 |
|
|
TxMailbox mbox = *tmra;
|
763 |
|
|
tmra++;
|
764 |
|
|
if (tmra == &(uncached->tx_mboxes[TXMBOX_COUNT])) {
|
765 |
|
|
tmra = &(uncached->tx_mboxes[0]);
|
766 |
|
|
}
|
767 |
|
|
|
768 |
|
|
switch(mbox.status & TXMBOX_STATUS_EPN_MASK) {
|
769 |
|
|
case TXMBOX_STATUS_EPN_EP0:
|
770 |
|
|
CYG_ASSERT(false == ep0.tx_indicator_valid, "Only one ep0 transmit should be in progress at a time");
|
771 |
|
|
ep0.tx_indicator = mbox;
|
772 |
|
|
ep0.tx_indicator_valid = true;
|
773 |
|
|
break;
|
774 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
775 |
|
|
case TXMBOX_STATUS_EPN_EP3:
|
776 |
|
|
CYG_ASSERT(false == ep3.tx_indicator_valid, "Only one ep3 transmit should be in progress at a time");
|
777 |
|
|
ep3.tx_indicator = mbox;
|
778 |
|
|
ep3.tx_indicator_valid = true;
|
779 |
|
|
break;
|
780 |
|
|
#endif
|
781 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
782 |
|
|
case TXMBOX_STATUS_EPN_EP5:
|
783 |
|
|
CYG_ASSERT(false == ep5.tx_indicator_valid, "Only one ep5 transmit should be in progress at a time");
|
784 |
|
|
ep5.tx_indicator = mbox;
|
785 |
|
|
ep5.tx_indicator_valid = true;
|
786 |
|
|
break;
|
787 |
|
|
#endif
|
788 |
|
|
default:
|
789 |
|
|
break;
|
790 |
|
|
}
|
791 |
|
|
} while (tmra != tmwa);
|
792 |
|
|
*USBS_TMRA = IBUS_SWAPPTR(TxMailbox, tmra); FLUSH_IBUS();
|
793 |
|
|
}
|
794 |
|
|
}
|
795 |
|
|
|
796 |
|
|
static void
|
797 |
|
|
drain_rx_mailbox(void)
|
798 |
|
|
{
|
799 |
|
|
RxMailbox* rmra = IBUS_SWAPPTR(RxMailbox, *USBS_RMRA);
|
800 |
|
|
RxMailbox* rmwa = IBUS_SWAPPTR(RxMailbox, *USBS_RMWA);
|
801 |
|
|
|
802 |
|
|
if (rmra != rmwa) {
|
803 |
|
|
do {
|
804 |
|
|
RxMailbox mbox = *rmra;
|
805 |
|
|
rmra++;
|
806 |
|
|
if (rmra == &(uncached->rx_mboxes[RXMBOX_COUNT])) {
|
807 |
|
|
rmra = &(uncached->rx_mboxes[0]);
|
808 |
|
|
}
|
809 |
|
|
|
810 |
|
|
switch(mbox.status & RXMBOX_STATUS_EPN_MASK) {
|
811 |
|
|
case RXMBOX_STATUS_EPN_EP0:
|
812 |
|
|
// Ignore zero-byte transfers. It is not clear why
|
813 |
|
|
// these happen, but they have been observed.
|
814 |
|
|
if (0 != (mbox.status & RXMBOX_STATUS_SIZE_MASK)) {
|
815 |
|
|
CYG_ASSERT(false == ep0.rx_indicator_valid, "Only one ep0 receive should be in progress at a time");
|
816 |
|
|
ep0.rx_indicator = mbox;
|
817 |
|
|
ep0.rx_indicator_valid = true;
|
818 |
|
|
}
|
819 |
|
|
break;
|
820 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
821 |
|
|
case RXMBOX_STATUS_EPN_EP4:
|
822 |
|
|
// If an error occurs then the hardware may report
|
823 |
|
|
// multiple rx completions, each with an IBUS error
|
824 |
|
|
// indicator. For now only the last rx indicator is
|
825 |
|
|
// taken into account, which means we could lose
|
826 |
|
|
// a successful receive that happens to be followed
|
827 |
|
|
// by an error.
|
828 |
|
|
// NOTE: any possibility of improving on this?
|
829 |
|
|
#if 1
|
830 |
|
|
CYG_ASSERT(false == ep4.rx_indicator_valid, "Only one ep4 receive should be in progress at a time");
|
831 |
|
|
#endif
|
832 |
|
|
ep4.rx_indicator = mbox;
|
833 |
|
|
ep4.rx_indicator_valid = true;
|
834 |
|
|
break;
|
835 |
|
|
#endif
|
836 |
|
|
default:
|
837 |
|
|
break;
|
838 |
|
|
}
|
839 |
|
|
} while (rmra != rmwa);
|
840 |
|
|
*USBS_RMRA = IBUS_SWAPPTR(RxMailbox, rmra); FLUSH_IBUS();
|
841 |
|
|
}
|
842 |
|
|
}
|
843 |
|
|
|
844 |
|
|
// ----------------------------------------------------------------------------
|
845 |
|
|
// Transmit locking.
|
846 |
|
|
//
|
847 |
|
|
// According to NEC errata U3 and U4 the hardware may exhibit
|
848 |
|
|
// undesirable behaviour if there are concurrent transmissions. There
|
849 |
|
|
// are various ways of resolving this, but the simplest is to perform
|
850 |
|
|
// locking in software so that at most one transmit endpoint is in use
|
851 |
|
|
// at any one time. This approach works fine if transmissions only
|
852 |
|
|
// involve one tx endpoint plus the control endpoint because the
|
853 |
|
|
// control endpoint generally only gets used during initialization and
|
854 |
|
|
// the other endpoint only gets used after initialization. If multiple
|
855 |
|
|
// transmit endpoints are used then locking in software becomes less
|
856 |
|
|
// acceptable, especially if isochronous transfers are used because
|
857 |
|
|
// timing is important for those.
|
858 |
|
|
//
|
859 |
|
|
// There is a theoretical problem if e.g. there is a very large bulk
|
860 |
|
|
// transfer on a busy bus and it is necessary to respond to a control
|
861 |
|
|
// message. The control reply would be delayed, possibly causing a
|
862 |
|
|
// violation of the USB standard and a timeout on the host.
|
863 |
|
|
|
864 |
|
|
#ifdef CYGIMP_DEVS_USB_UPD985XX_SERIALIZE_TRANSMITS
|
865 |
|
|
static void ep0_start_tx(void);
|
866 |
|
|
# if defined(CYGPKG_DEVS_USB_UPD985XX_EP3) || defined(CYGPKG_DEVS_USB_UPD985XX_EP5)
|
867 |
|
|
static void ep35_start_tx(ep35_impl*);
|
868 |
|
|
# endif
|
869 |
|
|
|
870 |
|
|
static cyg_bool tx_in_progress = false;
|
871 |
|
|
static cyg_bool ep0_tx_pending = false;
|
872 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
873 |
|
|
static cyg_bool ep3_tx_pending = false;
|
874 |
|
|
# endif
|
875 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
876 |
|
|
static cyg_bool ep5_tx_pending = false;
|
877 |
|
|
# endif
|
878 |
|
|
|
879 |
|
|
// Invoked from ep?_start_tx(). Scheduling may or may not be locked.
|
880 |
|
|
static cyg_bool
|
881 |
|
|
tx_try_lock(cyg_bool* which)
|
882 |
|
|
{
|
883 |
|
|
cyg_bool result;
|
884 |
|
|
cyg_drv_dsr_lock();
|
885 |
|
|
if (tx_in_progress) {
|
886 |
|
|
result = false;
|
887 |
|
|
*which = true;
|
888 |
|
|
} else {
|
889 |
|
|
result = true;
|
890 |
|
|
tx_in_progress = true;
|
891 |
|
|
}
|
892 |
|
|
cyg_drv_dsr_unlock();
|
893 |
|
|
return result;
|
894 |
|
|
}
|
895 |
|
|
|
896 |
|
|
// Invoked only from dsr context.
|
897 |
|
|
static void
|
898 |
|
|
tx_unlock(void)
|
899 |
|
|
{
|
900 |
|
|
tx_in_progress = false;
|
901 |
|
|
if (ep0_tx_pending) {
|
902 |
|
|
ep0_tx_pending = false;
|
903 |
|
|
ep0_start_tx();
|
904 |
|
|
return;
|
905 |
|
|
}
|
906 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
907 |
|
|
if (ep3_tx_pending) {
|
908 |
|
|
ep3_tx_pending = false;
|
909 |
|
|
ep35_start_tx(&ep3);
|
910 |
|
|
return;
|
911 |
|
|
}
|
912 |
|
|
# endif
|
913 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
914 |
|
|
if (ep5_tx_pending) {
|
915 |
|
|
ep5_tx_pending = false;
|
916 |
|
|
ep35_start_tx(&ep5);
|
917 |
|
|
return;
|
918 |
|
|
}
|
919 |
|
|
# endif
|
920 |
|
|
}
|
921 |
|
|
|
922 |
|
|
# define TX_TRY_LOCK(_x_) tx_try_lock(_x_)
|
923 |
|
|
# define TX_UNLOCK() tx_unlock()
|
924 |
|
|
|
925 |
|
|
#else
|
926 |
|
|
|
927 |
|
|
# define TX_TRY_LOCK(_x_) 1
|
928 |
|
|
# define TX_UNLOCK() CYG_EMPTY_STATEMENT
|
929 |
|
|
|
930 |
|
|
#endif
|
931 |
|
|
|
932 |
|
|
|
933 |
|
|
// ----------------------------------------------------------------------------
|
934 |
|
|
// Endpoint 0
|
935 |
|
|
//
|
936 |
|
|
// As usual, control messages are more complicated than the rest.
|
937 |
|
|
//
|
938 |
|
|
// 1) during initialization a receive is initiated into the common
|
939 |
|
|
// eight-byte buffer, used for the standard header of the control
|
940 |
|
|
// packet. Until that header has been received and analysed,
|
941 |
|
|
// there is no way of knowing whether or not the host will be
|
942 |
|
|
// sending any more data.
|
943 |
|
|
//
|
944 |
|
|
// 2) the control packet may indicate that the host will be sending
|
945 |
|
|
// more data. A higher-level handler for the control message should
|
946 |
|
|
// have provided a suitable buffer, so a receive can be started
|
947 |
|
|
// into that buffer. A flag indicates whether we are currently
|
948 |
|
|
// receiving a new control packet or additional data.
|
949 |
|
|
//
|
950 |
|
|
// 3) the host may decide to cancel that extra data and send a new
|
951 |
|
|
// control message instead. There is a flag to indicate that
|
952 |
|
|
// the transfer included a SETUP token.
|
953 |
|
|
//
|
954 |
|
|
// 4) transmits only happen when the control packet involves returning
|
955 |
|
|
// data. Unfortunately there is a problem in that, with eCos, the
|
956 |
|
|
// return data will generally not be in a single contiguous buffer.
|
957 |
|
|
// Discontinuous data could be handled by having a separate buffer
|
958 |
|
|
// descriptor for each bit of data, but it is not known in advance
|
959 |
|
|
// how many buffer descriptors might be needed so allocating
|
960 |
|
|
// those statically presents a problem as well. Instead a single
|
961 |
|
|
// static buffer is used, and data from higher-level code is copied
|
962 |
|
|
// there. This introduces a new problem: how big should that buffer
|
963 |
|
|
// be? A configuration option is used for that.
|
964 |
|
|
//
|
965 |
|
|
// If endpoint 6 is in use as well then things get more complicated
|
966 |
|
|
// because a single receive pool will be shared between endpoints 0
|
967 |
|
|
// and 6, and when adding a buffer to a pool there is no way of
|
968 |
|
|
// specifying the endpoint. Hence it will be necessary to receive
|
969 |
|
|
// into a static buffer and then copy into either an endpoint 0 or
|
970 |
|
|
// and endpoint 6 buffer.
|
971 |
|
|
|
972 |
|
|
// Fill the transmit buffer by repeatedly invoking the refill function
|
973 |
|
|
// and copying into the ep0 tx buffer. The relevant fields in the
|
974 |
|
|
// ep0 structure are cleared immediately and the completion function
|
975 |
|
|
// is called, even though the data has not actually gone out. That avoids
|
976 |
|
|
// a possible race condition where the host sends a new control packet
|
977 |
|
|
// immediately, before the transmit-complete has been processed
|
978 |
|
|
// (unlikely in practice, not least because ep0_tx_dsr() will get called
|
979 |
|
|
// before ep0_rx_dsr()).
|
980 |
|
|
static int
|
981 |
|
|
ep0_fill_txbuffer(void)
|
982 |
|
|
{
|
983 |
|
|
int filled = 0;
|
984 |
|
|
while (filled < CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE) {
|
985 |
|
|
if (0 != ep0.common.buffer_size) {
|
986 |
|
|
if ((filled + ep0.common.buffer_size) < CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE) {
|
987 |
|
|
memcpy(&(uncached->ep0_tx_buffer[filled]), ep0.common.buffer, ep0.common.buffer_size);
|
988 |
|
|
filled += ep0.common.buffer_size;
|
989 |
|
|
ep0.common.buffer_size = 0;
|
990 |
|
|
} else {
|
991 |
|
|
break;
|
992 |
|
|
}
|
993 |
|
|
} else if ((void (*)(usbs_control_endpoint*))0 != ep0.common.fill_buffer_fn) {
|
994 |
|
|
(*ep0.common.fill_buffer_fn)(&ep0.common);
|
995 |
|
|
} else {
|
996 |
|
|
break;
|
997 |
|
|
}
|
998 |
|
|
}
|
999 |
|
|
CYG_ASSERT((0 == ep0.common.buffer_size) && ((void (*)(usbs_control_endpoint*))0 == ep0.common.fill_buffer_fn), \
|
1000 |
|
|
"Endpoint 0 transmit buffer overflow");
|
1001 |
|
|
|
1002 |
|
|
if ((usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn) {
|
1003 |
|
|
(*ep0.common.complete_fn)(&ep0.common, 0);
|
1004 |
|
|
}
|
1005 |
|
|
ep0.common.buffer = (unsigned char*) 0;
|
1006 |
|
|
ep0.common.buffer_size = 0;
|
1007 |
|
|
ep0.common.fill_buffer_fn = 0;
|
1008 |
|
|
ep0.common.complete_fn = 0;
|
1009 |
|
|
|
1010 |
|
|
return filled;
|
1011 |
|
|
}
|
1012 |
|
|
|
1013 |
|
|
// Start a new receive operation on endpoint 0. This needs to happen
|
1014 |
|
|
// from a number of places, including from initialization.
|
1015 |
|
|
//
|
1016 |
|
|
// IMHO the hardware is somewhat overengineered here. All that is
|
1017 |
|
|
// needed is to receive a single eight-byte control packet, or a
|
1018 |
|
|
// small amount of additional control data. That could be achieved
|
1019 |
|
|
// by using a single buffer descriptor in the uncached structure,
|
1020 |
|
|
// plus a suitably-sized static uncached ep0_rx_buffer.
|
1021 |
|
|
//
|
1022 |
|
|
// But no, buffer descriptors must be linked and new buffers must
|
1023 |
|
|
// be added to the end. When a control packet arrives, the
|
1024 |
|
|
// receive pool continues to point at the old buffer descriptor.
|
1025 |
|
|
// So we need two buffer descriptors plus two links, switching
|
1026 |
|
|
// between them as appropriate.
|
1027 |
|
|
//
|
1028 |
|
|
// It is not at all clear what would happen if another packet
|
1029 |
|
|
// started to happen while things were being updated. There is
|
1030 |
|
|
// also potential confusion between endpoint 0 and endpoint 6
|
1031 |
|
|
// receives.
|
1032 |
|
|
|
1033 |
|
|
static void
|
1034 |
|
|
ep0_start_rx(cyg_uint32 size)
|
1035 |
|
|
{
|
1036 |
|
|
// The buffer descriptor to be added. This will be either
|
1037 |
|
|
// ep0_rxbufdescs[0] or ep0_rxbufdescs[2];
|
1038 |
|
|
RxBufferDescriptor* desc = &(uncached->ep0_rx_bufdescs[0]);
|
1039 |
|
|
|
1040 |
|
|
CYG_ASSERTC(size > 0);
|
1041 |
|
|
|
1042 |
|
|
// Block interrupts for the duration. This does not prevent
|
1043 |
|
|
// problems if the hardware sees another packet and starts
|
1044 |
|
|
// doing things, but should prevent some software race
|
1045 |
|
|
// conditions.
|
1046 |
|
|
cyg_drv_isr_lock();
|
1047 |
|
|
|
1048 |
|
|
// We are about to start a new rx operation, so the
|
1049 |
|
|
// current indicator may get invalidated.
|
1050 |
|
|
ep0.rx_indicator_valid = false;
|
1051 |
|
|
|
1052 |
|
|
// Start by looking at the current pool0 status. There are
|
1053 |
|
|
// three possibilities: during init or after reset, the pool
|
1054 |
|
|
// will be empty; otherwise the pool should point at either
|
1055 |
|
|
// rx_bufdescs[0] or rx_bufdescs[2], corresponding to the
|
1056 |
|
|
// last received packet.
|
1057 |
|
|
if (0 == (*USBS_RP0IR & USBS_RPxIR_RNOD_MASK)) {
|
1058 |
|
|
// Nothing currently in the pool. Use ep0_rx_bufdescs[0],
|
1059 |
|
|
// and no need to update a link.
|
1060 |
|
|
} else if (desc == *USBS_RP0AR) {
|
1061 |
|
|
// The pool already points at bufdescs[0], switch to bufdescs[2],
|
1062 |
|
|
// and link from bufdescs[1].
|
1063 |
|
|
desc = &(uncached->ep0_rx_bufdescs[2]);
|
1064 |
|
|
uncached->ep0_rx_bufdescs[1].buffer = (void*) desc;
|
1065 |
|
|
} else {
|
1066 |
|
|
// The pool should point at bufdescs[2], stick with bufdescs[0]
|
1067 |
|
|
CYG_ASSERT(&(uncached->ep0_rx_bufdescs[2]) == *USBS_RP0AR, "Endpoint 0 rx buffer confusion");
|
1068 |
|
|
uncached->ep0_rx_bufdescs[3].buffer = (void*) desc;
|
1069 |
|
|
}
|
1070 |
|
|
|
1071 |
|
|
// Now fill in the buffer directory being added
|
1072 |
|
|
desc[0].control = RXBUFDESC_CTRL_LAST | RXBUFDESC_CTRL_BUFDESC_BUFDESC | size;
|
1073 |
|
|
desc[0].buffer = (void*) uncached->ep0_rx_buffer;
|
1074 |
|
|
desc[1].control = RXBUFDESC_CTRL_BUFDESC_LINK;
|
1075 |
|
|
desc[1].buffer = 0;
|
1076 |
|
|
|
1077 |
|
|
while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
|
1078 |
|
|
// Do nothing: this situation should be short-lived.
|
1079 |
|
|
}
|
1080 |
|
|
*USBS_CA = IBUS_SWAPPTR(void, desc); FLUSH_IBUS();
|
1081 |
|
|
*USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_ADD_POOL0 | 1); FLUSH_IBUS();
|
1082 |
|
|
cyg_drv_isr_unlock();
|
1083 |
|
|
}
|
1084 |
|
|
|
1085 |
|
|
// Ditto for transmits. The data is assumed to be in
|
1086 |
|
|
// uncached->ep0_tx_buffer already. A size of 0 indicates
|
1087 |
|
|
// a need to send a terminating packet explicitly.
|
1088 |
|
|
static void
|
1089 |
|
|
ep0_start_tx(void)
|
1090 |
|
|
{
|
1091 |
|
|
if (!TX_TRY_LOCK(&ep0_tx_pending)) {
|
1092 |
|
|
return;
|
1093 |
|
|
}
|
1094 |
|
|
|
1095 |
|
|
uncached->ep0_tx_bufdesc.buffer = uncached->ep0_tx_buffer;
|
1096 |
|
|
uncached->ep0_tx_bufdesc.control = TXBUFDESC_CTRL_LAST | TXBUFDESC_CTRL_BUFDESC_BUFDESC | ep0.tx_size;
|
1097 |
|
|
|
1098 |
|
|
cyg_drv_isr_lock();
|
1099 |
|
|
while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
|
1100 |
|
|
// Do nothing: this situation should be short-lived.
|
1101 |
|
|
}
|
1102 |
|
|
*USBS_CA = IBUS_SWAPPTR(void, &(uncached->ep0_tx_bufdesc)); FLUSH_IBUS();
|
1103 |
|
|
*USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_TX_EP0 | ep0.tx_size); FLUSH_IBUS();
|
1104 |
|
|
cyg_drv_isr_unlock();
|
1105 |
|
|
}
|
1106 |
|
|
|
1107 |
|
|
// An endpoint 0 transmission has completed. Usually the only action
|
1108 |
|
|
// that is needed is to drain the tx mailbox entry, otherwise it is
|
1109 |
|
|
// possible that we could end up with ep0 transmits using up all
|
1110 |
|
|
// available slots. The endpoint 0 hardware requires no further
|
1111 |
|
|
// attention, and as far as higher-level code is concerned the
|
1112 |
|
|
// transmission completed a long time ago when ep0_fill_txbuffer()
|
1113 |
|
|
// called the completion function.
|
1114 |
|
|
//
|
1115 |
|
|
// There is one special case. If the host asked for e.g. a string
|
1116 |
|
|
// descriptor and asked for 255 bytes, but the string was only
|
1117 |
|
|
// e.g. 32 bytes, then there is a problem. With a default value
|
1118 |
|
|
// for CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE, the data will be
|
1119 |
|
|
// transferred as four 8-byte packets, but it is necessary to
|
1120 |
|
|
// terminate the transfer with a 0-byte packet. Endpoint 0 always
|
1121 |
|
|
// operates in NZLP mode so the hardware will never generate
|
1122 |
|
|
// this last packet. Instead it is necessary to set up an
|
1123 |
|
|
// additional transfer of zero bytes. That could be done at the
|
1124 |
|
|
// same time as the main data transfer, but then it would be
|
1125 |
|
|
// necessary to poll the hardware and wait until it has finished
|
1126 |
|
|
// processing that initial transfer.
|
1127 |
|
|
static void
|
1128 |
|
|
ep0_tx_dsr(void)
|
1129 |
|
|
{
|
1130 |
|
|
if (!ep0.tx_indicator_valid) {
|
1131 |
|
|
drain_tx_mailbox();
|
1132 |
|
|
if (!ep0.tx_indicator_valid) {
|
1133 |
|
|
// A transmit interrupt when there does not appear to be
|
1134 |
|
|
// any data?
|
1135 |
|
|
CYG_FAIL("EP0 tx DSR invoked when there is no valid tx indicator");
|
1136 |
|
|
return;
|
1137 |
|
|
}
|
1138 |
|
|
}
|
1139 |
|
|
// There is not actually anything worth looking at in the status.
|
1140 |
|
|
ep0.tx_indicator_valid = false;
|
1141 |
|
|
|
1142 |
|
|
if (ep0.tx_needs_zero_transfer) {
|
1143 |
|
|
ep0.tx_needs_zero_transfer = false;
|
1144 |
|
|
uncached->ep0_tx_bufdesc.buffer = uncached->ep0_tx_buffer;
|
1145 |
|
|
uncached->ep0_tx_bufdesc.control = TXBUFDESC_CTRL_LAST | TXBUFDESC_CTRL_BUFDESC_BUFDESC | 0;
|
1146 |
|
|
|
1147 |
|
|
cyg_drv_isr_lock();
|
1148 |
|
|
while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
|
1149 |
|
|
// Do nothing: this situation should be short-lived.
|
1150 |
|
|
}
|
1151 |
|
|
*USBS_CA = IBUS_SWAPPTR(void, &(uncached->ep0_tx_bufdesc)); FLUSH_IBUS();
|
1152 |
|
|
*USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_TX_EP0 | 0); FLUSH_IBUS();
|
1153 |
|
|
cyg_drv_isr_unlock();
|
1154 |
|
|
|
1155 |
|
|
} else {
|
1156 |
|
|
TX_UNLOCK();
|
1157 |
|
|
}
|
1158 |
|
|
}
|
1159 |
|
|
|
1160 |
|
|
// An endpoint 0 receive has completed. This could be a new control
|
1161 |
|
|
// message. Or it could be the data for a previous control message. Or
|
1162 |
|
|
// it could be a new control message when expecting the data from
|
1163 |
|
|
// a previous one. The ep0.rx_expecting_data field indicates
|
1164 |
|
|
// whether or not a new control message is expected.
|
1165 |
|
|
//
|
1166 |
|
|
// At times an interrupt triggers and there is an rx indication for a
|
1167 |
|
|
// zero-byte transfer. Such a transfer may be followed immediately by
|
1168 |
|
|
// a real transfer. It is not understood why the zero-byte transfer
|
1169 |
|
|
// occurs. They are ignored by the drain_rx_mailbox() code, to make
|
1170 |
|
|
// sure that there is at most one valid rx indicator at a time.
|
1171 |
|
|
static void
|
1172 |
|
|
ep0_rx_dsr(void)
|
1173 |
|
|
{
|
1174 |
|
|
// Start by checking the rx indicator to make sure that a packet
|
1175 |
|
|
// really has been received.
|
1176 |
|
|
if (!ep0.rx_indicator_valid) {
|
1177 |
|
|
drain_rx_mailbox();
|
1178 |
|
|
if (!ep0.rx_indicator_valid) {
|
1179 |
|
|
// Do not assert, in case of a spurious interrupt for a
|
1180 |
|
|
// zero-byte transfer.
|
1181 |
|
|
return;
|
1182 |
|
|
}
|
1183 |
|
|
}
|
1184 |
|
|
|
1185 |
|
|
// We have a valid receive, with the data held in uncached->ep0_rx_buffer.
|
1186 |
|
|
// Are we expecting the remaining data of a control transfer?
|
1187 |
|
|
if (ep0.rx_expecting_data) {
|
1188 |
|
|
// Was this data interrupted by a new setup packet?
|
1189 |
|
|
if (0 != (ep0.rx_indicator.status & RXMBOX_STATUS_SETUP_SETUP)) {
|
1190 |
|
|
// NOTE: it is not clear from the documentation exactly what
|
1191 |
|
|
// happens here, e.g. is it guaranteed that the new control
|
1192 |
|
|
// packet appears at the start of the buffer rather than
|
1193 |
|
|
// after any data previously received? Given typical
|
1194 |
|
|
// USB host-side implementations this scenario is considered
|
1195 |
|
|
// sufficiently unlikely that no further investigation has
|
1196 |
|
|
// been carried out.
|
1197 |
|
|
|
1198 |
|
|
// Inform higher-level code that the receive has been aborted.
|
1199 |
|
|
if ((usbs_control_return (*)(usbs_control_endpoint*, int)) 0 != ep0.common.complete_fn) {
|
1200 |
|
|
(*ep0.common.complete_fn)(&ep0.common, -EIO);
|
1201 |
|
|
}
|
1202 |
|
|
ep0.rx_expecting_data = false;
|
1203 |
|
|
ep0.common.buffer = (unsigned char*) 0;
|
1204 |
|
|
ep0.common.buffer_size = 0;
|
1205 |
|
|
ep0.common.fill_buffer_fn = 0;
|
1206 |
|
|
ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
|
1207 |
|
|
// Fall through the main control message handling code below.
|
1208 |
|
|
} else {
|
1209 |
|
|
// Data was expected and received. Transfer the data to the
|
1210 |
|
|
// user's buffer, and perform completion.
|
1211 |
|
|
usbs_control_return result;
|
1212 |
|
|
cyg_uint32 size = ep0.rx_indicator.status & RXMBOX_STATUS_SIZE_MASK;
|
1213 |
|
|
|
1214 |
|
|
CYG_ASSERT( (usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn, \
|
1215 |
|
|
"A completion function should be provided for OUT control messages");
|
1216 |
|
|
CYG_ASSERT(size == ep0.common.buffer_size, "Inconsistency between buffer and transfer sizes");
|
1217 |
|
|
memcpy(ep0.common.buffer, uncached->ep0_rx_buffer, size);
|
1218 |
|
|
result = (*ep0.common.complete_fn)(&ep0.common, 0);
|
1219 |
|
|
ep0.common.buffer = (unsigned char*) 0;
|
1220 |
|
|
ep0.common.buffer_size = 0;
|
1221 |
|
|
ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
|
1222 |
|
|
ep0.rx_expecting_data = false;
|
1223 |
|
|
|
1224 |
|
|
// Start another receive for the next control message.
|
1225 |
|
|
// Note that there has been a window where there was no receive
|
1226 |
|
|
// in progress for endpoint 0, even though according to the
|
1227 |
|
|
// USB spec a device must always be able to accept new
|
1228 |
|
|
// control messages.
|
1229 |
|
|
ep0_start_rx(8);
|
1230 |
|
|
return;
|
1231 |
|
|
}
|
1232 |
|
|
}
|
1233 |
|
|
|
1234 |
|
|
// When we get here we should have an eight-byte control message
|
1235 |
|
|
// in uncached->ep0_rx_buffer. This should get moved into
|
1236 |
|
|
// the ep0.common.control_buffer so that higher-level code sees
|
1237 |
|
|
// it in the appropriate location.
|
1238 |
|
|
CYG_ASSERT((ep0.rx_indicator.address == &(uncached->ep0_rx_bufdescs[0])) || \
|
1239 |
|
|
(ep0.rx_indicator.address == &(uncached->ep0_rx_bufdescs[2])), \
|
1240 |
|
|
"Received ep0 data should involve the ep0 rx buffer descriptor");
|
1241 |
|
|
|
1242 |
|
|
CYG_ASSERT(8 == (ep0.rx_indicator.status & RXMBOX_STATUS_SIZE_MASK), "Control messages should be 8 bytes");
|
1243 |
|
|
memcpy(ep0.common.control_buffer, uncached->ep0_rx_buffer, 8);
|
1244 |
|
|
|
1245 |
|
|
// If we have received a control packet then any reset signals really
|
1246 |
|
|
// will have come from the host and must be processed normally.
|
1247 |
|
|
// Make sure that reset interrupts are no longer masked off.
|
1248 |
|
|
if (0 == (*USBS_IMR2 & IBUS_SWAP32(USBS_GSR2_URST))) {
|
1249 |
|
|
*USBS_IMR2 |= IBUS_SWAP32(USBS_GSR2_URST); FLUSH_IBUS();
|
1250 |
|
|
usbs_upd985xx_gsr2_mask |= USBS_GSR2_URST;
|
1251 |
|
|
}
|
1252 |
|
|
|
1253 |
|
|
{
|
1254 |
|
|
usbs_control_return result = USBS_CONTROL_RETURN_UNKNOWN;
|
1255 |
|
|
usb_devreq* req = (usb_devreq*) ep0.common.control_buffer;
|
1256 |
|
|
int length, direction, protocol, recipient;
|
1257 |
|
|
|
1258 |
|
|
// Now we need to do some decoding of the data. A non-zero
|
1259 |
|
|
// length field indicates that there will be a subsequent
|
1260 |
|
|
// IN or OUT phase. The direction is controlled by the
|
1261 |
|
|
// top bit of the first byte. The protocol is determined
|
1262 |
|
|
// by other bits of the top byte.
|
1263 |
|
|
length = (req->length_hi << 8) | req->length_lo;
|
1264 |
|
|
direction = req->type & USB_DEVREQ_DIRECTION_MASK;
|
1265 |
|
|
protocol = req->type & USB_DEVREQ_TYPE_MASK;
|
1266 |
|
|
recipient = req->type & USB_DEVREQ_RECIPIENT_MASK;
|
1267 |
|
|
|
1268 |
|
|
DBG(("ep0, new control request: type %x, code %x\n", req->type, req->request));
|
1269 |
|
|
DBG((" %s, length %d, value hi %x lo %x, index hi %x lo %x\n",
|
1270 |
|
|
(USB_DEVREQ_DIRECTION_OUT == direction) ? "out" : "in",
|
1271 |
|
|
length, req->value_hi, req->value_lo, req->index_hi, req->index_lo));
|
1272 |
|
|
|
1273 |
|
|
if (USB_DEVREQ_TYPE_STANDARD == protocol) {
|
1274 |
|
|
|
1275 |
|
|
// First see if the request can be handled entirely in
|
1276 |
|
|
// this module.
|
1277 |
|
|
if (USB_DEVREQ_SET_ADDRESS == req->request) {
|
1278 |
|
|
// The USB device address should be in value_lo.
|
1279 |
|
|
// No more data is expected.
|
1280 |
|
|
int old_state = ep0.common.state;
|
1281 |
|
|
int address = req->value_lo;
|
1282 |
|
|
if ((0 != length) || (address > 127)) {
|
1283 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1284 |
|
|
} else {
|
1285 |
|
|
*USBS_GMR = (*USBS_GMR & ~(USBS_GMR_FA_MASK | USBS_GMR_VT)) | (address << USBS_GMR_FA_SHIFT); FLUSH_IBUS();
|
1286 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1287 |
|
|
}
|
1288 |
|
|
// Switch to addressed state, informing higher-level
|
1289 |
|
|
// code of this.
|
1290 |
|
|
if (USBS_STATE_ADDRESSED != (old_state & USBS_STATE_MASK)) {
|
1291 |
|
|
ep0.common.state = USBS_STATE_ADDRESSED;
|
1292 |
|
|
if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
|
1293 |
|
|
(*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
|
1294 |
|
|
USBS_STATE_CHANGE_ADDRESSED, old_state);
|
1295 |
|
|
}
|
1296 |
|
|
}
|
1297 |
|
|
// End of SET_ADDRESS handling
|
1298 |
|
|
} else if (USB_DEVREQ_GET_STATUS == req->request) {
|
1299 |
|
|
// GET_STATUS on the device as a whole is used to
|
1300 |
|
|
// check the remote-wakeup and self-powered bits.
|
1301 |
|
|
// GET_STATUS on an endpoint is used to determine
|
1302 |
|
|
// the halted condition.
|
1303 |
|
|
// GET_STATUS on anything else has to be left to
|
1304 |
|
|
// other code.
|
1305 |
|
|
if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {
|
1306 |
|
|
// The host should expect two bytes back.
|
1307 |
|
|
if ((2 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) {
|
1308 |
|
|
ep0.common.control_buffer[0] = 0; // Not self-powered, no remote wakeup
|
1309 |
|
|
ep0.common.control_buffer[1] = 0;
|
1310 |
|
|
ep0.common.buffer = ep0.common.control_buffer;
|
1311 |
|
|
ep0.common.buffer_size = 2;
|
1312 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1313 |
|
|
} else {
|
1314 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1315 |
|
|
}
|
1316 |
|
|
|
1317 |
|
|
} else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {
|
1318 |
|
|
if ((2 == length) && (USB_DEVREQ_DIRECTION_IN == direction)) {
|
1319 |
|
|
int endpoint = req->index_lo;
|
1320 |
|
|
if (0 == endpoint) {
|
1321 |
|
|
// get-status on endpoint 0 is either undefined or always valid.
|
1322 |
|
|
// endpoint 0 is always up.
|
1323 |
|
|
ep0.common.control_buffer[0] = 0;
|
1324 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1325 |
|
|
}
|
1326 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
1327 |
|
|
else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 3) == endpoint) &&
|
1328 |
|
|
(USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
|
1329 |
|
|
ep0.common.control_buffer[0] = ep3.common.halted;
|
1330 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1331 |
|
|
}
|
1332 |
|
|
#endif
|
1333 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
1334 |
|
|
else if (((USB_DEVREQ_INDEX_DIRECTION_OUT | 4) == endpoint) &&
|
1335 |
|
|
(USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
|
1336 |
|
|
ep0.common.control_buffer[0] = ep4.common.halted;
|
1337 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1338 |
|
|
|
1339 |
|
|
}
|
1340 |
|
|
#endif
|
1341 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
1342 |
|
|
else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 5) == endpoint) &&
|
1343 |
|
|
(USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
|
1344 |
|
|
ep0.common.control_buffer[0] = ep5.common.halted;
|
1345 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1346 |
|
|
}
|
1347 |
|
|
#endif
|
1348 |
|
|
else {
|
1349 |
|
|
// An invalid endpoint has been specified or the
|
1350 |
|
|
// endpoint can only be examined in configured state.
|
1351 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1352 |
|
|
}
|
1353 |
|
|
if (USBS_CONTROL_RETURN_HANDLED == result) {
|
1354 |
|
|
ep0.common.control_buffer[1] = 0;
|
1355 |
|
|
ep0.common.buffer = ep0.common.control_buffer;
|
1356 |
|
|
ep0.common.buffer_size = 2;
|
1357 |
|
|
}
|
1358 |
|
|
} else {
|
1359 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1360 |
|
|
}
|
1361 |
|
|
} // Endpoint or device get-status
|
1362 |
|
|
|
1363 |
|
|
} else if (USB_DEVREQ_CLEAR_FEATURE == req->request) {
|
1364 |
|
|
|
1365 |
|
|
// CLEAR_FEATURE operates in much the same way as
|
1366 |
|
|
// GET_STATUS
|
1367 |
|
|
if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {
|
1368 |
|
|
|
1369 |
|
|
// No data should be transferred, and only remote-wakeup can be cleared.
|
1370 |
|
|
if ((0 != length) || (USB_DEVREQ_FEATURE_DEVICE_REMOTE_WAKEUP != req->value_lo)) {
|
1371 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1372 |
|
|
} else {
|
1373 |
|
|
// Clearing remote-wakeup is a no-op.
|
1374 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1375 |
|
|
}
|
1376 |
|
|
|
1377 |
|
|
} else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {
|
1378 |
|
|
// The only feature that can be cleared is endpoint-halt, no data should be transferred.
|
1379 |
|
|
if ((0 != length) || (USB_DEVREQ_FEATURE_ENDPOINT_HALT != req->value_lo)) {
|
1380 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1381 |
|
|
} else {
|
1382 |
|
|
int endpoint = req->index_lo;
|
1383 |
|
|
if (0 == endpoint) {
|
1384 |
|
|
// Clearing halt on endpoint 0 is always a no-op since that endpoint cannot be halted
|
1385 |
|
|
}
|
1386 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
1387 |
|
|
else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 3) == endpoint) &&
|
1388 |
|
|
(USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
|
1389 |
|
|
ep3_set_halted(&ep3.common, false);
|
1390 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1391 |
|
|
}
|
1392 |
|
|
#endif
|
1393 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
1394 |
|
|
else if (((USB_DEVREQ_INDEX_DIRECTION_OUT | 4) == endpoint) &&
|
1395 |
|
|
(USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
|
1396 |
|
|
ep4_set_halted(&ep4.common, false);
|
1397 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1398 |
|
|
}
|
1399 |
|
|
#endif
|
1400 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
1401 |
|
|
else if (((USB_DEVREQ_INDEX_DIRECTION_IN | 5) == endpoint) &&
|
1402 |
|
|
(USBS_STATE_CONFIGURED == (ep0.common.state & USBS_STATE_MASK))) {
|
1403 |
|
|
ep5_set_halted(&ep5.common, false);
|
1404 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1405 |
|
|
}
|
1406 |
|
|
#endif
|
1407 |
|
|
else {
|
1408 |
|
|
// Invalid endpoint or not in configured state.
|
1409 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1410 |
|
|
}
|
1411 |
|
|
}
|
1412 |
|
|
} // Endpoing or device clear-feature
|
1413 |
|
|
|
1414 |
|
|
} else if (USB_DEVREQ_SET_FEATURE == req->request) {
|
1415 |
|
|
|
1416 |
|
|
// SET_FEATURE also operates in much the same way as
|
1417 |
|
|
// GET_STATUS
|
1418 |
|
|
if (USB_DEVREQ_RECIPIENT_DEVICE == recipient) {
|
1419 |
|
|
// The only valid feature that can be set is remote-wakeup,
|
1420 |
|
|
// which is not supported by this driver.
|
1421 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1422 |
|
|
|
1423 |
|
|
} else if (USB_DEVREQ_RECIPIENT_ENDPOINT == recipient) {
|
1424 |
|
|
|
1425 |
|
|
// Only the halt condition can be set, and no data should be transferred.
|
1426 |
|
|
// Halting endpoint 0 should probably be disallowed although the
|
1427 |
|
|
// standard does not explicitly say so.
|
1428 |
|
|
if ((0 != length) ||
|
1429 |
|
|
(USB_DEVREQ_FEATURE_ENDPOINT_HALT != req->value_lo) ||
|
1430 |
|
|
(USBS_STATE_CONFIGURED != (ep0.common.state & USBS_STATE_MASK))) {
|
1431 |
|
|
|
1432 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1433 |
|
|
|
1434 |
|
|
} else {
|
1435 |
|
|
int endpoint = req->index_lo;
|
1436 |
|
|
if (0) {
|
1437 |
|
|
}
|
1438 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
1439 |
|
|
else if ((USB_DEVREQ_INDEX_DIRECTION_IN | 3) == endpoint) {
|
1440 |
|
|
ep3_set_halted(&ep3.common, true);
|
1441 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1442 |
|
|
}
|
1443 |
|
|
#endif
|
1444 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
1445 |
|
|
else if ((USB_DEVREQ_INDEX_DIRECTION_OUT | 4) == endpoint) {
|
1446 |
|
|
ep4_set_halted(&ep4.common, true);
|
1447 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1448 |
|
|
}
|
1449 |
|
|
#endif
|
1450 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
1451 |
|
|
else if ((USB_DEVREQ_INDEX_DIRECTION_IN | 5) == endpoint) {
|
1452 |
|
|
ep5_set_halted(&ep5.common, true);
|
1453 |
|
|
result = USBS_CONTROL_RETURN_HANDLED;
|
1454 |
|
|
}
|
1455 |
|
|
#endif
|
1456 |
|
|
else {
|
1457 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1458 |
|
|
}
|
1459 |
|
|
}
|
1460 |
|
|
} // Endpoint or device set-feature
|
1461 |
|
|
}
|
1462 |
|
|
|
1463 |
|
|
// If the result has not been handled yet, pass it to
|
1464 |
|
|
// the installed callback function (if any).
|
1465 |
|
|
if (USBS_CONTROL_RETURN_UNKNOWN == result) {
|
1466 |
|
|
if ((usbs_control_return (*)(usbs_control_endpoint*, void*))0 != ep0.common.standard_control_fn) {
|
1467 |
|
|
result = (*ep0.common.standard_control_fn)(&ep0.common, ep0.common.standard_control_data);
|
1468 |
|
|
}
|
1469 |
|
|
}
|
1470 |
|
|
|
1471 |
|
|
// If the result has still not been handled, leave it to
|
1472 |
|
|
// the default implementation in the USB slave common place.
|
1473 |
|
|
if (USBS_CONTROL_RETURN_UNKNOWN == result) {
|
1474 |
|
|
result = usbs_handle_standard_control(&ep0.common);
|
1475 |
|
|
}
|
1476 |
|
|
} else {
|
1477 |
|
|
// The other three types of control message can be
|
1478 |
|
|
// handled by similar code.
|
1479 |
|
|
usbs_control_return (*callback_fn)(usbs_control_endpoint*, void*);
|
1480 |
|
|
void* callback_arg;
|
1481 |
|
|
|
1482 |
|
|
if (USB_DEVREQ_TYPE_CLASS == protocol) {
|
1483 |
|
|
callback_fn = ep0.common.class_control_fn;
|
1484 |
|
|
callback_arg = ep0.common.class_control_data;
|
1485 |
|
|
} else if (USB_DEVREQ_TYPE_VENDOR == protocol) {
|
1486 |
|
|
callback_fn = ep0.common.vendor_control_fn;
|
1487 |
|
|
callback_arg = ep0.common.vendor_control_data;
|
1488 |
|
|
} else {
|
1489 |
|
|
callback_fn = ep0.common.reserved_control_fn;
|
1490 |
|
|
callback_arg = ep0.common.reserved_control_data;
|
1491 |
|
|
}
|
1492 |
|
|
|
1493 |
|
|
if ((usbs_control_return (*)(usbs_control_endpoint*, void*)) 0 == callback_fn) {
|
1494 |
|
|
result = USBS_CONTROL_RETURN_STALL;
|
1495 |
|
|
} else {
|
1496 |
|
|
result = (*callback_fn)(&ep0.common, callback_arg);
|
1497 |
|
|
}
|
1498 |
|
|
}
|
1499 |
|
|
|
1500 |
|
|
if (USBS_CONTROL_RETURN_HANDLED != result) {
|
1501 |
|
|
// This control request cannot be handled. Generate a stall.
|
1502 |
|
|
// These stalls will be cleared automaticaly by the next
|
1503 |
|
|
// setup packet.
|
1504 |
|
|
*EP0_CR |= (EP0_CR_ISS | EP0_CR_OSS); FLUSH_IBUS();
|
1505 |
|
|
// Start a receive for the next control message
|
1506 |
|
|
ep0_start_rx(8);
|
1507 |
|
|
} else {
|
1508 |
|
|
// The control request has been handled. Is there any more
|
1509 |
|
|
// data to be transferred?
|
1510 |
|
|
if (0 == length) {
|
1511 |
|
|
// Definitely start a receive for another control message
|
1512 |
|
|
ep0_start_rx(8);
|
1513 |
|
|
|
1514 |
|
|
// This operation is complete so we need to ack. It
|
1515 |
|
|
// appears that the way to achieve this is to send a
|
1516 |
|
|
// zero-byte packet.
|
1517 |
|
|
ep0.tx_size = 0;
|
1518 |
|
|
ep0_start_tx();
|
1519 |
|
|
|
1520 |
|
|
} else {
|
1521 |
|
|
// Time to check the direction.
|
1522 |
|
|
|
1523 |
|
|
if (USB_DEVREQ_DIRECTION_OUT == direction) {
|
1524 |
|
|
// The host expects to send more data. Higher-level code
|
1525 |
|
|
// should have provided an appropriate buffer.
|
1526 |
|
|
CYG_ASSERT( (unsigned char*) 0 != ep0.common.buffer, "A receive buffer should have been provided");
|
1527 |
|
|
CYG_ASSERT( (usbs_control_return (*)(usbs_control_endpoint*, int))0 != ep0.common.complete_fn, \
|
1528 |
|
|
"A completion function should be provided for OUT control messages");
|
1529 |
|
|
CYG_ASSERT(length <= CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE, "Insufficient buffer space configured");
|
1530 |
|
|
|
1531 |
|
|
ep0.rx_expecting_data = true;
|
1532 |
|
|
ep0_start_rx(length);
|
1533 |
|
|
} else {
|
1534 |
|
|
// The host expects to be able to read some data.
|
1535 |
|
|
// This needs to go into a single contiguous
|
1536 |
|
|
// buffer, and then the transfer can be started.
|
1537 |
|
|
// Care has to be taken with various boundary conditions.
|
1538 |
|
|
int actual_length = ep0_fill_txbuffer();
|
1539 |
|
|
if (actual_length > length) {
|
1540 |
|
|
actual_length = length;
|
1541 |
|
|
}
|
1542 |
|
|
if ((length != actual_length) && (0 == (actual_length % CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE))) {
|
1543 |
|
|
ep0.tx_needs_zero_transfer = true;
|
1544 |
|
|
} else {
|
1545 |
|
|
ep0.tx_needs_zero_transfer = false;
|
1546 |
|
|
}
|
1547 |
|
|
ep0.tx_size = actual_length;
|
1548 |
|
|
ep0_start_tx();
|
1549 |
|
|
|
1550 |
|
|
// And make sure that there is another receive in progress
|
1551 |
|
|
// for the next setup packet.
|
1552 |
|
|
ep0_start_rx(8);
|
1553 |
|
|
}
|
1554 |
|
|
}
|
1555 |
|
|
} // Control message handled
|
1556 |
|
|
}
|
1557 |
|
|
}
|
1558 |
|
|
|
1559 |
|
|
// Endpoint 0 initialization also takes care of initializing generic bits
|
1560 |
|
|
// of the USB controller, for example letting through resume and suspend
|
1561 |
|
|
// interrupts and setting up the mailboxes. Also, it is necessary to
|
1562 |
|
|
// start a receive operation so that the first control message can
|
1563 |
|
|
// be processed. This code gets called during device driver initialization
|
1564 |
|
|
// and after a reset from the host.
|
1565 |
|
|
static void
|
1566 |
|
|
ep0_init(void)
|
1567 |
|
|
{
|
1568 |
|
|
// Reset the various fields in the ep0 structure.
|
1569 |
|
|
ep0.common.buffer = (unsigned char*) 0;
|
1570 |
|
|
ep0.common.buffer_size = 0;
|
1571 |
|
|
ep0.common.fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
|
1572 |
|
|
ep0.common.fill_data = (void*) 0;
|
1573 |
|
|
ep0.common.fill_index = 0;
|
1574 |
|
|
ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
|
1575 |
|
|
ep0.rx_expecting_data = false;
|
1576 |
|
|
ep0.tx_indicator_valid = false;
|
1577 |
|
|
ep0.rx_indicator_valid = false;
|
1578 |
|
|
ep0.tx_needs_zero_transfer = false;
|
1579 |
|
|
|
1580 |
|
|
#ifdef CYGIMP_DEVS_USB_UPD985XX_SERIALIZE_TRANSMITS
|
1581 |
|
|
tx_in_progress = false;
|
1582 |
|
|
ep0_tx_pending = false;
|
1583 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
1584 |
|
|
ep3_tx_pending = false;
|
1585 |
|
|
# endif
|
1586 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
1587 |
|
|
ep5_tx_pending = false;
|
1588 |
|
|
# endif
|
1589 |
|
|
#endif
|
1590 |
|
|
|
1591 |
|
|
// The general mode register. We do not have an address yet. The
|
1592 |
|
|
// SOFINTVL field needs to be set to its default value. The other
|
1593 |
|
|
// bits should be zero for now.
|
1594 |
|
|
*USBS_GMR = USBS_GMR_SOFINTVL_DEFAULT_VALUE; FLUSH_IBUS();
|
1595 |
|
|
|
1596 |
|
|
// The version register and the status registers are read-only.
|
1597 |
|
|
|
1598 |
|
|
// Interrupt masks. Endpoint 0 transmits and receives both have
|
1599 |
|
|
// to be detected, as do the control operations. There should
|
1600 |
|
|
// be no need to worry about full mailboxes or empty receive
|
1601 |
|
|
// pools. DMA errors might be of interest, but it is not clear
|
1602 |
|
|
// what to do about them since there does not appear to be
|
1603 |
|
|
// a way of figuring out which transfer is affected. Frame number
|
1604 |
|
|
// and addressing problems are ignored, there is nothing obvious
|
1605 |
|
|
// that can be done about these. The other endpoints have their
|
1606 |
|
|
// own initialization routines.
|
1607 |
|
|
//
|
1608 |
|
|
// Care has to be taken with reset interrupts. With some hardware
|
1609 |
|
|
// the usb lines may be left floating during initialization, so
|
1610 |
|
|
// the chip believes it sees continuous reset interrupts. There
|
1611 |
|
|
// also appear to be problems if the host does generate a real
|
1612 |
|
|
// reset signal, with interrupt storms lasting 10 or more
|
1613 |
|
|
// milliseconds and preventing any other activity from taking
|
1614 |
|
|
// place. What is done here is that reset interrupts are enabled
|
1615 |
|
|
// if in the initial POWERED state. When a reset is detected,
|
1616 |
|
|
// either a spurious one or a real reset from the host,
|
1617 |
|
|
// handle_reset() will move the target to DEFAULT state, call
|
1618 |
|
|
// ep0_init() again, and reset interrupts will be masked out.
|
1619 |
|
|
// When a real control request is received from the host we
|
1620 |
|
|
// know we have a good connection and the reset interrupt will
|
1621 |
|
|
// be unmasked in ep0_rx_dsr(), so further resets from the
|
1622 |
|
|
// host will be processed correctly. If the target is disconnected
|
1623 |
|
|
// then we may again get a spurious reset interrupt, so we end
|
1624 |
|
|
// up back in DEFAULT state and the reset interrupt would be
|
1625 |
|
|
// masked again.
|
1626 |
|
|
*USBS_IMR1 = IBUS_SWAP32(USBS_GSR1_GSR2 | USBS_GSR1_EP0TF | USBS_GSR1_EP0RF); FLUSH_IBUS();
|
1627 |
|
|
usbs_upd985xx_gsr1_mask = (USBS_GSR1_EP0TF | USBS_GSR1_EP0RF);
|
1628 |
|
|
if (USBS_STATE_DEFAULT == (ep0.common.state & USBS_STATE_MASK)) {
|
1629 |
|
|
*USBS_IMR2 = IBUS_SWAP32(USBS_GSR2_URSM | USBS_GSR2_USPD); FLUSH_IBUS();
|
1630 |
|
|
usbs_upd985xx_gsr2_mask = (USBS_GSR2_URSM | USBS_GSR2_USPD);
|
1631 |
|
|
} else {
|
1632 |
|
|
*USBS_IMR2 = IBUS_SWAP32(USBS_GSR2_URSM | USBS_GSR2_URST | USBS_GSR2_USPD); FLUSH_IBUS();
|
1633 |
|
|
usbs_upd985xx_gsr2_mask = (USBS_GSR2_URSM | USBS_GSR2_URST | USBS_GSR2_USPD);
|
1634 |
|
|
}
|
1635 |
|
|
|
1636 |
|
|
// Writing to the command register is a bad idea, because even
|
1637 |
|
|
// writing 0 constitutes a command. Similarly there is no point
|
1638 |
|
|
// in writing to the command address register.
|
1639 |
|
|
|
1640 |
|
|
// The endpoint status register is read-only.
|
1641 |
|
|
|
1642 |
|
|
// Set the rx pool information registers to disable alerts.
|
1643 |
|
|
*USBS_RP0IR = IBUS_SWAP32(USBS_RPxIR_AL_NONE); FLUSH_IBUS();
|
1644 |
|
|
*USBS_RP1IR = IBUS_SWAP32(USBS_RPxIR_AL_NONE); FLUSH_IBUS();
|
1645 |
|
|
*USBS_RP2IR = IBUS_SWAP32(USBS_RPxIR_AL_NONE); FLUSH_IBUS();
|
1646 |
|
|
|
1647 |
|
|
// The pool address registers are read-only. The documentation
|
1648 |
|
|
// that describes initialization says that these registers need to
|
1649 |
|
|
// be filled in, but that seems wrong: providing receive buffers
|
1650 |
|
|
// involves the command register. Presumably on early revisions it
|
1651 |
|
|
// was necessary to fill in the address register.
|
1652 |
|
|
|
1653 |
|
|
// Sort out the mailboxes.
|
1654 |
|
|
*USBS_TMSA = IBUS_SWAPPTR(TxMailbox, &(uncached->tx_mboxes[0])); FLUSH_IBUS();
|
1655 |
|
|
*USBS_TMBA = IBUS_SWAPPTR(TxMailbox, &(uncached->tx_mboxes[TXMBOX_COUNT])); FLUSH_IBUS();
|
1656 |
|
|
*USBS_RMSA = IBUS_SWAPPTR(RxMailbox, &(uncached->rx_mboxes[0])); FLUSH_IBUS();
|
1657 |
|
|
*USBS_RMBA = IBUS_SWAPPTR(RxMailbox, &(uncached->rx_mboxes[RXMBOX_COUNT])); FLUSH_IBUS();
|
1658 |
|
|
// It is not clear whether these registers actually need to be initialized.
|
1659 |
|
|
// The documentation suggests that they do, unlike TMWA and RMWA which
|
1660 |
|
|
// are taken care of by the hardware.
|
1661 |
|
|
#if 0
|
1662 |
|
|
*USBS_TMRA = IBUS_SWAPPTR(TxMailbox, &(uncached->tx_mboxes[0])); FLUSH_IBUS();
|
1663 |
|
|
*USBS_RMRA = IBUS_SWAPPTR(RxMailbox, &(uncached->rx_mboxes[0])); FLUSH_IBUS();
|
1664 |
|
|
#endif
|
1665 |
|
|
|
1666 |
|
|
// Start a receive operation for a control message.
|
1667 |
|
|
ep0_start_rx(8);
|
1668 |
|
|
|
1669 |
|
|
// The endpoint 0 control register. The control packet size is
|
1670 |
|
|
// configurable, with a default value of 8. Setting the
|
1671 |
|
|
// enabled bit here affects the state as seen by the host.
|
1672 |
|
|
*EP0_CR = IBUS_SWAP32(EP0_CR_EP0EN | CYGNUM_DEVS_USB_UPD985XX_EP0_PKTSIZE); FLUSH_IBUS();
|
1673 |
|
|
|
1674 |
|
|
// The other endpoint registers will be initialized by the appropriate
|
1675 |
|
|
// _init() functions. Note that those other _init() functions should
|
1676 |
|
|
// probably be called before the ep0-enabled bit is set.
|
1677 |
|
|
}
|
1678 |
|
|
|
1679 |
|
|
// ----------------------------------------------------------------------------
|
1680 |
|
|
// Endpoint 1 - isochronous transmits.
|
1681 |
|
|
#if 0
|
1682 |
|
|
// A real implementation
|
1683 |
|
|
#else
|
1684 |
|
|
static inline void
|
1685 |
|
|
ep1_init(void)
|
1686 |
|
|
{
|
1687 |
|
|
*EP1_CR = IBUS_SWAP32(0); // Clear EP1EN bit, thus disabling the endpoint
|
1688 |
|
|
FLUSH_IBUS();
|
1689 |
|
|
}
|
1690 |
|
|
#endif
|
1691 |
|
|
|
1692 |
|
|
// ----------------------------------------------------------------------------
|
1693 |
|
|
// Endpoint 2 - isochronous receives
|
1694 |
|
|
#if 0
|
1695 |
|
|
// A real implementation
|
1696 |
|
|
#else
|
1697 |
|
|
static inline void
|
1698 |
|
|
ep2_init(void)
|
1699 |
|
|
{
|
1700 |
|
|
*EP2_CR = IBUS_SWAP32(0); // Clear EP2EN bit, thus disabling the endpoint
|
1701 |
|
|
FLUSH_IBUS();
|
1702 |
|
|
}
|
1703 |
|
|
#endif
|
1704 |
|
|
|
1705 |
|
|
// ----------------------------------------------------------------------------
|
1706 |
|
|
// Generic transmit support. This is intended for use with both endpoints
|
1707 |
|
|
// 3 and 5. For now the endpoint 0 code is too different.
|
1708 |
|
|
|
1709 |
|
|
#if defined(CYGPKG_DEVS_USB_UPD985XX_EP3) || defined(CYGPKG_DEVS_USB_UPD985XX_EP5)
|
1710 |
|
|
|
1711 |
|
|
// A utility routine for completing a transfer. This takes care of the
|
1712 |
|
|
// callback as well as resetting the buffer.
|
1713 |
|
|
static void
|
1714 |
|
|
ep35_tx_complete(ep35_impl* ep, int result)
|
1715 |
|
|
{
|
1716 |
|
|
void (*complete_fn)(void*, int) = ep->common.complete_fn;
|
1717 |
|
|
void* complete_data = ep->common.complete_data;
|
1718 |
|
|
|
1719 |
|
|
ep->common.buffer = (unsigned char*) 0;
|
1720 |
|
|
ep->common.buffer_size = 0;
|
1721 |
|
|
ep->common.complete_fn = (void (*)(void*, int)) 0;
|
1722 |
|
|
ep->common.complete_data = (void*) 0;
|
1723 |
|
|
|
1724 |
|
|
if ((void (*)(void*, int))0 != complete_fn) {
|
1725 |
|
|
(*complete_fn)(complete_data, result);
|
1726 |
|
|
}
|
1727 |
|
|
}
|
1728 |
|
|
|
1729 |
|
|
static void
|
1730 |
|
|
ep35_start_tx(ep35_impl* ep)
|
1731 |
|
|
{
|
1732 |
|
|
// Is this endpoint currently stalled? If so then a size of 0 can
|
1733 |
|
|
// be used to block until the stall condition is clear, anything
|
1734 |
|
|
// else should result in an immediate callback.
|
1735 |
|
|
if (ep->common.halted) {
|
1736 |
|
|
if (0 != ep->common.buffer_size) {
|
1737 |
|
|
ep35_tx_complete(ep, -EAGAIN);
|
1738 |
|
|
}
|
1739 |
|
|
} else if (0 == ep->common.buffer_size) {
|
1740 |
|
|
// A check to see if the endpoint is halted. It isn't.
|
1741 |
|
|
ep35_tx_complete(ep, 0);
|
1742 |
|
|
} else {
|
1743 |
|
|
cyg_uint32 send_command;
|
1744 |
|
|
#if 0
|
1745 |
|
|
diag_printf("Tx: %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
1746 |
|
|
ep->common.buffer[0], ep->common.buffer[1], ep->common.buffer[2], ep->common.buffer[3],
|
1747 |
|
|
ep->common.buffer[4], ep->common.buffer[5], ep->common.buffer[6], ep->common.buffer[7]);
|
1748 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
1749 |
|
|
ep->common.buffer[8], ep->common.buffer[9], ep->common.buffer[10], ep->common.buffer[11],
|
1750 |
|
|
ep->common.buffer[12], ep->common.buffer[13], ep->common.buffer[14], ep->common.buffer[15]);
|
1751 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
1752 |
|
|
ep->common.buffer[16], ep->common.buffer[17], ep->common.buffer[18], ep->common.buffer[19],
|
1753 |
|
|
ep->common.buffer[20], ep->common.buffer[21], ep->common.buffer[22], ep->common.buffer[23]);
|
1754 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
1755 |
|
|
ep->common.buffer[24], ep->common.buffer[25], ep->common.buffer[26], ep->common.buffer[27],
|
1756 |
|
|
ep->common.buffer[28], ep->common.buffer[29], ep->common.buffer[30], ep->common.buffer[31]);
|
1757 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
1758 |
|
|
ep->common.buffer[32], ep->common.buffer[33], ep->common.buffer[34], ep->common.buffer[35],
|
1759 |
|
|
ep->common.buffer[36], ep->common.buffer[37], ep->common.buffer[38], ep->common.buffer[39]);
|
1760 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
1761 |
|
|
ep->common.buffer[40], ep->common.buffer[41], ep->common.buffer[42], ep->common.buffer[43],
|
1762 |
|
|
ep->common.buffer[44], ep->common.buffer[45], ep->common.buffer[46], ep->common.buffer[47]);
|
1763 |
|
|
#endif
|
1764 |
|
|
|
1765 |
|
|
// Update the static buffer descriptor.
|
1766 |
|
|
ep->tx_bufdesc->buffer = MIPS_TO_UNCACHED(ep->common.buffer);
|
1767 |
|
|
ep->tx_bufdesc->control = ep->common.buffer_size | TXBUFDESC_CTRL_LAST | TXBUFDESC_CTRL_BUFDESC_BUFDESC;
|
1768 |
|
|
|
1769 |
|
|
// Make sure that the entire transmit buffer is flushed to
|
1770 |
|
|
// memory.
|
1771 |
|
|
HAL_DCACHE_STORE(ep->common.buffer, ep->common.buffer_size);
|
1772 |
|
|
|
1773 |
|
|
// Issue the send command. It is known that no transmits are
|
1774 |
|
|
// in progress for this endpoint so the upper bound of 2
|
1775 |
|
|
// pending transmits can be ignored. The send command involves
|
1776 |
|
|
// writing to two registers in succession, so interrupts had
|
1777 |
|
|
// better be disabled while doing this.
|
1778 |
|
|
send_command = ep->send_command | ep->common.buffer_size;
|
1779 |
|
|
cyg_drv_isr_lock();
|
1780 |
|
|
while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
|
1781 |
|
|
// Do nothing: this situation should be short-lived.
|
1782 |
|
|
}
|
1783 |
|
|
*USBS_CA = IBUS_SWAPPTR(void, (void*)ep->tx_bufdesc); FLUSH_IBUS();
|
1784 |
|
|
*USBS_CMR = IBUS_SWAP32(send_command); FLUSH_IBUS();
|
1785 |
|
|
cyg_drv_isr_unlock();
|
1786 |
|
|
}
|
1787 |
|
|
}
|
1788 |
|
|
|
1789 |
|
|
// The stalled state is controlled by a single bit in the appropriate
|
1790 |
|
|
// control register. However there is a problem in that it is not
|
1791 |
|
|
// possible to abort a transmission that is already going out.
|
1792 |
|
|
// Furthermore there is no way of detecting whether or not any
|
1793 |
|
|
// packets have already gone out for this transfer: setting the halt
|
1794 |
|
|
// bit before any data has gone out is reasonably ok, doing so
|
1795 |
|
|
// in the middle of a transfer could be confusing.
|
1796 |
|
|
//
|
1797 |
|
|
// The approach taken here is to check whether or not there is a
|
1798 |
|
|
// current tx buffer. If not then the stall bit can be set immediately.
|
1799 |
|
|
// Otherwise the halted flag is set here, and it is left to the dsr
|
1800 |
|
|
// to set the stall bit when the transfer completes. This may not
|
1801 |
|
|
// be totally standards-compliant, but is probably the best solution
|
1802 |
|
|
// for now.
|
1803 |
|
|
static void
|
1804 |
|
|
ep35_set_halted(ep35_impl* ep, cyg_bool new_value)
|
1805 |
|
|
{
|
1806 |
|
|
if (ep->common.halted == new_value) {
|
1807 |
|
|
return;
|
1808 |
|
|
}
|
1809 |
|
|
|
1810 |
|
|
// Avoid race conditions with the DSR updating the buffer fields.
|
1811 |
|
|
cyg_drv_dsr_lock();
|
1812 |
|
|
|
1813 |
|
|
if (new_value ){
|
1814 |
|
|
// Set the halted flag to prevent further transmits, and if
|
1815 |
|
|
// there is no transmission currently in progress then set
|
1816 |
|
|
// the stalled bit immediately.
|
1817 |
|
|
ep->common.halted = true;
|
1818 |
|
|
if ((void*)0 == ep->common.buffer) {
|
1819 |
|
|
*(ep->cr) |= IBUS_SWAP32(EPtx_CR_SSx); FLUSH_IBUS();
|
1820 |
|
|
}
|
1821 |
|
|
} else {
|
1822 |
|
|
// Update the hardware (that may be a no-op if the stalled bit
|
1823 |
|
|
// never got set by the DSR), and clear the halted flag.
|
1824 |
|
|
*(ep->cr) &= IBUS_SWAP32(~EPtx_CR_SSx); FLUSH_IBUS();
|
1825 |
|
|
ep->common.halted = false;
|
1826 |
|
|
|
1827 |
|
|
// If there is a pending request to wait until the endpoint stall
|
1828 |
|
|
// condition is clear, inform higher-level code. This test may
|
1829 |
|
|
// give false positives but those would be harmless.
|
1830 |
|
|
if (0 == ep->common.buffer_size) {
|
1831 |
|
|
ep35_tx_complete(ep, 0);
|
1832 |
|
|
}
|
1833 |
|
|
}
|
1834 |
|
|
|
1835 |
|
|
cyg_drv_dsr_unlock();
|
1836 |
|
|
}
|
1837 |
|
|
|
1838 |
|
|
// An interrupt has occured related to endpoint 3 or 5 - i.e. the EP3TF
|
1839 |
|
|
// or EP5TF interrupts, nothing else seems especially relevant. It is
|
1840 |
|
|
// necessary to extract the appropriate send indicator from the tx
|
1841 |
|
|
// mailbox to determine whether or not the transmission was successful
|
1842 |
|
|
// and report status to higher-level code.
|
1843 |
|
|
static void
|
1844 |
|
|
ep35_dsr(ep35_impl* ep)
|
1845 |
|
|
{
|
1846 |
|
|
TxMailbox mbox;
|
1847 |
|
|
|
1848 |
|
|
// Extract the transmit indicator if that has not happened
|
1849 |
|
|
// already courtesy of another DSR.
|
1850 |
|
|
if (!ep->tx_indicator_valid) {
|
1851 |
|
|
drain_tx_mailbox();
|
1852 |
|
|
if (!ep->tx_indicator_valid) {
|
1853 |
|
|
// A transmit interrupt when there does not appear to be
|
1854 |
|
|
// any data?
|
1855 |
|
|
CYG_FAIL("ep35_dsr invoked when there is no valid tx indicator");
|
1856 |
|
|
return;
|
1857 |
|
|
}
|
1858 |
|
|
}
|
1859 |
|
|
mbox = ep->tx_indicator;
|
1860 |
|
|
ep->tx_indicator_valid = false;
|
1861 |
|
|
|
1862 |
|
|
#ifdef CYGIMP_DEVS_USB_UPD985XX_EP5_BULK
|
1863 |
|
|
// If emulating bulk transfers over the interrupt endpoint, and
|
1864 |
|
|
// the transfer is an exact multiple of 64 bytes, then an extra
|
1865 |
|
|
// zero-byte terminating packet needs to be sent. Care has to be
|
1866 |
|
|
// taken to do this only once.
|
1867 |
|
|
if ( (ep == &ep5) && (0 == (ep5.common.buffer_size % 64)) ) {
|
1868 |
|
|
static cyg_bool sending_zero = false;
|
1869 |
|
|
if (!sending_zero) {
|
1870 |
|
|
sending_zero = true;
|
1871 |
|
|
uncached->ep5_tx_bufdesc.buffer = uncached->ep0_tx_buffer;
|
1872 |
|
|
uncached->ep5_tx_bufdesc.control = 0 | TXBUFDESC_CTRL_LAST | TXBUFDESC_CTRL_BUFDESC_BUFDESC;
|
1873 |
|
|
cyg_drv_isr_lock();
|
1874 |
|
|
while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
|
1875 |
|
|
// Do nothing: this situation should be short-lived.
|
1876 |
|
|
}
|
1877 |
|
|
*USBS_CA = IBUS_SWAPPTR(void, (void*) &(uncached->ep5_tx_bufdesc)); FLUSH_IBUS();
|
1878 |
|
|
*USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_TX_EP5 | 0); FLUSH_IBUS();
|
1879 |
|
|
cyg_drv_isr_unlock();
|
1880 |
|
|
|
1881 |
|
|
// Do not complete the transfer. Instead completion has to
|
1882 |
|
|
// wait for another interrupt.
|
1883 |
|
|
return;
|
1884 |
|
|
} else {
|
1885 |
|
|
// This interrupt was for the zero-byte packet, so drop through
|
1886 |
|
|
sending_zero = false;
|
1887 |
|
|
}
|
1888 |
|
|
}
|
1889 |
|
|
#endif
|
1890 |
|
|
|
1891 |
|
|
// If the endpoint should be halted but there was a transmit
|
1892 |
|
|
// in progress, update the hardware now.
|
1893 |
|
|
if (ep->common.halted) {
|
1894 |
|
|
*(ep->cr) |= IBUS_SWAP32(EPtx_CR_SSx); FLUSH_IBUS();
|
1895 |
|
|
}
|
1896 |
|
|
|
1897 |
|
|
// Allow any blocked transmits to proceed.
|
1898 |
|
|
TX_UNLOCK();
|
1899 |
|
|
|
1900 |
|
|
if (0 != (mbox.status & TXMBOX_STATUS_IBUS_ERROR)) {
|
1901 |
|
|
// This appears to be the only type of error that can be
|
1902 |
|
|
// detected. Possibly the transmit should be retried here
|
1903 |
|
|
// rather than reported.
|
1904 |
|
|
ep35_tx_complete(ep, -EPIPE);
|
1905 |
|
|
} else {
|
1906 |
|
|
ep35_tx_complete(ep, ep->common.buffer_size);
|
1907 |
|
|
}
|
1908 |
|
|
}
|
1909 |
|
|
#endif // Endpoints 3 or 5
|
1910 |
|
|
|
1911 |
|
|
// ----------------------------------------------------------------------------
|
1912 |
|
|
// Endpoint 3 - bulk transmits.
|
1913 |
|
|
|
1914 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
1915 |
|
|
static void
|
1916 |
|
|
ep3_start_tx(usbs_tx_endpoint* endpoint)
|
1917 |
|
|
{
|
1918 |
|
|
CYG_ASSERT( endpoint == &ep3.common, "USB data transfer involves the wrong endpoint");
|
1919 |
|
|
CYG_ASSERT( ep3.common.buffer_size < (64 * 1024), "Specified transfer size too large for current implementation");
|
1920 |
|
|
if (TX_TRY_LOCK(&ep3_tx_pending)) {
|
1921 |
|
|
ep35_start_tx(&ep3);
|
1922 |
|
|
}
|
1923 |
|
|
}
|
1924 |
|
|
|
1925 |
|
|
static void
|
1926 |
|
|
ep3_set_halted(usbs_tx_endpoint* endpoint, cyg_bool new_value)
|
1927 |
|
|
{
|
1928 |
|
|
CYG_ASSERT(endpoint = &ep3.common, "USB set-stall operation involves the wrong endpoint");
|
1929 |
|
|
ep35_set_halted(&ep3, new_value);
|
1930 |
|
|
}
|
1931 |
|
|
|
1932 |
|
|
// Initialization. This gets called during the device driver
|
1933 |
|
|
// initialization and after a reset. The main job is to initialize the
|
1934 |
|
|
// EP3 control register, but the relevant bits of the interrupt mask
|
1935 |
|
|
// are set here as well. The tx mailboxes are shared with other
|
1936 |
|
|
// endpoints, so that is handled by ep0_init(). Any traffic that
|
1937 |
|
|
// happened before the reset needs to be cleaned up.
|
1938 |
|
|
static void
|
1939 |
|
|
ep3_init(void)
|
1940 |
|
|
{
|
1941 |
|
|
// Assume 64 byte packets, terminate transfers with a zero-byte packet
|
1942 |
|
|
// if necessary since this endpoint is used for bulk transfers.
|
1943 |
|
|
*EP3_CR = IBUS_SWAP32(EP3_CR_EP3EN | EP3_CR_TM3_SZLP | 64); FLUSH_IBUS();
|
1944 |
|
|
*USBS_IMR1 |= IBUS_SWAP32(USBS_GSR1_EP3TF); FLUSH_IBUS();
|
1945 |
|
|
usbs_upd985xx_gsr1_mask |= IBUS_SWAP32(USBS_GSR1_EP3TF);
|
1946 |
|
|
ep3.common.halted = false;
|
1947 |
|
|
ep3.tx_indicator_valid = false;
|
1948 |
|
|
ep3.tx_bufdesc = &(uncached->ep3_tx_bufdesc);
|
1949 |
|
|
ep35_tx_complete(&ep3, -EPIPE);
|
1950 |
|
|
}
|
1951 |
|
|
#else
|
1952 |
|
|
static inline void
|
1953 |
|
|
ep3_init(void)
|
1954 |
|
|
{
|
1955 |
|
|
*EP3_CR = 0; // Clear EP3EN bit, thus disabling the endpoint
|
1956 |
|
|
FLUSH_IBUS();
|
1957 |
|
|
}
|
1958 |
|
|
# endif // Endpoint 3 configured in
|
1959 |
|
|
|
1960 |
|
|
// ----------------------------------------------------------------------------
|
1961 |
|
|
// Repeat for endpoint 5
|
1962 |
|
|
# ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
1963 |
|
|
|
1964 |
|
|
static void
|
1965 |
|
|
ep5_start_tx(usbs_tx_endpoint* endpoint)
|
1966 |
|
|
{
|
1967 |
|
|
CYG_ASSERT( endpoint == &ep5.common, "USB data transfer involves the wrong endpoint");
|
1968 |
|
|
#ifdef CYGIMP_DEVS_USB_UPD985XX_EP5_BULK
|
1969 |
|
|
CYG_ASSERT( ep5.common.buffer_size < (64 * 1024), "Specified transfer size too large for current implementation");
|
1970 |
|
|
#else
|
1971 |
|
|
CYG_ASSERT( ep5.common.buffer_size <= 64, "Specified transfer size too large for current implementation");
|
1972 |
|
|
#endif
|
1973 |
|
|
if (TX_TRY_LOCK(&ep5_tx_pending)) {
|
1974 |
|
|
ep35_start_tx(&ep5);
|
1975 |
|
|
}
|
1976 |
|
|
}
|
1977 |
|
|
|
1978 |
|
|
static void
|
1979 |
|
|
ep5_set_halted(usbs_tx_endpoint* endpoint, cyg_bool new_value)
|
1980 |
|
|
{
|
1981 |
|
|
CYG_ASSERT(endpoint = &ep5.common, "USB set-stall operation involves the wrong endpoint");
|
1982 |
|
|
ep35_set_halted(&ep5, new_value);
|
1983 |
|
|
}
|
1984 |
|
|
|
1985 |
|
|
// Initialization. This gets called during the device driver
|
1986 |
|
|
// initialization and after a reset. The main job is to initialize the
|
1987 |
|
|
// EP5 control register, but the relevant bits of the interrupt mask
|
1988 |
|
|
// are set here as well. The tx mailboxes are shared with other
|
1989 |
|
|
// endpoints, so that is handled by ep0_init(). Any traffic that
|
1990 |
|
|
// happened before the reset needs to be cleaned up.
|
1991 |
|
|
static void
|
1992 |
|
|
ep5_init(void)
|
1993 |
|
|
{
|
1994 |
|
|
// Assume 64 byte packets, terminate transfers with a zero-byte packet
|
1995 |
|
|
// if necessary since this endpoint is used for bulk transfers.
|
1996 |
|
|
*EP5_CR = IBUS_SWAP32(EP5_CR_EP5EN | 64); FLUSH_IBUS();
|
1997 |
|
|
*USBS_IMR1 |= IBUS_SWAP32(USBS_GSR1_EP5TF); FLUSH_IBUS();
|
1998 |
|
|
usbs_upd985xx_gsr1_mask |= IBUS_SWAP32(USBS_GSR1_EP5TF);
|
1999 |
|
|
ep5.common.halted = false;
|
2000 |
|
|
ep5.tx_indicator_valid = false;
|
2001 |
|
|
ep5.tx_bufdesc = &(uncached->ep5_tx_bufdesc);
|
2002 |
|
|
ep35_tx_complete(&ep5, -EPIPE);
|
2003 |
|
|
}
|
2004 |
|
|
#else
|
2005 |
|
|
static inline void
|
2006 |
|
|
ep5_init(void)
|
2007 |
|
|
{
|
2008 |
|
|
*EP5_CR = 0; // Clear EP5EN bit, thus disabling the endpoint
|
2009 |
|
|
FLUSH_IBUS();
|
2010 |
|
|
}
|
2011 |
|
|
#endif // Endpoint 5 configured in
|
2012 |
|
|
|
2013 |
|
|
|
2014 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
2015 |
|
|
// ----------------------------------------------------------------------------
|
2016 |
|
|
// Endpoint 4 - bulk receives.
|
2017 |
|
|
//
|
2018 |
|
|
// Bulk receives are mostly straightforward, but the cache does involve
|
2019 |
|
|
// a complication. The assumption is that the receive buffer will be in
|
2020 |
|
|
// cached memory, and is unlikely to be cacheline-aligned. Clearly the bulk
|
2021 |
|
|
// of the buffer has to be invalidated. However the receive buffer may share
|
2022 |
|
|
// some cache lines with other data at the head and tail, and invalidating
|
2023 |
|
|
// those would be wrong.
|
2024 |
|
|
//
|
2025 |
|
|
// The solution here is to split up a receive in to up to three areas,
|
2026 |
|
|
// head, main, and tail, where the head and tail are statically
|
2027 |
|
|
// allocated in uncached memory. Any one or two of these areas may be
|
2028 |
|
|
// unused, depending on alignment and transfer size. The main area
|
2029 |
|
|
// corresponds to the central section of the supplied receive buffer,
|
2030 |
|
|
// will be cacheline-aligned, and invalidated at the start of a receive.
|
2031 |
|
|
// Data will be copied from the head and tail areas into the receive
|
2032 |
|
|
// buffer by the dsr on completion of the transfer.
|
2033 |
|
|
//
|
2034 |
|
|
// There are additional complications caused by the hardware's need for
|
2035 |
|
|
// linked buffers.
|
2036 |
|
|
|
2037 |
|
|
static void
|
2038 |
|
|
ep4_rx_complete(int result)
|
2039 |
|
|
{
|
2040 |
|
|
void (*complete_fn)(void*, int) = ep4.common.complete_fn;
|
2041 |
|
|
void* complete_data = ep4.common.complete_data;
|
2042 |
|
|
|
2043 |
|
|
#if 0
|
2044 |
|
|
*EP4_CR = IBUS_SWAP32(EP4_CR_EP4EN | EP4_CR_RM4_ASSEMBLE | EP4_CR_NAK4 | 64); FLUSH_IBUS();
|
2045 |
|
|
#endif
|
2046 |
|
|
|
2047 |
|
|
#if 0
|
2048 |
|
|
if (result > 0) {
|
2049 |
|
|
diag_printf("Rx: %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
2050 |
|
|
ep4.common.buffer[0], ep4.common.buffer[1], ep4.common.buffer[2], ep4.common.buffer[3],
|
2051 |
|
|
ep4.common.buffer[4], ep4.common.buffer[5], ep4.common.buffer[6], ep4.common.buffer[7]);
|
2052 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
2053 |
|
|
ep4.common.buffer[8], ep4.common.buffer[9], ep4.common.buffer[10], ep4.common.buffer[11],
|
2054 |
|
|
ep4.common.buffer[12], ep4.common.buffer[13], ep4.common.buffer[14], ep4.common.buffer[15]);
|
2055 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
2056 |
|
|
ep4.common.buffer[16], ep4.common.buffer[17], ep4.common.buffer[18], ep4.common.buffer[19],
|
2057 |
|
|
ep4.common.buffer[20], ep4.common.buffer[21], ep4.common.buffer[22], ep4.common.buffer[23]);
|
2058 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
2059 |
|
|
ep4.common.buffer[24], ep4.common.buffer[25], ep4.common.buffer[26], ep4.common.buffer[27],
|
2060 |
|
|
ep4.common.buffer[28], ep4.common.buffer[29], ep4.common.buffer[30], ep4.common.buffer[31]);
|
2061 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
2062 |
|
|
ep4.common.buffer[32], ep4.common.buffer[33], ep4.common.buffer[34], ep4.common.buffer[35],
|
2063 |
|
|
ep4.common.buffer[36], ep4.common.buffer[37], ep4.common.buffer[38], ep4.common.buffer[39]);
|
2064 |
|
|
diag_printf(" %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
2065 |
|
|
ep4.common.buffer[40], ep4.common.buffer[41], ep4.common.buffer[42], ep4.common.buffer[43],
|
2066 |
|
|
ep4.common.buffer[44], ep4.common.buffer[45], ep4.common.buffer[46], ep4.common.buffer[47]);
|
2067 |
|
|
}
|
2068 |
|
|
#endif
|
2069 |
|
|
|
2070 |
|
|
ep4.common.buffer = (unsigned char*) 0;
|
2071 |
|
|
ep4.common.buffer_size = 0;
|
2072 |
|
|
ep4.common.complete_fn = (void (*)(void*, int)) 0;
|
2073 |
|
|
ep4.common.complete_data = (void*) 0;
|
2074 |
|
|
|
2075 |
|
|
if ((void (*)(void*, int))0 != complete_fn) {
|
2076 |
|
|
(*complete_fn)(complete_data, result);
|
2077 |
|
|
}
|
2078 |
|
|
}
|
2079 |
|
|
|
2080 |
|
|
static void
|
2081 |
|
|
ep4_start_rx(usbs_rx_endpoint* ep)
|
2082 |
|
|
{
|
2083 |
|
|
CYG_ASSERT( ep == &ep4.common, "USB data transfer involves the wrong endpoint");
|
2084 |
|
|
|
2085 |
|
|
// Is this endpoint currently stalled? If so then a size of 0 can
|
2086 |
|
|
// be used to block until the stall condition is clear, anything
|
2087 |
|
|
// else should result in an immediate callback.
|
2088 |
|
|
if (ep4.common.halted) {
|
2089 |
|
|
if (0 != ep4.common.buffer_size) {
|
2090 |
|
|
ep4_rx_complete(-EAGAIN);
|
2091 |
|
|
}
|
2092 |
|
|
} else if (0 == ep4.common.buffer_size) {
|
2093 |
|
|
// A check to see if the endpoint is halted. It isn't.
|
2094 |
|
|
ep4_rx_complete(0);
|
2095 |
|
|
} else {
|
2096 |
|
|
|
2097 |
|
|
// Time to work out how much data should go into the uncached
|
2098 |
|
|
// head and tail buffers, how much can go directly into the
|
2099 |
|
|
// receive buffer, how much memory needs to be invalidated, and so on.
|
2100 |
|
|
cyg_uint32 buffer_arith;
|
2101 |
|
|
|
2102 |
|
|
// Where to start filling in buffer descriptors.
|
2103 |
|
|
cyg_uint32 first_bufdesc;
|
2104 |
|
|
|
2105 |
|
|
// And the current buffer descriptor.
|
2106 |
|
|
cyg_uint32 current_bufdesc;
|
2107 |
|
|
|
2108 |
|
|
CYG_ASSERT( ep4.common.buffer_size < (64 * 1024), "Specified transfer size too large for current implementation");
|
2109 |
|
|
|
2110 |
|
|
// If there has not been a receive operation, tail_index
|
2111 |
|
|
// will still be set to -1. Otherwise it will be somewhere
|
2112 |
|
|
// between 1 and 3, or between 5 and 7, depending on
|
2113 |
|
|
// whether the previous receive operation used the
|
2114 |
|
|
// first four buffer descriptors or the last four.
|
2115 |
|
|
if (ep4.tail_index < 4) {
|
2116 |
|
|
first_bufdesc = 4;
|
2117 |
|
|
} else {
|
2118 |
|
|
first_bufdesc = 0;
|
2119 |
|
|
}
|
2120 |
|
|
current_bufdesc = first_bufdesc;
|
2121 |
|
|
|
2122 |
|
|
// Arithmetic, especially remainder operators, requires
|
2123 |
|
|
// integers rather than a pointer.
|
2124 |
|
|
buffer_arith = (cyg_uint32) ep4.common.buffer;
|
2125 |
|
|
|
2126 |
|
|
// The size of the "head" area. This involves up to
|
2127 |
|
|
// (cacheline-1) bytes, so that the main receive buffer
|
2128 |
|
|
// is suitably aligned.
|
2129 |
|
|
ep4.head_size = ((buffer_arith + HAL_DCACHE_LINE_SIZE - 1) & ~(HAL_DCACHE_LINE_SIZE - 1)) - buffer_arith;
|
2130 |
|
|
if (ep4.head_size > ep4.common.buffer_size) {
|
2131 |
|
|
ep4.head_size = ep4.common.buffer_size;
|
2132 |
|
|
}
|
2133 |
|
|
if (0 < ep4.head_size) {
|
2134 |
|
|
// It is necessary to receive some data into the uncached head area.
|
2135 |
|
|
uncached->ep4_rx_bufdescs[current_bufdesc].buffer = uncached->ep4_head;
|
2136 |
|
|
uncached->ep4_rx_bufdescs[current_bufdesc].control = RXBUFDESC_CTRL_BUFDESC_BUFDESC | ep4.head_size;
|
2137 |
|
|
current_bufdesc++;
|
2138 |
|
|
}
|
2139 |
|
|
|
2140 |
|
|
// Now for the size of the main area. This is the rest of the
|
2141 |
|
|
// transfer size, minus the tail area.
|
2142 |
|
|
ep4.direct_size = ep4.common.buffer_size - ep4.head_size;
|
2143 |
|
|
ep4.direct_size &= ~(HAL_DCACHE_LINE_SIZE - 1);
|
2144 |
|
|
if (ep4.direct_size > 0) {
|
2145 |
|
|
uncached->ep4_rx_bufdescs[current_bufdesc].buffer = MIPS_TO_UNCACHED(ep4.common.buffer + ep4.head_size);
|
2146 |
|
|
uncached->ep4_rx_bufdescs[current_bufdesc].control = RXBUFDESC_CTRL_BUFDESC_BUFDESC | ep4.direct_size;
|
2147 |
|
|
current_bufdesc++;
|
2148 |
|
|
HAL_DCACHE_INVALIDATE(ep4.common.buffer + ep4.head_size, ep4.direct_size);
|
2149 |
|
|
}
|
2150 |
|
|
|
2151 |
|
|
// And the size of the tail. This is the transfer size minus what we have accumulated so far.
|
2152 |
|
|
ep4.tail_size = ep4.common.buffer_size - (ep4.head_size + ep4.direct_size);
|
2153 |
|
|
if (ep4.tail_size > 0) {
|
2154 |
|
|
uncached->ep4_rx_bufdescs[current_bufdesc].buffer = uncached->ep4_tail;
|
2155 |
|
|
uncached->ep4_rx_bufdescs[current_bufdesc].control = RXBUFDESC_CTRL_BUFDESC_BUFDESC | ep4.tail_size;
|
2156 |
|
|
current_bufdesc++;
|
2157 |
|
|
}
|
2158 |
|
|
|
2159 |
|
|
// Or the LAST bit into the last of these buffer descriptors.
|
2160 |
|
|
uncached->ep4_rx_bufdescs[current_bufdesc - 1].control |= RXBUFDESC_CTRL_LAST;
|
2161 |
|
|
|
2162 |
|
|
// Turn the current one into a link descriptor.
|
2163 |
|
|
uncached->ep4_rx_bufdescs[current_bufdesc].control = RXBUFDESC_CTRL_BUFDESC_LINK;
|
2164 |
|
|
uncached->ep4_rx_bufdescs[current_bufdesc].buffer = 0;
|
2165 |
|
|
|
2166 |
|
|
// The buffer descriptors have now been sorted out. Time to
|
2167 |
|
|
// add this receive buffer to the pool. Atomicity becomes
|
2168 |
|
|
// important for some of these steps.
|
2169 |
|
|
cyg_drv_isr_lock();
|
2170 |
|
|
|
2171 |
|
|
// Update the link pointer used for the last receive operation
|
2172 |
|
|
// to point at the new set of buffer descriptors.
|
2173 |
|
|
if (-1 != ep4.tail_index) {
|
2174 |
|
|
uncached->ep4_rx_bufdescs[ep4.tail_index].buffer = (void*) &(uncached->ep4_rx_bufdescs[first_bufdesc]);
|
2175 |
|
|
}
|
2176 |
|
|
|
2177 |
|
|
// Keep track of the link pointer used for the last receive
|
2178 |
|
|
// operation.
|
2179 |
|
|
ep4.tail_index = current_bufdesc;
|
2180 |
|
|
|
2181 |
|
|
while (0 != (*USBS_CMR & IBUS_SWAP32(USBS_CMR_BUSY))) {
|
2182 |
|
|
// Do nothing: this situation should be short-lived.
|
2183 |
|
|
}
|
2184 |
|
|
*USBS_CA = IBUS_SWAPPTR(void, (void*)&(uncached->ep4_rx_bufdescs[first_bufdesc])); FLUSH_IBUS();
|
2185 |
|
|
*USBS_CMR = IBUS_SWAP32(USBS_CMR_COMMAND_ADD_POOL2 | 1); FLUSH_IBUS();
|
2186 |
|
|
#if 0
|
2187 |
|
|
*EP4_CR = IBUS_SWAP32(EP4_CR_EP4EN | EP4_CR_RM4_ASSEMBLE | 64); FLUSH_IBUS();
|
2188 |
|
|
#endif
|
2189 |
|
|
cyg_drv_isr_unlock();
|
2190 |
|
|
}
|
2191 |
|
|
}
|
2192 |
|
|
|
2193 |
|
|
// The stalled state is controlled by a single bit in the appropriate
|
2194 |
|
|
// control register. When it comes to ongoing receives, the reasoning
|
2195 |
|
|
// here is much the same as for ep3_set_halted(). Arguably this is not
|
2196 |
|
|
// quite right. set_halted() is most likely to be called in response
|
2197 |
|
|
// to a control request from the host, and the host is unlikely to
|
2198 |
|
|
// transmit any data at the same time as making this request. Hence the
|
2199 |
|
|
// host will see the wrong behaviour: it can still make one transfer
|
2200 |
|
|
// after asking for the stalled bit to be set. Since there does not
|
2201 |
|
|
// appear to be any way to cancel a supplied receive, this behaviour
|
2202 |
|
|
// still seems the most sensible.
|
2203 |
|
|
static void
|
2204 |
|
|
ep4_set_halted(usbs_rx_endpoint* ep, cyg_bool new_state)
|
2205 |
|
|
{
|
2206 |
|
|
CYG_ASSERT(ep == &ep4.common, "USB set-stall operation involves the wrong endpoint");
|
2207 |
|
|
|
2208 |
|
|
if (ep4.common.halted == new_state) {
|
2209 |
|
|
return;
|
2210 |
|
|
}
|
2211 |
|
|
|
2212 |
|
|
// Avoid race conditions with the DSR updating the buffer fields.
|
2213 |
|
|
cyg_drv_dsr_lock();
|
2214 |
|
|
|
2215 |
|
|
if (new_state){
|
2216 |
|
|
// Set the halted flag to prevent further transmits, and if
|
2217 |
|
|
// there is no receive currently in progress then set
|
2218 |
|
|
// the stalled bit immediately.
|
2219 |
|
|
ep4.common.halted = true;
|
2220 |
|
|
if ((void*)0 == ep4.common.buffer) {
|
2221 |
|
|
*EP4_CR |= IBUS_SWAP32(EP4_CR_SS4); FLUSH_IBUS();
|
2222 |
|
|
}
|
2223 |
|
|
} else {
|
2224 |
|
|
// Update the hardware (that may be a no-op if the stalled bit
|
2225 |
|
|
// never got set by the DSR), and clear the halted flag.
|
2226 |
|
|
*EP4_CR &= IBUS_SWAP32(~EP4_CR_SS4); FLUSH_IBUS();
|
2227 |
|
|
ep4.common.halted = false;
|
2228 |
|
|
|
2229 |
|
|
// If there is a pending request to wait until the endpoint stall
|
2230 |
|
|
// condition is clear, inform higher-level code. This test may
|
2231 |
|
|
// give false positives but those would be harmless.
|
2232 |
|
|
if (0 == ep4.common.buffer_size) {
|
2233 |
|
|
ep4_rx_complete(0);
|
2234 |
|
|
}
|
2235 |
|
|
}
|
2236 |
|
|
|
2237 |
|
|
cyg_drv_dsr_unlock();
|
2238 |
|
|
}
|
2239 |
|
|
|
2240 |
|
|
// An interrupt has occured related to endpoint 4 - i.e. the EP4RF
|
2241 |
|
|
// interrupt, nothing else seems especially relevant. The ISR will
|
2242 |
|
|
// have set the NAK bit in the control register. It is necessary to
|
2243 |
|
|
// extract the appropriate receive indicator from the rx mailbox to
|
2244 |
|
|
// determine whether or not the transmission was successful and how
|
2245 |
|
|
// much data was actually received, clear the interrupt bit, and
|
2246 |
|
|
// report status to higher-level code.
|
2247 |
|
|
static void
|
2248 |
|
|
ep4_dsr(void)
|
2249 |
|
|
{
|
2250 |
|
|
// Extract the transmit indicator if that has not happened
|
2251 |
|
|
// already courtesy of another DSR.
|
2252 |
|
|
if (!ep4.rx_indicator_valid) {
|
2253 |
|
|
drain_rx_mailbox();
|
2254 |
|
|
if (!ep4.rx_indicator_valid) {
|
2255 |
|
|
// A receive interrupt when there does not appear to be
|
2256 |
|
|
// any data? It appears that this can happen when there
|
2257 |
|
|
// are error conditions.
|
2258 |
|
|
#if 1
|
2259 |
|
|
CYG_FAIL("EP4_DSR invoked when there is no valid rx indicator");
|
2260 |
|
|
#endif
|
2261 |
|
|
return;
|
2262 |
|
|
}
|
2263 |
|
|
}
|
2264 |
|
|
ep4.rx_indicator_valid = false;
|
2265 |
|
|
|
2266 |
|
|
// If the endpoint should be halted but there was a transmit
|
2267 |
|
|
// in progress, update the hardware now.
|
2268 |
|
|
if (ep4.common.halted) {
|
2269 |
|
|
*EP4_CR |= IBUS_SWAP32(EP4_CR_SS4); FLUSH_IBUS();
|
2270 |
|
|
}
|
2271 |
|
|
if (0 != (ep4.rx_indicator.status & (RXMBOX_STATUS_IBUS_ERROR | 0))) {
|
2272 |
|
|
// This appears to be the only type of error that can be
|
2273 |
|
|
// detected. Everything else gets retried by the hardware,
|
2274 |
|
|
// except when using the isochronous endpoint.
|
2275 |
|
|
ep4_rx_complete(-EPIPE);
|
2276 |
|
|
} else {
|
2277 |
|
|
cyg_uint32 actual_size = ep4.rx_indicator.status & RXMBOX_STATUS_SIZE_MASK;
|
2278 |
|
|
|
2279 |
|
|
// Either the transfer size must match the requested size, or the
|
2280 |
|
|
// supplied buffer should have been aligned to cacheline boundaries.
|
2281 |
|
|
// Anything else risks leaving the receive pool in a confused
|
2282 |
|
|
// state and there is no way of cleaning things up.
|
2283 |
|
|
CYG_ASSERT((actual_size == ep4.common.buffer_size) || ((0 == ep4.head_size) && (0 == ep4.tail_size)), \
|
2284 |
|
|
"Buffers should be cacheline aligned if the protocol involves partial transfers");
|
2285 |
|
|
|
2286 |
|
|
// If there was some data in the head, move it from uncached
|
2287 |
|
|
// to cached. Ditto for tail. Note that these copies may be
|
2288 |
|
|
// for data that has not actually been transferred if the
|
2289 |
|
|
// actual transfer is less than expected, but overwriting bits
|
2290 |
|
|
// of the receive buffer in such circumstances should be
|
2291 |
|
|
// harmless.
|
2292 |
|
|
if (ep4.head_size > 0) {
|
2293 |
|
|
memcpy(ep4.common.buffer, uncached->ep4_head, ep4.head_size);
|
2294 |
|
|
}
|
2295 |
|
|
if (ep4.tail_size > 0) {
|
2296 |
|
|
memcpy(ep4.common.buffer + ep4.head_size + ep4.direct_size, uncached->ep4_tail, ep4.tail_size);
|
2297 |
|
|
}
|
2298 |
|
|
ep4_rx_complete(actual_size);
|
2299 |
|
|
}
|
2300 |
|
|
}
|
2301 |
|
|
|
2302 |
|
|
// Initialization. This gets called during the device driver
|
2303 |
|
|
// initialization and after a reset. The main job is to initialize the
|
2304 |
|
|
// EP4 control register, but the relevant bits of the interrupt mask
|
2305 |
|
|
// are set here as well. The rx mailboxes are shared with other
|
2306 |
|
|
// endpoints, so that is handled by ep0_init(). Any traffic that
|
2307 |
|
|
// happened before the reset needs to be cleaned up.
|
2308 |
|
|
static void
|
2309 |
|
|
ep4_init(void)
|
2310 |
|
|
{
|
2311 |
|
|
// Assume 64 byte packets, and use assemble mode so that we get a
|
2312 |
|
|
// single rx indication per transfer. In practice the buffer
|
2313 |
|
|
// directory will only ever contain one entry so there should be
|
2314 |
|
|
// no discernible difference between normal, assemble, or separate
|
2315 |
|
|
// mode.
|
2316 |
|
|
#if 0
|
2317 |
|
|
*EP4_CR = IBUS_SWAP32(EP4_CR_EP4EN | EP4_CR_RM4_ASSEMBLE | EP4_CR_NAK4 | 64); FLUSH_IBUS();
|
2318 |
|
|
#else
|
2319 |
|
|
*EP4_CR = IBUS_SWAP32(EP4_CR_EP4EN | EP4_CR_RM4_ASSEMBLE | 64); FLUSH_IBUS();
|
2320 |
|
|
#endif
|
2321 |
|
|
|
2322 |
|
|
*USBS_IMR1 |= IBUS_SWAP32(USBS_GSR1_EP4RF); FLUSH_IBUS();
|
2323 |
|
|
usbs_upd985xx_gsr1_mask |= USBS_GSR1_EP4RF;
|
2324 |
|
|
ep4.common.halted = false;
|
2325 |
|
|
ep4.rx_indicator_valid = false;
|
2326 |
|
|
ep4.tail_index = -1;
|
2327 |
|
|
ep4_rx_complete(-EPIPE);
|
2328 |
|
|
}
|
2329 |
|
|
#else
|
2330 |
|
|
static inline void
|
2331 |
|
|
ep4_init(void)
|
2332 |
|
|
{
|
2333 |
|
|
*EP4_CR = 0; // Clear EP4EN bit, thus disabling the endpoint
|
2334 |
|
|
FLUSH_IBUS();
|
2335 |
|
|
}
|
2336 |
|
|
#endif // Endpoint 4 configured in
|
2337 |
|
|
|
2338 |
|
|
// ----------------------------------------------------------------------------
|
2339 |
|
|
// Endpoint 6 - interrupt receives
|
2340 |
|
|
#if 0
|
2341 |
|
|
// A real implementation
|
2342 |
|
|
#else
|
2343 |
|
|
static inline void
|
2344 |
|
|
ep6_init(void)
|
2345 |
|
|
{
|
2346 |
|
|
*EP6_CR = 0; // Clear EP6EN bit, thus disabling the endpoint
|
2347 |
|
|
FLUSH_IBUS();
|
2348 |
|
|
}
|
2349 |
|
|
#endif
|
2350 |
|
|
|
2351 |
|
|
// ----------------------------------------------------------------------------
|
2352 |
|
|
// Make sure the hardware is in a known state by completely resetting
|
2353 |
|
|
// the USB controller. This gets called during device driver
|
2354 |
|
|
// initialization, and again whenever the host issues a reset signal.
|
2355 |
|
|
// The previous state is unknown. Even during eCos initialization
|
2356 |
|
|
// RedBoot may have involved USB I/O, or some POST code may have
|
2357 |
|
|
// performed loopback tests. The various endpoint init routines will
|
2358 |
|
|
// also perform software resets as appropriate.
|
2359 |
|
|
|
2360 |
|
|
static void
|
2361 |
|
|
usbs_upd985xx_handle_reset(void)
|
2362 |
|
|
{
|
2363 |
|
|
// Reset the USB hardware. This involves poking the warm reset
|
2364 |
|
|
// register and then polling the matching status register. It is
|
2365 |
|
|
// assumed that this poll will take a short time, and in practice
|
2366 |
|
|
// the loop appears to terminate immediately.
|
2367 |
|
|
*S_WRCR = S_WRCR_USBWR; FLUSH_IBUS();
|
2368 |
|
|
while (0 == (*S_WRSR & S_WRCR_USBWR)) {
|
2369 |
|
|
// Do nothing.
|
2370 |
|
|
}
|
2371 |
|
|
|
2372 |
|
|
// Get all the endpoints into a known state - for disabled
|
2373 |
|
|
// endpoints these init calls are inlined and just disable the
|
2374 |
|
|
// relevant hardware.
|
2375 |
|
|
ep0_init();
|
2376 |
|
|
ep1_init();
|
2377 |
|
|
ep2_init();
|
2378 |
|
|
ep3_init();
|
2379 |
|
|
ep4_init();
|
2380 |
|
|
ep5_init();
|
2381 |
|
|
ep6_init();
|
2382 |
|
|
}
|
2383 |
|
|
|
2384 |
|
|
// ----------------------------------------------------------------------------
|
2385 |
|
|
// Start(). This is typically called by the application itself once
|
2386 |
|
|
// everything else has been initialized, i.e. when the host should be
|
2387 |
|
|
// able to start talking to this device. There is no actual bit in the
|
2388 |
|
|
// chip itself to switch the USB pins from tri-state, so instead the
|
2389 |
|
|
// platform HAL has to supply appropriate functionality. In the absence
|
2390 |
|
|
// of such functionality things will only work if you start up eCos
|
2391 |
|
|
// with the USB cable disconnected, then plug in the cable once
|
2392 |
|
|
// start() has been called.
|
2393 |
|
|
//
|
2394 |
|
|
// The device driver initialization will have already set up the
|
2395 |
|
|
// hardware, and the first action from the host should be a reset
|
2396 |
|
|
// signal which will cause a re-initialization. There is no need
|
2397 |
|
|
// to do anything else here.
|
2398 |
|
|
|
2399 |
|
|
static void
|
2400 |
|
|
usbs_upd985xx_ep0_start(usbs_control_endpoint* endpoint)
|
2401 |
|
|
{
|
2402 |
|
|
CYG_ASSERT( endpoint == &ep0.common, "USB startup involves the wrong endpoint");
|
2403 |
|
|
|
2404 |
|
|
// If there is additional platform-specific initialization to
|
2405 |
|
|
// perform, do it now. This macro can come from the platform HAL,
|
2406 |
|
|
// but may not be available on all platforms.
|
2407 |
|
|
#ifdef UPD985XX_USB_PLATFORM_INIT
|
2408 |
|
|
UPD985XX_USB_PLATFORM_INIT();
|
2409 |
|
|
#endif
|
2410 |
|
|
}
|
2411 |
|
|
|
2412 |
|
|
// ----------------------------------------------------------------------------
|
2413 |
|
|
// The main DSR
|
2414 |
|
|
//
|
2415 |
|
|
// This gets called by the interrupt system or by the polling code
|
2416 |
|
|
// when one or more USB-related events have occurred. The ISR code
|
2417 |
|
|
// will have updated globals usbs_upd985xx_gsr1 and usbs_upd98x0x_gsr2
|
2418 |
|
|
// to indicate which events are pending. When running in interrupt
|
2419 |
|
|
// mode it is possible that further interrupts will occur while the
|
2420 |
|
|
// DSR is running, and hence that these globals will be updated
|
2421 |
|
|
// while the DSR is running. This is handled by a loop. A side effect
|
2422 |
|
|
// is that the DSR may get called when all the work has already
|
2423 |
|
|
// been done by a previous DSR, but that is harmless.
|
2424 |
|
|
|
2425 |
|
|
static void
|
2426 |
|
|
usbs_upd985xx_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
|
2427 |
|
|
{
|
2428 |
|
|
CYG_ASSERT(CYGNUM_HAL_INTERRUPT_USB == vector, "USB DSR should only be invoked for USB interrupts" );
|
2429 |
|
|
CYG_ASSERT(0 == data, "The USB DSR needs no global data pointer");
|
2430 |
|
|
|
2431 |
|
|
while ((0 != usbs_upd985xx_gsr1) || (0 != usbs_upd985xx_gsr2)) {
|
2432 |
|
|
// Only update the globals in one place since it involves
|
2433 |
|
|
// the overhead of two function calls.
|
2434 |
|
|
cyg_uint32 gsr1, gsr2;
|
2435 |
|
|
cyg_drv_isr_lock();
|
2436 |
|
|
gsr1 = usbs_upd985xx_gsr1;
|
2437 |
|
|
gsr2 = usbs_upd985xx_gsr2;
|
2438 |
|
|
usbs_upd985xx_gsr1 = 0;
|
2439 |
|
|
usbs_upd985xx_gsr2 = 0;
|
2440 |
|
|
cyg_drv_isr_unlock();
|
2441 |
|
|
|
2442 |
|
|
if (0 != gsr2) {
|
2443 |
|
|
// Treat reset specially. If there has been a reset then none of
|
2444 |
|
|
// the other bits are of any interest.
|
2445 |
|
|
if (0 != (USBS_GSR2_URST & gsr2)) {
|
2446 |
|
|
int old_state = ep0.common.state;
|
2447 |
|
|
// Update the state. ep0_init() detects this state change and
|
2448 |
|
|
// updates imr2 appropriate, preventing a continuous storm
|
2449 |
|
|
// of reset interrupts.
|
2450 |
|
|
ep0.common.state = USBS_STATE_DEFAULT;
|
2451 |
|
|
usbs_upd985xx_handle_reset();
|
2452 |
|
|
// This state change must be reported to higher-level code
|
2453 |
|
|
if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
|
2454 |
|
|
(*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
|
2455 |
|
|
USBS_STATE_CHANGE_RESET, old_state);
|
2456 |
|
|
}
|
2457 |
|
|
break;
|
2458 |
|
|
}
|
2459 |
|
|
// There is possible confusion if both suspend and resume
|
2460 |
|
|
// bits are set. Was there a suspend, quickly followed by
|
2461 |
|
|
// a resume? Were we already suspended, then resumed, now
|
2462 |
|
|
// suspended again? For now this complication is ignored and
|
2463 |
|
|
// resume is given priority over suspend.
|
2464 |
|
|
if (0 != (USBS_GSR2_URSM & gsr2)) {
|
2465 |
|
|
int old_state = ep0.common.state;
|
2466 |
|
|
if (0 != (old_state & USBS_STATE_SUSPENDED)) {
|
2467 |
|
|
ep0.common.state &= ~USBS_STATE_SUSPENDED;
|
2468 |
|
|
if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
|
2469 |
|
|
(*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
|
2470 |
|
|
USBS_STATE_CHANGE_RESUMED, old_state);
|
2471 |
|
|
}
|
2472 |
|
|
}
|
2473 |
|
|
} else if (0 != (USBS_GSR2_USPD & gsr2)) {
|
2474 |
|
|
int old_state = ep0.common.state;
|
2475 |
|
|
if (0 == (old_state & USBS_STATE_SUSPENDED)) {
|
2476 |
|
|
ep0.common.state |= USBS_STATE_SUSPENDED;
|
2477 |
|
|
if ((void (*)(usbs_control_endpoint*, void*, usbs_state_change, int))0 != ep0.common.state_change_fn) {
|
2478 |
|
|
(*ep0.common.state_change_fn)(&ep0.common, ep0.common.state_change_data,
|
2479 |
|
|
USBS_STATE_CHANGE_SUSPENDED, old_state);
|
2480 |
|
|
}
|
2481 |
|
|
}
|
2482 |
|
|
} else {
|
2483 |
|
|
// Handle error conditions on the isochronous endpoints?
|
2484 |
|
|
}
|
2485 |
|
|
}
|
2486 |
|
|
if (0 != gsr1) {
|
2487 |
|
|
|
2488 |
|
|
if (0 != (USBS_GSR1_EP0TF & gsr1)) {
|
2489 |
|
|
ep0_tx_dsr();
|
2490 |
|
|
}
|
2491 |
|
|
if (0 != (USBS_GSR1_EP0RF & gsr1)) {
|
2492 |
|
|
ep0_rx_dsr();
|
2493 |
|
|
}
|
2494 |
|
|
#if 0
|
2495 |
|
|
// EP1FU?
|
2496 |
|
|
if (0 != (USBS_GSR1_EP1TF & gsr1)) {
|
2497 |
|
|
ep1_dsr();
|
2498 |
|
|
}
|
2499 |
|
|
#endif
|
2500 |
|
|
#if 0
|
2501 |
|
|
// EP2FO?
|
2502 |
|
|
if (0 != (USBS_GSR1_EP2RF & gsr1)) {
|
2503 |
|
|
ep1_dsr();
|
2504 |
|
|
}
|
2505 |
|
|
#endif
|
2506 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
2507 |
|
|
if (0 != (USBS_GSR1_EP3TF & gsr1)) {
|
2508 |
|
|
ep35_dsr(&ep3);
|
2509 |
|
|
}
|
2510 |
|
|
#endif
|
2511 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
2512 |
|
|
if (0 != (USBS_GSR1_EP4RF & gsr1)) {
|
2513 |
|
|
ep4_dsr();
|
2514 |
|
|
}
|
2515 |
|
|
#endif
|
2516 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
2517 |
|
|
if (0 != (USBS_GSR1_EP5TF & gsr1)) {
|
2518 |
|
|
ep35_dsr(&ep5);
|
2519 |
|
|
}
|
2520 |
|
|
#endif
|
2521 |
|
|
#if 0
|
2522 |
|
|
if (0 != (USBS_GSR1_EP6RF & gsr1)) {
|
2523 |
|
|
ep6_dsr();
|
2524 |
|
|
}
|
2525 |
|
|
#endif
|
2526 |
|
|
}
|
2527 |
|
|
} // while there are unprocessed interrupts
|
2528 |
|
|
}
|
2529 |
|
|
|
2530 |
|
|
// ----------------------------------------------------------------------------
|
2531 |
|
|
// Interrupt handling.
|
2532 |
|
|
//
|
2533 |
|
|
// There are two status registers to look at. These are read-once
|
2534 |
|
|
// registers, i.e. reading the register causes all bits to be cleared,
|
2535 |
|
|
// so the relevant state has to be preserved in volatile globals which
|
2536 |
|
|
// can then be examined by the DSR. In theory the top bit of the first
|
2537 |
|
|
// status register can be used to check whether or not there is
|
2538 |
|
|
// anything of interest in the second one, but it seems quicker to
|
2539 |
|
|
// just read both registers. After masking out interrupts that are of
|
2540 |
|
|
// no interest, some global flags are updated. If this leaves a
|
2541 |
|
|
// non-zero value then the DSR must be invoked.
|
2542 |
|
|
|
2543 |
|
|
static cyg_uint32
|
2544 |
|
|
usbs_upd985xx_isr(cyg_vector_t vector, cyg_addrword_t data)
|
2545 |
|
|
{
|
2546 |
|
|
CYG_ASSERT(CYGNUM_HAL_INTERRUPT_USB == vector, "USB ISR should only be invoked for USB interrupts");
|
2547 |
|
|
CYG_ASSERT(0 == data, "The UPD985xx ISR needs no global data pointer");
|
2548 |
|
|
|
2549 |
|
|
usbs_upd985xx_gsr1 |= IBUS_SWAP32(*USBS_GSR1) & usbs_upd985xx_gsr1_mask;
|
2550 |
|
|
usbs_upd985xx_gsr2 |= IBUS_SWAP32(*USBS_GSR2) & usbs_upd985xx_gsr2_mask;
|
2551 |
|
|
|
2552 |
|
|
cyg_drv_interrupt_acknowledge(vector);
|
2553 |
|
|
return ((0 == usbs_upd985xx_gsr1) && (0 == usbs_upd985xx_gsr2)) ?
|
2554 |
|
|
CYG_ISR_HANDLED : CYG_ISR_CALL_DSR;
|
2555 |
|
|
}
|
2556 |
|
|
|
2557 |
|
|
// ----------------------------------------------------------------------------
|
2558 |
|
|
// Polling support. It is not clear that this is going to work particularly
|
2559 |
|
|
// well since according to the documentation the hardware does not generate
|
2560 |
|
|
// NAKs automatically - instead the ISR has to set the appropriate bits
|
2561 |
|
|
// sufficiently quickly to avoid confusing the host.
|
2562 |
|
|
//
|
2563 |
|
|
// Calling the isr directly avoids duplicating code, but means that
|
2564 |
|
|
// cyg_drv_interrupt_acknowledge() will get called when not inside a
|
2565 |
|
|
// real interrupt handler. This should be harmless.
|
2566 |
|
|
|
2567 |
|
|
static void
|
2568 |
|
|
usbs_upd985xx_poll(usbs_control_endpoint* endpoint)
|
2569 |
|
|
{
|
2570 |
|
|
CYG_ASSERT(endpoint == &ep0.common, "USB poll involves the wrong endpoint");
|
2571 |
|
|
if (CYG_ISR_CALL_DSR == usbs_upd985xx_isr(CYGNUM_HAL_INTERRUPT_USB, 0)) {
|
2572 |
|
|
usbs_upd985xx_dsr(CYGNUM_HAL_INTERRUPT_USB, 0, 0);
|
2573 |
|
|
}
|
2574 |
|
|
}
|
2575 |
|
|
|
2576 |
|
|
// ----------------------------------------------------------------------------
|
2577 |
|
|
// Initialization
|
2578 |
|
|
//
|
2579 |
|
|
// This routine gets called from a prioritized static constructor during
|
2580 |
|
|
// eCos startup.
|
2581 |
|
|
void
|
2582 |
|
|
usbs_upd985xx_init(void)
|
2583 |
|
|
{
|
2584 |
|
|
// Make sure the uncached data structure is accessed through
|
2585 |
|
|
// kseg1.
|
2586 |
|
|
uncached = (uncached_data*) MIPS_TO_UNCACHED(&cached_copy);
|
2587 |
|
|
|
2588 |
|
|
// Perform a full hardware reset.
|
2589 |
|
|
usbs_upd985xx_handle_reset();
|
2590 |
|
|
|
2591 |
|
|
// It is possible and desirable to install the interrupt handler
|
2592 |
|
|
// here, even though there will be no interrupts for a while yet.
|
2593 |
|
|
// FIXME: is 99 a sensible interrupt priority :-?
|
2594 |
|
|
cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_USB,
|
2595 |
|
|
99, // priority
|
2596 |
|
|
0, // data
|
2597 |
|
|
&usbs_upd985xx_isr,
|
2598 |
|
|
&usbs_upd985xx_dsr,
|
2599 |
|
|
&usbs_upd985xx_intr_handle,
|
2600 |
|
|
&usbs_upd985xx_intr_data);
|
2601 |
|
|
|
2602 |
|
|
cyg_drv_interrupt_attach(usbs_upd985xx_intr_handle);
|
2603 |
|
|
cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_USB);
|
2604 |
|
|
}
|
2605 |
|
|
|
2606 |
|
|
// ----------------------------------------------------------------------------
|
2607 |
|
|
// Testing support.
|
2608 |
|
|
|
2609 |
|
|
usbs_testing_endpoint usbs_testing_endpoints[] = {
|
2610 |
|
|
{
|
2611 |
|
|
endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_CONTROL,
|
2612 |
|
|
endpoint_number : 0,
|
2613 |
|
|
endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
|
2614 |
|
|
endpoint : (void*) &ep0.common,
|
2615 |
|
|
#ifdef CYGVAR_DEVS_USB_UPD985XX_EP0_DEVTAB_ENTRY
|
2616 |
|
|
devtab_entry : CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "0c",
|
2617 |
|
|
#else
|
2618 |
|
|
devtab_entry : (const char*) 0,
|
2619 |
|
|
#endif
|
2620 |
|
|
min_size : 1, // zero-byte control transfers are meaningless
|
2621 |
|
|
#if (CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE < CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE)
|
2622 |
|
|
max_size : CYGNUM_DEVS_USB_UPD985XX_EP0_RXBUFSIZE,
|
2623 |
|
|
#else
|
2624 |
|
|
max_size : CYGNUM_DEVS_USB_UPD985XX_EP0_TXBUFSIZE,
|
2625 |
|
|
#endif
|
2626 |
|
|
max_in_padding : 0,
|
2627 |
|
|
alignment : 0
|
2628 |
|
|
},
|
2629 |
|
|
|
2630 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP3
|
2631 |
|
|
{
|
2632 |
|
|
endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
|
2633 |
|
|
endpoint_number : 3,
|
2634 |
|
|
endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
|
2635 |
|
|
endpoint : (void*) &ep3.common,
|
2636 |
|
|
# ifdef CYGVAR_DEVS_USB_UPD985XX_EP3_DEVTAB_ENTRY
|
2637 |
|
|
devtab_entry : CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "3w",
|
2638 |
|
|
# else
|
2639 |
|
|
devtab_entry : (const char*) 0,
|
2640 |
|
|
# endif
|
2641 |
|
|
min_size : 0,
|
2642 |
|
|
max_size : 0x0FFFF, // Driver limitation, only a single buffer descriptor is used
|
2643 |
|
|
max_in_padding : 0,
|
2644 |
|
|
alignment : HAL_DCACHE_LINE_SIZE
|
2645 |
|
|
},
|
2646 |
|
|
#endif
|
2647 |
|
|
|
2648 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP4
|
2649 |
|
|
{
|
2650 |
|
|
endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
|
2651 |
|
|
endpoint_number : 4,
|
2652 |
|
|
endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_OUT,
|
2653 |
|
|
endpoint : (void*) &ep4.common,
|
2654 |
|
|
# ifdef CYGVAR_DEVS_USB_UPD985XX_EP4_DEVTAB_ENTRY
|
2655 |
|
|
devtab_entry : CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "4r",
|
2656 |
|
|
# else
|
2657 |
|
|
devtab_entry : (const char*) 0,
|
2658 |
|
|
# endif
|
2659 |
|
|
min_size : 1,
|
2660 |
|
|
max_size : 0x0FFFF, // Driver limitation
|
2661 |
|
|
max_in_padding : 0,
|
2662 |
|
|
alignment : HAL_DCACHE_LINE_SIZE
|
2663 |
|
|
},
|
2664 |
|
|
#endif
|
2665 |
|
|
|
2666 |
|
|
#ifdef CYGPKG_DEVS_USB_UPD985XX_EP5
|
2667 |
|
|
{
|
2668 |
|
|
# ifdef CYGIMP_DEVS_USB_UPD985XX_EP5_BULK
|
2669 |
|
|
endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_BULK,
|
2670 |
|
|
# else
|
2671 |
|
|
endpoint_type : USB_ENDPOINT_DESCRIPTOR_ATTR_INTERRUPT,
|
2672 |
|
|
# endif
|
2673 |
|
|
endpoint_number : 5,
|
2674 |
|
|
endpoint_direction : USB_ENDPOINT_DESCRIPTOR_ENDPOINT_IN,
|
2675 |
|
|
endpoint : (void*) &ep5.common,
|
2676 |
|
|
# ifdef CYGVAR_DEVS_USB_UPD985XX_EP5_DEVTAB_ENTRY
|
2677 |
|
|
devtab_entry : CYGDAT_DEVS_USB_UPD985XX_DEVTAB_BASENAME "5w",
|
2678 |
|
|
# else
|
2679 |
|
|
devtab_entry : (const char*) 0,
|
2680 |
|
|
# endif
|
2681 |
|
|
min_size : 1,
|
2682 |
|
|
max_size : 0x0FFFF, // Driver limitation, only a single buffer descriptor is used
|
2683 |
|
|
max_in_padding : 0,
|
2684 |
|
|
alignment : HAL_DCACHE_LINE_SIZE
|
2685 |
|
|
},
|
2686 |
|
|
#endif
|
2687 |
|
|
|
2688 |
|
|
USBS_TESTING_ENDPOINTS_TERMINATOR
|
2689 |
|
|
};
|