]> git.gag.com Git - fw/altos/blob - src/stm32f4/ao_usb_stm32f4.c
Add TeleMetrum v4.0 firmware to releases
[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         const uint8_t *data = _data;
237         int     l = len;
238
239         while (l > 0) {
240                 uint32_t d;
241                 memcpy(&d, data, 4);
242                 stm_usb.dfifo[ep].fifo = d;
243                 l -= 4;
244                 data += 4;
245         }
246
247         /* Set the IN data size */
248         stm_usb.diep[ep].dieptsiz = ((1 << STM_USB_DIEPTSIZ_PKTCNT) |
249                                     (len << STM_USB_DIEPTSIZ_XFRSIZ));
250
251         /* Enable the TX empty interrupt */
252         stm_usb.diepempmsk |= (1 << ep);
253
254         /* Enable the endpoint to queue the packet for transmission */
255         stm_usb.diep[ep].diepctl |= (1 << STM_USB_DIEPCTL_EPENA);
256 }
257
258 bool
259 ao_usb_dev_ep_in_busy(uint8_t ep)
260 {
261         (void) ep;
262         return false;
263 }
264
265 /* Receive OUT bytes from EPn */
266 uint16_t
267 ao_usb_dev_ep_out(uint8_t ep, void *_data, uint16_t len)
268 {
269         uint8_t         *data = _data;
270         uint16_t        received;
271         int             l = len;
272         uint32_t        t;
273
274         if (grxstsp_enum() != ep)
275                 return 0;
276
277         received = grxstsp_bcnt();
278         if (received > len)
279                 received = len;
280
281         while (l >= 4) {
282                 uint32_t d;
283                 d = stm_usb.dfifo[0].fifo;
284                 memcpy(data, &d, 4);
285                 l -= 4;
286                 data += 4;
287         }
288
289         if (l != 0) {
290                 t = stm_usb.dfifo[0].fifo;
291                 memcpy(data, &t, l);
292         }
293
294         ao_usb_dev_ep_out_start(ep);
295         return received;
296 }
297
298 void
299 ao_usb_dev_set_address(uint8_t address)
300 {
301         uint32_t        dcfg;
302
303         dcfg = stm_usb.dcfg;
304
305         dcfg &= ~(STM_USB_DCFG_DAD_MASK << STM_USB_DCFG_DAD);
306         dcfg |= address & STM_USB_DCFG_DAD_MASK;
307         stm_usb.dcfg = dcfg;
308 }
309
310 static void
311 ao_usb_core_reset(void)
312 {
313         /* Wait for AHB master IDLE state. */
314         while ((stm_usb.grstctl & (1 << STM_USB_GRSTCTL_AHBIDL)) == 0)
315                 ao_arch_nop();
316
317
318         /* Core soft reset */
319         stm_usb.grstctl |= (1 << STM_USB_GRSTCTL_CSRST);
320
321         /* Wait for reset to complete */
322
323         while ((stm_usb.grstctl & (1 << STM_USB_GRSTCTL_CSRST)) != 0)
324                 ao_arch_nop();
325 }
326
327 static void
328 ao_usb_core_init(void)
329 {
330         /* Enable embedded PHY */
331         stm_usb.gusbcfg |= (1 << STM_USB_GUSBCFG_PHYSEL);
332
333         /* Core reset */
334         ao_usb_core_reset();
335
336         /* Deactivate power down */
337         stm_usb.gccfg = (1 << STM_USB_GCCFG_PWRDWN);
338 }
339
340 static void
341 ao_usb_delay(uint32_t ms)
342 {
343         AO_TICK_TYPE    now = ao_time();
344         AO_TICK_TYPE    then = now + AO_MS_TO_TICKS(ms);
345
346         while ((int16_t) (then - ao_time()) > 0)
347                 ao_arch_nop();
348 }
349
350 static void
351 ao_usb_set_device_mode(void)
352 {
353         uint32_t        gusbcfg;
354
355         gusbcfg = stm_usb.gusbcfg;
356         gusbcfg &= ~((1 << STM_USB_GUSBCFG_FHMOD) |
357                      (1 << STM_USB_GUSBCFG_FDMOD));
358         gusbcfg |= (1 << STM_USB_GUSBCFG_FDMOD);
359         stm_usb.gusbcfg = gusbcfg;
360         ao_usb_delay(50);
361 }
362
363 static void
364 ao_usb_device_init(void)
365 {
366         /* deactivate vbus sensing */
367         stm_usb.gccfg |= (1 << STM_USB_GCCFG_VBDEN);
368
369         stm_usb.gccfg &= ~(1 << STM_USB_GCCFG_VBDEN);
370
371         /* Force device mode */
372         stm_usb.gotgctl |= ((1 << STM_USB_GOTGCTL_BVALOEN) |
373                             (1 << STM_USB_GOTGCTL_BVALOVAL));
374
375         /* Restart the phy clock */
376         stm_usb.pcgcctl = 0;
377
378         /* Device mode configuration */
379         stm_usb.dcfg |= (STM_USB_DCFG_PFIVL_80 << STM_USB_DCFG_PFIVL);
380
381         /* Set full speed phy */
382         stm_usb.dcfg |= (STM_USB_DCFG_DSPD_FULL_SPEED << STM_USB_DCFG_DSPD);
383
384         /* Flush the fifos */
385         ao_usb_flush_tx_fifo(STM_USB_GRSTCTL_TXFNUM_ALL);
386         ao_usb_flush_rx_fifo();
387
388         /* Clear all pending device interrupts */
389         stm_usb.diepmsk = 0;
390         stm_usb.doepmsk = 0;
391         stm_usb.daint = 0xffffffffUL;
392         stm_usb.daintmsk = 0;
393
394         /* Reset all endpoints */
395         for (int i = 0; i < 6; i++) {
396
397                 /* Reset IN endpoint */
398                 if (stm_usb.diep[i].diepctl & (1 << STM_USB_DIEPCTL_EPENA))
399                         stm_usb.diep[i].diepctl = ((1 << STM_USB_DIEPCTL_EPDIS) |
400                                                    (1 << STM_USB_DIEPCTL_SNAK));
401                 else
402                         stm_usb.diep[i].diepctl = 0;
403                 stm_usb.diep[i].dieptsiz = 0;
404                 stm_usb.diep[i].diepint = 0xffu;
405         }
406
407         for (int i = 0; i < 6; i++) {
408                 /* Reset OUT endpoint */
409                 if (stm_usb.doep[i].doepctl & (1 << STM_USB_DOEPCTL_EPENA))
410                         stm_usb.doep[i].doepctl = ((1 << STM_USB_DOEPCTL_EPDIS) |
411                                                    (1 << STM_USB_DOEPCTL_SNAK));
412                 else
413                         stm_usb.doep[i].doepctl = 0;
414
415                 stm_usb.doep[i].doeptsiz = 0;
416                 stm_usb.doep[i].doepint = 0xffu;
417         }
418
419         stm_usb.diepmsk &= ~(1 << STM_USB_DIEPMSK_TXFURM);
420
421         /* Disable all interrupts */
422         stm_usb.gintmsk = 0;
423
424         /* Clear pending interrupts */
425         stm_usb.gintsts = 0xfffffffful;
426
427         /* Enable core interrupts */
428         stm_usb.gintmsk = ((1 << STM_USB_GINTMSK_WUIM ) |
429                            (0 << STM_USB_GINTMSK_SRQIM ) |
430                            (0 << STM_USB_GINTMSK_DISCINT ) |
431                            (0 << STM_USB_GINTMSK_CIDSCHGM ) |
432                            (0 << STM_USB_GINTMSK_LPMINTM ) |
433                            (0 << STM_USB_GINTMSK_PTXFEM ) |
434                            (0 << STM_USB_GINTMSK_HCIM) |
435                            (0 << STM_USB_GINTMSK_PRTIM ) |
436                            (0 << STM_USB_GINTMSK_RSTDETM ) |
437                            (1 << STM_USB_GINTMSK_IISOOXFRM ) |
438                            (1 << STM_USB_GINTMSK_IISOIXFRM ) |
439                            (1 << STM_USB_GINTMSK_OEPINT) |
440                            (1 << STM_USB_GINTMSK_IEPINT) |
441                            (0 << STM_USB_GINTMSK_EOPFM ) |
442                            (0 << STM_USB_GINTMSK_ISOODRPM ) |
443                            (1 << STM_USB_GINTMSK_ENUMDNEM) |
444                            (1 << STM_USB_GINTMSK_USBRST) |
445                            (1 << STM_USB_GINTMSK_USBSUSPM ) |
446                            (0 << STM_USB_GINTMSK_ESUSPM ) |
447                            (0 << STM_USB_GINTMSK_GONAKEFFM ) |
448                            (0 << STM_USB_GINTMSK_GINAKEFFM ) |
449                            (0 << STM_USB_GINTMSK_NPTXFEM ) |
450                            (0 << STM_USB_GINTMSK_RXFLVLM) |
451                            (0 << STM_USB_GINTMSK_SOFM ) |
452                            (0 << STM_USB_GINTMSK_OTGINT ) |
453                            (0 << STM_USB_GINTMSK_MMISM));
454 }
455
456 static void
457 ao_usb_device_connect(void)
458 {
459         /* Enable pull-up/pull-down */
460         stm_usb.dctl &= ~(1 << STM_USB_DCTL_SDIS);
461         ao_usb_delay(20);
462 }
463
464 static void
465 ao_usb_device_disconnect(void)
466 {
467         /* Disable pull-up/pull-down */
468         stm_usb.dctl |= (1 << STM_USB_DCTL_SDIS);
469         ao_usb_delay(20);
470 }
471
472 static void
473 ao_usb_dev_start(void)
474 {
475         ao_usb_device_connect();
476         stm_usb.gahbcfg |= (1 << STM_USB_GAHBCFG_GINTMSK);
477 }
478
479 void
480 ao_usb_dev_enable(void)
481 {
482         ao_arch_block_interrupts();
483
484         /* Configure GPIOs */
485         ao_enable_port(&stm_gpioa);
486 #if 0
487         stm_afr_set(&stm_gpioa,  8, STM_AFR_AF10);      /* USB_FS_SOF */
488         stm_afr_set(&stm_gpioa,  9, STM_AFR_AF10);      /* USB_FS_VBUS */
489         stm_afr_set(&stm_gpioa, 10, STM_AFR_AF10);      /* USB_FS_ID */
490 #endif
491         stm_afr_set(&stm_gpioa, 11, STM_AFR_AF10);
492         stm_ospeedr_set(&stm_gpioa, 11, STM_OSPEEDR_HIGH);
493         stm_pupdr_set(&stm_gpioa, 11, STM_PUPDR_NONE);
494
495         stm_afr_set(&stm_gpioa, 12, STM_AFR_AF10);
496         stm_ospeedr_set(&stm_gpioa, 12, STM_OSPEEDR_HIGH);
497         stm_pupdr_set(&stm_gpioa, 12, STM_PUPDR_NONE);
498
499         /* Power on USB */
500         stm_rcc_ahb2_clk_enable(1 << STM_RCC_AHB2ENR_OTGFSEN);
501
502         /* Route interrupts */
503         stm_nvic_set_priority(STM_ISR_OTG_FS_POS, AO_STM_NVIC_LOW_PRIORITY);
504         stm_nvic_set_enable(STM_ISR_OTG_FS_POS);
505
506         ao_arch_release_interrupts();
507
508         /* Core init */
509         ao_usb_core_init();
510
511         /* Set device mode */
512         ao_usb_set_device_mode();
513
514         /* Reset FIFO allocations */
515         for (int i = 1; i < 16; i++)
516                 stm_usb.dieptxf[i-1] = 0x0;
517
518         ao_usb_device_init();
519
520         /* Disconnect */
521         ao_usb_device_disconnect();
522
523         /* Start */
524         ao_usb_dev_start();
525 }
526
527 void
528 ao_usb_dev_disable(void)
529 {
530         ao_usb_device_disconnect();
531
532         stm_usb.gusbcfg = ((1 << STM_USB_GUSBCFG_FDMOD) |
533                            (0 << STM_USB_GUSBCFG_FHMOD) |
534                            (6 << STM_USB_GUSBCFG_TRDT) |
535                            (0 << STM_USB_GUSBCFG_HNPCAP) |
536                            (0 << STM_USB_GUSBCFG_SRPCAP) |
537                            (1 << STM_USB_GUSBCFG_PHYSEL) |
538                            (0 << STM_USB_GUSBCFG_TOCAL));
539
540         stm_usb.gahbcfg = ((0 << STM_USB_GAHBCFG_PTXFELVL) |
541                            (1 << STM_USB_GAHBCFG_TXFELVL) |
542                            (0 << STM_USB_GAHBCFG_GINTMSK));
543
544         stm_usb.dctl = ((0 << STM_USB_DCTL_POPRGDNE) |
545                         (1 << STM_USB_DCTL_SDIS));
546
547         stm_rcc_ahb2_clk_disable(1 << STM_RCC_AHB2ENR_OTGFSEN);
548 }
549
550 void
551 stm_otg_fs_isr(void)
552 {
553         uint32_t        gintsts = stm_usb.gintsts;
554         uint8_t         ep0_receive = 0;
555         uint32_t        out_interrupt = 0;
556         uint32_t        in_interrupt = 0;
557
558         /* Clear all received interrupts */
559         stm_usb.gintsts = gintsts;
560
561         if (gintsts & (1 << STM_USB_GINTSTS_USBRST)) {
562                 ep0_receive |= AO_USB_EP0_GOT_RESET;
563         }
564
565         if (gintsts & (1 << STM_USB_GINTSTS_ENUMDNE)) {
566                 ao_usb_enum_done();
567         }
568
569         if (gintsts & ((1 << STM_USB_GINTSTS_OEPINT) |
570                        (1 << STM_USB_GINTSTS_IEPINT)))
571         {
572                 uint32_t        daint = stm_usb.daint;
573                 uint32_t        oepint = (daint >> STM_USB_DAINT_OEPINT) & STM_USB_DAINT_OEPINT_MASK;
574                 uint32_t        iepint = (daint >> STM_USB_DAINT_IEPINT) & STM_USB_DAINT_IEPINT_MASK;
575
576                 for (int ep = 0; ep < 6; ep++) {
577                         if (gintsts & (1 << STM_USB_GINTSTS_OEPINT)) {
578                                 if (oepint & (1 << ep)) {
579                                         uint32_t        doepint = stm_usb.doep[ep].doepint;
580
581                                         stm_usb.doep[ep].doepint = doepint;
582                                         if (doepint & (1 << STM_USB_DOEPINT_XFRC)) {
583                                                 if (ep == 0)
584                                                         ep0_receive |= AO_USB_EP0_GOT_SETUP;
585                                                 else
586                                                         out_interrupt |= (1 << ep);
587                                         }
588                                         grxstsp = stm_usb.grxstsp;
589                                 }
590                         }
591
592                         if (gintsts & (1 << STM_USB_GINTSTS_IEPINT)) {
593                                 if (iepint & (1 << ep)) {
594                                         uint32_t        diepint = stm_usb.diep[ep].diepint;
595
596                                         stm_usb.diep[ep].diepint = diepint;
597                                         if (diepint & (1 << STM_USB_DIEPINT_XFRC)) {
598                                                 if (ep == 0)
599                                                         ep0_receive |= AO_USB_EP0_GOT_TX_ACK;
600                                                 else
601                                                         in_interrupt |= (1 << ep);
602                                         }
603                                 }
604                         }
605                 }
606         } else {
607                 grxstsp = 0;
608         }
609
610         if (ep0_receive)
611                 ao_usb_ep0_interrupt(ep0_receive);
612
613         if (out_interrupt)
614                 ao_usb_out_interrupt(out_interrupt);
615
616         if (in_interrupt)
617                 ao_usb_in_interrupt(in_interrupt);
618 }
619
620 /*
621
622   running                               before plugging in              at first packet
623   gotgctl = 0x04cd0000,                 0x04c10000,                     0x04cd0000              *************
624
625       CURMOD = 0
626       OTGVER = 0
627       BSVLD = 1                         BSVLD = 0
628       ASVLD = 1                         ASVLD = 0
629       DBCT = 0
630       CIDSTS = 1
631
632   gotgint = 0x00100000,                 0x00100000,                     0x00100000
633
634       IDCHNG = 1
635
636   gahbcfg = 0x1,                        0x1,                            0x00000001
637
638       TXFELVL = 0       trigger half empty
639       GINTMSK = 1       interrupts enabled
640
641   gusbcfg = 0x40001840,                 0x40001440                      0x40001840              *************
642
643       FDMOD = 1 force device mode
644       FHMOD = 0
645       TRDT = 6                          5                               6
646       HNPCAP = 0
647       SRPCAP = 0
648       PHYSEL = 1
649       TOCAL = 0
650
651   grstctl = 0x80000040,                 0x80000000                      0x80000400              ***********
652
653       AHBIDL = 1
654       TXFNUM = 1                                TXFNUM = 0              TXFNUM = 0x20 (flush all)
655       TXFFLSH = 0
656       RXFFLSH = 0
657       FCRST = 0
658       PSRST = 0
659       CSRST = 0
660
661   gintsts = 0x0480b43a,                 0x04008022                      0x04888438              ***********
662
663       WKUPINT = 0                               0
664       SRQINT = 0                                0
665       DISCINT = 0                               0
666       CIDSCHG = 0                               0
667       LPMINT = 0                                0
668       PTXFE = 1                                 PTXFE = 1               PTXFE = 1
669       HCINT = 0
670       HPRTINT = 0
671       RSTDET = 1                                RSTDET = 0              RSTDET = 1
672       IPXFER = 0
673       IISOIXFR = 0
674       OEPINT = 0                                                        OEPINT = 1
675       IEPINT = 0
676       EOPF = 1                                  EOPF = 1                EOPF = 1
677       ISOODRP = 0
678       ENUMDNE = 1
679       USBRST = 1
680       USBSUSP = 0
681       ESUSP = 1                                                         ESUSP = 1
682       GONAKEFF = 0
683       GINAKEFF = 0
684       NPTXFE = 1                                NPTXFE = 1              NPTXFE = 1
685       RXFLVL = 1                                                        RXFLVL = 1
686       SOF = 1                                                           SOF = 1
687       OTGINT = 0
688       MMIS = 1                                  MMIS = 1                MMIS = 0
689       CMOD = 0
690
691   gintmsk = 0xc03c3814,                 0xc03c3814,
692
693       WUIM = 1
694       SRQIM = 1
695       DISCINT = 0
696       CIDSCHGM = 0
697       LPMINTM = 0
698       PTXFEM = 0
699       HCIM = 0
700       PRTIM = 0
701       RSTDETM = 0
702       IISOOXFRM = 1
703       IISOIXFRM = 1
704       OEPINT = 1
705       IEPINT = 1
706       EOPFM = 0
707       ISOODRPM = 0
708       ENUMDNEM = 1
709       USBRST = 1
710       USBSUSPM = 1
711       ESUSPM =0
712       GONAKEFFM = 0
713       GINAKEFFM = 0
714       NPTXFEM = 0
715       RXFLVLM = 1
716       SOFM = 0
717       OTGINT = 1
718       MMISM = 0
719
720   grxstsr = 0xac0080,                   0x0                             0x14c0080       ***************
721
722       STSPHST = 0                                                       STSPHST = 0
723       FRMNUM = 5                                                        FRMNUM = 10
724       PKTSTS = 6        -- SETUP data packet                            PKTSTS = 6 -- SETUP data packet
725       DPID = 0                                                          DPID = 0
726       BCNT = 8                                                          BCNT = 8
727       EPNUM = 0                                                         EPNUM = 0
728
729   grxstsp = 0xac0080,                   0x0                             0x14c0080
730
731       (same)
732
733   grxfsiz = 0x80,                       0x80                            0x80
734
735       RXFD = 128        512 bytes
736
737   dieptxf0 = 0x00400080,                0x00400080                      0x00400080
738
739       TX0FD = 64        256 bytes
740       TX0FSA = 0x80
741
742   gccfg = 0x21fff0,                     0x21fff0                        0x21fff0
743
744       VBDEN = 1
745       SDEN = 0
746       PDEN = 0
747       DCDEN = 0
748       BCDEN = 0
749       PWRDN = 1
750       PS2DET = 0
751       SDET = 0
752       PDET = 0
753       DCDET = 0
754
755   cid = 0x2000,                         0x2000                          0x2000
756
757       PRODUCT_ID = 0x2000
758
759   glpmcfg = 0x0,                        0x0                             0x0
760
761       ENBESL = 0
762       LPMRCNTTST = 0
763       SNDLPM = 0
764       LPMRCNT = 0
765       LPMCHIDX = 0
766       L1RSMOK = 0
767       SLPSTS = 0
768       LPMRSP = 0
769       L1DSEN = 0
770       BESLTHRS = 0
771       L1SSEN = 0
772       REMWAKE = 0
773       BESL = 0
774       LPMACK = 0
775       LPMEN = 0
776
777   dieptxf = {0x8000c0, 0x0, 0x0, 0x0, 0x0},     {0x8000c0, 0x0, 0x0, 0x0, 0x0}, {0x8000c0, 0x0, 0x0, 0x0, 0x0}, 
778
779       INEXPTXFD 0 = 0x80        512 bytes
780       INEXPTXSA 0 = 0xc0
781
782   dcfg = 0x82000b3,                     0x8200003,                      0x8200003
783
784       ERRATIM = 0
785       PFIVL = 0
786       DAD = 0xb                         DAD = 0x0                       DAD = 0
787       NZLSOHSK = 0
788       DSPD = 3  Full speed USB 1.1
789
790   dctl = 0x0,                           0x0                             0x0
791
792       DSBESLRJCT = 0
793       POPRGDNE = 0
794       CGONAK = 0
795       SGONAK = 0
796       CGINAK = 0
797       SGINAK = 0
798       TCTL = 0
799       GONSTS = 0
800       GINSTS = 0
801       SDIS = 0
802       RWUSIG = 0
803
804   dsts = 0x0043ff06,                    0x00000006                      0x00400c06
805
806       DEVLNSTS = 1      (D+ low, D- high)
807       FNSOF = 0x3ff                                                     FNSOF = 0xc
808       EERR = 0
809       ENUMSPD = 3       Full speed                                      ENUMSPD = 3
810       SUSPSTS = 0                                                       SUSPSTS = 0
811
812   diepmsk = 0xb,                        0x0                             0xb
813
814       NAKM = 0
815       TXFURM = 0
816       INEPNEM = 0
817       INEPNMM = 0
818       ITTXFEMSK = 0
819       TOM = 1
820       EPDM = 1
821       XFRCM = 1
822
823   doepmsk = 0x2b,                       0x0                             0x2b
824
825       NYETMSK = 0
826       NAKMSK = 0
827       BERRM =0
828       OUTPKTERRM = 0
829       STSPHSRXM = 1
830       OTEPDM = 0
831       STUPM = 1
832       EPDM = 1
833       XFRCM = 1
834
835   daint = 0x0,                          0x0                     0x10000
836
837   daintmsk = 0x30003,                   0x0                     0x10001
838
839       OEPM = 0x3        endpoints 0 and 1                       OEPM = 0x1      endpoint 0
840       IEPM = 0x3        endpoints 0 and 1                       IEPM = 0x1      endpoint 0
841
842   dvbusdis = 0x17d7,                    0x17d7                  0x17d7
843
844       VBUSDT = 0x17d7   reset value
845
846   dvbuspulse = 0x5b8,                   0x5b8                   0x5b8
847
848       DVBUSP = 0x5b8    reset value
849
850   diepempmsk = 0x0,                     0x0                     0x0
851
852       INEPTXFEM = 0             no endpoints
853
854   diep = {{
855       diepctl = 0x28000,
856
857           EPENA = 0
858           EPDIS = 0
859           SNAK = 0
860           CNAK = 0
861           TXFNUM = 0
862           STALL = 0
863           EPTYP = 0
864           NAKSTS = 1
865           USBAEP = 1
866           MPSIZ = 0             64 bytes
867
868       diepint = 0x20c0,
869
870           NAK = 1
871           PKTDRPSTS = 0
872           TXFIFOUDRN = 0
873           TXFE = 1
874           INEPNE = 1
875           ITTXFE = 0
876           TOC = 0
877           EPDISD = 0
878           XFRC = 0
879
880       dieptsiz = 0x0,
881
882           PKTCNT = 0
883           XFRSIZ = 0
884
885       dtxfsts = 0x40,
886
887           INEPTFSAV = 0x40      256 bytes available
888
889     }, {
890       diepctl = 0x00490040,
891
892           EPENA = 0
893           EPDIS = 0
894           SODDFRM = 0
895           SD0PID  = 0
896           SNAK = 0
897           CNAK = 0
898           TXFNUM = 1
899           STALL = 0
900           EPTYP = 2             bulk
901           NAKSTS = 0
902           EONUM = 1
903           USBAEP = 0
904           MPSIZ = 64    256 bytes
905
906       diepint = 0x2090,
907
908           NAK = 1
909           PKTDRPSTS = 0
910           TXFIFOUDRN = 0
911           TXFE = 1
912           INEPNE = 0
913           INPENM = 0
914           ITTXFE = 1
915           TOC = 0
916           EPDISD = 0
917           XFRC = 0
918
919       dieptsiz = 0x0,
920
921           MCNT = 0
922           PKTCNT = 0
923           XFRSIZ = 0
924
925       dtxfsts = 0x80,
926
927           INEPTFSAV = 0x80              512 bytes available
928
929     }, {
930       diepctl = 0x0,
931       pad_04 = 0x0,
932       diepint = 0x80,
933       pad_0c = 0x0,
934       dieptsiz = 0x0,
935       pad_14 = 0x43425355,
936       dtxfsts = 0x40,
937       pad_1c = 0x400000
938     }, {
939       diepctl = 0x0,
940       pad_04 = 0x0,
941       diepint = 0x80,
942       pad_0c = 0x0,
943       dieptsiz = 0x0,
944       pad_14 = 0x43425355,
945       dtxfsts = 0x40,
946       pad_1c = 0x400000
947     }, {
948       diepctl = 0x0,
949       pad_04 = 0x0,
950       diepint = 0x80,
951       pad_0c = 0x0,
952       dieptsiz = 0x0,
953       pad_14 = 0x43425355,
954       dtxfsts = 0x40,
955       pad_1c = 0x400000
956     }, {
957       diepctl = 0x0,
958       pad_04 = 0x0,
959       diepint = 0x80,
960       pad_0c = 0x0,
961       dieptsiz = 0x0,
962       pad_14 = 0x43425355,
963       dtxfsts = 0x40,
964       pad_1c = 0x400000
965     }},
966
967   doep = {{
968       doepctl = 0x80028000,             0x00008000,                     0x28000
969
970           EPENA = 1                         EPENA = 0                   EPENA = 0
971           EPDIS = 0
972           SNAK =0
973           CNAK = 0
974           STALL = 0
975           SNPM = 0
976           EPTYP = 0
977           NAKSTS = 1                        NAKSTS = 0                  NAKSTS = 1
978           USPAEP = 1                                                    USPAEP = 1
979           MPSIZ = 0             64 bytes                                MPSIZ = 0
980
981       doepint = 0x8010,                 0x0                             0x8008
982
983           NYET = 0
984           NAK = 0
985           BERR = 0
986           OUTPKTERR = 0
987           STSPHSRX = 0
988           OTEPDIS = 1
989           STUP = 0                                                      STUP = 1
990           EPDISD = 0
991           XFRC = 0
992
993       doeptsiz = 0x38,                  0x0                             0x20080008
994
995           STPCNT = 0    1 packet                                        STPCNT = 1
996           PKTCNT = 0                                                    PKTCNT = 1
997           XFRSIZ = 0x38 56 bytes (64 - 8)                               XFRSIZ = 8
998
999     }, {
1000       doepctl = 0x800b0040,
1001
1002           EPENA = 1
1003           EPDIS = 0
1004           SD1PID = 0
1005           SD0PID = 0
1006           SNAK = 0
1007           CNAK = 0
1008           STALL = 0
1009           SNPM =0
1010           EPTYP = 2             Bulk
1011           NAKSTS = 1
1012           EONUM = 1
1013           USBAEP = 0
1014           MPSIZ = 0x40  64 bytes
1015
1016       doepint = 0x0,
1017       doeptsiz = 0x21,
1018
1019           RXDPID = 0
1020           PKTCNT = 0
1021           XFRSIZ = 0x21    33 bytes ?
1022
1023     }, {
1024       doepctl = 0x0,
1025       pad_04 = 0x0,
1026       doepint = 0x0,
1027       pad_0c = 0x0,
1028       doeptsiz = 0x0,
1029       pad_14 = 0x43425355,
1030       pad_18 = 0x40,
1031       pad_1c = 0x400000
1032     }, {
1033       doepctl = 0x0,
1034       pad_04 = 0x0,
1035       doepint = 0x0,
1036       pad_0c = 0x0,
1037       doeptsiz = 0x0,
1038       pad_14 = 0x43425355,
1039       pad_18 = 0x40,
1040       pad_1c = 0x400000
1041     }, {
1042       doepctl = 0x0,
1043       pad_04 = 0x0,
1044       doepint = 0x0,
1045       pad_0c = 0x0,
1046       doeptsiz = 0x0,
1047       pad_14 = 0x43425355,
1048       pad_18 = 0x40,
1049       pad_1c = 0x400000
1050     }, {
1051       doepctl = 0x0,
1052       pad_04 = 0x0,
1053       doepint = 0x0,
1054       pad_0c = 0x0,
1055       doeptsiz = 0x0,
1056       pad_14 = 0x43425355,
1057       pad_18 = 0x40,
1058       pad_1c = 0x400000
1059     }},
1060
1061   pcgcctl = 0x0,                0x0,                    0x0
1062
1063       SUSP = 0
1064       PHYSLEEP = 0
1065       ENL1GTG = 0
1066       PHYSUSP = 0
1067       GATEHCLK = 0
1068       STPPCLK = 0
1069
1070   dfifo = {{
1071         fifo =                                          0x1000680,
1072                                                                 
1073
1074       Clock configuration:
1075
1076 $5 = {
1077   cr = 0x0f077d83, 
1078
1079         PLLI2SRDY = 1
1080         PLLI2SON = 1
1081         PLLRDY = 1
1082         PLLON = 1
1083         CSSON = 0
1084         HSEBYP = 1
1085         HSERDY = 1
1086         HSEON = 1
1087         HSICAL = 0x7d
1088         HSITRIM = 0x10
1089         HSIRDY = 1
1090         HSION = 1
1091
1092   pllcfgr = 0x27403208,
1093
1094         PLLR = 2
1095         PLLQ = 7
1096         PLLSRC = 1      HSE
1097         PLLP = 0        2               
1098         PLLN = 0xc8     200
1099         PLLM = 8
1100
1101                 clk_pllin = 8000000 / 8 = 1000000
1102                 vco = 1000000 * 200 = 200000000
1103                 clk_pll1p = 200000000 / 2 = 100000000 (100MHz)
1104                 clk_pll1q = 200000000 / 7 = ???
1105                 clk_pll1r = 200000000 / 2 = 100000000 (100MHz)
1106
1107   cfgr = 0x0000100a, 
1108   cir = 0x00000000, 
1109   ahb1rstr = 0x0, 
1110   ahb2rstr = 0x0, 
1111   ahb3rstr = 0x0, 
1112   pad_1c = 0x0, 
1113   apb1rstr = 0x0, 
1114   apb2rstr = 0x0, 
1115   pad_28 = 0x0, 
1116   pad_2c = 0x0, 
1117   ahb1enr = 0x40107f, 
1118   ahb2enr = 0x80, 
1119   ahbdnr = 0x3, 
1120   pad_3c = 0x0, 
1121   apb1enr = 0x11000410, 
1122   apb2enr = 0xc800, 
1123   pad_48 = 0x0, 
1124   pad_4c = 0x0, 
1125   ahb1lpenr = 0x6390ff, 
1126   ahb2lpenr = 0xd0, 
1127   ahb3lpenr = 0x3, 
1128   pad_5c = 0x0, 
1129   apb1lpenr = 0xfffecfff, 
1130   apb2lpenr = 0x357f9f3, 
1131   pad_68 = 0x0, 
1132   pad_6c = 0x0, 
1133   bdcr = 0x8200, 
1134   csr = 0x1e000003, 
1135   pad_78 = 0x0, 
1136   pad_7c = 0x0, 
1137   sscgr = 0x0, 
1138   plli2scfgr = 0x44003008, 
1139
1140         PLLI2SR = 4
1141         PLLI2SQ = 4
1142         PLLI2SSRC = 0   HSE (due to PLLSRC)
1143         PLLI2SN = 0xc0  192
1144         PLLI2SM = 8
1145
1146                 clk_plli2sin = 8000000 / 8 = 1000000
1147                 vcoi2s = 1000000 * 192 = 192000000
1148                 ck_pl2q = 192000000 / 4 = 48000000
1149                 ck_pl2r = 192000000 / 4 = 48000000
1150
1151   pad_88 = 0x0, 
1152   dckcfgr = 0x0, 
1153
1154
1155   ckgatenr = 0x0,
1156
1157         All clock gates enabled
1158
1159   dckcfgr2 = 0x08000000
1160
1161         LPTIMER1SEL = 0         APB
1162         CKSDIOSEL = 0           CK_48MHz
1163         CK48MSEL = 1            PLLI2S_Q
1164         I2CFMP1SEL = 0          APB
1165 }
1166
1167 */
1168
1169 /*
1170  *
1171  * altos clock configuration
1172  * (gdb) print/x stm_rcc
1173  * $8 = {
1174  *        altos                 demo firmware
1175  * cr = 0x0307 7d80,            0x0f077d83, 
1176  *
1177  *   PLLI2SRDY 0                1
1178  *   PLLI2SON  0                1
1179  *   PLLRDY    1                1
1180  *   PLLON     1                1
1181  *   CSSON     0                0
1182  *   HSEBYP    1                1
1183  *   HSERDY    1                1
1184  *   HSEON     1                1
1185  *   HSICAL    0x7d             0x7d
1186  *   HSITRIM   0x10             0x10
1187  *   HSIRDY    0                1
1188  *   HSION     0                1
1189  *
1190  * pllcfgr = 0x24403008,        0x27403208,
1191  *   PLLR       2               2
1192  *   PLLQ       4               7
1193  *   PLLSRC     1               1
1194  *   PLLP       0 (/2)          0 (/2)
1195  *   PLLN       192             200
1196  *   PLLM       8               8
1197  *
1198  * cfgr = 0x3640100a,           0x0000100a,
1199  *   upper bits are just MCO
1200  *
1201  *   cir = 0x0,                 0x0
1202  *   ahb1rstr = 0x0,            0x0
1203  *   ahb2rstr = 0x0,            0x0
1204  *   ahb3rstr = 0x0,
1205  *   pad_1c = 0x0,
1206  *   apb1rstr = 0x0,
1207  *   apb2rstr = 0x0,
1208  *   pad_28 = 0x0,
1209  *   pad_2c = 0x0,
1210  *   _ahb1enr = 0x55,           0x80
1211  *   _ahb2enr = 0x80,           0xc800
1212  *   ahbdnr = 0x0,
1213  *   pad_3c = 0x0,
1214  *   apb1enr = 0x10000400,
1215  *   apb2enr = 0x8020,
1216  *   pad_48 = 0x0,
1217  *   pad_4c = 0x0,
1218  *   ahb1lpenr = 0x6390ff,      0x6390ff
1219  *   ahb2lpenr = 0xd0,          0xd0
1220  *   ahb3lpenr = 0x3,           0x3
1221  *   pad_5c = 0x0,
1222  *   apb1lpenr = 0xfffecfff,    0xfffecfff,
1223  *   apb2lpenr = 0x357f9f3,     0x357f9f3,
1224  *   pad_68 = 0x0,
1225  *   pad_6c = 0x0,
1226  *   bdcr = 0x0,                0x8200,
1227  *   csr = 0x0,                 0x1e000003,
1228  *   pad_78 = 0x0,
1229  *   pad_7c = 0x0,
1230  *   sscgr = 0x0,
1231  *   plli2scfgr = 0x24003010,   0x44003008,
1232  *   pad_88 = 0x0,
1233  *   dckcfgr = 0x0,
1234  *   ckgatenr = 0x0,
1235  *   dckcfgr2 = 0x8000000       0x08000000
1236  * }
1237  *
1238  *
1239  */
1240
1241 /*
1242  *
1243  * main
1244  *      HAL_Init
1245  *      SystemClock_Config
1246  *   
1247  *      USBD_Init
1248  *              USBD_LL_Init
1249  *                      HAL_PCD_Init
1250  *                              HAL_PCD_MspInit
1251  *                                      __HAL_RCC_GPIOA_CLK_ENABLE
1252  *                                      HAL_GPIO_Init
1253  *                                      __HAL_RCC_USB_OTG_FS_CLK_ENABLE
1254  *                                      HAL_NVIC_SetPriority
1255  *                                      HAL_NVIC_EnableIRQ
1256  *                              USB_CoreInit
1257  *                                      Select FS Embedded PHY
1258  *                                      USB_CoreReset
1259  *                                      Deactivate the power down
1260  *                              USB_SetCurrentMode
1261  *                              USB_DevInit
1262  *                                      VBUS sensing stuff
1263  *                                      Restart PHY clock
1264  *                                      USB_SetDevSpeed
1265  *                                      USB_FlushTxFifo
1266  *                                      USB_FlushRxFifo
1267  *                                      Clear pending interrupts
1268  *                                      Disable all endpoints
1269  *                                      Disable all interrupts
1270  *                                      Clear pending interrupts
1271  *                                      enable interrupts
1272  *                              USB_DevDisconnect
1273  *                                      Turn on SDIS bit
1274  *                                      delay 3ms
1275  *                      HAL_PCDEx_SeRxFifo
1276  *                      HAL_PCDEx_SetTxFifo
1277  *      USBD_RegisterClass
1278  *      USBD_MSC_RegisterStorage
1279  *      USBD_Start
1280  *              USBD_LL_Start
1281  *                      HAL_PCD_Start
1282  *                              __HAL_LOCK
1283  *                              USB_DevConnect
1284  *                                      Turn off SDIS bit
1285  *                                      delay 3ms
1286  *                              __HAL_PCD_ENABLE
1287  *                                      USB_EnableGlobalInt
1288  *                                              USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
1289  *                              __HAL_UNLOCK
1290  *
1291  */