29#if CFG_TUH_ENABLED && defined(TUP_USBIP_CHIPIDEA_FS)
31#ifdef TUP_USBIP_CHIPIDEA_FS_KINETIS
32 #include "fsl_device_registers.h"
35 #error "MCU is not supported"
147 for (num = 0; num < CFG_TUH_ENDPOINT_MAX * 2; ++num) {
149 if ((p->dev_addr ==
dev_addr) && (p->ep_addr == ep_addr))
158 unsigned const dir_tx =
tu_edpt_dir(pipe->ep_addr) ? 0 : 1;
160 unsigned const odd = ep->
odd;
162 TU_ASSERT(0 == bd[odd].own, -1);
168 bd[odd ].
data = pipe->data;
169 bd[odd ^ 1].
data = pipe->data ^ 1;
174 unsigned const mps = pipe->max_packet_size;
179 bd[odd ^ 1].
bc = rem >= 2 * mps ? mps: rem - mps;
180 bd[odd ^ 1].
addr = pipe->buffer + mps;
182 if (dir_tx) ++num_tokens;
184 bd[odd].
bc = rem >= mps ? mps: rem;
185 bd[odd].
addr = pipe->buffer;
196 unsigned msk = TU_GENMASK(31, pipenum);
198 if (next)
return next;
199 msk = TU_GENMASK(pipenum, 0);
208 unsigned const bc = bd->
bc;
209 unsigned const rem = pipe->
remaining - bc;
212 if (rem && bc == pipe->max_packet_size) {
213 int const next_rem = rem - pipe->max_packet_size;
216 bd->
addr += pipe->max_packet_size * 2;
217 bd->
bc = next_rem > pipe->max_packet_size ? pipe->max_packet_size: next_rem;
220 while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ;
221 KHCI->TOKEN = KHCI->TOKEN;
223 while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ;
224 KHCI->TOKEN = KHCI->TOKEN;
228 pipe->data = bd->
data ^ 1;
235 TU_ASSERT(0 <= num_tokens);
237 const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
238 NVIC_DisableIRQ(USB0_IRQn);
241 unsigned flags = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK;
242 flags |= USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK;
243 switch (pipe->xfer) {
245 flags |= USB_ENDPT_EPHSHK_MASK;
248 flags |= USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK;
251 flags |= USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK;
256 KHCI->ENDPOINT[0].ENDPT = flags;
257 KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | pipe->dev_addr;
262 while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ;
264 }
while (--num_tokens);
265 if (ie) NVIC_EnableIRQ(USB0_IRQn);
272 pipe->buffer = bd->
addr;
273 pipe->data = bd->
data ^ 1;
277 KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK;
284 const unsigned s = KHCI->STAT;
285 KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK;
287 unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0;
293 const unsigned pid = bd->
tok_pid;
303 int pipenum = ep->pipenum;
317 if (0 <= next_pipenum)
331 tu_edpt_addr(KHCI->TOKEN & USB_TOKEN_TOKENENDPT_MASK, dir_in),
335 if (0 <= next_pipenum)
341 unsigned ctl = KHCI->CTL;
342 if (!(ctl & USB_CTL_JSTATE_MASK)) {
344 KHCI->ADDR = USB_ADDR_LSEN_MASK;
345 KHCI->ENDPOINT[0].ENDPT = USB_ENDPT_HOSTWOHUB_MASK;
352 KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK;
353 KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;
354 KHCI->CTL &= ~USB_CTL_USBENSOFEN_MASK;
356 KHCI->ENDPOINT[0].ENDPT = 0;
363 for (
unsigned i = 0; i < 2; ++i, ++bd) {
374 KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
375 while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK);
378 KHCI->USBTRC0 |= TU_BIT(6);
379 KHCI->BDTPAGE1 = (uint8_t)((uintptr_t)
_hcd.
bdt >> 8);
380 KHCI->BDTPAGE2 = (uint8_t)((uintptr_t)
_hcd.
bdt >> 16);
381 KHCI->BDTPAGE3 = (uint8_t)((uintptr_t)
_hcd.
bdt >> 24);
383 KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;
384 KHCI->CTL |= USB_CTL_ODDRST_MASK;
385 for (
unsigned i = 0; i < 16; ++i) {
386 KHCI->ENDPOINT[i].ENDPT = 0;
388 KHCI->CTL &= ~USB_CTL_ODDRST_MASK;
392 KHCI->CTL = USB_CTL_HOSTMODEEN_MASK | USB_CTL_SE0_MASK;
393 KHCI->USBCTRL = USB_USBCTRL_PDE_MASK;
395 NVIC_ClearPendingIRQ(USB0_IRQn);
396 KHCI->INTEN = USB_INTEN_ATTACHEN_MASK | USB_INTEN_TOKDNEEN_MASK |
397 USB_INTEN_USBRSTEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK;
406 NVIC_EnableIRQ(USB0_IRQn);
412 NVIC_DisableIRQ(USB0_IRQn);
421 uint32_t frmnum = KHCI->FRMNUML;
422 frmnum |= KHCI->FRMNUMH << 8u;
432 if (KHCI->ISTAT & USB_ISTAT_ATTACH_MASK)
440 KHCI->CTL &= ~USB_CTL_USBENSOFEN_MASK;
441 KHCI->CTL |= USB_CTL_RESET_MASK;
443 while (cnt--) __NOP();
444 KHCI->CTL &= ~USB_CTL_RESET_MASK;
445 KHCI->CTL |= USB_CTL_USBENSOFEN_MASK;
457 const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
458 NVIC_DisableIRQ(USB0_IRQn);
459 if (KHCI->ADDR & USB_ADDR_LSEN_MASK)
461 if (ie) NVIC_EnableIRQ(USB0_IRQn);
468 const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
469 NVIC_DisableIRQ(USB0_IRQn);
472 for (;p != end; ++p) {
474 tu_memclr(p,
sizeof(*p));
476 if (ie) NVIC_EnableIRQ(USB0_IRQn);
489 if (pipenum < 0)
return false;
493 pipe[0].buffer = (uint8_t*)(uintptr_t)setup_packet;
503 unsigned hostwohub = KHCI->ENDPOINT[0].ENDPT & USB_ENDPT_HOSTWOHUB_MASK;
504 KHCI->ENDPOINT[0].ENDPT = hostwohub |
505 USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK;
506 KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) |
dev_addr;
507 while (KHCI->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) ;
522 for (; p < end && (p->dev_addr || p->ep_addr); ++p) ;
523 if (p == end)
return false;
526 p->ep_addr = ep_addr;
534 TU_ASSERT(!q->dev_addr && !q->ep_addr);
552 TU_ASSERT(0 <= pipenum);
555 unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn);
556 NVIC_DisableIRQ(USB0_IRQn);
563 KHCI->INTEN |= USB_ISTAT_SOFTOK_MASK;
564 if (ie) NVIC_EnableIRQ(USB0_IRQn);
580 if (num < 0)
return false;
592 uint32_t is = KHCI->ISTAT;
593 uint32_t msk = KHCI->INTEN;
598 KHCI->ISTAT = (is & ~msk & ~USB_ISTAT_TOKDNE_MASK) | USB_ISTAT_SOFTOK_MASK;
601 if (is & USB_ISTAT_ERROR_MASK) {
602 unsigned err = KHCI->ERRSTAT;
604 TU_LOG1(
" ERR %x\r\n",
err);
607 KHCI->INTEN &= ~USB_ISTAT_ERROR_MASK;
611 if (is & USB_ISTAT_USBRST_MASK) {
612 KHCI->INTEN = (msk & ~USB_INTEN_USBRSTEN_MASK) | USB_INTEN_ATTACHEN_MASK;
616 if (is & USB_ISTAT_ATTACH_MASK) {
617 KHCI->INTEN = (msk & ~USB_INTEN_ATTACHEN_MASK) | USB_INTEN_USBRSTEN_MASK;
622 if (is & USB_ISTAT_STALL_MASK) {
623 KHCI->ISTAT = USB_ISTAT_STALL_MASK;
625 if (is & USB_ISTAT_SOFTOK_MASK) {
626 msk &= ~USB_ISTAT_SOFTOK_MASK;
631 if (!(is & USB_ISTAT_TOKDNE_MASK))
635 if (is & USB_ISTAT_TOKDNE_MASK) {
static TU_ATTR_ALWAYS_INLINE unsigned __builtin_ctz(unsigned int value)
static TU_ATTR_ALWAYS_INLINE void hcd_event_device_remove(uint8_t rhport, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void hcd_event_device_attach(uint8_t rhport, bool in_isr)
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(512)
struct TU_ATTR_PACKED pipe_state_t
void hcd_int_disable(uint8_t rhport)
static void process_attach(uint8_t rhport)
static int prepare_packets(int pipenum)
static void process_bus_reset(uint8_t rhport)
struct TU_ATTR_PACKED endpoint_state_t
static int select_next_pipenum(int pipenum)
static void suspend_transfer(int pipenum, buffer_descriptor_t *bd)
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
void hcd_int_enable(uint8_t rhport)
static void process_tokdne(uint8_t rhport)
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen)
void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr)
void hcd_port_reset_end(uint8_t rhport)
TU_VERIFY_STATIC(sizeof(buffer_descriptor_t)==8, "size is not correct")
void hcd_port_reset(uint8_t rhport)
bool hcd_port_connect_status(uint8_t rhport)
uint32_t hcd_frame_number(uint8_t rhport)
tusb_speed_t hcd_port_speed_get(uint8_t rhport)
struct TU_ATTR_PACKED buffer_descriptor_t
void hcd_int_handler(uint8_t rhport, bool in_isr)
static bool resume_transfer(int pipenum)
static bool continue_transfer(int pipenum, buffer_descriptor_t *bd)
bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc)
static unsigned find_pipe(uint_fast8_t dev_addr, uint_fast8_t ep_addr)
AUDIO Channel Cluster Descriptor (4.1)
uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
endpoint_state_t endpoint[2]
buffer_descriptor_t bdt[2][2]
tusb_speed_t
defined base on EHCI specs value for Endpoint Speed
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
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)