mikroSDK Reference Manual
dcd.h
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2019 Ha Thach (tinyusb.org)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 * This file is part of the TinyUSB stack.
25 */
26
27#ifndef _TUSB_DCD_H_
28#define _TUSB_DCD_H_
29
30#include "common/tusb_common.h"
31#include "osal/osal.h"
32#include "common/tusb_fifo.h"
33
34#ifdef __cplusplus
35 extern "C" {
36#endif
37
38//--------------------------------------------------------------------+
39// Configuration
40//--------------------------------------------------------------------+
41
42#ifndef CFG_TUD_ENDPPOINT_MAX
43 #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX
44#endif
45
46//--------------------------------------------------------------------+
47// MACRO CONSTANT TYPEDEF PROTYPES
48//--------------------------------------------------------------------+
49
50typedef enum
51{
52 DCD_EVENT_INVALID = 0,
53 DCD_EVENT_BUS_RESET,
54 DCD_EVENT_UNPLUGGED,
55 DCD_EVENT_SOF,
56 DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support
57 DCD_EVENT_RESUME,
58
59 DCD_EVENT_SETUP_RECEIVED,
60 DCD_EVENT_XFER_COMPLETE,
61
62 // Not an DCD event, just a convenient way to defer ISR function
63 USBD_EVENT_FUNC_CALL,
64
65 DCD_EVENT_COUNT
66} dcd_eventid_t;
67
68typedef struct TU_ATTR_ALIGNED(4)
69{
70 uint8_t rhport;
71 uint8_t event_id;
72
73 union
74 {
75 // BUS RESET
76 struct {
77 tusb_speed_t speed;
78 } bus_reset;
79
80 // SOF
81 struct {
82 uint32_t frame_count;
83 }sof;
84
85 // SETUP_RECEIVED
86 tusb_control_request_t setup_received;
87
88 // XFER_COMPLETE
89 struct {
90 uint8_t ep_addr;
91 uint8_t result;
92 uint32_t len;
93 }xfer_complete;
94
95 // FUNC_CALL
96 struct {
97 void (*func) (void*);
98 void* param;
99 }func_call;
100 };
101} dcd_event_t;
102
103//TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct");
104
105//--------------------------------------------------------------------+
106// Memory API
107//--------------------------------------------------------------------+
108
109// clean/flush data cache: write cache -> memory.
110// Required before an DMA TX transfer to make sure data is in memory
111void dcd_dcache_clean(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
112
113// invalidate data cache: mark cache as invalid, next read will read from memory
114// Required BOTH before and after an DMA RX transfer
115void dcd_dcache_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
116
117// clean and invalidate data cache
118// Required before an DMA transfer where memory is both read/write by DMA
119void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
120
121//--------------------------------------------------------------------+
122// Controller API
123//--------------------------------------------------------------------+
124
125// Initialize controller to device mode
126void dcd_init (uint8_t rhport);
127
128// Interrupt Handler
129void dcd_int_handler(uint8_t rhport);
130
131// Enable device interrupt
132void dcd_int_enable (uint8_t rhport);
133
134// Disable device interrupt
135void dcd_int_disable(uint8_t rhport);
136
137// Receive Set Address request, mcu port must also include status IN response
138void dcd_set_address(uint8_t rhport, uint8_t dev_addr);
139
140// Wake up host
141void dcd_remote_wakeup(uint8_t rhport);
142
143// Connect by enabling internal pull-up resistor on D+/D-
144void dcd_connect(uint8_t rhport) TU_ATTR_WEAK;
145
146// Disconnect by disabling internal pull-up resistor on D+/D-
147void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK;
148
149// Enable/Disable Start-of-frame interrupt. Default is disabled
150void dcd_sof_enable(uint8_t rhport, bool en);
151
152//--------------------------------------------------------------------+
153// Endpoint API
154//--------------------------------------------------------------------+
155
156// Invoked when a control transfer's status stage is complete.
157// May help DCD to prepare for next control transfer, this API is optional.
158void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const * request) TU_ATTR_WEAK;
159
160// Configure endpoint's registers according to descriptor
161bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep);
162
163// Close all non-control endpoints, cancel all pending transfers if any.
164// Invoked when switching from a non-zero Configuration by SET_CONFIGURE therefore
165// required for multiple configuration support.
166void dcd_edpt_close_all (uint8_t rhport);
167
168// Close an endpoint.
169// Since it is weak, caller must TU_ASSERT this function's existence before calling it.
170void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK;
171
172// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
173bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes);
174
175// Submit an transfer using fifo, When complete dcd_event_xfer_complete() is invoked to notify the stack
176// This API is optional, may be useful for register-based for transferring data.
177bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) TU_ATTR_WEAK;
178
179// Stall endpoint, any queuing transfer should be removed from endpoint
180void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr);
181
182// clear stall, data toggle is also reset to DATA0
183// This API never calls with control endpoints, since it is auto cleared when receiving setup packet
184void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr);
185
186// Allocate packet buffer used by ISO endpoints
187// Some MCU need manual packet buffer allocation, we allocation largest size to avoid clustering
188TU_ATTR_WEAK bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size);
189
190// Configure and enable an ISO endpoint according to descriptor
191TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc);
192
193//--------------------------------------------------------------------+
194// Event API (implemented by stack)
195//--------------------------------------------------------------------+
196
197// Called by DCD to notify device stack
198extern void dcd_event_handler(dcd_event_t const * event, bool in_isr);
199
200// helper to send bus signal event
201TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
202{
203 dcd_event_t event = { .rhport = rhport, .event_id = eid };
204 dcd_event_handler(&event, in_isr);
205}
206
207// helper to send bus reset event
208TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr)
209{
210 dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET };
211 event.bus_reset.speed = speed;
212 dcd_event_handler(&event, in_isr);
213}
214
215// helper to send setup received
216TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
217{
218 dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
219 memcpy(&event.setup_received, setup, sizeof(tusb_control_request_t));
220
221 dcd_event_handler(&event, in_isr);
222}
223
224// helper to send transfer complete event
225TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
226{
227 dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
228
229 event.xfer_complete.ep_addr = ep_addr;
230 event.xfer_complete.len = xferred_bytes;
231 event.xfer_complete.result = result;
232
233 dcd_event_handler(&event, in_isr);
234}
235
236static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr)
237{
238 dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF };
239 event.sof.frame_count = frame_count;
240 dcd_event_handler(&event, in_isr);
241}
242
243#ifdef __cplusplus
244 }
245#endif
246
247#endif /* _TUSB_DCD_H_ */
tusb_speed_t
defined base on EHCI specs value for Endpoint Speed
Definition tusb_types.h:48
AUDIO Channel Cluster Descriptor (4.1)
Definition audio.h:647
Definition tusb_fifo.h:108