30#if CFG_TUD_ENABLED && defined(TUP_USBIP_MUSB)
33#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport])
35#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED)
38_Pragma(
"GCC diagnostic ignored \"-Waddress-of-packed-member\"");
47#if defined(TUP_USBIP_MUSB_TI)
49#elif defined(TUP_USBIP_MUSB_ADI)
52 #error "Unsupported MCU"
59#define REQUEST_TYPE_INVALID (0xFFu)
63 volatile uint16_t
u16;
64 volatile uint32_t
u32;
81 uint16_t pipe_buf_is_fifo[2];
91#if MUSB_CFG_DYNAMIC_FIFO
101 uint8_t ffsize = 28 -
tu_min8(28, __builtin_clz(nbytes));
102 if ((8u << ffsize) < nbytes) {
115 bool double_packet) {
121 ffsize |= MUSB_FIFOSZ_DOUBLE_PACKET;
136 (void) musb; (void) epnum; (void) is_rx;
140TU_ATTR_ALWAYS_INLINE
static inline bool hwfifo_config(
musb_regs_t* musb,
unsigned epnum,
unsigned is_rx,
unsigned mps,
141 bool double_packet) {
142 (void) epnum; (void) mps;
143 if (!double_packet) {
144 #if defined(TUP_USBIP_MUSB_ADI)
163 const uint8_t csrl_dtog = clear_dtog ? MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx) : 0;
166 for (
unsigned i=0; i<2; i++) {
167 if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) {
168 maxp_csr->csrl = MUSB_CSRL_FLUSH_FIFO(is_rx) | csrl_dtog;
176 uintptr_t addr = (uintptr_t)buf;
178 reg->
u32 = *(uint32_t
const *)addr;
183 reg->
u16 = *(uint16_t
const *)addr;
188 reg->
u8 = *(uint8_t
const *)addr;
195 uintptr_t addr = (uintptr_t)buf;
197 *(uint32_t *)addr = reg->
u32;
202 *(uint16_t *)addr = reg->
u16;
207 *(uint8_t *)addr = reg->
u8;
213 static const struct {
215 void (*tu_fifo_advance)(
tu_fifo_t *f, uint16_t n);
216 void (*pipe_read_write)(
void *buf,
volatile void *fifo,
unsigned len);
222 ops[dir].tu_fifo_get_info(f, &
info);
223 unsigned total_len = len;
224 len = TU_MIN(total_len,
info.len_lin);
225 ops[dir].pipe_read_write(
info.ptr_lin, fifo, len);
226 unsigned rem = total_len - len;
228 len = TU_MIN(rem,
info.len_wrap);
229 ops[dir].pipe_read_write(
info.ptr_wrap, fifo, len);
232 ops[dir].tu_fifo_advance(f, total_len - rem);
240 volatile uint32_t *fifo_ptr = &musb_regs->
fifo[0];
255 ep_csr->
csr0l = MUSB_CSRL0_RXRDYC;
262 unsigned epnum_minus1 = epnum - 1;
273 const unsigned mps = ep_csr->
tx_maxp;
274 const unsigned len = TU_MIN(mps, rem);
275 void *buf = pipe->
buf;
276 volatile void *fifo_ptr = &musb_regs->
fifo[epnum];
283 pipe->
buf = buf + len;
287 ep_csr->
tx_csrl = MUSB_TXCSRL1_TXRDY;
295 unsigned epnum_minus1 = epnum - 1;
301 TU_ASSERT(ep_csr->
rx_csrl & MUSB_RXCSRL1_RXRDY);
303 const unsigned mps = ep_csr->
rx_maxp;
305 const unsigned vld = ep_csr->
rx_count;
306 const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
307 void *buf = pipe->
buf;
308 volatile void *fifo_ptr = &musb_regs->
fifo[epnum];
314 pipe->
buf = buf + len;
318 if ((len < mps) || (rem == len)) {
329 unsigned epnum_minus1 = epnum - 1;
354 TU_ASSERT(req != REQUEST_TYPE_INVALID ||
total_bytes == 0);
365 if (req == REQUEST_TYPE_INVALID) {
370 TU_LOG1(
"Drop CONTROL_STAGE_ACK\r\n");
378 const unsigned len = TU_MIN(TU_MIN(rem, 64),
total_bytes);
379 volatile void *fifo_ptr = &musb_regs->
fifo[0];
388 if ((len < 64) || (rem == len)) {
392 ep_csr->
csr0l = MUSB_CSRL0_TXRDY | MUSB_CSRL0_DATAEND;
394 ep_csr->
csr0l = MUSB_CSRL0_TXRDY;
402 ep_csr->
csr0l = MUSB_CSRL0_RXRDYC;
410 ep_csr->
csr0l = MUSB_CSRL0_RXRDYC | MUSB_CSRL0_DATAEND;
419 uint_fast8_t csrl = ep_csr->
csr0l;
424 if (csrl & MUSB_CSRL0_STALLED) {
431 if (csrl & MUSB_CSRL0_SETEND) {
432 TU_LOG1(
" ABORT by the next packets\r\n");
433 ep_csr->
csr0l = MUSB_CSRL0_SETENDC;
443 req = REQUEST_TYPE_INVALID;
444 if (!(csrl & MUSB_CSRL0_RXRDY))
return;
447 if (csrl & MUSB_CSRL0_RXRDY) {
449 if (req == REQUEST_TYPE_INVALID) {
457 const unsigned vld = ep_csr->
count0;
459 const unsigned len = TU_MIN(TU_MIN(rem, 64), vld);
460 volatile void *fifo_ptr = &musb_regs->
fifo[0];
477 if (req != REQUEST_TYPE_INVALID && !
tu_edpt_dir(req)) {
505 const unsigned epn_minus1 = epn - 1;
511 if (ep_csr->
tx_csrl & MUSB_TXCSRL1_STALLED) {
512 ep_csr->
tx_csrl &= ~(MUSB_TXCSRL1_STALLED | MUSB_TXCSRL1_UNDRN);
518 if (ep_csr->
rx_csrl & MUSB_RXCSRL1_STALLED) {
519 ep_csr->
rx_csrl &= ~(MUSB_RXCSRL1_STALLED | MUSB_RXCSRL1_OVER);
538#if MUSB_CFG_DYNAMIC_FIFO
552 for (
unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
564#if CFG_TUSB_DEBUG >= MUSB_DEBUG
568 TU_LOG1(
"Number of endpoints: %u TX, %u RX\r\n", musb_regs->
epinfo_bit.tx_ep_num, musb_regs->
epinfo_bit.rx_ep_num);
569 TU_LOG1(
"RAM Info: %u DMA Channel, %u RAM address width\r\n", musb_regs->
raminfo_bit.dma_channel, musb_regs->
raminfo_bit.ram_bits);
571 musb_regs->
index = 0;
574#if MUSB_CFG_DYNAMIC_FIFO
575 TU_LOG1(
"Dynamic FIFO configuration\r\n");
577 for (uint8_t i=1; i <= musb_regs->
epinfo_bit.tx_ep_num; i++) {
578 musb_regs->
index = i;
589#if CFG_TUSB_DEBUG >= MUSB_DEBUG
619 ep_csr->
csr0l = MUSB_CSRL0_RXRDYC | MUSB_CSRL0_DATAEND;
625 musb_regs->
power |= MUSB_POWER_RESUME;
628 while (cnt--) __NOP();
630 musb_regs->
power &= ~MUSB_POWER_RESUME;
637 musb_regs->
power |= TUD_OPT_HIGH_SPEED ? MUSB_POWER_HSENAB : 0;
638 musb_regs->
power |= MUSB_POWER_SOFTCONN;
645 musb_regs->
power &= ~MUSB_POWER_SOFTCONN;
678 const uint8_t is_rx = 1 - dir_in;
679 musb_ep_maxp_csr_t* maxp_csr = &ep_csr->
maxp_csr[is_rx];
681 maxp_csr->maxp = mps;
683#if MUSB_CFG_SHARED_FIFO
685 maxp_csr->csrh |= MUSB_CSRH_TX_MODE;
702 const uint8_t is_rx = 1 - dir_in;
704 return hwfifo_config(musb, epn, is_rx, largest_packet_size,
true);
723 const uint8_t is_rx = 1 - dir_in;
724 musb_ep_maxp_csr_t* maxp_csr = &ep_csr->
maxp_csr[is_rx];
726 maxp_csr->maxp = mps;
727 maxp_csr->csrh |= MUSB_CSRH_ISO;
728#if MUSB_CFG_SHARED_FIFO
730 maxp_csr->csrh |= MUSB_CSRH_TX_MODE;
736#if MUSB_CFG_DYNAMIC_FIFO
756 for (
unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
758 for (
unsigned d = 0; d < 2; d++) {
759 musb_ep_maxp_csr_t* maxp_csr = &ep_csr->
maxp_csr[d];
767#if MUSB_CFG_DYNAMIC_FIFO
825 ep_csr->
csr0l = MUSB_CSRL0_STALL;
829 ep_csr->
maxp_csr[is_rx].csrl = MUSB_CSRL_SEND_STALL(is_rx);
847 ep_csr->
maxp_csr[is_rx].csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx);
857 const uint8_t saved_index = musb_regs->
index;
862 uint_fast8_t intr_usb = musb_regs->
intr_usb;
863 uint_fast8_t intr_tx = musb_regs->
intr_tx;
864 uint_fast8_t intr_rx = musb_regs->
intr_rx;
868 if (intr_usb & MUSB_IS_DISCON) {
870 if (intr_usb & MUSB_IS_SOF) {
873 if (intr_usb & MUSB_IS_RESET) {
876 if (intr_usb & MUSB_IS_RESUME) {
879 if (intr_usb & MUSB_IS_SUSPEND) {
884 if (intr_tx & TU_BIT(0)) {
886 intr_tx &= ~TU_BIT(0);
891 intr_tx &= ~TU_BIT(num);
898 intr_rx &= ~TU_BIT(num);
901 musb_regs->
index = saved_index;
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_signal(uint8_t rhport, dcd_eventid_t eid, bool in_isr)
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)
static TU_ATTR_ALWAYS_INLINE void dcd_event_setup_received(uint8_t rhport, uint8_t const *setup, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_reset(uint8_t rhport, tusb_speed_t speed, bool in_isr)
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes)
struct TU_ATTR_PACKED pipe_state_t
static void process_setup_packet(uint8_t rhport)
static TU_ATTR_ALWAYS_INLINE uint8_t hwfifo_byte2size(uint16_t nbytes)
static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr)
static void process_bus_reset(uint8_t rhport)
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
void dcd_int_handler(uint8_t rhport)
static TU_ATTR_ALWAYS_INLINE void hwfifo_reset(musb_regs_t *musb, unsigned epnum, unsigned is_rx)
bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
void dcd_disconnect(uint8_t rhport)
static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
void dcd_edpt_close_all(uint8_t rhport)
_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\"")
void dcd_int_disable(uint8_t rhport)
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
static void process_ep0(uint8_t rhport)
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr)
static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len)
void dcd_connect(uint8_t rhport)
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr)
static TU_ATTR_ALWAYS_INLINE bool hwfifo_config(musb_regs_t *musb, unsigned epnum, unsigned is_rx, unsigned mps, bool double_packet)
static uint32_t alloced_fifo_bytes
void print_musb_info(musb_regs_t *musb_regs)
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
static TU_ATTR_ALWAYS_INLINE void hwfifo_flush(musb_regs_t *musb, unsigned epnum, unsigned is_rx, bool clear_dtog)
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir)
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size)
void dcd_int_enable(uint8_t rhport)
void dcd_remote_wakeup(uint8_t rhport)
void dcd_sof_enable(uint8_t rhport, bool en)
static TU_ATTR_ALWAYS_INLINE unsigned __builtin_ctz(unsigned int value)
TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN union TU_ATTR_PACKED hw_fifo_t
static TU_ATTR_ALWAYS_INLINE void musb_dcd_int_disable(uint8_t rhport)
static void musb_dcd_phy_init(uint8_t rhport)
static void musb_dcd_int_handler_enter(uint8_t rhport)
static TU_ATTR_ALWAYS_INLINE void musb_dcd_int_clear(uint8_t rhport)
static TU_ATTR_ALWAYS_INLINE void musb_dcd_int_enable(uint8_t rhport)
static TU_ATTR_ALWAYS_INLINE unsigned musb_dcd_get_int_enable(uint8_t rhport)
static TU_ATTR_ALWAYS_INLINE musb_ep_csr_t * get_ep_csr(musb_regs_t *musb_regs, unsigned epnum)
AUDIO Channel Cluster Descriptor (4.1)
musb_ep_maxp_csr_t maxp_csr[2]
musb_ep_csr_t indexed_csr
__IO uint16_t fifo_addr[2]
__IO uint16_t rx_doulbe_packet_disable
struct TU_ATTR_PACKED::@190::@213 fifo_size_bit
__IO uint16_t tx_double_packet_disable
__IO uint16_t intren_ep[2]
__IO uint8_t config_data0
struct TU_ATTR_PACKED::@235::@256 hwvers_bit
struct TU_ATTR_PACKED::@237::@259 epinfo_bit
struct TU_ATTR_PACKED::@239::@261 raminfo_bit
uint16_t pipe_buf_is_fifo[2]
tusb_control_request_t setup_packet
pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX-1]
static TU_ATTR_ALWAYS_INLINE uint8_t tu_min8(uint8_t x, uint8_t y)
void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
Get linear write info.
void tu_fifo_advance_write_pointer(tu_fifo_t *f, uint16_t n)
Advance write pointer - intended to be used in combination with DMA. It is possible to fill the FIFO ...
void tu_fifo_advance_read_pointer(tu_fifo_t *f, uint16_t n)
Advance read pointer - intended to be used in combination with DMA. It is possible to read from the F...
void tu_fifo_get_read_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info)
Get read info.
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const *desc_ep)
TU_ATTR_PACKED_END TU_ATTR_BIT_FIELD_ORDER_END static TU_ATTR_ALWAYS_INLINE tusb_dir_t tu_edpt_dir(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)