/** * @brief Submit a new URB for processing * @param hhcd : HCD handle * @param ch_num : Channel number * This parameter can be a value from 1 to 15 * @param direction : Channel number * This parameter can be one of the these values: * 0 : Output * 1 : Input * @param ep_type : Endpoint Type * This parameter can be one of the these values: * @arg EP_TYPE_CTRL: Control type * @arg EP_TYPE_ISOC: Isochrounous type * @arg EP_TYPE_BULK: Bulk type * @arg EP_TYPE_INTR: Interrupt type * @param token : Endpoint Type * This parameter can be one of the these values: * @arg 0: HC_PID_SETUP * @arg 1: HC_PID_DATA1 * @param pbuff : pointer to URB data * @param length : Length of URB data * @param do_ping : activate do ping protocol (for high speed only) * This parameter can be one of the these values: * 0 : do ping inactive * 1 : do ping active * @retval HAL state */ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t direction , uint8_t ep_type, uint8_t token, uint8_t* pbuff, uint16_t length, uint8_t do_ping) { hhcd->hc[ch_num].ep_is_in = direction; hhcd->hc[ch_num].ep_type = ep_type; if(token == 0) { hhcd->hc[ch_num].data_pid = HC_PID_SETUP; } else { hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } /* Manage Data Toggle */ switch(ep_type) { case EP_TYPE_CTRL: if((token == 1) && (direction == 0)) /*send data */ { if ( length == 0 ) { /* For Status OUT stage, Length==0, Status Out PID = 1 */ hhcd->hc[ch_num].toggle_out = 1; } /* Set the Data Toggle bit as per the Flag */ if ( hhcd->hc[ch_num].toggle_out == 0) { /* Put the PID 0 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { /* Put the PID 1 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ; } if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) { hhcd->hc[ch_num].do_ping = do_ping; } } break; case EP_TYPE_BULK: if(direction == 0) { /* Set the Data Toggle bit as per the Flag */ if ( hhcd->hc[ch_num].toggle_out == 0) { /* Put the PID 0 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { /* Put the PID 1 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ; } if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) { hhcd->hc[ch_num].do_ping = do_ping; } } else { if( hhcd->hc[ch_num].toggle_in == 0) { hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } } break; case EP_TYPE_INTR: if(direction == 0) { /* Set the Data Toggle bit as per the Flag */ if ( hhcd->hc[ch_num].toggle_out == 0) { /* Put the PID 0 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { /* Put the PID 1 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ; } } else { if( hhcd->hc[ch_num].toggle_in == 0) { hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } } break; case EP_TYPE_ISOC: hhcd->hc[ch_num].data_pid = HC_PID_DATA0; break; } hhcd->hc[ch_num].xfer_buff = pbuff; hhcd->hc[ch_num].xfer_len = length; hhcd->hc[ch_num].urb_state = URB_IDLE; hhcd->hc[ch_num].xfer_count = 0 ; hhcd->hc[ch_num].ch_num = ch_num; hhcd->hc[ch_num].state = HC_IDLE; return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable); }
/** * @brief Submit a new URB for processing. * @param hhcd: HCD handle * @param ch_num: Channel number. * This parameter can be a value from 1 to 15 * @param direction: Channel number. * This parameter can be one of these values: * 0 : Output / 1 : Input * @param ep_type: Endpoint Type. * This parameter can be one of these values: * EP_TYPE_CTRL: Control type/ * EP_TYPE_ISOC: Isochronous type/ * EP_TYPE_BULK: Bulk type/ * EP_TYPE_INTR: Interrupt type/ * @param token: Endpoint Type. * This parameter can be one of these values: * 0: HC_PID_SETUP / 1: HC_PID_DATA1 * @param pbuff: pointer to URB data * @param length: Length of URB data * @param do_ping: activate do ping protocol (for high speed only). * This parameter can be one of these values: * 0 : do ping inactive / 1 : do ping active * @retval HAL status */ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint8_t ch_num, uint8_t direction , uint8_t ep_type, uint8_t token, uint8_t* pbuff, uint16_t length, uint8_t do_ping) { if ((hhcd->hc[ch_num].ep_is_in != direction)) { if ((hhcd->hc[ch_num].ep_type == EP_TYPE_CTRL)){ /* reconfigure the endpoint !!! from tx -> rx, and rx ->tx */ USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; if (direction) { USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM; USBx_HC(ch_num)->HCCHAR |= 1 << 15; } else { USBx_HC(ch_num)->HCINTMSK &= ~USB_OTG_HCINTMSK_BBERRM; USBx_HC(ch_num)->HCCHAR &= ~(1 << 15); } hhcd->hc[ch_num].ep_is_in = direction; /* if reception put toggle_in to 1 */ if (direction == 1) hhcd->hc[ch_num].toggle_in=1; } } hhcd->hc[ch_num].ep_type = ep_type; if(token == 0) { hhcd->hc[ch_num].data_pid = HC_PID_SETUP; } else { hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } /* Manage Data Toggle */ switch(ep_type) { case EP_TYPE_CTRL: if((token == 1) && (direction == 0)) /*send data */ { if ( length == 0 ) { /* For Status OUT stage, Length==0, Status Out PID = 1 */ hhcd->hc[ch_num].toggle_out = 1; } /* Set the Data Toggle bit as per the Flag */ if ( hhcd->hc[ch_num].toggle_out == 0) { /* Put the PID 0 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { /* Put the PID 1 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ; } if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) { hhcd->hc[ch_num].do_ping = do_ping; } } else if ((token == 1) && (direction == 1)) { if( hhcd->hc[ch_num].toggle_in == 0) { hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } } break; case EP_TYPE_BULK: if(direction == 0) { /* Set the Data Toggle bit as per the Flag */ if ( hhcd->hc[ch_num].toggle_out == 0) { /* Put the PID 0 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { /* Put the PID 1 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ; } if(hhcd->hc[ch_num].urb_state != URB_NOTREADY) { hhcd->hc[ch_num].do_ping = do_ping; } } else { if( hhcd->hc[ch_num].toggle_in == 0) { hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } } break; case EP_TYPE_INTR: if(direction == 0) { /* Set the Data Toggle bit as per the Flag */ if ( hhcd->hc[ch_num].toggle_out == 0) { /* Put the PID 0 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { /* Put the PID 1 */ hhcd->hc[ch_num].data_pid = HC_PID_DATA1 ; } } else { if( hhcd->hc[ch_num].toggle_in == 0) { hhcd->hc[ch_num].data_pid = HC_PID_DATA0; } else { hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } } break; case EP_TYPE_ISOC: hhcd->hc[ch_num].data_pid = HC_PID_DATA0; break; } hhcd->hc[ch_num].xfer_buff = pbuff; hhcd->hc[ch_num].xfer_len = length; hhcd->hc[ch_num].urb_state = URB_IDLE; hhcd->hc[ch_num].xfer_count = 0 ; hhcd->hc[ch_num].ch_num = ch_num; hhcd->hc[ch_num].state = HC_IDLE; return USB_HC_StartXfer(hhcd->Instance, &(hhcd->hc[ch_num]), hhcd->Init.dma_enable); }