minor update dcd nrf5x

add walkaround CDC buffer for nrf52 (due to not able to NAK OUT packet)
This commit is contained in:
hathach 2018-04-12 00:33:31 +07:00
parent 7faceeb02d
commit df367bac54
2 changed files with 39 additions and 47 deletions

View File

@ -66,11 +66,17 @@ typedef struct {
}cdcd_data_t; }cdcd_data_t;
// TODO multiple rhport // TODO multiple rhport
CFG_TUSB_ATTR_USBRAM ATTR_ALIGNED(4) uint8_t _tmp_rx_buf[64]; #ifdef NRF52840_XXAA
CFG_TUSB_ATTR_USBRAM ATTR_ALIGNED(4) uint8_t _tmp_tx_buf[64]; // FIXME nrf52 OUT bug ( Controller ACK data even we didn't prepare transfer )
CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _tmp_rx_buf[1024];
#else
CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _tmp_rx_buf[64];
#endif
CFG_TUSB_ATTR_USBRAM CFG_TUSB_MEM_ALIGN uint8_t _tmp_tx_buf[64];
FIFO_DEF(_rx_ff, CFG_TUD_CDC_BUFSIZE, uint8_t, true); FIFO_DEF(_rx_ff, CFG_TUD_CDC_BUFSIZE, uint8_t, true);
FIFO_DEF(_tx_ff, CFG_TUD_CDC_BUFSIZE, uint8_t, true); FIFO_DEF(_tx_ff, CFG_TUD_CDC_BUFSIZE, uint8_t, false);
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION // INTERNAL OBJECT & FUNCTION DECLARATION
@ -83,7 +89,7 @@ STATIC_VAR cdcd_data_t cdcd_data[CONTROLLER_DEVICE_NUMBER];
bool tud_n_cdc_connected(uint8_t rhport) bool tud_n_cdc_connected(uint8_t rhport)
{ {
// Either RTS or DTR active considered as connected // Either RTS or DTR active considered as connected
return cdcd_data[rhport].line_state; return (cdcd_data[rhport].line_state != 0);
} }
uint32_t tud_n_cdc_available(uint8_t rhport) uint32_t tud_n_cdc_available(uint8_t rhport)
@ -104,7 +110,7 @@ uint32_t tud_n_cdc_read(uint8_t rhport, void* buffer, uint32_t bufsize)
uint32_t tud_n_cdc_write_char(uint8_t rhport, char ch) uint32_t tud_n_cdc_write_char(uint8_t rhport, char ch)
{ {
return fifo_write(&_tx_ff, &ch); return fifo_write(&_tx_ff, &ch) ? 1 : 0;
} }
uint32_t tud_n_cdc_write(uint8_t rhport, void const* buffer, uint32_t bufsize) uint32_t tud_n_cdc_write(uint8_t rhport, void const* buffer, uint32_t bufsize)
@ -281,7 +287,7 @@ tusb_error_t cdcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, tusb_event_t event, u
fifo_write_n(&_rx_ff, _tmp_rx_buf, xferred_bytes); fifo_write_n(&_rx_ff, _tmp_rx_buf, xferred_bytes);
// preparing for next // preparing for next
TU_ASSERT(dcd_edpt_xfer(rhport, p_cdc->ep_out, _tmp_rx_buf, sizeof(_tmp_rx_buf)), TUSB_ERROR_DCD_EDPT_XFER); TU_ASSERT( dcd_edpt_xfer(rhport, p_cdc->ep_out, _tmp_rx_buf, sizeof(_tmp_rx_buf)), TUSB_ERROR_DCD_EDPT_XFER );
// fire callback // fire callback
if (tud_cdc_rx_cb) tud_cdc_rx_cb(rhport); if (tud_cdc_rx_cb) tud_cdc_rx_cb(rhport);

View File

