/******************************************************************************* * Function Name : Mass_Storage_Out * Description : Mass Storage OUT transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Mass_Storage_Out (void) { u8 CMD; CMD = CBW.CB[0]; Data_Len = GetEPRxCount(ENDP2); PMAToUserBufferCopy(Bulk_Data_Buff, ENDP2_RXADDR, Data_Len); switch (Bot_State) { case BOT_IDLE: CBW_Decode(); break; case BOT_DATA_OUT: if (CMD == SCSI_WRITE10) { SCSI_Write10_Cmd(SCSI_LBA , SCSI_BlkLen); break; } Bot_Abort(DIR_OUT); Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE); break; default: Bot_Abort(BOTH_DIR); Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE); break; } }
/******************************************************************************* * Function Name : EP1_OUT_Callback. * Description : EP1 OUT Callback Routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP1_OUT_Callback(void) { u8 DataLen; //保存接收数据的长度 u8 DataBuffer[64]; //保存接收数据的缓冲区 DataLen = GetEPRxCount(ENDP1); //获取收到的长度 PMAToUserBufferCopy(DataBuffer, ENDP1_RXADDR, DataLen); //复制数据 SetEPRxValid(ENDP1); //设置端点有效,以接收下一次数据 if(DataLen==1) //收到一字节的输出报告 { //D0位表示数字键盘灯,D1位表示大写字母锁定灯 // if(DataBuffer[0]&0x01) //数字键盘灯亮 // { // GPIOC->BSRR=(1<<6); //亮LED3 // } // else // { // GPIOC->BRR=(1<<6); //灭LED3 // } // if(DataBuffer[0]&0x02) //大写字母锁定键 // { // GPIOC->BSRR=(1<<7); //亮LED2 // } // else // { // GPIOC->BRR=(1<<7); //灭LED2 // } } }
uint16_t stm32_usbd_ep_get_OUT_count(uint8_t idx) { int8_t index; index = stm32_usbd_ep(idx); if (index < 0) { return 0; } idx = (uint8_t)index; if (stm32_usbd_OUT_dbuffer[idx]) { if(GetENDPOINT(idx) & EP_DTOG_TX) { return GetEPDblBuf1Count(idx); } else { return GetEPDblBuf0Count(idx); } } else { return GetEPRxCount(idx); } }
/******************************************************************************* * Function Name : USB_SIL_Read * Description : Write a buffer of data to a selected endpoint. * Input : - bEpAddr: The address of the non control endpoint. * - pBufferPointer: The pointer to which will be saved the * received data buffer. * Output : None. * Return : Number of received data (in Bytes). *******************************************************************************/ uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer) { uint32_t DataLength = 0; #ifndef STM32F10X_CL /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(bEpAddr & 0x7F); /* Use the memory interface function to write to the selected endpoint */ PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength); #else USB_OTG_EP *ep; /* Get the structure pointer of the selected Endpoint */ ep = PCD_GetOutEP(bEpAddr); /* Get the number of received data */ DataLength = ep->xfer_len; /* Use the PCD interface layer function to read the selected endpoint */ PCD_EP_Read (bEpAddr, pBufferPointer, DataLength); #endif /* STM32F10X_CL */ /* Return the number of received data */ return DataLength; }
///////////////////////////////////////////////////////////////////////////// //! Gets a byte from the receive buffer //! \param[in] usb_com USB_COM number (not supported yet, should always be 0) //! \return -1 if USB_COM not available //! \return -2 if no new byte available //! \return >= 0: received byte //! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_COM layer functions ///////////////////////////////////////////////////////////////////////////// s32 MIOS32_USB_COM_RxBufferGet(u8 usb_com) { #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( !rx_buffer_new_data_ctr ) return -2; // nothing new in buffer // get byte - this operation should be atomic! // MIOS32_IRQ_Disable(); // TODO: access buffer directly, so that we don't need to copy into temporary buffer u8 buffer_out[MIOS32_USB_COM_DATA_OUT_SIZE]; PMAToUserBufferCopy(buffer_out, MIOS32_USB_ENDP3_RXADDR, GetEPRxCount(ENDP3)); u8 b = buffer_out[rx_buffer_ix++]; if( !--rx_buffer_new_data_ctr ) SetEPRxValid(ENDP3); // MIOS32_IRQ_Enable(); return b; // return received byte #endif }
/******************************************************************************* * Function Name : Mass_Storage_Out * Description : Mass Storage OUT transfer. * Input : None. * Output : None. * Return : None. //USB->设备 *******************************************************************************/ void Mass_Storage_Out (void) { u8 CMD; USB_STATUS_REG|=0X10;//标记轮询 CMD = CBW.CB[0]; Data_Len = GetEPRxCount(ENDP4); PMAToUserBufferCopy(Bulk_Data_Buff, ENDP4_RXADDR, Data_Len); //printf("Bot_State_out:%d;Data_Len=%d",Bot_State,Data_Len); switch (Bot_State) { case BOT_IDLE: CBW_Decode(); break; case BOT_DATA_OUT://USB发送数据到设备 if (CMD == SCSI_WRITE10) { USB_STATUS_REG|=0X01;//标记正在写数据 SCSI_Write10_Cmd(CBW.bLUN , SCSI_LBA , SCSI_BlkLen); break; } Bot_Abort(DIR_OUT); Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE); break; default: Bot_Abort(BOTH_DIR); Set_Scsi_Sense_Data(CBW.bLUN, ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND); Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE); break; } }
/******************************************************************************* * Function Name : EP2_OUT_Callback. * Description : EP2 OUT Callback Routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP2_OUT_Callback(void) { USB_R_Size = GetEPRxCount(ENDP2); PMAToUserBufferCopy((u8 *)USB_R_Buffer, ENDP2_RXADDR, USB_R_Size); SetEPRxStatus(ENDP2, EP_RX_VALID); /* enable the next transaction*/ USB_Receive_Flag = 0xff; //Mass_Storage_Out(); }
/******************************************************************************* * Function Name : EP3_OUT_Callback * Description : * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP3_OUT_Callback(void) { Receive_length = GetEPRxCount(ENDP3); // Len data buffers USB. PMAToUserBufferCopy((unsigned char*)Receive_Buffer, ENDP3_RXADDR, Receive_length); //memcpy(&Command_Buffer[len_command], (unsigned char*)Receive_Buffer, Receive_length); //Copy buffers USB -> TEMP. memset((unsigned char*)Receive_Buffer, 0, Receive_length); //Clear buffer USB. SetEPRxValid(ENDP3); }
static void PIOS_USB_CDC_DATA_EP_OUT_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); uint32_t DataLength; /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(usb_cdc_dev->cfg->data_rx_ep); if (DataLength > sizeof(usb_cdc_dev->rx_packet_buffer)) { usb_cdc_dev->rx_oversize++; DataLength = sizeof(usb_cdc_dev->rx_packet_buffer); } /* Use the memory interface function to read from the selected endpoint */ PMAToUserBufferCopy((uint8_t *) usb_cdc_dev->rx_packet_buffer, GetEPRxAddr(usb_cdc_dev->cfg->data_rx_ep), DataLength); if (!usb_cdc_dev->rx_in_cb) { /* No Rx call back registered, disable the receiver */ SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK); return; } uint16_t headroom; bool need_yield = false; uint16_t rc; rc = (usb_cdc_dev->rx_in_cb)(usb_cdc_dev->rx_in_context, usb_cdc_dev->rx_packet_buffer, DataLength, &headroom, &need_yield); if (rc < DataLength) { /* Lost bytes on rx */ usb_cdc_dev->rx_dropped += (DataLength - rc); } if (headroom >= sizeof(usb_cdc_dev->rx_packet_buffer)) { /* We have room for a maximum length message */ SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_VALID); } else { /* Not enough room left for a message, apply backpressure */ SetEPRxStatus(usb_cdc_dev->cfg->data_rx_ep, EP_RX_NAK); } #if defined(PIOS_INCLUDE_FREERTOS) if (need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ }
/******************************************************************************* * Function Name : USB_SIL_Read * Description : Write a buffer of data to a selected endpoint. * Input : - bEpAddr: The address of the non control endpoint. * - pBufferPointer: The pointer to which will be saved the * received data buffer. * Output : None. * Return : Number of received data (in Bytes). *******************************************************************************/ uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer) { uint32_t DataLength = 0; /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(bEpAddr & 0x7F); /* Use the memory interface function to write to the selected endpoint */ PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength); /* Return the number of received data */ return DataLength; }
/******************************************************************************* * Function Name : EP3_OUT_Callback * Description : EP3 OUT Callback Routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP3_OUT_Callback(void) { /* Get the number of received data on the selected Endpoint */ USB_Rx_length = GetEPRxCount(ENDP3); /* Use the memory interface function to write to the selected endpoint */ PMAToUserBufferCopy(USB_Rx_Buffer, ENDP3_RXADDR, USB_Rx_length); /* USB data should be immediately processed, this allow next USB traffic being NAKed till the end of the processing */ USB_Rx_State = 1; USB_Rx_ptr = 0; }
PUBLIC uint32 HW_USB_Read(uint8 bEpAddr, uint8* pBufferPointer, bool SetValid) { uint32 DataLength = 0; /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(bEpAddr & 0x7F); /* Use the memory interface function to write to the selected endpoint */ HwUsbPMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength); if(SetValid) SetEPRxValid(bEpAddr & 0x0F); return DataLength; }
void EP3_OUT_Callback(void) { uint8_t i; UsbRxLength = GetEPRxCount( ENDP3 ); PMAToUserBufferCopy( ( unsigned char* )UsbRxBuffer, ENDP3_RXADDR, UsbRxLength ); for( i = 0; i < UsbRxLength; i++ ) { if( IsFifoFull( &UartUsb.FifoRx ) == false ) { // Read one byte from the receive data register FifoPush( &UartUsb.FifoRx, UsbRxBuffer[i] ); } } if( UartUsb.IrqNotify != NULL ) { UartUsb.IrqNotify( UART_NOTIFY_RX ); } }
/** * EP1 OUT Callback Routine */ static void PIOS_USB_HID_EP_OUT_Callback(void) { struct pios_usb_hid_dev * usb_hid_dev = (struct pios_usb_hid_dev *)pios_usb_hid_id; bool valid = PIOS_USB_HID_validate(usb_hid_dev); PIOS_Assert(valid); uint32_t DataLength; /* Read received data (63 bytes) */ /* Get the number of received data on the selected Endpoint */ DataLength = GetEPRxCount(usb_hid_dev->cfg->data_rx_ep); if (DataLength > sizeof(usb_hid_dev->rx_packet_buffer)) { DataLength = sizeof(usb_hid_dev->rx_packet_buffer); } /* Use the memory interface function to read from the selected endpoint */ PMAToUserBufferCopy((uint8_t *) usb_hid_dev->rx_packet_buffer, GetEPRxAddr(usb_hid_dev->cfg->data_rx_ep), DataLength); if (!usb_hid_dev->rx_in_cb) { /* No Rx call back registered, disable the receiver */ SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK); return; } /* The first byte is report ID (not checked), the second byte is the valid data length */ uint16_t headroom; bool need_yield = false; #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context, &usb_hid_dev->rx_packet_buffer[1], sizeof(usb_hid_dev->rx_packet_buffer)-1, &headroom, &need_yield); #else (usb_hid_dev->rx_in_cb)(usb_hid_dev->rx_in_context, &usb_hid_dev->rx_packet_buffer[2], usb_hid_dev->rx_packet_buffer[1], &headroom, &need_yield); #endif #ifdef PIOS_USB_BOARD_BL_HID_HAS_NO_LENGTH_BYTE uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 1; #else uint16_t max_payload_length = PIOS_USB_BOARD_HID_DATA_LENGTH - 2; #endif if (headroom >= max_payload_length) { /* We have room for a maximum length message */ SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_VALID); } else { /* Not enough room left for a message, apply backpressure */ SetEPRxStatus(usb_hid_dev->cfg->data_rx_ep, EP_RX_NAK); } #if defined(PIOS_INCLUDE_FREERTOS) if (need_yield) { vPortYieldFromISR(); } #endif /* PIOS_INCLUDE_FREERTOS */ }
/******************************************************************************* * Function Name : EP3_OUT_Callback * Description : * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP3_OUT_Callback(void) { packet_receive = 1; Receive_length = GetEPRxCount(ENDP3); PMAToUserBufferCopy((unsigned char*)Receive_Buffer, ENDP3_RXADDR, Receive_length); }
/** * @brief Correct Transfer interrupt's service * @param None * @retval None */ void CTR(void) { USB_EP *ep; uint16_t count=0; uint8_t EPindex; __IO uint16_t wIstr; __IO uint16_t wEPVal = 0; /* stay in loop while pending interrupts */ while (((wIstr = _GetISTR()) & ISTR_CTR) != 0) { /* extract highest priority endpoint number */ EPindex = (uint8_t)(wIstr & ISTR_EP_ID); if (EPindex == 0) { /* Decode and service control endpoint interrupt */ /* DIR bit = origin of the interrupt */ if ((wIstr & ISTR_DIR) == 0) { /* DIR = 0 */ /* DIR = 0 => IN int */ /* DIR = 0 implies that (EP_CTR_TX = 1) always */ _ClearEP_CTR_TX(ENDP0); ep = &((&USB_Device_dev)->dev.in_ep[0]); ep->xfer_count = GetEPTxCount(ep->num); ep->xfer_buff += ep->xfer_count; /* TX COMPLETE */ USBD_DCD_INT_fops->DataInStage(&USB_Device_dev, 0x00); } else { /* DIR = 1 */ /* DIR = 1 & CTR_RX => SETUP or OUT int */ /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ ep = &((&USB_Device_dev)->dev.out_ep[0]); wEPVal = _GetENDPOINT(ENDP0); if ((wEPVal &EP_SETUP) != 0) { /* Get SETUP Packet*/ ep->xfer_count = GetEPRxCount(ep->num); PMAToUserBufferCopy(&((&USB_Device_dev)->dev.setup_packet[0]),ep->pmaadress , ep->xfer_count); /* SETUP bit kept frozen while CTR_RX = 1*/ _ClearEP_CTR_RX(ENDP0); /* Process SETUP Packet*/ USBD_DCD_INT_fops->SetupStage(&USB_Device_dev); } else if ((wEPVal & EP_CTR_RX) != 0) { _ClearEP_CTR_RX(ENDP0); /* Get Control Data OUT Packet*/ ep->xfer_count = GetEPRxCount(ep->num); if (ep->xfer_count != 0) { PMAToUserBufferCopy(ep->xfer_buff, ep->pmaadress, ep->xfer_count); ep->xfer_buff+=ep->xfer_count; } /* Process Control Data OUT Packet*/ USBD_DCD_INT_fops->DataOutStage(&USB_Device_dev, 0x00); _SetEPRxCount(ENDP0, ep->maxpacket); _SetEPRxStatus(ENDP0,EP_RX_VALID); } } }/* if(EPindex == 0) */ else { /* Decode and service non control endpoints interrupt */ /* process related endpoint register */ wEPVal = _GetENDPOINT(EPindex); if ((wEPVal & EP_CTR_RX) != 0) { /* clear int flag */ _ClearEP_CTR_RX(EPindex); ep = &((&USB_Device_dev)->dev.out_ep[EPindex]); /* OUT double Buffering*/ if (ep->doublebuffer == 0) { count = GetEPRxCount(ep->num); if (count != 0) { PMAToUserBufferCopy(ep->xfer_buff, ep->pmaadress, count); } } else { if (GetENDPOINT(ep->num) & EP_DTOG_RX) { /*read from endpoint BUF0Addr buffer*/ count = GetEPDblBuf0Count(ep->num); if (count != 0) { PMAToUserBufferCopy(ep->xfer_buff, ep->pmaaddr0, count); } } else { /*read from endpoint BUF1Addr buffer*/ count = GetEPDblBuf1Count(ep->num); if (count != 0) { PMAToUserBufferCopy(ep->xfer_buff, ep->pmaaddr1, count); } } FreeUserBuffer(ep->num, EP_DBUF_OUT); } /*multi-packet on the NON control OUT endpoint*/ ep->xfer_count+=count; ep->xfer_buff+=count; if ((ep->xfer_len == 0) || (count < ep->maxpacket)) { /* RX COMPLETE */ USBD_DCD_INT_fops->DataOutStage(&USB_Device_dev, ep->num); } else { DCD_EP_PrepareRx (&USB_Device_dev,ep->num, ep->xfer_buff, ep->xfer_len); } } /* if((wEPVal & EP_CTR_RX) */ if ((wEPVal & EP_CTR_TX) != 0) { ep = &((&USB_Device_dev)->dev.in_ep[EPindex]); /* clear int flag */ _ClearEP_CTR_TX(EPindex); /* IN double Buffering*/ if (ep->doublebuffer == 0) { ep->xfer_count = GetEPTxCount(ep->num); if (ep->xfer_count != 0) { UserToPMABufferCopy(ep->xfer_buff, ep->pmaadress, ep->xfer_count); } } else { if (GetENDPOINT(ep->num) & EP_DTOG_TX) { /*read from endpoint BUF0Addr buffer*/ ep->xfer_count = GetEPDblBuf0Count(ep->num); if (ep->xfer_count != 0) { UserToPMABufferCopy(ep->xfer_buff, ep->pmaaddr0, ep->xfer_count); } } else { /*read from endpoint BUF1Addr buffer*/ ep->xfer_count = GetEPDblBuf1Count(ep->num); if (ep->xfer_count != 0) { UserToPMABufferCopy(ep->xfer_buff, ep->pmaaddr1, ep->xfer_count); } } FreeUserBuffer(ep->num, EP_DBUF_IN); } /*multi-packet on the NON control IN endpoint*/ ep->xfer_count =GetEPTxCount(ep->num); ep->xfer_buff+=ep->xfer_count; /* Zero Length Packet? */ if (ep->xfer_len == 0) { /* TX COMPLETE */ USBD_DCD_INT_fops->DataInStage(&USB_Device_dev, ep->num); } else { DCD_EP_Tx (&USB_Device_dev,ep->num, ep->xfer_buff, ep->xfer_len); } } /* if((wEPVal & EP_CTR_TX) != 0) */ }/* if(EPindex == 0) else */ }/* while(...) */ }
///////////////////////////////////////////////////////////////////////////// //! Called by STM32 USB driver to check for OUT streams //! \note Applications shouldn't call this function directly, instead please use \ref MIOS32_COM layer functions ///////////////////////////////////////////////////////////////////////////// void MIOS32_USB_COM_EP3_OUT_Callback(void) { // new data has been received - notify this rx_buffer_new_data_ctr = GetEPRxCount(ENDP3); rx_buffer_ix = 0; }
/******************************************************************************* * Function Name : EP3_OUT_Callback * Description : * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP3_OUT_Callback(void) { receiveLength = GetEPRxCount(ENDP3); // HJI PMAToUserBufferCopy((unsigned char*)receiveBuffer, ENDP3_RXADDR, receiveLength); // HJI }