when I use usb to transfer, i fine many datas are lost.Is it because the DMA size is too small?Where can i see the dma size?(In nrf52833/examples/peripheral/usb_cdc_acm ).Thanks.
when I use usb to transfer, i fine many datas are lost.Is it because the DMA size is too small?Where can i see the dma size?(In nrf52833/examples/peripheral/usb_cdc_acm ).Thanks.
I think you should look at the return codes of app_usbd_cdc_acm_write() and app_usbd_cdc_acm_read(). I suspect data is lost because error codes are ignored or not handled (e.g. you should buffer data and retry if the return code is not success).
Also check out the documentation and another devzone case below:
https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/lib_usbd_class_cdc.html
https://devzone.nordicsemi.com/f/nordic-q-a/23265/max-frame-size-usb-bulk-transmision-increase-speed
Best regards,
Kenneth
When I use Putty to send data to the NRF52833 through usb,it keeps reminding "
static void usbd_dmareq_process(void)
{
if (!m_dma_pending)
{
uint32_t req;
while (0 != (req = m_ep_dma_waiting & m_ep_ready))
{
uint8_t pos;
if (NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST && ((req & USBD_EPISO_BIT_MASK) != 0))
{
pos = usbd_dma_scheduler_algorithm(req & USBD_EPISO_BIT_MASK);
}
else
{
pos = usbd_dma_scheduler_algorithm(req);
}
nrfx_usbd_ep_t ep = bit2ep(pos);
usbd_ep_state_t * p_state = ep_state_access(ep);
nrfx_usbd_ep_transfer_t transfer;
bool continue_transfer;
NRFX_STATIC_ASSERT(offsetof(usbd_ep_state_t, handler.feeder) ==
offsetof(usbd_ep_state_t, handler.consumer));
NRFX_ASSERT((p_state->handler.feeder) != NULL);
if (NRF_USBD_EPIN_CHECK(ep))
{
/* Device -> Host */
continue_transfer = p_state->handler.feeder(
&transfer,
p_state->p_context,
p_state->max_packet_size);
if (!continue_transfer)
{
p_state->handler.feeder = NULL;
}
}
else
{
/* Host -> Device */
const size_t rx_size = nrfx_usbd_epout_size_get(ep);
continue_transfer = p_state->handler.consumer(
&transfer,
p_state->p_context,
p_state->max_packet_size,
rx_size);
if (transfer.p_data.rx == NULL)
{
/* Dropping transfer - allow processing */
NRFX_ASSERT(transfer.size == 0);
}
else if (transfer.size < rx_size)
{
NRFX_LOG_DEBUG("Endpoint %x overload (r: %u, e: %u)", ep, rx_size, transfer.size);
p_state->status = NRFX_USBD_EP_OVERLOAD;
(void)(NRFX_ATOMIC_FETCH_AND(&m_ep_dma_waiting, ~(1U << pos)));
NRFX_USBD_EP_TRANSFER_EVENT(evt, ep, NRFX_USBD_EP_OVERLOAD);
m_event_handler(&evt);
/* This endpoint will not be transmitted now, repeat the loop */
continue;
}
else
{
/* Nothing to do - only check integrity if assertions are enabled */
NRFX_ASSERT(transfer.size == rx_size);
}
if (!continue_transfer)
{
p_state->handler.consumer = NULL;
}
}
usbd_dma_pending_set();
m_ep_ready &= ~(1U << pos);
if (NRFX_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
{
NRFX_LOG_DEBUG(
"USB DMA process: Starting transfer on EP: %x, size: %u",
ep,
transfer.size);
}
/* Update number of currently transferred bytes */
p_state->transfer_cnt += transfer.size;
/* Start transfer to the endpoint buffer */
nrf_usbd_ep_easydma_set(ep, transfer.p_data.addr, (uint32_t)transfer.size);
if (nrfx_usbd_errata_104())
{
uint32_t cnt_end = (uint32_t)(-1);
do
{
uint32_t cnt = (uint32_t)(-1);
do
{
nrf_usbd_event_clear(NRF_USBD_EVENT_STARTED);
usbd_dma_start(ep);
nrfx_systick_delay_us(2);
++cnt;
}while (!nrf_usbd_event_check(NRF_USBD_EVENT_STARTED));
if (cnt)
{
NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" DMA restarted: %u times", cnt);
}
nrfx_systick_delay_us(30);
while (0 == (0x20 & *((volatile uint32_t *)(NRF_USBD_BASE + 0x474))))
{
nrfx_systick_delay_us(2);
}
nrfx_systick_delay_us(1);
++cnt_end;
} while (!nrf_usbd_event_check(nrfx_usbd_ep_to_endevent(ep)));
if (cnt_end)
{
NRFX_USBD_LOG_PROTO1_FIX_PRINTF(" DMA fully restarted: %u times", cnt_end);
}
}
else
{
usbd_dma_start(ep);
/* There is a lot of USBD registers that cannot be accessed during EasyDMA transfer.
* This is quick fix to maintain stability of the stack.
* It cost some performance but makes stack stable. */
while (!nrf_usbd_event_check(nrfx_usbd_ep_to_endevent(ep)) &&
!nrf_usbd_event_check(NRF_USBD_EVENT_USBRESET))
{
/* Empty */
}
}
if (NRFX_USBD_DMAREQ_PROCESS_DEBUG)
{
NRFX_LOG_DEBUG("USB DMA process - finishing");
}
/* Transfer started - exit the loop */
break;
}
}
else
{
if (NRFX_USBD_DMAREQ_PROCESS_DEBUG)
{
NRFX_LOG_DEBUG("USB DMA process - EasyDMA busy");
}
}
}Please see my comments on how to use the high level api to buffer and send/receive data. I do not think it is a good idea to start modify or play around with the low level usb drivers.
I can see that the code you refer to have the following define:
#ifndef NRFX_USBD_EARLY_DMA_PROCESS /* Try to process DMA request when endpoint transmission has been detected * and just after last EasyDMA has been processed. * It speeds up the transmission a little (about 10% measured) * with a cost of more CPU power used. */ #define NRFX_USBD_EARLY_DMA_PROCESS 1 #endif
Please see my comments on how to use the high level api to buffer and send/receive data. I do not think it is a good idea to start modify or play around with the low level usb drivers.
I can see that the code you refer to have the following define:
#ifndef NRFX_USBD_EARLY_DMA_PROCESS /* Try to process DMA request when endpoint transmission has been detected * and just after last EasyDMA has been processed. * It speeds up the transmission a little (about 10% measured) * with a cost of more CPU power used. */ #define NRFX_USBD_EARLY_DMA_PROCESS 1 #endif