diff --git a/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_hcd.c b/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_hcd.c index e2ba96d481..4f49587a87 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_hcd.c +++ b/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_hal_hcd.c @@ -200,7 +200,10 @@ HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, hhcd->hc[ch_num].ep_num = epnum & 0x7FU; hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80U) == 0x80U); hhcd->hc[ch_num].speed = speed; - + /* reset to 0 */ + hhcd->hc[ch_num].toggle_out = 0; + hhcd->hc[ch_num].toggle_in = 0; + status = USB_HC_Init(hhcd->Instance, ch_num, epnum, @@ -335,7 +338,26 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint16_t length, uint8_t do_ping) { - hhcd->hc[ch_num].ep_is_in = direction; + 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) @@ -372,6 +394,18 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, 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: @@ -402,7 +436,7 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } } - + break; case EP_TYPE_INTR: if(direction == 0U) @@ -429,7 +463,7 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, } } break; - + case EP_TYPE_ISOC: hhcd->hc[ch_num].data_pid = HC_PID_DATA0; break; @@ -866,6 +900,8 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) } else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) { + + int reactivate = 0; __HAL_HCD_MASK_HALT_HC_INT(chnum); if(hhcd->hc[chnum].state == HC_XFRC) @@ -896,9 +932,10 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) tmpreg &= ~USB_OTG_HCCHAR_CHDIS; tmpreg |= USB_OTG_HCCHAR_CHENA; USBx_HC(chnum)->HCCHAR = tmpreg; + reactivate = 1; } __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); - HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + if (reactivate == 0) HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); } else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) diff --git a/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_ll_usb.c b/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_ll_usb.c index d49b33325e..85dbca6514 100644 --- a/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_ll_usb.c +++ b/targets/TARGET_STM/TARGET_STM32F2/device/stm32f2xx_ll_usb.c @@ -1518,6 +1518,7 @@ HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDe /* Write packet into the Tx FIFO. */ USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0); + hc->xfer_count = hc->xfer_len; } } diff --git a/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_hal_hcd.c b/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_hal_hcd.c index 44d6840605..25a8e574df 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_hal_hcd.c +++ b/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_hal_hcd.c @@ -204,7 +204,10 @@ HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, hhcd->hc[ch_num].ep_num = epnum & 0x7FU; hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80U) == 0x80U); hhcd->hc[ch_num].speed = speed; - + /* reset to 0 */ + hhcd->hc[ch_num].toggle_out = 0; + hhcd->hc[ch_num].toggle_in = 0; + status = USB_HC_Init(hhcd->Instance, ch_num, epnum, @@ -339,9 +342,27 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint16_t length, uint8_t do_ping) { - hhcd->hc[ch_num].ep_is_in = direction; - hhcd->hc[ch_num].ep_type = ep_type; - + 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 == 0U) { hhcd->hc[ch_num].data_pid = HC_PID_SETUP; @@ -376,6 +397,17 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, 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: @@ -870,20 +902,21 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) } else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) { + int reactivate=0; __HAL_HCD_MASK_HALT_HC_INT(chnum); - + if(hhcd->hc[chnum].state == HC_XFRC) { hhcd->hc[chnum].urb_state = URB_DONE; } - + else if (hhcd->hc[chnum].state == HC_STALL) { hhcd->hc[chnum].urb_state = URB_STALL; } - + else if((hhcd->hc[chnum].state == HC_XACTERR) || - (hhcd->hc[chnum].state == HC_DATATGLERR)) + (hhcd->hc[chnum].state == HC_DATATGLERR)) { if(hhcd->hc[chnum].ErrCnt++ > 3U) { @@ -894,15 +927,16 @@ static void HCD_HC_IN_IRQHandler(HCD_HandleTypeDef *hhcd, uint8_t chnum) { hhcd->hc[chnum].urb_state = URB_NOTREADY; } - + /* re-activate the channel */ tmpreg = USBx_HC(chnum)->HCCHAR; tmpreg &= ~USB_OTG_HCCHAR_CHDIS; tmpreg |= USB_OTG_HCCHAR_CHENA; USBx_HC(chnum)->HCCHAR = tmpreg; + reactivate = 1; } __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); - HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + if (reactivate == 0) HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); } else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) diff --git a/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_ll_usb.c b/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_ll_usb.c index 0f6def20fc..702c45aaa0 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_ll_usb.c +++ b/targets/TARGET_STM/TARGET_STM32F4/device/stm32f4xx_ll_usb.c @@ -1540,6 +1540,7 @@ HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDe /* Write packet into the Tx FIFO. */ USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0); + hc->xfer_count = hc->xfer_len; } } diff --git a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_hcd.c b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_hcd.c index a49717bb89..1ac92a912b 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_hcd.c +++ b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_hal_hcd.c @@ -200,6 +200,9 @@ HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, hhcd->hc[ch_num].ep_num = epnum & 0x7F; hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80) == 0x80); hhcd->hc[ch_num].speed = speed; + /* reset to 0 */ + hhcd->hc[ch_num].toggle_out = 0; + hhcd->hc[ch_num].toggle_in = 0; status = USB_HC_Init(hhcd->Instance, ch_num, @@ -337,9 +340,27 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint16_t length, uint8_t do_ping) { - hhcd->hc[ch_num].ep_is_in = direction; - hhcd->hc[ch_num].ep_type = ep_type; - + 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; @@ -348,7 +369,7 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, { hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } - + /* Manage Data Toggle */ switch(ep_type) { @@ -359,7 +380,7 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, { /* 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 */ @@ -374,8 +395,20 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, 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) { @@ -404,7 +437,7 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, hhcd->hc[ch_num].data_pid = HC_PID_DATA1; } } - + break; case EP_TYPE_INTR: if(direction == 0) @@ -870,7 +903,8 @@ static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum) } else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) { - __HAL_HCD_MASK_HALT_HC_INT(chnum); + int reactivate = 0; + __HAL_HCD_MASK_HALT_HC_INT(chnum); if(hhcd->hc[chnum].state == HC_XFRC) { @@ -894,15 +928,16 @@ static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum) { hhcd->hc[chnum].urb_state = URB_NOTREADY; } - + /* re-activate the channel */ tmpreg = USBx_HC(chnum)->HCCHAR; tmpreg &= ~USB_OTG_HCCHAR_CHDIS; tmpreg |= USB_OTG_HCCHAR_CHENA; - USBx_HC(chnum)->HCCHAR = tmpreg; + USBx_HC(chnum)->HCCHAR = tmpreg; + reactivate = 1; } __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); - HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + if (reactivate == 0 )HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); } else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) diff --git a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_ll_usb.c b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_ll_usb.c index d992109199..b8593ef562 100644 --- a/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_ll_usb.c +++ b/targets/TARGET_STM/TARGET_STM32F7/device/stm32f7xx_ll_usb.c @@ -1520,6 +1520,8 @@ HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDe /* Write packet into the Tx FIFO. */ USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0); + hc->xfer_count = hc->xfer_len; + } } diff --git a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_hcd.c b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_hcd.c index 2cf5cc729f..f43fde3ea9 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_hcd.c +++ b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_hcd.c @@ -206,6 +206,9 @@ HAL_StatusTypeDef HAL_HCD_HC_Init(HCD_HandleTypeDef *hhcd, hhcd->hc[ch_num].ep_num = epnum & 0x7F; hhcd->hc[ch_num].ep_is_in = ((epnum & 0x80) == 0x80); hhcd->hc[ch_num].speed = speed; + /* reset to 0 */ + hhcd->hc[ch_num].toggle_out = 0; + hhcd->hc[ch_num].toggle_in = 0; status = USB_HC_Init(hhcd->Instance, ch_num, @@ -343,8 +346,26 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, uint16_t length, uint8_t do_ping) { - hhcd->hc[ch_num].ep_is_in = direction; - hhcd->hc[ch_num].ep_type = ep_type; + 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) { @@ -380,6 +401,17 @@ HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest(HCD_HandleTypeDef *hhcd, 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: @@ -878,6 +910,7 @@ static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum) } else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH) { + int reactivate = 0; __HAL_HCD_MASK_HALT_HC_INT(chnum); if(hhcd->hc[chnum].state == HC_XFRC) @@ -907,10 +940,11 @@ static void HCD_HC_IN_IRQHandler (HCD_HandleTypeDef *hhcd, uint8_t chnum) tmpreg = USBx_HC(chnum)->HCCHAR; tmpreg &= ~USB_OTG_HCCHAR_CHDIS; tmpreg |= USB_OTG_HCCHAR_CHENA; - USBx_HC(chnum)->HCCHAR = tmpreg; + USBx_HC(chnum)->HCCHAR = tmpreg; + reactivate = 1; } __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH); - HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); + if (reactivate == 0) HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state); } else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR) diff --git a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_usb.c b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_usb.c index 2fffe7d275..8048d89a36 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_usb.c +++ b/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_usb.c @@ -1399,6 +1399,8 @@ HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDe /* Write packet into the Tx FIFO. */ USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0); + hc->xfer_count = hc->xfer_len; + } }