Merge branch 'master' of https://github.com/hathach/tinyusb into pr1942
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright 2021 Bridgetek Pte Ltd
|
||||
@@ -24,15 +24,15 @@
|
||||
* This file is part of the TinyUSB stack.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Contains code adapted from Bridgetek Pte Ltd via license terms stated
|
||||
/*
|
||||
* Contains code adapted from Bridgetek Pte Ltd via license terms stated
|
||||
* in https://brtchip.com/BRTSourceCodeLicenseAgreement
|
||||
*/
|
||||
|
||||
#include "tusb_option.h"
|
||||
|
||||
#if CFG_TUD_ENABLED && \
|
||||
(CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X)
|
||||
(CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X)
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ft900.h>
|
||||
@@ -58,7 +58,7 @@ struct ft9xx_xfer_state
|
||||
{
|
||||
volatile uint8_t ready; // OUT Transfer has been received and waiting for transfer.
|
||||
volatile uint8_t valid; // Transfer is pending and total_size, remain_size, and buff_ptr are valid.
|
||||
|
||||
|
||||
int16_t total_size; // Total transfer size in bytes for this transfer.
|
||||
int16_t remain_size; // Total remaining in transfer.
|
||||
uint8_t *buff_ptr; // Pointer to buffer to transmit from or receive to.
|
||||
@@ -92,7 +92,7 @@ static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len
|
||||
|
||||
// Manage an OUT transfer from the host.
|
||||
// This can be up-to the maximum packet size of the endpoint.
|
||||
// Continuation of a transfer beyond the maximum packet size is performed
|
||||
// Continuation of a transfer beyond the maximum packet size is performed
|
||||
// by the interrupt handler.
|
||||
static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes)
|
||||
{
|
||||
@@ -125,7 +125,7 @@ static uint16_t _ft9xx_edpt_xfer_out(uint8_t ep_number, uint8_t *buffer, uint16_
|
||||
|
||||
// Manage an IN transfer to the host.
|
||||
// This can be up-to the maximum packet size of the endpoint.
|
||||
// Continuation of a transfer beyond the maximum packet size is performed
|
||||
// Continuation of a transfer beyond the maximum packet size is performed
|
||||
// by the interrupt handler.
|
||||
static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t xfer_bytes)
|
||||
{
|
||||
@@ -196,7 +196,7 @@ static uint16_t _ft9xx_edpt_xfer_in(uint8_t ep_number, uint8_t *buffer, uint16_t
|
||||
return xfer_bytes;
|
||||
}
|
||||
|
||||
// Reset all non-control endpoints to a default state.
|
||||
// Reset all non-control endpoints to a default state.
|
||||
// Control endpoint is always enabled and ready. All others disabled.
|
||||
static void _ft9xx_reset_edpts(void)
|
||||
{
|
||||
@@ -208,7 +208,7 @@ static void _ft9xx_reset_edpts(void)
|
||||
// Disable hardware.
|
||||
USBD_EP_CR_REG(i) = 0;
|
||||
}
|
||||
|
||||
|
||||
// Enable interrupts from USB device control.
|
||||
USBD_REG(cmie) = MASK_USBD_CMIE_ALL;
|
||||
}
|
||||
@@ -319,7 +319,7 @@ static void _dcd_ft9xx_detach(void)
|
||||
}
|
||||
|
||||
// Determine the speed of the USB to which we are connected.
|
||||
// Set the speed of the PHY accordingly.
|
||||
// Set the speed of the PHY accordingly.
|
||||
// High speed can be disabled through CFG_TUSB_RHPORT0_MODE or CFG_TUD_MAX_SPEED settings.
|
||||
static void _ft9xx_usb_speed(void)
|
||||
{
|
||||
@@ -379,16 +379,16 @@ static void _ft9xx_usb_speed(void)
|
||||
}
|
||||
|
||||
// Send a buffer to the USB IN FIFO.
|
||||
// When the macro USBD_USE_STREAMS is defined this will stream a buffer of data
|
||||
// When the macro USBD_USE_STREAMS is defined this will stream a buffer of data
|
||||
// to the FIFO using the most efficient MCU streamout combination.
|
||||
// If streaming is disabled then it will send each byte of the buffer in turn
|
||||
// If streaming is disabled then it will send each byte of the buffer in turn
|
||||
// to the FIFO. The is no reason to not stream.
|
||||
// The total number of bytes sent to the FIFO is returned.
|
||||
static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_t length)
|
||||
{
|
||||
uint16_t bytes_read = 0;
|
||||
uint16_t buff_size = length;
|
||||
|
||||
|
||||
#ifdef USBD_USE_STREAMS
|
||||
volatile uint8_t *data_reg;
|
||||
|
||||
@@ -423,7 +423,7 @@ static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_
|
||||
bytes_read = buff_size;
|
||||
}
|
||||
#else // USBD_USE_STREAMS
|
||||
|
||||
|
||||
bytes_read = buff_size;
|
||||
while (buff_size--)
|
||||
{
|
||||
@@ -438,7 +438,7 @@ static uint16_t _ft9xx_dusb_in(uint8_t ep_number, const uint8_t *buffer, uint16_
|
||||
// Receive a buffer from the USB OUT FIFO.
|
||||
// When the macro USBD_USE_STREAMS is defined this will stream from the FIFO
|
||||
// to a buffer of data using the most efficient MCU streamin combination.
|
||||
// If streaming is disabled then it will receive each byte from the FIFO in turn
|
||||
// If streaming is disabled then it will receive each byte from the FIFO in turn
|
||||
// to the buffer. The is no reason to not stream.
|
||||
// The total number of bytes received from the FIFO is returned.
|
||||
static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t length)
|
||||
@@ -448,7 +448,7 @@ static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len
|
||||
#endif // USBD_USE_STREAMS
|
||||
uint16_t bytes_read = 0;
|
||||
uint16_t buff_size = length;
|
||||
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
if (ep_number == USBD_EP_0)
|
||||
@@ -596,7 +596,7 @@ void dcd_remote_wakeup(uint8_t rhport)
|
||||
SYS->MSC0CFG = SYS->MSC0CFG | MASK_SYS_MSC0CFG_DEV_RMWAKEUP;
|
||||
|
||||
// At least 2 ms of delay needed for RESUME Data K state.
|
||||
delayms(2);
|
||||
delayms(2);
|
||||
|
||||
SYS->MSC0CFG &= ~MASK_SYS_MSC0CFG_DEV_RMWAKEUP;
|
||||
|
||||
@@ -621,7 +621,7 @@ void dcd_connect(uint8_t rhport)
|
||||
// Determine bus speed and signal speed to tusb.
|
||||
_ft9xx_usb_speed();
|
||||
}
|
||||
|
||||
|
||||
// Setup the control endpoint only.
|
||||
#if CFG_TUD_ENDPOINT0_SIZE == 64
|
||||
USBD_EP_CR_REG(USBD_EP_0) = (USBD_EP0_MAX_SIZE_64 << BIT_USBD_EP0_MAX_SIZE);
|
||||
@@ -702,7 +702,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
TU_LOG1("FT9xx endpoint size not valid: requested %d max 1024\r\n", ep_size);
|
||||
return false;
|
||||
}
|
||||
// Calculate actual amount of buffer RAM used by this endpoint. This may be more than the
|
||||
// Calculate actual amount of buffer RAM used by this endpoint. This may be more than the
|
||||
// requested size.
|
||||
ep_buff_size = 8 << ep_reg_size;
|
||||
|
||||
@@ -714,7 +714,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
if (ep_xfer[ep_number].type != USBD_EP_TYPE_DISABLED)
|
||||
{
|
||||
// This could be because an endpoint has been assigned with the same number.
|
||||
// On FT9xx, IN and OUT endpoints may not have the same number. e.g. There
|
||||
// On FT9xx, IN and OUT endpoints may not have the same number. e.g. There
|
||||
// cannot been an 0x81 and 0x01 endpoint.
|
||||
TU_LOG1("FT9xx endpoint %d already assigned\r\n", ep_number);
|
||||
return false;
|
||||
@@ -723,7 +723,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
// Check that there is enough buffer RAM to allocate to this new endpoint.
|
||||
// Available buffer RAM depends on the device revision.
|
||||
// The IN and OUT buffer RAM should be the same size.
|
||||
if (ep_dir == USBD_DIR_IN)
|
||||
if (ep_dir == USBD_DIR_IN)
|
||||
total_ram = USBD_RAMTOTAL_IN;
|
||||
else
|
||||
total_ram = USBD_RAMTOTAL_OUT;
|
||||
@@ -753,7 +753,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
|
||||
if (total_ram < ep_buff_size)
|
||||
{
|
||||
TU_LOG1("FT9xx insufficient buffer RAM for endpoint %d\r\n", ep_number);
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set the type of this endpoint in the control register.
|
||||
@@ -827,7 +827,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
|
||||
ep_xfer[ep_number].total_size = total_bytes;
|
||||
ep_xfer[ep_number].remain_size = total_bytes;
|
||||
ep_xfer[ep_number].buff_ptr = buffer;
|
||||
|
||||
|
||||
if (ep_number == USBD_EP_0)
|
||||
{
|
||||
ep_xfer[USBD_EP_0].dir = ep_dir;
|
||||
@@ -876,7 +876,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
|
||||
// then report the transfer complete with dcd_event_xfer_complete.
|
||||
ep_xfer[ep_number].valid = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
status = true;
|
||||
}
|
||||
else
|
||||
@@ -922,7 +922,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
CRITICAL_SECTION_END
|
||||
}
|
||||
|
||||
// Clear stall (non-control endpoint), data toggle is also reset to DATA0
|
||||
// Clear stall (non-control endpoint), data toggle is also reset to DATA0
|
||||
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
{
|
||||
uint8_t ep_number = tu_edpt_number(ep_addr);
|
||||
@@ -1025,7 +1025,7 @@ void dcd_int_handler(uint8_t rhport)
|
||||
|
||||
// Host has sent a SETUP packet. Receive this into the SETUP packet store.
|
||||
_ft9xx_dusb_out(USBD_EP_0, (uint8_t *)_ft9xx_setup_packet, sizeof(USB_device_request));
|
||||
|
||||
|
||||
// Send the packet to tinyusb.
|
||||
dcd_event_setup_received(BOARD_TUD_RHPORT, _ft9xx_setup_packet, true);
|
||||
|
||||
@@ -1046,13 +1046,13 @@ void dcd_int_handler(uint8_t rhport)
|
||||
{
|
||||
xfer_bytes = (uint16_t)ep_xfer[USBD_EP_0].total_size;
|
||||
|
||||
// Transfer incoming data from an OUT packet to the buffer supplied.
|
||||
// Transfer incoming data from an OUT packet to the buffer supplied.
|
||||
if (ep_xfer[USBD_EP_0].dir == TUSB_DIR_OUT)
|
||||
{
|
||||
xfer_bytes = _ft9xx_edpt_xfer_out(USBD_EP_0, ep_xfer[USBD_EP_0].buff_ptr, xfer_bytes);
|
||||
}
|
||||
// Now signal completion of data packet.
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT, USBD_EP_0 | (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0),
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT, USBD_EP_0 | (ep_xfer[USBD_EP_0].dir ? TUSB_DIR_IN_MASK : 0),
|
||||
xfer_bytes, XFER_RESULT_SUCCESS, true);
|
||||
|
||||
// Incoming FIFO has been cleared.
|
||||
@@ -1097,13 +1097,13 @@ void dcd_int_handler(uint8_t rhport)
|
||||
// Start or continue an OUT transfer.
|
||||
if (ep_xfer[ep_number].dir == TUSB_DIR_OUT)
|
||||
{
|
||||
xfer_bytes = _ft9xx_edpt_xfer_out(ep_number,
|
||||
ep_xfer[ep_number].buff_ptr,
|
||||
xfer_bytes = _ft9xx_edpt_xfer_out(ep_number,
|
||||
ep_xfer[ep_number].buff_ptr,
|
||||
(uint16_t)ep_xfer[ep_number].remain_size);
|
||||
|
||||
// Report each OUT packet received to the stack.
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT,
|
||||
ep_number /* | TUSB_DIR_OUT_MASK */,
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT,
|
||||
ep_number /* | TUSB_DIR_OUT_MASK */,
|
||||
xfer_bytes, XFER_RESULT_SUCCESS, true);
|
||||
|
||||
ep_xfer[ep_number].buff_ptr += xfer_bytes;
|
||||
@@ -1114,8 +1114,8 @@ void dcd_int_handler(uint8_t rhport)
|
||||
{
|
||||
if (ep_xfer[ep_number].remain_size > 0)
|
||||
{
|
||||
xfer_bytes = _ft9xx_edpt_xfer_in(ep_number,
|
||||
ep_xfer[ep_number].buff_ptr,
|
||||
xfer_bytes = _ft9xx_edpt_xfer_in(ep_number,
|
||||
ep_xfer[ep_number].buff_ptr,
|
||||
(uint16_t)ep_xfer[ep_number].remain_size);
|
||||
|
||||
ep_xfer[ep_number].buff_ptr += xfer_bytes;
|
||||
@@ -1124,8 +1124,8 @@ void dcd_int_handler(uint8_t rhport)
|
||||
|
||||
if (ep_xfer[ep_number].remain_size == 0)
|
||||
{
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT,
|
||||
ep_number | TUSB_DIR_IN_MASK,
|
||||
dcd_event_xfer_complete(BOARD_TUD_RHPORT,
|
||||
ep_number | TUSB_DIR_IN_MASK,
|
||||
ep_xfer[ep_number].total_size, XFER_RESULT_SUCCESS, true);
|
||||
}
|
||||
}
|
||||
@@ -1151,7 +1151,7 @@ void dcd_int_handler(uint8_t rhport)
|
||||
// once the transfer is initiated.
|
||||
// Strictly this should not happen for a non-control endpoint. Interrupts
|
||||
// are disabled when there are no transfers setup for an endpoint.
|
||||
ep_xfer[ep_number].ready = 1;
|
||||
ep_xfer[ep_number].ready = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1159,13 +1159,13 @@ void dcd_int_handler(uint8_t rhport)
|
||||
}
|
||||
}
|
||||
|
||||
// Power management interrupt handler.
|
||||
// Power management interrupt handler.
|
||||
// This handles USB device related power management interrupts only.
|
||||
void ft9xx_usbd_pm_ISR(void)
|
||||
{
|
||||
uint16_t pmcfg = SYS->PMCFG_H;
|
||||
|
||||
// Main interrupt handler is responible for
|
||||
// Main interrupt handler is responible for
|
||||
if (pmcfg & MASK_SYS_PMCFG_DEV_CONN_DEV)
|
||||
{
|
||||
// Signal connection interrupt
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021, Ha Thach (tinyusb.org)
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
|
||||
#define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base)
|
||||
|
||||
// Clean means to push any cached changes to RAM and invalidate "removes" the
|
||||
// entry from the cache.
|
||||
#if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1
|
||||
#define CleanInvalidateDCache_by_Addr SCB_CleanInvalidateDCache_by_Addr
|
||||
#else
|
||||
@@ -199,6 +201,8 @@ static void bus_reset(uint8_t rhport)
|
||||
_dcd_data.qhd[0][0].qtd_overlay.next = _dcd_data.qhd[0][1].qtd_overlay.next = QTD_NEXT_INVALID;
|
||||
|
||||
_dcd_data.qhd[0][0].int_on_setup = 1; // OUT only
|
||||
|
||||
CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t));
|
||||
}
|
||||
|
||||
void dcd_init(uint8_t rhport)
|
||||
@@ -541,7 +545,7 @@ static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir
|
||||
tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// only number of bytes in the IOC qtd
|
||||
dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), xferred_bytes, result, true);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
@@ -85,7 +85,7 @@ typedef struct
|
||||
}ehci_data_t;
|
||||
|
||||
// Periodic frame list must be 4K alignment
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4096) static ehci_data_t ehci_data;
|
||||
CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(4096) static ehci_data_t ehci_data;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// PROTOTYPE
|
||||
@@ -566,7 +566,7 @@ static void period_list_xfer_complete_isr(uint8_t hostid, uint32_t interval_ms)
|
||||
case EHCI_QTYPE_ITD: // TODO support hs/fs ISO
|
||||
case EHCI_QTYPE_SITD:
|
||||
case EHCI_QTYPE_FSTN:
|
||||
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
@@ -683,7 +683,7 @@ void hcd_int_handler(uint8_t rhport)
|
||||
|
||||
uint32_t int_status = regs->status;
|
||||
int_status &= regs->inten;
|
||||
|
||||
|
||||
regs->status = int_status; // Acknowledge handled interrupt
|
||||
|
||||
if (int_status == 0) return;
|
||||
|
||||
@@ -874,4 +874,3 @@ void dcd_int_disable (uint8_t rhport)
|
||||
}
|
||||
|
||||
#endif // #if OPT_MCU_ESP32S2 || OPT_MCU_ESP32S3
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Koji KITAYAMA
|
||||
@@ -572,7 +572,7 @@ static void process_bus_reset(uint8_t rhport)
|
||||
_dcd.pipe0.buf = NULL;
|
||||
|
||||
USB0->TXIE = 1; /* Enable only EP0 */
|
||||
USB0->RXIE = 0;
|
||||
USB0->RXIE = 0;
|
||||
|
||||
/* Clear FIFO settings */
|
||||
for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
|
||||
@@ -722,7 +722,7 @@ void dcd_edpt_close_all(uint8_t rhport)
|
||||
unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn);
|
||||
NVIC_DisableIRQ(USB0_IRQn);
|
||||
USB0->TXIE = 1; /* Enable only EP0 */
|
||||
USB0->RXIE = 0;
|
||||
USB0->RXIE = 0;
|
||||
for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) {
|
||||
regs->TXMAXP = 0;
|
||||
regs->TXCSRH = 0;
|
||||
@@ -854,7 +854,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
if (tu_edpt_dir(ep_addr)) { /* IN */
|
||||
regs->TXCSRL = USB_TXCSRL1_CLRDT;
|
||||
} else { /* OUT */
|
||||
regs->RXCSRL = USB_RXCSRL1_CLRDT;
|
||||
regs->RXCSRL = USB_RXCSRL1_CLRDT;
|
||||
}
|
||||
if (ie) NVIC_EnableIRQ(USB0_IRQn);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Koji KITAYAMA
|
||||
@@ -588,7 +588,7 @@ void hcd_int_disable(uint8_t rhport)
|
||||
uint32_t hcd_frame_number(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
/* The device must be reset at least once after connection
|
||||
/* The device must be reset at least once after connection
|
||||
* in order to start the frame counter. */
|
||||
if (_hcd.need_reset) hcd_port_reset(rhport);
|
||||
return USB0->FRAME;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Koji Kitayama
|
||||
@@ -486,7 +486,7 @@ void dcd_init(uint8_t rhport)
|
||||
#else
|
||||
U1PWRCbits.USBPWR = 1;
|
||||
#endif
|
||||
|
||||
|
||||
#if TU_PIC_INT_SIZE == 4
|
||||
uint32_t bdt_phys = KVA_TO_PA((uintptr_t)_dcd.bdt);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
|
||||
*******************************************************************************/
|
||||
/*******************************************************************************
|
||||
USBHS Peripheral Library Register Definitions
|
||||
USBHS Peripheral Library Register Definitions
|
||||
|
||||
File Name:
|
||||
usbhs_registers.h
|
||||
@@ -50,16 +50,16 @@
|
||||
#define USBHS_REG_INTRRX 0x004
|
||||
#define USBHS_REG_INTRTXE 0x006
|
||||
#define USBHS_REG_INTRRXE 0x008
|
||||
#define USBHS_REG_INTRUSB 0x00A
|
||||
#define USBHS_REG_INTRUSBE 0x00B
|
||||
#define USBHS_REG_INTRUSB 0x00A
|
||||
#define USBHS_REG_INTRUSBE 0x00B
|
||||
#define USBHS_REG_FRAME 0x00C
|
||||
#define USBHS_REG_INDEX 0x00E
|
||||
#define USBHS_REG_TESTMODE 0x00F
|
||||
|
||||
/*******************************************************
|
||||
* Endpoint Control Status Registers (CSR). These values
|
||||
* Endpoint Control Status Registers (CSR). These values
|
||||
* should be added to either the 0x10 to access the
|
||||
* register through Indexed CSR. To access the actual
|
||||
* register through Indexed CSR. To access the actual
|
||||
* CSR, see ahead in this header file.
|
||||
******************************************************/
|
||||
|
||||
@@ -99,20 +99,20 @@
|
||||
#define USBHS_EP_DEVICE_RX_SEND_STALL 0x20
|
||||
|
||||
/* FADDR - Device Function Address */
|
||||
typedef union
|
||||
typedef union
|
||||
{
|
||||
struct __attribute__((packed))
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
unsigned FUNC:7;
|
||||
unsigned :1;
|
||||
};
|
||||
|
||||
uint8_t w;
|
||||
uint8_t w;
|
||||
|
||||
} __USBHS_FADDR_t;
|
||||
|
||||
/* POWER - Control Resume and Suspend signalling */
|
||||
typedef union
|
||||
typedef union
|
||||
{
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
@@ -126,14 +126,14 @@ typedef union
|
||||
unsigned ISOUPD:1;
|
||||
};
|
||||
struct
|
||||
{
|
||||
{
|
||||
uint8_t w;
|
||||
};
|
||||
|
||||
} __USBHS_POWER_t;
|
||||
|
||||
/* INTRTXE - Transmit endpoint interrupt enable */
|
||||
typedef union
|
||||
typedef union
|
||||
{
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
@@ -155,7 +155,7 @@ typedef union
|
||||
} __USBHS_INTRTXE_t;
|
||||
|
||||
/* INTRRXE - Receive endpoint interrupt enable */
|
||||
typedef union
|
||||
typedef union
|
||||
{
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
@@ -198,7 +198,7 @@ typedef union
|
||||
} __USBHS_INTRUSBE_t;
|
||||
|
||||
/* FRAME - Frame number */
|
||||
typedef union
|
||||
typedef union
|
||||
{
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
@@ -213,7 +213,7 @@ typedef union
|
||||
} __USBHS_FRAME_t;
|
||||
|
||||
/* INDEX - Endpoint index */
|
||||
typedef union
|
||||
typedef union
|
||||
{
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
@@ -228,7 +228,7 @@ typedef union
|
||||
} __USBHS_INDEX_t;
|
||||
|
||||
/* TESTMODE - Test mode register */
|
||||
typedef union
|
||||
typedef union
|
||||
{
|
||||
struct __attribute__((packed))
|
||||
{
|
||||
@@ -248,7 +248,7 @@ typedef union
|
||||
|
||||
} __USBHS_TESTMODE_t;
|
||||
|
||||
/* COUNT0 - Indicates the amount of data received in endpoint 0 */
|
||||
/* COUNT0 - Indicates the amount of data received in endpoint 0 */
|
||||
typedef union
|
||||
{
|
||||
struct __attribute__((packed))
|
||||
@@ -627,7 +627,7 @@ typedef union
|
||||
};
|
||||
uint16_t w;
|
||||
|
||||
} __USBHS_TXMAXP_t;
|
||||
} __USBHS_TXMAXP_t;
|
||||
|
||||
/* TXFIFOSZ - Size of the transmit endpoint FIFO */
|
||||
typedef struct __attribute__((packed))
|
||||
@@ -781,7 +781,7 @@ typedef union
|
||||
|
||||
} __USBHS_DMACNTL_t;
|
||||
|
||||
/* Endpoint Control and Status Register Set */
|
||||
/* Endpoint Control and Status Register Set */
|
||||
typedef struct __attribute__((packed))
|
||||
{
|
||||
volatile __USBHS_TXMAXP_t TXMAXPbits;
|
||||
@@ -906,7 +906,7 @@ typedef struct __attribute__((aligned(4),packed))
|
||||
|
||||
volatile __USBHS_TXFIFOADD_t TXFIFOADDbits;
|
||||
volatile __USBHS_RXFIFOADD_t RXFIFOADDbits;
|
||||
|
||||
|
||||
volatile uint32_t VCONTROL;
|
||||
volatile uint16_t HWVERS;
|
||||
volatile uint8_t padding1[10];
|
||||
@@ -923,7 +923,7 @@ typedef struct __attribute__((aligned(4),packed))
|
||||
volatile __USBHS_TARGET_ADDR_t TADDR[16];
|
||||
volatile __USBHS_EPCSR_t EPCSR[16];
|
||||
volatile uint32_t DMA_INTR;
|
||||
volatile __USBHS_DMA_CHANNEL_t DMA_CHANNEL[8];
|
||||
volatile __USBHS_DMA_CHANNEL_t DMA_CHANNEL[8];
|
||||
volatile uint32_t RQPKTXOUNT[16];
|
||||
|
||||
} usbhs_registers_t;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018, hathach (tinyusb.org)
|
||||
|
||||
@@ -2007,7 +2007,7 @@
|
||||
|
||||
/** \brief DEVDMA hardware registers */
|
||||
typedef struct
|
||||
{
|
||||
{
|
||||
__IO uint32_t DEVDMANXTDSC; /**< (DEVDMA Offset: 0x00) Device DMA Channel Next Descriptor Address Register */
|
||||
__IO uint32_t DEVDMAADDRESS; /**< (DEVDMA Offset: 0x04) Device DMA Channel Address Register */
|
||||
__IO uint32_t DEVDMACONTROL; /**< (DEVDMA Offset: 0x08) Device DMA Channel Control Register */
|
||||
@@ -2016,7 +2016,7 @@ typedef struct
|
||||
|
||||
/** \brief HSTDMA hardware registers */
|
||||
typedef struct
|
||||
{
|
||||
{
|
||||
__IO uint32_t HSTDMANXTDSC; /**< (HSTDMA Offset: 0x00) Host DMA Channel Next Descriptor Address Register */
|
||||
__IO uint32_t HSTDMAADDRESS; /**< (HSTDMA Offset: 0x04) Host DMA Channel Address Register */
|
||||
__IO uint32_t HSTDMACONTROL; /**< (HSTDMA Offset: 0x08) Host DMA Channel Control Register */
|
||||
@@ -2025,7 +2025,7 @@ typedef struct
|
||||
|
||||
/** \brief USBHS hardware registers */
|
||||
typedef struct
|
||||
{
|
||||
{
|
||||
__IO uint32_t DEVCTRL; /**< (USBHS Offset: 0x00) Device General Control Register */
|
||||
__I uint32_t DEVISR; /**< (USBHS Offset: 0x04) Device Global Interrupt Status Register */
|
||||
__O uint32_t DEVICR; /**< (USBHS Offset: 0x08) Device Global Interrupt Clear Register */
|
||||
|
||||
@@ -241,7 +241,7 @@ static void dcd_ep_handler(uint8_t ep_ix)
|
||||
if (int_status & DEVEPTISR_RXOUTI)
|
||||
{
|
||||
uint8_t *ptr = EP_GET_FIFO_PTR(0,8);
|
||||
|
||||
|
||||
if (count && xfer->total_len)
|
||||
{
|
||||
uint16_t remain = xfer->total_len - xfer->queued_len;
|
||||
@@ -252,7 +252,7 @@ static void dcd_ep_handler(uint8_t ep_ix)
|
||||
if (xfer->buffer)
|
||||
{
|
||||
memcpy(xfer->buffer + xfer->queued_len, ptr, count);
|
||||
} else
|
||||
} else
|
||||
{
|
||||
tu_fifo_write_n(xfer->fifo, ptr, count);
|
||||
}
|
||||
@@ -281,7 +281,7 @@ static void dcd_ep_handler(uint8_t ep_ix)
|
||||
{
|
||||
// TX not complete
|
||||
dcd_transmit_packet(xfer, 0);
|
||||
} else
|
||||
} else
|
||||
{
|
||||
// TX complete
|
||||
dcd_event_xfer_complete(0, 0x80 + 0, xfer->total_len, XFER_RESULT_SUCCESS, true);
|
||||
@@ -292,7 +292,7 @@ static void dcd_ep_handler(uint8_t ep_ix)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
} else
|
||||
{
|
||||
if (int_status & DEVEPTISR_RXOUTI)
|
||||
{
|
||||
@@ -333,7 +333,7 @@ static void dcd_ep_handler(uint8_t ep_ix)
|
||||
{
|
||||
// TX not complete
|
||||
dcd_transmit_packet(xfer, ep_ix);
|
||||
} else
|
||||
} else
|
||||
{
|
||||
// TX complete
|
||||
dcd_event_xfer_complete(0, 0x80 + ep_ix, xfer->total_len, XFER_RESULT_SUCCESS, true);
|
||||
@@ -359,7 +359,7 @@ static void dcd_dma_handler(uint8_t ep_ix)
|
||||
if(USB_REG->DEVEPTCFG[ep_ix] & DEVEPTCFG_EPDIR)
|
||||
{
|
||||
dcd_event_xfer_complete(0, 0x80 + ep_ix, count, XFER_RESULT_SUCCESS, true);
|
||||
} else
|
||||
} else
|
||||
{
|
||||
dcd_event_xfer_complete(0, ep_ix, count, XFER_RESULT_SUCCESS, true);
|
||||
}
|
||||
@@ -507,12 +507,12 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||
// Enable Endpoint 0 Interrupts
|
||||
USB_REG->DEVIER = DEVIER_PEP_0;
|
||||
return true;
|
||||
} else
|
||||
} else
|
||||
{
|
||||
// Endpoint configuration is not successful
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
} else
|
||||
{
|
||||
// Enable the endpoint
|
||||
USB_REG->DEVEPT |= ((0x01 << epnum) << DEVEPT_EPEN0_Pos);
|
||||
@@ -544,7 +544,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||
{
|
||||
USB_REG->DEVIER = ((0x01 << epnum) << DEVIER_PEP_0_Pos);
|
||||
return true;
|
||||
} else
|
||||
} else
|
||||
{
|
||||
// Endpoint configuration is not successful
|
||||
return false;
|
||||
@@ -583,7 +583,7 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix)
|
||||
{
|
||||
memcpy(ptr, xfer->buffer + xfer->queued_len, len);
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
tu_fifo_read_n(xfer->fifo, ptr, len);
|
||||
}
|
||||
@@ -595,7 +595,7 @@ static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix)
|
||||
{
|
||||
// Control endpoint: clear the interrupt flag to send the data
|
||||
USB_REG->DEVEPTICR[0] = DEVEPTICR_TXINIC;
|
||||
} else
|
||||
} else
|
||||
{
|
||||
// Other endpoint types: clear the FIFO control flag to send the data
|
||||
USB_REG->DEVEPTIDR[ep_ix] = DEVEPTIDR_FIFOCONC;
|
||||
@@ -616,7 +616,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
|
||||
xfer->total_len = total_bytes;
|
||||
xfer->queued_len = 0;
|
||||
xfer->fifo = NULL;
|
||||
|
||||
|
||||
if (EP_DMA_SUPPORT(epnum) && total_bytes != 0)
|
||||
{
|
||||
// Force the CPU to flush the buffer. We increase the size by 32 because the call aligns the
|
||||
@@ -648,12 +648,12 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
|
||||
// and the DMA transfer must be not started.
|
||||
// It is the end of transfer
|
||||
return false;
|
||||
} else
|
||||
} else
|
||||
{
|
||||
if (dir == TUSB_DIR_OUT)
|
||||
{
|
||||
USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES;
|
||||
} else
|
||||
} else
|
||||
{
|
||||
dcd_transmit_packet(xfer,epnum);
|
||||
}
|
||||
@@ -701,20 +701,20 @@ bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
|
||||
|
||||
// Clean invalidate cache of linear part
|
||||
CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.ptr_lin, 4), info.len_lin + 31);
|
||||
|
||||
|
||||
USB_REG->DEVDMA[epnum - 1].DEVDMAADDRESS = (uint32_t)info.ptr_lin;
|
||||
if (info.len_wrap)
|
||||
{
|
||||
// Clean invalidate cache of wrapped part
|
||||
CleanInValidateCache((uint32_t*) tu_align((uint32_t) info.ptr_wrap, 4), info.len_wrap + 31);
|
||||
|
||||
|
||||
dma_desc[epnum - 1].next_desc = 0;
|
||||
dma_desc[epnum - 1].buff_addr = (uint32_t)info.ptr_wrap;
|
||||
dma_desc[epnum - 1].chnl_ctrl =
|
||||
udd_dma_ctrl_wrap | (info.len_wrap << DEVDMACONTROL_BUFF_LENGTH_Pos);
|
||||
// Clean cache of wrapped DMA descriptor
|
||||
CleanInValidateCache((uint32_t*)&dma_desc[epnum - 1], sizeof(dma_desc_t));
|
||||
|
||||
|
||||
udd_dma_ctrl_lin |= DEVDMASTATUS_DESC_LDST;
|
||||
USB_REG->DEVDMA[epnum - 1].DEVDMANXTDSC = (uint32_t)&dma_desc[epnum - 1];
|
||||
} else {
|
||||
@@ -743,7 +743,7 @@ bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
|
||||
if (dir == TUSB_DIR_OUT)
|
||||
{
|
||||
USB_REG->DEVEPTIER[epnum] = DEVEPTIER_RXOUTES;
|
||||
} else
|
||||
} else
|
||||
{
|
||||
dcd_transmit_packet(xfer,epnum);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
@@ -187,11 +187,16 @@ static void xact_out_dma(uint8_t epnum)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Trigger DMA move data from Endpoint -> SRAM
|
||||
NRF_USBD->ISOOUT.PTR = (uint32_t) xfer->buffer;
|
||||
NRF_USBD->ISOOUT.MAXCNT = xact_len;
|
||||
if (xfer->started)
|
||||
{
|
||||
// Trigger DMA move data from Endpoint -> SRAM
|
||||
NRF_USBD->ISOOUT.PTR = (uint32_t) xfer->buffer;
|
||||
NRF_USBD->ISOOUT.MAXCNT = xact_len;
|
||||
|
||||
start_dma(&NRF_USBD->TASKS_STARTISOOUT);
|
||||
start_dma(&NRF_USBD->TASKS_STARTISOOUT);
|
||||
} else {
|
||||
atomic_flag_clear(&_dcd.dma_running);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
/*
|
||||
Theory of operation:
|
||||
|
||||
The NUC100/NUC120 USBD peripheral has six "EP"s, but each is simplex,
|
||||
so two collectively (peripheral nomenclature of "EP0" and "EP1") are needed to
|
||||
implement USB EP0. PERIPH_EP0 and PERIPH_EP1 are used by this driver for
|
||||
The NUC100/NUC120 USBD peripheral has six "EP"s, but each is simplex,
|
||||
so two collectively (peripheral nomenclature of "EP0" and "EP1") are needed to
|
||||
implement USB EP0. PERIPH_EP0 and PERIPH_EP1 are used by this driver for
|
||||
EP0_IN and EP0_OUT respectively. This leaves up to four for user usage.
|
||||
*/
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
/*
|
||||
Theory of operation:
|
||||
|
||||
The NUC121/NUC125/NUC126 USBD peripheral has eight "EP"s, but each is simplex,
|
||||
so two collectively (peripheral nomenclature of "EP0" and "EP1") are needed to
|
||||
implement USB EP0. PERIPH_EP0 and PERIPH_EP1 are used by this driver for
|
||||
The NUC121/NUC125/NUC126 USBD peripheral has eight "EP"s, but each is simplex,
|
||||
so two collectively (peripheral nomenclature of "EP0" and "EP1") are needed to
|
||||
implement USB EP0. PERIPH_EP0 and PERIPH_EP1 are used by this driver for
|
||||
EP0_IN and EP0_OUT respectively. This leaves up to six for user usage.
|
||||
*/
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
/*
|
||||
Theory of operation:
|
||||
|
||||
The NUC505 USBD peripheral has twelve "EP"s, where each is simplex, in addition
|
||||
The NUC505 USBD peripheral has twelve "EP"s, where each is simplex, in addition
|
||||
to dedicated support for the control endpoint (EP0). The non-user endpoints
|
||||
are referred to as "user" EPs in this code, and follow the datasheet
|
||||
are referred to as "user" EPs in this code, and follow the datasheet
|
||||
nomenclature of EPA through EPL.
|
||||
*/
|
||||
|
||||
@@ -389,7 +389,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
|
||||
while (total_bytes < USBD->CEPRXCNT);
|
||||
for (int count = 0; count < total_bytes; count++)
|
||||
*buffer++ = USBD->CEPDAT_BYTE;
|
||||
|
||||
|
||||
dcd_event_xfer_complete(0, ep_addr, total_bytes, XFER_RESULT_SUCCESS, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Koji Kitayama
|
||||
@@ -26,12 +26,14 @@
|
||||
|
||||
#include "tusb_option.h"
|
||||
|
||||
#if CFG_TUD_ENABLED && ( \
|
||||
( CFG_TUSB_MCU == OPT_MCU_MKL25ZXX ) || ( CFG_TUSB_MCU == OPT_MCU_K32L2BXX ) \
|
||||
)
|
||||
#if CFG_TUD_ENABLED && defined(TUP_USBIP_CHIPIDEA_FS)
|
||||
|
||||
#include "fsl_device_registers.h"
|
||||
#define KHCI USB0
|
||||
#ifdef TUP_USBIP_CHIPIDEA_FS_KINETIS
|
||||
#include "fsl_device_registers.h"
|
||||
#define KHCI USB0
|
||||
#else
|
||||
#error "MCU is not supported"
|
||||
#endif
|
||||
|
||||
#include "device/dcd.h"
|
||||
|
||||
@@ -296,7 +298,7 @@ void dcd_int_disable(uint8_t rhport)
|
||||
|
||||
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
|
||||
{
|
||||
_dcd.addr = dev_addr & 0x7F;
|
||||
_dcd.addr = dev_addr & 0x7F;
|
||||
/* Response with status first before changing device address */
|
||||
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
|
||||
}
|
||||
@@ -528,7 +530,7 @@ void dcd_int_handler(uint8_t rhport)
|
||||
if (is & USB_ISTAT_SLEEP_MASK) {
|
||||
// TU_LOG2("Suspend: "); TU_LOG2_HEX(is);
|
||||
|
||||
// Note Host usually has extra delay after bus reset (without SOF), which could falsely
|
||||
// Note Host usually has extra delay after bus reset (without SOF), which could falsely
|
||||
// detected as Sleep event. Though usbd has debouncing logic so we are good
|
||||
KHCI->ISTAT = USB_ISTAT_SLEEP_MASK;
|
||||
process_bus_sleep(rhport);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Koji Kitayama
|
||||
@@ -26,12 +26,14 @@
|
||||
|
||||
#include "tusb_option.h"
|
||||
|
||||
#if CFG_TUH_ENABLED && ( \
|
||||
( CFG_TUSB_MCU == OPT_MCU_MKL25ZXX ) || ( CFG_TUSB_MCU == OPT_MCU_K32L2BXX ) \
|
||||
)
|
||||
#if CFG_TUH_ENABLED && defined(TUP_USBIP_CHIPIDEA_FS)
|
||||
|
||||
#include "fsl_device_registers.h"
|
||||
#define KHCI USB0
|
||||
#ifdef TUP_USBIP_CHIPIDEA_FS_KINETIS
|
||||
#include "fsl_device_registers.h"
|
||||
#define KHCI USB0
|
||||
#else
|
||||
#error "MCU is not supported"
|
||||
#endif
|
||||
|
||||
#include "host/hcd.h"
|
||||
|
||||
@@ -135,8 +137,8 @@ typedef struct
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
// BDT(Buffer Descriptor Table) must be 256-byte aligned
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static hcd_data_t _hcd;
|
||||
//CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _rx_buf[1024];
|
||||
CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(512) static hcd_data_t _hcd;
|
||||
//CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(4) static uint8_t _rx_buf[1024];
|
||||
|
||||
int find_pipe(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
@@ -414,7 +416,7 @@ void hcd_int_disable(uint8_t rhport)
|
||||
uint32_t hcd_frame_number(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
/* The device must be reset at least once after connection
|
||||
/* The device must be reset at least once after connection
|
||||
* in order to start the frame counter. */
|
||||
if (_hcd.need_reset) hcd_port_reset(rhport);
|
||||
uint32_t frmnum = KHCI->FRMNUML;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019, Ha Thach (tinyusb.org)
|
||||
@@ -44,4 +44,3 @@ void hcd_int_disable(uint8_t rhport)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
@@ -373,7 +373,7 @@ void dcd_edpt_close_all (uint8_t rhport)
|
||||
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
||||
{
|
||||
(void) rhport;
|
||||
|
||||
|
||||
uint8_t ep_id = ep_addr2id(ep_addr);
|
||||
_dcd.ep[ep_id][0].cmd_sts.active = _dcd.ep[ep_id][0].cmd_sts.active = 0; // TODO proper way is to EPSKIP then wait ep[][].active then write ep[][].disable (see table 778 in LPC55S69 Use Manual)
|
||||
_dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1;
|
||||
@@ -426,7 +426,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
|
||||
static void bus_reset(uint8_t rhport)
|
||||
{
|
||||
tu_memclr(&_dcd, sizeof(dcd_data_t));
|
||||
edpt_reset_all(rhport);
|
||||
edpt_reset_all(rhport);
|
||||
|
||||
// disable all endpoints as specified by LPC55S69 UM Table 778
|
||||
for(uint8_t ep_id = 0; ep_id < 2*MAX_EP_PAIRS; ep_id++)
|
||||
@@ -575,4 +575,3 @@ void dcd_int_handler(uint8_t rhport)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021, Ha Thach (tinyusb.org)
|
||||
|
||||
@@ -569,7 +569,7 @@ static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir
|
||||
tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// only number of bytes in the IOC qtd
|
||||
dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), xferred_bytes, result, true);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
@@ -145,7 +145,7 @@ enum {
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static ohci_data_t ohci_data;
|
||||
CFG_TUH_MEM_SECTION TU_ATTR_ALIGNED(256) static ohci_data_t ohci_data;
|
||||
|
||||
static ohci_ed_t * const p_ed_head[] =
|
||||
{
|
||||
@@ -715,4 +715,3 @@ void hcd_int_handler(uint8_t hostid)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018, hathach (tinyusb.org)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUD_RPI_PIO_USB
|
||||
|
||||
#include "pico.h"
|
||||
#include "hardware/sync.h"
|
||||
#include "rp2040_usb.h"
|
||||
|
||||
#if TUD_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX
|
||||
@@ -198,7 +199,7 @@ static void __tusb_irq_path_func(hw_handle_buff_status)(void)
|
||||
usb_hw_clear->buf_status = bit;
|
||||
|
||||
// IN transfer for even i, OUT transfer for odd i
|
||||
struct hw_endpoint *ep = hw_endpoint_get_by_num(i >> 1u, !(i & 1u));
|
||||
struct hw_endpoint *ep = hw_endpoint_get_by_num(i >> 1u, (i & 1u) ? TUSB_DIR_OUT : TUSB_DIR_IN);
|
||||
|
||||
// Continue xfer
|
||||
bool done = hw_endpoint_xfer_continue(ep);
|
||||
@@ -384,6 +385,11 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void)
|
||||
/* Controller API
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
// older SDK
|
||||
#ifndef PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY
|
||||
#define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff
|
||||
#endif
|
||||
|
||||
void dcd_init (uint8_t rhport)
|
||||
{
|
||||
assert(rhport == 0);
|
||||
|
||||
@@ -446,7 +446,7 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport)
|
||||
return TUSB_SPEED_FULL;
|
||||
default:
|
||||
panic("Invalid speed\n");
|
||||
return TUSB_SPEED_INVALID;
|
||||
// return TUSB_SPEED_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -613,7 +613,7 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
|
||||
(void) ep_addr;
|
||||
|
||||
panic("hcd_clear_stall");
|
||||
return true;
|
||||
// return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -68,15 +68,19 @@ void rp2040_usb_init(void)
|
||||
reset_block(RESETS_RESET_USBCTRL_BITS);
|
||||
unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
|
||||
|
||||
#ifdef __GNUC__
|
||||
// Clear any previous state just in case
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#if __GNUC__ > 6
|
||||
#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
|
||||
#endif
|
||||
|
||||
// Mux the controller to the onboard usb phy
|
||||
usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS;
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
#define __tusb_irq_path_func(x) x
|
||||
#endif
|
||||
|
||||
#define usb_hw_set hw_set_alias(usb_hw)
|
||||
#define usb_hw_clear hw_clear_alias(usb_hw)
|
||||
#define usb_hw_set ((usb_hw_t *) hw_set_alias_untyped(usb_hw))
|
||||
#define usb_hw_clear ((usb_hw_t *) hw_clear_alias_untyped(usb_hw))
|
||||
|
||||
#define pico_info(...) TU_LOG(2, __VA_ARGS__)
|
||||
#define pico_trace(...) TU_LOG(3, __VA_ARGS__)
|
||||
@@ -47,7 +47,7 @@ typedef struct hw_endpoint
|
||||
{
|
||||
// Is this a valid struct
|
||||
bool configured;
|
||||
|
||||
|
||||
// Transfer direction (i.e. IN is rx for host but tx for device)
|
||||
// allows us to common up transfer functions
|
||||
bool rx;
|
||||
@@ -119,17 +119,17 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t _hw_endpoint_buffer_control_get_val
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_value32 (struct hw_endpoint *ep, uint32_t value)
|
||||
{
|
||||
return _hw_endpoint_buffer_control_update32(ep, 0, value);
|
||||
_hw_endpoint_buffer_control_update32(ep, 0, value);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_set_mask32 (struct hw_endpoint *ep, uint32_t value)
|
||||
{
|
||||
return _hw_endpoint_buffer_control_update32(ep, ~value, value);
|
||||
_hw_endpoint_buffer_control_update32(ep, ~value, value);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void _hw_endpoint_buffer_control_clear_mask32 (struct hw_endpoint *ep, uint32_t value)
|
||||
{
|
||||
return _hw_endpoint_buffer_control_update32(ep, ~value, 0);
|
||||
_hw_endpoint_buffer_control_update32(ep, ~value, 0);
|
||||
}
|
||||
|
||||
static inline uintptr_t hw_data_offset (uint8_t *buf)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Koji Kitayama
|
||||
@@ -31,79 +31,36 @@
|
||||
// We disable SOF for now until needed later on
|
||||
#define USE_SOF 0
|
||||
|
||||
#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \
|
||||
CFG_TUSB_MCU == OPT_MCU_RX65X || \
|
||||
CFG_TUSB_MCU == OPT_MCU_RX72N )
|
||||
#if CFG_TUD_ENABLED && (TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) || \
|
||||
TU_CHECK_MCU(OPT_MCU_RAXXX))
|
||||
|
||||
#include "device/dcd.h"
|
||||
#include "iodefine.h"
|
||||
#include "rusb2_type.h"
|
||||
|
||||
#if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)
|
||||
#include "rusb2_rx.h"
|
||||
#elif TU_CHECK_MCU(OPT_MCU_RAXXX)
|
||||
#include "rusb2_ra.h"
|
||||
#else
|
||||
#error "Unsupported MCU"
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
// MACRO TYPEDEF CONSTANT ENUM
|
||||
//--------------------------------------------------------------------+
|
||||
#define SYSTEM_PRCR_PRC1 (1<<1)
|
||||
#define SYSTEM_PRCR_PRKEY (0xA5u<<8)
|
||||
|
||||
#define USB_FIFOSEL_TX ((uint16_t)(1u<<5))
|
||||
#define USB_FIFOSEL_BIGEND ((uint16_t)(1u<<8))
|
||||
#define USB_FIFOSEL_MBW_8 ((uint16_t)(0u<<10))
|
||||
#define USB_FIFOSEL_MBW_16 ((uint16_t)(1u<<10))
|
||||
#define USB_IS0_CTSQ ((uint16_t)(7u))
|
||||
#define USB_IS0_DVSQ ((uint16_t)(7u<<4))
|
||||
#define USB_IS0_VALID ((uint16_t)(1u<<3))
|
||||
#define USB_IS0_BRDY ((uint16_t)(1u<<8))
|
||||
#define USB_IS0_NRDY ((uint16_t)(1u<<9))
|
||||
#define USB_IS0_BEMP ((uint16_t)(1u<<10))
|
||||
#define USB_IS0_CTRT ((uint16_t)(1u<<11))
|
||||
#define USB_IS0_DVST ((uint16_t)(1u<<12))
|
||||
#define USB_IS0_SOFR ((uint16_t)(1u<<13))
|
||||
#define USB_IS0_RESM ((uint16_t)(1u<<14))
|
||||
#define USB_IS0_VBINT ((uint16_t)(1u<<15))
|
||||
#define USB_IS1_SACK ((uint16_t)(1u<<4))
|
||||
#define USB_IS1_SIGN ((uint16_t)(1u<<5))
|
||||
#define USB_IS1_EOFERR ((uint16_t)(1u<<6))
|
||||
#define USB_IS1_ATTCH ((uint16_t)(1u<<11))
|
||||
#define USB_IS1_DTCH ((uint16_t)(1u<<12))
|
||||
#define USB_IS1_BCHG ((uint16_t)(1u<<14))
|
||||
#define USB_IS1_OVRCR ((uint16_t)(1u<<15))
|
||||
/* LINK core registers */
|
||||
#if defined(__CCRX__)
|
||||
#define RUSB2 ((RUSB2_REG_t __evenaccess*) RUSB2_REG_BASE)
|
||||
#else
|
||||
#define RUSB2 ((RUSB2_REG_t*) RUSB2_REG_BASE)
|
||||
#endif
|
||||
|
||||
#define USB_IS0_CTSQ_MSK (7u)
|
||||
#define USB_IS0_CTSQ_SETUP (1u)
|
||||
#define USB_IS0_DVSQ_DEF (1u<<4)
|
||||
#define USB_IS0_DVSQ_ADDR (2u<<4)
|
||||
#define USB_IS0_DVSQ_SUSP0 (4u<<4)
|
||||
#define USB_IS0_DVSQ_SUSP1 (5u<<4)
|
||||
#define USB_IS0_DVSQ_SUSP2 (6u<<4)
|
||||
#define USB_IS0_DVSQ_SUSP3 (7u<<4)
|
||||
|
||||
#define USB_PIPECTR_PID_NAK (0u)
|
||||
#define USB_PIPECTR_PID_BUF (1u)
|
||||
#define USB_PIPECTR_PID_STALL (2u)
|
||||
#define USB_PIPECTR_CCPL (1u<<2)
|
||||
#define USB_PIPECTR_SQMON (1u<<6)
|
||||
#define USB_PIPECTR_SQCLR (1u<<8)
|
||||
#define USB_PIPECTR_ACLRM (1u<<9)
|
||||
#define USB_PIPECTR_INBUFM (1u<<14)
|
||||
#define USB_PIPECTR_BSTS (1u<<15)
|
||||
|
||||
#define USB_FIFOCTR_DTLN (0x1FF)
|
||||
#define USB_FIFOCTR_FRDY (1u<<13)
|
||||
#define USB_FIFOCTR_BCLR (1u<<14)
|
||||
#define USB_FIFOCTR_BVAL (1u<<15)
|
||||
|
||||
#define USB_PIPECFG_SHTNAK (1u<<7)
|
||||
#define USB_PIPECFG_DBLB (1u<<9)
|
||||
#define USB_PIPECFG_BULK (1u<<14)
|
||||
#define USB_PIPECFG_ISO (3u<<14)
|
||||
#define USB_PIPECFG_INT (2u<<14)
|
||||
|
||||
#define FIFO_REQ_CLR (1u)
|
||||
#define FIFO_COMPLETE (1u<<1)
|
||||
|
||||
// Start of definition of packed structs (used by the CCRX toolchain)
|
||||
/* Start of definition of packed structs (used by the CCRX toolchain) */
|
||||
TU_ATTR_PACKED_BEGIN
|
||||
TU_ATTR_BIT_FIELD_ORDER_BEGIN
|
||||
|
||||
typedef struct {
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
union {
|
||||
struct {
|
||||
uint16_t : 8;
|
||||
@@ -116,7 +73,7 @@ typedef struct {
|
||||
uint16_t TRN;
|
||||
} reg_pipetre_t;
|
||||
|
||||
typedef union {
|
||||
typedef union TU_ATTR_PACKED {
|
||||
struct {
|
||||
volatile uint16_t u8: 8;
|
||||
volatile uint16_t : 0;
|
||||
@@ -150,28 +107,6 @@ typedef struct
|
||||
//--------------------------------------------------------------------+
|
||||
static dcd_data_t _dcd;
|
||||
|
||||
static uint32_t disable_interrupt(void)
|
||||
{
|
||||
uint32_t pswi;
|
||||
#if defined(__CCRX__)
|
||||
pswi = get_psw() & 0x010000;
|
||||
clrpsw_i();
|
||||
#else
|
||||
pswi = __builtin_rx_mvfc(0) & 0x010000;
|
||||
__builtin_rx_clrpsw('I');
|
||||
#endif
|
||||
return pswi;
|
||||
}
|
||||
|
||||
static void enable_interrupt(uint32_t pswi)
|
||||
{
|
||||
#if defined(__CCRX__)
|
||||
set_psw(get_psw() | pswi);
|
||||
#else
|
||||
__builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned find_pipe(unsigned xfer)
|
||||
{
|
||||
switch (xfer) {
|
||||
@@ -202,22 +137,18 @@ static unsigned find_pipe(unsigned xfer)
|
||||
|
||||
static volatile uint16_t* get_pipectr(unsigned num)
|
||||
{
|
||||
volatile uint16_t *ctr = NULL;
|
||||
if (num) {
|
||||
ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD;
|
||||
ctr += num - 1;
|
||||
return (volatile uint16_t*)&(RUSB2->PIPE_CTR[num - 1]);
|
||||
} else {
|
||||
ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD;
|
||||
return (volatile uint16_t*)&(RUSB2->DCPCTR);
|
||||
}
|
||||
return ctr;
|
||||
}
|
||||
|
||||
static volatile reg_pipetre_t* get_pipetre(unsigned num)
|
||||
{
|
||||
volatile reg_pipetre_t* tre = NULL;
|
||||
if ((1 <= num) && (num <= 5)) {
|
||||
tre = (volatile reg_pipetre_t*)&USB0.PIPE1TRE.WORD;
|
||||
tre += num - 1;
|
||||
tre = (volatile reg_pipetre_t*)&(RUSB2->PIPE_TR[num - 1].E);
|
||||
}
|
||||
return tre;
|
||||
}
|
||||
@@ -225,36 +156,31 @@ static volatile reg_pipetre_t* get_pipetre(unsigned num)
|
||||
static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr)
|
||||
{
|
||||
(void)rhport;
|
||||
volatile uint16_t *ctr = NULL;
|
||||
const unsigned epn = tu_edpt_number(ep_addr);
|
||||
const unsigned epn = tu_edpt_number(ep_addr);
|
||||
if (epn) {
|
||||
const unsigned dir = tu_edpt_dir(ep_addr);
|
||||
const unsigned num = _dcd.ep[dir][epn];
|
||||
if (num) {
|
||||
ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD;
|
||||
ctr += num - 1;
|
||||
}
|
||||
return get_pipectr(num);
|
||||
} else {
|
||||
ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD;
|
||||
return get_pipectr(0);
|
||||
}
|
||||
return ctr;
|
||||
}
|
||||
|
||||
static unsigned edpt0_max_packet_size(void)
|
||||
{
|
||||
return USB0.DCPMAXP.BIT.MXPS;
|
||||
return RUSB2->DCPMAXP_b.MXPS;
|
||||
}
|
||||
|
||||
static unsigned edpt_max_packet_size(unsigned num)
|
||||
{
|
||||
USB0.PIPESEL.WORD = num;
|
||||
return USB0.PIPEMAXP.WORD;
|
||||
RUSB2->PIPESEL = num;
|
||||
return RUSB2->PIPEMAXP;
|
||||
}
|
||||
|
||||
static inline void pipe_wait_for_ready(unsigned num)
|
||||
{
|
||||
while (USB0.D0FIFOSEL.BIT.CURPIPE != num) ;
|
||||
while (!USB0.D0FIFOCTR.BIT.FRDY) ;
|
||||
while (RUSB2->D0FIFOSEL_b.CURPIPE != num) ;
|
||||
while (!RUSB2->D0FIFOCTR_b.FRDY) ;
|
||||
}
|
||||
|
||||
static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
|
||||
@@ -316,13 +242,15 @@ static bool pipe0_xfer_in(void)
|
||||
void *buf = pipe->buf;
|
||||
if (len) {
|
||||
if (pipe->ff) {
|
||||
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&USB0.CFIFO.WORD, len, TUSB_DIR_IN);
|
||||
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->CFIFO, len, TUSB_DIR_IN);
|
||||
} else {
|
||||
pipe_write_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len);
|
||||
pipe_write_packet(buf, (volatile void*)&RUSB2->CFIFO, len);
|
||||
pipe->buf = (uint8_t*)buf + len;
|
||||
}
|
||||
}
|
||||
if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||
if (len < mps) {
|
||||
RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
|
||||
}
|
||||
pipe->remaining = rem - len;
|
||||
return false;
|
||||
}
|
||||
@@ -333,18 +261,20 @@ static bool pipe0_xfer_out(void)
|
||||
const unsigned rem = pipe->remaining;
|
||||
|
||||
const unsigned mps = edpt0_max_packet_size();
|
||||
const unsigned vld = USB0.CFIFOCTR.BIT.DTLN;
|
||||
const unsigned vld = RUSB2->CFIFOCTR_b.DTLN;
|
||||
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
|
||||
void *buf = pipe->buf;
|
||||
if (len) {
|
||||
if (pipe->ff) {
|
||||
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&USB0.CFIFO.WORD, len, TUSB_DIR_OUT);
|
||||
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->CFIFO, len, TUSB_DIR_OUT);
|
||||
} else {
|
||||
pipe_read_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len);
|
||||
pipe_read_packet(buf, (volatile void*)&RUSB2->CFIFO, len);
|
||||
pipe->buf = (uint8_t*)buf + len;
|
||||
}
|
||||
}
|
||||
if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR;
|
||||
if (len < mps) {
|
||||
RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
|
||||
}
|
||||
pipe->remaining = rem - len;
|
||||
if ((len < mps) || (rem == len)) {
|
||||
pipe->buf = NULL;
|
||||
@@ -363,22 +293,24 @@ static bool pipe_xfer_in(unsigned num)
|
||||
return true;
|
||||
}
|
||||
|
||||
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0);
|
||||
RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
|
||||
const unsigned mps = edpt_max_packet_size(num);
|
||||
pipe_wait_for_ready(num);
|
||||
const unsigned len = TU_MIN(rem, mps);
|
||||
void *buf = pipe->buf;
|
||||
if (len) {
|
||||
if (pipe->ff) {
|
||||
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&USB0.D0FIFO.WORD, len, TUSB_DIR_IN);
|
||||
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->D0FIFO, len, TUSB_DIR_IN);
|
||||
} else {
|
||||
pipe_write_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len);
|
||||
pipe_write_packet(buf, (volatile void*)&RUSB2->D0FIFO, len);
|
||||
pipe->buf = (uint8_t*)buf + len;
|
||||
}
|
||||
}
|
||||
if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||
USB0.D0FIFOSEL.WORD = 0;
|
||||
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
if (len < mps) {
|
||||
RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
|
||||
}
|
||||
RUSB2->D0FIFOSEL = 0;
|
||||
while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */
|
||||
pipe->remaining = rem - len;
|
||||
return false;
|
||||
}
|
||||
@@ -388,24 +320,26 @@ static bool pipe_xfer_out(unsigned num)
|
||||
pipe_state_t *pipe = &_dcd.pipe[num];
|
||||
const unsigned rem = pipe->remaining;
|
||||
|
||||
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_8;
|
||||
RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT;
|
||||
const unsigned mps = edpt_max_packet_size(num);
|
||||
pipe_wait_for_ready(num);
|
||||
const unsigned vld = USB0.D0FIFOCTR.BIT.DTLN;
|
||||
const unsigned vld = RUSB2->D0FIFOCTR_b.DTLN;
|
||||
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
|
||||
void *buf = pipe->buf;
|
||||
if (len) {
|
||||
if (pipe->ff) {
|
||||
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&USB0.D0FIFO.WORD, len, TUSB_DIR_OUT);
|
||||
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->D0FIFO, len, TUSB_DIR_OUT);
|
||||
} else {
|
||||
pipe_read_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len);
|
||||
pipe_read_packet(buf, (volatile void*)&RUSB2->D0FIFO, len);
|
||||
pipe->buf = (uint8_t*)buf + len;
|
||||
}
|
||||
}
|
||||
if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BCLR;
|
||||
USB0.D0FIFOSEL.WORD = 0;
|
||||
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
pipe->remaining = rem - len;
|
||||
if (len < mps) {
|
||||
RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
|
||||
}
|
||||
RUSB2->D0FIFOSEL = 0;
|
||||
while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */
|
||||
pipe->remaining = rem - len;
|
||||
if ((len < mps) || (rem == len)) {
|
||||
pipe->buf = NULL;
|
||||
return NULL != buf;
|
||||
@@ -416,13 +350,13 @@ static bool pipe_xfer_out(unsigned num)
|
||||
static void process_setup_packet(uint8_t rhport)
|
||||
{
|
||||
uint16_t setup_packet[4];
|
||||
if (0 == (USB0.INTSTS0.WORD & USB_IS0_VALID)) return;
|
||||
USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR;
|
||||
setup_packet[0] = tu_le16toh(USB0.USBREQ.WORD);
|
||||
setup_packet[1] = USB0.USBVAL;
|
||||
setup_packet[2] = USB0.USBINDX;
|
||||
setup_packet[3] = USB0.USBLENG;
|
||||
USB0.INTSTS0.WORD = ~USB_IS0_VALID;
|
||||
if (0 == (RUSB2->INTSTS0 & RUSB2_INTSTS0_VALID_Msk)) return;
|
||||
RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
|
||||
setup_packet[0] = tu_le16toh(RUSB2->USBREQ);
|
||||
setup_packet[1] = RUSB2->USBVAL;
|
||||
setup_packet[2] = RUSB2->USBINDX;
|
||||
setup_packet[3] = RUSB2->USBLENG;
|
||||
RUSB2->INTSTS0 = ~((uint16_t)RUSB2_INTSTS0_VALID_Msk);
|
||||
dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet[0], true);
|
||||
}
|
||||
|
||||
@@ -430,7 +364,7 @@ static void process_status_completion(uint8_t rhport)
|
||||
{
|
||||
uint8_t ep_addr;
|
||||
/* Check the data stage direction */
|
||||
if (USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX) {
|
||||
if (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) {
|
||||
/* IN transfer. */
|
||||
ep_addr = tu_edpt_addr(0, TUSB_DIR_IN);
|
||||
} else {
|
||||
@@ -444,11 +378,12 @@ static bool process_pipe0_xfer(int buffer_type, uint8_t ep_addr, void* buffer, u
|
||||
{
|
||||
/* configure fifo direction and access unit settings */
|
||||
if (ep_addr) { /* IN, 2 bytes */
|
||||
USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0);
|
||||
while (!(USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX)) ;
|
||||
} else { /* OUT, a byte */
|
||||
USB0.CFIFOSEL.WORD = USB_FIFOSEL_MBW_8;
|
||||
while (USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX) ;
|
||||
RUSB2->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT |
|
||||
(TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
|
||||
while (!(RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ;
|
||||
} else { /* OUT, a byte */
|
||||
RUSB2->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT;
|
||||
while (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ;
|
||||
}
|
||||
|
||||
pipe_state_t *pipe = &_dcd.pipe[0];
|
||||
@@ -458,14 +393,14 @@ static bool process_pipe0_xfer(int buffer_type, uint8_t ep_addr, void* buffer, u
|
||||
if (total_bytes) {
|
||||
pipe->buf = buffer;
|
||||
if (ep_addr) { /* IN */
|
||||
TU_ASSERT(USB0.DCPCTR.BIT.BSTS && (USB0.USBREQ.WORD & 0x80));
|
||||
TU_ASSERT(RUSB2->DCPCTR_b.BSTS && (RUSB2->USBREQ & 0x80));
|
||||
pipe0_xfer_in();
|
||||
}
|
||||
USB0.DCPCTR.WORD = USB_PIPECTR_PID_BUF;
|
||||
RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF;
|
||||
} else {
|
||||
/* ZLP */
|
||||
pipe->buf = NULL;
|
||||
USB0.DCPCTR.WORD = USB_PIPECTR_CCPL | USB_PIPECTR_PID_BUF;
|
||||
RUSB2->DCPCTR = RUSB2_DCPCTR_CCPL_Msk | RUSB2_PIPE_CTR_PID_BUF;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -487,11 +422,11 @@ static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, ui
|
||||
if (total_bytes) {
|
||||
pipe_xfer_in(num);
|
||||
} else { /* ZLP */
|
||||
USB0.D0FIFOSEL.WORD = num;
|
||||
RUSB2->D0FIFOSEL = num;
|
||||
pipe_wait_for_ready(num);
|
||||
USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||
USB0.D0FIFOSEL.WORD = 0;
|
||||
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
|
||||
RUSB2->D0FIFOSEL = 0;
|
||||
while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
}
|
||||
} else {
|
||||
#if defined(__CCRX__)
|
||||
@@ -502,11 +437,11 @@ static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, ui
|
||||
if (pt) {
|
||||
const unsigned mps = edpt_max_packet_size(num);
|
||||
volatile uint16_t *ctr = get_pipectr(num);
|
||||
if (*ctr & 0x3) *ctr = USB_PIPECTR_PID_NAK;
|
||||
if (*ctr & 0x3) *ctr = RUSB2_PIPE_CTR_PID_NAK;
|
||||
pt->TRE = TU_BIT(8);
|
||||
pt->TRN = (total_bytes + mps - 1) / mps;
|
||||
pt->TRENB = 1;
|
||||
*ctr = USB_PIPECTR_PID_BUF;
|
||||
*ctr = RUSB2_PIPE_CTR_PID_BUF;
|
||||
}
|
||||
}
|
||||
// TU_LOG1("X %x %d %d\r\n", ep_addr, total_bytes, buffer_type);
|
||||
@@ -558,28 +493,28 @@ static void process_pipe_brdy(uint8_t rhport, unsigned num)
|
||||
|
||||
static void process_bus_reset(uint8_t rhport)
|
||||
{
|
||||
USB0.BEMPENB.WORD = 1;
|
||||
USB0.BRDYENB.WORD = 1;
|
||||
USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR;
|
||||
USB0.D0FIFOSEL.WORD = 0;
|
||||
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
USB0.D1FIFOSEL.WORD = 0;
|
||||
while (USB0.D1FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
volatile uint16_t *ctr = (volatile uint16_t*)((uintptr_t)(&USB0.PIPE1CTR.WORD));
|
||||
volatile uint16_t *tre = (volatile uint16_t*)((uintptr_t)(&USB0.PIPE1TRE.WORD));
|
||||
RUSB2->BEMPENB = 1;
|
||||
RUSB2->BRDYENB = 1;
|
||||
RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
|
||||
RUSB2->D0FIFOSEL = 0;
|
||||
while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
RUSB2->D1FIFOSEL = 0;
|
||||
while (RUSB2->D1FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
volatile uint16_t *ctr = (volatile uint16_t*)((uintptr_t) (&RUSB2->PIPE_CTR[0]));
|
||||
volatile uint16_t *tre = (volatile uint16_t*)((uintptr_t) (&RUSB2->PIPE_TR[0].E));
|
||||
for (int i = 1; i <= 5; ++i) {
|
||||
USB0.PIPESEL.WORD = i;
|
||||
USB0.PIPECFG.WORD = 0;
|
||||
*ctr = USB_PIPECTR_ACLRM;
|
||||
RUSB2->PIPESEL = i;
|
||||
RUSB2->PIPECFG = 0;
|
||||
*ctr = RUSB2_PIPE_CTR_ACLRM_Msk;
|
||||
*ctr = 0;
|
||||
++ctr;
|
||||
*tre = TU_BIT(8);
|
||||
tre += 2;
|
||||
}
|
||||
for (int i = 6; i <= 9; ++i) {
|
||||
USB0.PIPESEL.WORD = i;
|
||||
USB0.PIPECFG.WORD = 0;
|
||||
*ctr = USB_PIPECTR_ACLRM;
|
||||
RUSB2->PIPESEL = i;
|
||||
RUSB2->PIPECFG = 0;
|
||||
*ctr = RUSB2_PIPE_CTR_ACLRM_Msk;
|
||||
*ctr = 0;
|
||||
++ctr;
|
||||
}
|
||||
@@ -589,7 +524,7 @@ static void process_bus_reset(uint8_t rhport)
|
||||
|
||||
static void process_set_address(uint8_t rhport)
|
||||
{
|
||||
const uint32_t addr = USB0.USBADDR.BIT.USBADDR;
|
||||
const uint32_t addr = RUSB2->USBADDR_b.USBADDR;
|
||||
if (!addr) return;
|
||||
const tusb_control_request_t setup_packet = {
|
||||
#if defined(__CCRX__)
|
||||
@@ -608,59 +543,76 @@ static void process_set_address(uint8_t rhport)
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Device API
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#if 0 // previously present in the rx driver before generalization
|
||||
static uint32_t disable_interrupt(void)
|
||||
{
|
||||
uint32_t pswi;
|
||||
#if defined(__CCRX__)
|
||||
pswi = get_psw() & 0x010000;
|
||||
clrpsw_i();
|
||||
#else
|
||||
pswi = __builtin_rx_mvfc(0) & 0x010000;
|
||||
__builtin_rx_clrpsw('I');
|
||||
#endif
|
||||
return pswi;
|
||||
}
|
||||
|
||||
static void enable_interrupt(uint32_t pswi)
|
||||
{
|
||||
#if defined(__CCRX__)
|
||||
set_psw(get_psw() | pswi);
|
||||
#else
|
||||
__builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void dcd_init(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
/* Enable USB0 */
|
||||
|
||||
#if 0 // previously present in the rx driver before generalization
|
||||
uint32_t pswi = disable_interrupt();
|
||||
SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1;
|
||||
MSTP(USB0) = 0;
|
||||
SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY;
|
||||
enable_interrupt(pswi);
|
||||
USB0.SYSCFG.BIT.SCKE = 1;
|
||||
while (!USB0.SYSCFG.BIT.SCKE) ;
|
||||
USB0.SYSCFG.BIT.DRPD = 0;
|
||||
USB0.SYSCFG.BIT.DCFM = 0;
|
||||
USB0.SYSCFG.BIT.USBE = 1;
|
||||
|
||||
USB.DPUSR0R.BIT.FIXPHY0 = 0u; /* USB0 Transceiver Output fixed */
|
||||
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
|
||||
USB0.PHYSLEW.LONG = 0x5;
|
||||
IR(PERIB, INTB185) = 0;
|
||||
#else
|
||||
IR(USB0, USBI0) = 0;
|
||||
#endif
|
||||
|
||||
/* Setup default control pipe */
|
||||
USB0.DCPMAXP.BIT.MXPS = 64;
|
||||
USB0.INTENB0.WORD = USB_IS0_VBINT | USB_IS0_BRDY | USB_IS0_BEMP |
|
||||
USB_IS0_DVST | USB_IS0_CTRT | (USE_SOF ? USB_IS0_SOFR: 0) | USB_IS0_RESM;
|
||||
USB0.BEMPENB.WORD = 1;
|
||||
USB0.BRDYENB.WORD = 1;
|
||||
RUSB2->SYSCFG_b.SCKE = 1;
|
||||
while (!RUSB2->SYSCFG_b.SCKE) ;
|
||||
RUSB2->SYSCFG_b.DRPD = 0;
|
||||
RUSB2->SYSCFG_b.DCFM = 0;
|
||||
RUSB2->SYSCFG_b.USBE = 1;
|
||||
|
||||
if (USB0.INTSTS0.BIT.VBSTS) {
|
||||
// MCU specific PHY init
|
||||
rusb2_phy_init();
|
||||
|
||||
RUSB2->PHYSLEW = 0x5;
|
||||
RUSB2->DPUSR0R_FS_b.FIXPHY0 = 0u; /* USB_BASE Transceiver Output fixed */
|
||||
|
||||
/* Setup default control pipe */
|
||||
RUSB2->DCPMAXP_b.MXPS = 64;
|
||||
RUSB2->INTENB0 = RUSB2_INTSTS0_VBINT_Msk | RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_BEMP_Msk |
|
||||
RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (USE_SOF ? RUSB2_INTSTS0_SOFR_Msk : 0) |
|
||||
RUSB2_INTSTS0_RESM_Msk;
|
||||
RUSB2->BEMPENB = 1;
|
||||
RUSB2->BRDYENB = 1;
|
||||
|
||||
if (RUSB2->INTSTS0_b.VBSTS) {
|
||||
dcd_connect(rhport);
|
||||
}
|
||||
}
|
||||
|
||||
void dcd_int_enable(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
|
||||
IEN(PERIB, INTB185) = 1;
|
||||
#else
|
||||
IEN(USB0, USBI0) = 1;
|
||||
#endif
|
||||
rusb2_int_enable(rhport);
|
||||
}
|
||||
|
||||
void dcd_int_disable(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
|
||||
IEN(PERIB, INTB185) = 0;
|
||||
#else
|
||||
IEN(USB0, USBI0) = 0;
|
||||
#endif
|
||||
rusb2_int_disable(rhport);
|
||||
}
|
||||
|
||||
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
|
||||
@@ -672,19 +624,19 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
|
||||
void dcd_remote_wakeup(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
USB0.DVSTCTR0.BIT.WKUP = 1;
|
||||
RUSB2->DVSTCTR0_b.WKUP = 1;
|
||||
}
|
||||
|
||||
void dcd_connect(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
USB0.SYSCFG.BIT.DPRPU = 1;
|
||||
RUSB2->SYSCFG_b.DPRPU = 1;
|
||||
}
|
||||
|
||||
void dcd_disconnect(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
USB0.SYSCFG.BIT.DPRPU = 0;
|
||||
RUSB2->SYSCFG_b.DPRPU = 0;
|
||||
}
|
||||
|
||||
void dcd_sof_enable(uint8_t rhport, bool en)
|
||||
@@ -720,26 +672,26 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||
|
||||
/* setup pipe */
|
||||
dcd_int_disable(rhport);
|
||||
USB0.PIPESEL.WORD = num;
|
||||
USB0.PIPEMAXP.WORD = mps;
|
||||
RUSB2->PIPESEL = num;
|
||||
RUSB2->PIPEMAXP = mps;
|
||||
volatile uint16_t *ctr = get_pipectr(num);
|
||||
*ctr = USB_PIPECTR_ACLRM | USB_PIPECTR_SQCLR;
|
||||
*ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk;
|
||||
*ctr = 0;
|
||||
unsigned cfg = (dir << 4) | epn;
|
||||
if (xfer == TUSB_XFER_BULK) {
|
||||
cfg |= (USB_PIPECFG_BULK | USB_PIPECFG_SHTNAK | USB_PIPECFG_DBLB);
|
||||
cfg |= (RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk);
|
||||
} else if (xfer == TUSB_XFER_INTERRUPT) {
|
||||
cfg |= USB_PIPECFG_INT;
|
||||
cfg |= RUSB2_PIPECFG_TYPE_INT;
|
||||
} else {
|
||||
cfg |= (USB_PIPECFG_ISO | USB_PIPECFG_DBLB);
|
||||
cfg |= (RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk);
|
||||
}
|
||||
USB0.PIPECFG.WORD = cfg;
|
||||
USB0.BRDYSTS.WORD = 0x1FFu ^ TU_BIT(num);
|
||||
USB0.BRDYENB.WORD |= TU_BIT(num);
|
||||
RUSB2->PIPECFG = cfg;
|
||||
RUSB2->BRDYSTS = 0x1FFu ^ TU_BIT(num);
|
||||
RUSB2->BRDYENB |= TU_BIT(num);
|
||||
if (dir || (xfer != TUSB_XFER_BULK)) {
|
||||
*ctr = USB_PIPECTR_PID_BUF;
|
||||
*ctr = RUSB2_PIPE_CTR_PID_BUF;
|
||||
}
|
||||
// TU_LOG1("O %d %x %x\r\n", USB0.PIPESEL.WORD, USB0.PIPECFG.WORD, USB0.PIPEMAXP.WORD);
|
||||
// TU_LOG1("O %d %x %x\r\n", RUSB2->PIPESEL, RUSB2->PIPECFG, RUSB2->PIPEMAXP);
|
||||
dcd_int_enable(rhport);
|
||||
|
||||
return true;
|
||||
@@ -764,11 +716,11 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
||||
const unsigned dir = tu_edpt_dir(ep_addr);
|
||||
const unsigned num = _dcd.ep[dir][epn];
|
||||
|
||||
USB0.BRDYENB.WORD &= ~TU_BIT(num);
|
||||
RUSB2->BRDYENB &= ~TU_BIT(num);
|
||||
volatile uint16_t *ctr = get_pipectr(num);
|
||||
*ctr = 0;
|
||||
USB0.PIPESEL.WORD = num;
|
||||
USB0.PIPECFG.WORD = 0;
|
||||
RUSB2->PIPESEL = num;
|
||||
RUSB2->PIPECFG = 0;
|
||||
_dcd.pipe[num].ep = 0;
|
||||
_dcd.ep[dir][epn] = 0;
|
||||
}
|
||||
@@ -799,8 +751,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
if (!ctr) return;
|
||||
dcd_int_disable(rhport);
|
||||
const uint32_t pid = *ctr & 0x3;
|
||||
*ctr = pid | USB_PIPECTR_PID_STALL;
|
||||
*ctr = USB_PIPECTR_PID_STALL;
|
||||
*ctr = pid | RUSB2_PIPE_CTR_PID_STALL;
|
||||
*ctr = RUSB2_PIPE_CTR_PID_STALL;
|
||||
dcd_int_enable(rhport);
|
||||
}
|
||||
|
||||
@@ -809,15 +761,15 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr);
|
||||
if (!ctr) return;
|
||||
dcd_int_disable(rhport);
|
||||
*ctr = USB_PIPECTR_SQCLR;
|
||||
*ctr = RUSB2_PIPE_CTR_SQCLR_Msk;
|
||||
|
||||
if (tu_edpt_dir(ep_addr)) { /* IN */
|
||||
*ctr = USB_PIPECTR_PID_BUF;
|
||||
*ctr = RUSB2_PIPE_CTR_PID_BUF;
|
||||
} else {
|
||||
const unsigned num = _dcd.ep[0][tu_edpt_number(ep_addr)];
|
||||
USB0.PIPESEL.WORD = num;
|
||||
if (USB0.PIPECFG.BIT.TYPE != 1) {
|
||||
*ctr = USB_PIPECTR_PID_BUF;
|
||||
RUSB2->PIPESEL = num;
|
||||
if (RUSB2->PIPECFG_b.TYPE != 1) {
|
||||
*ctr = RUSB2_PIPE_CTR_PID_BUF;
|
||||
}
|
||||
}
|
||||
dcd_int_enable(rhport);
|
||||
@@ -830,70 +782,71 @@ void dcd_int_handler(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
|
||||
unsigned is0 = USB0.INTSTS0.WORD;
|
||||
unsigned is0 = RUSB2->INTSTS0;
|
||||
/* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */
|
||||
USB0.INTSTS0.WORD = ~((USB_IS0_CTRT | USB_IS0_DVST | USB_IS0_SOFR | USB_IS0_RESM | USB_IS0_VBINT) & is0) | USB_IS0_VALID;
|
||||
if (is0 & USB_IS0_VBINT) {
|
||||
if (USB0.INTSTS0.BIT.VBSTS) {
|
||||
RUSB2->INTSTS0 = ~((RUSB2_INTSTS0_CTRT_Msk | RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_SOFR_Msk |
|
||||
RUSB2_INTSTS0_RESM_Msk | RUSB2_INTSTS0_VBINT_Msk) & is0) | RUSB2_INTSTS0_VALID_Msk;
|
||||
if (is0 & RUSB2_INTSTS0_VBINT_Msk) {
|
||||
if (RUSB2->INTSTS0_b.VBSTS) {
|
||||
dcd_connect(rhport);
|
||||
} else {
|
||||
dcd_disconnect(rhport);
|
||||
}
|
||||
}
|
||||
if (is0 & USB_IS0_RESM) {
|
||||
if (is0 & RUSB2_INTSTS0_RESM_Msk) {
|
||||
dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
|
||||
#if (0==USE_SOF)
|
||||
USB0.INTENB0.BIT.SOFE = 0;
|
||||
RUSB2->INTENB0_b.SOFE = 0;
|
||||
#endif
|
||||
}
|
||||
if ((is0 & USB_IS0_SOFR) && USB0.INTENB0.BIT.SOFE) {
|
||||
if ((is0 & RUSB2_INTSTS0_SOFR_Msk) && RUSB2->INTENB0_b.SOFE) {
|
||||
// USBD will exit suspended mode when SOF event is received
|
||||
dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
|
||||
#if (0==USE_SOF)
|
||||
USB0.INTENB0.BIT.SOFE = 0;
|
||||
#if (0 == USE_SOF)
|
||||
RUSB2->INTENB0_b.SOFE = 0;
|
||||
#endif
|
||||
}
|
||||
if (is0 & USB_IS0_DVST) {
|
||||
switch (is0 & USB_IS0_DVSQ) {
|
||||
case USB_IS0_DVSQ_DEF:
|
||||
if (is0 & RUSB2_INTSTS0_DVST_Msk) {
|
||||
switch (is0 & RUSB2_INTSTS0_DVSQ_Msk) {
|
||||
case RUSB2_INTSTS0_DVSQ_STATE_DEF:
|
||||
process_bus_reset(rhport);
|
||||
break;
|
||||
case USB_IS0_DVSQ_ADDR:
|
||||
case RUSB2_INTSTS0_DVSQ_STATE_ADDR:
|
||||
process_set_address(rhport);
|
||||
break;
|
||||
case USB_IS0_DVSQ_SUSP0:
|
||||
case USB_IS0_DVSQ_SUSP1:
|
||||
case USB_IS0_DVSQ_SUSP2:
|
||||
case USB_IS0_DVSQ_SUSP3:
|
||||
case RUSB2_INTSTS0_DVSQ_STATE_SUSP0:
|
||||
case RUSB2_INTSTS0_DVSQ_STATE_SUSP1:
|
||||
case RUSB2_INTSTS0_DVSQ_STATE_SUSP2:
|
||||
case RUSB2_INTSTS0_DVSQ_STATE_SUSP3:
|
||||
dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
|
||||
#if (0==USE_SOF)
|
||||
USB0.INTENB0.BIT.SOFE = 1;
|
||||
RUSB2->INTENB0_b.SOFE = 1;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is0 & USB_IS0_CTRT) {
|
||||
if (is0 & USB_IS0_CTSQ_SETUP) {
|
||||
if (is0 & RUSB2_INTSTS0_CTRT_Msk) {
|
||||
if (is0 & RUSB2_INTSTS0_CTSQ_CTRL_RDATA) {
|
||||
/* A setup packet has been received. */
|
||||
process_setup_packet(rhport);
|
||||
} else if (0 == (is0 & USB_IS0_CTSQ_MSK)) {
|
||||
} else if (0 == (is0 & RUSB2_INTSTS0_CTSQ_Msk)) {
|
||||
/* A ZLP has been sent/received. */
|
||||
process_status_completion(rhport);
|
||||
}
|
||||
}
|
||||
if (is0 & USB_IS0_BEMP) {
|
||||
const unsigned s = USB0.BEMPSTS.WORD;
|
||||
USB0.BEMPSTS.WORD = 0;
|
||||
if (is0 & RUSB2_INTSTS0_BEMP_Msk) {
|
||||
const unsigned s = RUSB2->BEMPSTS;
|
||||
RUSB2->BEMPSTS = 0;
|
||||
if (s & 1) {
|
||||
process_pipe0_bemp(rhport);
|
||||
}
|
||||
}
|
||||
if (is0 & USB_IS0_BRDY) {
|
||||
const unsigned m = USB0.BRDYENB.WORD;
|
||||
unsigned s = USB0.BRDYSTS.WORD & m;
|
||||
if (is0 & RUSB2_INTSTS0_BRDY_Msk) {
|
||||
const unsigned m = RUSB2->BRDYENB;
|
||||
unsigned s = RUSB2->BRDYSTS & m;
|
||||
/* clear active bits (don't write 0 to already cleared bits according to the HW manual) */
|
||||
USB0.BRDYSTS.WORD = ~s;
|
||||
RUSB2->BRDYSTS = ~s;
|
||||
while (s) {
|
||||
#if defined(__CCRX__)
|
||||
static const int Mod37BitPosition[] = {
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2021 Koji Kitayama
|
||||
@@ -27,86 +27,35 @@
|
||||
|
||||
#include "tusb_option.h"
|
||||
|
||||
#if CFG_TUH_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_RX63X || \
|
||||
CFG_TUSB_MCU == OPT_MCU_RX65X || \
|
||||
CFG_TUSB_MCU == OPT_MCU_RX72N )
|
||||
#if CFG_TUH_ENABLED && (TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) || \
|
||||
TU_CHECK_MCU(OPT_MCU_RAXXX))
|
||||
|
||||
#include "host/hcd.h"
|
||||
#include "iodefine.h"
|
||||
#include "rusb2_type.h"
|
||||
|
||||
#if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)
|
||||
#include "rusb2_rx.h"
|
||||
#elif TU_CHECK_MCU(OPT_MCU_RAXXX)
|
||||
#include "rusb2_ra.h"
|
||||
#else
|
||||
#error "Unsupported MCU"
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
#define SYSTEM_PRCR_PRC1 (1<<1)
|
||||
#define SYSTEM_PRCR_PRKEY (0xA5u<<8)
|
||||
|
||||
#define USB_DVSTCTR0_LOW (1u)
|
||||
#define USB_DVSTCTR0_FULL (2u)
|
||||
/* LINK core registers */
|
||||
#if defined(__CCRX__)
|
||||
#define RUSB2 ((RUSB2_REG_t __evenaccess*) RUSB2_REG_BASE)
|
||||
#else
|
||||
#define RUSB2 ((RUSB2_REG_t*) RUSB2_REG_BASE)
|
||||
#endif
|
||||
|
||||
#define USB_FIFOSEL_TX ((uint16_t)(1u<<5))
|
||||
#define USB_FIFOSEL_BIGEND ((uint16_t)(1u<<8))
|
||||
#define USB_FIFOSEL_MBW_8 ((uint16_t)(0u<<10))
|
||||
#define USB_FIFOSEL_MBW_16 ((uint16_t)(1u<<10))
|
||||
#define USB_IS0_CTSQ ((uint16_t)(7u))
|
||||
#define USB_IS0_DVSQ ((uint16_t)(7u<<4))
|
||||
#define USB_IS0_VALID ((uint16_t)(1u<<3))
|
||||
#define USB_IS0_BRDY ((uint16_t)(1u<<8))
|
||||
#define USB_IS0_NRDY ((uint16_t)(1u<<9))
|
||||
#define USB_IS0_BEMP ((uint16_t)(1u<<10))
|
||||
#define USB_IS0_CTRT ((uint16_t)(1u<<11))
|
||||
#define USB_IS0_DVST ((uint16_t)(1u<<12))
|
||||
#define USB_IS0_SOFR ((uint16_t)(1u<<13))
|
||||
#define USB_IS0_RESM ((uint16_t)(1u<<14))
|
||||
#define USB_IS0_VBINT ((uint16_t)(1u<<15))
|
||||
#define USB_IS1_SACK ((uint16_t)(1u<<4))
|
||||
#define USB_IS1_SIGN ((uint16_t)(1u<<5))
|
||||
#define USB_IS1_EOFERR ((uint16_t)(1u<<6))
|
||||
#define USB_IS1_ATTCH ((uint16_t)(1u<<11))
|
||||
#define USB_IS1_DTCH ((uint16_t)(1u<<12))
|
||||
#define USB_IS1_BCHG ((uint16_t)(1u<<14))
|
||||
#define USB_IS1_OVRCR ((uint16_t)(1u<<15))
|
||||
|
||||
#define USB_IS0_CTSQ_MSK (7u)
|
||||
#define USB_IS0_CTSQ_SETUP (1u)
|
||||
#define USB_IS0_DVSQ_DEF (1u<<4)
|
||||
#define USB_IS0_DVSQ_ADDR (2u<<4)
|
||||
#define USB_IS0_DVSQ_SUSP0 (4u<<4)
|
||||
#define USB_IS0_DVSQ_SUSP1 (5u<<4)
|
||||
#define USB_IS0_DVSQ_SUSP2 (6u<<4)
|
||||
#define USB_IS0_DVSQ_SUSP3 (7u<<4)
|
||||
|
||||
#define USB_PIPECTR_PID_MSK (3u)
|
||||
#define USB_PIPECTR_PID_NAK (0u)
|
||||
#define USB_PIPECTR_PID_BUF (1u)
|
||||
#define USB_PIPECTR_PID_STALL (2u)
|
||||
#define USB_PIPECTR_CCPL (1u<<2)
|
||||
#define USB_PIPECTR_SQMON (1u<<6)
|
||||
#define USB_PIPECTR_SQCLR (1u<<8)
|
||||
#define USB_PIPECTR_ACLRM (1u<<9)
|
||||
#define USB_PIPECTR_INBUFM (1u<<14)
|
||||
#define USB_PIPECTR_BSTS (1u<<15)
|
||||
|
||||
#define USB_FIFOCTR_DTLN (0x1FF)
|
||||
#define USB_FIFOCTR_FRDY (1u<<13)
|
||||
#define USB_FIFOCTR_BCLR (1u<<14)
|
||||
#define USB_FIFOCTR_BVAL (1u<<15)
|
||||
|
||||
#define USB_PIPECFG_SHTNAK (1u<<7)
|
||||
#define USB_PIPECFG_DBLB (1u<<9)
|
||||
#define USB_PIPECFG_BULK (1u<<14)
|
||||
#define USB_PIPECFG_ISO (3u<<14)
|
||||
#define USB_PIPECFG_INT (2u<<14)
|
||||
|
||||
#define USB_DEVADD_LOW (1u<<6)
|
||||
#define USB_DEVADD_FULL (2u<<6)
|
||||
|
||||
#define FIFO_REQ_CLR (1u)
|
||||
#define FIFO_COMPLETE (1u<<1)
|
||||
|
||||
// Start of definition of packed structs (used by the CCRX toolchain)
|
||||
TU_ATTR_PACKED_BEGIN
|
||||
TU_ATTR_BIT_FIELD_ORDER_BEGIN
|
||||
|
||||
typedef struct {
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
union {
|
||||
struct {
|
||||
uint16_t : 8;
|
||||
@@ -119,7 +68,7 @@ typedef struct {
|
||||
uint16_t TRN;
|
||||
} reg_pipetre_t;
|
||||
|
||||
typedef union {
|
||||
typedef union TU_ATTR_PACKED {
|
||||
struct {
|
||||
volatile uint16_t u8: 8;
|
||||
volatile uint16_t : 0;
|
||||
@@ -127,8 +76,7 @@ typedef union {
|
||||
volatile uint16_t u16;
|
||||
} hw_fifo_t;
|
||||
|
||||
typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
typedef struct TU_ATTR_PACKED {
|
||||
void *buf; /* the start address of a transfer data buffer */
|
||||
uint16_t length; /* the number of bytes in the buffer */
|
||||
uint16_t remaining; /* the number of bytes remaining in the buffer */
|
||||
@@ -156,28 +104,6 @@ typedef struct
|
||||
//--------------------------------------------------------------------+
|
||||
static hcd_data_t _hcd;
|
||||
|
||||
static uint32_t disable_interrupt(void)
|
||||
{
|
||||
uint32_t pswi;
|
||||
#if defined(__CCRX__)
|
||||
pswi = get_psw() & 0x010000;
|
||||
clrpsw_i();
|
||||
#else
|
||||
pswi = __builtin_rx_mvfc(0) & 0x010000;
|
||||
__builtin_rx_clrpsw('I');
|
||||
#endif
|
||||
return pswi;
|
||||
}
|
||||
|
||||
static void enable_interrupt(uint32_t pswi)
|
||||
{
|
||||
#if defined(__CCRX__)
|
||||
set_psw(get_psw() | pswi);
|
||||
#else
|
||||
__builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned find_pipe(unsigned xfer)
|
||||
{
|
||||
switch (xfer) {
|
||||
@@ -208,58 +134,49 @@ static unsigned find_pipe(unsigned xfer)
|
||||
|
||||
static volatile uint16_t* get_pipectr(unsigned num)
|
||||
{
|
||||
volatile uint16_t *ctr = NULL;
|
||||
if (num) {
|
||||
ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD;
|
||||
ctr += num - 1;
|
||||
return (volatile uint16_t*)&(RUSB2->PIPE_CTR[num - 1]);
|
||||
} else {
|
||||
ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD;
|
||||
return (volatile uint16_t*)&(RUSB2->DCPCTR);
|
||||
}
|
||||
return ctr;
|
||||
}
|
||||
|
||||
static volatile reg_pipetre_t* get_pipetre(unsigned num)
|
||||
{
|
||||
volatile reg_pipetre_t* tre = NULL;
|
||||
if ((1 <= num) && (num <= 5)) {
|
||||
tre = (volatile reg_pipetre_t*)&USB0.PIPE1TRE.WORD;
|
||||
tre += num - 1;
|
||||
tre = (volatile reg_pipetre_t*)&(RUSB2->PIPE_TR[num - 1].E);
|
||||
}
|
||||
return tre;
|
||||
}
|
||||
|
||||
static volatile uint16_t* addr_to_pipectr(uint8_t dev_addr, unsigned ep_addr)
|
||||
{
|
||||
volatile uint16_t *ctr = NULL;
|
||||
const unsigned epn = tu_edpt_number(ep_addr);
|
||||
const unsigned epn = tu_edpt_number(ep_addr);
|
||||
if (epn) {
|
||||
const unsigned dir_in = tu_edpt_dir(ep_addr);
|
||||
const unsigned num = _hcd.ep[dev_addr][dir_in][epn - 1];
|
||||
if (num) {
|
||||
ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD;
|
||||
ctr += num - 1;
|
||||
}
|
||||
const unsigned num = _hcd.ep[dev_addr][dir_in][epn - 1];
|
||||
return get_pipectr(num);
|
||||
} else {
|
||||
ctr = (volatile uint16_t*)&USB0.DCPCTR.WORD;
|
||||
return get_pipectr(0);
|
||||
}
|
||||
return ctr;
|
||||
}
|
||||
|
||||
static unsigned edpt0_max_packet_size(void)
|
||||
{
|
||||
return USB0.DCPMAXP.BIT.MXPS;
|
||||
return RUSB2->DCPMAXP_b.MXPS;
|
||||
}
|
||||
|
||||
static unsigned edpt_max_packet_size(unsigned num)
|
||||
{
|
||||
USB0.PIPESEL.WORD = num;
|
||||
return USB0.PIPEMAXP.BIT.MXPS;
|
||||
RUSB2->PIPESEL = num;
|
||||
return RUSB2->PIPEMAXP_b.MXPS;
|
||||
}
|
||||
|
||||
static inline void pipe_wait_for_ready(unsigned num)
|
||||
{
|
||||
while (USB0.D0FIFOSEL.BIT.CURPIPE != num) ;
|
||||
while (!USB0.D0FIFOCTR.BIT.FRDY) ;
|
||||
while (RUSB2->D0FIFOSEL_b.CURPIPE != num) ;
|
||||
while (!RUSB2->D0FIFOCTR_b.FRDY) ;
|
||||
}
|
||||
|
||||
static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
|
||||
@@ -290,21 +207,23 @@ static bool pipe0_xfer_in(void)
|
||||
const unsigned rem = pipe->remaining;
|
||||
|
||||
const unsigned mps = edpt0_max_packet_size();
|
||||
const unsigned vld = USB0.CFIFOCTR.BIT.DTLN;
|
||||
const unsigned vld = RUSB2->CFIFOCTR_b.DTLN;
|
||||
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
|
||||
void *buf = pipe->buf;
|
||||
if (len) {
|
||||
USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK;
|
||||
pipe_read_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len);
|
||||
RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
|
||||
pipe_read_packet(buf, (volatile void*)&RUSB2->CFIFO, len);
|
||||
pipe->buf = (uint8_t*)buf + len;
|
||||
}
|
||||
if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BCLR;
|
||||
if (len < mps) {
|
||||
RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
|
||||
}
|
||||
pipe->remaining = rem - len;
|
||||
if ((len < mps) || (rem == len)) {
|
||||
pipe->buf = NULL;
|
||||
return true;
|
||||
}
|
||||
USB0.DCPCTR.WORD = USB_PIPECTR_PID_BUF;
|
||||
RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -320,10 +239,12 @@ static bool pipe0_xfer_out(void)
|
||||
const unsigned len = TU_MIN(mps, rem);
|
||||
void *buf = pipe->buf;
|
||||
if (len) {
|
||||
pipe_write_packet(buf, (volatile void*)&USB0.CFIFO.WORD, len);
|
||||
pipe_write_packet(buf, (volatile void*)&RUSB2->CFIFO, len);
|
||||
pipe->buf = (uint8_t*)buf + len;
|
||||
}
|
||||
if (len < mps) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||
if (len < mps) {
|
||||
RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
|
||||
}
|
||||
pipe->remaining = rem - len;
|
||||
return false;
|
||||
}
|
||||
@@ -333,20 +254,22 @@ static bool pipe_xfer_in(unsigned num)
|
||||
pipe_state_t *pipe = &_hcd.pipe[num];
|
||||
const unsigned rem = pipe->remaining;
|
||||
|
||||
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_8;
|
||||
RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT;
|
||||
const unsigned mps = edpt_max_packet_size(num);
|
||||
pipe_wait_for_ready(num);
|
||||
const unsigned vld = USB0.D0FIFOCTR.BIT.DTLN;
|
||||
const unsigned vld = RUSB2->D0FIFOCTR_b.DTLN;
|
||||
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
|
||||
void *buf = pipe->buf;
|
||||
if (len) {
|
||||
pipe_read_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len);
|
||||
pipe_read_packet(buf, (volatile void*)&RUSB2->D0FIFO, len);
|
||||
pipe->buf = (uint8_t*)buf + len;
|
||||
}
|
||||
if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BCLR;
|
||||
USB0.D0FIFOSEL.WORD = 0;
|
||||
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
pipe->remaining = rem - len;
|
||||
if (len < mps) {
|
||||
RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
|
||||
}
|
||||
RUSB2->D0FIFOSEL = 0;
|
||||
while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
pipe->remaining = rem - len;
|
||||
if ((len < mps) || (rem == len)) {
|
||||
pipe->buf = NULL;
|
||||
return NULL != buf;
|
||||
@@ -364,18 +287,19 @@ static bool pipe_xfer_out(unsigned num)
|
||||
return true;
|
||||
}
|
||||
|
||||
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0);
|
||||
RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
|
||||
const unsigned mps = edpt_max_packet_size(num);
|
||||
pipe_wait_for_ready(num);
|
||||
const unsigned len = TU_MIN(rem, mps);
|
||||
void *buf = pipe->buf;
|
||||
if (len) {
|
||||
pipe_write_packet(buf, (volatile void*)&USB0.D0FIFO.WORD, len);
|
||||
pipe_write_packet(buf, (volatile void*)&RUSB2->D0FIFO, len);
|
||||
pipe->buf = (uint8_t*)buf + len;
|
||||
}
|
||||
if (len < mps) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||
USB0.D0FIFOSEL.WORD = 0;
|
||||
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
if (len < mps)
|
||||
RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
|
||||
RUSB2->D0FIFOSEL = 0;
|
||||
while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
pipe->remaining = rem - len;
|
||||
return false;
|
||||
}
|
||||
@@ -387,11 +311,12 @@ static bool process_pipe0_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer,
|
||||
|
||||
/* configure fifo direction and access unit settings */
|
||||
if (dir_in) { /* IN, a byte */
|
||||
USB0.CFIFOSEL.WORD = USB_FIFOSEL_MBW_8;
|
||||
while (USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX) ;
|
||||
} else { /* OUT, 2 bytes */
|
||||
USB0.CFIFOSEL.WORD = USB_FIFOSEL_TX | USB_FIFOSEL_MBW_16 | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? USB_FIFOSEL_BIGEND : 0);
|
||||
while (!(USB0.CFIFOSEL.WORD & USB_FIFOSEL_TX)) ;
|
||||
RUSB2->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT;
|
||||
while (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ;
|
||||
} else { /* OUT, 2 bytes */
|
||||
RUSB2->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT |
|
||||
(TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
|
||||
while (!(RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ;
|
||||
}
|
||||
|
||||
pipe_state_t *pipe = &_hcd.pipe[0];
|
||||
@@ -401,25 +326,25 @@ static bool process_pipe0_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer,
|
||||
if (buflen) {
|
||||
pipe->buf = buffer;
|
||||
if (!dir_in) { /* OUT */
|
||||
TU_ASSERT(USB0.DCPCTR.BIT.BSTS && (USB0.USBREQ.WORD & 0x80));
|
||||
TU_ASSERT(RUSB2->DCPCTR_b.BSTS && (RUSB2->USBREQ & 0x80));
|
||||
pipe0_xfer_out();
|
||||
}
|
||||
} else { /* ZLP */
|
||||
pipe->buf = NULL;
|
||||
if (!dir_in) { /* OUT */
|
||||
USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||
RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
|
||||
}
|
||||
if (dir_in == USB0.DCPCFG.BIT.DIR) {
|
||||
TU_ASSERT(USB_PIPECTR_PID_NAK == USB0.DCPCTR.BIT.PID);
|
||||
USB0.DCPCTR.BIT.SQSET = 1;
|
||||
USB0.DCPCFG.BIT.DIR = dir_in ^ 1;
|
||||
if (dir_in == RUSB2->DCPCFG_b.DIR) {
|
||||
TU_ASSERT(RUSB2_PIPE_CTR_PID_NAK == RUSB2->DCPCTR_b.PID);
|
||||
RUSB2->DCPCTR_b.SQSET = 1;
|
||||
RUSB2->DCPCFG_b.DIR = dir_in ^ 1;
|
||||
}
|
||||
}
|
||||
USB0.DCPCTR.WORD = USB_PIPECTR_PID_BUF;
|
||||
RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen)
|
||||
static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void *buffer, uint16_t buflen)
|
||||
{
|
||||
const unsigned epn = tu_edpt_number(ep_addr);
|
||||
const unsigned dir_in = tu_edpt_dir(ep_addr);
|
||||
@@ -435,23 +360,23 @@ static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, u
|
||||
if (buflen) {
|
||||
pipe_xfer_out(num);
|
||||
} else { /* ZLP */
|
||||
USB0.D0FIFOSEL.WORD = num;
|
||||
RUSB2->D0FIFOSEL = num;
|
||||
pipe_wait_for_ready(num);
|
||||
USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||
USB0.D0FIFOSEL.WORD = 0;
|
||||
while (USB0.D0FIFOSEL.BIT.CURPIPE) ; /* if CURPIPE bits changes, check written value */
|
||||
RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
|
||||
RUSB2->D0FIFOSEL = 0;
|
||||
while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */
|
||||
}
|
||||
} else {
|
||||
volatile uint16_t *ctr = get_pipectr(num);
|
||||
volatile reg_pipetre_t *pt = get_pipetre(num);
|
||||
if (pt) {
|
||||
const unsigned mps = edpt_max_packet_size(num);
|
||||
if (*ctr & 0x3) *ctr = USB_PIPECTR_PID_NAK;
|
||||
if (*ctr & 0x3) *ctr = RUSB2_PIPE_CTR_PID_NAK;
|
||||
pt->TRE = TU_BIT(8);
|
||||
pt->TRN = (buflen + mps - 1) / mps;
|
||||
pt->TRENB = 1;
|
||||
}
|
||||
*ctr = USB_PIPECTR_PID_BUF;
|
||||
*ctr = RUSB2_PIPE_CTR_PID_BUF;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -485,10 +410,10 @@ static void process_pipe_nrdy(uint8_t rhport, unsigned num)
|
||||
unsigned result;
|
||||
uint16_t volatile *ctr = get_pipectr(num);
|
||||
// TU_LOG1("NRDY %d %x\n", num, *ctr);
|
||||
switch (*ctr & USB_PIPECTR_PID_MSK) {
|
||||
switch (*ctr & RUSB2_PIPE_CTR_PID_Msk) {
|
||||
default: return;
|
||||
case USB_PIPECTR_PID_STALL: result = XFER_RESULT_STALLED; break;
|
||||
case USB_PIPECTR_PID_NAK: result = XFER_RESULT_FAILED; break;
|
||||
case RUSB2_PIPE_CTR_PID_STALL: result = XFER_RESULT_STALLED; break;
|
||||
case RUSB2_PIPE_CTR_PID_NAK: result = XFER_RESULT_FAILED; break;
|
||||
}
|
||||
pipe_state_t *pipe = &_hcd.pipe[num];
|
||||
hcd_event_xfer_complete(pipe->dev, pipe->ep,
|
||||
@@ -520,78 +445,93 @@ static void process_pipe_brdy(uint8_t rhport, unsigned num)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Host API
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
#if 0 // previously present in the rx driver before generalization
|
||||
static uint32_t disable_interrupt(void)
|
||||
{
|
||||
uint32_t pswi;
|
||||
#if defined(__CCRX__)
|
||||
pswi = get_psw() & 0x010000;
|
||||
clrpsw_i();
|
||||
#else
|
||||
pswi = __builtin_rx_mvfc(0) & 0x010000;
|
||||
__builtin_rx_clrpsw('I');
|
||||
#endif
|
||||
return pswi;
|
||||
}
|
||||
|
||||
static void enable_interrupt(uint32_t pswi)
|
||||
{
|
||||
#if defined(__CCRX__)
|
||||
set_psw(get_psw() | pswi);
|
||||
#else
|
||||
__builtin_rx_mvtc(0, __builtin_rx_mvfc(0) | pswi);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hcd_init(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
/* Enable USB0 */
|
||||
|
||||
#if 0 // previously present in the rx driver before generalization
|
||||
uint32_t pswi = disable_interrupt();
|
||||
SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1;
|
||||
MSTP(USB0) = 0;
|
||||
SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY;
|
||||
enable_interrupt(pswi);
|
||||
USB0.SYSCFG.BIT.SCKE = 1;
|
||||
while (!USB0.SYSCFG.BIT.SCKE) ;
|
||||
USB0.SYSCFG.BIT.DPRPU = 0;
|
||||
USB0.SYSCFG.BIT.DRPD = 0;
|
||||
USB0.SYSCFG.BIT.DCFM = 1;
|
||||
|
||||
USB0.DVSTCTR0.BIT.VBUSEN = 1;
|
||||
|
||||
USB0.SYSCFG.BIT.DRPD = 1;
|
||||
for (volatile int i = 0; i < 30000; ++i) ;
|
||||
USB0.SYSCFG.BIT.USBE = 1;
|
||||
|
||||
USB.DPUSR0R.BIT.FIXPHY0 = 0u; /* USB0 Transceiver Output fixed */
|
||||
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
|
||||
USB0.PHYSLEW.LONG = 0x5;
|
||||
IR(PERIB, INTB185) = 0;
|
||||
#else
|
||||
IR(USB0, USBI0) = 0;
|
||||
#endif
|
||||
|
||||
RUSB2->SYSCFG_b.SCKE = 1;
|
||||
while (!RUSB2->SYSCFG_b.SCKE) ;
|
||||
RUSB2->SYSCFG_b.DPRPU = 0;
|
||||
RUSB2->SYSCFG_b.DRPD = 0;
|
||||
RUSB2->SYSCFG_b.DCFM = 1;
|
||||
|
||||
RUSB2->DVSTCTR0_b.VBUSEN = 1;
|
||||
|
||||
RUSB2->SYSCFG_b.DRPD = 1;
|
||||
for (volatile int i = 0; i < 30000; ++i) ;
|
||||
RUSB2->SYSCFG_b.USBE = 1;
|
||||
|
||||
// MCU specific PHY init
|
||||
rusb2_phy_init();
|
||||
|
||||
RUSB2->PHYSLEW = 0x5;
|
||||
RUSB2->DPUSR0R_FS_b.FIXPHY0 = 0u; /* Transceiver Output fixed */
|
||||
|
||||
/* Setup default control pipe */
|
||||
USB0.DCPCFG.WORD = USB_PIPECFG_SHTNAK;
|
||||
USB0.DCPMAXP.WORD = 64;
|
||||
USB0.INTENB0.WORD = USB_IS0_BRDY | USB_IS0_NRDY | USB_IS0_BEMP;
|
||||
USB0.INTENB1.WORD = USB_IS1_SACK | USB_IS1_SIGN |
|
||||
USB_IS1_ATTCH | USB_IS1_DTCH;
|
||||
USB0.BEMPENB.WORD = 1;
|
||||
USB0.NRDYENB.WORD = 1;
|
||||
USB0.BRDYENB.WORD = 1;
|
||||
RUSB2->DCPCFG = RUSB2_PIPECFG_SHTNAK_Msk;
|
||||
RUSB2->DCPMAXP = 64;
|
||||
RUSB2->INTENB0 = RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk;
|
||||
RUSB2->INTENB1 = RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk;
|
||||
RUSB2->BEMPENB = 1;
|
||||
RUSB2->NRDYENB = 1;
|
||||
RUSB2->BRDYENB = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void hcd_int_enable(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
|
||||
IEN(PERIB, INTB185) = 1;
|
||||
#else
|
||||
IEN(USB0, USBI0) = 1;
|
||||
#endif
|
||||
rusb2_int_enable(rhport);
|
||||
}
|
||||
|
||||
void hcd_int_disable(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
#if ( CFG_TUSB_MCU == OPT_MCU_RX72N )
|
||||
IEN(PERIB, INTB185) = 0;
|
||||
#else
|
||||
IEN(USB0, USBI0) = 0;
|
||||
#endif
|
||||
rusb2_int_disable(rhport);
|
||||
}
|
||||
|
||||
uint32_t hcd_frame_number(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
/* The device must be reset at least once after connection
|
||||
/* The device must be reset at least once after connection
|
||||
* in order to start the frame counter. */
|
||||
if (_hcd.need_reset) hcd_port_reset(rhport);
|
||||
return USB0.FRMNUM.BIT.FRNM;
|
||||
return RUSB2->FRMNUM_b.FRNM;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------+
|
||||
@@ -600,23 +540,24 @@ uint32_t hcd_frame_number(uint8_t rhport)
|
||||
bool hcd_port_connect_status(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
return USB0.INTSTS1.BIT.ATTCH ? true : false;
|
||||
return RUSB2->INTSTS1_b.ATTCH ? true : false;
|
||||
}
|
||||
|
||||
void hcd_port_reset(uint8_t rhport)
|
||||
{
|
||||
USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK;
|
||||
while (USB0.DCPCTR.BIT.PBUSY) ;
|
||||
RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
|
||||
while (RUSB2->DCPCTR_b.PBUSY) ;
|
||||
hcd_int_disable(rhport);
|
||||
USB0.DVSTCTR0.BIT.UACT = 0;
|
||||
if (USB0.DCPCTR.BIT.SUREQ)
|
||||
USB0.DCPCTR.BIT.SUREQCLR = 1;
|
||||
RUSB2->DVSTCTR0_b.UACT = 0;
|
||||
if (RUSB2->DCPCTR_b.SUREQ) {
|
||||
RUSB2->DCPCTR_b.SUREQCLR = 1;
|
||||
}
|
||||
hcd_int_enable(rhport);
|
||||
/* Reset should be asserted 10-20ms. */
|
||||
USB0.DVSTCTR0.BIT.USBRST = 1;
|
||||
RUSB2->DVSTCTR0_b.USBRST = 1;
|
||||
for (volatile int i = 0; i < 2400000; ++i) ;
|
||||
USB0.DVSTCTR0.BIT.USBRST = 0;
|
||||
USB0.DVSTCTR0.BIT.UACT = 1;
|
||||
RUSB2->DVSTCTR0_b.USBRST = 0;
|
||||
RUSB2->DVSTCTR0_b.UACT = 1;
|
||||
_hcd.need_reset = false;
|
||||
}
|
||||
|
||||
@@ -628,10 +569,10 @@ void hcd_port_reset_end(uint8_t rhport)
|
||||
tusb_speed_t hcd_port_speed_get(uint8_t rhport)
|
||||
{
|
||||
(void)rhport;
|
||||
switch (USB0.DVSTCTR0.BIT.RHST) {
|
||||
switch (RUSB2->DVSTCTR0_b.RHST) {
|
||||
default: return TUSB_SPEED_INVALID;
|
||||
case USB_DVSTCTR0_FULL: return TUSB_SPEED_FULL;
|
||||
case USB_DVSTCTR0_LOW: return TUSB_SPEED_LOW;
|
||||
case RUSB2_DVSTCTR0_RHST_FS: return TUSB_SPEED_FULL;
|
||||
case RUSB2_DVSTCTR0_RHST_LS: return TUSB_SPEED_LOW;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,13 +588,13 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
|
||||
unsigned num = *ep;
|
||||
if (!num || dev_addr != _hcd.pipe[num].dev) continue;
|
||||
|
||||
ctr = (uint16_t volatile*)&USB0.PIPE1CTR.WORD + num - 1;
|
||||
ctr = (uint16_t volatile*)&RUSB2->PIPE_CTR[num - 1];
|
||||
*ctr = 0;
|
||||
USB0.NRDYENB.WORD &= ~TU_BIT(num);
|
||||
USB0.BRDYENB.WORD &= ~TU_BIT(num);
|
||||
USB0.PIPESEL.WORD = num;
|
||||
USB0.PIPECFG.WORD = 0;
|
||||
USB0.PIPEMAXP.WORD = 0;
|
||||
RUSB2->NRDYENB &= ~TU_BIT(num);
|
||||
RUSB2->BRDYENB &= ~TU_BIT(num);
|
||||
RUSB2->PIPESEL = num;
|
||||
RUSB2->PIPECFG = 0;
|
||||
RUSB2->PIPEMAXP = 0;
|
||||
|
||||
_hcd.pipe[num].ep = 0;
|
||||
_hcd.pipe[num].dev = 0;
|
||||
@@ -667,36 +608,36 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
|
||||
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
|
||||
{
|
||||
(void)rhport;
|
||||
// TU_LOG1("S %d %x\n", dev_addr, USB0.DCPCTR.WORD);
|
||||
// TU_LOG1("S %d %x\n", dev_addr, RUSB2->DCPCTR);
|
||||
|
||||
TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */
|
||||
TU_ASSERT(0 == USB0.DCPCTR.BIT.SUREQ);
|
||||
TU_ASSERT(0 == RUSB2->DCPCTR_b.SUREQ);
|
||||
|
||||
USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK;
|
||||
RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
|
||||
|
||||
_hcd.pipe[0].buf = NULL;
|
||||
_hcd.pipe[0].length = 8;
|
||||
_hcd.pipe[0].remaining = 0;
|
||||
_hcd.pipe[0].dev = dev_addr;
|
||||
|
||||
while (USB0.DCPCTR.BIT.PBUSY) ;
|
||||
USB0.DCPMAXP.WORD = (dev_addr << 12) | _hcd.ctl_mps[dev_addr];
|
||||
while (RUSB2->DCPCTR_b.PBUSY) ;
|
||||
RUSB2->DCPMAXP = (dev_addr << 12) | _hcd.ctl_mps[dev_addr];
|
||||
|
||||
/* Set direction in advance for DATA stage */
|
||||
uint8_t const bmRequesttype = setup_packet[0];
|
||||
USB0.DCPCFG.BIT.DIR = tu_edpt_dir(bmRequesttype) ? 0: 1;
|
||||
RUSB2->DCPCFG_b.DIR = tu_edpt_dir(bmRequesttype) ? 0: 1;
|
||||
|
||||
uint16_t const* p = (uint16_t const*)(uintptr_t)&setup_packet[0];
|
||||
USB0.USBREQ.WORD = tu_htole16(p[0]);
|
||||
USB0.USBVAL = p[1];
|
||||
USB0.USBINDX = p[2];
|
||||
USB0.USBLENG = p[3];
|
||||
RUSB2->USBREQ = tu_htole16(p[0]);
|
||||
RUSB2->USBVAL = p[1];
|
||||
RUSB2->USBINDX = p[2];
|
||||
RUSB2->USBLENG = p[3];
|
||||
|
||||
USB0.DCPCTR.BIT.SUREQ = 1;
|
||||
RUSB2->DCPCTR_b.SUREQ = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
|
||||
bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc)
|
||||
{
|
||||
(void)rhport;
|
||||
TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */
|
||||
@@ -705,14 +646,14 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
||||
const unsigned epn = tu_edpt_number(ep_addr);
|
||||
const unsigned mps = tu_edpt_packet_size(ep_desc);
|
||||
if (0 == epn) {
|
||||
USB0.DCPCTR.WORD = USB_PIPECTR_PID_NAK;
|
||||
RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
|
||||
hcd_devtree_info_t devtree;
|
||||
hcd_devtree_get_info(dev_addr, &devtree);
|
||||
uint16_t volatile *devadd = (uint16_t volatile *)(uintptr_t)&USB0.DEVADD0.WORD;
|
||||
uint16_t volatile *devadd = (uint16_t volatile *)(uintptr_t) &RUSB2->DEVADD[0];
|
||||
devadd += dev_addr;
|
||||
while (USB0.DCPCTR.BIT.PBUSY) ;
|
||||
USB0.DCPMAXP.WORD = (dev_addr << 12) | mps;
|
||||
*devadd = (TUSB_SPEED_FULL == devtree.speed) ? USB_DEVADD_FULL : USB_DEVADD_LOW;
|
||||
while (RUSB2->DCPCTR_b.PBUSY) ;
|
||||
RUSB2->DCPMAXP = (dev_addr << 12) | mps;
|
||||
*devadd = (TUSB_SPEED_FULL == devtree.speed) ? RUSB2_DEVADD_USBSPD_FS : RUSB2_DEVADD_USBSPD_LS;
|
||||
_hcd.ctl_mps[dev_addr] = mps;
|
||||
return true;
|
||||
}
|
||||
@@ -731,25 +672,25 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
||||
|
||||
/* setup pipe */
|
||||
hcd_int_disable(rhport);
|
||||
USB0.PIPESEL.WORD = num;
|
||||
USB0.PIPEMAXP.WORD = (dev_addr << 12) | mps;
|
||||
RUSB2->PIPESEL = num;
|
||||
RUSB2->PIPEMAXP = (dev_addr << 12) | mps;
|
||||
volatile uint16_t *ctr = get_pipectr(num);
|
||||
*ctr = USB_PIPECTR_ACLRM | USB_PIPECTR_SQCLR;
|
||||
*ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk;
|
||||
*ctr = 0;
|
||||
unsigned cfg = ((1 ^ dir_in) << 4) | epn;
|
||||
if (xfer == TUSB_XFER_BULK) {
|
||||
cfg |= USB_PIPECFG_BULK | USB_PIPECFG_SHTNAK | USB_PIPECFG_DBLB;
|
||||
cfg |= RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk;
|
||||
} else if (xfer == TUSB_XFER_INTERRUPT) {
|
||||
cfg |= USB_PIPECFG_INT;
|
||||
cfg |= RUSB2_PIPECFG_TYPE_INT;
|
||||
} else {
|
||||
cfg |= USB_PIPECFG_ISO | USB_PIPECFG_DBLB;
|
||||
cfg |= RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk;
|
||||
}
|
||||
USB0.PIPECFG.WORD = cfg;
|
||||
USB0.BRDYSTS.WORD = 0x1FFu ^ TU_BIT(num);
|
||||
USB0.NRDYENB.WORD |= TU_BIT(num);
|
||||
USB0.BRDYENB.WORD |= TU_BIT(num);
|
||||
RUSB2->PIPECFG = cfg;
|
||||
RUSB2->BRDYSTS = 0x1FFu ^ TU_BIT(num);
|
||||
RUSB2->NRDYENB |= TU_BIT(num);
|
||||
RUSB2->BRDYENB |= TU_BIT(num);
|
||||
if (!dir_in) {
|
||||
*ctr = USB_PIPECTR_PID_BUF;
|
||||
*ctr = RUSB2_PIPE_CTR_PID_BUF;
|
||||
}
|
||||
hcd_int_enable(rhport);
|
||||
|
||||
@@ -776,12 +717,12 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
|
||||
*ctr = pid & 2;
|
||||
*ctr = 0;
|
||||
}
|
||||
*ctr = USB_PIPECTR_SQCLR;
|
||||
*ctr = RUSB2_PIPE_CTR_SQCLR_Msk;
|
||||
unsigned const epn = tu_edpt_number(ep_addr);
|
||||
if (!epn) return true;
|
||||
|
||||
if (!tu_edpt_dir(ep_addr)) { /* OUT */
|
||||
*ctr = USB_PIPECTR_PID_BUF;
|
||||
*ctr = RUSB2_PIPE_CTR_PID_BUF;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -799,52 +740,49 @@ void hcd_int_handler(uint8_t rhport)
|
||||
20, 8, 19, 18};
|
||||
#endif
|
||||
|
||||
unsigned is1 = USB0.INTSTS1.WORD;
|
||||
unsigned is0 = USB0.INTSTS0.WORD;
|
||||
unsigned is1 = RUSB2->INTSTS1;
|
||||
unsigned is0 = RUSB2->INTSTS0;
|
||||
/* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */
|
||||
USB0.INTSTS1.WORD = ~((USB_IS1_SACK | USB_IS1_SIGN | USB_IS1_ATTCH | USB_IS1_DTCH) & is1);
|
||||
USB0.INTSTS0.WORD = ~((USB_IS0_BRDY | USB_IS0_NRDY | USB_IS0_BEMP) & is0);
|
||||
RUSB2->INTSTS1 = ~((RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk) & is1);
|
||||
RUSB2->INTSTS0 = ~((RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk) & is0);
|
||||
// TU_LOG1("IS %04x %04x\n", is0, is1);
|
||||
is1 &= USB0.INTENB1.WORD;
|
||||
is0 &= USB0.INTENB0.WORD;
|
||||
is1 &= RUSB2->INTENB1;
|
||||
is0 &= RUSB2->INTENB0;
|
||||
|
||||
if (is1 & USB_IS1_SACK) {
|
||||
if (is1 & RUSB2_INTSTS1_SACK_Msk) {
|
||||
/* Set DATA1 in advance for the next transfer. */
|
||||
USB0.DCPCTR.BIT.SQSET = 1;
|
||||
hcd_event_xfer_complete(USB0.DCPMAXP.BIT.DEVSEL,
|
||||
tu_edpt_addr(0, TUSB_DIR_OUT),
|
||||
8, XFER_RESULT_SUCCESS, true);
|
||||
RUSB2->DCPCTR_b.SQSET = 1;
|
||||
hcd_event_xfer_complete(RUSB2->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_SUCCESS, true);
|
||||
}
|
||||
if (is1 & USB_IS1_SIGN) {
|
||||
hcd_event_xfer_complete(USB0.DCPMAXP.BIT.DEVSEL,
|
||||
tu_edpt_addr(0, TUSB_DIR_OUT),
|
||||
8, XFER_RESULT_FAILED, true);
|
||||
if (is1 & RUSB2_INTSTS1_SIGN_Msk) {
|
||||
hcd_event_xfer_complete(RUSB2->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_FAILED, true);
|
||||
}
|
||||
if (is1 & USB_IS1_ATTCH) {
|
||||
USB0.DVSTCTR0.BIT.UACT = 1;
|
||||
if (is1 & RUSB2_INTSTS1_ATTCH_Msk) {
|
||||
RUSB2->DVSTCTR0_b.UACT = 1;
|
||||
_hcd.need_reset = true;
|
||||
USB0.INTENB1.WORD = (USB0.INTENB1.WORD & ~USB_IS1_ATTCH) | USB_IS1_DTCH;
|
||||
RUSB2->INTENB1 = (RUSB2->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk;
|
||||
hcd_event_device_attach(rhport, true);
|
||||
}
|
||||
if (is1 & USB_IS1_DTCH) {
|
||||
USB0.DVSTCTR0.BIT.UACT = 0;
|
||||
if (USB0.DCPCTR.BIT.SUREQ)
|
||||
USB0.DCPCTR.BIT.SUREQCLR = 1;
|
||||
USB0.INTENB1.WORD = (USB0.INTENB1.WORD & ~USB_IS1_DTCH) | USB_IS1_ATTCH;
|
||||
if (is1 & RUSB2_INTSTS1_DTCH_Msk) {
|
||||
RUSB2->DVSTCTR0_b.UACT = 0;
|
||||
if (RUSB2->DCPCTR_b.SUREQ) {
|
||||
RUSB2->DCPCTR_b.SUREQCLR = 1;
|
||||
}
|
||||
RUSB2->INTENB1 = (RUSB2->INTENB1 & ~RUSB2_INTSTS1_DTCH_Msk) | RUSB2_INTSTS1_ATTCH_Msk;
|
||||
hcd_event_device_remove(rhport, true);
|
||||
}
|
||||
|
||||
if (is0 & USB_IS0_BEMP) {
|
||||
const unsigned s = USB0.BEMPSTS.WORD;
|
||||
USB0.BEMPSTS.WORD = 0;
|
||||
if (is0 & RUSB2_INTSTS0_BEMP_Msk) {
|
||||
const unsigned s = RUSB2->BEMPSTS;
|
||||
RUSB2->BEMPSTS = 0;
|
||||
if (s & 1) {
|
||||
process_pipe0_bemp(rhport);
|
||||
}
|
||||
}
|
||||
if (is0 & USB_IS0_NRDY) {
|
||||
const unsigned m = USB0.NRDYENB.WORD;
|
||||
unsigned s = USB0.NRDYSTS.WORD & m;
|
||||
USB0.NRDYSTS.WORD = ~s;
|
||||
if (is0 & RUSB2_INTSTS0_NRDY_Msk) {
|
||||
const unsigned m = RUSB2->NRDYENB;
|
||||
unsigned s = RUSB2->NRDYSTS & m;
|
||||
RUSB2->NRDYSTS = ~s;
|
||||
while (s) {
|
||||
#if defined(__CCRX__)
|
||||
const unsigned num = Mod37BitPosition[(-s & s) % 37];
|
||||
@@ -855,11 +793,11 @@ void hcd_int_handler(uint8_t rhport)
|
||||
s &= ~TU_BIT(num);
|
||||
}
|
||||
}
|
||||
if (is0 & USB_IS0_BRDY) {
|
||||
const unsigned m = USB0.BRDYENB.WORD;
|
||||
unsigned s = USB0.BRDYSTS.WORD & m;
|
||||
if (is0 & RUSB2_INTSTS0_BRDY_Msk) {
|
||||
const unsigned m = RUSB2->BRDYENB;
|
||||
unsigned s = RUSB2->BRDYSTS & m;
|
||||
/* clear active bits (don't write 0 to already cleared bits according to the HW manual) */
|
||||
USB0.BRDYSTS.WORD = ~s;
|
||||
RUSB2->BRDYSTS = ~s;
|
||||
while (s) {
|
||||
#if defined(__CCRX__)
|
||||
const unsigned num = Mod37BitPosition[(-s & s) % 37];
|
||||
60
src/portable/renesas/rusb2/rusb2_ra.h
Normal file
60
src/portable/renesas/rusb2/rusb2_ra.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Rafael Silva (@perigoso)
|
||||
*
|
||||
* 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 _RUSB2_RA_H_
|
||||
#define _RUSB2_RA_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* renesas fsp api */
|
||||
#include "bsp_api.h"
|
||||
|
||||
#define RUSB2_REG_BASE (0x40090000)
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
NVIC_EnableIRQ(TU_IRQn);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_disable(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
NVIC_DisableIRQ(TU_IRQn);
|
||||
}
|
||||
|
||||
// MCU specific PHY init
|
||||
TU_ATTR_ALWAYS_INLINE static inline void rusb2_phy_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RUSB2_RA_H_ */
|
||||
74
src/portable/renesas/rusb2/rusb2_rx.h
Normal file
74
src/portable/renesas/rusb2/rusb2_rx.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Koji Kitayama
|
||||
* Portions copyrighted (c) 2021 Roland Winistoerfer
|
||||
* Copyright (c) 2022 Rafael Silva (@perigoso)
|
||||
*
|
||||
* 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 _RUSB2_RX_H_
|
||||
#define _RUSB2_RX_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "iodefine.h"
|
||||
|
||||
#define RUSB2_REG_BASE (0x000A0000)
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
#if (CFG_TUSB_MCU == OPT_MCU_RX72N)
|
||||
IEN(PERIB, INTB185) = 1;
|
||||
#else
|
||||
IEN(USB0, USBI0) = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_disable(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
#if (CFG_TUSB_MCU == OPT_MCU_RX72N)
|
||||
IEN(PERIB, INTB185) = 0;
|
||||
#else
|
||||
IEN(USB0, USBI0) = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// MCU specific PHY init
|
||||
TU_ATTR_ALWAYS_INLINE static inline void rusb2_phy_init(void)
|
||||
{
|
||||
#if (CFG_TUSB_MCU == OPT_MCU_RX72N)
|
||||
IR(PERIB, INTB185) = 0;
|
||||
#else
|
||||
IR(USB0, USBI0) = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RUSB2_RX_H_ */
|
||||
1669
src/portable/renesas/rusb2/rusb2_type.h
Normal file
1669
src/portable/renesas/rusb2/rusb2_type.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Nathan Conrad
|
||||
@@ -181,7 +181,7 @@ static void dcd_handle_bus_reset(void);
|
||||
static void dcd_transmit_packet(xfer_ctl_t * xfer, uint16_t ep_ix);
|
||||
static void dcd_ep_ctr_handler(void);
|
||||
|
||||
// PMA allocation/access
|
||||
// PMA allocation/access
|
||||
static uint8_t open_ep_count;
|
||||
static uint16_t ep_buf_ptr; ///< Points to first free memory location
|
||||
static void dcd_pma_alloc_reset(void);
|
||||
@@ -270,7 +270,7 @@ void dcd_init (uint8_t rhport)
|
||||
|
||||
USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
|
||||
dcd_handle_bus_reset();
|
||||
|
||||
|
||||
// Enable pull-up if supported
|
||||
if ( dcd_connect ) dcd_connect(rhport);
|
||||
}
|
||||
@@ -372,6 +372,9 @@ void dcd_int_enable (uint8_t rhport)
|
||||
NVIC_EnableIRQ(USB_HP_IRQn);
|
||||
NVIC_EnableIRQ(USB_LP_IRQn);
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
|
||||
NVIC_EnableIRQ(USB_FS_IRQn);
|
||||
|
||||
#else
|
||||
#error Unknown arch in USB driver
|
||||
#endif
|
||||
@@ -422,6 +425,9 @@ void dcd_int_disable(uint8_t rhport)
|
||||
NVIC_DisableIRQ(USB_HP_IRQn);
|
||||
NVIC_DisableIRQ(USB_LP_IRQn);
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
|
||||
NVIC_DisableIRQ(USB_FS_IRQn);
|
||||
|
||||
#else
|
||||
#error Unknown arch in USB driver
|
||||
#endif
|
||||
@@ -477,12 +483,12 @@ static void dcd_handle_bus_reset(void)
|
||||
//__IO uint16_t * const epreg = &(EPREG(0));
|
||||
USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag
|
||||
|
||||
|
||||
|
||||
for(uint32_t i=0; i<STFSDEV_EP_COUNT; i++)
|
||||
{
|
||||
// Clear all EPREG (or maybe this is automatic? I'm not sure)
|
||||
pcd_set_endpoint(USB,i,0u);
|
||||
|
||||
|
||||
// Clear EP allocation status
|
||||
ep_alloc_status[i].ep_num = 0xFF;
|
||||
ep_alloc_status[i].ep_type = 0xFF;
|
||||
@@ -544,7 +550,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) /* Setup packet */
|
||||
{
|
||||
uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex);
|
||||
@@ -770,11 +776,11 @@ static void dcd_pma_alloc_reset(void)
|
||||
|
||||
/***
|
||||
* Allocate a section of PMA
|
||||
*
|
||||
*
|
||||
* If the EP number has already been allocated, and the new allocation
|
||||
* is larger than the old allocation, then this will fail with a TU_ASSERT.
|
||||
* (This is done to simplify the code. More complicated algorithms could be used)
|
||||
*
|
||||
*
|
||||
* During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually.
|
||||
*/
|
||||
static uint16_t dcd_pma_alloc(uint8_t ep_addr, size_t length)
|
||||
@@ -865,7 +871,7 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
|
||||
ep_alloc_status[i].ep_num = epnum;
|
||||
ep_alloc_status[i].ep_type = ep_type;
|
||||
ep_alloc_status[i].allocated[dir] = true;
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -887,7 +893,7 @@ static void dcd_ep_free(uint8_t ep_addr)
|
||||
for(uint8_t i = 0; i < STFSDEV_EP_COUNT; i++)
|
||||
{
|
||||
// Check if EP number & dir are the same
|
||||
if(ep_alloc_status[i].ep_num == epnum &&
|
||||
if(ep_alloc_status[i].ep_num == epnum &&
|
||||
ep_alloc_status[i].allocated[dir] == dir)
|
||||
{
|
||||
ep_alloc_status[i].allocated[dir] = false;
|
||||
@@ -995,9 +1001,9 @@ void dcd_edpt_close_all (uint8_t rhport)
|
||||
|
||||
/**
|
||||
* Close an endpoint.
|
||||
*
|
||||
*
|
||||
* This function may be called with interrupts enabled or disabled.
|
||||
*
|
||||
*
|
||||
* This also clears transfers in progress, should there be any.
|
||||
*/
|
||||
void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
|
||||
@@ -1025,9 +1031,9 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
|
||||
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size)
|
||||
{
|
||||
(void)rhport;
|
||||
|
||||
|
||||
TU_ASSERT(largest_packet_size <= 1024);
|
||||
|
||||
|
||||
uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS);
|
||||
const uint16_t buffer_size = pcd_aligned_buffer_size(largest_packet_size);
|
||||
|
||||
@@ -1062,7 +1068,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpo
|
||||
{
|
||||
pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS);
|
||||
}
|
||||
|
||||
|
||||
pcd_set_ep_address(USB, ep_idx, tu_edpt_number(p_endpoint_desc->bEndpointAddress));
|
||||
// Be normal, for now, instead of only accepting zero-byte packets (on control endpoint)
|
||||
// or being double-buffered (bulk endpoints)
|
||||
@@ -1291,11 +1297,11 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wN
|
||||
{
|
||||
// Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
|
||||
tu_fifo_buffer_info_t info;
|
||||
tu_fifo_get_read_info(ff, &info);
|
||||
|
||||
tu_fifo_get_read_info(ff, &info);
|
||||
|
||||
uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin);
|
||||
uint16_t cnt_wrap = TU_MIN(wNBytes - cnt_lin, info.len_wrap);
|
||||
|
||||
|
||||
// We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
|
||||
// last lin byte will be combined with wrapped part
|
||||
// To ensure PMA is always access 16bit aligned (dst aligned to 16 bit)
|
||||
@@ -1402,7 +1408,7 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNB
|
||||
// Copy last linear byte & first wrapped byte
|
||||
uint16_t tmp;
|
||||
dcd_read_packet_memory(&tmp, src, 2);
|
||||
|
||||
|
||||
((uint8_t*)info.ptr_lin)[cnt_lin - 1] = (uint8_t)tmp;
|
||||
((uint8_t*)info.ptr_wrap)[0] = (uint8_t)(tmp >> 8U);
|
||||
src += 2;
|
||||
@@ -1429,4 +1435,3 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNB
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -121,6 +121,14 @@
|
||||
#include "stm32l4xx.h"
|
||||
#define PMA_LENGTH (1024u)
|
||||
|
||||
#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
|
||||
#include "stm32l5xx.h"
|
||||
#define PMA_LENGTH (1024u)
|
||||
|
||||
#ifndef USB_PMAADDR
|
||||
#define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS))
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error You are using an untested or unimplemented STM32 variant. Please update the driver.
|
||||
// This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -996,7 +996,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||
if (dir_in) {
|
||||
USBC_Writew(mps, USBC_REG_TXMAXP(USBC0_BASE));
|
||||
|
||||
reg_val = (1 << USBC_BP_TXCSR_D_MODE)
|
||||
reg_val = (1 << USBC_BP_TXCSR_D_MODE)
|
||||
| (1 << USBC_BP_TXCSR_D_FLUSH_FIFO)
|
||||
| (1 << USBC_BP_TXCSR_D_CLEAR_DATA_TOGGLE);
|
||||
if (xfer == TUSB_XFER_ISOCHRONOUS)
|
||||
@@ -1048,7 +1048,7 @@ void dcd_edpt_close_all(uint8_t rhport)
|
||||
USBC_REG_TXCSR(USBC0_BASE));
|
||||
|
||||
USBC_Writew(0, USBC_REG_RXMAXP(USBC0_BASE));
|
||||
USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO),
|
||||
USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO),
|
||||
USBC_REG_RXCSR(USBC0_BASE));
|
||||
|
||||
USBC_Writew(0, USBC_REG_TXFIFOAD(USBC0_BASE));
|
||||
@@ -1078,7 +1078,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
||||
} else {
|
||||
USBC_INT_DisableRxEp(epn);
|
||||
USBC_Writew(0, USBC_REG_RXMAXP(USBC0_BASE));
|
||||
USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO),
|
||||
USBC_Writew((1 << USBC_BP_RXCSR_D_CLEAR_DATA_TOGGLE) | (1 << USBC_BP_RXCSR_D_FLUSH_FIFO),
|
||||
USBC_REG_RXCSR(USBC0_BASE));
|
||||
|
||||
USBC_Writew(0, USBC_REG_RXFIFOAD(USBC0_BASE));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2018, hathach (tinyusb.org)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2022 Greg Davill
|
||||
* Copyright (c) 2022 Greg Davill
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -261,7 +261,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
|
||||
USBHS_Dev_Endp0_Tog ^= 1;
|
||||
} else {
|
||||
xfer->queued_len += short_packet_size;
|
||||
|
||||
|
||||
EP_TX_DMA_ADDR(epnum) = (uint32_t)buffer;
|
||||
USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << epnum);
|
||||
EP_TX_LEN(epnum) = short_packet_size;
|
||||
@@ -366,7 +366,7 @@ void dcd_int_handler(uint8_t rhport) {
|
||||
} else if (intflag & USBHS_SETUP_FLAG) {
|
||||
USBHS_Dev_Endp0_Tog = 1;
|
||||
dcd_event_setup_received(0, EP0_DatabufHD, true);
|
||||
|
||||
|
||||
USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */
|
||||
} else if (intflag & USBHS_DETECT_FLAG) {
|
||||
USBHS_Dev_Endp0_Tog = 1;
|
||||
|
||||
Reference in New Issue
Block a user