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

ref: c8fe27c955b05f63fefa02f9c19dbbfb47de11ee stm32h747i-disco-usb-image-viewer/include/usb_device.h -rw-r--r-- 3.3 KiB
c8fe27c9 — Rutherther feat: implement usb devicd cdc descriptors, init, setup 5 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
104
105
106
107
108
109
110
111
112
113
#include <stm32h747xx.h>
#include "usb.h"

#ifndef USB_DEVICE_H
#define USB_DEVICE_H

typedef enum {
  // error states first so they are lowest
  CONTROL_ERROR = -4,
  UNKNOWN_CONTROL_COMMAND = -4,
  ERROR = -3,
  UNKNOWN_INTERRUPT = -2,
  OTG_ERROR = -1, // shouldn't happen, since otg is not used

  INIT = 0,
  RESET = 1,
  RESET_DONE = 2,
  SET_ADDRESS_RCVD = 3,
  ENUMERATED = 4,
} usb_device_state_t;

typedef struct {
  volatile uint32_t data[128];
} usb_fifo_t;

struct usb_class_header_t;
struct usb_device_t;
typedef struct usb_device_t usb_device_t;

typedef struct {
  struct usb_class_header_t *(*init)(usb_device_t *device,
                uint16_t id_vendor, uint16_t id_product,
                char *vendor_name, char *product_name,
                uint16_t serial_number, char* serial_name);
  void (*send_configuration)(usb_device_t* device, usb_setup_command_t* cmd);
  void (*setup_endpoints)(usb_device_t* device, uint8_t configuration);
  void (*reset_endpoints)(usb_device_t* device);

  void (*reset_callback)(usb_device_t* device);
  void (*setup_packet_callback)(usb_device_t* device, usb_setup_command_t* cmd);
  void (*enumeration_done_callback)(usb_device_t* device);
  void (*txfifo_empty_callback)(usb_device_t* device, uint8_t endpoint);
  void (*rxfifo_empty_callback)(usb_device_t* device, uint8_t endpoint);
  void (*transmit_done_callback)(usb_device_t* device, uint8_t endpoint);
  void (*nak_callback)(usb_device_t* device, uint8_t endpoint);
  void (*nyet_callback)(usb_device_t* device, uint8_t endpoint);
} usb_class_vtable_t;

typedef struct {
  usb_interface_descriptor_t interface_descriptor;
  uint8_t endpoint_descriptors_count;
  usb_endpoint_descriptor_t *endpoint_descriptors;
} usb_interface_t;

struct usb_class_header_t {
  usb_device_descriptor_t device_descriptor;
  usb_device_qualifier_t device_qualifier;
  usb_configuration_descriptor_t configuration_descriptor;
  uint8_t interfaces_count;
  usb_interface_t *interfaces;
  usb_string_descriptor_zero_t string_descriptor_zero;
  usb_unicode_string_descriptor_t *string_descriptors;
};
typedef struct usb_class_header_t usb_class_header_t;

typedef enum {
  SETUP_STAGE_NONE,
  SETUP_STAGE_RCVD_SETUP_PACKET,
  SETUP_STAGE_AWAITING_RESPONSE,
  SETUP_STAGE_SENDING_RESPONSE,
  SETUP_STAGE_SENDING_ACK,
  SETUP_STAGE_AWAITING_ACK,
} usb_setup_command_stage_t;

struct usb_device_t {
  USB_OTG_GlobalTypeDef *core;
  USB_OTG_DeviceTypeDef *device;

  USB_OTG_OUTEndpointTypeDef *out;
  USB_OTG_INEndpointTypeDef *in;

  usb_fifo_t *fifos;

  usb_class_vtable_t vt;
  usb_class_header_t* class;

  usb_device_state_t state;

  // TODO: is this count field required?
  uint8_t received_setup_commands_count;
  uint8_t received_setup_commands_index;
  usb_setup_command_stage_t setup_stage;
  uint8_t detected_setup_errors;
  usb_setup_command_t received_setup_commands[3];
};

// has configuration etc

typedef enum {
  USB_OTG_HS1 = 0,
  USB_OTG_FS2 = 1,
} usb_device_slot_t;
extern usb_device_t usb_devices[2];

void *usb_device_init(usb_device_slot_t slot, usb_class_vtable_t *class,
                      uint16_t id_vendor, uint16_t id_product,
                      char *vendor_name, char *product_name,
                      uint16_t serial_number, char* serial_name);

void usb_device_setup(void* device);
void usb_device_wait_for_handshake(void* device);

#endif // USB_DEVICE_H
Do not follow this link