Open FFBoard
Open source force feedback firmware
dcd_pio_usb.c
Go to the documentation of this file.
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2018, hathach (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#include "tusb_option.h"
28
29#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUD_RPI_PIO_USB
30
31#include "pico.h"
32#include "pio_usb.h"
33#include "pio_usb_ll.h"
34
35#include "device/dcd.h"
36
37//--------------------------------------------------------------------+
38// MACRO TYPEDEF CONSTANT ENUM DECLARATION
39//--------------------------------------------------------------------+
40
41#define RHPORT_OFFSET 1
42#define RHPORT_PIO(_x) ((_x)-RHPORT_OFFSET)
43
44//------------- -------------//
45static usb_device_t *usb_device = NULL;
46static usb_descriptor_buffers_t desc;
47
48/*------------------------------------------------------------------*/
49/* Device API
50 *------------------------------------------------------------------*/
51
52// Initialize controller to device mode
53bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
54 (void) rhport;
55 (void) rh_init;
56 static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG;
57 usb_device = pio_usb_device_init(&config, &desc);
58
59 return true;
60}
61
62// Enable device interrupt
63void dcd_int_enable (uint8_t rhport)
64{
65 (void) rhport;
66}
67
68// Disable device interrupt
69void dcd_int_disable (uint8_t rhport)
70{
71 (void) rhport;
72}
73
74// Receive Set Address request, mcu port must also include status IN response
75void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
76{
77 // must be called before queuing status
78 pio_usb_device_set_address(dev_addr);
79 dcd_edpt_xfer(rhport, 0x80, NULL, 0);
80}
81
82// Wake up host
83void dcd_remote_wakeup (uint8_t rhport)
84{
85 (void) rhport;
86}
87
88// Connect by enabling internal pull-up resistor on D+/D-
89void dcd_connect(uint8_t rhport)
90{
91 (void) rhport;
92}
93
94// Disconnect by disabling internal pull-up resistor on D+/D-
95void dcd_disconnect(uint8_t rhport)
96{
97 (void) rhport;
98}
99
100//--------------------------------------------------------------------+
101// Endpoint API
102//--------------------------------------------------------------------+
103
104// Configure endpoint's registers according to descriptor
105bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep)
106{
107 (void) rhport;
108 return pio_usb_device_endpoint_open((uint8_t const*) desc_ep);
109}
110
111void dcd_edpt_close_all (uint8_t rhport)
112{
113 (void) rhport;
114}
115
116// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
117bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
118{
119 (void) rhport;
120 endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr);
121 return pio_usb_ll_transfer_start(ep, buffer, total_bytes);
122}
123
124// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c
125//bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
126//{
127// (void) rhport;
128// (void) ep_addr;
129// (void) ff;
130// (void) total_bytes;
131// return false;
132//}
133
134// Stall endpoint
135void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
136{
137 (void) rhport;
138 endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr);
139 ep->has_transfer = false;
140 ep->stalled = true;
141}
142
143// clear stall, data toggle is also reset to DATA0
144void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
145{
146 (void) rhport;
147 endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr);
148 ep->data_id = 0;
149 ep->stalled = false;
150}
151
152//--------------------------------------------------------------------+
153//
154//--------------------------------------------------------------------+
155
156static void __no_inline_not_in_flash_func(handle_endpoint_irq)(uint8_t tu_rhport, xfer_result_t result, volatile uint32_t* ep_reg)
157{
158 const uint32_t ep_all = *ep_reg;
159
160 for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++)
161 {
162 uint32_t const mask = (1u << ep_idx);
163
164 if (ep_all & mask)
165 {
166 endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx);
167 dcd_event_xfer_complete(tu_rhport, ep->ep_num, ep->actual_len, result, true);
168 }
169 }
170
171 // clear all
172 (*ep_reg) &= ~ep_all;
173}
174
175// IRQ Handler
176void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id)
177{
178 uint8_t const tu_rhport = root_id + 1;
179 root_port_t* rport = PIO_USB_ROOT_PORT(root_id);
180 uint32_t const ints = rport->ints;
181
182 if (ints & PIO_USB_INTS_RESET_END_BITS)
183 {
184 dcd_event_bus_reset(tu_rhport, TUSB_SPEED_FULL, true);
185 }
186
187 if (ints & PIO_USB_INTS_SETUP_REQ_BITS)
188 {
189 dcd_event_setup_received(tu_rhport, rport->setup_packet, true);
190 }
191
192 if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS )
193 {
194 handle_endpoint_irq(tu_rhport, XFER_RESULT_SUCCESS, &rport->ep_complete);
195 }
196
197 if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS )
198 {
199 handle_endpoint_irq(tu_rhport, XFER_RESULT_STALLED, &rport->ep_stalled);
200 }
201
202 if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS )
203 {
204 handle_endpoint_irq(tu_rhport, XFER_RESULT_FAILED, &rport->ep_error);
205 }
206
207 // clear all
208 rport->ints &= ~ints;
209}
210
211#endif
static TU_ATTR_ALWAYS_INLINE void dcd_event_xfer_complete(uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
Definition: dcd.h:222
static TU_ATTR_ALWAYS_INLINE void dcd_event_setup_received(uint8_t rhport, uint8_t const *setup, bool in_isr)
Definition: dcd.h:213
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_reset(uint8_t rhport, tusb_speed_t speed, bool in_isr)
Definition: dcd.h:204
uint16_t total_bytes
Definition: dcd_nuc505.c:113
uint8_t dev_addr
Definition: dcd_pic32mz.c:81
static usb_descriptor_buffers_t desc
Definition: dcd_pio_usb.c:46
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_pio_usb.c:135
void dcd_disconnect(uint8_t rhport)
Definition: dcd_pio_usb.c:95
void dcd_edpt_close_all(uint8_t rhport)
Definition: dcd_pio_usb.c:111
void dcd_int_disable(uint8_t rhport)
Definition: dcd_pio_usb.c:69
void __no_inline_not_in_flash_func() pio_usb_device_irq_handler(uint8_t root_id)
Definition: dcd_pio_usb.c:176
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_pio_usb.c:144
void dcd_connect(uint8_t rhport)
Definition: dcd_pio_usb.c:89
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
Definition: dcd_pio_usb.c:117
static usb_device_t * usb_device
Definition: dcd_pio_usb.c:45
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
Definition: dcd_pio_usb.c:75
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: dcd_pio_usb.c:53
static void __no_inline_not_in_flash_func() handle_endpoint_irq(uint8_t tu_rhport, xfer_result_t result, volatile uint32_t *ep_reg)
Definition: dcd_pio_usb.c:156
void dcd_int_enable(uint8_t rhport)
Definition: dcd_pio_usb.c:63
void dcd_remote_wakeup(uint8_t rhport)
Definition: dcd_pio_usb.c:83
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
Definition: dcd_pio_usb.c:105
uint8_t const * buffer
Definition: midi_device.h:100
AUDIO Channel Cluster Descriptor (4.1)
Definition: audio.h:647
@ TUSB_SPEED_FULL
Definition: tusb_types.h:50
xfer_result_t
Definition: tusb_types.h:236
@ XFER_RESULT_FAILED
Definition: tusb_types.h:238
@ XFER_RESULT_SUCCESS
Definition: tusb_types.h:237
@ XFER_RESULT_STALLED
Definition: tusb_types.h:239