~ruther/stm32h747i-disco-usb-image-viewer

ref: 3644d05456728e9e59ae8fa9deeead6768544eff stm32h747i-disco-usb-image-viewer/src/usb_device.c -rw-r--r-- 3.0 KiB
3644d054 — Rutherther chore: some renames 6 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include "usb_device.h"
#include <stdlib.h>
#include <stddef.h>
#include <stm32h747xx.h>

/* USB_OTG_GlobalTypeDef */

usb_device_t* usb1_device;

void* usb_device_init(void* peripheral_address, usb_class_t* class, void* buffer)
{
  if (buffer == NULL) {
    buffer = (void*)malloc(sizeof(usb_device_t));
  }

  usb_device_t* device = (usb_device_t*)buffer;

  device->core = peripheral_address;
  device->device = peripheral_address + USB_OTG_DEVICE_BASE;

  usb1_device = device;

  return device;
}

void usb_device_reset(void* device_ptr)
{
  usb_device_t* device = (usb_device_t*)device_ptr;
  while ((device->core->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
  device->core->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
  while (device->core->GRSTCTL & USB_OTG_GRSTCTL_CSRST);
  while ((device->core->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0);
}

void usb_device_clear_interrupts(void* device_ptr)
{
  usb_device_t* device = (usb_device_t*)device_ptr;
  device->core->GINTSTS = 0; // clear interrupts

  // for other interrupts the rx queue has to be read
}

void usb_device_setup(void* device_ptr)
{
  RCC->AHB1ENR |= RCC_AHB1ENR_USB1OTGHSEN | RCC_AHB1ENR_USB1OTGHSULPIEN;

  volatile uint32_t dummy;
  dummy = RCC->AHB1ENR;
  dummy = RCC->AHB1ENR;

  NVIC_SetPriority(OTG_FS_IRQn, 2);
  NVIC_EnableIRQ(OTG_FS_IRQn);

  // 1. core initialization
  usb_device_t* device = (usb_device_t*)device_ptr;

  RCC->AHB1ENR |= RCC_AHB1ENR_USB1OTGHSULPIEN | RCC_AHB1ENR_USB1OTGHSEN;

  /* PWR->CR3 |= PWR_CR3_USBREGEN; */
  /* while ((PWR->CR3 & PWR_CR3_USB33RDY) == 0); */

  device->core->GCCFG |= USB_OTG_GCCFG_PWRDWN;

  device->core->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;

  // global interrupt mask
  // rx fifo non empty
  // periodic tx fifo empty level
  usb_device_clear_interrupts(device_ptr);
  device->core->GAHBCFG = USB_OTG_GAHBCFG_GINT | USB_OTG_GAHBCFG_TXFELVL | USB_OTG_GAHBCFG_HBSTLEN_2;

  // hnp capable, srp capable, otg hs timeout, usb turnaround
  // TODO: based on enumeration speed set TOCAL - fs timeout calibration
  device->core->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_ULPIEVBUSI | USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_TRDT_3 | USB_OTG_GUSBCFG_TRDT_2;

  // unmask otg interrupt mask
  device->core->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM;

  // device initialization

  // descdma, device speed, non-zero-length status out handshake, periodic frame interval
  device->device->DCFG = 0;

  // TODO device threshold control register IF DMA

  usb_device_reset(device_ptr);

  // sdis bit
  device->device->DCTL = ~(USB_OTG_DCTL_SDIS);

  // unmask interrupts usb reset, enumeration done, early suspend, usb suspend, sof
  device->core->GINTMSK |= USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_RSTDEM | USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ESUSPM | USB_OTG_GINTMSK_SOFM;

  // wait for usbrst interrupt - the reset
  while (((device->core->GINTSTS) & USB_OTG_GINTSTS_USBRST) == 0) {}

  // wait for enumdne interrupt - end of reset
  while (((device->core->GINTSTS) & USB_OTG_GINTSTS_ENUMDNE) == 0) {}
}

void otg_hs_handler(void) {

}
Do not follow this link