void MouseProcess(void) { Msg msg = GetMessage(); if(msg == MSG_SWITCH){ CurrentProcess = KeyboardProcess; CurrentSystick = KeyboardSystick; KeyboardUIInit(); for(u32 i=0;i<sizeof(JoyMouseBuffer);i++){ JoyMouseBuffer[i] = 0; } JoyMouseBuffer[IDX_ID] = MOUSE_REPORT_ID; UserToPMABufferCopy(JoyMouseBuffer, GetEPTxAddr(ENDP2), 5); /* enable endpoint for transmission */ SetEPTxCount(ENDP2, 5); SetEPTxValid(ENDP2); }else if(KEY_PAUSE == msg){ bMode = !bMode; if(bMode){ AirMouseUIInit(); }else{ MouseUIInit(); } }else if(msg){ JoyMouseBuffer[IDX_ID] = MOUSE_REPORT_ID; UserToPMABufferCopy(JoyMouseBuffer, GetEPTxAddr(ENDP2), 5); /* enable endpoint for transmission */ SetEPTxCount(ENDP2, 5); SetEPTxValid(ENDP2); if(bMode){ UpdateBall(); } } }
/******************************************************************************* * Function Name : Read_Memory * Description : Handle the Read operation from the microSD card. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Read_Memory(void) { if (!Block_Read_count) { MSD_ReadBlock(Data_Buffer, Memory_Offset, 512); UserToPMABufferCopy(Data_Buffer, ENDP1_TXADDR, BULK_MAX_PACKET_SIZE); Block_Read_count = 512 - BULK_MAX_PACKET_SIZE; Block_offset = BULK_MAX_PACKET_SIZE; } else { UserToPMABufferCopy(Data_Buffer + Block_offset, ENDP1_TXADDR, BULK_MAX_PACKET_SIZE); Block_Read_count -= BULK_MAX_PACKET_SIZE; Block_offset += BULK_MAX_PACKET_SIZE; } SetEPTxCount(ENDP1, BULK_MAX_PACKET_SIZE); SetEPTxStatus(ENDP1, EP_TX_VALID); Memory_Offset += BULK_MAX_PACKET_SIZE; Transfer_Length -= BULK_MAX_PACKET_SIZE; CSW.dDataResidue -= BULK_MAX_PACKET_SIZE; if (Transfer_Length == 0) { Block_Read_count = 0; Block_offset = 0; Memory_Offset = 0; Bot_State = BOT_DATA_IN_LAST; } }
/** * @brief Transmit data Buffer * @param pdev: device instance * @param ep_addr: endpoint address * @param pbuf: pointer to Tx buffer * @param buf_len: data length * @retval : status */ uint32_t DCD_EP_Tx ( USB_CORE_HANDLE *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len) { __IO uint32_t len = 0; USB_EP *ep; ep = &pdev->dev.in_ep[ep_addr & 0x7F]; /*setup and start the Xfer */ ep->num = ep_addr & 0x7F; ep->xfer_buff = pbuf; ep->xfer_len = buf_len; ep->xfer_count = 0; /*Multi packet transfer*/ if (ep->xfer_len > ep->maxpacket) { len=ep->maxpacket; ep->xfer_len-=len; } else { len=ep->xfer_len; ep->xfer_len =0; } /* configure and validate Tx endpoint */ if (ep->doublebuffer == 0) { UserToPMABufferCopy(ep->xfer_buff, ep->pmaadress, len); SetEPTxCount(ep->num, len); } else { uint16_t pmabuffer=0; /*Set the Double buffer counter*/ SetEPDblBuffCount(ep->num, ep->is_in, len); /*Write the data to the USB endpoint*/ if (GetENDPOINT(ep->num)&EP_DTOG_TX) { pmabuffer = ep->pmaaddr1; } else { pmabuffer = ep->pmaaddr0; } UserToPMABufferCopy(ep->xfer_buff, pmabuffer, len); FreeUserBuffer(ep->num, ep->is_in); } SetEPTxStatus(ep->num, EP_TX_VALID); return USB_OK; }
/******************************************************************************* * Function Name : Read_Memory * Description : Handle the Read operation from the microSD card. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Read_Memory(u8 lun, u32 Memory_Offset, u32 Transfer_Length) { static u32 Offset, Length; if (TransferState == TXFR_IDLE ) { Offset = Memory_Offset * Mass_Block_Size[lun]; Length = Transfer_Length * Mass_Block_Size[lun]; TransferState = TXFR_ONGOING; } if (TransferState == TXFR_ONGOING ) { if (!Block_Read_count) { MAL_Read(lun , Offset , Data_Buffer, Mass_Block_Size[lun]); UserToPMABufferCopy((u8 *)Data_Buffer, ENDP1_TXADDR, BULK_MAX_PACKET_SIZE); Block_Read_count = Mass_Block_Size[lun] - BULK_MAX_PACKET_SIZE; Block_offset = BULK_MAX_PACKET_SIZE; } else { UserToPMABufferCopy((u8 *)Data_Buffer + Block_offset, ENDP1_TXADDR, BULK_MAX_PACKET_SIZE); Block_Read_count -= BULK_MAX_PACKET_SIZE; Block_offset += BULK_MAX_PACKET_SIZE; } SetEPTxCount(ENDP1, BULK_MAX_PACKET_SIZE); SetEPTxStatus(ENDP1, EP_TX_VALID); Offset += BULK_MAX_PACKET_SIZE; Length -= BULK_MAX_PACKET_SIZE; CSW.dDataResidue -= BULK_MAX_PACKET_SIZE; Led_RW_ON(); } if (Length == 0) { Block_Read_count = 0; Block_offset = 0; Offset = 0; Bot_State = BOT_DATA_IN_LAST; TransferState = TXFR_IDLE; Led_RW_OFF(); } }
static void PIOS_USB_HID_SendReport(struct pios_usb_hid_dev * usb_hid_dev) { uint16_t bytes_to_tx; if (!usb_hid_dev->tx_out_cb) { return; } bool need_yield = false; #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context, &usb_hid_dev->tx_packet_buffer[1], sizeof(usb_hid_dev->tx_packet_buffer)-1, NULL, &need_yield); #else bytes_to_tx = (usb_hid_dev->tx_out_cb)(usb_hid_dev->tx_out_context, &usb_hid_dev->tx_packet_buffer[2], sizeof(usb_hid_dev->tx_packet_buffer)-2, NULL, &need_yield); #endif if (bytes_to_tx == 0) { return; } /* Always set type as report ID */ usb_hid_dev->tx_packet_buffer[0] = 1; #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer, GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep), bytes_to_tx + 1); #else usb_hid_dev->tx_packet_buffer[1] = bytes_to_tx; UserToPMABufferCopy(usb_hid_dev->tx_packet_buffer, GetEPTxAddr(usb_hid_dev->cfg->data_tx_ep), bytes_to_tx + 2); #endif /* Is this correct? Why do we always send the whole buffer? */ SetEPTxCount(usb_hid_dev->cfg->data_tx_ep, sizeof(usb_hid_dev->tx_packet_buffer)); SetEPTxValid(usb_hid_dev->cfg->data_tx_ep); #if defined(PIOS_INCLUDE_FREERTOS) if (need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ }
static void PIOS_USB_CDC_SendData(struct pios_usb_cdc_dev * usb_cdc_dev) { uint16_t bytes_to_tx; if (!usb_cdc_dev->tx_out_cb) { return; } bool need_yield = false; bytes_to_tx = (usb_cdc_dev->tx_out_cb)(usb_cdc_dev->tx_out_context, usb_cdc_dev->tx_packet_buffer, sizeof(usb_cdc_dev->tx_packet_buffer), NULL, &need_yield); if (bytes_to_tx == 0) { return; } UserToPMABufferCopy(usb_cdc_dev->tx_packet_buffer, GetEPTxAddr(usb_cdc_dev->cfg->data_tx_ep), bytes_to_tx); SetEPTxCount(usb_cdc_dev->cfg->data_tx_ep, bytes_to_tx); SetEPTxValid(usb_cdc_dev->cfg->data_tx_ep); #if defined(PIOS_INCLUDE_FREERTOS) portEND_SWITCHING_ISR(need_yield); #endif /* PIOS_INCLUDE_FREERTOS */ }
/******************************************************************************* * Function Name : EP1_IN_Callback * Description : * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP1_IN_Callback (void) { if (USB_Tx_State == 1) { unsigned char USB_TX_Buffer[VIRTUAL_COM_PORT_DATA_SIZE]; int USB_Tx_length = 0; // try and fill the buffer int c; while (USB_Tx_length<VIRTUAL_COM_PORT_DATA_SIZE && ((c = jshGetCharToTransmit(EV_USBSERIAL)) >= 0) ) { // get byte to transmit USB_TX_Buffer[USB_Tx_length++] = c; } // if nothing, set state to 0 if (USB_Tx_length==0) { USB_Tx_State = 0; return; } // else send data and keep going UserToPMABufferCopy(&USB_TX_Buffer[0], ENDP1_TXADDR, USB_Tx_length); SetEPTxCount(ENDP1, USB_Tx_length); SetEPTxValid(ENDP1); } }
/******************************************************************************* * Function Name : DataStageIn. * Description : Data stage of a Control Read Transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void DataStageIn(void) { ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; uint32_t save_wLength = pEPinfo->Usb_wLength; uint32_t ControlState = pInformation->ControlState; uint8_t *DataBuffer; uint32_t Length; if ((save_wLength == 0) && (ControlState == LAST_IN_DATA)) { if (Data_Mul_MaxPacketSize == TRUE) { // No more data to send and empty packet SetEPTxCount(ENDP0,0); SaveTState = EP_TX_VALID; ControlState = LAST_IN_DATA; Data_Mul_MaxPacketSize = FALSE; } else { // No more data to send so STALL the TX Status ControlState = WAIT_STATUS_OUT; SaveTState = EP_TX_STALL; } } else { Length = pEPinfo->PacketSize; ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA; if (Length > save_wLength) Length = save_wLength; DataBuffer = (*pEPinfo->CopyData)(Length); UserToPMABufferCopy(DataBuffer,GetEPTxAddr(ENDP0),Length); SetEPTxCount(ENDP0,Length); pEPinfo->Usb_wLength -= Length; pEPinfo->Usb_wOffset += Length; SaveTState = EP_TX_VALID; SaveRState = EP_RX_VALID; // Expect the host to abort the data IN stage } pInformation->ControlState = ControlState; }
/* This low-level send bytes function is NON-BLOCKING; blocking behavior, with * a timeout, is implemented in usercode (or in the Wirish C++ high level * implementation). * * This function will quickly copy up to 64 bytes of data (out of an * arbitrarily large buffer) into the USB peripheral TX buffer and return the * number placed in that buffer. It is up to usercode to divide larger packets * into 64-byte chunks to guarantee delivery. Use usbGetCountTx() to determine * whether the bytes were ACTUALLY recieved by the host or just transfered to * the buffer. * * The function will return -1 if it doesn't think that the USB host is * "connected", but it can't detect this state robustly. "Connected" in this * context means that an actual program on the Host operating system is * connected to the virtual COM/ttyACM device and is recieving the bytes; the * Host operating system is almost always configured and keeping this endpoint * alive, but the bytes never get read out of the endpoint buffer. * * The behavior of this function is subtle and frustrating; it has gone through * many simpler and cleaner implementation that frustratingly don't work cross * platform. * * */ uint16 usbSendBytes(uint8* sendBuf, uint16 len) { uint16 loaded = 0; if (bDeviceState != CONFIGURED || (!usbGetDTR() && !usbGetRTS())) { // Indicates to caller to stop trying, were not configured/connected // The DTR and RTS lines are handled differently on major platforms, so // the above logic is unreliable return 0; } // Due to a variety of shit this is how we roll; all buffering etc is pushed // upstream if (countTx) { return 0; } // We can only put VCOM_TX_EPSIZE bytes in the buffer if(len > VCOM_TX_EPSIZE) { loaded = VCOM_TX_EPSIZE; } else { loaded = len; } // Try to load some bytes if we can if (loaded) { UserToPMABufferCopy(sendBuf,VCOM_TX_ADDR + countTx, loaded); _SetEPTxCount(VCOM_TX_ENDP, countTx+loaded); _SetEPTxValid(VCOM_TX_ENDP); countTx += loaded; } return loaded; }
static void PIOS_USB_CDC_CTRL_EP_IN_Callback(void) { struct pios_usb_cdc_dev * usb_cdc_dev = (struct pios_usb_cdc_dev *)pios_usb_cdc_id; bool valid = PIOS_USB_CDC_validate(usb_cdc_dev); PIOS_Assert(valid); /* Give back UART State Bitmap */ /* UART State Bitmap * 15-7: reserved * 6: bOverRun overrun error * 5: bParity parity error * 4: bFraming framing error * 3: bRingSignal RI * 2: bBreak break reception * 1: bTxCarrier DSR * 0: bRxCarrier DCD */ uart_state.bmUartState = htousbs(0x0003); UserToPMABufferCopy((uint8_t *) &uart_state, GetEPTxAddr(usb_cdc_dev->cfg->ctrl_tx_ep), sizeof(uart_state)); SetEPTxCount(usb_cdc_dev->cfg->ctrl_tx_ep, PIOS_USB_BOARD_CDC_MGMT_LENGTH); SetEPTxValid(usb_cdc_dev->cfg->ctrl_tx_ep); }
int usbSendBytes(uchar *data,int size) { if(size==0) wait_us(140); // 0byte packet対ç–. /* Last transmission hasn't finished, abort */ if (countTx) { return 0; } if( GetEPTxStatus(ENDP1) == EP_TX_VALID) return 0; if( size >= MAX_SEND_BYTES_CDC) { size = MAX_SEND_BYTES_CDC; } UserToPMABufferCopy(data, ENDP1_TXADDR, size); SetEPTxCount(ENDP1, size); countTx += size; if(size==0) countTx++; // 0byte packet対ç–. SetEPTxValid(ENDP1); if(size==0) wait_us(140); // 0byte packet対ç–. return size; }
void USB_Transmit(void) { // nur blockweises kopieren des sendebuffers, nicht alles mit einem mal // if something has to be send and the txd fifo is not full if(USB_tx_buffer.Locked == TRUE) { if(_GetEPTxStatus(ENDP1) == EP_TX_NAK) { u16 i; if(USB_tx_buffer.Position < USB_tx_buffer.DataBytes) { i = USB_tx_buffer.DataBytes - USB_tx_buffer.Position; // bytes to send if(i > 64) i = 64; // limit packet size to 64 bytes UserToPMABufferCopy(&(USB_tx_buffer.pData[USB_tx_buffer.Position]), ENDP1_TXADDR, i); SetEPTxCount(ENDP1,i); SetEPTxValid(ENDP1); USB_tx_buffer.Position += i; } } if(USB_tx_buffer.Position >= USB_tx_buffer.DataBytes) // all bytes transfered { Buffer_Clear(&USB_tx_buffer); // clear buffer } } }
///////////////////////////////////////////////////////////////////////////// //! puts more than one byte onto the transmit buffer (used for atomic sends) //! \param[in] usb_com USB_COM number (not supported yet, should always be 0) //! \param[in] *buffer pointer to buffer which should be transmitted //! \param[in] len number of bytes which should be transmitted //! \return 0 if no error //! \return -1 if USB_COM not available //! \return -2 if buffer full or cannot get all requested bytes (retry) //! \return -3 if USB_COM not supported by MIOS32_USB_COM_TxBufferPut Routine //! \return -4 if too many bytes should be sent //! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_COM layer functions ///////////////////////////////////////////////////////////////////////////// s32 MIOS32_USB_COM_TxBufferPutMore_NonBlocking(u8 usb_com, u8 *buffer, u16 len) { #if MIOS32_USB_COM_NUM == 0 return -1; // no USB_COM available #else if( usb_com >= MIOS32_USB_COM_NUM ) return -1; // USB_COM not available if( len > MIOS32_USB_COM_DATA_IN_SIZE ) return -4; // cannot get all requested bytes if( tx_buffer_busy ) return -2; // buffer full (retry) // copy bytes to be transmitted into transmit buffer UserToPMABufferCopy(buffer, MIOS32_USB_ENDP4_TXADDR, len); // send buffer tx_buffer_busy = 1; SetEPTxCount(ENDP4, len); SetEPTxValid(ENDP4); return 0; // no error #endif }
// write to USB void EP1_IN_Callback (void) { //uint16_t USB_Tx_ptr; uint16_t USB_TX_Length; if (USB_Tx_State == 1) { if(BUFFER_IS_EMPTY(USB_TX)) { USB_Tx_State = 0; } else { USB_TX_Length = BUFFER_CONTIGUOUS_DATA_LENGTH(USB_TX); if (USB_TX_Length > VIRTUAL_COM_PORT_DATA_SIZE) USB_TX_Length = VIRTUAL_COM_PORT_DATA_SIZE; #ifdef USE_STM3210C_EVAL USB_SIL_Write(EP1_IN, &USART_Rx_Buffer[USB_Tx_ptr], USB_TX_Length); #else UserToPMABufferCopy(USB_TX_Head, ENDP1_TXADDR, USB_TX_Length); BUFFER_MOVE_HEAD(USB_TX, USB_TX_Length); SetEPTxCount(ENDP1, USB_TX_Length); SetEPTxValid(ENDP1); #endif } } }
void sendKeys(u8* buffer) { u32 i; #ifdef NOT_USED if (bDeviceState == CONFIGURED) { while(!PrevXferComplete); PrevXferComplete = 0; /* Use the memory interface function to write to the selected endpoint */ UserToPMABufferCopy(buffer, ENDP4_TXADDR, 8); /* Update the data length in the control register */ SetEPTxCount(ENDP4, 8); SetEPTxStatus (ENDP4, EP_TX_VALID); } #endif while (Is_usb_endpoint_stall_requested(EP_KB_IN)) { if (Is_usb_setup_received()) { usb_process_request(); } } // MSC Compliance - Free BAD out receive during SCSI command while( Is_usb_out_received(EP_CCID_OUT) ) { Usb_ack_out_received_free(EP_CCID_OUT); } while (!Is_usb_in_ready(EP_KB_IN)) { if(!Is_usb_endpoint_enabled(EP_KB_IN)) { i = 0; // todo USB Reset } } Usb_reset_endpoint_fifo_access(EP_KB_IN); /* Usb_write_endpoint_data(EP_KB_IN, 8, 'D'); Usb_write_endpoint_data(EP_KB_IN, 8, 'D'); Usb_write_endpoint_data(EP_KB_IN, 8, 'D'); Usb_write_endpoint_data(EP_KB_IN, 8, 'D'); */ usb_write_ep_txpacket(EP_KB_IN, buffer, 8, NULL); // Usb_send_in(EP_CONTROL); Usb_ack_in_ready_send(EP_KB_IN); // MSC Compliance - Wait end of all transmitions on USB line while( 0 != Usb_nb_busy_bank(EP_KB_IN) ) { if (Is_usb_setup_received()) usb_process_request(); } }
/******************************************************************************* * Function Name : Handle_USBAsynchXfer. * Description : send data to USB. * Input : None. * Return : none. *******************************************************************************/ void Handle_USBAsynchXfer (void) { if(USB_Tx_State != 1) { unsigned char USB_TX_Buffer[VIRTUAL_COM_PORT_DATA_SIZE]; int USB_Tx_length = 0; // try and fill the buffer int c; while (USB_Tx_length<VIRTUAL_COM_PORT_DATA_SIZE && ((c = jshGetCharToTransmit(EV_USBSERIAL)) >=0) ) { // get byte to transmit USB_TX_Buffer[USB_Tx_length++] = c; } // if nothing, set state to 0 if (USB_Tx_length==0) { USB_Tx_State = 0; return; } USB_Tx_State = 1; #ifdef USE_STM3210C_EVAL USB_SIL_Write(EP1_IN, &USB_TX_Buffer[0], USB_Tx_length); #else UserToPMABufferCopy(&USB_TX_Buffer[0], ENDP1_TXADDR, USB_Tx_length); SetEPTxCount(ENDP1, USB_Tx_length); SetEPTxValid(ENDP1); #endif /* USE_STM3210C_EVAL */ } }
/******************************************************************************* * Function Name : Handle_USBAsynchXfer. * Description : send data to USB. * Input : None. * Return : none. *******************************************************************************/ void Handle_USBAsynchXfer (void) { rt_uint32_t level; rt_uint32_t remain; if(USB_Tx_State != 1) { level = rt_hw_interrupt_disable(); remain = RT_RINGBUFFER_SIZE(&tx_ringbuffer); if(remain == 0) { USB_Tx_State = 0; rt_hw_interrupt_enable(level); return; } if (remain > VIRTUAL_COM_PORT_DATA_SIZE) { remain = VIRTUAL_COM_PORT_DATA_SIZE; } rt_ringbuffer_get(&tx_ringbuffer, tx_buf, remain); rt_hw_interrupt_enable(level); USB_Tx_State = 1; UserToPMABufferCopy(tx_buf, ENDP1_TXADDR, remain); SetEPTxCount(ENDP1, remain); SetEPTxValid(ENDP1); } }
/******************************************************************************* * Function Name : DataStageIn. * Description : Data stage of a Control Read Transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void DataStageIn(void) { ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; uint32_t save_wLength = pEPinfo->Usb_wLength; uint32_t ControlState = pInformation->ControlState; uint8_t *DataBuffer; uint32_t Length; if ((save_wLength == 0) && (ControlState == LAST_IN_DATA)) { if(Data_Mul_MaxPacketSize == TRUE) { // No more data to send and empty packet Send0LengthData(); ControlState = LAST_IN_DATA; Data_Mul_MaxPacketSize = FALSE; } else { // No more data to send so STALL the TX Status ControlState = WAIT_STATUS_OUT; vSetEPTxStatus(EP_TX_STALL); } goto Expect_Status_Out; // FIXME: <--- ZOMG TEH 'GOTO' !!!! } Length = pEPinfo->PacketSize; ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA; if (Length > save_wLength) Length = save_wLength; DataBuffer = (*pEPinfo->CopyData)(Length); UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length); SetEPTxCount(ENDP0, Length); pEPinfo->Usb_wLength -= Length; pEPinfo->Usb_wOffset += Length; vSetEPTxStatus(EP_TX_VALID); USB_StatusOut(); // Expect the host to abort the data IN stage Expect_Status_Out: // FIXME: <--- ZOMG TEH LABEL !!!! pInformation->ControlState = ControlState; }
/******************************************************************************* * Function Name : Joystick_Send. * Description : prepares buffer to be sent containing Joystick event infos. * Input : Keys: keys received from terminal. * Output : None. * Return value : None. *******************************************************************************/ void Joystick_Send(u8 Keys) { u8 Mouse_Buffer[4] = {0, 0, 0, 0}; s8 X = 0, Y = 0; switch (Keys) { case LEFT: X -= CURSOR_STEP; break; case RIGHT: X += CURSOR_STEP; break; case UP: Y -= CURSOR_STEP; break; case DOWN: Y += CURSOR_STEP; break; default: return; } /* prepare buffer to send */ Mouse_Buffer[1] = X; Mouse_Buffer[2] = Y; /*copy mouse position info in ENDP1 Tx Packet Memory Area*/ UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP1), 4); /* enable endpoint for transmission */ SetEPTxValid(ENDP1); }
/******************************************************************************* * Function Name : EP1_IN_Callback. * Description : EP1 IN Callback Routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP1_IN_Callback (void) { uint16_t USB_Tx_ptr; uint16_t USB_Tx_length; if (USB_Tx_State == 1) { if (USART_Rx_length == 0) { USB_Tx_State = 0; } else { if (USART_Rx_length > CDC_DATA_SIZE){ USB_Tx_ptr = USART_Rx_ptr_out; USB_Tx_length = CDC_DATA_SIZE; USART_Rx_ptr_out += CDC_DATA_SIZE; USART_Rx_length -= CDC_DATA_SIZE; } else { USB_Tx_ptr = USART_Rx_ptr_out; USB_Tx_length = USART_Rx_length; USART_Rx_ptr_out += USART_Rx_length; USART_Rx_length = 0; } UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length); SetEPTxCount(ENDP1, USB_Tx_length); SetEPTxValid(ENDP1); } } }
vsf_err_t stm32_usbd_ep_write_IN_buffer(uint8_t idx, uint8_t *buffer, uint16_t size) { uint32_t PMA_ptr; int8_t index; index = stm32_usbd_ep(idx); if (index < 0) { return VSFERR_FAIL; } idx = (uint8_t)index; if (stm32_usbd_IN_dbuffer[idx]) { if(GetENDPOINT(idx) & EP_DTOG_RX) { PMA_ptr = GetEPDblBuf1Addr(idx); } else { PMA_ptr = GetEPDblBuf0Addr(idx); } } else { PMA_ptr = GetEPTxAddr(idx); } UserToPMABufferCopy(buffer, PMA_ptr, size); return VSFERR_NONE; }
/******************************************************************************* * Function Name : UART_To_USB_Send_Data. * Description : send the received data from UART 0 to USB. * Input : None. * Return : none. *******************************************************************************/ void UART_To_USB_Send_Data(void) { buffer_in[count_in] = UART_ReceiveData(UART0); count_in++; UserToPMABufferCopy(buffer_in,ENDP1_TXADDR, count_in); SetEPTxCount(ENDP1,count_in); SetEPTxValid(ENDP1); }
//----------------------------------------------------------------- void USB_PutChar(u8 c) { u16 timeout = 0; while (_GetEPTxStatus(ENDP1) != EP_TX_NAK){ if (timeout++ > 60000) return;} UserToPMABufferCopy(&c, ENDP1_TXADDR, 2); SetEPTxCount(ENDP1,2); SetEPTxValid(ENDP1); }
/* This low-level send bytes function is NON-BLOCKING; blocking behavior, with * a timeout, is implemented in usercode (or in the Wirish C++ high level * implementation). * * This function will quickly copy up to 64 bytes of data (out of an * arbitrarily large buffer) into the USB peripheral TX buffer and return the * number placed in that buffer. It is up to usercode to divide larger packets * into 64-byte chunks to guarantee delivery. * * */ void usbBlockingSendByte(char ch) { while (countTx); UserToPMABufferCopy((uint8*)&ch,VCOM_TX_ADDR,1); _SetEPTxCount(VCOM_TX_ENDP,1); _SetEPTxValid(VCOM_TX_ENDP); countTx = 1; while (countTx); }
/******************************************************************************* * Function Name : USB_SIL_Write * Description : Write a buffer of data to a selected endpoint. * Input : - bEpAddr: The address of the non control endpoint. * - pBufferPointer: The pointer to the buffer of data to be written * to the endpoint. * - wBufferSize: Number of data to be written (in bytes). * Output : None. * Return : Status. *******************************************************************************/ uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize) { /* Use the memory interface function to write to the selected endpoint */ UserToPMABufferCopy(pBufferPointer, GetEPTxAddr(bEpAddr & 0x7F), wBufferSize); /* Update the data length in the control register */ SetEPTxCount((bEpAddr & 0x7F), wBufferSize); return 0; }
/******************************************************************************* * Function Name : Handle_USBAsynchXfer. * Description : send data to USB. * Input : None. * Return : none. *******************************************************************************/ void Handle_USBAsynchXfer (void) { uint16_t USB_Tx_ptr; uint16_t USB_Tx_length; if(USB_Tx_State != 1) { if (USART_Rx_ptr_out == USART_RX_DATA_SIZE) { USART_Rx_ptr_out = 0; } if(USART_Rx_ptr_out == USART_Rx_ptr_in) { USB_Tx_State = 0; return; } if(USART_Rx_ptr_out > USART_Rx_ptr_in) /* rollback */ { USART_Rx_length = USART_RX_DATA_SIZE - USART_Rx_ptr_out; } else { USART_Rx_length = USART_Rx_ptr_in - USART_Rx_ptr_out; } if (USART_Rx_length > VIRTUAL_COM_PORT_DATA_SIZE) { USB_Tx_ptr = USART_Rx_ptr_out; USB_Tx_length = VIRTUAL_COM_PORT_DATA_SIZE; USART_Rx_ptr_out += VIRTUAL_COM_PORT_DATA_SIZE; USART_Rx_length -= VIRTUAL_COM_PORT_DATA_SIZE; } else { USB_Tx_ptr = USART_Rx_ptr_out; USB_Tx_length = USART_Rx_length; USART_Rx_ptr_out += USART_Rx_length; USART_Rx_length = 0; } USB_Tx_State = 1; #ifdef USE_STM3210C_EVAL USB_SIL_Write(EP1_IN, &USART_Rx_Buffer[USB_Tx_ptr], USB_Tx_length); #else UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length); SetEPTxCount(ENDP1, USB_Tx_length); SetEPTxValid(ENDP1); #endif /* USE_STM3210C_EVAL */ } }
/******************************************************************************* * Function Name : DataStageIn. * Description : Data stage of a Control Read Transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void DataStageIn(void) { ENDPOINT_INFO* pEPinfo = &pInformation->Ctrl_Info; uint32_t save_wLength = pEPinfo->Usb_wLength; uint32_t ControlState = pInformation->ControlState; uint8_t* DataBuffer; uint32_t Length; if((save_wLength == 0) && (ControlState == LAST_IN_DATA)) { if(Data_Mul_MaxPacketSize == TRUE) { /* No more data to send and empty packet */ Send0LengthData(); ControlState = LAST_IN_DATA; Data_Mul_MaxPacketSize = FALSE; } else { /* No more data to send so STALL the TX Status*/ ControlState = WAIT_STATUS_OUT; #ifdef STM32F10X_CL PCD_EP_Read(ENDP0, 0, 0); #endif /* STM32F10X_CL */ #ifndef STM32F10X_CL vSetEPTxStatus(EP_TX_STALL); #endif /* STM32F10X_CL */ } goto Expect_Status_Out; } Length = pEPinfo->PacketSize; ControlState = (save_wLength <= Length) ? LAST_IN_DATA : IN_DATA; if(Length > save_wLength) { Length = save_wLength; } DataBuffer = (*pEPinfo->CopyData)(Length); #ifdef STM32F10X_CL PCD_EP_Write(ENDP0, DataBuffer, Length); #else UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length); #endif /* STM32F10X_CL */ SetEPTxCount(ENDP0, Length); pEPinfo->Usb_wLength -= Length; pEPinfo->Usb_wOffset += Length; vSetEPTxStatus(EP_TX_VALID); USB_StatusOut(); /* Expect the host to abort the data IN stage */ Expect_Status_Out: pInformation->ControlState = ControlState; }
/******************************************************************************* * Function Name : Transfer_Data_Request * Description : Send the request response to the PC HOST. * Input : u8* Data_Address : point to the data to transfer. * u16 Data_Length : the nember of Bytes to transfer. * Output : None. * Return : None. *******************************************************************************/ void Transfer_Data_Request(u8* Data_Pointer, u16 Data_Len) { UserToPMABufferCopy(Data_Pointer, ENDP1_TXADDR, Data_Len); SetEPTxCount(ENDP1, Data_Len); SetEPTxStatus(ENDP1, EP_TX_VALID); Bot_State = BOT_DATA_IN_LAST; CSW.dDataResidue -= Data_Len; CSW.bStatus = CSW_CMD_PASSED; }
//----------------------------------------------------------------- void USB_PutString(u8 *string) { u8 i = 0; u16 timeout = 0; while (string[i++] != 0){} // get string len while (_GetEPTxStatus(ENDP1) != EP_TX_NAK){ if (timeout++ > 60000) return;} UserToPMABufferCopy(string, ENDP1_TXADDR, ++i); // copy string to usb buffer SetEPTxCount(ENDP1,i); SetEPTxValid(ENDP1); }
void Handle_USBAsynchXfer (void) { if( GetEPTxStatus(ENDP1) == EP_TX_VALID) return; int Recv_Size = USART_RecvData(Recv_Buffer); if( Recv_Size ) { UserToPMABufferCopy(Recv_Buffer, ENDP1_TXADDR, Recv_Size); SetEPTxCount(ENDP1, Recv_Size); SetEPTxValid(ENDP1); } }