mirror of
https://github.com/hathach/tinyusb.git
synced 2025-01-31 05:52:55 +08:00
nrf5x: clean up dcd, add comment
This commit is contained in:
parent
7219ef8ed6
commit
00694b56c5
@ -70,12 +70,10 @@ typedef struct {
|
||||
uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid)
|
||||
uint8_t ep2drv[2][8]; // map endpoint to driver ( 0xff is invalid )
|
||||
|
||||
|
||||
}usbd_device_t;
|
||||
|
||||
static usbd_device_t _usbd_dev;
|
||||
|
||||
|
||||
// Auto descriptor is enabled, descriptor set point to auto generated one
|
||||
#if CFG_TUD_DESC_AUTO
|
||||
extern tud_desc_set_t const _usbd_auto_desc_set;
|
||||
|
@ -64,9 +64,7 @@ enum
|
||||
USBD_INTENCLR_ENDISOIN_Msk | USBD_INTEN_ENDISOOUT_Msk
|
||||
};
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* VARIABLE DECLARATION
|
||||
*------------------------------------------------------------------*/
|
||||
// Transfer descriptor
|
||||
typedef struct
|
||||
{
|
||||
uint8_t* buffer;
|
||||
@ -78,35 +76,119 @@ typedef struct
|
||||
// indicate packet is already ACK
|
||||
volatile bool data_received;
|
||||
|
||||
} nom_xfer_t;
|
||||
} xfer_td_t;
|
||||
|
||||
/*static*/ struct
|
||||
// Data for managing dcd
|
||||
static struct
|
||||
{
|
||||
// All 8 endpoints including control IN & OUT (offset 1)
|
||||
nom_xfer_t xfer[8][2];
|
||||
xfer_td_t xfer[8][2];
|
||||
|
||||
// Only one DMA can run at a time
|
||||
volatile bool dma_running;
|
||||
}_dcd;
|
||||
|
||||
void bus_reset(void)
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Control / Bulk / Interrupt (CBI) Transfer
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
// helper to start DMA
|
||||
static void edpt_dma_start(volatile uint32_t* reg_startep)
|
||||
{
|
||||
for(int i=0; i<8; i++)
|
||||
// Only one dma can be active
|
||||
if ( _dcd.dma_running )
|
||||
{
|
||||
NRF_USBD->TASKS_STARTEPIN[i] = 0;
|
||||
NRF_USBD->TASKS_STARTEPOUT[i] = 0;
|
||||
if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)
|
||||
{
|
||||
// If called within ISR, use usbd task to defer later
|
||||
usbd_defer_func( (osal_task_func_t) edpt_dma_start, (void*) reg_startep, true );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise simply block wait
|
||||
while ( _dcd.dma_running ) { }
|
||||
}
|
||||
}
|
||||
|
||||
NRF_USBD->TASKS_STARTISOIN = 0;
|
||||
NRF_USBD->TASKS_STARTISOOUT = 0;
|
||||
_dcd.dma_running = true;
|
||||
|
||||
tu_varclr(&_dcd);
|
||||
_dcd.xfer[0][TUSB_DIR_IN].mps = MAX_PACKET_SIZE;
|
||||
_dcd.xfer[0][TUSB_DIR_OUT].mps = MAX_PACKET_SIZE;
|
||||
(*reg_startep) = 1;
|
||||
__ISB(); __DSB();
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Controller API
|
||||
*------------------------------------------------------------------*/
|
||||
// DMA is complete
|
||||
static void edpt_dma_end(void)
|
||||
{
|
||||
TU_ASSERT(_dcd.dma_running, );
|
||||
_dcd.dma_running = false;
|
||||
}
|
||||
|
||||
// helper getting td
|
||||
static inline xfer_td_t* get_td(uint8_t epnum, uint8_t dir)
|
||||
{
|
||||
return &_dcd.xfer[epnum][dir];
|
||||
}
|
||||
|
||||
/*------------- CBI OUT Transfer -------------*/
|
||||
|
||||
// Prepare for a CBI transaction OUT, call at the start
|
||||
// Allow ACK incoming data
|
||||
static void xact_out_prepare(uint8_t epnum)
|
||||
{
|
||||
if ( epnum == 0 )
|
||||
{
|
||||
NRF_USBD->TASKS_EP0RCVOUT = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write zero value to SIZE register will allow hw to ACK (accept data)
|
||||
// If it is not already done by DMA
|
||||
NRF_USBD->SIZE.EPOUT[epnum] = 0;
|
||||
}
|
||||
|
||||
__ISB(); __DSB();
|
||||
}
|
||||
|
||||
// Start DMA to move data from Endpoint -> RAM
|
||||
static void xact_out_dma(uint8_t epnum)
|
||||
{
|
||||
xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT);
|
||||
|
||||
uint8_t const xact_len = NRF_USBD->SIZE.EPOUT[epnum];
|
||||
|
||||
// Trigger DMA move data from Endpoint -> SRAM
|
||||
NRF_USBD->EPOUT[epnum].PTR = (uint32_t) xfer->buffer;
|
||||
NRF_USBD->EPOUT[epnum].MAXCNT = xact_len;
|
||||
|
||||
edpt_dma_start(&NRF_USBD->TASKS_STARTEPOUT[epnum]);
|
||||
|
||||
xfer->buffer += xact_len;
|
||||
xfer->actual_len += xact_len;
|
||||
}
|
||||
|
||||
/*------------- CBI IN Transfer -------------*/
|
||||
|
||||
// Prepare for a CBI transaction IN, call at the start
|
||||
// it start DMA to transfer data from RAM -> Endpoint
|
||||
static void xact_in_prepare(uint8_t epnum)
|
||||
{
|
||||
xfer_td_t* xfer = get_td(epnum, TUSB_DIR_IN);
|
||||
|
||||
// Each transaction is up to Max Packet Size
|
||||
uint8_t const xact_len = tu_min16(xfer->total_len - xfer->actual_len, xfer->mps);
|
||||
|
||||
NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer;
|
||||
NRF_USBD->EPIN[epnum].MAXCNT = xact_len;
|
||||
|
||||
xfer->buffer += xact_len;
|
||||
|
||||
edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[epnum]);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Tinyusb DCD API
|
||||
//--------------------------------------------------------------------+
|
||||
bool dcd_init (uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
@ -135,109 +217,6 @@ void dcd_set_config (uint8_t rhport, uint8_t config_num)
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/* Control
|
||||
*------------------------------------------------------------------*/
|
||||
static void edpt_dma_start(volatile uint32_t* reg_startep)
|
||||
{
|
||||
// Only one dma can be active
|
||||
if ( _dcd.dma_running )
|
||||
{
|
||||
if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)
|
||||
{
|
||||
// If called within ISR, use usbd task to defer later
|
||||
usbd_defer_func( (osal_task_func_t) edpt_dma_start, (void*) reg_startep, true );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise simply block wait
|
||||
while ( _dcd.dma_running ) { }
|
||||
}
|
||||
}
|
||||
|
||||
_dcd.dma_running = true;
|
||||
|
||||
(*reg_startep) = 1;
|
||||
__ISB(); __DSB();
|
||||
}
|
||||
|
||||
static void edpt_dma_end(void)
|
||||
{
|
||||
TU_ASSERT(_dcd.dma_running, );
|
||||
|
||||
_dcd.dma_running = false;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/*
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
static inline nom_xfer_t* get_td(uint8_t epnum, uint8_t dir)
|
||||
{
|
||||
return &_dcd.xfer[epnum][dir];
|
||||
}
|
||||
|
||||
/*------------- Bulk/Int OUT transfer -------------*/
|
||||
|
||||
/**
|
||||
* Prepare Bulk/Int out transaction, Endpoint start to accept/ACK Data
|
||||
* @param epnum
|
||||
*/
|
||||
static void xact_out_prepare(uint8_t epnum)
|
||||
{
|
||||
if ( epnum == 0 )
|
||||
{
|
||||
NRF_USBD->TASKS_EP0RCVOUT = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write zero value to SIZE register will allow hw to ACK (accept data)
|
||||
// If it is not already done by DMA
|
||||
NRF_USBD->SIZE.EPOUT[epnum] = 0;
|
||||
}
|
||||
|
||||
__ISB(); __DSB();
|
||||
}
|
||||
|
||||
static void xact_out_dma(uint8_t epnum)
|
||||
{
|
||||
nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_OUT);
|
||||
|
||||
uint8_t const xact_len = NRF_USBD->SIZE.EPOUT[epnum];
|
||||
|
||||
// Trigger DMA move data from Endpoint -> SRAM
|
||||
NRF_USBD->EPOUT[epnum].PTR = (uint32_t) xfer->buffer;
|
||||
NRF_USBD->EPOUT[epnum].MAXCNT = xact_len;
|
||||
|
||||
edpt_dma_start(&NRF_USBD->TASKS_STARTEPOUT[epnum]);
|
||||
|
||||
xfer->buffer += xact_len;
|
||||
xfer->actual_len += xact_len;
|
||||
}
|
||||
|
||||
|
||||
/*------------- Bulk/Int IN transfer -------------*/
|
||||
|
||||
/**
|
||||
* Prepare Bulk/Int in transaction, use DMA to transfer data from Memory -> Endpoint
|
||||
* @param epnum
|
||||
*/
|
||||
static void xact_in_prepare(uint8_t epnum)
|
||||
{
|
||||
nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_IN);
|
||||
|
||||
// Each transaction is up to Max Packet Size
|
||||
uint8_t const xact_len = tu_min16(xfer->total_len - xfer->actual_len, xfer->mps);
|
||||
|
||||
NRF_USBD->EPIN[epnum].PTR = (uint32_t) xfer->buffer;
|
||||
NRF_USBD->EPIN[epnum].MAXCNT = xact_len;
|
||||
|
||||
xfer->buffer += xact_len;
|
||||
|
||||
edpt_dma_start(&NRF_USBD->TASKS_STARTEPIN[epnum]);
|
||||
}
|
||||
|
||||
bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
|
||||
{
|
||||
(void) rhport;
|
||||
@ -268,7 +247,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 dir = edpt_dir(ep_addr);
|
||||
|
||||
nom_xfer_t* xfer = get_td(epnum, dir);
|
||||
xfer_td_t* xfer = get_td(epnum, dir);
|
||||
|
||||
xfer->buffer = buffer;
|
||||
xfer->total_len = total_bytes;
|
||||
@ -352,14 +331,30 @@ bool dcd_edpt_busy (uint8_t rhport, uint8_t ep_addr)
|
||||
uint8_t const epnum = edpt_number(ep_addr);
|
||||
uint8_t const dir = edpt_dir(ep_addr);
|
||||
|
||||
nom_xfer_t* xfer = get_td(epnum, dir);
|
||||
xfer_td_t* xfer = get_td(epnum, dir);
|
||||
|
||||
return xfer->actual_len < xfer->total_len;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
/*
|
||||
/* Interrupt Handler
|
||||
*------------------------------------------------------------------*/
|
||||
void bus_reset(void)
|
||||
{
|
||||
for(int i=0; i<8; i++)
|
||||
{
|
||||
NRF_USBD->TASKS_STARTEPIN[i] = 0;
|
||||
NRF_USBD->TASKS_STARTEPOUT[i] = 0;
|
||||
}
|
||||
|
||||
NRF_USBD->TASKS_STARTISOIN = 0;
|
||||
NRF_USBD->TASKS_STARTISOOUT = 0;
|
||||
|
||||
tu_varclr(&_dcd);
|
||||
_dcd.xfer[0][TUSB_DIR_IN].mps = MAX_PACKET_SIZE;
|
||||
_dcd.xfer[0][TUSB_DIR_OUT].mps = MAX_PACKET_SIZE;
|
||||
}
|
||||
|
||||
void USBD_IRQHandler(void)
|
||||
{
|
||||
uint32_t const inten = NRF_USBD->INTEN;
|
||||
@ -448,7 +443,7 @@ void USBD_IRQHandler(void)
|
||||
{
|
||||
if ( BIT_TEST_(int_status, USBD_INTEN_ENDEPOUT0_Pos+epnum))
|
||||
{
|
||||
nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_OUT);
|
||||
xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT);
|
||||
uint8_t const xact_len = NRF_USBD->EPOUT[epnum].AMOUNT;
|
||||
|
||||
// Data in endpoint has been consumed
|
||||
@ -488,7 +483,7 @@ void USBD_IRQHandler(void)
|
||||
{
|
||||
if ( BIT_TEST_(data_status, epnum ) || ( epnum == 0 && is_control_in) )
|
||||
{
|
||||
nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_IN);
|
||||
xfer_td_t* xfer = get_td(epnum, TUSB_DIR_IN);
|
||||
|
||||
xfer->actual_len += NRF_USBD->EPIN[epnum].MAXCNT;
|
||||
|
||||
@ -509,7 +504,7 @@ void USBD_IRQHandler(void)
|
||||
{
|
||||
if ( BIT_TEST_(data_status, 16+epnum ) || ( epnum == 0 && is_control_out) )
|
||||
{
|
||||
nom_xfer_t* xfer = get_td(epnum, TUSB_DIR_OUT);
|
||||
xfer_td_t* xfer = get_td(epnum, TUSB_DIR_OUT);
|
||||
|
||||
if (xfer->actual_len < xfer->total_len)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user