Merge branch 'master' into dwc2_dma
This commit is contained in:
@@ -168,14 +168,14 @@ enum {
|
||||
};
|
||||
|
||||
enum {
|
||||
MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame
|
||||
MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame to save CPU/SPI bus usage
|
||||
};
|
||||
|
||||
enum {
|
||||
EP_STATE_IDLE = 0,
|
||||
EP_STATE_COMPLETE = 1,
|
||||
EP_STATE_ABORTING = 2,
|
||||
EP_STATE_ATTEMPT_1 = 3, // pending 1st attempt
|
||||
EP_STATE_ATTEMPT_1 = 3, // Number of attempts to transfer in a frame. Incremented after each NAK
|
||||
EP_STATE_ATTEMPT_MAX = 15
|
||||
};
|
||||
|
||||
@@ -183,17 +183,20 @@ enum {
|
||||
//
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
uint8_t ep_num : 4;
|
||||
uint8_t is_setup : 1;
|
||||
uint8_t is_out : 1;
|
||||
uint8_t is_iso : 1;
|
||||
} hxfr_bm_t;
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(hxfr_bm_t) == 1, "size is not correct");
|
||||
|
||||
typedef struct {
|
||||
uint8_t daddr;
|
||||
|
||||
union { ;
|
||||
struct TU_ATTR_PACKED {
|
||||
uint8_t ep_num : 4;
|
||||
uint8_t is_setup : 1;
|
||||
uint8_t is_out : 1;
|
||||
uint8_t is_iso : 1;
|
||||
}hxfr_bm;
|
||||
|
||||
union {
|
||||
hxfr_bm_t hxfr_bm;
|
||||
uint8_t hxfr;
|
||||
};
|
||||
|
||||
@@ -219,7 +222,16 @@ typedef struct {
|
||||
uint8_t hien;
|
||||
uint8_t mode;
|
||||
uint8_t peraddr;
|
||||
uint8_t hxfr;
|
||||
union {
|
||||
hxfr_bm_t hxfr_bm;
|
||||
uint8_t hxfr;
|
||||
};
|
||||
|
||||
// owner of data in SNDFIFO, for retrying NAKed without re-writing to FIFO
|
||||
struct {
|
||||
uint8_t daddr;
|
||||
uint8_t hxfr;
|
||||
}sndfifo_owner;
|
||||
|
||||
atomic_flag busy; // busy transferring
|
||||
|
||||
@@ -317,33 +329,9 @@ bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_is
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint16_t len, bool in_isr) {
|
||||
uint8_t hirq;
|
||||
reg |= CMDBYTE_WRITE;
|
||||
|
||||
max3421_spi_lock(rhport, in_isr);
|
||||
|
||||
tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1);
|
||||
_hcd_data.hirq = hirq;
|
||||
tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len);
|
||||
|
||||
max3421_spi_unlock(rhport, in_isr);
|
||||
}
|
||||
|
||||
static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) {
|
||||
uint8_t hirq;
|
||||
uint8_t const reg = RCVVFIFO_ADDR;
|
||||
|
||||
max3421_spi_lock(rhport, in_isr);
|
||||
|
||||
tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1);
|
||||
_hcd_data.hirq = hirq;
|
||||
tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len);
|
||||
|
||||
max3421_spi_unlock(rhport, in_isr);
|
||||
}
|
||||
|
||||
//------------- register write helper -------------//
|
||||
//--------------------------------------------------------------------
|
||||
// Register helper
|
||||
//--------------------------------------------------------------------
|
||||
TU_ATTR_ALWAYS_INLINE static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) {
|
||||
reg_write(rhport, HIRQ_ADDR, data, in_isr);
|
||||
// HIRQ write 1 is clear
|
||||
@@ -377,6 +365,47 @@ TU_ATTR_ALWAYS_INLINE static inline void sndbc_write(uint8_t rhport, uint8_t dat
|
||||
reg_write(rhport, SNDBC_ADDR, data, in_isr);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// FIFO access (receive, send, setup)
|
||||
//--------------------------------------------------------------------
|
||||
static void hwfifo_write(uint8_t rhport, uint8_t reg, const uint8_t* buffer, uint8_t len, bool in_isr) {
|
||||
uint8_t hirq;
|
||||
reg |= CMDBYTE_WRITE;
|
||||
|
||||
max3421_spi_lock(rhport, in_isr);
|
||||
|
||||
tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1);
|
||||
_hcd_data.hirq = hirq;
|
||||
tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len);
|
||||
|
||||
max3421_spi_unlock(rhport, in_isr);
|
||||
}
|
||||
|
||||
// Write to SNDFIFO if len > 0 and update SNDBC
|
||||
TU_ATTR_ALWAYS_INLINE static inline void hwfifo_send(uint8_t rhport, const uint8_t* buffer, uint8_t len, bool in_isr) {
|
||||
if (len) {
|
||||
hwfifo_write(rhport, SNDFIFO_ADDR, buffer, len, in_isr);
|
||||
}
|
||||
sndbc_write(rhport, len, in_isr);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void hwfifo_setup(uint8_t rhport, const uint8_t* buffer, bool in_isr) {
|
||||
hwfifo_write(rhport, SUDFIFO_ADDR, buffer, 8, in_isr);
|
||||
}
|
||||
|
||||
static void hwfifo_receive(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) {
|
||||
uint8_t hirq;
|
||||
uint8_t const reg = RCVVFIFO_ADDR;
|
||||
|
||||
max3421_spi_lock(rhport, in_isr);
|
||||
|
||||
tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1);
|
||||
_hcd_data.hirq = hirq;
|
||||
tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len);
|
||||
|
||||
max3421_spi_unlock(rhport, in_isr);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Endpoint helper
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -417,7 +446,7 @@ static void free_ep(uint8_t daddr) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if endpoint has an queued transfer and not reach max NAK
|
||||
// Check if endpoint has a queued transfer and not reach max NAK in this frame
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool is_ep_pending(max3421_ep_t const * ep) {
|
||||
uint8_t const state = ep->state;
|
||||
return ep->packet_size && (state >= EP_STATE_ATTEMPT_1) &&
|
||||
@@ -487,6 +516,7 @@ bool hcd_init(uint8_t rhport) {
|
||||
reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false);
|
||||
|
||||
// v1 is 0x01, v2 is 0x12, v3 is 0x13
|
||||
// Note: v1 and v2 has host OUT errata whose workaround is not implemented in this driver
|
||||
uint8_t const revision = reg_read(rhport, REVISION_ADDR, false);
|
||||
TU_LOG2_HEX(revision);
|
||||
TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false);
|
||||
@@ -615,22 +645,45 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * e
|
||||
return true;
|
||||
}
|
||||
|
||||
/* The microcontroller repeatedly writes the SNDFIFO register R2 to load the FIFO with up to 64 data bytes.
|
||||
* Then the microcontroller writes the SNDBC register, which this does three things:
|
||||
* 1. Tells the MAX3421E SIE (Serial Interface Engine) how many bytes in the FIFO to send.
|
||||
* 2. Connects the SNDFIFO and SNDBC register to the USB logic for USB transmission.
|
||||
* 3. Clears the SNDBAVIRQ interrupt flag. If the second FIFO is available for µC loading, the SNDBAVIRQ immediately re-asserts.
|
||||
|
||||
+-----------+
|
||||
--->| SNDBC-A |
|
||||
/ | SNDFIFO-A |
|
||||
/ +-----------+
|
||||
+------+ +-------------+ / +----------+
|
||||
| MCU |------>| R2: SNDFIFO |---- << Write R7 Flip >> ---| MAX3241E |
|
||||
|(hcd) | | R7: SNDBC | / | SIE |
|
||||
+------+ +-------------+ / +----------+
|
||||
+-----------+ /
|
||||
| SNDBC-B | /
|
||||
| SNDFIFO-B |<---
|
||||
+-----------+
|
||||
Note: xact_out() is called when starting a new transfer, continue a transfer (isr) or retry a transfer (NAK)
|
||||
For NAK retry, we do not need to write to FIFO or SNDBC register again.
|
||||
*/
|
||||
static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) {
|
||||
// Page 12: Programming BULK-OUT Transfers
|
||||
// TODO double buffered
|
||||
// TODO: double buffering for ISO transfer
|
||||
if (switch_ep) {
|
||||
peraddr_write(rhport, ep->daddr, in_isr);
|
||||
|
||||
uint8_t const hctl = (ep->data_toggle ? HCTL_SNDTOG1 : HCTL_SNDTOG0);
|
||||
const uint8_t hctl = (ep->data_toggle ? HCTL_SNDTOG1 : HCTL_SNDTOG0);
|
||||
reg_write(rhport, HCTL_ADDR, hctl, in_isr);
|
||||
}
|
||||
|
||||
uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size);
|
||||
TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,);
|
||||
if (xact_len) {
|
||||
fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr);
|
||||
// Only write to sndfifo and sdnbc register if it is not a NAKed retry
|
||||
if (!(ep->daddr == _hcd_data.sndfifo_owner.daddr && ep->hxfr == _hcd_data.sndfifo_owner.hxfr)) {
|
||||
// skip SNDBAV IRQ check, overwrite sndfifo if needed
|
||||
const uint8_t xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size);
|
||||
hwfifo_send(rhport, ep->buf, xact_len, in_isr);
|
||||
}
|
||||
sndbc_write(rhport, xact_len, in_isr);
|
||||
_hcd_data.sndfifo_owner.daddr = ep->daddr;
|
||||
_hcd_data.sndfifo_owner.hxfr = ep->hxfr;
|
||||
|
||||
hxfr_write(rhport, ep->hxfr, in_isr);
|
||||
}
|
||||
|
||||
@@ -648,7 +701,7 @@ static void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_is
|
||||
|
||||
static void xact_setup(uint8_t rhport, max3421_ep_t *ep, bool in_isr) {
|
||||
peraddr_write(rhport, ep->daddr, in_isr);
|
||||
fifo_write(rhport, SUDFIFO_ADDR, ep->buf, 8, in_isr);
|
||||
hwfifo_setup(rhport, ep->buf, in_isr);
|
||||
hxfr_write(rhport, HXFR_SETUP, in_isr);
|
||||
}
|
||||
|
||||
@@ -662,7 +715,7 @@ static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool
|
||||
|
||||
// status
|
||||
if (ep->buf == NULL || ep->total_len == 0) {
|
||||
uint8_t const hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN));
|
||||
const uint8_t hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN));
|
||||
peraddr_write(rhport, ep->daddr, in_isr);
|
||||
hxfr_write(rhport, hxfr, in_isr);
|
||||
return;
|
||||
@@ -823,11 +876,11 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re
|
||||
}
|
||||
|
||||
static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
||||
uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr);
|
||||
uint8_t const hresult = hrsl & HRSL_RESULT_MASK;
|
||||
uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK;
|
||||
uint8_t const hxfr_type = _hcd_data.hxfr & 0xf0;
|
||||
uint8_t const ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1;
|
||||
const uint8_t hrsl = reg_read(rhport, HRSL_ADDR, in_isr);
|
||||
const uint8_t hresult = hrsl & HRSL_RESULT_MASK;
|
||||
const uint8_t ep_num = _hcd_data.hxfr_bm.ep_num;
|
||||
const uint8_t hxfr_type = _hcd_data.hxfr & 0xf0;
|
||||
const uint8_t ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1;
|
||||
|
||||
max3421_ep_t *ep = find_opened_ep(_hcd_data.peraddr, ep_num, ep_dir);
|
||||
TU_VERIFY(ep, );
|
||||
@@ -842,7 +895,8 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
||||
// control endpoint -> retry immediately and return
|
||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||
return;
|
||||
} else if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) {
|
||||
}
|
||||
if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) {
|
||||
ep->state++;
|
||||
}
|
||||
}
|
||||
@@ -853,7 +907,6 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||
} else if (next_ep) {
|
||||
// switch to next pending endpoint
|
||||
// TODO could have issue with double buffered if not clear previously out data
|
||||
xact_generic(rhport, next_ep, true, in_isr);
|
||||
} else {
|
||||
// no more pending in this frame -> clear busy
|
||||
@@ -896,11 +949,15 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
||||
if (ep->state == EP_STATE_COMPLETE) {
|
||||
xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr);
|
||||
}else {
|
||||
// more to transfer
|
||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr);
|
||||
hxfr_write(rhport, _hcd_data.hxfr, in_isr); // more to transfer
|
||||
}
|
||||
} else {
|
||||
// SETUP or OUT transfer
|
||||
|
||||
// clear sndfifo owner since data is sent
|
||||
_hcd_data.sndfifo_owner.daddr = 0xff;
|
||||
_hcd_data.sndfifo_owner.hxfr = 0xff;
|
||||
|
||||
uint8_t xact_len;
|
||||
|
||||
if (hxfr_type & HXFR_SETUP) {
|
||||
@@ -917,8 +974,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) {
|
||||
if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) {
|
||||
xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr);
|
||||
} else {
|
||||
// more to transfer
|
||||
xact_out(rhport, ep, false, in_isr);
|
||||
xact_out(rhport, ep, false, in_isr); // more to transfer
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -978,16 +1034,16 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
|
||||
// not call this handler again. So we need to loop until all IRQ are cleared
|
||||
while (hirq & (HIRQ_RCVDAV_IRQ | HIRQ_HXFRDN_IRQ)) {
|
||||
if (hirq & HIRQ_RCVDAV_IRQ) {
|
||||
uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK;
|
||||
const uint8_t ep_num = _hcd_data.hxfr_bm.ep_num;
|
||||
max3421_ep_t* ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1);
|
||||
uint8_t xact_len = 0;
|
||||
|
||||
// RCVDAV_IRQ can trigger 2 times (dual buffered)
|
||||
while (hirq & HIRQ_RCVDAV_IRQ) {
|
||||
uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr);
|
||||
const uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr);
|
||||
xact_len = (uint8_t) tu_min16(rcvbc, ep->total_len - ep->xferred_len);
|
||||
if (xact_len) {
|
||||
fifo_read(rhport, ep->buf, xact_len, in_isr);
|
||||
hwfifo_receive(rhport, ep->buf, xact_len, in_isr);
|
||||
ep->buf += xact_len;
|
||||
ep->xferred_len += xact_len;
|
||||
}
|
||||
|
||||
@@ -207,6 +207,7 @@ void dcd_init(uint8_t rhport)
|
||||
USB_USBRSTMSK_M |
|
||||
USB_ENUMDONEMSK_M |
|
||||
USB_RESETDETMSK_M |
|
||||
USB_WKUPINT_M |
|
||||
USB_DISCONNINTMSK_M; // host most only
|
||||
|
||||
dcd_connect(rhport);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,16 +37,10 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"");
|
||||
|
||||
#include "host/hcd.h"
|
||||
|
||||
#if TU_CHECK_MCU(OPT_MCU_MSP432E4)
|
||||
#include "musb_msp432e.h"
|
||||
|
||||
#elif TU_CHECK_MCU(OPT_MCU_TM4C123, OPT_MCU_TM4C129)
|
||||
#include "musb_tm4c.h"
|
||||
|
||||
// HACK generalize later
|
||||
#include "musb_type.h"
|
||||
#define FIFO0_WORD FIFO0
|
||||
#include "musb_type.h"
|
||||
|
||||
#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129)
|
||||
#include "musb_ti.h"
|
||||
#else
|
||||
#error "Unsupported MCUs"
|
||||
#endif
|
||||
|
||||
150
src/portable/mentor/musb/musb_max32.h
Normal file
150
src/portable/mentor/musb/musb_max32.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#ifndef TUSB_MUSB_MAX32_H_
|
||||
#define TUSB_MUSB_MAX32_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "mxc_device.h"
|
||||
#include "usbhs_regs.h"
|
||||
|
||||
#define MUSB_CFG_SHARED_FIFO 1 // shared FIFO for TX and RX endpoints
|
||||
#define MUSB_CFG_DYNAMIC_FIFO 0 // dynamic EP FIFO sizing
|
||||
|
||||
const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS };
|
||||
|
||||
#if CFG_TUD_ENABLED
|
||||
#define USBHS_M31_CLOCK_RECOVERY
|
||||
|
||||
// Mapping of IRQ numbers to port. Currently just 1.
|
||||
static const IRQn_Type musb_irqs[] = {
|
||||
USB_IRQn
|
||||
};
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) {
|
||||
NVIC_EnableIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) {
|
||||
NVIC_DisableIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) {
|
||||
#ifdef NVIC_GetEnableIRQ // only defined in CMSIS 5
|
||||
return NVIC_GetEnableIRQ(musb_irqs[rhport]);
|
||||
#else
|
||||
uint32_t IRQn = (uint32_t) musb_irqs[rhport];
|
||||
return ((NVIC->ISER[IRQn >> 5UL] & (1UL << (IRQn & 0x1FUL))) != 0UL) ? 1UL : 0UL;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) {
|
||||
NVIC_ClearPendingIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
static inline void musb_dcd_int_handler_enter(uint8_t rhport) {
|
||||
mxc_usbhs_regs_t* hs_phy = MXC_USBHS;
|
||||
uint32_t mxm_int, mxm_int_en, mxm_is;
|
||||
|
||||
//Handle PHY specific events
|
||||
mxm_int = hs_phy->mxm_int;
|
||||
mxm_int_en = hs_phy->mxm_int_en;
|
||||
mxm_is = mxm_int & mxm_int_en;
|
||||
hs_phy->mxm_int = mxm_is;
|
||||
|
||||
if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) {
|
||||
dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void musb_dcd_phy_init(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
mxc_usbhs_regs_t* hs_phy = MXC_USBHS;
|
||||
|
||||
// Interrupt for VBUS disconnect
|
||||
hs_phy->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS;
|
||||
|
||||
musb_dcd_int_clear(rhport);
|
||||
|
||||
// Unsuspend the MAC
|
||||
hs_phy->mxm_suspend = 0;
|
||||
|
||||
// Configure PHY
|
||||
hs_phy->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11);
|
||||
hs_phy->m31_phy_xcfgi_63_32 = 0;
|
||||
hs_phy->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64);
|
||||
hs_phy->m31_phy_xcfgi_127_96 = 0;
|
||||
|
||||
#ifdef USBHS_M31_CLOCK_RECOVERY
|
||||
hs_phy->m31_phy_noncry_rstb = 1;
|
||||
hs_phy->m31_phy_noncry_en = 1;
|
||||
hs_phy->m31_phy_outclksel = 0;
|
||||
hs_phy->m31_phy_coreclkin = 0;
|
||||
hs_phy->m31_phy_xtlsel = 2; /* Select 25 MHz clock */
|
||||
#else
|
||||
hs_phy->m31_phy_noncry_rstb = 0;
|
||||
hs_phy->m31_phy_noncry_en = 0;
|
||||
hs_phy->m31_phy_outclksel = 1;
|
||||
hs_phy->m31_phy_coreclkin = 1;
|
||||
hs_phy->m31_phy_xtlsel = 3; /* Select 30 MHz clock */
|
||||
#endif
|
||||
hs_phy->m31_phy_pll_en = 1;
|
||||
hs_phy->m31_phy_oscouten = 1;
|
||||
|
||||
/* Reset PHY */
|
||||
hs_phy->m31_phy_ponrst = 0;
|
||||
hs_phy->m31_phy_ponrst = 1;
|
||||
}
|
||||
|
||||
// static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) {
|
||||
// (void) mps;
|
||||
//
|
||||
// //Most likely the caller has already grabbed the right register block. But
|
||||
// //as a precaution save and restore the register bank anyways
|
||||
// unsigned saved_index = musb_periph_inst[rhport]->index;
|
||||
//
|
||||
// musb_periph_inst[rhport]->index = epnum;
|
||||
//
|
||||
// //Disable double buffering
|
||||
// if (dir_in) {
|
||||
// musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE);
|
||||
// } else {
|
||||
// musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS);
|
||||
// }
|
||||
//
|
||||
// musb_periph_inst[rhport]->index = saved_index;
|
||||
// }
|
||||
|
||||
#endif // CFG_TUD_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TUSB_MUSB_MAX32_H_
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021, Ha Thach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_MUSB_MSP432E_H_
|
||||
#define _TUSB_MUSB_MSP432E_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "msp.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021, Ha Thach (tinyusb.org)
|
||||
* Copyright (c) 2024, Brent Kowal (Analog Devices, Inc)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -24,8 +24,8 @@
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#ifndef _TUSB_MUSB_TM4C_H_
|
||||
#define _TUSB_MUSB_TM4C_H_
|
||||
#ifndef TUSB_MUSB_TI_H_
|
||||
#define TUSB_MUSB_TI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -33,13 +33,59 @@
|
||||
|
||||
#if CFG_TUSB_MCU == OPT_MCU_TM4C123
|
||||
#include "TM4C123.h"
|
||||
#define FIFO0_WORD FIFO0
|
||||
#define FIFO1_WORD FIFO1
|
||||
//#elif CFG_TUSB_MCU == OPT_MCU_TM4C129
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_MSP432E4
|
||||
#include "msp.h"
|
||||
#else
|
||||
#error "Unsupported MCUs"
|
||||
#endif
|
||||
|
||||
#define MUSB_CFG_SHARED_FIFO 0
|
||||
#define MUSB_CFG_DYNAMIC_FIFO 1
|
||||
#define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096
|
||||
|
||||
const uintptr_t MUSB_BASES[] = { USB0_BASE };
|
||||
|
||||
// Header supports both device and host modes. Only include what's necessary
|
||||
#if CFG_TUD_ENABLED
|
||||
|
||||
// Mapping of IRQ numbers to port. Currently just 1.
|
||||
static const IRQn_Type musb_irqs[] = {
|
||||
USB0_IRQn
|
||||
};
|
||||
|
||||
static inline void musb_dcd_phy_init(uint8_t rhport){
|
||||
(void)rhport;
|
||||
//Nothing to do for this part
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) {
|
||||
NVIC_EnableIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) {
|
||||
NVIC_DisableIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) {
|
||||
return NVIC_GetEnableIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) {
|
||||
NVIC_ClearPendingIRQ(musb_irqs[rhport]);
|
||||
}
|
||||
|
||||
static inline void musb_dcd_int_handler_enter(uint8_t rhport) {
|
||||
(void)rhport;
|
||||
//Nothing to do for this part
|
||||
}
|
||||
|
||||
#endif // CFG_TUD_ENABLED
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif // TUSB_MUSB_TI_H_
|
||||
File diff suppressed because it is too large
Load Diff
@@ -277,6 +277,11 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
|
||||
(void) rhport; (void) ep_addr;
|
||||
// TODO implement dcd_edpt_close()
|
||||
}
|
||||
|
||||
void dcd_edpt_close_all (uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -441,11 +441,11 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
|
||||
bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE));
|
||||
|
||||
if (control_status) {
|
||||
// Status Phase also requires EasyDMA has to be available as well !!!!
|
||||
edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS);
|
||||
|
||||
// The nRF doesn't interrupt on status transmit so we queue up a success response.
|
||||
dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr());
|
||||
|
||||
// Status Phase also requires EasyDMA has to be available as well !!!!
|
||||
edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS);
|
||||
} else if (dir == TUSB_DIR_OUT) {
|
||||
xfer->started = true;
|
||||
if (epnum == 0) {
|
||||
|
||||
@@ -335,6 +335,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
|
||||
(void) rhport; (void) ep_addr;
|
||||
// TODO implement dcd_edpt_close()
|
||||
}
|
||||
|
||||
void dcd_edpt_close_all (uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -53,6 +53,14 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) {
|
||||
//--------------------------------------------------------------------+
|
||||
// Implementation
|
||||
//--------------------------------------------------------------------+
|
||||
// Provide own byte by byte memcpy as not all copies are aligned
|
||||
static void unaligned_memcpy(void *dst, const void *src, size_t n) {
|
||||
uint8_t *dst_byte = (uint8_t*)dst;
|
||||
const uint8_t *src_byte = (const uint8_t*)src;
|
||||
while (n--) {
|
||||
*dst_byte++ = *src_byte++;
|
||||
}
|
||||
}
|
||||
|
||||
void rp2040_usb_init(void) {
|
||||
// Reset usb controller
|
||||
@@ -67,7 +75,6 @@ void rp2040_usb_init(void) {
|
||||
#pragma GCC diagnostic ignored "-Wstringop-overflow"
|
||||
#endif
|
||||
#endif
|
||||
memset(usb_hw, 0, sizeof(*usb_hw));
|
||||
memset(usb_dpram, 0, sizeof(*usb_dpram));
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
@@ -125,7 +132,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep,
|
||||
|
||||
if (!ep->rx) {
|
||||
// Copy data from user buffer to hw buffer
|
||||
memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen);
|
||||
unaligned_memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen);
|
||||
ep->user_buf += buflen;
|
||||
|
||||
// Mark as full
|
||||
@@ -230,7 +237,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uin
|
||||
// we have received AFTER we have copied it to the user buffer at the appropriate offset
|
||||
assert(buf_ctrl & USB_BUF_CTRL_FULL);
|
||||
|
||||
memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes);
|
||||
unaligned_memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes);
|
||||
ep->xferred_len = (uint16_t) (ep->xferred_len + xferred_bytes);
|
||||
ep->user_buf += xferred_bytes;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -54,44 +54,8 @@
|
||||
#endif
|
||||
|
||||
#define FSDEV_PMA_SIZE (512u)
|
||||
|
||||
// volatile 32-bit aligned
|
||||
#define _va32 volatile TU_ATTR_ALIGNED(4)
|
||||
|
||||
typedef struct {
|
||||
_va32 uint16_t EP0R; // 00: USB Endpoint 0 register
|
||||
_va32 uint16_t EP1R; // 04: USB Endpoint 1 register
|
||||
_va32 uint16_t EP2R; // 08: USB Endpoint 2 register
|
||||
_va32 uint16_t EP3R; // 0C: USB Endpoint 3 register
|
||||
_va32 uint16_t EP4R; // 10: USB Endpoint 4 register
|
||||
_va32 uint16_t EP5R; // 14: USB Endpoint 5 register
|
||||
_va32 uint16_t EP6R; // 18: USB Endpoint 6 register
|
||||
_va32 uint16_t EP7R; // 1C: USB Endpoint 7 register
|
||||
_va32 uint16_t RESERVED7[16]; // Reserved
|
||||
_va32 uint16_t CNTR; // 40: Control register
|
||||
_va32 uint16_t ISTR; // 44: Interrupt status register
|
||||
_va32 uint16_t FNR; // 48: Frame number register
|
||||
_va32 uint16_t DADDR; // 4C: Device address register
|
||||
_va32 uint16_t BTABLE; // 50: Buffer Table address register
|
||||
} USB_TypeDef;
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(USB_TypeDef) == 0x54, "Size is not correct");
|
||||
TU_VERIFY_STATIC(offsetof(USB_TypeDef, CNTR) == 0x40, "Wrong offset");
|
||||
|
||||
#define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */
|
||||
#define USB_PMAADDR (APB1PERIPH_BASE + 0x00006000UL) /*!< USB_IP Packet Memory Area base address */
|
||||
#define USB ((USB_TypeDef *)USB_BASE)
|
||||
|
||||
/******************************************************************************/
|
||||
/* */
|
||||
/* USB Device General registers */
|
||||
/* */
|
||||
/******************************************************************************/
|
||||
#define USB_CNTR (USB_BASE + 0x40U) /*!< Control register */
|
||||
#define USB_ISTR (USB_BASE + 0x44U) /*!< Interrupt status register */
|
||||
#define USB_FNR (USB_BASE + 0x48U) /*!< Frame number register */
|
||||
#define USB_DADDR (USB_BASE + 0x4CU) /*!< Device address register */
|
||||
#define USB_BTABLE (USB_BASE + 0x50U) /*!< Buffer Table address register */
|
||||
#define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL)
|
||||
#define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL)
|
||||
|
||||
/**************************** ISTR interrupt events *************************/
|
||||
#define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */
|
||||
|
||||
@@ -1,371 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright(c) 2016 STMicroelectronics
|
||||
* Copyright(c) N Conrad
|
||||
* Copyright (c) 2024, hathach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TUSB_FSDEV_COMMON_H
|
||||
#define TUSB_FSDEV_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
// FSDEV_PMA_SIZE is PMA buffer size in bytes.
|
||||
// On 512-byte devices, access with a stride of two words (use every other 16-bit address)
|
||||
// On 1024-byte devices, access with a stride of one word (use every 16-bit address)
|
||||
|
||||
// For purposes of accessing the packet
|
||||
#if ((FSDEV_PMA_SIZE) == 512u)
|
||||
#define FSDEV_PMA_STRIDE (2u)
|
||||
#elif ((FSDEV_PMA_SIZE) == 1024u)
|
||||
#define FSDEV_PMA_STRIDE (1u)
|
||||
#endif
|
||||
|
||||
// The fsdev_bus_t type can be used for both register and PMA access necessities
|
||||
// For type-safety create a new macro for the volatile address of PMAADDR
|
||||
// The compiler should warn us if we cast it to a non-volatile type?
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
typedef uint32_t fsdev_bus_t;
|
||||
static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR;
|
||||
|
||||
#else
|
||||
typedef uint16_t fsdev_bus_t;
|
||||
// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden)
|
||||
static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR;
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) {
|
||||
size_t total_word_offset = (((USBx)->BTABLE)>>1) + x;
|
||||
total_word_offset *= FSDEV_PMA_STRIDE;
|
||||
return &(pma[total_word_offset]);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Aligned buffer size according to hardware */
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) {
|
||||
/* The STM32 full speed USB peripheral supports only a limited set of
|
||||
* buffer sizes given by the RX buffer entry format in the USB_BTABLE. */
|
||||
uint16_t blocksize = (size > 62) ? 32 : 2;
|
||||
|
||||
// Round up while dividing requested size by blocksize
|
||||
uint16_t numblocks = (size + blocksize - 1) / blocksize ;
|
||||
|
||||
return numblocks * blocksize;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
volatile uint32_t *reg = (volatile uint32_t *)(USB_DRD_BASE + bEpIdx*4);
|
||||
*reg = wRegValue;
|
||||
#else
|
||||
volatile uint16_t *reg = (volatile uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
|
||||
*reg = (uint16_t)wRegValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
volatile const uint32_t *reg = (volatile const uint32_t *)(USB_DRD_BASE + bEpIdx*4);
|
||||
#else
|
||||
volatile const uint16_t *reg = (volatile const uint16_t *)((&USBx->EP0R) + bEpIdx*2u);
|
||||
#endif
|
||||
return *reg;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= (uint32_t)USB_EP_T_MASK;
|
||||
regVal |= wType;
|
||||
regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EP_T_FIELD;
|
||||
return regVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears bit CTR_RX / CTR_TX in the endpoint register.
|
||||
* @param USBx USB peripheral instance register address.
|
||||
* @param bEpIdx Endpoint Number.
|
||||
* @retval None
|
||||
*/
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EPREG_MASK;
|
||||
regVal &= ~USB_EP_CTR_RX;
|
||||
regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0)
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EPREG_MASK;
|
||||
regVal &= ~USB_EP_CTR_TX;
|
||||
regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0)
|
||||
pcd_set_endpoint(USBx, bEpIdx,regVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief gets counter of the tx buffer.
|
||||
* @param USBx USB peripheral instance register address.
|
||||
* @param bEpIdx Endpoint Number.
|
||||
* @retval Counter value
|
||||
*/
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
return (pma32[2*bEpIdx] & 0x03FF0000) >> 16;
|
||||
#else
|
||||
volatile const uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx);
|
||||
return *regPtr & 0x3ffU;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16;
|
||||
#else
|
||||
volatile const uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx);
|
||||
return *regPtr & 0x3ffU;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt
|
||||
#define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt
|
||||
|
||||
/**
|
||||
* @brief Sets address in an endpoint register.
|
||||
* @param USBx USB peripheral instance register address.
|
||||
* @param bEpIdx Endpoint Number.
|
||||
* @param bAddr Address.
|
||||
* @retval None
|
||||
*/
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EPREG_MASK;
|
||||
regVal |= bAddr;
|
||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
||||
pcd_set_endpoint(USBx, bEpIdx,regVal);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
return pma32[2*bEpIdx] & 0x0000FFFFu ;
|
||||
#else
|
||||
return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u);
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
return pma32[2*bEpIdx + 1] & 0x0000FFFFu;
|
||||
#else
|
||||
return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address
|
||||
#define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu);
|
||||
#else
|
||||
*pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u) = addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu);
|
||||
#else
|
||||
*pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u) = addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address
|
||||
#define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16);
|
||||
#else
|
||||
volatile uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx);
|
||||
*reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_dbuf1_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16);
|
||||
#else
|
||||
volatile uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx);
|
||||
*reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU);
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx,
|
||||
uint32_t blocksize, uint32_t numblocks) {
|
||||
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
(void) USBx;
|
||||
pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26);
|
||||
#else
|
||||
volatile uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u);
|
||||
*pdwReg = (blocksize << 15) | ((numblocks - blocksize) << 10);
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) {
|
||||
wCount = pcd_aligned_buffer_size(wCount);
|
||||
|
||||
/* We assume that the buffer size is already aligned to hardware requirements. */
|
||||
uint16_t blocksize = (wCount > 62) ? 1 : 0;
|
||||
uint16_t numblocks = wCount / (blocksize ? 32 : 2);
|
||||
|
||||
/* There should be no remainder in the above calculation */
|
||||
TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/);
|
||||
|
||||
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
|
||||
pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_dbuf0_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) {
|
||||
pcd_set_ep_bufsize(USBx, 2*bEpIdx, wCount);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) {
|
||||
pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount);
|
||||
}
|
||||
|
||||
#define pcd_set_ep_rx_dbuf1_cnt pcd_set_ep_rx_cnt
|
||||
|
||||
/**
|
||||
* @brief sets the status for tx transfer (bits STAT_TX[1:0]).
|
||||
* @param USBx USB peripheral instance register address.
|
||||
* @param bEpIdx Endpoint Number.
|
||||
* @param wState new state
|
||||
* @retval None
|
||||
*/
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EPTX_DTOGMASK;
|
||||
regVal ^= wState;
|
||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the status for rx transfer (bits STAT_TX[1:0])
|
||||
* @param USBx USB peripheral instance register address.
|
||||
* @param bEpIdx Endpoint Number.
|
||||
* @param wState new state
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EPRX_DTOGMASK;
|
||||
regVal ^= wState;
|
||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
return (regVal & USB_EPRX_STAT) >> (12u);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EPREG_MASK;
|
||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX;
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EPREG_MASK;
|
||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX;
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
if((regVal & USB_EP_DTOG_RX) != 0) {
|
||||
pcd_rx_dtog(USBx,bEpIdx);
|
||||
}
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
if((regVal & USB_EP_DTOG_TX) != 0) {
|
||||
pcd_tx_dtog(USBx,bEpIdx);
|
||||
}
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal |= USB_EP_KIND;
|
||||
regVal &= USB_EPREG_MASK;
|
||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) {
|
||||
uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx);
|
||||
regVal &= USB_EPKIND_MASK;
|
||||
regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX;
|
||||
pcd_set_endpoint(USBx, bEpIdx, regVal);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -35,6 +35,7 @@
|
||||
#if CFG_TUSB_MCU == OPT_MCU_STM32F0
|
||||
#include "stm32f0xx.h"
|
||||
#define FSDEV_PMA_SIZE (1024u)
|
||||
#define FSDEV_REG_BASE USB_BASE
|
||||
// F0x2 models are crystal-less
|
||||
// All have internal D+ pull-up
|
||||
// 070RB: 2 x 16 bits/word memory LPM Support, BCD Support
|
||||
@@ -81,12 +82,9 @@
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
|
||||
#include "stm32g0xx.h"
|
||||
#define FSDEV_BUS_32BIT
|
||||
#define FSDEV_PMA_SIZE (2048u)
|
||||
#undef USB_PMAADDR
|
||||
#define USB_PMAADDR USB_DRD_PMAADDR
|
||||
#define USB_TypeDef USB_DRD_TypeDef
|
||||
#define EP0R CHEP0R
|
||||
#define USB USB_DRD_FS
|
||||
|
||||
#define USB_EP_CTR_RX USB_EP_VTRX
|
||||
#define USB_EP_CTR_TX USB_EP_VTTX
|
||||
#define USB_EP_T_FIELD USB_CHEP_UTYPE
|
||||
@@ -99,7 +97,6 @@
|
||||
#define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
|
||||
#define USB_EPRX_STAT USB_CH_RX_VALID
|
||||
#define USB_EPKIND_MASK USB_EP_KIND_MASK
|
||||
#define USB USB_DRD_FS
|
||||
#define USB_CNTR_FRES USB_CNTR_USBRST
|
||||
#define USB_CNTR_RESUME USB_CNTR_L2RES
|
||||
#define USB_ISTR_EP_ID USB_ISTR_IDN
|
||||
@@ -109,17 +106,9 @@
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
|
||||
#include "stm32h5xx.h"
|
||||
#define FSDEV_BUS_32BIT
|
||||
|
||||
#if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE)
|
||||
#define USB_DRD_BASE USB_DRD_FS_BASE
|
||||
#endif
|
||||
|
||||
#define FSDEV_PMA_SIZE (2048u)
|
||||
#undef USB_PMAADDR
|
||||
#define USB_PMAADDR USB_DRD_PMAADDR
|
||||
#define USB_TypeDef USB_DRD_TypeDef
|
||||
#define EP0R CHEP0R
|
||||
#define USB USB_DRD_FS
|
||||
|
||||
#define USB_EP_CTR_RX USB_EP_VTRX
|
||||
#define USB_EP_CTR_TX USB_EP_VTTX
|
||||
#define USB_EP_T_FIELD USB_CHEP_UTYPE
|
||||
@@ -132,7 +121,6 @@
|
||||
#define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
|
||||
#define USB_EPRX_STAT USB_CH_RX_VALID
|
||||
#define USB_EPKIND_MASK USB_EP_KIND_MASK
|
||||
#define USB USB_DRD_FS
|
||||
#define USB_CNTR_FRES USB_CNTR_USBRST
|
||||
#define USB_CNTR_RESUME USB_CNTR_L2RES
|
||||
#define USB_ISTR_EP_ID USB_ISTR_IDN
|
||||
@@ -143,9 +131,8 @@
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
|
||||
#include "stm32wbxx.h"
|
||||
#define FSDEV_PMA_SIZE (1024u)
|
||||
/* ST provided header has incorrect value */
|
||||
#undef USB_PMAADDR
|
||||
#define USB_PMAADDR USB1_PMAADDR
|
||||
/* ST provided header has incorrect value of USB_PMAADDR */
|
||||
#define FSDEV_PMA_BASE USB1_PMAADDR
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
|
||||
#include "stm32l4xx.h"
|
||||
@@ -161,13 +148,9 @@
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
|
||||
#include "stm32u5xx.h"
|
||||
#define FSDEV_BUS_32BIT
|
||||
|
||||
#define FSDEV_PMA_SIZE (2048u)
|
||||
#undef USB_PMAADDR
|
||||
#define USB_PMAADDR USB_DRD_PMAADDR
|
||||
#define USB_TypeDef USB_DRD_TypeDef
|
||||
#define EP0R CHEP0R
|
||||
#define USB USB_DRD_FS
|
||||
|
||||
#define USB_EP_CTR_RX USB_EP_VTRX
|
||||
#define USB_EP_CTR_TX USB_EP_VTTX
|
||||
#define USB_EP_T_FIELD USB_CHEP_UTYPE
|
||||
@@ -180,7 +163,6 @@
|
||||
#define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
|
||||
#define USB_EPRX_STAT USB_CH_RX_VALID
|
||||
#define USB_EPKIND_MASK USB_EP_KIND_MASK
|
||||
#define USB USB_DRD_FS
|
||||
#define USB_CNTR_FRES USB_CNTR_USBRST
|
||||
#define USB_CNTR_RESUME USB_CNTR_L2RES
|
||||
#define USB_ISTR_EP_ID USB_ISTR_IDN
|
||||
@@ -193,6 +175,31 @@
|
||||
// This includes U0
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Register and PMA Base Address
|
||||
//--------------------------------------------------------------------+
|
||||
#ifndef FSDEV_REG_BASE
|
||||
#if defined(USB_BASE)
|
||||
#define FSDEV_REG_BASE USB_BASE
|
||||
#elif defined(USB_DRD_BASE)
|
||||
#define FSDEV_REG_BASE USB_DRD_BASE
|
||||
#elif defined(USB_DRD_FS_BASE)
|
||||
#define FSDEV_REG_BASE USB_DRD_FS_BASE
|
||||
#else
|
||||
#error "FSDEV_REG_BASE not defined"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FSDEV_PMA_BASE
|
||||
#if defined(USB_PMAADDR)
|
||||
#define FSDEV_PMA_BASE USB_PMAADDR
|
||||
#elif defined(USB_DRD_PMAADDR)
|
||||
#define FSDEV_PMA_BASE USB_DRD_PMAADDR
|
||||
#else
|
||||
#error "FSDEV_PMA_BASE not defined"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// This checks if the device has "LPM"
|
||||
#if defined(USB_ISTR_L1REQ)
|
||||
#define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ)
|
||||
|
||||
307
src/portable/st/stm32_fsdev/fsdev_type.h
Normal file
307
src/portable/st/stm32_fsdev/fsdev_type.h
Normal file
@@ -0,0 +1,307 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright(c) N Conrad
|
||||
* Copyright(c) 2024, hathach (tinyusb.org)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
#ifndef TUSB_FSDEV_TYPE_H
|
||||
#define TUSB_FSDEV_TYPE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdint.h"
|
||||
|
||||
// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it
|
||||
// Both of these MUST be a multiple of 2, and are in byte units.
|
||||
#ifndef FSDEV_BTABLE_BASE
|
||||
#define FSDEV_BTABLE_BASE 0U
|
||||
#endif
|
||||
|
||||
TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes");
|
||||
|
||||
// FSDEV_PMA_SIZE is PMA buffer size in bytes.
|
||||
// - 512-byte devices, access with a stride of two words (use every other 16-bit address)
|
||||
// - 1024-byte devices, access with a stride of one word (use every 16-bit address)
|
||||
// - 2048-byte devices, access with 32-bit address
|
||||
|
||||
// For purposes of accessing the packet
|
||||
#if FSDEV_PMA_SIZE == 512
|
||||
// 1x16 bit / word access scheme
|
||||
#define FSDEV_PMA_STRIDE 2
|
||||
#define pma_access_scheme TU_ATTR_ALIGNED(4)
|
||||
#elif FSDEV_PMA_SIZE == 1024
|
||||
// 2x16 bit / word access scheme
|
||||
#define FSDEV_PMA_STRIDE 1
|
||||
#define pma_access_scheme
|
||||
#elif FSDEV_PMA_SIZE == 2048
|
||||
// 32 bit access scheme
|
||||
#define FSDEV_BUS_32BIT
|
||||
#define FSDEV_PMA_STRIDE 1
|
||||
#define pma_access_scheme
|
||||
#endif
|
||||
|
||||
// The fsdev_bus_t type can be used for both register and PMA access necessities
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
typedef uint32_t fsdev_bus_t;
|
||||
#define fsdevbus_unaligned_read(_addr) tu_unaligned_read32(_addr)
|
||||
#define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write32(_addr, _value)
|
||||
#else
|
||||
typedef uint16_t fsdev_bus_t;
|
||||
#define fsdevbus_unaligned_read(_addr) tu_unaligned_read16(_addr)
|
||||
#define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write16(_addr, _value)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
FSDEV_BUS_SIZE = sizeof(fsdev_bus_t),
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BTable Typedef
|
||||
//--------------------------------------------------------------------+
|
||||
enum {
|
||||
BTABLE_BUF_TX = 0,
|
||||
BTABLE_BUF_RX = 1
|
||||
};
|
||||
|
||||
// hardware limit endpoint
|
||||
#define FSDEV_EP_COUNT 8
|
||||
|
||||
// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either
|
||||
// 16-bit or 32-bit depending on FSDEV_BUS_32BIT.
|
||||
// 0: TX (IN), 1: RX (OUT)
|
||||
typedef union {
|
||||
// data is strictly 16-bit access (address could be 32-bit aligned)
|
||||
struct {
|
||||
volatile pma_access_scheme uint16_t addr;
|
||||
volatile pma_access_scheme uint16_t count;
|
||||
} ep16[FSDEV_EP_COUNT][2];
|
||||
|
||||
// strictly 32-bit access
|
||||
struct {
|
||||
volatile uint32_t count_addr;
|
||||
} ep32[FSDEV_EP_COUNT][2];
|
||||
} fsdev_btable_t;
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct");
|
||||
TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM");
|
||||
|
||||
#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(FSDEV_BTABLE_BASE)))
|
||||
|
||||
typedef struct {
|
||||
volatile pma_access_scheme fsdev_bus_t value;
|
||||
} fsdev_pma_buf_t;
|
||||
|
||||
#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(_addr)))
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Registers Typedef
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// volatile 32-bit aligned
|
||||
#define _va32 volatile TU_ATTR_ALIGNED(4)
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
_va32 fsdev_bus_t reg;
|
||||
}ep[FSDEV_EP_COUNT];
|
||||
|
||||
_va32 uint32_t RESERVED7[8]; // Reserved
|
||||
_va32 fsdev_bus_t CNTR; // 40: Control register
|
||||
_va32 fsdev_bus_t ISTR; // 44: Interrupt status register
|
||||
_va32 fsdev_bus_t FNR; // 48: Frame number register
|
||||
_va32 fsdev_bus_t DADDR; // 4C: Device address register
|
||||
_va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only)
|
||||
_va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only)
|
||||
_va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only)
|
||||
} fsdev_regs_t;
|
||||
|
||||
TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset");
|
||||
TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct");
|
||||
|
||||
#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE)
|
||||
|
||||
|
||||
#ifndef USB_EPTX_STAT
|
||||
#define USB_EPTX_STAT 0x0030U
|
||||
#endif
|
||||
|
||||
#ifndef USB_EPRX_STAT
|
||||
#define USB_EPRX_STAT 0x3000U
|
||||
#endif
|
||||
|
||||
#ifndef USB_EPTX_STAT_Pos
|
||||
#define USB_EPTX_STAT_Pos 4u
|
||||
#endif
|
||||
|
||||
#ifndef USB_EP_DTOG_TX_Pos
|
||||
#define USB_EP_DTOG_TX_Pos 6u
|
||||
#endif
|
||||
|
||||
#ifndef USB_EP_CTR_TX_Pos
|
||||
#define USB_EP_CTR_TX_Pos 7u
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
EP_STAT_DISABLED = 0,
|
||||
EP_STAT_STALL = 1,
|
||||
EP_STAT_NAK = 2,
|
||||
EP_STAT_VALID = 3
|
||||
}ep_stat_t;
|
||||
|
||||
#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
|
||||
#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Endpoint Helper
|
||||
// - CTR is write 0 to clear
|
||||
// - DTOG and STAT are write 1 to toggle
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) {
|
||||
return FSDEV_REG->ep[ep_id].reg;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value, bool need_exclusive) {
|
||||
if (need_exclusive) {
|
||||
dcd_int_disable(0);
|
||||
}
|
||||
|
||||
FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value;
|
||||
|
||||
if (need_exclusive) {
|
||||
dcd_int_enable(0);
|
||||
}
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void ep_write_clear_ctr(uint32_t ep_id, tusb_dir_t dir) {
|
||||
uint32_t reg = FSDEV_REG->ep[ep_id].reg;
|
||||
reg |= USB_EP_CTR_TX | USB_EP_CTR_RX;
|
||||
reg &= USB_EPREG_MASK;
|
||||
reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
|
||||
ep_write(ep_id, reg, false);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) {
|
||||
*reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void ep_change_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) {
|
||||
*reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) {
|
||||
return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// BTable Helper
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu;
|
||||
#else
|
||||
return FSDEV_BTABLE->ep16[ep_id][buf_id].addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
|
||||
count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu);
|
||||
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
|
||||
#else
|
||||
FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t btable_get_count(uint32_t ep_id, uint8_t buf_id) {
|
||||
uint16_t count;
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16);
|
||||
#else
|
||||
count = FSDEV_BTABLE->ep16[ep_id][buf_id].count;
|
||||
#endif
|
||||
return count & 0x3FFU;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) {
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
|
||||
count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16);
|
||||
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
|
||||
#else
|
||||
uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count;
|
||||
cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU);
|
||||
FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Aligned buffer size according to hardware */
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) {
|
||||
/* The STM32 full speed USB peripheral supports only a limited set of
|
||||
* buffer sizes given by the RX buffer entry format in the USB_BTABLE. */
|
||||
uint16_t block_in_bytes;
|
||||
if (size > 62) {
|
||||
block_in_bytes = 32;
|
||||
*blsize = 1;
|
||||
*num_block = tu_div_ceil(size, 32);
|
||||
} else {
|
||||
block_in_bytes = 2;
|
||||
*blsize = 0;
|
||||
*num_block = tu_div_ceil(size, 2);
|
||||
}
|
||||
|
||||
return (*num_block) * block_in_bytes;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount) {
|
||||
uint8_t blsize, num_block;
|
||||
(void) pma_align_buffer_size(wCount, &blsize, &num_block);
|
||||
|
||||
/* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
|
||||
uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10);
|
||||
if (bl_nb == 0) {
|
||||
// zlp but 0 is invalid value, set blsize to 1 (32 bytes)
|
||||
// Note: lower value can cause PMAOVR on setup with ch32v203
|
||||
bl_nb = 1 << 15;
|
||||
}
|
||||
|
||||
#ifdef FSDEV_BUS_32BIT
|
||||
uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
|
||||
count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu);
|
||||
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
|
||||
#else
|
||||
FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
#if defined(TUP_USBIP_DWC2_STM32)
|
||||
#include "dwc2_stm32.h"
|
||||
#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
|
||||
#elif defined(TUP_USBIP_DWC2_ESP32)
|
||||
#include "dwc2_esp32.h"
|
||||
#elif TU_CHECK_MCU(OPT_MCU_GD32VF103)
|
||||
#include "dwc2_gd32.h"
|
||||
@@ -732,12 +732,34 @@ void dcd_remote_wakeup(uint8_t rhport) {
|
||||
void dcd_connect(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
|
||||
|
||||
#ifdef TUP_USBIP_DWC2_ESP32
|
||||
usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf;
|
||||
conf.pad_pull_override = 0;
|
||||
conf.dp_pullup = 0;
|
||||
conf.dp_pulldown = 0;
|
||||
conf.dm_pullup = 0;
|
||||
conf.dm_pulldown = 0;
|
||||
USB_WRAP.otg_conf = conf;
|
||||
#endif
|
||||
|
||||
dwc2->dctl &= ~DCTL_SDIS;
|
||||
}
|
||||
|
||||
void dcd_disconnect(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
|
||||
|
||||
#ifdef TUP_USBIP_DWC2_ESP32
|
||||
usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf;
|
||||
conf.pad_pull_override = 1;
|
||||
conf.dp_pullup = 0;
|
||||
conf.dp_pulldown = 1;
|
||||
conf.dm_pullup = 0;
|
||||
conf.dm_pulldown = 1;
|
||||
USB_WRAP.otg_conf = conf;
|
||||
#endif
|
||||
|
||||
dwc2->dctl |= DCTL_SDIS;
|
||||
}
|
||||
|
||||
@@ -1299,25 +1321,13 @@ void dcd_int_handler(uint8_t rhport) {
|
||||
// }
|
||||
}
|
||||
|
||||
#if defined(TUP_USBIP_DWC2_TEST_MODE) && CFG_TUD_TEST_MODE
|
||||
|
||||
bool dcd_check_test_mode_support(test_mode_t test_selector) {
|
||||
// Check if test mode selector is unsupported
|
||||
if (TEST_FORCE_ENABLE < test_selector || TEST_J > test_selector) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) {
|
||||
// Get port address...
|
||||
#if CFG_TUD_TEST_MODE
|
||||
void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector) {
|
||||
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
|
||||
|
||||
// Enable the test mode
|
||||
dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos);
|
||||
dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (((uint8_t) test_selector) << DCTL_TCTL_Pos);
|
||||
}
|
||||
|
||||
#endif /* TUP_USBIP_DWC2_TEST_MODE && CFG_TUD_TEST_MODE */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -32,61 +32,53 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
//#include "soc/usb_periph.h"
|
||||
#include "freertos/task.h"
|
||||
#include "soc/usb_wrap_struct.h"
|
||||
|
||||
#define DWC2_REG_BASE 0x60080000UL
|
||||
#define DWC2_EP_MAX 7
|
||||
#define DWC2_EP_IN_MAX 5
|
||||
|
||||
static const dwc2_controller_t _dwc2_controller[] =
|
||||
{
|
||||
static const dwc2_controller_t _dwc2_controller[] = {
|
||||
{ .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_in_count = DWC2_EP_IN_MAX, .ep_fifo_size = 1024 }
|
||||
};
|
||||
|
||||
static intr_handle_t usb_ih;
|
||||
|
||||
static void dcd_int_handler_wrap(void* arg)
|
||||
{
|
||||
(void) arg;
|
||||
static void dcd_int_handler_wrap(void* arg) {
|
||||
(void)arg;
|
||||
dcd_int_handler(0);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE
|
||||
static inline void dwc2_dcd_int_enable (uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) {
|
||||
(void)rhport;
|
||||
esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE
|
||||
static inline void dwc2_dcd_int_disable (uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) {
|
||||
(void)rhport;
|
||||
esp_intr_free(usb_ih);
|
||||
}
|
||||
|
||||
static inline void dwc2_remote_wakeup_delay(void)
|
||||
{
|
||||
TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1));
|
||||
}
|
||||
|
||||
// MCU specific PHY init, called BEFORE core reset
|
||||
static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
|
||||
{
|
||||
(void) dwc2;
|
||||
(void) hs_phy_type;
|
||||
TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) {
|
||||
(void)dwc2;
|
||||
(void)hs_phy_type;
|
||||
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
// MCU specific PHY update, it is called AFTER init() and core reset
|
||||
static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
|
||||
{
|
||||
(void) dwc2;
|
||||
(void) hs_phy_type;
|
||||
TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) {
|
||||
(void)dwc2;
|
||||
(void)hs_phy_type;
|
||||
|
||||
// nothing to do
|
||||
}
|
||||
@@ -95,4 +87,4 @@ static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DWC2_ESP32_H_ */
|
||||
#endif
|
||||
|
||||
@@ -102,6 +102,22 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate packet buffer used by ISO endpoints
|
||||
// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering
|
||||
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
|
||||
(void) rhport;
|
||||
(void) ep_addr;
|
||||
(void) largest_packet_size;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Configure and enable an ISO endpoint according to descriptor
|
||||
bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) {
|
||||
(void) rhport;
|
||||
(void) desc_ep;
|
||||
return false;
|
||||
}
|
||||
|
||||
void dcd_edpt_close_all (uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -332,6 +332,11 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
|
||||
(void) rhport; (void) ep_addr;
|
||||
// TODO implement dcd_edpt_close()
|
||||
}
|
||||
|
||||
void dcd_edpt_close_all (uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
@@ -436,6 +436,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
|
||||
return true;
|
||||
}
|
||||
|
||||
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
|
||||
(void) rhport; (void) ep_addr;
|
||||
// TODO implement dcd_edpt_close()
|
||||
}
|
||||
|
||||
void dcd_edpt_close_all (uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
Reference in New Issue
Block a user