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 */ }
/******************************************************************************* * Function Name : DataStageOut. * Description : Data stage of a Control Write Transfer. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void DataStageOut(void) { ENDPOINT_INFO *pEPinfo = &pInformation->Ctrl_Info; uint32_t save_rLength; save_rLength = pEPinfo->Usb_rLength; if (pEPinfo->CopyData && save_rLength) { uint8_t *Buffer; uint32_t Length; Length = pEPinfo->PacketSize; if (Length > save_rLength) { Length = save_rLength; } Buffer = (*pEPinfo->CopyData)(Length); pEPinfo->Usb_rLength -= Length; pEPinfo->Usb_rOffset += Length; PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length); } if (pEPinfo->Usb_rLength != 0) { vSetEPRxStatus(EP_RX_VALID);/* re-enable for next data reception */ SetEPTxCount(ENDP0, 0); vSetEPTxStatus(EP_TX_VALID);/* Expect the host to abort the data OUT stage */ } /* Set the next State*/ if (pEPinfo->Usb_rLength >= pEPinfo->PacketSize) { pInformation->ControlState = OUT_DATA; } else { if (pEPinfo->Usb_rLength > 0) { pInformation->ControlState = LAST_OUT_DATA; } else if (pEPinfo->Usb_rLength == 0) { pInformation->ControlState = WAIT_STATUS_IN; USB_StatusIn(); } } }
/******************************************************************************* * Function Name : Read_Memory * Description : Handle the Read operation from the microSD card. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Read_Memory(uint8_t lun, uint32_t Memory_Offset, uint32_t Transfer_Length) { static uint32_t 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]); USB_SIL_Write(EP2_IN, (uint8_t *)Data_Buffer, BULK_MAX_PACKET_SIZE); Block_Read_count = Mass_Block_Size[lun] - BULK_MAX_PACKET_SIZE; Block_offset = BULK_MAX_PACKET_SIZE; } else { USB_SIL_Write(EP2_IN, (uint8_t *)Data_Buffer + Block_offset, BULK_MAX_PACKET_SIZE); Block_Read_count -= BULK_MAX_PACKET_SIZE; Block_offset += BULK_MAX_PACKET_SIZE; } SetEPTxCount(ENDP2, BULK_MAX_PACKET_SIZE); SetEPTxStatus(ENDP2, EP_TX_VALID); Offset += BULK_MAX_PACKET_SIZE; Length -= BULK_MAX_PACKET_SIZE; CSW.dDataResidue -= BULK_MAX_PACKET_SIZE; } if (Length == 0) { Block_Read_count = 0; Block_offset = 0; Offset = 0; Bot_State = BOT_DATA_IN_LAST; TransferState = TXFR_IDLE; } }
/******************************************************************************* * 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(); } }
/******************************************************************************* * Function Name : UART_To_USB_Send_Data. * Description : send the received data from UART 0 to USB. * Input : None. * Return : none. *******************************************************************************/ void USART_To_USB_Send_Data(void) { if (USART_InitStructure.USART_WordLength == USART_WordLength_8b) { buffer_in[count_in] = USART_ReceiveData(USART1) & 0x7F; } else if (USART_InitStructure.USART_WordLength == USART_WordLength_9b) { buffer_in[count_in] = USART_ReceiveData(USART1); } count_in++; UserToPMABufferCopy(buffer_in, ENDP1_TXADDR, count_in); SetEPTxCount(ENDP1, count_in); SetEPTxValid(ENDP1); }
/******************************************************************************* * Function Name : Set_CSW * Description : Set the SCW with the needed fields. * Input : u8 CSW_Status this filed can be CSW_CMD_PASSED,CSW_CMD_FAILED, * or CSW_PHASE_ERROR. * Output : None. * Return : None. *******************************************************************************/ void Set_CSW (u8 CSW_Status, u8 Send_Permission) { CSW.dSignature = BOT_CSW_SIGNATURE; CSW.bStatus = CSW_Status; UserToPMABufferCopy(((u8 *)& CSW), ENDP1_TXADDR, CSW_DATA_LENGTH); SetEPTxCount(ENDP1, CSW_DATA_LENGTH); Bot_State = BOT_ERROR; if (Send_Permission) { Bot_State = BOT_CSW_Send; SetEPTxStatus(ENDP1, EP_TX_VALID); } }
// // 仮想COMポートからのデータをPC側に返送する. // void EP1_IN_Callback (void) { #if 0 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); } #if LED_DEBUG led2_blink(0); #endif #endif countTx = 0; }
/** * send data to USB. */ void usb_send_data(void) { uint8_t txBuffer[VIRTUAL_COM_PORT_DATA_SIZE]; uint16_t txCount; if (g_usb_deviceState != CONFIGURED) { return; } txCount = min(usb_tx_ring_buffer.available, VIRTUAL_COM_PORT_DATA_SIZE); if (txCount > 0) { ring_buffer_read(&usb_tx_ring_buffer, txBuffer, txCount); UserToPMABufferCopy(txBuffer, ENDP1_TXADDR, txCount); SetEPTxCount(ENDP1, txCount); 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; } 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: pInformation->ControlState = ControlState; }
uint8_t UartUsbPutChar( Uart_t *obj, uint8_t data ) { if( UsbMcuIsDeviceConfigured( ) == false ) { return 2; } if( IsFifoFull( &obj->FifoTx ) == false ) { __disable_irq( ); FifoPush( &obj->FifoTx, data ); __enable_irq( ); if( UsbPacketTx == 1 ) { /*Sent flag*/ UsbPacketTx = 0; SetEPTxCount( ENDP1, 0 ); SetEPTxValid( ENDP1 ); } return 0; // OK } return 1; // Busy // if( UsbPacketTx == 1 ) // { // /*Sent flag*/ // UsbPacketTx = 0; // /* send packet to PMA*/ // UserToPMABufferCopy( ( unsigned char* )&data, ENDP1_TXADDR, 1 ); // SetEPTxCount( ENDP1, 1 ); // SetEPTxValid( ENDP1 ); // return 0; // OK // } // else // { // if( IsFifoFull( &obj->FifoTx ) == false ) // { // __disable_irq( ); // FifoPush( &obj->FifoTx, data ); // __enable_irq( ); // return 0; // OK // } // } // return 1; // Busy }
/******************************************************************************* * Function Name : PIOS_HID_Reset. * Description : Custom HID reset routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void PIOS_HID_Reset(void) { /* Set Joystick_DEVICE as not configured */ pInformation->Current_Configuration = 0; pInformation->Current_Interface = 0;/*the default Interface*/ /* Current Feature initialization */ pInformation->Current_Feature = PIOS_HID_ConfigDescriptor[7]; #ifdef STM32F10X_CL /* EP0 is already configured in DFU_Init() by USB_SIL_Init() function */ /* Init EP1 IN as Interrupt endpoint */ OTG_DEV_EP_Init(EP1_IN, OTG_DEV_EP_TYPE_INT, 2); /* Init EP1 OUT as Interrupt endpoint */ OTG_DEV_EP_Init(EP1_OUT, OTG_DEV_EP_TYPE_INT, 2); #else SetBTABLE(BTABLE_ADDRESS); /* Initialize Endpoint 0 */ SetEPType(ENDP0, EP_CONTROL); SetEPTxStatus(ENDP0, EP_TX_STALL); SetEPRxAddr(ENDP0, ENDP0_RXADDR); SetEPTxAddr(ENDP0, ENDP0_TXADDR); Clear_Status_Out(ENDP0); SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); SetEPRxValid(ENDP0); /* Initialize Endpoint 1 */ SetEPType(ENDP1, EP_INTERRUPT); SetEPTxAddr(ENDP1, ENDP1_TXADDR); SetEPRxAddr(ENDP1, ENDP1_RXADDR); SetEPTxCount(ENDP1, PIOS_USB_HID_DATA_LENGTH+2); /* add two for indicating report id and valid data length */ SetEPRxCount(ENDP1, PIOS_USB_HID_DATA_LENGTH+2); SetEPRxStatus(ENDP1, EP_RX_VALID); SetEPTxStatus(ENDP1, EP_TX_NAK); /* Set this device to response on default address */ SetDeviceAddress(0); #endif /* STM32F10X_CL */ bDeviceState = ATTACHED; }
/******************************************************************************* * 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) { #ifndef STM32F10X_CL /* 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); #else /* Use the PCD interface layer function to write to the selected endpoint */ PCD_EP_Write (bEpAddr, pBufferPointer, wBufferSize); #endif /* STM32F10X_CL */ return 0; }
void monkey_ep_reset(void) { int i; /* Set Joystick_DEVICE as not configured */ pInformation->Current_Configuration = 0; pInformation->Current_Interface = 0;/*the default Interface*/ /* Current Feature initialization */ pInformation->Current_Feature = config1_descriptor[7]; for(i=0; i<8; ++i) { if(ep_conf_list[i].direct==0) continue; switch(ep_conf_list[i].attr) { case 0x00: SetEPType(i, EP_BULK); ClearEPDoubleBuff(i); break; case 0x01: SetEPType(i, EP_CONTROL); Clear_Status_Out(i); break; case 0x02: SetEPType(i, EP_ISOCHRONOUS); break; case 0x03: SetEPType(i, EP_INTERRUPT); break; } if(ep_conf_list[i].direct & EP_IN) { SetEPTxStatus(i, ep_conf_list[i].tx_status); SetEPTxAddr(i, ep_conf_list[i].tx_addr); SetEPTxCount(i, ep_conf_list[i].tx_max); } if(ep_conf_list[i].direct & EP_OUT) { SetEPRxAddr(i, ep_conf_list[i].rx_addr); SetEPRxCount(i, ep_conf_list[i].rx_max); SetEPRxStatus(i, ep_conf_list[i].rx_status); } } }
/******************************************************************************* * Function Name : EP1_IN_Callback * Description : * 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 (caribou_bytequeue_level(caribou_uart_rx_queue(CONSOLE_USART)) == 0) { USB_Tx_State = 0; } else { USB_Tx_length = caribou_bytequeue_gets(caribou_uart_rx_queue(CONSOLE_USART),USART_Rx_Buffer,VIRTUAL_COM_PORT_DATA_SIZE); UserToPMABufferCopy(&USART_Rx_Buffer, ENDP1_TXADDR, USB_Tx_length); SetEPTxCount(ENDP1, USB_Tx_length); SetEPTxValid(ENDP1); } } }
static void PIOS_USB_RCTX_SendReport(struct pios_usb_rctx_dev *usb_rctx_dev) { #ifdef PIOS_INCLUDE_FREERTOS bool need_yield = false; #endif /* PIOS_INCLUDE_FREERTOS */ usb_rctx_dev->report.id = 3; /* FIXME: shouldn't hard-code this report ID */ UserToPMABufferCopy((uint8_t *)&usb_rctx_dev->report, GetEPTxAddr(usb_rctx_dev->cfg->data_tx_ep), sizeof(usb_rctx_dev->report)); SetEPTxCount(usb_rctx_dev->cfg->data_tx_ep, sizeof(usb_rctx_dev->report)); SetEPTxValid(usb_rctx_dev->cfg->data_tx_ep); #ifdef PIOS_INCLUDE_FREERTOS if (need_yield) { vPortYield(); } #endif /* PIOS_INCLUDE_FREERTOS */ }
void EP1_IN_Callback (void) { UsbPacketTx = 1; UsbTxLength = 0; while( IsFifoEmpty( &UartUsb.FifoTx ) == false ) { UsbTxBuffer[UsbTxLength] = FifoPop( &UartUsb.FifoTx ); UsbTxLength++; } if( UsbTxLength > 0 ) { UsbPacketTx = 0; UserToPMABufferCopy( ( unsigned char* )UsbTxBuffer, ENDP1_TXADDR, UsbTxLength ); SetEPTxCount( ENDP1, UsbTxLength ); SetEPTxValid( ENDP1 ); } }
/* * This code has been adapted from the ST Microelectronics CDC * Example, which is covered under the V2 Liberty License: * http://www.st.com/software_license_agreement_liberty_v2 */ static void usb_handle_transfer(void) { portBASE_TYPE hpta = false; xQueueHandle queue = serial_get_tx_queue(usb_state.serial); uint8_t *buff = usb_state.USB_Tx_Buffer; size_t len = 0; for (; len < VIRTUAL_COM_PORT_DATA_SIZE; ++len) if (!xQueueReceiveFromISR(queue, buff + len, &hpta)) break; /* Check if we actually have something to send */ if (len) { UserToPMABufferCopy(usb_state.USB_Tx_Buffer, ENDP1_TXADDR, len); SetEPTxCount(ENDP1, len); SetEPTxValid(ENDP1); } portEND_SWITCHING_ISR(hpta); }
/******************************************************************************* * Function Name : EP1_IN_Callback * Description : * 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 > 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; } #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 } } }
/******************************************************************************* * Function Name : Read_Memory * Description : Handle the Read operation from the microSD card. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void Read_Memory(void) { //unsigned int a=0,b=0; NAND_ADDRESS Nand_Addr; // GPIO_SetBits(GPIOB, GPIO_Pin_5); if (!Block_Read_count) { //NAND_ConvertOffsetToAddress(Memory_Offset, 64, &Nand_Addr); NAND_ConvertOffsetToAddress(Memory_Offset, 2048, &Nand_Addr); NAND_ReadSmallPage(Data1_Buffer, Nand_Addr, 1); //NAND_ReadSpareArea(Data1_Buffer, Nand_Addr, 1); UserToPMABufferCopy(Data1_Buffer, ENDP1_TXADDR, BULK_MAX_PACKET_SIZE); Block_Read_count = 2048 - BULK_MAX_PACKET_SIZE; //Block_Read_count = 64 - BULK_MAX_PACKET_SIZE; Block_offset = BULK_MAX_PACKET_SIZE; } else { UserToPMABufferCopy(Data1_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; //Led_RW_ON(); if (Transfer_Length == 0) { Block_Read_count = 0; Block_offset = 0; Memory_Offset = 0; Bot_State = BOT_DATA_IN_LAST; //Led_RW_OFF(); } }
/******************************************************************************* * 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; u32 save_wLength = pEPinfo->Usb_wLength; u32 ControlState = pInformation->ControlState; u8 *DataBuffer; u32 Length; if ((save_wLength == 0) && (ControlState == LAST_IN_DATA)) { /* no more data to send so STALL the TX Status*/ ControlState = WAIT_STATUS_OUT; vSetEPTxStatus(EP_TX_STALL); 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); 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: pInformation->ControlState = ControlState; }
/******************************************************************************* * Function Name : OTPWriter_Reset. * Description : OTPWriter Mouse reset routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void OTPWriter_Reset(void) { /* Set OTPWriter_DEVICE as not configured */ pInformation->Current_Configuration = 0; pInformation->Current_Interface = 0;/*the default Interface*/ /* Current Feature initialization */ pInformation->Current_Feature = OTPWriter_ConfigDescriptor[7]; SetBTABLE(BTABLE_ADDRESS); /* Initialize Endpoint 0 */ SetEPType(ENDP0, EP_CONTROL); SetEPTxStatus(ENDP0, EP_TX_STALL); SetEPRxAddr(ENDP0, ENDP0_RXADDR); SetEPTxAddr(ENDP0, ENDP0_TXADDR); Clear_Status_Out(ENDP0); SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); SetEPRxValid(ENDP0); /* Initialize Endpoint 1 */ SetEPType(ENDP1, EP_INTERRUPT); SetEPRxAddr(ENDP1, ENDP1_RXADDR); SetEPRxCount(ENDP1, ReceiveLength); SetEPRxStatus(ENDP1, EP_RX_VALID); //SetEPTxStatus(ENDP1, EP_TX_DIS); /* Initialize Endpoint 2 */ SetEPType(ENDP2, EP_INTERRUPT); SetEPTxAddr(ENDP2, ENDP2_TXADDR); SetEPTxCount(ENDP2, SendLength); // SetEPTxStatus(ENDP2, EP_TX_DIS); SetEPTxStatus(ENDP2, EP_TX_NAK); bDeviceState = ATTACHED; /* Set this device to response on default address */ SetDeviceAddress(0); }
void EP7_IN_Callback (void) { if (USB_Tx_State == 1) { u8_t *buf; int avail = ringbuf_available_linear(&tx_rb, &buf); if (avail == 0) { USB_Tx_State = 0; return; } if (avail > VIRTUAL_COM_PORT_DATA_SIZE) { avail = VIRTUAL_COM_PORT_DATA_SIZE; } UserToPMABufferCopy(buf, ENDP7_TXADDR, avail); ringbuf_get(&tx_rb, 0, avail); SetEPTxCount(ENDP7, avail); SetEPTxValid(ENDP7); } }
/******************************************************************************* * Function Name : CustomHID_Reset. * Description : Custom HID reset routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void CustomHID_Reset(void) { /* Set Joystick_DEVICE as not configured */ pInformation->Current_Configuration = 0; pInformation->Current_Interface = 0;/*the default Interface*/ /* Current Feature initialization */ pInformation->Current_Feature = CustomHID_ConfigDescriptor[7]; *(volatile unsigned *)(0x40005C50L)=(0x00&0xFFF8);//设置USB分组缓冲区描述表起始地址:0 /* Initialize Endpoint 0 */ //设置EP0控制端点 ENDP0 ((u8)0) EP_CONTROL (0x0200) *(((volatile unsigned *)(0x40005C00L)) + ENDP0)=((_GetENDPOINT(ENDP0) & 0x898f) | EP_CONTROL); SetEPTxStatus(ENDP0, EP_TX_STALL); //设置EP0端点发送延迟 SetEPRxAddr(ENDP0, ENDP0_RXADDR); //设置EP0的接受地址 ENDP0_RXADDR (0x18) SetEPTxAddr(ENDP0, ENDP0_TXADDR); //设置EP0的发送地址 ENDP0_TXADDR (0x58) _ClearEP_KIND(ENDP0); //设置端点EP0的类型DBL_BUF 双缓冲端点 SetEPRxCount(ENDP0, Device_Property.MaxPacketSize); //设置EP0的计数器的值 _SetEPRxStatus(ENDP0, EP_RX_VALID); //设置端点接受有效 EP_RX_VALID=0x3000 /* Initialize Endpoint 1 */ SetEPType(ENDP1, EP_INTERRUPT); SetEPRxAddr(ENDP1, ENDP1_RXADDR); //ADDR内部寄存器被用作当前缓冲区的指针 ENDP1_RXADDR=(0x98) SetEPRxCount(ENDP1, 22); //COUNT寄存器用于记录剩下未传输的字节数 SetEPRxStatus(ENDP1, EP_RX_VALID); //设置端点接受有效 EP_RX_VALID=0x3000 /* Initialize Endpoint 2 */ SetEPType(ENDP2, EP_INTERRUPT); SetEPTxAddr(ENDP2, ENDP2_TXADDR); SetEPTxCount(ENDP2, 22); SetEPTxStatus(ENDP2, EP_TX_NAK);//设置端点发送不应答 EP_TX_NAK=(0x0020) bDeviceState = ATTACHED; //ATTACHED=1 /* Set this device to response on default address */ SetDeviceAddress(0); }
/******************************************************************************* * Function Name : EP1_IN_Callback * Description : * 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 > 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; } UserToPMABufferCopy(&USART_Rx_Buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length); SetEPTxCount(ENDP1, USB_Tx_length); SetEPTxValid(ENDP1); //dbg_print("USB Tx\r\n"); } } }
vsf_err_t stm32_usbd_ep_set_IN_epsize(uint8_t idx, uint16_t epsize) { int8_t index; index = stm32_usbd_get_ep(idx); if (index < 0) { return VSFERR_FAIL; } idx = (uint8_t)index; if ((EP_Cfg_Ptr - epsize) < STM32_USBD_EP_NUM * 8) { return VSFERR_NOT_ENOUGH_RESOURCES; } stm32_usbd_IN_epsize[idx] = epsize; SetEPTxCount(idx, epsize); // fix for 16-bit aligned memory EP_Cfg_Ptr -= epsize & 1 ? epsize + 1 : epsize; SetEPTxAddr(idx, EP_Cfg_Ptr); SetEPTxStatus(idx, EP_TX_NAK); return VSFERR_NONE; }
/******************************************************************************* * Function Name : NoData_Setup0. * Description : Proceed the processing of setup request without data stage. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void NoData_Setup0(void) { RESULT Result = USB_UNSUPPORT; uint32_t RequestNo = pInformation->USBbRequest; uint32_t ControlState; if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) { // Device Request // SET_CONFIGURATION if (RequestNo == SET_CONFIGURATION) Result = Standard_SetConfiguration(); // SET ADDRESS else if (RequestNo == SET_ADDRESS) { if ((pInformation->USBwValue0 > 127) || (pInformation->USBwValue1 != 0) || (pInformation->USBwIndex != 0) || (pInformation->Current_Configuration != 0)) { // Device Address should be 127 or less ControlState = STALLED; pInformation->ControlState = ControlState; return; } else Result = USB_SUCCESS; } else if (RequestNo == SET_FEATURE) { // SET FEATURE for Device if ((pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP) && (pInformation->USBwIndex == 0)) { Result = Standard_SetDeviceFeature(); } else { Result = USB_UNSUPPORT; } } else if (RequestNo == CLEAR_FEATURE) { // Clear FEATURE for Device if (pInformation->USBwValue0 == DEVICE_REMOTE_WAKEUP && pInformation->USBwIndex == 0 && ValBit(pInformation->Current_Feature, 5)) { Result = Standard_ClearFeature(); } else { Result = USB_UNSUPPORT; } } } else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) { // Interface Request // SET INTERFACE if (RequestNo == SET_INTERFACE) Result = Standard_SetInterface(); } else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT)) { // EndPoint Request // CLEAR FEATURE for EndPoint if (RequestNo == CLEAR_FEATURE) { Result = Standard_ClearFeature(); } else if (RequestNo == SET_FEATURE) { // SET FEATURE for EndPoint Result = Standard_SetEndPointFeature(); } } else Result = USB_UNSUPPORT; if (Result != USB_SUCCESS) { Result = (*pProperty->Class_NoData_Setup)(RequestNo); if (Result == USB_NOT_READY) { ControlState = PAUSE; pInformation->ControlState = ControlState; return; } } if (Result != USB_SUCCESS) { ControlState = STALLED; pInformation->ControlState = ControlState; return; } ControlState = WAIT_STATUS_IN; // After no data stage SETUP SetEPTxCount(ENDP0,0); SaveTState = EP_TX_VALID; pInformation->ControlState = ControlState; return; }
/******************************************************************************* * Function Name : EP1_Send_Callback. * Description : EP1 Sending data Callback Routine. * Input : None. * Output : None. * Return : None. *******************************************************************************/ void EP1_Send_Callback(void) { UserToPMABufferCopy((u8 *)USB_S_Buffer, ENDP1_TXADDR, USB_S_Size); SetEPTxCount(ENDP1, USB_S_Size); SetEPTxStatus(ENDP1, EP_TX_VALID); }
void dfu_main(void) { int send_report; uint8_t kbd_report_loc[KBD_SIZE]; #if defined (USE_STM32L152D_EVAL) FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_OPTVERRUSR); #endif Pointer = (uint32_t)&_application_start; DeviceState = STATE_dfuERROR; DeviceStatus[0] = STATUS_ERRFIRMWARE; DeviceStatus[4] = DeviceState; usb_cable_reset(); Set_System(); matrix_init_all(); led_init_all(); matrix_scan_init(); leds_override = LEDS_OVERRIDE_STARTUP; usb_report_sent = 1; Set_USBClock(); USB_Init(); matrix_scan_start(); /* Main loop */ send_report = 0; while (1){ if (unlikely(do_usb_resume)){ /* Check if the remote wakeup feature is enabled (it could be disabled * by the host through ClearFeature request) */ if (bDeviceState != SUSPENDED) { /* do nothing */ do_usb_resume = 0; } else if (usb_remote_wakeup_enabled()) { Resume(RESUME_INTERNAL); do_usb_resume = 0; } else { /* resume disabled, disable kbd-triggered wakeup and go to the suspend state */ matrix_idle_wakeup_event_leave(); /* clear flag before suspend * because the flag can be set again on resume */ do_usb_resume = 0; Suspend_Low(); } continue; } if (bDeviceState != CONFIGURED){ __WFI(); /* Wait for interrupt */ continue; } if (unlikely(leds_override)){ handle_leds_override(); } __disable_irq(); if ((kbd_report_status & REPORT_STATUS_DONE) && usb_report_sent){ kbd_report_status &= ~REPORT_STATUS_DONE; send_report = 1; memcpy((void*)kbd_report_loc, (void*)kbd_report_fullscan, KBD_SIZE); } if (unlikely((usb_report_idle_timer == 0) && (usb_report_idle != 0))){ send_report = 1; usb_report_idle_timer = usb_report_idle; } __enable_irq(); if (send_report){ usb_report_sent = 0; send_report = 0; USB_SIL_Write(EP1_IN, kbd_report_loc, KBD_SIZE); SetEPTxCount(ENDP1, KBD_SIZE); SetEPTxValid(ENDP1); } __WFI(); /* Wait for interrupt */ } }
void usb_SendData(unsigned char *pData, int length) { volatile int i = 0; unsigned int delay_cnt; #if (USB_DEVICE_CONFIG & _USE_USB_VIRTUAL_COMM_DEVICE) int batch = length/VIRTUAL_COM_PORT_DATA_SIZE; int res = length%VIRTUAL_COM_PORT_DATA_SIZE; #endif #if(USB_DEVICE_CONFIG & _USE_USB_KEYBOARD_DEVICE) if (g_usb_type == USB_KEYBOARD) //按键 { count_in = length; UserToPMABufferCopy(pData, GetEPTxAddr(ENDP1), count_in); SetEPTxCount(ENDP1, count_in); /* enable endpoint for transmission */ SetEPTxValid(ENDP1); //StartDelay(600); //3S的延时 delay_cnt = 300; while (count_in != 0 && delay_cnt != 0 &&(bDeviceState == CONFIGURED)) { delay_cnt--; delay_ms(10); } } else #elif (USB_DEVICE_CONFIG & _USE_USB_VIRTUAL_COMM_DEVICE) if(g_usb_type == USB_VIRTUAL_PORT) { for (i = 0; i < batch; i++) { count_in = VIRTUAL_COM_PORT_DATA_SIZE; UserToPMABufferCopy(pData+i*VIRTUAL_COM_PORT_DATA_SIZE, ENDP1_TXADDR, count_in); SetEPTxCount(ENDP1, count_in); SetEPTxValid(ENDP1); //StartDelay(600); delay_cnt = 300; while (count_in != 0 && delay_cnt != 0 && (bDeviceState == CONFIGURED)) { delay_cnt--; delay_ms(10); } } if (res > 0) { //最后一包 count_in = res; UserToPMABufferCopy(pData+batch*VIRTUAL_COM_PORT_DATA_SIZE, ENDP1_TXADDR, count_in); SetEPTxCount(ENDP1, count_in); SetEPTxValid(ENDP1); //StartDelay(600); delay_cnt = 300; while (count_in != 0 && delay_cnt != 0 &&(bDeviceState == CONFIGURED)) { delay_cnt--; delay_ms(10); } } }//Virtual port else #elif (USB_DEVICE_CONFIG & _USE_USB_MASS_STOARGE_DEVICE) #ifdef DUMMY_FAT_FS if((g_usb_type == USB_MASSSTORAGE)&&(g_mass_storage_device_type == MASSTORAGE_DEVICE_TYPE_DUMMY_FAT)) { if (length > G_SEND_BUF_LENGTH) { length = G_SEND_BUF_LENGTH; } MEMCPY(g_send_buff,pData,length); }//USB_Masstorage #endif #endif ; }
void SendData_To_PC(unsigned char *pData, int length) { volatile int i = 0; int batch = length/VIRTUAL_COM_PORT_DATA_SIZE; int res = length%VIRTUAL_COM_PORT_DATA_SIZE; unsigned int delay_cnt; if (g_usb_type == USB_KEYBOARD) //按键 { count_in = length; UserToPMABufferCopy(pData, GetEPTxAddr(ENDP1), count_in); SetEPTxCount(ENDP1, count_in); /* enable endpoint for transmission */ SetEPTxValid(ENDP1); //StartDelay(600); //3S的延时 delay_cnt = 300; while (count_in != 0 && delay_cnt != 0 &&(bDeviceState == CONFIGURED)) { delay_cnt--; Delay(20000); } } else if(g_usb_type == USB_VIRTUAL_PORT) { for (i = 0; i < batch; i++) { count_in = VIRTUAL_COM_PORT_DATA_SIZE; UserToPMABufferCopy(pData+i*VIRTUAL_COM_PORT_DATA_SIZE, ENDP1_TXADDR, count_in); SetEPTxCount(ENDP1, count_in); SetEPTxValid(ENDP1); //StartDelay(600); delay_cnt = 300; while (count_in != 0 && delay_cnt != 0 && (bDeviceState == CONFIGURED)) { delay_cnt--; Delay(20000); } } if (res > 0) { //最后一包 count_in = res; UserToPMABufferCopy(pData+batch*VIRTUAL_COM_PORT_DATA_SIZE, ENDP1_TXADDR, count_in); SetEPTxCount(ENDP1, count_in); SetEPTxValid(ENDP1); //StartDelay(600); delay_cnt = 300; while (count_in != 0 && delay_cnt != 0 &&(bDeviceState == CONFIGURED)) { delay_cnt--; Delay(20000); } } }//Virtual port else { if (length > G_SEND_BUF_LENGTH) { length = G_SEND_BUF_LENGTH; } memcpy(g_send_buff,pData,length); }//USB_Masstorage }