📄 usbdrv.c
字号:
* None
*
* Description
* Generates zero length data packet
----------------------------------------------------------------*/
void zero_length_data_response(endpoint_t ep_num)
{
FLUSH_TXEP(ep_num);
// FLUSH_RXEP(ep_num);
usbn9604_tx_enable(ep_num);
}
/*------------------------------------------------------------------------------
* Prototype
* void fill_control_fifo()
*
* Parameters
* None
*
* Returns
* None
*
* Description
* Transfers data from the control buffer to zero endpoint control fifo.
----------------------------------------------------------------------------*/
void fill_control_fifo(void)
{
byte *data_ptr = control_send_buffer.data;
byte *temp=control_send_buffer.data;
//byte i=control_send_buffer.bytes_counter;
/*-----------------------------------
* number of bytes actually to be sent
*-----------------------------------*/
int count = mini(control_send_buffer.bytes_counter, EP0_FIFO_SIZE);
FLUSH_RXEP(ENDPOINT_0);//=FLUSHRX0
FLUSH_TXEP(ENDPOINT_0);//=FLUSHTX0
/*----------------------------------
* update control buffer parameters
*----------------------------------*/
control_send_buffer.data += count;
control_send_buffer.bytes_counter -= count;
/*for(i=0;i<18;i++)
Uart_Printf("%X,",*temp++);*/
//i=control_send_buffer.bytes_counter;
//Uart_Printf("\nDI:");
while(count--)
{
//Uart_Printf("%x-",*data_ptr);
EP_FIFO_WRITE(ENDPOINT_0, *data_ptr++);//write 8 bytes
}
}
/*------------------------------------------------------------------------------
* Prototype
* void usbn9604_tx_enable(int ep_num)
*
* Parameters
* ep_num - endpoin number
*
* Returns
* None
*
* Description
* Enable tx endpoint transmission
----------------------------------------------------------------------------*/
void usbn9604_tx_enable(int ep_num)
{
byte Toggle = endpoint_stat[ep_num]->toggle_bit;
/*-------------------------------------------
* update toggle bit of appropriate endpoint
*-------------------------------------------*/
endpoint_stat[ep_num]->toggle_bit = !endpoint_stat[ep_num]->toggle_bit;
Toggle = Toggle << 2;
switch (ep_num){
case ENDPOINT_0:
write_usb(EP_TXC(ep_num), Toggle|TX_EN);
write_usb(EP_RXC(ENDPOINT_0), 0x0);
break;
case ENDPOINT_1:
case ENDPOINT_5:
write_usb(EP_TXC(ep_num), Toggle|TX_LAST|TX_EN);
break;
case ENDPOINT_3: /* isochronous */
write_usb(EP_TXC(ep_num), Toggle|TX_LAST|IGN_ISOMSK|TX_EN);
break;
}
}
/*------------------------------------------------------------------------------
* Prototype
* void usbn9604_tx_retransmit_enable(int ep_num)
*
* Parameters
* ep_num - endpoin number
*
* Returns
* None
*
* Description
* Enable tx data retransmission
----------------------------------------------------------------------------*/
void usbn9604_tx_retransmit_enable(int ep_num)
{
/*------------------------------
* use previous toggle bit value
*------------------------------*/
byte Toggle = endpoint_stat[ep_num]->toggle_bit;
Toggle = Toggle << 2;
if (ep_num == ENDPOINT_0)
/*-------------------------------------------------
* there is no retransmission from the endpoint zero
*------------------------------------------------*/
return;
else
write_usb(EP_TXC(ep_num), Toggle|TX_LAST|TX_EN|RFF);//RFF: refill FIFO
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void USB_init_dma(endpoint_t endPoint)
*
* Parameters
* endPoint - Number of Endpoint for DMA support
*
* Returns
* None
*
* Description
* This is a sample code for dma initialization. This function should be called before starting
* DMA operation.
----------------------------------------------------------------------------------------------*/
extern USB_endpoint_desc_t *usb_dev_endpoints[];
void USB_init_dma(endpoint_t endPoint)
{
byte dmaControl = 0; /* value of DMA control register */
DMA_ep = endPoint;
/*-------------------------------
* update DMA source field
*-------------------------------*/
dmaControl = ((endPoint - 1)&3);
/*----------------------------------
* update DMA Toggle bit if needeed
*-----------------------------------*/
if (IS_EP_ISO(endPoint))
{
/*----------------------
* Isochronous endpoint.
*-----------------------*/
if (IS_EP_IN(endPoint))
/*------------------------------------------------
* Transmit endpoint
* It seems that in this mode ISO Mask should
* better be ignored.
*-----------------------------------------------*/
write_usb(EP_TXC(endPoint), IGN_ISOMSK);
else
/*------------------------------------------------
* Receive endpoint
* It seems that in this mode toggle compare should
* better be disabled.
*-----------------------------------------------*/
dmaControl |= IGNRXTGL;
}
else
{
/*----------------------------------
* update DMA Toggle bit if needeed
*-----------------------------------*/
if (endpoint_stat[endPoint]->toggle_bit)
dmaControl |= DMA_DTGL;
}
/*------------------------------
* write to DMA control register
*------------------------------*/
write_usb(DMACNTRL,dmaControl);
/*--------------------------------
* clear all dma events to be sure
*--------------------------------*/
write_usb(DMAEV,0x00);
/*-------------------------------------
* do automatic error handling if needed
*------------------------------------*/
write_usb(DMAERR,0x88);
/*-------------------------
* enable DMA interrupts
*-----------------------*/
write_usb(DMAMSK,(DMA_DCNT|DMA_DSIZ|DMA_DERR |DMA_DSHLT ));
/*-----------------------------------------------
* enable DMA Request interrupt for DMA emulation
*------------------------------------------------*/
// ICU_UNMASK_INT(DRQ_INT);
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void USB_start_dma(byte DCOUNT)
*
* Parameters
* DCOUNT - (Number of packets to transfer)
*
* Returns
* None
*
* Description
* This sample code for strat dma process. Call this function each time DMA fills/empties a page.
* Note, after calling this function you must set endpoint Enable bit of respective endpoint
* using ENABLE_EP(endpoint number) macro.
* Before starting DMA process, disable interrupt of respective endpoint using
* DISABLE_TX_INTS(TX_FIFO[number of FIFO]) for transfer operations or
* DISABLE_RX_INTS(RX_FIFO[number of FIFO]) for receive operations
----------------------------------------------------------------------------------------------*/
void USB_start_dma(int DCOUNT)
{
byte dmaControl = 0; /* value of DMA control register */
/*-----------------------------------
* write number of packets to transfer
* to DMA count register
*----------------------------------*/
write_usb(DMACNT,(DCOUNT -1));
/*----------------------------------------------
* Set Atomatic DMA Mode and enable DMA operation
*------------------------------------------------*/
dmaControl = read_usb(DMACNTRL);
dmaControl |= (DMA_ADMA | DMA_DEN);
write_usb(DMACNTRL,dmaControl);
}
/*----------------------------------------------------
* For test use
*----------------------------------------------------*/
/*#pragma interrupt(usb_drq_handler)
void usb_drq_handler(void)
{
// ICU_clear_int(DRQ_INT);
_disable_();
ICU_MASK_INT(DRQ_INT);
PFDOUT = (PFDOUT & 0x7f);
while (ICU_STATUS_INT(DRQ_INT))
USBDATA = 0x14;
PFDOUT = (PFDOUT | 0x80);
ICU_UNMASK_INT(DRQ_INT);
_enable_();
}*/
/*----------------------------------------------------------------------------------------------
* Prototype
* void BulkTransmitEvent()
*
* Parameters
* None
*
* Returns
* None
*
* Description
* Send new packet to endpoint num 1 (bulk transmit) according to the current bulk command
----------------------------------------------------------------------------------------------*/
/*__inline*/ void BulkTransmitEvent(void)
{
byte curBuff = 0;
byte byteToWrite = 0;
/*----------------------------------------
* Is there more date to be sent?
*----------------------------------------*/
if (bulkState.restToWrite > 0)
{
/* ------------------------------------------------
* Is it bulk immediate response back command?
* ------------------------------------------------*/
if (bulkState.command.bulkCommand == BULK_SEND_IMM_BACK)
{
/*--------------------------------------------
* Check whether current buffer ready ( full )
* --------------------------------------------*/
//_disable_();
curBuff = bulkState.bufferForSendData;
if (bulkState.locBuff[curBuff].sendReady)
{
/* --------------------------------------
* Buffer is ready.
* Send new packet from this buffer
----------------------------------------*/
byteToWrite = mini(bulkState.restToWrite,TX_BULK_EP_FIFO_SIZE);
USB_Transmit_Data(byteToWrite,bulkState.locBuff[curBuff].buffer,ENDPOINT_1);
bulkState.restToWrite -= byteToWrite;
bulkState.locBuff[curBuff].sendReady = FALSE;
/* ---------------------------------
* Buffer ready to receive new data
* --------------------------------*/
bulkState.locBuff[curBuff].getReady = TRUE;
/*-------------------------
* Go to the next buffer
* ------------------------*/
bulkState.bufferForSendData = bulkState.locBuff[curBuff].nextBuf;
}
else
{ /* --------------------------------------
* Buffer is not ready.
* wait for the next interrupt
* -------------------------------------*/
//clear_event(EVT_USB_BULK_TX);
}
//_enable_();
}
/* ------------------------------------------------
* Is it
* - bulk send data command or
* - bulk delayed response command
* ------------------------------------------------*/
else
{ /* ---------------
* send new packet
*-----------------*/
byteToWrite = (bulkState.restToWrite < TX_BULK_EP_FIFO_SIZE) ?
bulkState.restToWrite : TX_BULK_EP_FIFO_SIZE ;
bulkState.restToWrite -= byteToWrite;
/* --------------------------------------
* If it is bulk delayed response command
* --------------------------------------*/
if ( bulkState.command.bulkCommand == BULK_SEND_AFTER_LAST_BACK )
{ /* ---------------------------------------
* Send next packet from the local buffer
* -------------------------------------*/
USB_Transmit_Data(byteToWrite,writePtr,ENDPOINT_1);
writePtr += byteToWrite;
}
else
/* ------------------------------------------------------------------------------
* Send a new packet, each byte of which is equal to a one determined by the host.
*-------------------------------------------------------------------------------*/
USB_write_data(byteToWrite,bulkState.data,ENDPOINT_1);
}
}
/*---------------------------------
* There is no more data to send
*--------------------------------*/
else
{
/*------------------------------------
* Send zero length packet to
* mark end of the data, if needed
* -----------------------------------*/
if (bulkState.zeroPacketNeed)
{
usbn9604_tx_enable(ENDPOINT_1);
bulkState.zeroPacketNeed = FALSE;
}
/*--------------------------------------------------
* Put the pointer to the begging of the local buffer
*-------------------------------------------------*/
writePtr = buffer;
bulkState.command.bulkCommand = BULK_NO_COMMAND;
bulkState.numOfErrors = 0;
bulkState.data = 0;
}
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void BulkReceiveEvent()
*
* Parameters
* None
*
* Returns
* None
*
* Description
* Read new packet from endpoint num 2 (bulk receive) according to the current bulk command
----------------------------------------------------------------------------------------------*/
/*__inline*/ void BulkReceiveEvent()
{
byte curBuff;
byte readCount = 0;
byte byteToWrite = 0;
dword i,j;
static dword pointer=0;
/* ------------------------------------------------
* Is it bulk immediate response back command?
* ------------------------------------------------*/
if (bulkState.command.bulkCommand == BULK_SEND_IMM_BACK)
{
/*--------------------------------------------
* Check whether current buffer ready ( empty )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -