using BRDY interruption for handling IN transfers.
This commit is contained in:
parent
f8cf88f918
commit
e010ea30e5
|
@ -200,9 +200,9 @@ static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr)
|
||||||
{
|
{
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
volatile uint16_t *ctr = NULL;
|
volatile uint16_t *ctr = NULL;
|
||||||
const unsigned epn = ep_addr & 0xFu;
|
const unsigned epn = tu_edpt_number(ep_addr);
|
||||||
if (epn) {
|
if (epn) {
|
||||||
const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
|
const unsigned dir = tu_edpt_dir(ep_addr);
|
||||||
const unsigned num = _dcd.ep[dir][epn];
|
const unsigned num = _dcd.ep[dir][epn];
|
||||||
if (num) {
|
if (num) {
|
||||||
ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD;
|
ctr = (volatile uint16_t*)&USB0.PIPE1CTR.WORD;
|
||||||
|
@ -234,39 +234,11 @@ static unsigned select_pipe(unsigned num, unsigned attr)
|
||||||
/* 1 less than 64 bytes were written
|
/* 1 less than 64 bytes were written
|
||||||
* 2 no bytes were written
|
* 2 no bytes were written
|
||||||
* 0 mps bytes were written */
|
* 0 mps bytes were written */
|
||||||
static int write_fifo(volatile void *fifo, pipe_state_t* pipe, unsigned mps, unsigned ofs)
|
static int write_fifo(volatile void *fifo, pipe_state_t* pipe, unsigned mps)
|
||||||
{
|
|
||||||
unsigned rem = pipe->remaining - ofs;
|
|
||||||
if (!rem) return 2;
|
|
||||||
unsigned len = (rem < mps) ? rem: mps;
|
|
||||||
|
|
||||||
hw_fifo_t *reg = (hw_fifo_t*)fifo;
|
|
||||||
uintptr_t addr = pipe->addr + pipe->length - rem;
|
|
||||||
if (addr & 1u) {
|
|
||||||
/* addr is not 2-byte aligned */
|
|
||||||
reg->u8 = *(const uint8_t *)addr;
|
|
||||||
++addr;
|
|
||||||
--len;
|
|
||||||
}
|
|
||||||
while (len >= 2) {
|
|
||||||
reg->u16 = *(const uint16_t *)addr;
|
|
||||||
addr += 2;
|
|
||||||
len -= 2;
|
|
||||||
}
|
|
||||||
if (len) {
|
|
||||||
reg->u8 = *(const uint8_t *)addr;
|
|
||||||
++addr;
|
|
||||||
}
|
|
||||||
if (rem < mps) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#if 1
|
|
||||||
static int write_fifo2(volatile void *fifo, pipe_state_t* pipe, unsigned mps)
|
|
||||||
{
|
{
|
||||||
unsigned rem = pipe->remaining;
|
unsigned rem = pipe->remaining;
|
||||||
if (!rem) return 2;
|
if (!rem) return 2;
|
||||||
unsigned len = (rem < mps) ? rem: mps;
|
unsigned len = TU_MIN(rem, mps);
|
||||||
pipe->remaining = rem - len;
|
|
||||||
|
|
||||||
hw_fifo_t *reg = (hw_fifo_t*)fifo;
|
hw_fifo_t *reg = (hw_fifo_t*)fifo;
|
||||||
uintptr_t addr = pipe->addr + pipe->length - rem;
|
uintptr_t addr = pipe->addr + pipe->length - rem;
|
||||||
|
@ -288,7 +260,6 @@ static int write_fifo2(volatile void *fifo, pipe_state_t* pipe, unsigned mps)
|
||||||
if (rem < mps) return 1;
|
if (rem < mps) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 1 if the number of bytes read is less than 64 bytes
|
/* 1 if the number of bytes read is less than 64 bytes
|
||||||
* 0 otherwise */
|
* 0 otherwise */
|
||||||
|
@ -359,7 +330,7 @@ static bool process_edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer,
|
||||||
pipe->data = USB0.DCPCTR.BIT.SQMON;
|
pipe->data = USB0.DCPCTR.BIT.SQMON;
|
||||||
if (ep_addr) { /* IN */
|
if (ep_addr) { /* IN */
|
||||||
TU_ASSERT(USB0.DCPCTR.BIT.BSTS && (USB0.USBREQ.WORD & 0x80));
|
TU_ASSERT(USB0.DCPCTR.BIT.BSTS && (USB0.USBREQ.WORD & 0x80));
|
||||||
if (write_fifo(&USB0.CFIFO.WORD, pipe, 64, 0)) {
|
if (write_fifo(&USB0.CFIFO.WORD, pipe, 64)) {
|
||||||
USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,7 +343,6 @@ static bool process_edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer,
|
||||||
pipe->remaining = 0;
|
pipe->remaining = 0;
|
||||||
pipe->data = USB0.DCPCTR.BIT.SQMON;
|
pipe->data = USB0.DCPCTR.BIT.SQMON;
|
||||||
USB0.DCPCTR.WORD = USB_PIPECTR_CCPL | USB_PIPECTR_PID_BUF;
|
USB0.DCPCTR.WORD = USB_PIPECTR_CCPL | USB_PIPECTR_PID_BUF;
|
||||||
// TU_LOG1("Z %x\r\n", USB0.DCPCTR.WORD);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -382,9 +352,8 @@ static void process_edpt0_bemp(uint8_t rhport)
|
||||||
pipe_state_t *pipe = &_dcd.pipe[0];
|
pipe_state_t *pipe = &_dcd.pipe[0];
|
||||||
unsigned data = pipe->data;
|
unsigned data = pipe->data;
|
||||||
if (USB0.DCPCTR.BIT.SQMON == data) {
|
if (USB0.DCPCTR.BIT.SQMON == data) {
|
||||||
TU_LOG1("W %x\r\n", USB0.DCPCTR.WORD);
|
|
||||||
/* retry transfer */
|
/* retry transfer */
|
||||||
int r = write_fifo(&USB0.CFIFO.WORD, &_dcd.pipe[0], 64, 0);
|
int r = write_fifo(&USB0.CFIFO.WORD, &_dcd.pipe[0], 64);
|
||||||
if (r) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
if (r) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -392,16 +361,14 @@ static void process_edpt0_bemp(uint8_t rhport)
|
||||||
if (rem > 64) {
|
if (rem > 64) {
|
||||||
pipe->remaining = rem - 64;
|
pipe->remaining = rem - 64;
|
||||||
pipe->data = data ^ 1;
|
pipe->data = data ^ 1;
|
||||||
TU_LOG1("Y %d %x\r\n", rem - 64, USB0.DCPCTR.WORD);
|
int r = write_fifo(&USB0.CFIFO.WORD, &_dcd.pipe[0], 64);
|
||||||
int r = write_fifo(&USB0.CFIFO.WORD, &_dcd.pipe[0], 64, 0);
|
|
||||||
if (r) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
if (r) USB0.CFIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pipe->addr = 0;
|
pipe->addr = 0;
|
||||||
pipe->remaining = 0;
|
pipe->remaining = 0;
|
||||||
dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN),
|
dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN),
|
||||||
pipe->length, XFER_RESULT_SUCCESS, true);
|
pipe->length, XFER_RESULT_SUCCESS, true);
|
||||||
// TU_LOG1("c\r\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_edpt0_brdy(uint8_t rhport)
|
static void process_edpt0_brdy(uint8_t rhport)
|
||||||
|
@ -414,8 +381,7 @@ static void process_edpt0_brdy(uint8_t rhport)
|
||||||
}
|
}
|
||||||
dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_OUT),
|
dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_OUT),
|
||||||
_dcd.pipe[0].length - _dcd.pipe[0].remaining,
|
_dcd.pipe[0].length - _dcd.pipe[0].remaining,
|
||||||
XFER_RESULT_SUCCESS, true);
|
XFER_RESULT_SUCCESS, true);
|
||||||
// TU_LOG1("c\r\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,8 +389,8 @@ static bool process_pipe_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer,
|
||||||
{
|
{
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
|
|
||||||
const unsigned epn = ep_addr & 0xFu;
|
const unsigned epn = tu_edpt_number(ep_addr);
|
||||||
const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
|
const unsigned dir = tu_edpt_dir(ep_addr);
|
||||||
const unsigned num = _dcd.ep[dir][epn];
|
const unsigned num = _dcd.ep[dir][epn];
|
||||||
|
|
||||||
TU_ASSERT(num);
|
TU_ASSERT(num);
|
||||||
|
@ -439,120 +405,61 @@ static bool process_pipe_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer,
|
||||||
if (dir) { /* IN */
|
if (dir) { /* IN */
|
||||||
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16;
|
USB0.D0FIFOSEL.WORD = num | USB_FIFOSEL_MBW_16;
|
||||||
while (!(USB0.D0FIFOSEL.BIT.CURPIPE != num)) ;
|
while (!(USB0.D0FIFOSEL.BIT.CURPIPE != num)) ;
|
||||||
#if 0
|
int r = write_fifo(&USB0.D0FIFO.WORD, pipe, mps);
|
||||||
unsigned ofs = 0;
|
if (r) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||||
if (USB0.PIPECFG.BIT.DBLB && (total_bytes > mps)) {
|
|
||||||
write_fifo(&USB0.D0FIFO.WORD, pipe, mps, 0);
|
|
||||||
}
|
|
||||||
if (write_fifo(&USB0.D0FIFO.WORD, pipe, mps, ofs)) {
|
|
||||||
USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (USB0.PIPECFG.BIT.DBLB && (total_bytes > mps)) {
|
|
||||||
write_fifo2(&USB0.D0FIFO.WORD, pipe, mps);
|
|
||||||
wait_for_pipe_ready();
|
|
||||||
}
|
|
||||||
if (write_fifo2(&USB0.D0FIFO.WORD, pipe, mps)) {
|
|
||||||
USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
USB0.D0FIFOSEL.WORD = 0;
|
USB0.D0FIFOSEL.WORD = 0;
|
||||||
} else {
|
} else {
|
||||||
volatile reg_pipetre_t *pt = get_pipetre(num);
|
volatile reg_pipetre_t *pt = get_pipetre(num);
|
||||||
if (pt) {
|
if (pt) {
|
||||||
volatile uint16_t *ctr = get_pipectr(num);
|
volatile uint16_t *ctr = get_pipectr(num);
|
||||||
if (*ctr & 0x3) *ctr = USB_PIPECTR_PID_NAK;
|
if (*ctr & 0x3) *ctr = USB_PIPECTR_PID_NAK;
|
||||||
pt->TRE = 1u << 8;
|
pt->TRE = TU_BIT(8);
|
||||||
pt->TRN = (total_bytes + mps - 1) / mps;
|
pt->TRN = (total_bytes + mps - 1) / mps;
|
||||||
pt->TRENB = 1;
|
pt->TRENB = 1;
|
||||||
*ctr = USB_PIPECTR_PID_BUF;
|
*ctr = USB_PIPECTR_PID_BUF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TU_LOG1("X %x %d\r\n", ep_addr, total_bytes);
|
//TU_LOG1("X %x %d\r\n", ep_addr, total_bytes);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
static void process_pipe_bemp(uint8_t rhport, unsigned num)
|
|
||||||
{
|
|
||||||
pipe_state_t *pipe = &_dcd.pipe[num];
|
|
||||||
unsigned rem = pipe->remaining;
|
|
||||||
USB0.PIPESEL.WORD = num;
|
|
||||||
const unsigned mps = USB0.PIPEMAXP.WORD;
|
|
||||||
|
|
||||||
if (rem > mps) {
|
|
||||||
rem -= mps;
|
|
||||||
pipe->remaining = rem;
|
|
||||||
if (USB0.PIPECFG.BIT.DBLB) {
|
|
||||||
if (rem > mps) {
|
|
||||||
unsigned ctr = select_pipe(num, USB_FIFOSEL_MBW_16);
|
|
||||||
int r = write_fifo(&USB0.D0FIFO.WORD, pipe, mps, mps);
|
|
||||||
if (r) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
|
||||||
USB0.D0FIFOSEL.WORD = 0;
|
|
||||||
TU_LOG1("< %d %x %x %d\r\n", rem, ctr, *get_pipectr(num), r);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unsigned ctr = select_pipe(num, USB_FIFOSEL_MBW_16);
|
|
||||||
int r = write_fifo(&USB0.D0FIFO.WORD, pipe, mps, 0);
|
|
||||||
if (r) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
|
||||||
USB0.D0FIFOSEL.WORD = 0;
|
|
||||||
TU_LOG1("< %d %x %x %d\r\n", rem, ctr, *get_pipectr(num), r);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pipe->addr = 0;
|
|
||||||
pipe->remaining = 0;
|
|
||||||
USB0.D0FIFOSEL.WORD = 0;
|
|
||||||
dcd_event_xfer_complete(rhport, pipe->ep, pipe->length,
|
|
||||||
XFER_RESULT_SUCCESS, true);
|
|
||||||
TU_LOG1("cE\r\n");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static void process_pipe_bemp(uint8_t rhport, unsigned num)
|
|
||||||
{
|
|
||||||
pipe_state_t *pipe = &_dcd.pipe[num];
|
|
||||||
const unsigned rem = pipe->remaining;
|
|
||||||
if (rem) {
|
|
||||||
USB0.PIPESEL.WORD = num;
|
|
||||||
const unsigned mps = USB0.PIPEMAXP.WORD;
|
|
||||||
unsigned ctr = select_pipe(num, USB_FIFOSEL_MBW_16);
|
|
||||||
int r = write_fifo2(&USB0.D0FIFO.WORD, pipe, mps);
|
|
||||||
if (r) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
|
||||||
USB0.D0FIFOSEL.WORD = 0;
|
|
||||||
TU_LOG1("< %d %x %x %d\r\n", rem, ctr, *get_pipectr(num), r);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (*get_pipectr(num) & USB_PIPECTR_INBUFM) {
|
|
||||||
TU_LOG1("< SKIP\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pipe->addr = 0;
|
|
||||||
pipe->remaining = 0;
|
|
||||||
USB0.D0FIFOSEL.WORD = 0;
|
|
||||||
dcd_event_xfer_complete(rhport, pipe->ep, pipe->length,
|
|
||||||
XFER_RESULT_SUCCESS, true);
|
|
||||||
TU_LOG1("cE\r\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void process_pipe_brdy(uint8_t rhport, unsigned num)
|
static void process_pipe_brdy(uint8_t rhport, unsigned num)
|
||||||
{
|
{
|
||||||
const unsigned ctr = select_pipe(num, USB_FIFOSEL_MBW_8);
|
|
||||||
const unsigned len = ctr & USB_FIFOCTR_DTLN;
|
|
||||||
const unsigned mps = USB0.PIPEMAXP.WORD;
|
|
||||||
pipe_state_t *pipe = &_dcd.pipe[num];
|
pipe_state_t *pipe = &_dcd.pipe[num];
|
||||||
// TU_LOG1("> %d %x %x\r\n", num, USB0.D0FIFOSEL.WORD, ctr);
|
if (!tu_edpt_dir(pipe->ep)) {
|
||||||
int cplt = read_fifo(&USB0.D0FIFO.WORD, pipe, mps, len);
|
const unsigned ctr = select_pipe(num, USB_FIFOSEL_MBW_8);
|
||||||
if (cplt || (len < mps)) {
|
const unsigned len = ctr & USB_FIFOCTR_DTLN;
|
||||||
if (2 != cplt) {
|
const unsigned mps = USB0.PIPEMAXP.WORD;
|
||||||
USB0.D0FIFO.WORD = USB_FIFOCTR_BCLR;
|
int cplt = read_fifo(&USB0.D0FIFO.WORD, pipe, mps, len);
|
||||||
|
if (cplt || (len < mps)) {
|
||||||
|
if (2 != cplt) {
|
||||||
|
USB0.D0FIFO.WORD = USB_FIFOCTR_BCLR;
|
||||||
|
}
|
||||||
|
USB0.D0FIFOSEL.WORD = 0;
|
||||||
|
dcd_event_xfer_complete(rhport, pipe->ep,
|
||||||
|
pipe->length - pipe->remaining,
|
||||||
|
XFER_RESULT_SUCCESS, true);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
USB0.D0FIFOSEL.WORD = 0;
|
USB0.D0FIFOSEL.WORD = 0;
|
||||||
dcd_event_xfer_complete(rhport, pipe->ep,
|
|
||||||
pipe->length - pipe->remaining,
|
|
||||||
XFER_RESULT_SUCCESS, true);
|
|
||||||
// TU_LOG1("c\r\n");
|
|
||||||
} else {
|
} else {
|
||||||
|
select_pipe(num, USB_FIFOSEL_MBW_16);
|
||||||
|
const unsigned mps = USB0.PIPEMAXP.WORD;
|
||||||
|
unsigned rem = pipe->remaining;
|
||||||
|
rem -= TU_MIN(rem, mps);
|
||||||
|
pipe->remaining = rem;
|
||||||
|
if (rem) {
|
||||||
|
int r = 0;
|
||||||
|
r = write_fifo(&USB0.D0FIFO.WORD, pipe, mps);
|
||||||
|
if (r) USB0.D0FIFOCTR.WORD = USB_FIFOCTR_BVAL;
|
||||||
|
USB0.D0FIFOSEL.WORD = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
USB0.D0FIFOSEL.WORD = 0;
|
USB0.D0FIFOSEL.WORD = 0;
|
||||||
|
pipe->addr = 0;
|
||||||
|
pipe->remaining = 0;
|
||||||
|
dcd_event_xfer_complete(rhport, pipe->ep, pipe->length,
|
||||||
|
XFER_RESULT_SUCCESS, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +478,7 @@ static void process_bus_reset(uint8_t rhport)
|
||||||
*ctr = USB_PIPECTR_ACLRM;
|
*ctr = USB_PIPECTR_ACLRM;
|
||||||
*ctr = 0;
|
*ctr = 0;
|
||||||
++ctr;
|
++ctr;
|
||||||
*tre = (1u<<8);
|
*tre = TU_BIT(8);
|
||||||
tre += 2;
|
tre += 2;
|
||||||
}
|
}
|
||||||
for (int i = 6; i <= 9; ++i) {
|
for (int i = 6; i <= 9; ++i) {
|
||||||
|
@ -583,7 +490,7 @@ static void process_bus_reset(uint8_t rhport)
|
||||||
}
|
}
|
||||||
tu_varclr(&_dcd);
|
tu_varclr(&_dcd);
|
||||||
dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true);
|
dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true);
|
||||||
TU_LOG1("R\r\n");
|
// TU_LOG1("R\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_set_address(uint8_t rhport)
|
static void process_set_address(uint8_t rhport)
|
||||||
|
@ -626,7 +533,6 @@ void dcd_init(uint8_t rhport)
|
||||||
USB0.BEMPENB.WORD = 1;
|
USB0.BEMPENB.WORD = 1;
|
||||||
USB0.BRDYENB.WORD = 1;
|
USB0.BRDYENB.WORD = 1;
|
||||||
|
|
||||||
TU_LOG1("INIT\r\n");
|
|
||||||
if (USB0.INTSTS0.BIT.VBSTS) {
|
if (USB0.INTSTS0.BIT.VBSTS) {
|
||||||
dcd_connect(rhport);
|
dcd_connect(rhport);
|
||||||
}
|
}
|
||||||
|
@ -676,8 +582,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
|
|
||||||
const unsigned ep_addr = ep_desc->bEndpointAddress;
|
const unsigned ep_addr = ep_desc->bEndpointAddress;
|
||||||
const unsigned epn = ep_addr & 0xFu;
|
const unsigned epn = tu_edpt_number(ep_addr);
|
||||||
const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
|
const unsigned dir = tu_edpt_dir(ep_addr);
|
||||||
const unsigned xfer = ep_desc->bmAttributes.xfer;
|
const unsigned xfer = ep_desc->bmAttributes.xfer;
|
||||||
|
|
||||||
const unsigned mps = ep_desc->wMaxPacketSize.size;
|
const unsigned mps = ep_desc->wMaxPacketSize.size;
|
||||||
|
@ -692,6 +598,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||||
_dcd.ep[dir][epn] = num;
|
_dcd.ep[dir][epn] = num;
|
||||||
|
|
||||||
/* setup pipe */
|
/* setup pipe */
|
||||||
|
dcd_int_disable(rhport);
|
||||||
USB0.PIPESEL.WORD = num;
|
USB0.PIPESEL.WORD = num;
|
||||||
USB0.PIPEMAXP.WORD = mps;
|
USB0.PIPEMAXP.WORD = mps;
|
||||||
volatile uint16_t *ctr = get_pipectr(num);
|
volatile uint16_t *ctr = get_pipectr(num);
|
||||||
|
@ -705,17 +612,14 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||||
} else {
|
} else {
|
||||||
cfg |= USB_PIPECFG_ISO | USB_PIPECFG_DBLB;
|
cfg |= USB_PIPECFG_ISO | USB_PIPECFG_DBLB;
|
||||||
}
|
}
|
||||||
USB0.PIPECFG.WORD = cfg;
|
USB0.PIPECFG.WORD = cfg;
|
||||||
if (dir) {
|
USB0.BRDYSTS.WORD = 0x1FFu ^ TU_BIT(num);
|
||||||
USB0.BEMPENB.WORD |= 1u << num;
|
USB0.BRDYENB.WORD |= TU_BIT(num);
|
||||||
|
if (dir || (xfer != TUSB_XFER_BULK)) {
|
||||||
*ctr = USB_PIPECTR_PID_BUF;
|
*ctr = USB_PIPECTR_PID_BUF;
|
||||||
} else {
|
|
||||||
USB0.BRDYENB.WORD |= 1u << num;
|
|
||||||
if (xfer != TUSB_XFER_BULK) {
|
|
||||||
*ctr = USB_PIPECTR_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", USB0.PIPESEL.WORD, USB0.PIPECFG.WORD, USB0.PIPEMAXP.WORD);
|
||||||
|
dcd_int_enable(rhport);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -723,12 +627,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||||
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
||||||
{
|
{
|
||||||
(void)rhport;
|
(void)rhport;
|
||||||
const unsigned epn = ep_addr & 0xFu;
|
const unsigned epn = tu_edpt_number(ep_addr);
|
||||||
const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
|
const unsigned dir = tu_edpt_dir(ep_addr);
|
||||||
const unsigned num = _dcd.ep[dir][epn];
|
const unsigned num = _dcd.ep[dir][epn];
|
||||||
|
|
||||||
USB0.BEMPENB.WORD &= ~(1u << num);
|
USB0.BRDYENB.WORD &= ~TU_BIT(num);
|
||||||
USB0.BRDYENB.WORD &= ~(1u << num);
|
|
||||||
volatile uint16_t *ctr = get_pipectr(num);
|
volatile uint16_t *ctr = get_pipectr(num);
|
||||||
*ctr = 0;
|
*ctr = 0;
|
||||||
USB0.PIPESEL.WORD = num;
|
USB0.PIPESEL.WORD = num;
|
||||||
|
@ -740,7 +643,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
||||||
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
|
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
|
||||||
{
|
{
|
||||||
bool r;
|
bool r;
|
||||||
const unsigned epn = ep_addr & 0xFu;
|
const unsigned epn = tu_edpt_number(ep_addr);
|
||||||
dcd_int_disable(rhport);
|
dcd_int_disable(rhport);
|
||||||
if (0 == epn) {
|
if (0 == epn) {
|
||||||
r = process_edpt0_xfer(rhport, ep_addr, buffer, total_bytes);
|
r = process_edpt0_xfer(rhport, ep_addr, buffer, total_bytes);
|
||||||
|
@ -816,17 +719,10 @@ void dcd_int_handler(uint8_t rhport)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is0 & USB_IS0_BEMP) {
|
if (is0 & USB_IS0_BEMP) {
|
||||||
const unsigned m = USB0.BEMPENB.WORD;
|
const unsigned s = USB0.BEMPSTS.WORD;
|
||||||
unsigned s = USB0.BEMPSTS.WORD & m;
|
|
||||||
USB0.BEMPSTS.WORD = 0;
|
USB0.BEMPSTS.WORD = 0;
|
||||||
if (s & 1) {
|
if (s & 1) {
|
||||||
process_edpt0_bemp(rhport);
|
process_edpt0_bemp(rhport);
|
||||||
s &= ~1;
|
|
||||||
}
|
|
||||||
while (s) {
|
|
||||||
const unsigned num = __builtin_ctz(s);
|
|
||||||
process_pipe_bemp(rhport, num);
|
|
||||||
s &= ~(1<<num);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is0 & USB_IS0_BRDY) {
|
if (is0 & USB_IS0_BRDY) {
|
||||||
|
@ -840,7 +736,7 @@ void dcd_int_handler(uint8_t rhport)
|
||||||
while (s) {
|
while (s) {
|
||||||
const unsigned num = __builtin_ctz(s);
|
const unsigned num = __builtin_ctz(s);
|
||||||
process_pipe_brdy(rhport, num);
|
process_pipe_brdy(rhport, num);
|
||||||
s &= ~(1<<num);
|
s &= ~TU_BIT(num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue