diff options
Diffstat (limited to 'core/usb/usb_callbacks.c')
| -rw-r--r-- | core/usb/usb_callbacks.c | 54 | 
1 files changed, 43 insertions, 11 deletions
diff --git a/core/usb/usb_callbacks.c b/core/usb/usb_callbacks.c index 83b39c7..402e8f5 100644 --- a/core/usb/usb_callbacks.c +++ b/core/usb/usb_callbacks.c @@ -31,28 +31,54 @@ USB_Line_Coding line_coding = {   datatype:    0x08  }; -uint8 vcomBufferTx[VCOM_TX_EPSIZE];  uint8 vcomBufferRx[VCOM_RX_EPSIZE]; -uint8 countTx = 0; -uint8 countRx = 0; +uint8 countTx    = 0; +uint8 recvBufIn  = 0; +uint8 recvBufOut = 0; +uint8 maxNewBytes   = VCOM_RX_EPSIZE;  RESET_STATE reset_state = START;  void vcomDataTxCb(void) {    /* do whatever after data has been sent to host */ + +  /* allows usbSendBytes to stop blocking */ + +    countTx = 0;  } +/* we could get arbitrarily complicated here for speed purposes +   however, the simple scheme here is to implement a receive fifo +   and always set the maximum to new bytes to the space remaining +   in the fifo. this number will be reincremented after calls +   to usbReceiveBytes */  void vcomDataRxCb(void) {    /* do whatever after data has been received from host */ - /*  countRx = GetEPRxCount(VCOM_RX_ENDP); */ -/*   PMAToUserBufferCopy(vcomBufferRx,VCOM_RX_ADDR,countRx); */ -/*   SetEPRxValid(VCOM_RX_ENDP); */ -/*   countTx = countRx; */ -/*   UserToPMABufferCopy(vcomBufferRx,VCOM_TX_ADDR,countTx); */ -/*   SetEPTxCount(VCOM_TX_ENDP,countTx); */ -/*   SetEPTxValid(VCOM_TX_ENDP); */ +  /* setEPRxCount on the previous cycle should garuntee +     we havnt received more bytes than we can fit */ +  uint8 newBytes = _GetEPRxCount(VCOM_RX_ENDP); +  /* assert (newBytes <= maxNewBytes); */ + +  if (recvBufIn + newBytes < VCOM_RX_EPSIZE) { +    PMAToUserBufferCopy(&vcomBufferRx[recvBufIn],VCOM_RX_ADDR,newBytes); +    recvBufIn += newBytes; +  } else { +    /* we have to copy the data in two chunks because we roll over +       the edge of the circular buffer */ +    uint8 tailBytes = VCOM_RX_EPSIZE - recvBufIn; +    uint8 remaining = newBytes - tailBytes; + +    PMAToUserBufferCopy(&vcomBufferRx[recvBufIn],VCOM_RX_ADDR,tailBytes); +    PMAToUserBufferCopy(&vcomBufferRx[0],        VCOM_RX_ADDR,remaining); + +    recvBufIn += (newBytes % VCOM_RX_EPSIZE); +  } +   +  maxNewBytes    -= newBytes; +  SetEPRxCount(VCOM_RX_ENDP,maxNewBytes); +  SetEPRxValid(VCOM_RX_ENDP);  }  void vcomManagementCb(void) { @@ -115,12 +141,18 @@ void usbReset(void) {    /* setup data endpoint IN (tx)  */    SetEPType     (VCOM_TX_ENDP, EP_BULK); -  SetEPRxAddr   (VCOM_TX_ENDP, VCOM_TX_ADDR); +  SetEPTxAddr   (VCOM_TX_ENDP, VCOM_TX_ADDR);    SetEPTxStatus (VCOM_TX_ENDP, EP_TX_NAK);    SetEPRxStatus (VCOM_TX_ENDP, EP_RX_DIS);    bDeviceState = ATTACHED;    SetDeviceAddress(0); + +  /* reset the rx fifo */ +  recvBufIn   = 0; +  recvBufOut  = 0; +  maxNewBytes = VCOM_RX_EPSIZE; +  countTx     = 0;  }  | 
