📄 usb_cdc.c
字号:
*****************************************************************************/
int cdc_input_ready(void)
{
int i,count;
char c;
/* If the receive buffer is not empty retun 1. */
if (rx_length > rx_ndx)
{
//uart_putch(rx_length>>8);
//uart_putch(rx_length);
count = rx_length - rx_ndx;
for(i=0;i<count;i++)
{
c = cdc_getch();
cur_tx_buffer[tx_ndx++] = c;
}
for(i=0;i<count;i++)
{
uart_putch(cur_tx_buffer[i]);
}
cdc_putbuf();
return(1);
}
/* If the rx buffer is empty. */
/* See if host is talking to us. */
if (usb_get_state() != USBST_CONFIGURED)
{
/* If not, enter startup state. This means rx_buffer is empty,
and if host will be connected, the next rx transfer is
started. */
rx_length=1; /* rx_length != 0 will make cdc_input_ready to start
the next rx transfer on USB. */
rx_ndx=rx_length; /* Enter rx buffer is empty state. */
return(0);
}
/* if rx_length != 0 then the buffer has been empty and we need to start
the next rx transfer on USB. */
if (rx_length > 0)
{
rx_length = 0; /* Do this to avoid getting here while the next frame
is not received and processed by the main app. */
rx_ndx=0; /* Set rx buffer state to unread. */
/* We have no information how much data the host is willing to send,
and thus we don't know when the started transmission will end.
The usb driver will treat a trensmission ended if the number of
needed bytes has been received, or if a short packet has been
received. So we ask the driver to receive data that fits exactly
one packet. This way after the first frame the transfer will end.
(If the host sends less data than a packet, then it will end any way,
and if the host wants to send more data then a packet can hold, then
we will make an usb_receive call for each packet.
If we wold try to receive let's syat 64k, and the host has not that
much data, then we would wait till the end of time for data. */
usb_receive(RX_EP_NO, (void *) 0, (void *) rx_buffer, sizeof(rx_buffer), sizeof(rx_buffer));
return(0);
}
/* If we get here, then the rx buffer is empty, and a frame reception is
started. So we check for the status of the reception. */
if (!usb_ep_is_busy(RX_EP_NO))
{
/* Read out error status of endpoint. The reception may be aborted due
to a status change on the USB (disconnect, sleep, etc..) or due to
an error (CRC, bit stuffing, etc...). In both case wee need to restart
reception if possible. */
switch(usb_ep_error(RX_EP_NO))
{
case USBEPERR_NONE: /* Reception finished with no error. */
/* Read out number of received bytes. This will make us to return
received characters for the next call. Note: the transfer may
contain 0 characters, so we return the first character only when
the next call is made. */
rx_length=(hcc_u8)usb_get_done(RX_EP_NO);
break;
case USBEPERR_PROTOCOL_ERROR:
/* If we have an error, then we restart the reception. */
usb_receive(RX_EP_NO, (void *) 0, (void *) rx_buffer, sizeof(rx_buffer), sizeof(rx_buffer));
break;
case USBEPERR_HOST_ABORT:
/* USB disconnected or in low power mode.
Do nothing because this is handled by the second if above. */
break;
case USBEPERR_USER_ABORT:
case USBEPERR_TO_MANY_DATA:
default:
/* Upps! unexpected error. Stop here. */
while(1)
;
}
}
return(0);
}
/*****************************************************************************
* Name:
* cdc_putch
* In:
* 0: output is busy, character dropped
* 1: character buffered and will be sent later.
* Out:
* N/A
*
* Description:
* Put one character into tx_buffer.
*
* Assumptions:
* --
*****************************************************************************/
int cdc_putch(hcc_u8 c)
{
int r=0;
/* Store character into current buffer. */
if (tx_ndx < sizeof(tx_buffer1))
{
r=1;
cur_tx_buffer[tx_ndx++]=(hcc_u8)c;
}
/* Hndle USB. See if we need to send something. */
if (tx_ndx != 0)
{
//UART_PutString(5,"!=0\r\n");
/* Host properly connected us, and the TX endpoint is not busy */
if (usb_get_state() == USBST_CONFIGURED)
{
//UART_PutString(18,"USBST_CONFIGURED\r\n");
if (!usb_ep_is_busy(TX_EP_NO))
{
/* Check the status of the next transfer. */
switch (usb_ep_error(TX_EP_NO))
{
case USBEPERR_NONE: /* Finished with no error. */
//UART_PutString(15,"USBEPERR_NONE\r\n");
/* Start sending next chunk. */
usb_send(TX_EP_NO, (void *) 0, (void *) cur_tx_buffer, tx_ndx, tx_ndx);
/* Switch buffer. */
tx_ndx=0;
cur_tx_buffer = (hcc_u8*)((cur_tx_buffer == (hcc_u8*)tx_buffer1) ? tx_buffer2 : tx_buffer1);
break;
case USBEPERR_PROTOCOL_ERROR:
case USBEPERR_HOST_ABORT:
/* It is possible to resend the previous buffer here. */
//UART_PutString(7,"error\r\n");
break;
case USBEPERR_USER_ABORT:
case USBEPERR_TO_MANY_DATA:
default:
//UART_PutString(6,"else\r\n");
/* Upps! unexpected error. Stop here. */
while(1)
;
}
}
}
}
return(r);
}
/*****************************************************************************
*
****************************************************************************/
int cdc_line_coding_changed(void)
{
if(new_line_coding)
{
new_line_coding=0;
return(1);
}
return(0);
}
/*****************************************************************************
*
****************************************************************************/
void cdc_get_line_coding(line_coding_t *l)
{
l->bps=RD_LE32(line_coding);
l->nstp=line_coding[4];
l->parity=line_coding[5];
l->ndata=line_coding[6];
}
/*****************************************************************************
*
****************************************************************************/
void cdc_init(void)
{
cur_tx_buffer=(hcc_u8*)tx_buffer1;
tx_ndx=0;
}
void cdc_putbuf(void)
{
/* Hndle USB. See if we need to send something. */
if (tx_ndx != 0)
{
//UART_PutString(5,"!=0\r\n");
/* Host properly connected us, and the TX endpoint is not busy */
if (usb_get_state() == USBST_CONFIGURED)
{
//UART_PutString(18,"USBST_CONFIGURED\r\n");
if (!usb_ep_is_busy(TX_EP_NO))
{
/* Check the status of the next transfer. */
switch (usb_ep_error(TX_EP_NO))
{
case USBEPERR_NONE: /* Finished with no error. */
//UART_PutString(15,"USBEPERR_NONE\r\n");
/* Start sending next chunk. */
usb_send(TX_EP_NO, (void *) 0, (void *) cur_tx_buffer, tx_ndx, tx_ndx);
/* Switch buffer. */
tx_ndx=0;
cur_tx_buffer = (hcc_u8*)((cur_tx_buffer == (hcc_u8*)tx_buffer1) ? tx_buffer2 : tx_buffer1);
break;
case USBEPERR_PROTOCOL_ERROR:
case USBEPERR_HOST_ABORT:
/* It is possible to resend the previous buffer here. */
//UART_PutString(7,"error\r\n");
break;
case USBEPERR_USER_ABORT:
case USBEPERR_TO_MANY_DATA:
default:
//UART_PutString(6,"else\r\n");
/* Upps! unexpected error. Stop here. */
while(1)
;
}
}
}
}
}
/****************************** END OF FILE **********************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -