diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/usb-drv-as3525v2.c | 272 | ||||
-rw-r--r-- | firmware/target/arm/as3525/usb-drv-as3525v2.h | 8 |
2 files changed, 126 insertions, 154 deletions
diff --git a/firmware/target/arm/as3525/usb-drv-as3525v2.c b/firmware/target/arm/as3525/usb-drv-as3525v2.c index 37f5798e34..fc6b858755 100644 --- a/firmware/target/arm/as3525/usb-drv-as3525v2.c +++ b/firmware/target/arm/as3525/usb-drv-as3525v2.c | |||
@@ -34,6 +34,18 @@ | |||
34 | #define LOGF_ENABLE | 34 | #define LOGF_ENABLE |
35 | #include "logf.h" | 35 | #include "logf.h" |
36 | #include "usb-drv-as3525v2.h" | 36 | #include "usb-drv-as3525v2.h" |
37 | #include "usb_core.h" | ||
38 | |||
39 | static int __in_ep_list[USB_NUM_IN_EP] = {USB_IN_EP_LIST}; | ||
40 | static int __out_ep_list[USB_NUM_OUT_EP] = {USB_OUT_EP_LIST}; | ||
41 | |||
42 | /* iterate through each in/out ep except EP0 | ||
43 | * 'counter' is the counter, 'ep' is the actual value */ | ||
44 | #define FOR_EACH_IN_EP(counter, ep) \ | ||
45 | for(counter = 0, ep = __in_ep_list[0]; counter < USB_NUM_IN_EP; counter++, ep = __in_ep_list[counter]) | ||
46 | |||
47 | #define FOR_EACH_OUT_EP(counter, ep) \ | ||
48 | for(counter = 0, ep = __out_ep_list[0]; counter < USB_NUM_OUT_EP; counter++, ep = __out_ep_list[counter]) | ||
37 | 49 | ||
38 | struct usb_endpoint | 50 | struct usb_endpoint |
39 | { | 51 | { |
@@ -63,7 +75,10 @@ static void usb_delay(void) | |||
63 | { | 75 | { |
64 | int i = 0; | 76 | int i = 0; |
65 | while(i < 0x300) | 77 | while(i < 0x300) |
78 | { | ||
79 | asm volatile("nop"); | ||
66 | i++; | 80 | i++; |
81 | } | ||
67 | } | 82 | } |
68 | 83 | ||
69 | static void as3525v2_connect(void) | 84 | static void as3525v2_connect(void) |
@@ -110,31 +125,20 @@ static void as3525v2_connect(void) | |||
110 | usb_delay(); | 125 | usb_delay(); |
111 | } | 126 | } |
112 | 127 | ||
113 | static void usb_enable_common_interrupts(void) | ||
114 | { | ||
115 | /* Clear any pending otg interrupt */ | ||
116 | USB_GOTGINT = 0xffffffff; | ||
117 | /* Clear any pending interrupt */ | ||
118 | USB_GINTSTS = 0Xffffffff; | ||
119 | /* Enable interrupts */ | ||
120 | USB_GINTMSK = USB_GINTMSK_otgintr | ||
121 | | USB_GINTMSK_conidstschng | ||
122 | | USB_GINTMSK_disconnect; | ||
123 | } | ||
124 | |||
125 | static void usb_enable_device_interrupts(void) | 128 | static void usb_enable_device_interrupts(void) |
126 | { | 129 | { |
127 | /* Disable all interrupts */ | ||
128 | USB_GINTMSK = 0; | ||
129 | /* Clear any pending interrupt */ | 130 | /* Clear any pending interrupt */ |
130 | USB_GINTSTS = 0xffffffff; | 131 | USB_GINTSTS = 0xffffffff; |
131 | /* Enable common interrupts */ | 132 | /* Clear any pending otg interrupt */ |
132 | usb_enable_common_interrupts(); | 133 | USB_GOTGINT = 0xffffffff; |
133 | /* Enable interrupts */ | 134 | /* Enable interrupts */ |
134 | USB_GINTMSK |= USB_GINTMSK_usbreset | 135 | USB_GINTMSK = USB_GINTMSK_usbreset |
135 | | USB_GINTMSK_enumdone | 136 | | USB_GINTMSK_enumdone |
136 | | USB_GINTMSK_inepintr | 137 | | USB_GINTMSK_inepintr |
137 | | USB_GINTMSK_outepintr; | 138 | | USB_GINTMSK_outepintr |
139 | | USB_GINTMSK_otgintr | ||
140 | | USB_GINTMSK_usbsuspend | ||
141 | | USB_GINTMSK_wkupintr; | ||
138 | } | 142 | } |
139 | 143 | ||
140 | static void usb_flush_tx_fifos(int nums) | 144 | static void usb_flush_tx_fifos(int nums) |
@@ -184,6 +188,47 @@ static void core_reset(void) | |||
184 | udelay(1); | 188 | udelay(1); |
185 | } | 189 | } |
186 | 190 | ||
191 | static void reset_endpoints(void) | ||
192 | { | ||
193 | int i, ep; | ||
194 | /* disable all endpoints except EP0 */ | ||
195 | FOR_EACH_IN_EP(i, ep) | ||
196 | if(USB_DIEPCTL(ep) & USB_DEPCTL_epena) | ||
197 | USB_DIEPCTL(ep) = USB_DEPCTL_epdis | USB_DEPCTL_snak; | ||
198 | else | ||
199 | USB_DIEPCTL(ep) = 0; | ||
200 | |||
201 | FOR_EACH_OUT_EP(i, ep) | ||
202 | if(USB_DOEPCTL(ep) & USB_DEPCTL_epena) | ||
203 | USB_DOEPCTL(ep) = USB_DEPCTL_epdis | USB_DEPCTL_snak; | ||
204 | else | ||
205 | USB_DOEPCTL(ep) = 0; | ||
206 | /* Setup EP0 OUT with the following parameters: | ||
207 | * packet count = 1 | ||
208 | * setup packet count = 1 | ||
209 | * transfer size = 64 | ||
210 | * Setup EP0 IN/OUT with 64 byte maximum packet size and activate both. Enable transfer on EP0 OUT | ||
211 | */ | ||
212 | |||
213 | /* 64 bytes packet size, active endpoint */ | ||
214 | USB_DOEPCTL(0) = USB_DEPCTL_usbactep | (USB_DEPCTL_MPS_64 << USB_DEPCTL_mps_bit_pos); | ||
215 | |||
216 | USB_DOEPTSIZ(0) = (1 << USB_DEPTSIZ0_supcnt_bit_pos) | ||
217 | | (1 << USB_DEPTSIZ0_pkcnt_bit_pos) | ||
218 | | 64; | ||
219 | |||
220 | /* setup DMA */ | ||
221 | clean_dcache_range((void*)&ep0_setup_pkt, sizeof ep0_setup_pkt); /* force write back */ | ||
222 | USB_DOEPDMA(0) = (unsigned long)&ep0_setup_pkt; /* virtual address=physical address */ | ||
223 | |||
224 | /* Enable endpoint, clear nak */ | ||
225 | USB_DOEPCTL(0) |= USB_DEPCTL_epena | USB_DEPCTL_cnak; | ||
226 | |||
227 | /* 64 bytes packet size, active endpoint */ | ||
228 | USB_DIEPCTL(0) = (USB_DEPCTL_MPS_64 << USB_DEPCTL_mps_bit_pos) | ||
229 | | USB_DEPCTL_usbactep; | ||
230 | } | ||
231 | |||
187 | static void core_dev_init(void) | 232 | static void core_dev_init(void) |
188 | { | 233 | { |
189 | unsigned int usb_num_in_ep = 0; | 234 | unsigned int usb_num_in_ep = 0; |
@@ -192,9 +237,7 @@ static void core_dev_init(void) | |||
192 | /* Restart the phy clock */ | 237 | /* Restart the phy clock */ |
193 | USB_PCGCCTL = 0; | 238 | USB_PCGCCTL = 0; |
194 | /* Set phy speed : high speed */ | 239 | /* Set phy speed : high speed */ |
195 | USB_DCFG = (USB_DCFG & (~USB_DCFG_devspd_bits)) | USB_DCFG_devspd_hs_phy_hs; | 240 | USB_DCFG = (USB_DCFG & ~USB_DCFG_devspd_bits) | USB_DCFG_devspd_hs_phy_hs; |
196 | /* Set periodic frame interval */ | ||
197 | USB_DCFG = (USB_DCFG & (~USB_DCFG_perfrint_bits)) | (USB_DCFG_FRAME_INTERVAL_80 << USB_DCFG_perfrint_bit_pos); | ||
198 | 241 | ||
199 | /* Check hardware capabilities */ | 242 | /* Check hardware capabilities */ |
200 | if(USB_GHWCFG2_ARCH != USB_INT_DMA_ARCH) | 243 | if(USB_GHWCFG2_ARCH != USB_INT_DMA_ARCH) |
@@ -208,6 +251,7 @@ static void core_dev_init(void) | |||
208 | if(USB_GHWCFG4_DED_FIFO_EN != 1) /* it seems to be multiple tx fifo support */ | 251 | if(USB_GHWCFG4_DED_FIFO_EN != 1) /* it seems to be multiple tx fifo support */ |
209 | panicf("usb: no multiple tx fifo"); | 252 | panicf("usb: no multiple tx fifo"); |
210 | 253 | ||
254 | /* do some logging */ | ||
211 | logf("hwcfg1: %08lx", USB_GHWCFG1); | 255 | logf("hwcfg1: %08lx", USB_GHWCFG1); |
212 | logf("hwcfg2: %08lx", USB_GHWCFG2); | 256 | logf("hwcfg2: %08lx", USB_GHWCFG2); |
213 | logf("hwcfg3: %08lx", USB_GHWCFG3); | 257 | logf("hwcfg3: %08lx", USB_GHWCFG3); |
@@ -233,11 +277,13 @@ static void core_dev_init(void) | |||
233 | panicf("usb: num out ep static mismatch(%u,%u)", usb_num_out_ep, USB_NUM_OUT_EP); | 277 | panicf("usb: num out ep static mismatch(%u,%u)", usb_num_out_ep, USB_NUM_OUT_EP); |
234 | 278 | ||
235 | logf("%d in ep, %d out ep", usb_num_in_ep, usb_num_out_ep); | 279 | logf("%d in ep, %d out ep", usb_num_in_ep, usb_num_out_ep); |
280 | /* | ||
236 | logf("initial:"); | 281 | logf("initial:"); |
237 | logf(" tot fifo sz: %lx", USB_GHWCFG3_DFIFO_LEN); | 282 | logf(" tot fifo sz: %lx", USB_GHWCFG3_DFIFO_LEN); |
238 | logf(" rx fifo: [%04x,+%4lx]", 0, USB_GRXFSIZ); | 283 | logf(" rx fifo: [%04x,+%4lx]", 0, USB_GRXFSIZ); |
239 | logf(" nptx fifo: [%04lx,+%4lx]", USB_GET_FIFOSIZE_START_ADR(USB_GNPTXFSIZ), | 284 | logf(" nptx fifo: [%04lx,+%4lx]", USB_GET_FIFOSIZE_START_ADR(USB_GNPTXFSIZ), |
240 | USB_GET_FIFOSIZE_DEPTH(USB_GNPTXFSIZ)); | 285 | USB_GET_FIFOSIZE_DEPTH(USB_GNPTXFSIZ)); |
286 | */ | ||
241 | for(i = 1; i <= USB_NUM_IN_EP; i++) | 287 | for(i = 1; i <= USB_NUM_IN_EP; i++) |
242 | { | 288 | { |
243 | logf(" dieptx fifo(%2u): [%04lx,+%4lx]", i, | 289 | logf(" dieptx fifo(%2u): [%04lx,+%4lx]", i, |
@@ -253,72 +299,40 @@ static void core_dev_init(void) | |||
253 | USB_GRSTCTL = USB_GRSTCTL_intknqflsh; | 299 | USB_GRSTCTL = USB_GRSTCTL_intknqflsh; |
254 | 300 | ||
255 | /* Clear all pending device interrupts */ | 301 | /* Clear all pending device interrupts */ |
256 | USB_DIEPMSK = 0; | ||
257 | USB_DOEPMSK = 0; | ||
258 | USB_DAINT = 0xffffffff; | 302 | USB_DAINT = 0xffffffff; |
259 | USB_DAINTMSK = 0; | 303 | /* Setup interrupt masks for enpoints */ |
260 | 304 | /* Setup interrupt masks */ | |
261 | for(i = 0; i <= USB_NUM_IN_EP; i++) | 305 | USB_DOEPMSK = USB_DOEPINT_setup | USB_DOEPINT_xfercompl | USB_DOEPINT_ahberr |
262 | { | 306 | | USB_DOEPINT_epdisabled; |
263 | /* disable endpoint if enabled */ | 307 | USB_DIEPMSK = USB_DIEPINT_xfercompl | USB_DIEPINT_timeout |
264 | if(USB_DIEPCTL(i) & USB_DEPCTL_epena) | 308 | | USB_DIEPINT_epdisabled | USB_DIEPINT_ahberr |
265 | USB_DIEPCTL(i) = USB_DEPCTL_epdis | USB_DEPCTL_snak; | 309 | | USB_DIEPINT_intknepmis; |
266 | else | 310 | USB_DAINTMSK = 0xffffffff; |
267 | USB_DIEPCTL(i) = 0; | ||
268 | |||
269 | USB_DIEPTSIZ(i) = 0; | ||
270 | USB_DIEPDMA(i) = 0; | ||
271 | USB_DIEPINT(i) = 0xff; | ||
272 | } | ||
273 | |||
274 | for(i = 0; i <= USB_NUM_OUT_EP; i++) | ||
275 | { | ||
276 | /* disable endpoint if enabled */ | ||
277 | if(USB_DOEPCTL(i) & USB_DEPCTL_epena) | ||
278 | USB_DOEPCTL(i) = USB_DEPCTL_epdis | USB_DEPCTL_snak; | ||
279 | else | ||
280 | USB_DOEPCTL(i) = 0; | ||
281 | 311 | ||
282 | USB_DOEPTSIZ(i) = 0; | 312 | reset_endpoints(); |
283 | USB_DOEPDMA(i) = 0; | ||
284 | USB_DOEPINT(i) = 0xff; | ||
285 | } | ||
286 | 313 | ||
287 | /* fixme: threshold tweaking only takes place if we use multiple tx fifos it seems */ | 314 | /* fixme: threshold tweaking only takes place if we use multiple tx fifos it seems */ |
288 | /* only dump them for now, leave threshold disabled */ | 315 | /* only dump them for now, leave threshold disabled */ |
316 | /* | ||
289 | logf("threshold control:"); | 317 | logf("threshold control:"); |
290 | logf(" non_iso_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_non_iso_thr_en) ? 1 : 0); | 318 | logf(" non_iso_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_non_iso_thr_en) ? 1 : 0); |
291 | logf(" iso_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_iso_thr_en) ? 1 : 0); | 319 | logf(" iso_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_iso_thr_en) ? 1 : 0); |
292 | logf(" tx_thr_len: %lu", (USB_DTHRCTL & USB_DTHRCTL_tx_thr_len_bits) >> USB_DTHRCTL_tx_thr_len_bit_pos); | 320 | logf(" tx_thr_len: %lu", (USB_DTHRCTL & USB_DTHRCTL_tx_thr_len_bits) >> USB_DTHRCTL_tx_thr_len_bit_pos); |
293 | logf(" rx_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_rx_thr_en) ? 1 : 0); | 321 | logf(" rx_thr_en: %d", (USB_DTHRCTL & USB_DTHRCTL_rx_thr_en) ? 1 : 0); |
294 | logf(" rx_thr_len: %lu", (USB_DTHRCTL & USB_DTHRCTL_rx_thr_len_bits) >> USB_DTHRCTL_rx_thr_len_bit_pos); | 322 | logf(" rx_thr_len: %lu", (USB_DTHRCTL & USB_DTHRCTL_rx_thr_len_bits) >> USB_DTHRCTL_rx_thr_len_bit_pos); |
323 | */ | ||
295 | 324 | ||
296 | /* enable USB interrupts */ | 325 | /* enable USB interrupts */ |
297 | usb_enable_device_interrupts(); | 326 | usb_enable_device_interrupts(); |
298 | |||
299 | /* enable fifo underrun interrupt ? */ | ||
300 | USB_DIEPMSK |= USB_DIEPINT_txfifoundrn; | ||
301 | } | 327 | } |
302 | 328 | ||
303 | static void core_init(void) | 329 | static void core_init(void) |
304 | { | 330 | { |
305 | /* Setup phy for high speed */ | ||
306 | USB_GUSBCFG &= ~USB_GUSBCFG_ulpi_ext_vbus_drv; | ||
307 | /* Disable external TS Dline pulsing (???) */ | ||
308 | USB_GUSBCFG &= ~USB_GUSBCFG_term_sel_dl_pulse; | ||
309 | /* core reset */ | ||
310 | core_reset(); | ||
311 | |||
312 | /* Select UTMI */ | ||
313 | USB_GUSBCFG &= ~USB_GUSBCFG_ulpi_utmi_sel; | ||
314 | /* Select UTMI+ 16 */ | 331 | /* Select UTMI+ 16 */ |
315 | USB_GUSBCFG |= USB_GUSBCFG_phy_if; | 332 | USB_GUSBCFG |= USB_GUSBCFG_phy_if; |
316 | /* core reset */ | 333 | /* core reset */ |
317 | core_reset(); | 334 | core_reset(); |
318 | 335 | ||
319 | /* fixme: the linux code does that but the clip+ doesn't use ULPI it seems */ | ||
320 | USB_GUSBCFG &= ~(USB_GUSBCFG_ulpi_fsls | USB_GUSBCFG_ulpi_clk_sus_m); | ||
321 | |||
322 | /* fixme: the current code is for internal DMA only, the clip+ architecture | 336 | /* fixme: the current code is for internal DMA only, the clip+ architecture |
323 | * define the internal DMA model */ | 337 | * define the internal DMA model */ |
324 | /* Set burstlen and enable DMA*/ | 338 | /* Set burstlen and enable DMA*/ |
@@ -327,9 +341,6 @@ static void core_init(void) | |||
327 | /* Disable HNP and SRP, not sure it's useful because we already forced dev mode */ | 341 | /* Disable HNP and SRP, not sure it's useful because we already forced dev mode */ |
328 | USB_GUSBCFG &= ~(USB_GUSBCFG_srpcap | USB_GUSBCFG_hnpcapp); | 342 | USB_GUSBCFG &= ~(USB_GUSBCFG_srpcap | USB_GUSBCFG_hnpcapp); |
329 | 343 | ||
330 | /* enable basic interrupts */ | ||
331 | usb_enable_common_interrupts(); | ||
332 | |||
333 | /* perform device model specific init */ | 344 | /* perform device model specific init */ |
334 | core_dev_init(); | 345 | core_dev_init(); |
335 | } | 346 | } |
@@ -351,8 +362,6 @@ void usb_drv_init(void) | |||
351 | logf("usb_drv_init"); | 362 | logf("usb_drv_init"); |
352 | /* Enable PHY and clocks (but leave pullups disabled) */ | 363 | /* Enable PHY and clocks (but leave pullups disabled) */ |
353 | as3525v2_connect(); | 364 | as3525v2_connect(); |
354 | /* Disable global interrupts */ | ||
355 | usb_disable_global_interrupts(); | ||
356 | logf("usb: synopsis id: %lx", USB_GSNPSID); | 365 | logf("usb: synopsis id: %lx", USB_GSNPSID); |
357 | /* Core init */ | 366 | /* Core init */ |
358 | core_init(); | 367 | core_init(); |
@@ -365,68 +374,12 @@ void usb_drv_exit(void) | |||
365 | logf("usb_drv_exit"); | 374 | logf("usb_drv_exit"); |
366 | } | 375 | } |
367 | 376 | ||
368 | static void activate_ep0(void) | ||
369 | { | ||
370 | /* Setup EP0 OUT to receive setup packets and | ||
371 | * EP0 IN to transmit packets | ||
372 | * The setup takes enumeration speed into account | ||
373 | */ | ||
374 | |||
375 | /* Setup packet size of IN ep based of enumerated speed */ | ||
376 | switch((USB_DSTS & USB_DSTS_enumspd_bits) >> USB_DSTS_enumspd_bit_pos) | ||
377 | { | ||
378 | case USB_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: | ||
379 | case USB_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: | ||
380 | case USB_DSTS_ENUMSPD_FS_PHY_48MHZ: | ||
381 | /* Use 64 bytes packet size */ | ||
382 | USB_DIEPCTL(0) = (USB_DIEPCTL(0) & (~USB_DEPCTL_mps_bits)) | ||
383 | | (USB_DEPCTL_MPS_64 << USB_DEPCTL_mps_bit_pos); | ||
384 | break; | ||
385 | case USB_DSTS_ENUMSPD_LS_PHY_6MHZ: | ||
386 | USB_DIEPCTL(0) = (USB_DIEPCTL(0) & (~USB_DEPCTL_mps_bits)) | ||
387 | | (USB_DEPCTL_MPS_8 << USB_DEPCTL_mps_bit_pos); | ||
388 | break; | ||
389 | default: | ||
390 | panicf("usb: invalid enum speed"); | ||
391 | } | ||
392 | |||
393 | /* Enable OUT ep for receive */ | ||
394 | //USB_DOEPCTL(0) |= USB_DEPCTL_epena; | ||
395 | |||
396 | /* Clear non periodic NAK for IN ep */ | ||
397 | USB_DCTL |= USB_DCTL_cgnpinnak; | ||
398 | } | ||
399 | |||
400 | static void ep0_out_start(void) | ||
401 | { | ||
402 | /* Setup EP0 OUT with the following parameters: | ||
403 | * packet count = 1 | ||
404 | * setup packet count = 1 | ||
405 | * transfer size = 8 (=sizeof setup packet) | ||
406 | */ | ||
407 | USB_DOEPTSIZ(0) = (1 << USB_DEPTSIZ0_supcnt_bit_pos) | ||
408 | | (1 << USB_DEPTSIZ0_pkcnt_bit_pos) | ||
409 | | 8; | ||
410 | |||
411 | /* setup DMA */ | ||
412 | clean_dcache_range((void*)&ep0_setup_pkt, sizeof ep0_setup_pkt); /* force write back */ | ||
413 | USB_DOEPDMA(0) = (unsigned long)&ep0_setup_pkt; /* virtual address=physical address */ | ||
414 | |||
415 | /* enable EP */ | ||
416 | USB_DOEPCTL(0) |= USB_DEPCTL_epena | USB_DEPCTL_usbactep; | ||
417 | } | ||
418 | |||
419 | static bool handle_usb_reset(void) | 377 | static bool handle_usb_reset(void) |
420 | { | 378 | { |
421 | unsigned int i; | ||
422 | logf("usb: bus reset"); | 379 | logf("usb: bus reset"); |
423 | 380 | ||
424 | /* Clear the Remote Wakeup Signalling */ | 381 | /* Clear the Remote Wakeup Signalling */ |
425 | USB_DCTL &= ~USB_DCTL_rmtwkupsig; | 382 | USB_DCTL &= ~USB_DCTL_rmtwkupsig; |
426 | |||
427 | /* Set NAK for all OUT EPs */ | ||
428 | for(i = 0; i <= USB_NUM_OUT_EP; i++) | ||
429 | USB_DOEPCTL(i) = USB_DEPCTL_snak; | ||
430 | 383 | ||
431 | /* Flush the NP Tx FIFO */ | 384 | /* Flush the NP Tx FIFO */ |
432 | usb_flush_tx_fifos(0); | 385 | usb_flush_tx_fifos(0); |
@@ -434,39 +387,49 @@ static bool handle_usb_reset(void) | |||
434 | /* Flush the Learning Queue */ | 387 | /* Flush the Learning Queue */ |
435 | USB_GRSTCTL = USB_GRSTCTL_intknqflsh; | 388 | USB_GRSTCTL = USB_GRSTCTL_intknqflsh; |
436 | 389 | ||
437 | /* Setup interrupt masks */ | 390 | reset_endpoints(); |
438 | USB_DAINTMSK = USB_DAINT_IN_EP(0) | USB_DAINT_OUT_EP(0); | ||
439 | USB_DOEPMSK = USB_DOEPINT_setup | USB_DOEPINT_xfercompl | USB_DOEPINT_ahberr | ||
440 | | USB_DOEPINT_epdisabled; | ||
441 | USB_DIEPMSK = USB_DIEPINT_xfercompl | USB_DIEPINT_timeout | ||
442 | | USB_DIEPINT_epdisabled | USB_DIEPINT_ahberr | ||
443 | | USB_DIEPINT_intknepmis; | ||
444 | 391 | ||
445 | /* Reset Device Address */ | 392 | /* Reset Device Address */ |
446 | USB_DCFG &= ~USB_DCFG_devadr_bits; | 393 | USB_DCFG &= ~USB_DCFG_devadr_bits; |
447 | 394 | ||
448 | /* setup EP0 to receive SETUP packets */ | 395 | usb_core_bus_reset(); |
449 | ep0_out_start(); | ||
450 | /* Clear interrupt */ | ||
451 | USB_GINTSTS = USB_GINTMSK_usbreset; | ||
452 | 396 | ||
453 | return true; | 397 | return true; |
454 | } | 398 | } |
455 | 399 | ||
456 | static bool handle_enum_done(void) | 400 | static bool handle_usb_suspend(void) |
457 | { | 401 | { |
458 | logf("usb: enum done"); | 402 | logf("usb: suspend"); |
403 | |||
404 | return true; | ||
405 | } | ||
406 | |||
407 | static bool handle_wake_up(void) | ||
408 | { | ||
409 | logf("usb: wake up"); | ||
459 | 410 | ||
460 | /* Enable EP0 to receive SETUP packets */ | 411 | return true; |
461 | activate_ep0(); | 412 | } |
462 | 413 | ||
463 | /* Set USB turnaround time | 414 | static bool handle_enum_done(void) |
464 | * fixme: unsure about this */ | 415 | { |
465 | //USB_GUSBCFG = (USB_GUSBCFG & ~USB_GUSBCFG_usbtrdtim_bits) | (5 << USB_GUSBCFG_usbtrdtim_bit_pos); | 416 | logf("usb: enum done"); |
466 | //panicf("usb: turnaround time is %d", (USB_GUSBCFG & USB_GUSBCFG_usbtrdtim_bits) >> USB_GUSBCFG_usbtrdtim_bit_pos); | ||
467 | 417 | ||
468 | /* Clear interrupt */ | 418 | /* read speed */ |
469 | USB_GINTSTS = USB_GINTMSK_enumdone; | 419 | logf("DSTS: %lx", USB_DSTS); |
420 | logf("DOEPCTL0=%lx", USB_DOEPCTL(0)); | ||
421 | logf("DOEPTSIZ=%lx", USB_DOEPTSIZ(0)); | ||
422 | logf("DIEPCTL0=%lx", USB_DIEPCTL(0)); | ||
423 | logf("DOEPMSK=%lx", USB_DOEPMSK); | ||
424 | logf("DIEPMSK=%lx", USB_DIEPMSK); | ||
425 | logf("DAINTMSK=%lx", USB_DAINTMSK); | ||
426 | logf("DAINT=%lx", USB_DAINT); | ||
427 | logf("GINTSTS=%lx", USB_GINTSTS); | ||
428 | logf("GINTMSK=%lx", USB_GINTMSK); | ||
429 | logf("DCTL=%lx", USB_DCTL); | ||
430 | logf("GAHBCFG=%lx", USB_GAHBCFG); | ||
431 | logf("GUSBCFG=%lx", USB_GUSBCFG); | ||
432 | logf("DCFG=%lx", USB_DCFG); | ||
470 | 433 | ||
471 | return true; | 434 | return true; |
472 | } | 435 | } |
@@ -523,7 +486,6 @@ static void dump_intsts(char *buffer, size_t size, unsigned long sts) | |||
523 | /* interrupt service routine */ | 486 | /* interrupt service routine */ |
524 | void INT_USB(void) | 487 | void INT_USB(void) |
525 | { | 488 | { |
526 | static char buffer[256]; | ||
527 | /* some bits in GINTSTS can be set even though we didn't enable the interrupt source | 489 | /* some bits in GINTSTS can be set even though we didn't enable the interrupt source |
528 | * so AND it with the actual mask */ | 490 | * so AND it with the actual mask */ |
529 | unsigned long sts = USB_GINTSTS & USB_GINTMSK; | 491 | unsigned long sts = USB_GINTSTS & USB_GINTMSK; |
@@ -545,8 +507,14 @@ void INT_USB(void) | |||
545 | /* device part */ | 507 | /* device part */ |
546 | HANDLED_CASE(USB_GINTMSK_usbreset, handle_usb_reset) | 508 | HANDLED_CASE(USB_GINTMSK_usbreset, handle_usb_reset) |
547 | HANDLED_CASE(USB_GINTMSK_enumdone, handle_enum_done) | 509 | HANDLED_CASE(USB_GINTMSK_enumdone, handle_enum_done) |
510 | HANDLED_CASE(USB_GINTMSK_usbsuspend, handle_usb_suspend) | ||
511 | HANDLED_CASE(USB_GINTMSK_wkupintr, handle_wake_up) | ||
512 | /* | ||
548 | HANDLED_CASE(USB_GINTMSK_inepintr, handle_in_ep_int) | 513 | HANDLED_CASE(USB_GINTMSK_inepintr, handle_in_ep_int) |
549 | HANDLED_CASE(USB_GINTMSK_outepintr, handle_out_ep_int) | 514 | HANDLED_CASE(USB_GINTMSK_outepintr, handle_out_ep_int) |
515 | */ | ||
516 | UNHANDLED_CASE(USB_GINTMSK_outepintr) | ||
517 | UNHANDLED_CASE(USB_GINTMSK_inepintr) | ||
550 | 518 | ||
551 | /* common part */ | 519 | /* common part */ |
552 | UNHANDLED_CASE(USB_GINTMSK_otgintr) | 520 | UNHANDLED_CASE(USB_GINTMSK_otgintr) |
@@ -557,15 +525,15 @@ void INT_USB(void) | |||
557 | if(sts & ~handled_one) | 525 | if(sts & ~handled_one) |
558 | goto Lunhandled; | 526 | goto Lunhandled; |
559 | 527 | ||
528 | USB_GINTSTS = USB_GINTSTS; | ||
529 | |||
560 | return; | 530 | return; |
561 | 531 | ||
562 | Lunhandled: | 532 | Lunhandled: |
563 | dump_intsts(buffer, sizeof buffer, sts); | 533 | panicf("unhandled usb int: %lx", sts); |
564 | panicf("unhandled usb int: %lx (%s)", sts, buffer); | ||
565 | 534 | ||
566 | Lerr: | 535 | Lerr: |
567 | dump_intsts(buffer, sizeof buffer, sts); | 536 | panicf("error in usb int: %lx", sts); |
568 | panicf("error in usb int: %lx (%s)", sts, buffer); | ||
569 | } | 537 | } |
570 | 538 | ||
571 | int usb_drv_port_speed(void) | 539 | int usb_drv_port_speed(void) |
diff --git a/firmware/target/arm/as3525/usb-drv-as3525v2.h b/firmware/target/arm/as3525/usb-drv-as3525v2.h index e2932d0dd6..37e8aee1e9 100644 --- a/firmware/target/arm/as3525/usb-drv-as3525v2.h +++ b/firmware/target/arm/as3525/usb-drv-as3525v2.h | |||
@@ -363,7 +363,11 @@ | |||
363 | * Parameters | 363 | * Parameters |
364 | */ | 364 | */ |
365 | /* Number of IN/OUT endpoints */ | 365 | /* Number of IN/OUT endpoints */ |
366 | #define USB_NUM_IN_EP 3u | 366 | #define USB_NUM_IN_EP 3 |
367 | #define USB_NUM_OUT_EP 2u | 367 | #define USB_NUM_OUT_EP 2 |
368 | |||
369 | /* List of IN enpoints */ | ||
370 | #define USB_IN_EP_LIST 1, 3, 5 | ||
371 | #define USB_OUT_EP_LIST 2, 4 | ||
368 | 372 | ||
369 | #endif /* __USB_DRV_AS3525v2_H__ */ | 373 | #endif /* __USB_DRV_AS3525v2_H__ */ |