altos/stm32f4: Add start of stm32f413 USB support
[fw/altos] / src / stm32f4 / ao_usb_stm32f4.c
1 /*
2  * Copyright © 2018 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include "ao_usb_gen.h"
20
21 static uint32_t grxstsp;
22
23 static inline uint8_t
24 grxstsp_enum(void)
25 {
26         return (grxstsp >> STM_USB_GRXSTSP_EPNUM) & STM_USB_GRXSTSP_EPNUM_MASK;
27 }
28
29 static inline uint8_t
30 grxstsp_pktsts(void)
31 {
32         return (grxstsp >> STM_USB_GRXSTSP_PKTSTS) & STM_USB_GRXSTSP_PKTSTS_MASK;
33 }
34
35 static inline uint16_t
36 grxstsp_bcnt(void)
37 {
38         return (grxstsp >> STM_USB_GRXSTSP_BCNT) & STM_USB_GRXSTSP_BCNT_MASK;
39 }
40
41 static void
42 ao_usb_dev_ep_out_start(uint8_t ep)
43 {
44         stm_usb.doep[ep].doeptsiz = ((1 << STM_USB_DOEPTSIZ_PKTCNT) |
45                                      (3 << STM_USB_DOEPTSIZ_STUPCNT) |
46                                      (24 << STM_USB_DOEPTSIZ_XFRSIZ));
47
48 //      stm_usb.doep[ep].doepctl |= (1 << STM_USB_DOEPCTL_EPENA);
49 }
50
51 static void
52 ao_usb_mask_in_bits(vuint32_t *addr, uint32_t shift, uint32_t mask, uint32_t bits)
53 {
54         uint32_t        value;
55
56         value = *addr;
57         value &= ~(mask << shift);
58         value |= (bits << shift);
59         *addr = value;
60 }
61
62 static void
63 ao_usb_activate_ep0(void)
64 {
65         stm_usb.diep[0].diepctl = ((0 << STM_USB_DIEPCTL_TXFNUM) |
66                                    (0 << STM_USB_DIEPCTL_STALL) |
67                                    (STM_USB_DIEPCTL_EPTYP_CONTROL << STM_USB_DIEPCTL_EPTYP) |
68                                    (1 << STM_USB_DIEPCTL_USBAEP) |
69                                    (STM_USB_DIEPCTL_MPSIZ0_64 << STM_USB_DIEPCTL_MPSIZ));
70         stm_usb.doep[0].doepctl = ((0 << STM_USB_DOEPCTL_SNPM) |
71                                    (STM_USB_DOEPCTL_EPTYP_CONTROL << STM_USB_DOEPCTL_EPTYP) |
72                                    (1 << STM_USB_DOEPCTL_USBAEP) |
73                                    (STM_USB_DOEPCTL_MPSIZ0_64 << STM_USB_DOEPCTL_MPSIZ));
74 }
75
76 #if 0
77 static void
78 ao_usb_activate_in(int epnum)
79 {
80         stm_usb.daintmsk |= (1 << (epnum + STM_USB_DAINTMSK_IEPM));
81         stm_usb.diep[epnum].diepctl = ((epnum << STM_USB_DIEPCTL_TXFNUM) |
82                                        (0 << STM_USB_DIEPCTL_STALL) |
83                                        (STM_USB_DIEPCTL_EPTYP_BULK << STM_USB_DIEPCTL_EPTYP) |
84                                        (1 << STM_USB_DIEPCTL_USBAEP) |
85                                        (64 << STM_USB_DIEPCTL_MPSIZ));
86 }
87
88 static void
89 ao_usb_activate_out(int epnum)
90 {
91         stm_usb.daintmsk |= (1 << (epnum + STM_USB_DAINTMSK_OEPM));
92         stm_usb.doep[epnum].doepctl = ((0 << STM_USB_DOEPCTL_SNPM) |
93                                        (STM_USB_DOEPCTL_EPTYP_BULK << STM_USB_DOEPCTL_EPTYP) |
94                                        (1 << STM_USB_DOEPCTL_USBAEP) |
95                                        (64 << STM_USB_DOEPCTL_MPSIZ));
96 }
97 #endif
98
99 static void
100 ao_usb_enum_done(void)
101 {
102         /* Set turn-around delay. 6 is for high hclk (> 32MHz) */
103         ao_usb_mask_in_bits(&stm_usb.gusbcfg, STM_USB_GUSBCFG_TRDT, STM_USB_GUSBCFG_TRDT_MASK, 6);
104
105         ao_usb_activate_ep0();
106 }
107
108 static void
109 ao_usb_flush_tx_fifo(uint32_t fifo)
110 {
111         stm_usb.grstctl = ((1 << STM_USB_GRSTCTL_TXFFLSH) |
112                            (fifo << STM_USB_GRSTCTL_TXFNUM));
113         while ((stm_usb.grstctl & (1 << STM_USB_GRSTCTL_TXFFLSH)) != 0)
114                 ao_arch_nop();
115 }
116
117 static void
118 ao_usb_flush_rx_fifo(void)
119 {
120         stm_usb.grstctl = (1 << STM_USB_GRSTCTL_RXFFLSH);
121         while ((stm_usb.grstctl & (1 << STM_USB_GRSTCTL_RXFFLSH)) != 0)
122                 ao_arch_nop();
123 }
124
125 /* reset and enable EP0 */
126 void
127 ao_usb_dev_ep0_init(void)
128 {
129         uint32_t        diepctl;
130
131         /* Flush TX fifo */
132         ao_usb_flush_tx_fifo(STM_USB_GRSTCTL_TXFNUM_ALL);
133
134         /* Clear interrupts */
135         for (int i = 0; i < 6; i++) {
136                 stm_usb.diep[i].diepint = 0xfffffffful;
137                 stm_usb.doep[i].doepint = 0xfffffffful;
138         }
139         stm_usb.daint = 0xfffffffful;
140
141         /* Enable EP0 in/out interrupts */
142         /* 2. Unmask interrupt bits */
143         stm_usb.daintmsk |= ((1 << (STM_USB_DAINTMSK_IEPM + 0)) |
144                              (1 << (STM_USB_DAINTMSK_OEPM + 0)));
145
146         stm_usb.doepmsk |= ((1 << STM_USB_DOEPMSK_STUPM) |
147                             (1 << STM_USB_DOEPMSK_EPDM) |
148                             (1 << STM_USB_DOEPMSK_XFRCM));
149         stm_usb.diepmsk |= ((1 << STM_USB_DIEPMSK_TOM) |
150                             (1 << STM_USB_DIEPMSK_XFRCM) |
151                             (1 << STM_USB_DIEPMSK_EPDM));
152
153         /* 1. Set NAK bit for all OUT endpoints */
154         stm_usb.doep[0].doepctl |= (1 << STM_USB_DOEPCTL_CNAK);
155         for (int i = 1; i < 6; i++)
156                 stm_usb.doep[i].doepctl |= (1 << STM_USB_DOEPCTL_SNAK);
157
158         /* 3. Setup FIFO ram allocation */
159
160         /* XXX make principled decisions here */
161         stm_usb.grxfsiz = 0x80;
162
163         stm_usb.dieptxf0 = ((0x40 << STM_USB_DIEPTXF0_TX0FD) |          /* size = 256 bytes */
164                             (0x80 << STM_USB_DIEPTXF0_TX0FSA));         /* start address = 0x80 */
165
166         /* 4. Program OUT endpoint 0 to receive a SETUP packet */
167
168         uint32_t        doeptsiz;
169
170         doeptsiz = ((1 << STM_USB_DOEPTSIZ_PKTCNT) |
171                     (0x40 << STM_USB_DOEPTSIZ_XFRSIZ) |
172                     (1 << STM_USB_DOEPTSIZ_STUPCNT));
173
174         stm_usb.doep[0].doeptsiz = doeptsiz;
175
176         /* Program MPSIZ field to set maximum packet size */
177
178         diepctl = ((0 << STM_USB_DIEPCTL_EPENA ) |
179                    (0 << STM_USB_DIEPCTL_EPDIS ) |
180                    (0 << STM_USB_DIEPCTL_SNAK ) |
181                    (0 << STM_USB_DIEPCTL_CNAK ) |
182                    (0 << STM_USB_DIEPCTL_TXFNUM) |
183                    (0 << STM_USB_DIEPCTL_STALL ) |
184                    (STM_USB_DIEPCTL_EPTYP_CONTROL << STM_USB_DIEPCTL_EPTYP ) |
185                    (0 << STM_USB_DIEPCTL_NAKSTS ) |
186                    (0 << STM_USB_DIEPCTL_EONUM ) |
187                    (1 << STM_USB_DIEPCTL_USBAEP ) |
188                    (STM_USB_DIEPCTL_MPSIZ0_64 << STM_USB_DIEPCTL_MPSIZ));
189
190         stm_usb.diep[0].diepctl = diepctl;
191
192         uint32_t        doepctl;
193
194         doepctl = ((0 << STM_USB_DOEPCTL_EPENA ) |
195                    (0 << STM_USB_DOEPCTL_EPDIS ) |
196                    (0 << STM_USB_DOEPCTL_SNAK ) |
197                    (0 << STM_USB_DOEPCTL_CNAK ) |
198                    (0 << STM_USB_DOEPCTL_STALL ) |
199                    (0 << STM_USB_DOEPCTL_SNPM ) |
200                    (STM_USB_DOEPCTL_EPTYP_CONTROL << STM_USB_DOEPCTL_EPTYP ) |
201                    (0 << STM_USB_DOEPCTL_NAKSTS ) |
202                    (1 << STM_USB_DOEPCTL_USBAEP ) |
203                    (STM_USB_DOEPCTL_MPSIZ0_64 << STM_USB_DOEPCTL_MPSIZ));
204
205         stm_usb.doep[0].doepctl = doepctl;
206
207         /* Clear interrupts */
208         stm_usb.diep[0].diepint = 0xffffffff;
209         stm_usb.doep[0].doepint = 0xffffffff;
210
211         ao_usb_dev_ep_out_start(0);
212 }
213
214 void
215 ao_usb_dev_ep0_in(const void *data, uint16_t len)
216 {
217         return ao_usb_dev_ep_in(0, data, len);
218 }
219
220 bool
221 ao_usb_dev_ep0_in_busy(void)
222 {
223         return false;
224 }
225
226 uint16_t
227 ao_usb_dev_ep0_out(void *data, uint16_t len)
228 {
229         return ao_usb_dev_ep_out(0, data, len);
230 }
231
232 /* Queue IN bytes to EPn */
233 void
234 ao_usb_dev_ep_in(uint8_t ep, const void *data, uint16_t len)
235 {
236         int     l = len;
237
238         while (l > 0) {
239                 stm_usb.dfifo[ep].fifo = *((__packed uint32_t *) data);
240                 l -= 4;
241                 data += 4;
242         }
243
244         /* Set the IN data size */
245         stm_usb.diep[ep].dieptsiz = ((1 << STM_USB_DIEPTSIZ_PKTCNT) |
246                                     (len << STM_USB_DIEPTSIZ_XFRSIZ));
247
248         /* Enable the TX empty interrupt */
249         stm_usb.diepempmsk |= (1 << ep);
250
251         /* Enable the endpoint to queue the packet for transmission */
252         stm_usb.diep[ep].diepctl |= (1 << STM_USB_DIEPCTL_EPENA);
253 }
254
255 bool
256 ao_usb_dev_ep_in_busy(uint8_t ep)
257 {
258         (void) ep;
259         return false;
260 }
261
262 /* Receive OUT bytes from EPn */
263 uint16_t
264 ao_usb_dev_ep_out(uint8_t ep, void *data, uint16_t len)
265 {
266         uint16_t        received;
267         int             l = len;
268         uint32_t        t;
269
270         if (grxstsp_enum() != ep)
271                 return 0;
272
273         received = grxstsp_bcnt();
274         if (received > len)
275                 received = len;
276
277         while (l >= 4) {
278                 *((__packed uint32_t *) data) = stm_usb.dfifo[0].fifo;
279                 l -= 4;
280                 data += 4;
281         }
282
283         if (l != 0) {
284                 t = stm_usb.dfifo[0].fifo;
285                 memcpy(data, &t, l);
286         }
287
288         ao_usb_dev_ep_out_start(ep);
289         return received;
290 }
291
292 void
293 ao_usb_dev_set_address(uint8_t address)
294 {
295         uint32_t        dcfg;
296
297         dcfg = stm_usb.dcfg;
298
299         dcfg &= ~(STM_USB_DCFG_DAD_MASK << STM_USB_DCFG_DAD);
300         dcfg |= address & STM_USB_DCFG_DAD_MASK;
301         stm_usb.dcfg = dcfg;
302 }
303
304 static void
305 ao_usb_core_reset(void)
306 {
307         /* Wait for AHB master IDLE state. */
308         while ((stm_usb.grstctl & (1 << STM_USB_GRSTCTL_AHBIDL)) == 0)
309                 ao_arch_nop();
310
311
312         /* Core soft reset */
313         stm_usb.grstctl |= (1 << STM_USB_GRSTCTL_CSRST);
314
315         /* Wait for reset to complete */
316
317         while ((stm_usb.grstctl & (1 << STM_USB_GRSTCTL_CSRST)) != 0)
318                 ao_arch_nop();
319 }
320
321 static void
322 ao_usb_core_init(void)
323 {
324         /* Enable embedded PHY */
325         stm_usb.gusbcfg |= (1 << STM_USB_GUSBCFG_PHYSEL);
326
327         /* Core reset */
328         ao_usb_core_reset();
329
330         /* Deactivate power down */
331         stm_usb.gccfg = (1 << STM_USB_GCCFG_PWRDWN);
332 }
333
334 static void
335 ao_usb_delay(uint32_t ms)
336 {
337         AO_TICK_TYPE    now = ao_time();
338         AO_TICK_TYPE    then = now + AO_MS_TO_TICKS(ms);
339
340         while ((int16_t) (then - ao_time()) > 0)
341                 ao_arch_nop();
342 }
343
344 static void
345 ao_usb_set_device_mode(void)
346 {
347         uint32_t        gusbcfg;
348
349         gusbcfg = stm_usb.gusbcfg;
350         gusbcfg &= ~((1 << STM_USB_GUSBCFG_FHMOD) |
351                      (1 << STM_USB_GUSBCFG_FDMOD));
352         gusbcfg |= (1 << STM_USB_GUSBCFG_FDMOD);
353         stm_usb.gusbcfg = gusbcfg;
354         ao_usb_delay(50);
355 }
356
357 static void
358 ao_usb_device_init(void)
359 {
360         /* deactivate vbus sensing */
361         stm_usb.gccfg &= ~(1 << STM_USB_GCCFG_VBDEN);
362
363         /* Force device mode */
364         stm_usb.gotgctl |= ((1 << STM_USB_GOTGCTL_BVALOEN) |
365                             (1 << STM_USB_GOTGCTL_BVALOVAL));
366
367         /* Restart the phy clock */
368         stm_usb.pcgcctl = 0;
369
370         /* Device mode configuration */
371         stm_usb.dcfg |= (STM_USB_DCFG_PFIVL_80 << STM_USB_DCFG_PFIVL);
372
373         /* Set full speed phy */
374         stm_usb.dcfg |= (STM_USB_DCFG_DSPD_FULL_SPEED << STM_USB_DCFG_DSPD);
375
376         /* Flush the fifos */
377         ao_usb_flush_tx_fifo(STM_USB_GRSTCTL_TXFNUM_ALL);
378         ao_usb_flush_rx_fifo();
379
380         /* Clear all pending device interrupts */
381         stm_usb.diepmsk = 0;
382         stm_usb.doepmsk = 0;
383         stm_usb.daint = 0xffffffffUL;
384         stm_usb.daintmsk = 0;
385
386         /* Reset all endpoints */
387         for (int i = 0; i < 6; i++) {
388
389                 /* Reset IN endpoint */
390                 if (stm_usb.diep[i].diepctl & (1 << STM_USB_DIEPCTL_EPENA))
391                         stm_usb.diep[i].diepctl = ((1 << STM_USB_DIEPCTL_EPDIS) |
392                                                    (1 << STM_USB_DIEPCTL_SNAK));
393                 else
394                         stm_usb.diep[i].diepctl = 0;
395                 stm_usb.diep[i].dieptsiz = 0;
396                 stm_usb.diep[i].diepint = 0xfffffffful;
397
398                 /* Reset OUT endpoint */
399                 if (stm_usb.doep[i].doepctl & (1 << STM_USB_DOEPCTL_EPENA))
400                         stm_usb.doep[i].doepctl = ((1 << STM_USB_DOEPCTL_EPDIS) |
401                                                    (1 << STM_USB_DOEPCTL_SNAK));
402                 else
403                         stm_usb.doep[i].doepctl = 0;
404
405                 stm_usb.doep[i].doeptsiz = 0;
406                 stm_usb.doep[i].doepint = 0xfffffffful;
407         }
408
409         /* Disable all interrupts */
410         stm_usb.gintmsk = 0;
411
412         /* Clear pending interrupts */
413         stm_usb.gintsts = 0xfffffffful;
414
415         /* Enable core interrupts */
416         stm_usb.gintmsk = ((1 << STM_USB_GINTMSK_WUIM ) |
417                            (0 << STM_USB_GINTMSK_SRQIM ) |
418                            (0 << STM_USB_GINTMSK_DISCINT ) |
419                            (0 << STM_USB_GINTMSK_CIDSCHGM ) |
420                            (0 << STM_USB_GINTMSK_LPMINTM ) |
421                            (0 << STM_USB_GINTMSK_PTXFEM ) |
422                            (0 << STM_USB_GINTMSK_HCIM) |
423                            (0 << STM_USB_GINTMSK_PRTIM ) |
424                            (0 << STM_USB_GINTMSK_RSTDETM ) |
425                            (1 << STM_USB_GINTMSK_IISOOXFRM ) |
426                            (1 << STM_USB_GINTMSK_IISOIXFRM ) |
427                            (1 << STM_USB_GINTMSK_OEPINT) |
428                            (1 << STM_USB_GINTMSK_IEPINT) |
429                            (0 << STM_USB_GINTMSK_EOPFM ) |
430                            (0 << STM_USB_GINTMSK_ISOODRPM ) |
431                            (1 << STM_USB_GINTMSK_ENUMDNEM) |
432                            (1 << STM_USB_GINTMSK_USBRST) |
433                            (1 << STM_USB_GINTMSK_USBSUSPM ) |
434                            (0 << STM_USB_GINTMSK_ESUSPM ) |
435                            (0 << STM_USB_GINTMSK_GONAKEFFM ) |
436                            (0 << STM_USB_GINTMSK_GINAKEFFM ) |
437                            (0 << STM_USB_GINTMSK_NPTXFEM ) |
438                            (0 << STM_USB_GINTMSK_RXFLVLM) |
439                            (0 << STM_USB_GINTMSK_SOFM ) |
440                            (0 << STM_USB_GINTMSK_OTGINT ) |
441                            (0 << STM_USB_GINTMSK_MMISM));
442 }
443
444 static void
445 ao_usb_device_connect(void)
446 {
447         /* Enable pull-up/pull-down */
448         stm_usb.dctl &= ~(1 << STM_USB_DCTL_SDIS);
449         ao_usb_delay(20);
450 }
451
452 #if 0
453 static void
454 ao_usb_device_disconnect(void)
455 {
456         /* Disable pull-up/pull-down */
457         stm_usb.dctl |= (1 << STM_USB_DCTL_SDIS);
458         ao_usb_delay(20);
459 }
460 #endif
461
462 void
463 ao_usb_dev_enable(void)
464 {
465         ao_arch_block_interrupts();
466
467         /* Configure GPIOs */
468         ao_enable_port(&stm_gpioa);
469 #if 0
470         stm_afr_set(&stm_gpioa,  8, STM_AFR_AF10);      /* USB_FS_SOF */
471         stm_afr_set(&stm_gpioa,  9, STM_AFR_AF10);      /* USB_FS_VBUS */
472         stm_afr_set(&stm_gpioa, 10, STM_AFR_AF10);      /* USB_FS_ID */
473 #endif
474         stm_afr_set(&stm_gpioa, 11, STM_AFR_AF10);
475         stm_ospeedr_set(&stm_gpioa, 11, STM_OSPEEDR_HIGH);
476         stm_pupdr_set(&stm_gpioa, 11, STM_PUPDR_NONE);
477         stm_afr_set(&stm_gpioa, 12, STM_AFR_AF10);
478         stm_ospeedr_set(&stm_gpioa, 12, STM_OSPEEDR_HIGH);
479         stm_pupdr_set(&stm_gpioa, 12, STM_PUPDR_NONE);
480
481         /* Power on USB */
482         stm_rcc.ahb2enr |= (1 << STM_RCC_AHB2ENR_OTGFSEN);
483
484         /* Route interrupts */
485         stm_nvic_set_priority(STM_ISR_OTG_FS_POS, AO_STM_NVIC_LOW_PRIORITY);
486         stm_nvic_set_enable(STM_ISR_OTG_FS_POS);
487
488         /* Core init */
489         ao_usb_core_init();
490
491         /* Set device mode */
492         ao_usb_set_device_mode();
493
494         /* Reset FIFO allocations */
495         for (int i = 1; i < 16; i++)
496                 stm_usb.dieptxf[i-1] = 0x0;
497
498         ao_usb_device_init();
499
500         /* Connect */
501         ao_usb_device_connect();
502 }
503
504 void
505 ao_usb_dev_disable(void)
506 {
507         stm_usb.gusbcfg = ((1 << STM_USB_GUSBCFG_FDMOD) |
508                            (0 << STM_USB_GUSBCFG_FHMOD) |
509                            (6 << STM_USB_GUSBCFG_TRDT) |
510                            (0 << STM_USB_GUSBCFG_HNPCAP) |
511                            (0 << STM_USB_GUSBCFG_SRPCAP) |
512                            (1 << STM_USB_GUSBCFG_PHYSEL) |
513                            (0 << STM_USB_GUSBCFG_TOCAL));
514
515         stm_usb.gahbcfg = ((0 << STM_USB_GAHBCFG_PTXFELVL) |
516                            (1 << STM_USB_GAHBCFG_TXFELVL) |
517                            (0 << STM_USB_GAHBCFG_GINTMSK));
518
519         stm_usb.dctl = ((0 << STM_USB_DCTL_POPRGDNE) |
520                         (1 << STM_USB_DCTL_SDIS));
521
522         stm_rcc.ahb2enr &= ~(1 << STM_RCC_AHB2ENR_OTGFSEN);
523 }
524
525 void
526 stm_otg_fs_isr(void)
527 {
528         uint32_t        gintsts = stm_usb.gintsts;
529         uint8_t         ep0_receive = 0;
530         uint32_t        out_interrupt = 0;
531         uint32_t        in_interrupt = 0;
532
533         /* Clear all received interrupts */
534         stm_usb.gintsts = gintsts;
535
536         if (gintsts & (1 << STM_USB_GINTSTS_USBRST)) {
537                 ep0_receive |= AO_USB_EP0_GOT_RESET;
538         }
539
540         if (gintsts & (1 << STM_USB_GINTSTS_ENUMDNE)) {
541                 ao_usb_enum_done();
542         }
543
544         if (gintsts & ((1 << STM_USB_GINTSTS_OEPINT) |
545                        (1 << STM_USB_GINTSTS_IEPINT)))
546         {
547                 uint32_t        daint = stm_usb.daint;
548                 uint32_t        oepint = (daint >> STM_USB_DAINT_OEPINT) & STM_USB_DAINT_OEPINT_MASK;
549                 uint32_t        iepint = (daint >> STM_USB_DAINT_IEPINT) & STM_USB_DAINT_IEPINT_MASK;
550
551                 for (int ep = 0; ep < 6; ep++) {
552                         if (gintsts & (1 << STM_USB_GINTSTS_OEPINT)) {
553                                 if (oepint & (1 << ep)) {
554                                         uint32_t        doepint = stm_usb.doep[ep].doepint;
555
556                                         stm_usb.doep[ep].doepint = doepint;
557                                         if (doepint & (1 << STM_USB_DOEPINT_XFRC)) {
558                                                 if (ep == 0)
559                                                         ep0_receive |= AO_USB_EP0_GOT_SETUP;
560                                                 else
561                                                         out_interrupt |= (1 << ep);
562                                         }
563                                         grxstsp = stm_usb.grxstsp;
564                                 }
565                         }
566
567                         if (gintsts & (1 << STM_USB_GINTSTS_IEPINT)) {
568                                 if (iepint & (1 << ep)) {
569                                         uint32_t        diepint = stm_usb.diep[ep].diepint;
570
571                                         stm_usb.diep[ep].diepint = diepint;
572                                         if (diepint & (1 << STM_USB_DIEPINT_XFRC)) {
573                                                 if (ep == 0)
574                                                         ep0_receive |= AO_USB_EP0_GOT_TX_ACK;
575                                                 else
576                                                         in_interrupt |= (1 << ep);
577                                         }
578                                 }
579                         }
580                 }
581         } else {
582                 grxstsp = 0;
583         }
584
585         if (ep0_receive)
586                 ao_usb_ep0_interrupt(ep0_receive);
587
588         if (out_interrupt)
589                 ao_usb_out_interrupt(out_interrupt);
590
591         if (in_interrupt)
592                 ao_usb_in_interrupt(in_interrupt);
593 }
594
595 /*
596
597   running                               before plugging in              at first packet
598   gotgctl = 0x04cd0000,                 0x04c10000,                     0x04cd0000              *************
599
600       CURMOD = 0
601       OTGVER = 0
602       BSVLD = 1                         BSVLD = 0
603       ASVLD = 1                         ASVLD = 0
604       DBCT = 0
605       CIDSTS = 1
606
607   gotgint = 0x00100000,                 0x00100000,                     0x00100000
608
609       IDCHNG = 1
610
611   gahbcfg = 0x1,                        0x1,                            0x00000001
612
613       TXFELVL = 0       trigger half empty
614       GINTMSK = 1       interrupts enabled
615
616   gusbcfg = 0x40001840,                 0x40001440                      0x40001840              *************
617
618       FDMOD = 1 force device mode
619       FHMOD = 0
620       TRDT = 6                          5                               6
621       HNPCAP = 0
622       SRPCAP = 0
623       PHYSEL = 1
624       TOCAL = 0
625
626   grstctl = 0x80000040,                 0x80000000                      0x80000400              ***********
627
628       AHBIDL = 1
629       TXFNUM = 1                                TXFNUM = 0              TXFNUM = 0x20 (flush all)
630       TXFFLSH = 0
631       RXFFLSH = 0
632       FCRST = 0
633       PSRST = 0
634       CSRST = 0
635
636   gintsts = 0x0480b43a,                 0x04008022                      0x04888438              ***********
637
638       WKUPINT = 0                               0
639       SRQINT = 0                                0
640       DISCINT = 0                               0
641       CIDSCHG = 0                               0
642       LPMINT = 0                                0
643       PTXFE = 1                                 PTXFE = 1               PTXFE = 1
644       HCINT = 0
645       HPRTINT = 0
646       RSTDET = 1                                RSTDET = 0              RSTDET = 1
647       IPXFER = 0
648       IISOIXFR = 0
649       OEPINT = 0                                                        OEPINT = 1
650       IEPINT = 0
651       EOPF = 1                                  EOPF = 1                EOPF = 1
652       ISOODRP = 0
653       ENUMDNE = 1
654       USBRST = 1
655       USBSUSP = 0
656       ESUSP = 1                                                         ESUSP = 1
657       GONAKEFF = 0
658       GINAKEFF = 0
659       NPTXFE = 1                                NPTXFE = 1              NPTXFE = 1
660       RXFLVL = 1                                                        RXFLVL = 1
661       SOF = 1                                                           SOF = 1
662       OTGINT = 0
663       MMIS = 1                                  MMIS = 1                MMIS = 0
664       CMOD = 0
665
666   gintmsk = 0xc03c3814,                 0xc03c3814,
667
668       WUIM = 1
669       SRQIM = 1
670       DISCINT = 0
671       CIDSCHGM = 0
672       LPMINTM = 0
673       PTXFEM = 0
674       HCIM = 0
675       PRTIM = 0
676       RSTDETM = 0
677       IISOOXFRM = 1
678       IISOIXFRM = 1
679       OEPINT = 1
680       IEPINT = 1
681       EOPFM = 0
682       ISOODRPM = 0
683       ENUMDNEM = 1
684       USBRST = 1
685       USBSUSPM = 1
686       ESUSPM =0
687       GONAKEFFM = 0
688       GINAKEFFM = 0
689       NPTXFEM = 0
690       RXFLVLM = 1
691       SOFM = 0
692       OTGINT = 1
693       MMISM = 0
694
695   grxstsr = 0xac0080,                   0x0                             0x14c0080       ***************
696
697       STSPHST = 0                                                       STSPHST = 0
698       FRMNUM = 5                                                        FRMNUM = 10
699       PKTSTS = 6        -- SETUP data packet                            PKTSTS = 6 -- SETUP data packet
700       DPID = 0                                                          DPID = 0
701       BCNT = 8                                                          BCNT = 8
702       EPNUM = 0                                                         EPNUM = 0
703
704   grxstsp = 0xac0080,                   0x0                             0x14c0080
705
706       (same)
707
708   grxfsiz = 0x80,                       0x80                            0x80
709
710       RXFD = 128        512 bytes
711
712   dieptxf0 = 0x00400080,                0x00400080                      0x00400080
713
714       TX0FD = 64        256 bytes
715       TX0FSA = 0x80
716
717   gccfg = 0x21fff0,                     0x21fff0                        0x21fff0
718
719       VBDEN = 1
720       SDEN = 0
721       PDEN = 0
722       DCDEN = 0
723       BCDEN = 0
724       PWRDN = 1
725       PS2DET = 0
726       SDET = 0
727       PDET = 0
728       DCDET = 0
729
730   cid = 0x2000,                         0x2000                          0x2000
731
732       PRODUCT_ID = 0x2000
733
734   glpmcfg = 0x0,                        0x0                             0x0
735
736       ENBESL = 0
737       LPMRCNTTST = 0
738       SNDLPM = 0
739       LPMRCNT = 0
740       LPMCHIDX = 0
741       L1RSMOK = 0
742       SLPSTS = 0
743       LPMRSP = 0
744       L1DSEN = 0
745       BESLTHRS = 0
746       L1SSEN = 0
747       REMWAKE = 0
748       BESL = 0
749       LPMACK = 0
750       LPMEN = 0
751
752   dieptxf = {0x8000c0, 0x0, 0x0, 0x0, 0x0},     {0x8000c0, 0x0, 0x0, 0x0, 0x0}, {0x8000c0, 0x0, 0x0, 0x0, 0x0}, 
753
754       INEXPTXFD 0 = 0x80        512 bytes
755       INEXPTXSA 0 = 0xc0
756
757   dcfg = 0x82000b3,                     0x8200003,                      0x8200003
758
759       ERRATIM = 0
760       PFIVL = 0
761       DAD = 0xb                         DAD = 0x0                       DAD = 0
762       NZLSOHSK = 0
763       DSPD = 3  Full speed USB 1.1
764
765   dctl = 0x0,                           0x0                             0x0
766
767       DSBESLRJCT = 0
768       POPRGDNE = 0
769       CGONAK = 0
770       SGONAK = 0
771       CGINAK = 0
772       SGINAK = 0
773       TCTL = 0
774       GONSTS = 0
775       GINSTS = 0
776       SDIS = 0
777       RWUSIG = 0
778
779   dsts = 0x0043ff06,                    0x00000006                      0x00400c06
780
781       DEVLNSTS = 1      (D+ low, D- high)
782       FNSOF = 0x3ff                                                     FNSOF = 0xc
783       EERR = 0
784       ENUMSPD = 3       Full speed                                      ENUMSPD = 3
785       SUSPSTS = 0                                                       SUSPSTS = 0
786
787   diepmsk = 0xb,                        0x0                             0xb
788
789       NAKM = 0
790       TXFURM = 0
791       INEPNEM = 0
792       INEPNMM = 0
793       ITTXFEMSK = 0
794       TOM = 1
795       EPDM = 1
796       XFRCM = 1
797
798   doepmsk = 0x2b,                       0x0                             0x2b
799
800       NYETMSK = 0
801       NAKMSK = 0
802       BERRM =0
803       OUTPKTERRM = 0
804       STSPHSRXM = 1
805       OTEPDM = 0
806       STUPM = 1
807       EPDM = 1
808       XFRCM = 1
809
810   daint = 0x0,                          0x0                     0x10000
811
812   daintmsk = 0x30003,                   0x0                     0x10001
813
814       OEPM = 0x3        endpoints 0 and 1                       OEPM = 0x1      endpoint 0
815       IEPM = 0x3        endpoints 0 and 1                       IEPM = 0x1      endpoint 0
816
817   dvbusdis = 0x17d7,                    0x17d7                  0x17d7
818
819       VBUSDT = 0x17d7   reset value
820
821   dvbuspulse = 0x5b8,                   0x5b8                   0x5b8
822
823       DVBUSP = 0x5b8    reset value
824
825   diepempmsk = 0x0,                     0x0                     0x0
826
827       INEPTXFEM = 0             no endpoints
828
829   diep = {{
830       diepctl = 0x28000,
831
832           EPENA = 0
833           EPDIS = 0
834           SNAK = 0
835           CNAK = 0
836           TXFNUM = 0
837           STALL = 0
838           EPTYP = 0
839           NAKSTS = 1
840           USBAEP = 1
841           MPSIZ = 0             64 bytes
842
843       diepint = 0x20c0,
844
845           NAK = 1
846           PKTDRPSTS = 0
847           TXFIFOUDRN = 0
848           TXFE = 1
849           INEPNE = 1
850           ITTXFE = 0
851           TOC = 0
852           EPDISD = 0
853           XFRC = 0
854
855       dieptsiz = 0x0,
856
857           PKTCNT = 0
858           XFRSIZ = 0
859
860       dtxfsts = 0x40,
861
862           INEPTFSAV = 0x40      256 bytes available
863
864     }, {
865       diepctl = 0x00490040,
866
867           EPENA = 0
868           EPDIS = 0
869           SODDFRM = 0
870           SD0PID  = 0
871           SNAK = 0
872           CNAK = 0
873           TXFNUM = 1
874           STALL = 0
875           EPTYP = 2             bulk
876           NAKSTS = 0
877           EONUM = 1
878           USBAEP = 0
879           MPSIZ = 64    256 bytes
880
881       diepint = 0x2090,
882
883           NAK = 1
884           PKTDRPSTS = 0
885           TXFIFOUDRN = 0
886           TXFE = 1
887           INEPNE = 0
888           INPENM = 0
889           ITTXFE = 1
890           TOC = 0
891           EPDISD = 0
892           XFRC = 0
893
894       dieptsiz = 0x0,
895
896           MCNT = 0
897           PKTCNT = 0
898           XFRSIZ = 0
899
900       dtxfsts = 0x80,
901
902           INEPTFSAV = 0x80              512 bytes available
903
904     }, {
905       diepctl = 0x0,
906       pad_04 = 0x0,
907       diepint = 0x80,
908       pad_0c = 0x0,
909       dieptsiz = 0x0,
910       pad_14 = 0x43425355,
911       dtxfsts = 0x40,
912       pad_1c = 0x400000
913     }, {
914       diepctl = 0x0,
915       pad_04 = 0x0,
916       diepint = 0x80,
917       pad_0c = 0x0,
918       dieptsiz = 0x0,
919       pad_14 = 0x43425355,
920       dtxfsts = 0x40,
921       pad_1c = 0x400000
922     }, {
923       diepctl = 0x0,
924       pad_04 = 0x0,
925       diepint = 0x80,
926       pad_0c = 0x0,
927       dieptsiz = 0x0,
928       pad_14 = 0x43425355,
929       dtxfsts = 0x40,
930       pad_1c = 0x400000
931     }, {
932       diepctl = 0x0,
933       pad_04 = 0x0,
934       diepint = 0x80,
935       pad_0c = 0x0,
936       dieptsiz = 0x0,
937       pad_14 = 0x43425355,
938       dtxfsts = 0x40,
939       pad_1c = 0x400000
940     }},
941
942   doep = {{
943       doepctl = 0x80028000,             0x00008000,                     0x28000
944
945           EPENA = 1                         EPENA = 0                   EPENA = 0
946           EPDIS = 0
947           SNAK =0
948           CNAK = 0
949           STALL = 0
950           SNPM = 0
951           EPTYP = 0
952           NAKSTS = 1                        NAKSTS = 0                  NAKSTS = 1
953           USPAEP = 1                                                    USPAEP = 1
954           MPSIZ = 0             64 bytes                                MPSIZ = 0
955
956       doepint = 0x8010,                 0x0                             0x8008
957
958           NYET = 0
959           NAK = 0
960           BERR = 0
961           OUTPKTERR = 0
962           STSPHSRX = 0
963           OTEPDIS = 1
964           STUP = 0                                                      STUP = 1
965           EPDISD = 0
966           XFRC = 0
967
968       doeptsiz = 0x38,                  0x0                             0x20080008
969
970           STPCNT = 0    1 packet                                        STPCNT = 1
971           PKTCNT = 0                                                    PKTCNT = 1
972           XFRSIZ = 0x38 56 bytes (64 - 8)                               XFRSIZ = 8
973
974     }, {
975       doepctl = 0x800b0040,
976
977           EPENA = 1
978           EPDIS = 0
979           SD1PID = 0
980           SD0PID = 0
981           SNAK = 0
982           CNAK = 0
983           STALL = 0
984           SNPM =0
985           EPTYP = 2             Bulk
986           NAKSTS = 1
987           EONUM = 1
988           USBAEP = 0
989           MPSIZ = 0x40  64 bytes
990
991       doepint = 0x0,
992       doeptsiz = 0x21,
993
994           RXDPID = 0
995           PKTCNT = 0
996           XFRSIZ = 0x21    33 bytes ?
997
998     }, {
999       doepctl = 0x0,
1000       pad_04 = 0x0,
1001       doepint = 0x0,
1002       pad_0c = 0x0,
1003       doeptsiz = 0x0,
1004       pad_14 = 0x43425355,
1005       pad_18 = 0x40,
1006       pad_1c = 0x400000
1007     }, {
1008       doepctl = 0x0,
1009       pad_04 = 0x0,
1010       doepint = 0x0,
1011       pad_0c = 0x0,
1012       doeptsiz = 0x0,
1013       pad_14 = 0x43425355,
1014       pad_18 = 0x40,
1015       pad_1c = 0x400000
1016     }, {
1017       doepctl = 0x0,
1018       pad_04 = 0x0,
1019       doepint = 0x0,
1020       pad_0c = 0x0,
1021       doeptsiz = 0x0,
1022       pad_14 = 0x43425355,
1023       pad_18 = 0x40,
1024       pad_1c = 0x400000
1025     }, {
1026       doepctl = 0x0,
1027       pad_04 = 0x0,
1028       doepint = 0x0,
1029       pad_0c = 0x0,
1030       doeptsiz = 0x0,
1031       pad_14 = 0x43425355,
1032       pad_18 = 0x40,
1033       pad_1c = 0x400000
1034     }},
1035
1036   pcgcctl = 0x0,                0x0,                    0x0
1037
1038       SUSP = 0
1039       PHYSLEEP = 0
1040       ENL1GTG = 0
1041       PHYSUSP = 0
1042       GATEHCLK = 0
1043       STPPCLK = 0
1044
1045   dfifo = {{
1046         fifo =                                          0x1000680,
1047                                                                 
1048
1049       Clock configuration:
1050
1051 $5 = {
1052   cr = 0x0f077d83, 
1053
1054         PLLI2SRDY = 1
1055         PLLI2SON = 1
1056         PLLRDY = 1
1057         PLLON = 1
1058         CSSON = 0
1059         HSEBYP = 1
1060         HSERDY = 1
1061         HSEON = 1
1062         HSICAL = 0x7d
1063         HSITRIM = 0x10
1064         HSIRDY = 1
1065         HSION = 1
1066
1067   pllcfgr = 0x27403208,
1068
1069         PLLR = 2
1070         PLLQ = 7
1071         PLLSRC = 1      HSE
1072         PLLP = 0        2               
1073         PLLN = 0xc8     200
1074         PLLM = 8
1075
1076                 clk_pllin = 8000000 / 8 = 1000000
1077                 vco = 1000000 * 200 = 200000000
1078                 clk_pll1p = 200000000 / 2 = 100000000 (100MHz)
1079                 clk_pll1q = 200000000 / 7 = ???
1080                 clk_pll1r = 200000000 / 2 = 100000000 (100MHz)
1081
1082   cfgr = 0x0000100a, 
1083   cir = 0x00000000, 
1084   ahb1rstr = 0x0, 
1085   ahb2rstr = 0x0, 
1086   ahb3rstr = 0x0, 
1087   pad_1c = 0x0, 
1088   apb1rstr = 0x0, 
1089   apb2rstr = 0x0, 
1090   pad_28 = 0x0, 
1091   pad_2c = 0x0, 
1092   ahb1enr = 0x40107f, 
1093   ahb2enr = 0x80, 
1094   ahbdnr = 0x3, 
1095   pad_3c = 0x0, 
1096   apb1enr = 0x11000410, 
1097   apb2enr = 0xc800, 
1098   pad_48 = 0x0, 
1099   pad_4c = 0x0, 
1100   ahb1lpenr = 0x6390ff, 
1101   ahb2lpenr = 0xd0, 
1102   ahb3lpenr = 0x3, 
1103   pad_5c = 0x0, 
1104   apb1lpenr = 0xfffecfff, 
1105   apb2lpenr = 0x357f9f3, 
1106   pad_68 = 0x0, 
1107   pad_6c = 0x0, 
1108   bdcr = 0x8200, 
1109   csr = 0x1e000003, 
1110   pad_78 = 0x0, 
1111   pad_7c = 0x0, 
1112   sscgr = 0x0, 
1113   plli2scfgr = 0x44003008, 
1114
1115         PLLI2SR = 4
1116         PLLI2SQ = 4
1117         PLLI2SSRC = 0   HSE (due to PLLSRC)
1118         PLLI2SN = 0xc0  192
1119         PLLI2SM = 8
1120
1121                 clk_plli2sin = 8000000 / 8 = 1000000
1122                 vcoi2s = 1000000 * 192 = 192000000
1123                 ck_pl2q = 192000000 / 4 = 48000000
1124                 ck_pl2r = 192000000 / 4 = 48000000
1125
1126   pad_88 = 0x0, 
1127   dckcfgr = 0x0, 
1128
1129
1130   ckgatenr = 0x0,
1131
1132         All clock gates enabled
1133
1134   dckcfgr2 = 0x08000000
1135
1136         LPTIMER1SEL = 0         APB
1137         CKSDIOSEL = 0           CK_48MHz
1138         CK48MSEL = 1            PLLI2S_Q
1139         I2CFMP1SEL = 0          APB
1140 }
1141       
1142
1143
1144 */