2 * Copyright © 2018 Keith Packard <keithp@keithp.com>
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.
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.
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.
19 #include "ao_usb_gen.h"
21 static uint32_t grxstsp;
26 return (grxstsp >> STM_USB_GRXSTSP_EPNUM) & STM_USB_GRXSTSP_EPNUM_MASK;
32 return (grxstsp >> STM_USB_GRXSTSP_PKTSTS) & STM_USB_GRXSTSP_PKTSTS_MASK;
35 static inline uint16_t
38 return (grxstsp >> STM_USB_GRXSTSP_BCNT) & STM_USB_GRXSTSP_BCNT_MASK;
42 ao_usb_dev_ep_out_start(uint8_t ep)
44 stm_usb.doep[ep].doeptsiz = ((1 << STM_USB_DOEPTSIZ_PKTCNT) |
45 (3 << STM_USB_DOEPTSIZ_STUPCNT) |
46 (24 << STM_USB_DOEPTSIZ_XFRSIZ));
48 // stm_usb.doep[ep].doepctl |= (1 << STM_USB_DOEPCTL_EPENA);
52 ao_usb_mask_in_bits(vuint32_t *addr, uint32_t shift, uint32_t mask, uint32_t bits)
57 value &= ~(mask << shift);
58 value |= (bits << shift);
63 ao_usb_activate_ep0(void)
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));
78 ao_usb_activate_in(int epnum)
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));
89 ao_usb_activate_out(int epnum)
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));
100 ao_usb_enum_done(void)
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);
105 ao_usb_activate_ep0();
109 ao_usb_flush_tx_fifo(uint32_t fifo)
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)
118 ao_usb_flush_rx_fifo(void)
120 stm_usb.grstctl = (1 << STM_USB_GRSTCTL_RXFFLSH);
121 while ((stm_usb.grstctl & (1 << STM_USB_GRSTCTL_RXFFLSH)) != 0)
125 /* reset and enable EP0 */
127 ao_usb_dev_ep0_init(void)
132 ao_usb_flush_tx_fifo(STM_USB_GRSTCTL_TXFNUM_ALL);
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;
139 stm_usb.daint = 0xfffffffful;
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)));
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));
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);
158 /* 3. Setup FIFO ram allocation */
160 /* XXX make principled decisions here */
161 stm_usb.grxfsiz = 0x80;
163 stm_usb.dieptxf0 = ((0x40 << STM_USB_DIEPTXF0_TX0FD) | /* size = 256 bytes */
164 (0x80 << STM_USB_DIEPTXF0_TX0FSA)); /* start address = 0x80 */
166 /* 4. Program OUT endpoint 0 to receive a SETUP packet */
170 doeptsiz = ((1 << STM_USB_DOEPTSIZ_PKTCNT) |
171 (0x40 << STM_USB_DOEPTSIZ_XFRSIZ) |
172 (1 << STM_USB_DOEPTSIZ_STUPCNT));
174 stm_usb.doep[0].doeptsiz = doeptsiz;
176 /* Program MPSIZ field to set maximum packet size */
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));
190 stm_usb.diep[0].diepctl = diepctl;
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));
205 stm_usb.doep[0].doepctl = doepctl;
207 /* Clear interrupts */
208 stm_usb.diep[0].diepint = 0xffffffff;
209 stm_usb.doep[0].doepint = 0xffffffff;
211 ao_usb_dev_ep_out_start(0);
215 ao_usb_dev_ep0_in(const void *data, uint16_t len)
217 return ao_usb_dev_ep_in(0, data, len);
221 ao_usb_dev_ep0_in_busy(void)
227 ao_usb_dev_ep0_out(void *data, uint16_t len)
229 return ao_usb_dev_ep_out(0, data, len);
232 /* Queue IN bytes to EPn */
234 ao_usb_dev_ep_in(uint8_t ep, const void *_data, uint16_t len)
236 const uint8_t *data = _data;
242 stm_usb.dfifo[ep].fifo = d;
247 /* Set the IN data size */
248 stm_usb.diep[ep].dieptsiz = ((1 << STM_USB_DIEPTSIZ_PKTCNT) |
249 (len << STM_USB_DIEPTSIZ_XFRSIZ));
251 /* Enable the TX empty interrupt */
252 stm_usb.diepempmsk |= (1 << ep);
254 /* Enable the endpoint to queue the packet for transmission */
255 stm_usb.diep[ep].diepctl |= (1 << STM_USB_DIEPCTL_EPENA);
259 ao_usb_dev_ep_in_busy(uint8_t ep)
265 /* Receive OUT bytes from EPn */
267 ao_usb_dev_ep_out(uint8_t ep, void *_data, uint16_t len)
269 uint8_t *data = _data;
274 if (grxstsp_enum() != ep)
277 received = grxstsp_bcnt();
283 d = stm_usb.dfifo[0].fifo;
290 t = stm_usb.dfifo[0].fifo;
294 ao_usb_dev_ep_out_start(ep);
299 ao_usb_dev_set_address(uint8_t address)
305 dcfg &= ~(STM_USB_DCFG_DAD_MASK << STM_USB_DCFG_DAD);
306 dcfg |= address & STM_USB_DCFG_DAD_MASK;
311 ao_usb_core_reset(void)
313 /* Wait for AHB master IDLE state. */
314 while ((stm_usb.grstctl & (1 << STM_USB_GRSTCTL_AHBIDL)) == 0)
318 /* Core soft reset */
319 stm_usb.grstctl |= (1 << STM_USB_GRSTCTL_CSRST);
321 /* Wait for reset to complete */
323 while ((stm_usb.grstctl & (1 << STM_USB_GRSTCTL_CSRST)) != 0)
328 ao_usb_core_init(void)
330 /* Enable embedded PHY */
331 stm_usb.gusbcfg |= (1 << STM_USB_GUSBCFG_PHYSEL);
336 /* Deactivate power down */
337 stm_usb.gccfg = (1 << STM_USB_GCCFG_PWRDWN);
341 ao_usb_delay(uint32_t ms)
343 AO_TICK_TYPE now = ao_time();
344 AO_TICK_TYPE then = now + AO_MS_TO_TICKS(ms);
346 while ((int16_t) (then - ao_time()) > 0)
351 ao_usb_set_device_mode(void)
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;
364 ao_usb_device_init(void)
366 /* deactivate vbus sensing */
367 stm_usb.gccfg |= (1 << STM_USB_GCCFG_VBDEN);
369 stm_usb.gccfg &= ~(1 << STM_USB_GCCFG_VBDEN);
371 /* Force device mode */
372 stm_usb.gotgctl |= ((1 << STM_USB_GOTGCTL_BVALOEN) |
373 (1 << STM_USB_GOTGCTL_BVALOVAL));
375 /* Restart the phy clock */
378 /* Device mode configuration */
379 stm_usb.dcfg |= (STM_USB_DCFG_PFIVL_80 << STM_USB_DCFG_PFIVL);
381 /* Set full speed phy */
382 stm_usb.dcfg |= (STM_USB_DCFG_DSPD_FULL_SPEED << STM_USB_DCFG_DSPD);
384 /* Flush the fifos */
385 ao_usb_flush_tx_fifo(STM_USB_GRSTCTL_TXFNUM_ALL);
386 ao_usb_flush_rx_fifo();
388 /* Clear all pending device interrupts */
391 stm_usb.daint = 0xffffffffUL;
392 stm_usb.daintmsk = 0;
394 /* Reset all endpoints */
395 for (int i = 0; i < 6; i++) {
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));
402 stm_usb.diep[i].diepctl = 0;
403 stm_usb.diep[i].dieptsiz = 0;
404 stm_usb.diep[i].diepint = 0xffu;
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));
413 stm_usb.doep[i].doepctl = 0;
415 stm_usb.doep[i].doeptsiz = 0;
416 stm_usb.doep[i].doepint = 0xffu;
419 stm_usb.diepmsk &= ~(1 << STM_USB_DIEPMSK_TXFURM);
421 /* Disable all interrupts */
424 /* Clear pending interrupts */
425 stm_usb.gintsts = 0xfffffffful;
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));
457 ao_usb_device_connect(void)
459 /* Enable pull-up/pull-down */
460 stm_usb.dctl &= ~(1 << STM_USB_DCTL_SDIS);
465 ao_usb_device_disconnect(void)
467 /* Disable pull-up/pull-down */
468 stm_usb.dctl |= (1 << STM_USB_DCTL_SDIS);
473 ao_usb_dev_start(void)
475 ao_usb_device_connect();
476 stm_usb.gahbcfg |= (1 << STM_USB_GAHBCFG_GINTMSK);
480 ao_usb_dev_enable(void)
482 ao_arch_block_interrupts();
484 /* Configure GPIOs */
485 ao_enable_port(&stm_gpioa);
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 */
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);
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);
500 stm_rcc_ahb2_clk_enable(1 << STM_RCC_AHB2ENR_OTGFSEN);
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);
506 ao_arch_release_interrupts();
511 /* Set device mode */
512 ao_usb_set_device_mode();
514 /* Reset FIFO allocations */
515 for (int i = 1; i < 16; i++)
516 stm_usb.dieptxf[i-1] = 0x0;
518 ao_usb_device_init();
521 ao_usb_device_disconnect();
528 ao_usb_dev_disable(void)
530 ao_usb_device_disconnect();
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));
540 stm_usb.gahbcfg = ((0 << STM_USB_GAHBCFG_PTXFELVL) |
541 (1 << STM_USB_GAHBCFG_TXFELVL) |
542 (0 << STM_USB_GAHBCFG_GINTMSK));
544 stm_usb.dctl = ((0 << STM_USB_DCTL_POPRGDNE) |
545 (1 << STM_USB_DCTL_SDIS));
547 stm_rcc_ahb2_clk_disable(1 << STM_RCC_AHB2ENR_OTGFSEN);
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;
558 /* Clear all received interrupts */
559 stm_usb.gintsts = gintsts;
561 if (gintsts & (1 << STM_USB_GINTSTS_USBRST)) {
562 ep0_receive |= AO_USB_EP0_GOT_RESET;
565 if (gintsts & (1 << STM_USB_GINTSTS_ENUMDNE)) {
569 if (gintsts & ((1 << STM_USB_GINTSTS_OEPINT) |
570 (1 << STM_USB_GINTSTS_IEPINT)))
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;
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;
581 stm_usb.doep[ep].doepint = doepint;
582 if (doepint & (1 << STM_USB_DOEPINT_XFRC)) {
584 ep0_receive |= AO_USB_EP0_GOT_SETUP;
586 out_interrupt |= (1 << ep);
588 grxstsp = stm_usb.grxstsp;
592 if (gintsts & (1 << STM_USB_GINTSTS_IEPINT)) {
593 if (iepint & (1 << ep)) {
594 uint32_t diepint = stm_usb.diep[ep].diepint;
596 stm_usb.diep[ep].diepint = diepint;
597 if (diepint & (1 << STM_USB_DIEPINT_XFRC)) {
599 ep0_receive |= AO_USB_EP0_GOT_TX_ACK;
601 in_interrupt |= (1 << ep);
611 ao_usb_ep0_interrupt(ep0_receive);
614 ao_usb_out_interrupt(out_interrupt);
617 ao_usb_in_interrupt(in_interrupt);
622 running before plugging in at first packet
623 gotgctl = 0x04cd0000, 0x04c10000, 0x04cd0000 *************
632 gotgint = 0x00100000, 0x00100000, 0x00100000
636 gahbcfg = 0x1, 0x1, 0x00000001
638 TXFELVL = 0 trigger half empty
639 GINTMSK = 1 interrupts enabled
641 gusbcfg = 0x40001840, 0x40001440 0x40001840 *************
643 FDMOD = 1 force device mode
651 grstctl = 0x80000040, 0x80000000 0x80000400 ***********
654 TXFNUM = 1 TXFNUM = 0 TXFNUM = 0x20 (flush all)
661 gintsts = 0x0480b43a, 0x04008022 0x04888438 ***********
668 PTXFE = 1 PTXFE = 1 PTXFE = 1
671 RSTDET = 1 RSTDET = 0 RSTDET = 1
674 OEPINT = 0 OEPINT = 1
676 EOPF = 1 EOPF = 1 EOPF = 1
684 NPTXFE = 1 NPTXFE = 1 NPTXFE = 1
685 RXFLVL = 1 RXFLVL = 1
688 MMIS = 1 MMIS = 1 MMIS = 0
691 gintmsk = 0xc03c3814, 0xc03c3814,
720 grxstsr = 0xac0080, 0x0 0x14c0080 ***************
722 STSPHST = 0 STSPHST = 0
723 FRMNUM = 5 FRMNUM = 10
724 PKTSTS = 6 -- SETUP data packet PKTSTS = 6 -- SETUP data packet
729 grxstsp = 0xac0080, 0x0 0x14c0080
733 grxfsiz = 0x80, 0x80 0x80
737 dieptxf0 = 0x00400080, 0x00400080 0x00400080
742 gccfg = 0x21fff0, 0x21fff0 0x21fff0
755 cid = 0x2000, 0x2000 0x2000
759 glpmcfg = 0x0, 0x0 0x0
777 dieptxf = {0x8000c0, 0x0, 0x0, 0x0, 0x0}, {0x8000c0, 0x0, 0x0, 0x0, 0x0}, {0x8000c0, 0x0, 0x0, 0x0, 0x0},
779 INEXPTXFD 0 = 0x80 512 bytes
782 dcfg = 0x82000b3, 0x8200003, 0x8200003
786 DAD = 0xb DAD = 0x0 DAD = 0
788 DSPD = 3 Full speed USB 1.1
804 dsts = 0x0043ff06, 0x00000006 0x00400c06
806 DEVLNSTS = 1 (D+ low, D- high)
807 FNSOF = 0x3ff FNSOF = 0xc
809 ENUMSPD = 3 Full speed ENUMSPD = 3
810 SUSPSTS = 0 SUSPSTS = 0
812 diepmsk = 0xb, 0x0 0xb
823 doepmsk = 0x2b, 0x0 0x2b
835 daint = 0x0, 0x0 0x10000
837 daintmsk = 0x30003, 0x0 0x10001
839 OEPM = 0x3 endpoints 0 and 1 OEPM = 0x1 endpoint 0
840 IEPM = 0x3 endpoints 0 and 1 IEPM = 0x1 endpoint 0
842 dvbusdis = 0x17d7, 0x17d7 0x17d7
844 VBUSDT = 0x17d7 reset value
846 dvbuspulse = 0x5b8, 0x5b8 0x5b8
848 DVBUSP = 0x5b8 reset value
850 diepempmsk = 0x0, 0x0 0x0
852 INEPTXFEM = 0 no endpoints
887 INEPTFSAV = 0x40 256 bytes available
890 diepctl = 0x00490040,
927 INEPTFSAV = 0x80 512 bytes available
968 doepctl = 0x80028000, 0x00008000, 0x28000
970 EPENA = 1 EPENA = 0 EPENA = 0
977 NAKSTS = 1 NAKSTS = 0 NAKSTS = 1
978 USPAEP = 1 USPAEP = 1
979 MPSIZ = 0 64 bytes MPSIZ = 0
981 doepint = 0x8010, 0x0 0x8008
993 doeptsiz = 0x38, 0x0 0x20080008
995 STPCNT = 0 1 packet STPCNT = 1
996 PKTCNT = 0 PKTCNT = 1
997 XFRSIZ = 0x38 56 bytes (64 - 8) XFRSIZ = 8
1000 doepctl = 0x800b0040,
1014 MPSIZ = 0x40 64 bytes
1021 XFRSIZ = 0x21 33 bytes ?
1029 pad_14 = 0x43425355,
1038 pad_14 = 0x43425355,
1047 pad_14 = 0x43425355,
1056 pad_14 = 0x43425355,
1061 pcgcctl = 0x0, 0x0, 0x0
1074 Clock configuration:
1092 pllcfgr = 0x27403208,
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)
1121 apb1enr = 0x11000410,
1125 ahb1lpenr = 0x6390ff,
1129 apb1lpenr = 0xfffecfff,
1130 apb2lpenr = 0x357f9f3,
1138 plli2scfgr = 0x44003008,
1142 PLLI2SSRC = 0 HSE (due to PLLSRC)
1146 clk_plli2sin = 8000000 / 8 = 1000000
1147 vcoi2s = 1000000 * 192 = 192000000
1148 ck_pl2q = 192000000 / 4 = 48000000
1149 ck_pl2r = 192000000 / 4 = 48000000
1157 All clock gates enabled
1159 dckcfgr2 = 0x08000000
1162 CKSDIOSEL = 0 CK_48MHz
1163 CK48MSEL = 1 PLLI2S_Q
1171 * altos clock configuration
1172 * (gdb) print/x stm_rcc
1174 * altos demo firmware
1175 * cr = 0x0307 7d80, 0x0f077d83,
1190 * pllcfgr = 0x24403008, 0x27403208,
1194 * PLLP 0 (/2) 0 (/2)
1198 * cfgr = 0x3640100a, 0x0000100a,
1199 * upper bits are just MCO
1202 * ahb1rstr = 0x0, 0x0
1203 * ahb2rstr = 0x0, 0x0
1210 * _ahb1enr = 0x55, 0x80
1211 * _ahb2enr = 0x80, 0xc800
1214 * apb1enr = 0x10000400,
1218 * ahb1lpenr = 0x6390ff, 0x6390ff
1219 * ahb2lpenr = 0xd0, 0xd0
1220 * ahb3lpenr = 0x3, 0x3
1222 * apb1lpenr = 0xfffecfff, 0xfffecfff,
1223 * apb2lpenr = 0x357f9f3, 0x357f9f3,
1226 * bdcr = 0x0, 0x8200,
1227 * csr = 0x0, 0x1e000003,
1231 * plli2scfgr = 0x24003010, 0x44003008,
1235 * dckcfgr2 = 0x8000000 0x08000000
1245 * SystemClock_Config
1251 * __HAL_RCC_GPIOA_CLK_ENABLE
1253 * __HAL_RCC_USB_OTG_FS_CLK_ENABLE
1254 * HAL_NVIC_SetPriority
1255 * HAL_NVIC_EnableIRQ
1257 * Select FS Embedded PHY
1259 * Deactivate the power down
1260 * USB_SetCurrentMode
1262 * VBUS sensing stuff
1267 * Clear pending interrupts
1268 * Disable all endpoints
1269 * Disable all interrupts
1270 * Clear pending interrupts
1275 * HAL_PCDEx_SeRxFifo
1276 * HAL_PCDEx_SetTxFifo
1277 * USBD_RegisterClass
1278 * USBD_MSC_RegisterStorage
1287 * USB_EnableGlobalInt
1288 * USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;