@ -55,7 +55,7 @@ enum
MAX_PACKET_SIZE = 64, MAX_PACKET_SIZE = 64,
// Mask of all END event (IN & OUT) for all endpoints. ENDEPIN0-7, ENDEPOUT0-7, ENDISOIN, ENDISOOUT // Mask of all END event (IN & OUT) for all endpoints. ENDEPIN0-7, ENDEPOUT0-7, ENDISOIN, ENDISOOUT
EDPT_END_ALL_MASK = 0x1FFBFC EDPT_END_ALL_MASK = 0x1FFBFCUL
}; };
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
@ -139,7 +139,7 @@ void dcd_set_config (uint8_t rhport, uint8_t config_num)
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
static void edpt_dma_start(uint8_t epnum, uint8_t dir) static void edpt_dma_start(uint8_t epnum, uint8_t dir)
{ {
// Only one dma could be active // Only one dma could be active, TODO resolve when this is called in ISR and dma is running
while ( _dcd.dma_running ) { } while ( _dcd.dma_running ) { }
_dcd.dma_running = true; _dcd.dma_running = true;
@ -229,16 +229,17 @@ bool dcd_control_xfer (uint8_t rhport, tusb_dir_t dir, uint8_t * buffer, uint16_
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* /*
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
static inline nom_xfer_t* get_td(uint8_t epnum, uint8_t dir)
{
return &_dcd.xfer[epnum-1][dir];
}
static void normal_xact_start(uint8_t epnum, uint8_t dir) static void normal_xact_start(uint8_t epnum, uint8_t dir)
{ {
nom_xfer_t* xfer = &_dcd.xfer[epnum-1][dir];
// Each transaction is up to Max Packet Size
uint8_t const xact_len = min16_of(xfer->total_len - xfer->actual_len, xfer->mps);
if ( dir == TUSB_DIR_OUT ) if ( dir == TUSB_DIR_OUT )
{ {
// Errata 135: HW issue on nrf5284 sample, SIZE.EPOUT won't trigger ACK as spec // Errata : HW issue on nrf5284 sample, SIZE.EPOUT won't trigger ACK as spec
// use the back door interface as sdk for walk around // use the back door interface as sdk for walk around
if ( nrf_drv_usbd_errata_sizeepout_rw() ) if ( nrf_drv_usbd_errata_sizeepout_rw() )
{ {
@ -254,6 +255,11 @@ static void normal_xact_start(uint8_t epnum, uint8_t dir)
} }
}else }else
{ {
nom_xfer_t* xfer = get_td(epnum, dir);
// Each transaction is up to Max Packet Size
uint8_t const xact_len = min16_of(xfer->total_len - xfer->actual_len, xfer->mps);
NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer; NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer;
NRF_USBD->EPIN[epnum].MAXCNT = xact_len; NRF_USBD->EPIN[epnum].MAXCNT = xact_len;
@ -293,7 +299,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
uint8_t const epnum = edpt_number(ep_addr); uint8_t const epnum = edpt_number(ep_addr);
uint8_t const dir = edpt_dir(ep_addr); uint8_t const dir = edpt_dir(ep_addr);
nom_xfer_t* xfer = &_dcd.xfer[epnum-1][dir]; nom_xfer_t* xfer = get_td(epnum, dir);
xfer->buffer = buffer; xfer->buffer = buffer;
xfer->total_len = total_bytes; xfer->total_len = total_bytes;
@ -307,14 +313,6 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
normal_xact_start(epnum, dir); normal_xact_start(epnum, dir);
// if ( dir == TUSB_DIR_OUT )
// {
// // TODO
// }else
// {
//
// }
return true; return true;
} }
@ -352,7 +350,7 @@ bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr)
uint8_t const epnum = edpt_number(ep_addr); uint8_t const epnum = edpt_number(ep_addr);
uint8_t const dir = edpt_dir(ep_addr); uint8_t const dir = edpt_dir(ep_addr);
nom_xfer_t* xfer = &_dcd.xfer[epnum-1][dir]; nom_xfer_t* xfer = get_td(epnum, dir);
return xfer->actual_len < xfer->total_len; return xfer->actual_len < xfer->total_len;
} }
@ -451,7 +449,7 @@ void USBD_IRQHandler(void)
{ {
if ( BIT_TEST_(data_status, epnum ) ) if ( BIT_TEST_(data_status, epnum ) )
{ {
nom_xfer_t* xfer = &_dcd.xfer[epnum-1][TUSB_DIR_IN]; nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_IN);
xfer->actual_len += NRF_USBD->EPIN[epnum].MAXCNT; xfer->actual_len += NRF_USBD->EPIN[epnum].MAXCNT;
@ -472,7 +470,7 @@ void USBD_IRQHandler(void)
{ {
if ( BIT_TEST_(data_status, 16+epnum ) ) if ( BIT_TEST_(data_status, 16+epnum ) )
{ {
nom_xfer_t* xfer = &_dcd.xfer[epnum-1][TUSB_DIR_OUT]; nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_OUT);
uint8_t const xact_len = NRF_USBD->SIZE.EPOUT[epnum]; uint8_t const xact_len = NRF_USBD->SIZE.EPOUT[epnum];
@ -493,27 +491,15 @@ void USBD_IRQHandler(void)
{ {
if ( BIT_TEST_(int_status, USBD_INTEN_ENDEPOUT0_Pos+epnum) ) if ( BIT_TEST_(int_status, USBD_INTEN_ENDEPOUT0_Pos+epnum) )
{ {
nom_xfer_t* xfer = &_dcd.xfer[epnum-1][TUSB_DIR_OUT]; nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_OUT);
uint8_t const xact_len = NRF_USBD->EPOUT[epnum].AMOUNT;
// Transfer complete if transaction len < Max Packet Size or total len is transferred // Transfer complete if transaction len < Max Packet Size or total len is transferred
if ( (NRF_USBD->EPOUT[epnum].AMOUNT == xfer->mps) && (xfer->actual_len < xfer->total_len) ) if ( (xact_len == xfer->mps) && (xfer->actual_len < xfer->total_len) )
{ {
// Allow Host -> Endpoint // Prepare for more data from Host -> Endpoint
normal_xact_start(epnum, TUSB_DIR_OUT);
// HW issue on nrf5284 sample, SIZE.EPOUT won't trigger ACK as spec
// use the back door interface as sdk for walk around
if ( nrf_drv_usbd_errata_sizeepout_rw() )
{
*((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + 2*epnum;
*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0;
(void) (((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
}
else
{
// Overwrite size will allow hw to accept data
NRF_USBD->SIZE.EPOUT[epnum] = 0;
__ISB(); __DSB();
}
}else }else
{ {
xfer->total_len = xfer->actual_len; xfer->total_len = xfer->actual_len;
@ -535,9 +521,9 @@ void USBD_IRQHandler(void)
if ( nrf_drv_usbd_errata_104() ) if ( nrf_drv_usbd_errata_104() )
{ {
// Check all the queued IN transfer, retire all transfer if 10 frames has passed // Check all the queued IN transfer, retire all transfer if 10 frames has passed
for (int i=0; i<7; i++) for (int ep=1; ep<= 8; ep++)
{ {
nom_xfer_t* xfer = &_dcd.xfer[i][TUSB_DIR_IN]; nom_xfer_t* xfer = get_td(ep, TUSB_DIR_IN);
if (xfer->actual_len < xfer->total_len) if (xfer->actual_len < xfer->total_len)
{ {
@ -555,7 +541,7 @@ void USBD_IRQHandler(void)
if (diff > 10) if (diff > 10)
{ {
xfer->actual_len = xfer->total_len; xfer->actual_len = xfer->total_len;
dcd_xfer_complete(0, (i+1) | TUSB_DIR_IN_MASK, xfer->actual_len, true); dcd_xfer_complete(0, ep | TUSB_DIR_IN_MASK, xfer->actual_len, true);
} }
} }
} }