more multiple ports update

This commit is contained in:
hathach 2023-07-06 19:35:42 +07:00
parent 95b77a0e73
commit 1eefc2b3ef
No known key found for this signature in database
GPG Key ID: F5D50C6D51D17CBA
3 changed files with 208 additions and 147 deletions

View File

@ -63,22 +63,11 @@
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
/* LINK core registers */
#if defined(__CCRX__)
#define RUSB2 ((rusb2_reg_t __evenaccess*) RUSB2_REG_BASE)
#elif defined(__RX__)
#define RUSB2 ((rusb2_reg_t*) RUSB2_REG_BASE)
#elif (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)
#define RUSB2 ((R_USB_HS0_Type*)R_USB_HS0_BASE)
#else
#define RUSB2 ((R_USB_FS0_Type*)R_USB_FS0_BASE)
#endif
/* Start of definition of packed structs (used by the CCRX toolchain) */
TU_ATTR_PACKED_BEGIN
TU_ATTR_BIT_FIELD_ORDER_BEGIN
typedef struct TU_ATTR_PACKED {
typedef struct TU_ATTR_PACKED _ccrx_evenaccess {
union {
struct {
uint16_t : 8;
@ -186,52 +175,53 @@ static unsigned find_pipe(unsigned xfer)
return 0;
}
static volatile uint16_t* get_pipectr(unsigned num)
static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num)
{
if (num) {
return (volatile uint16_t*)&(RUSB2->PIPE_CTR[num - 1]);
return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]);
} else {
return (volatile uint16_t*)&(RUSB2->DCPCTR);
return (volatile uint16_t*)&(rusb->DCPCTR);
}
}
static volatile reg_pipetre_t* get_pipetre(unsigned num)
static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num)
{
volatile reg_pipetre_t* tre = NULL;
if ((1 <= num) && (num <= 5)) {
tre = (volatile reg_pipetre_t*)&(RUSB2->PIPE_TR[num - 1].E);
tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E);
}
return tre;
}
static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr)
{
(void)rhport;
rusb2_reg_t *rusb = RUSB2_REG(rhport);
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];
return get_pipectr(num);
return get_pipectr(rusb, num);
} else {
return get_pipectr(0);
return get_pipectr(rusb, 0);
}
}
static unsigned edpt0_max_packet_size(void)
static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb)
{
return RUSB2->DCPMAXP_b.MXPS;
return rusb->DCPMAXP_b.MXPS;
}
static unsigned edpt_max_packet_size(unsigned num)
static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num)
{
RUSB2->PIPESEL = num;
return RUSB2->PIPEMAXP;
rusb->PIPESEL = num;
return rusb->PIPEMAXP;
}
static inline void pipe_wait_for_ready(unsigned num)
static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num)
{
while (RUSB2->D0FIFOSEL_b.CURPIPE != num) ;
while (!RUSB2->D0FIFOCTR_b.FRDY) ;
while ( rusb->D0FIFOSEL_b.CURPIPE != num ) {}
while ( !rusb->D0FIFOCTR_b.FRDY ) {}
}
static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
@ -284,61 +274,70 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne
ops[dir].tu_fifo_advance(f, total_len - rem);
}
static bool pipe0_xfer_in(void)
static bool pipe0_xfer_in(rusb2_reg_t* rusb)
{
pipe_state_t *pipe = &_dcd.pipe[0];
const unsigned rem = pipe->remaining;
if (!rem) {
pipe->buf = NULL;
return true;
}
const unsigned mps = edpt0_max_packet_size();
const unsigned len = TU_MIN(mps, rem);
const uint16_t mps = edpt0_max_packet_size(rusb);
const uint16_t len = tu_min16(mps, rem);
void *buf = pipe->buf;
if (len) {
if (pipe->ff) {
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->CFIFO, len, TUSB_DIR_IN);
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len, TUSB_DIR_IN);
} else {
pipe_write_packet(buf, (volatile void*)&RUSB2->CFIFO, len);
pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len);
pipe->buf = (uint8_t*)buf + len;
}
}
if (len < mps) {
RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
}
pipe->remaining = rem - len;
return false;
}
static bool pipe0_xfer_out(void)
static bool pipe0_xfer_out(rusb2_reg_t* rusb)
{
pipe_state_t *pipe = &_dcd.pipe[0];
const unsigned rem = pipe->remaining;
const unsigned mps = edpt0_max_packet_size();
const unsigned vld = RUSB2->CFIFOCTR_b.DTLN;
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
const uint16_t mps = edpt0_max_packet_size(rusb);
const uint16_t vld = rusb->CFIFOCTR_b.DTLN;
const uint16_t len = tu_min16(tu_min16(rem, mps), vld);
void *buf = pipe->buf;
if (len) {
if (pipe->ff) {
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->CFIFO, len, TUSB_DIR_OUT);
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len, TUSB_DIR_OUT);
} else {
pipe_read_packet(buf, (volatile void*)&RUSB2->CFIFO, len);
pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len);
pipe->buf = (uint8_t*)buf + len;
}
}
if (len < mps) {
RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
}
pipe->remaining = rem - len;
if ((len < mps) || (rem == len)) {
pipe->buf = NULL;
return true;
}
return false;
}
static bool pipe_xfer_in(unsigned num)
static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num)
{
pipe_state_t *pipe = &_dcd.pipe[num];
const unsigned rem = pipe->remaining;
@ -348,119 +347,141 @@ static bool pipe_xfer_in(unsigned num)
return true;
}
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);
rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
const uint16_t mps = edpt_max_packet_size(rusb, num);
pipe_wait_for_ready(rusb, num);
const uint16_t len = tu_min16(rem, mps);
void *buf = pipe->buf;
if (len) {
if (pipe->ff) {
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->D0FIFO, len, TUSB_DIR_IN);
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len, TUSB_DIR_IN);
} else {
pipe_write_packet(buf, (volatile void*)&RUSB2->D0FIFO, len);
pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len);
pipe->buf = (uint8_t*)buf + len;
}
}
if (len < mps) {
RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
}
RUSB2->D0FIFOSEL = 0;
while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */
rusb->D0FIFOSEL = 0;
while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */
pipe->remaining = rem - len;
return false;
}
static bool pipe_xfer_out(unsigned num)
static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num)
{
pipe_state_t *pipe = &_dcd.pipe[num];
const unsigned rem = pipe->remaining;
const uint16_t rem = pipe->remaining;
RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT;
const unsigned mps = edpt_max_packet_size(num);
pipe_wait_for_ready(num);
const unsigned vld = RUSB2->D0FIFOCTR_b.DTLN;
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT;
const uint16_t mps = edpt_max_packet_size(rusb, num);
pipe_wait_for_ready(rusb, num);
const uint16_t vld = rusb->D0FIFOCTR_b.DTLN;
const uint16_t len = tu_min16(tu_min16(rem, mps), vld);
void *buf = pipe->buf;
if (len) {
if (pipe->ff) {
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->D0FIFO, len, TUSB_DIR_OUT);
pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len, TUSB_DIR_OUT);
} else {
pipe_read_packet(buf, (volatile void*)&RUSB2->D0FIFO, len);
pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len);
pipe->buf = (uint8_t*)buf + len;
}
}
if (len < mps) {
RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
}
RUSB2->D0FIFOSEL = 0;
while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */
rusb->D0FIFOSEL = 0;
while (rusb->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;
}
return false;
}
static void process_setup_packet(uint8_t rhport)
{
uint16_t setup_packet[4];
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);
rusb2_reg_t* rusb = RUSB2_REG(rhport);
if (0 == (rusb->INTSTS0 & RUSB2_INTSTS0_VALID_Msk)) return;
rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk;
uint16_t setup_packet[4] = {
tu_htole16(rusb->USBREQ),
tu_htole16(rusb->USBVAL),
tu_htole16(rusb->USBINDX),
tu_htole16(rusb->USBLENG)
};
rusb->INTSTS0 = ~((uint16_t) RUSB2_INTSTS0_VALID_Msk);
dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet[0], true);
}
static void process_status_completion(uint8_t rhport)
{
rusb2_reg_t* rusb = RUSB2_REG(rhport);
uint8_t ep_addr;
/* Check the data stage direction */
if (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) {
if (rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) {
/* IN transfer. */
ep_addr = tu_edpt_addr(0, TUSB_DIR_IN);
} else {
/* OUT transfer. */
ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT);
}
dcd_event_xfer_complete(rhport, ep_addr, 0, XFER_RESULT_SUCCESS, true);
}
static bool process_pipe0_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes)
static bool process_pipe0_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes)
{
/* configure fifo direction and access unit settings */
if (ep_addr) { /* IN, 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)) ;
} else { /* OUT, a byte */
RUSB2->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT;
while (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ;
if ( ep_addr ) {
/* IN, 2 bytes */
rusb->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT |
(TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
while ( !(rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ) {}
} else {
/* OUT, a byte */
rusb->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT;
while ( rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE ) {}
}
pipe_state_t *pipe = &_dcd.pipe[0];
pipe->ff = buffer_type;
pipe->length = total_bytes;
pipe->remaining = total_bytes;
if (total_bytes) {
pipe->buf = buffer;
if (ep_addr) { /* IN */
TU_ASSERT(RUSB2->DCPCTR_b.BSTS && (RUSB2->USBREQ & 0x80));
pipe0_xfer_in();
if ( total_bytes ) {
pipe->buf = buffer;
if ( ep_addr ) {
/* IN */
TU_ASSERT(rusb->DCPCTR_b.BSTS && (rusb->USBREQ & 0x80));
pipe0_xfer_in(rusb);
}
RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF;
rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF;
} else {
/* ZLP */
pipe->buf = NULL;
RUSB2->DCPCTR = RUSB2_DCPCTR_CCPL_Msk | RUSB2_PIPE_CTR_PID_BUF;
pipe->buf = NULL;
rusb->DCPCTR = RUSB2_DCPCTR_CCPL_Msk | RUSB2_PIPE_CTR_PID_BUF;
}
return true;
}
static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes)
static bool process_pipe_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes)
{
const unsigned epn = tu_edpt_number(ep_addr);
const unsigned dir = tu_edpt_dir(ep_addr);
@ -473,49 +494,55 @@ static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, ui
pipe->buf = buffer;
pipe->length = total_bytes;
pipe->remaining = total_bytes;
if (dir) { /* IN */
if (dir) {
/* IN */
if (total_bytes) {
pipe_xfer_in(num);
} else { /* ZLP */
RUSB2->D0FIFOSEL = num;
pipe_wait_for_ready(num);
RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
RUSB2->D0FIFOSEL = 0;
while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */
pipe_xfer_in(rusb, num);
} else {
/* ZLP */
rusb->D0FIFOSEL = num;
pipe_wait_for_ready(rusb, num);
rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk;
rusb->D0FIFOSEL = 0;
/* if CURPIPE bits changes, check written value */
while (rusb->D0FIFOSEL_b.CURPIPE) {}
}
} else {
#if defined(__CCRX__)
__evenaccess volatile reg_pipetre_t *pt = get_pipetre(num);
#else
volatile reg_pipetre_t *pt = get_pipetre(num);
#endif
// OUT
volatile reg_pipetre_t *pt = get_pipetre(rusb, num);
if (pt) {
const unsigned mps = edpt_max_packet_size(num);
volatile uint16_t *ctr = get_pipectr(num);
const uint16_t mps = edpt_max_packet_size(rusb, num);
volatile uint16_t *ctr = get_pipectr(rusb, num);
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 = RUSB2_PIPE_CTR_PID_BUF;
}
}
// TU_LOG1("X %x %d %d\r\n", ep_addr, total_bytes, buffer_type);
// TU_LOG2("X %x %d %d\r\n", ep_addr, total_bytes, buffer_type);
return true;
}
static bool process_edpt_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes)
static bool process_edpt_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes)
{
const unsigned epn = tu_edpt_number(ep_addr);
if (0 == epn) {
return process_pipe0_xfer(buffer_type, ep_addr, buffer, total_bytes);
return process_pipe0_xfer(rusb, buffer_type, ep_addr, buffer, total_bytes);
} else {
return process_pipe_xfer(buffer_type, ep_addr, buffer, total_bytes);
return process_pipe_xfer(rusb, buffer_type, ep_addr, buffer, total_bytes);
}
}
static void process_pipe0_bemp(uint8_t rhport)
{
bool completed = pipe0_xfer_in();
rusb2_reg_t* rusb = RUSB2_REG(rhport);
bool completed = pipe0_xfer_in(rusb);
if (completed) {
pipe_state_t *pipe = &_dcd.pipe[0];
dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN),
@ -525,17 +552,20 @@ static void process_pipe0_bemp(uint8_t rhport)
static void process_pipe_brdy(uint8_t rhport, unsigned num)
{
rusb2_reg_t* rusb = RUSB2_REG(rhport);
pipe_state_t *pipe = &_dcd.pipe[num];
const unsigned dir = tu_edpt_dir(pipe->ep);
bool completed;
if (dir) { /* IN */
completed = pipe_xfer_in(num);
if (dir) {
/* IN */
completed = pipe_xfer_in(rusb, num);
} else {
// OUT
if (num) {
completed = pipe_xfer_out(num);
completed = pipe_xfer_out(rusb, num);
} else {
completed = pipe0_xfer_out();
completed = pipe0_xfer_out(rusb);
}
}
if (completed) {
@ -606,8 +636,10 @@ static void process_bus_reset(uint8_t rhport)
static void process_set_address(uint8_t rhport)
{
const uint32_t addr = RUSB2->USBADDR & 0xFF;
rusb2_reg_t* rusb = RUSB2_REG(rhport);
const uint32_t addr = rusb->USBADDR & 0xFF;
if (!addr) return;
const tusb_control_request_t setup_packet = {
#if defined(__CCRX__)
.bmRequestType = { 0 }, /* Note: CCRX needs the braces over this struct member */
@ -618,8 +650,9 @@ static void process_set_address(uint8_t rhport)
.wValue = addr,
.wIndex = 0,
.wLength = 0,
};
dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet, true);
};
dcd_event_setup_received(rhport, (const uint8_t *) &setup_packet, true);
}
/*------------------------------------------------------------------*/
@ -704,7 +737,7 @@ void dcd_init(uint8_t rhport)
rusb->INTSTS0 = 0;
rusb->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_INTSTS0_NRDY_Msk;
RUSB2_INTSTS0_RESM_Msk;
rusb->BEMPENB = 1;
rusb->BRDYENB = 1;
@ -766,33 +799,43 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
{
(void)rhport;
rusb2_reg_t * rusb = RUSB2_REG(rhport);
const unsigned ep_addr = ep_desc->bEndpointAddress;
const unsigned epn = tu_edpt_number(ep_addr);
const unsigned dir = tu_edpt_dir(ep_addr);
const unsigned xfer = ep_desc->bmAttributes.xfer;
const unsigned mps = tu_edpt_packet_size(ep_desc);
if (xfer == TUSB_XFER_ISOCHRONOUS && mps > 256) {
/* USBa supports up to 256 bytes */
return false;
if (xfer == TUSB_XFER_ISOCHRONOUS) {
// Fullspeed ISO is limit to 256 bytes
if ( !is_highspeed(rhport) && mps > 256) {
return false;
}
}
const unsigned num = find_pipe(xfer);
if (!num) return false;
TU_ASSERT(num);
_dcd.pipe[num].ep = ep_addr;
_dcd.ep[dir][epn] = num;
/* setup pipe */
dcd_int_disable(rhport);
#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)
RUSB2->PIPEBUF = 0x7C08;
#endif
RUSB2->PIPESEL = num;
RUSB2->PIPEMAXP = mps;
volatile uint16_t *ctr = get_pipectr(num);
if ( is_highspeed(rhport) ) {
// FIXME shouldn't be after pipe selection and config, also the BUFNMB should be changed
// depending on the allocation scheme
rusb->PIPEBUF = 0x7C08;
}
rusb->PIPESEL = num;
rusb->PIPEMAXP = mps;
volatile uint16_t *ctr = get_pipectr(rusb, num);
*ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk;
*ctr = 0;
unsigned cfg = (dir << 4) | epn;
if (xfer == TUSB_XFER_BULK) {
cfg |= (RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk);
} else if (xfer == TUSB_XFER_INTERRUPT) {
@ -800,13 +843,16 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
} else {
cfg |= (RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk);
}
RUSB2->PIPECFG = cfg;
RUSB2->BRDYSTS = 0x1FFu ^ TU_BIT(num);
RUSB2->BRDYENB |= TU_BIT(num);
rusb->PIPECFG = cfg;
rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num);
rusb->BRDYENB |= TU_BIT(num);
if (dir || (xfer != TUSB_XFER_BULK)) {
*ctr = RUSB2_PIPE_CTR_PID_BUF;
}
// TU_LOG1("O %d %x %x\r\n", RUSB2->PIPESEL, RUSB2->PIPECFG, RUSB2->PIPEMAXP);
// TU_LOG1("O %d %x %x\r\n", rusb->PIPESEL, rusb->PIPECFG, rusb->PIPEMAXP);
dcd_int_enable(rhport);
return true;
@ -826,26 +872,28 @@ void dcd_edpt_close_all(uint8_t rhport)
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
{
(void)rhport;
rusb2_reg_t * rusb = RUSB2_REG(rhport);
const unsigned epn = tu_edpt_number(ep_addr);
const unsigned dir = tu_edpt_dir(ep_addr);
const unsigned num = _dcd.ep[dir][epn];
RUSB2->BRDYENB &= ~TU_BIT(num);
volatile uint16_t *ctr = get_pipectr(num);
rusb->BRDYENB &= ~TU_BIT(num);
volatile uint16_t *ctr = get_pipectr(rusb, num);
*ctr = 0;
RUSB2->PIPESEL = num;
RUSB2->PIPECFG = 0;
rusb->PIPESEL = num;
rusb->PIPECFG = 0;
_dcd.pipe[num].ep = 0;
_dcd.ep[dir][epn] = 0;
}
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
{
bool r;
rusb2_reg_t* rusb = RUSB2_REG(rhport);
dcd_int_disable(rhport);
r = process_edpt_xfer(0, ep_addr, buffer, total_bytes);
bool r = process_edpt_xfer(rusb, 0, ep_addr, buffer, total_bytes);
dcd_int_enable(rhport);
return r;
}
@ -853,10 +901,12 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
{
// USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1
TU_ASSERT(ff->item_size == 1);
bool r;
rusb2_reg_t* rusb = RUSB2_REG(rhport);
dcd_int_disable(rhport);
r = process_edpt_xfer(1, ep_addr, ff, total_bytes);
bool r = process_edpt_xfer(rusb, 1, ep_addr, ff, total_bytes);
dcd_int_enable(rhport);
return r;
}
@ -873,8 +923,10 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{
rusb2_reg_t * rusb = RUSB2_REG(rhport);
volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr);
if (!ctr) return;
dcd_int_disable(rhport);
*ctr = RUSB2_PIPE_CTR_SQCLR_Msk;
@ -882,8 +934,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
*ctr = RUSB2_PIPE_CTR_PID_BUF;
} else {
const unsigned num = _dcd.ep[0][tu_edpt_number(ep_addr)];
RUSB2->PIPESEL = num;
if (RUSB2->PIPECFG_b.TYPE != 1) {
rusb->PIPESEL = num;
if (rusb->PIPECFG_b.TYPE != 1) {
*ctr = RUSB2_PIPE_CTR_PID_BUF;
}
}
@ -953,9 +1005,9 @@ void dcd_int_handler(uint8_t rhport)
}
}
if ( is0 & RUSB2_INTSTS0_NRDY_Msk ) {
rusb->NRDYSTS = 0;
}
// if ( is0 & RUSB2_INTSTS0_NRDY_Msk ) {
// rusb->NRDYSTS = 0;
// }
// Control transfer stage changes
if ( is0 & RUSB2_INTSTS0_CTRT_Msk ) {
@ -970,7 +1022,7 @@ void dcd_int_handler(uint8_t rhport)
// Buffer empty
if ( is0 & RUSB2_INTSTS0_BEMP_Msk ) {
const unsigned s = rusb->BEMPSTS;
const uint16_t s = rusb->BEMPSTS;
rusb->BEMPSTS = 0;
if ( s & 1 ) {
process_pipe0_bemp(rhport);

View File

@ -37,6 +37,8 @@ extern "C" {
#define RUSB2_REG_BASE (0x000A0000)
#define RUSB2_REG(_p) ((rusb2_reg_t *) RUSB2_REG_BASE)
// Start/Stop MSTP TODO implement later
TU_ATTR_ALWAYS_INLINE static inline void rusb2_module_start(uint8_t rhport, bool start) {
(void) rhport;

View File

@ -33,6 +33,13 @@
extern "C" {
#endif
// CCRX specific attribute to generate a Code that Accesses Variables in the Declared Size
#ifdef __CCRX__
#define _ccrx_evenaccess __evenaccess
#else
#define _ccrx_evenaccess
#endif
/*--------------------------------------------------------------------*/
/* Register Definitions */
/*--------------------------------------------------------------------*/
@ -64,7 +71,7 @@ typedef struct {
/* RUSB2 Registers Structure */
typedef struct {
typedef struct _ccrx_evenaccess {
union {
volatile uint16_t SYSCFG; /* (@ 0x00000000) System Configuration Control Register */