]> mj.ucw.cz Git - home-hw.git/blob - usb/Inc/usb.h
Merge branch 'master' of ssh://git.ucw.cz/home/mj/GIT/home-hw
[home-hw.git] / usb / Inc / usb.h
1 /*** Configurable parameters ***/
2
3 #define USB_SELF_POWERED
4 #define USB_NUM_CONFIGURATIONS 1
5 #undef USB_DEBUG
6
7 /*** USB state structure ***/
8
9 /*
10  *  We have a single buffer for all control transfers.
11  *  It must be able to contain:
12  *
13  *    - 2-byte status replies
14  *    - UTF-16 versions of all string descriptors
15  *
16  *  In addition to that, its length must be even.
17  */
18 #define USB_EP0_BUF_SIZE 256
19
20 struct usb {
21   PCD_HandleTypeDef *hpcd;
22   byte state;                   // USB_STATE_xxx
23   byte pre_suspend_state;
24   byte address;                 // Device address assigned by the host (0=none)
25   byte config;                  // Selected configuration (0=none)
26   byte remote_wakeup;           // State of remote wakeup feature
27
28   // State of endpoint 00
29   byte ep0_state;               // USB_EP0_xxx
30   u16 ep0_setup_data_length;
31   u16 ep0_remaining_length;
32   u16 ep0_total_length;
33   byte ep0_buf[USB_EP0_BUF_SIZE];
34
35   // Descriptor data to be filled by the user during usb_dev_reset()
36   const byte *desc_device;
37   const byte *desc_config;
38   const char * const *desc_string;
39   const byte *desc_languages;
40   u16 desc_device_len;
41   u16 desc_config_len;
42   u16 desc_string_items;
43   u16 desc_languages_len;
44
45   // Internal use
46   u16 last_pma_alloc;
47 };
48
49 enum usb_device_state {
50   USB_STATE_DEFAULT,
51   USB_STATE_ADDRESSED,
52   USB_STATE_CONFIGURED,
53   USB_STATE_SUSPENDED,
54 };
55
56 enum usb_ep0_state {
57   USB_EP0_IDLE,
58   USB_EP0_SETUP,
59   USB_EP0_DATA_IN,
60   USB_EP0_DATA_OUT,
61   USB_EP0_STATUS_IN,
62   USB_EP0_STATUS_OUT,
63   USB_EP0_STALL,
64 };
65
66 #ifdef USB_DEBUG
67 #define usb_debug debug_printf
68 #else
69 static inline void usb_debug(char *msg, ...)
70 { }
71 #endif
72
73 // Parsed setup request
74 struct setup_request {
75   byte bmRequest;
76   byte bRequest;
77   u16 wValue;
78   u16 wIndex;
79   u16 wLength;
80 };
81
82 /*** Functions provided by low-level code ***/
83
84 void usb_init(struct usb *usb, PCD_HandleTypeDef *hpcd);
85 void usb_start(struct usb *usb);
86
87 void usb_ctl_send_status(struct usb *usb);
88 void usb_ctl_recv_status(struct usb *usb);
89 void usb_ctl_send_data(struct usb *usb, const byte *data, uint len);
90 void usb_ctl_recv_data(struct usb *usb, byte *data, uint len);
91 void usb_ctl_error(struct usb *usb);
92 void usb_ctl_setup_error(struct usb *usb, struct setup_request *setup);
93
94 /*** Callbacks to user code ***/
95
96 // Device was reset
97 void usb_dev_reset(struct usb *usb);
98
99 // Configure the device (usb->config is the selected configuration)
100 void usb_dev_configure(struct usb *usb);
101
102 // Un-configure the device (usb->config is the configuration we are leaving)
103 void usb_dev_unconfigure(struct usb *usb);
104
105 // Intercept a setup packet. Returns true if default processing should be skipped.
106 // Remember to check if usb->state == USB_STATE_CONFIGURED for most requests.
107 bool usb_dev_setup_hook(struct usb *usb, struct setup_request *setup);
108
109 // Finished receiving control packet data requested by usb_ctl_recv_data()
110 void usb_dev_ctl_recv_done(struct usb *usb);
111
112 // Finished sending control packet data requested by usb_ctl_send_data()
113 void usb_dev_ctl_send_done(struct usb *usb);
114
115 // Finished receiving data on a non-control endpoint
116 void usb_dev_recv_done(struct usb *usb, byte epnum);
117
118 // Finished sending data on a non-control endpoint
119 void usb_dev_send_done(struct usb *usb, byte epnum);
120
121 /*** Constants from USB specs ***/
122
123 #define USB_REQ_DIRECTION 0x80
124
125 enum usb_req_type {
126   USB_REQ_TYPE_STANDARD = 0x00,
127   USB_REQ_TYPE_CLASS = 0x20,
128   USB_REQ_TYPE_VENDOR = 0x40,
129   USB_REQ_TYPE_MASK = 0x60,
130 };
131
132 enum usb_req_recipient {
133   USB_REQ_RECIPIENT_DEVICE = 0x00,
134   USB_REQ_RECIPIENT_INTERFACE = 0x01,
135   USB_REQ_RECIPIENT_ENDPOINT = 0x02,
136   USB_REQ_RECIPIENT_MASK = 0x1f,
137 };
138
139 enum usb_req_standard {
140   USB_REQ_GET_STATUS = 0x00,
141   USB_REQ_CLEAR_FEATURE = 0x01,
142   USB_REQ_SET_FEATURE = 0x03,
143   USB_REQ_SET_ADDRESS = 0x05,
144   USB_REQ_GET_DESCRIPTOR = 0x06,
145   USB_REQ_SET_DESCRIPTOR = 0x07,
146   USB_REQ_GET_CONFIGURATION = 0x08,
147   USB_REQ_SET_CONFIGURATION = 0x09,
148   USB_REQ_GET_INTERFACE = 0x0A,
149   USB_REQ_SET_INTERFACE = 0x0B,
150   USB_REQ_SYNCH_FRAME = 0x0C,
151 };
152
153 enum usb_desc_type {
154   USB_DESC_TYPE_DEVICE = 1,
155   USB_DESC_TYPE_CONFIGURATION = 2,
156   USB_DESC_TYPE_STRING = 3,
157   USB_DESC_TYPE_INTERFACE = 4,
158   USB_DESC_TYPE_ENDPOINT = 5,
159   USB_DESC_TYPE_DEVICE_QUALIFIER = 6,
160   USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION = 7,
161   USB_DESC_TYPE_BOS = 0x0F,
162 };
163
164 enum usb_dev_status {
165   USB_DEV_STATUS_REMOTE_WAKEUP = 2,
166   USB_DEV_STATUS_SELF_POWERED = 1,
167 };
168
169 enum usb_feature {
170   USB_FEATURE_EP_HALT = 0,
171   USB_FEATURE_REMOTE_WAKEUP = 1,
172   USB_FEATURE_TEST_MODE = 2,
173 };
174
175 #define USB_HS_MAX_PACKET_SIZE 512
176 #define USB_FS_MAX_PACKET_SIZE 64
177 #define USB_MAX_EP0_SIZE 64
178
179 enum usb_ep_type {
180   USB_EP_TYPE_CTRL = 0,
181   USB_EP_TYPE_ISOC = 1,
182   USB_EP_TYPE_BULK = 2,
183   USB_EP_TYPE_INTR = 3,
184 };
185
186 /*** Wrappers around HAL routines ***/
187
188 // Wrappers return HAL_OK / HAL_ERROR / HAL_BUSY / HAL_TIMEOUT
189
190 // Call from configure callback
191 static inline HAL_StatusTypeDef usb_ep_open(struct usb *usb, byte ep_addr, byte ep_type, byte ep_max_size)
192 {
193   HAL_PCDEx_PMAConfig(usb->hpcd, ep_addr, PCD_SNG_BUF, usb->last_pma_alloc);
194   usb->last_pma_alloc += (ep_max_size + 7) & ~7U;
195   return HAL_PCD_EP_Open(usb->hpcd, ep_addr, ep_max_size, ep_type);
196 }
197
198 // Call from unconfigure callback
199 static inline HAL_StatusTypeDef usb_ep_close(struct usb *usb, byte ep_addr)
200 {
201   return HAL_PCD_EP_Close(usb->hpcd, ep_addr);
202 }
203
204 static inline HAL_StatusTypeDef usb_ep_flush(struct usb *usb, byte ep_addr)
205 {
206   return HAL_PCD_EP_Flush(usb->hpcd, ep_addr);
207 }
208
209 static inline HAL_StatusTypeDef usb_ep_stall(struct usb *usb, byte ep_addr)
210 {
211   return HAL_PCD_EP_SetStall(usb->hpcd, ep_addr);
212 }
213
214 static inline HAL_StatusTypeDef usb_ep_unstall(struct usb *usb, byte ep_addr)
215 {
216   return HAL_PCD_EP_ClrStall(usb->hpcd, ep_addr);
217 }
218
219 static inline int usb_ep_is_stalled(struct usb *usb, byte ep_addr)
220 {
221   return ((ep_addr & 0x80) ? usb->hpcd->IN_ep : usb->hpcd->OUT_ep) [ep_addr & 0x7f].is_stall;
222 }
223
224 static inline HAL_StatusTypeDef usb_ep_send(struct usb *usb, byte ep_addr, const byte *buf, u32 size)
225 {
226   return HAL_PCD_EP_Transmit(usb->hpcd, ep_addr, (byte *) buf, size);
227 }
228
229 static inline HAL_StatusTypeDef usb_ep_receive(struct usb *usb, byte ep_addr, byte *buf, u32 size)
230 {
231   return HAL_PCD_EP_Receive(usb->hpcd, ep_addr, buf, size);
232 }
233
234 static inline u32 usb_ep_received_size(struct usb *usb, byte ep_addr)
235 {
236   return HAL_PCD_EP_GetRxCount(usb->hpcd, ep_addr);
237 }