cancel
Showing results for 
Search instead for 
Did you mean: 

USB Isochronous IN Host example

Kevin Carney
Associate II
Posted on March 28, 2018 at 00:17

Is there an example of using the USB Isochronous IN pipe in Host mode for STM32?

None of he examples I have found show how to do this.  I have found several people asking for the same thing, but I started a new question hoping that something has developed.

7 REPLIES 7
Colin Cina
Associate II
Posted on July 03, 2018 at 10:52

Hey ! I'm in the same situation as you. Have you found anything regarding isochronous in transfers in the meantime?? 

Keep it up

Colin

Kevin Carney
Associate II
Posted on July 03, 2018 at 16:08

I opened a support issues and someone sent me the files below.  I have not had time to go back and see if I could incorporate these into my project, yet.  Good luck. 

https://www.dropbox.com/s/s9ms7lr4r1j3izq/USBH_AUDIO_IN_OUT_H7_EVAL_FreeRTOS.zip?dl=0

 
Posted on July 03, 2018 at 16:12

Thx a lot !!

Get Outlook for Android<https://aka.ms/ghei36>

Piers Hawksley
Associate III

I'm looking at isochronous transfers in the F7.

Do STM make available older versions of the stm32cubemx H7 library? The files @Community memberarney​ made available are based on version 1.2, now version 1.3 is out it is quite hard guessing what the changes to the library code are (unless it is only the one in the readme?) - A diff between the code in the archive and version 1.2 of the H7 library would be rather useful to help spot any other (necessary) changes.

Just applying the fix (which is very similar to an earlier one I found (before the forums changed, I think it was at https://community.st.com/0D50X00009XkdyKSAR

  else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)

with:

  else if((hhcd->hc[chnum].ep_type == EP_TYPE_INTR)||

      (hhcd->hc[chnum].ep_type == EP_TYPE_ISOC))

in HCD_HC_IN_IRQHandler (in stm32f7xx_hal_hcd.c

The difference is the above change causes:

   USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;

to be set in the isochronous form as well as the interrupt form where as just adding:

  else if(hhcd->hc[chnum].ep_type == EP_TYPE_ISOC)

  {

   hhcd->hc[chnum].urb_state = URB_DONE;

   HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);

  }

(which the mod in the archive does) does not do.

I believe this fix is more likely to work as isochoronous transfers should be on all (micro) frames not only on odd frames.

> I think it was at https://community.st.com/0D50X00009XkdyKSAR

> but has evaporated since the change)

https://community.st.com/s/feed/0D50X00009XkdyKSAR perhaps?

Piers Hawksley
Associate III

Yes - exactly that change - many thanks

(sorry for slow reply - I was away from my computer and didn't get an email notification, so didn't check for replies)

dirk.frerichs
Associate II

hi

i have some questions ...

I wrote the "bug" in original files to get an isochronous interrupt

the quick fix solves this problem.

Piers Hawksley found the solution for the SOF interupts ...

    else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
    {
      USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
      hhcd->hc[chnum].urb_state = URB_DONE; 
      HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
    }
    else if(hhcd->hc[chnum].ep_type == EP_TYPE_ISOC)
    {
      hhcd->hc[chnum].urb_state = URB_DONE;
      HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
    }

Now i try to lower CPU usage during receive of data.

the old working version to receive JPG images is:

case VIDEO_STREAM_PLAY:
	if((phost->Timer-pVideo->EpVideoStream.wTimer) >= pVideo->EpVideoStream.bInterval)
	{
		pVideo->EpVideoStream.wTimer = phost->Timer;
		if( USBH_LL_GetURBState(phost , pVideo->EpVideoStream.bPipe) == 
                               USBH_URB_DONE ){
			HandleReceivedFrame( 	phost,
									pVideo ,
									DMA_USBH_Buffer,
									USBH_LL_GetLastXferSize(phost,
                                                                        pVideo->EpVideoStream.bPipe ));
 
					USBH_IsocReceiveData( phost ,
						DMA_USBH_Buffer,
						pVideo->EpVideoStream.wMaxPacketSize,
						pVideo->EpVideoStream.bPipe );
				}
			}
			osMessagePut ( phost->os_event, USBH_CLASS_EVENT, pVideo->EpVideoStream.bInterval );

the problem is:

the line: osMessagePut ( phost->os_event, USBH_CLASS_EVENT, pVideo->EpVideoStream.bInterval );

puts every 1ms a new event to call the USB_Process function

like polling ...

if timer expired and URB_DONE then get frame and start a new transfer ...

the SOF is unused in this case

now i tried to optimize this

the SOF is called every Frame ( ??? i dont know the details )

so it seems like we need a new call of osMessagePut ( phost->os_event, USBH_CLASS_EVENT, pVideo->EpVideoStream.bInterval ); every SOF interrupt ... right?

easy:

		case VIDEO_STREAM_PLAY:
				if( USBH_LL_GetURBState(phost , pVideo->EpVideoStream.bPipe) == USBH_URB_DONE ){
					HandleReceivedFrame( 	phost,
											pVideo ,
											DMA_USBH_Buffer,
											USBH_LL_GetLastXferSize(phost, pVideo->EpVideoStream.bPipe ));
 
					USBH_IsocReceiveData( phost ,
						DMA_USBH_Buffer,
						pVideo->EpVideoStream.wMaxPacketSize,
						pVideo->EpVideoStream.bPipe );
				}
			break;
 
 
 
static USBH_StatusTypeDef USBH_VIDEO_SOFProcess(USBH_HandleTypeDef *phost) {
	USBH_StatusTypeDef status  = USBH_OK;
	VIDEO_HandleTypeDef *pVideo = (VIDEO_HandleTypeDef *)phost->pActiveClass->pData;
	switch (pVideo->StreamState){
		case VIDEO_STREAM_PLAY:
			if((phost->Timer - pVideo->EpVideoStream.wTimer) >= 
					pVideo->EpVideoStream.bInterval ){
				osMessagePut ( phost->os_event, USBH_CLASS_EVENT, 0 );
			}
			break;
		default:
			break;
	}
	return status;
}

the receive of an IN packet is also calling

HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);

if i try to debug this changes .. i get a response with an image.

but only in debug mode and step by step.

if this part runs without breakpoints. the transmission stops after a few packets...

someone have an idea ?

sorry for my bad english ... :tired_face: