cancel
Showing results for 
Search instead for 
Did you mean: 

USB Split transaction in High Speed for STM32F769I-DISCO board

lge651
Associate

Posted on November 15, 2016 at 09:58

Hi,

I am writing a hub driver using HS controller for STM32F769I-DISCO board.

I have Configured the STM32F769I-DISCO boards to use the HS USB controller.

Added the code logic to support SPLIT Transaction protocol as per the STM32F7 reference manual using 

OTG_HCSPLTx register. 

Connected a HS HUB device (which supports Single Transaction Translator), and to the hub attached FS/LS device (like Network Dongle(FS), Mouse(LS)).

But still I am not able to get the FS/LS devices enumerated. 

Details of issue observed: 

    I don't receive any CHH interrupt in response to enabling of the 

SPLITEN bit in the register as per the explanation in Page-1601 of reference manual.

    ie. I have configured the HCSPLIT register with proper info like (Hub address, port number, split enable bit, xact position etc).

I have validated the HUB and found to be supporting single TT on other Host.

So, could someone help me understand following things:

     1.) Whether the STM32F769I - Discovery board supports split transactions or not ?

     2.) I also understand the STM32F7 MCU doesnot support inbuilt USB HS controller, so STM32F769I-Disco uses some external HS controller. 

       Whether the external HS controller used in STM32F769I-Disco support split transactions ? 

       Whether 

STM32F769I

MCU supports split transaction or not ?

What needs to be done in addition to what is stated in reference manual to get split protocol working if at all hardware of STM32F769I-Disco supports split protocol?

Thanks!!!

7 REPLIES 7
Jack Heaffey
Associate
Posted on January 06, 2017 at 15:52

Has there been any progress with this? I myself am trying to get split transactions working, with an STM32F756.

I set the SPLITEN bit in the HCSPLT register, and successfully transmit a SSPLIT OUT transaction. Following the reference manual, the COMPLSPLT bit should then be set after receiving the CHH interrupt. However, this interrupt does not occur.

lucas239955_stm1
Associate II
Posted on February 14, 2017 at 22:26

I also am having trouble with this issue at the moment.

st.mcu

‌,

vera.laurent

, Is there anyone from ST, specifically the USB division that could look into this?

Posted on February 15, 2017 at 17:05

Hello

Hutchinson.Lucas

‌,

Being reported by more than one user, the possible issue is reported internally for further investigation.

To help us understand what is going wrong here, please tell us:

- what HW are you using? (device, board...)

- how did you tested the split transaction? please share your code.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on February 15, 2017 at 23:10

Hi

‌,

Thanks for your response. Its good to hear you have also reported this issue internally.

The changes for SPLIT transaction are spread across following files:

Drivers\STM32F7xx_HAL_Driver\Inc\stm32f7xx_ll_usb.h Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_hal_hcd.c Drivers\STM32F7xx_HAL_Driver\Src\stm32f7xx_ll_usb.c

A short summary of whats done in software to add support for split transaction is as below:

1.) Configure the HCSPLT protocol with following information during pipe creation if connected device is found to be not high speed

Function Name: USB_HC_Init()Code Added:uint32_t tmpreg = 0;USBx_HC(ch_num)->HCSPLT = 0x00000000;if (speed != 0) //USBH_SPEED_HIGH){tmpreg = USBx_HC(ch_num)->HCSPLT;/* ALL */tmpreg &= ~USB_OTG_HCSPLT_XACTPOS_0;tmpreg |= USB_OTG_HCSPLT_XACTPOS_1;/* Set HUB address: For Now Hardcode to 5 */tmpreg |= USB_OTG_HCSPLT_HUBADDR_0;tmpreg |= USB_OTG_HCSPLT_HUBADDR_2;/* Set PORT address: For Now Hardcode to Port 0 */tmpreg |= USB_OTG_HCSPLT_PRTADDR_0;USBx_HC(ch_num)->HCSPLT = tmpreg;}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

2.) Configure the HCINTMSK for desired interrupts

Function Name: USB_HC_Init()Code Added:if(speed != 0){USBx_HC(ch_num)->HCINTMSK |=(USB_OTG_HCINTMSK_NAKM | USB_OTG_HCINTMSK_NYET | USB_OTG_HCINTMSK_ACKM);}�?�?�?�?�?�?�?�?�?�?�?�?�?

3.) Enable the START SPLIT in HCSPLT before starting any transfer on a non high speed device.

Function Name: USB_HC_StartXfer()Code Added:if (hc->speed != 0) //if not USBH_SPEED_HIGH{tmpreg = USBx_HC(hc->ch_num)->HCSPLT;/* Enable split transaction */tmpreg |= USB_OTG_HCSPLT_SPLITEN;USBx_HC(hc->ch_num)->HCSPLT = tmpreg;}�?�?�?�?�?�?�?�?�?�?�?

4.) Enable the COMPLETE SPLIT in HCSPLT after receiving the CHH interrupt in response to start split.

Function Name: HCD_HC_IN_IRQHandler & HCD_HC_OUT_IRQHandlerCode Added:/* Enable complete split */USBx_HC(chnum)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;�?�?�?�?�?

The issue we are facing is that even after configuring HCSPLT to start split while starting every new transfer with non high speed device.

Ideally one should expect CHH interrupt indicating that the start split request has been received by HUB. But unfortunately we are not receiving the CHH interrupt.
Amel NASRI
ST Employee
Posted on February 16, 2017 at 16:37

Hello

Hutchinson.Lucas

‌,

Could you please check in your stack that you are following these steps:

  1. Initialize and enable channel 1
  2. Prepare and link the required packet for channel 1 and at thisstage the host should send an OUT token
  3. The host generates an ACK interrupt as soon as the start split transaction completes successfully
  4. In response to the ACK interrupt, set the HCSPLT1.ComplSplt to send the complete split
  5. The host sends out the complete split transaction
  6. The host generates the XferCompl interrupt after successfully completing the complete split transaction and finally,in response to XferCompl interrupt, de-allocate the channel

Hope this may bring you some help.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Posted on March 14, 2017 at 11:41

I'm having issues with this as well.

In the reference manual (DocID028270 Rev 2), page 1678-1679, there is an sequence describing 'Bulk and control OUT/SETUP split transactions in DMA mode':

Bulk and control OUT/SETUP split transactions in DMA mode

The sequence of operations in (channel x) is as follows:

1. Initialize and enable channel x for start split as explained in Section : Channel initialization.

2. The OTG_HS host starts fetching the first packet as soon the channel is enabled and writes the OUT request along with the last DWORD fetch.

3. After successfully transmitting start split, the OTG_HS host generates the CHH interrupt.

4. In response to the CHH interrupt, set the COMPLSPLT bit in OTG_HCSPLT1 to send the complete split.

5. After successfully transmitting complete split, the OTG_HS host generates the CHH interrupt.

6. In response to the CHH interrupt, de-allocate the channel.

It states that there shall be a CHH interrupt both in step 3 and step 5, i.e. both aftersuccessfully transmitting start split and aftersuccessfully transmitting complete split. Is this correct?

Quote by

<LINK NO LONGER ACTIVE>

‌: 3. The host generates an ACK interrupt as soon as the start split transaction completes successfully

This is more like the behaviour I see. Although it doesn't seems to work. Nothing happens after I set the HCSPLT1.COMPLSPLT bit.

if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
{
 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
 if (USBx_HC(chnum)->HCSPLT & USB_OTG_HCSPLT_SPLITEN)
 {
 USBx_HC(chnum)->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
 }�?�?�?�?�?�?�?�?
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I don't get any more interrupts after that.

Posted on March 15, 2017 at 11:16

I've done some more investigation. This is the code I use to initiate the split transactions in USB_HC_Init:

 /* Enable split transactions */
 uint8_t host_speed = USB_GetHostSpeed(USBx);
 if (host_speed == USB_OTG_SPEED_HIGH &&
 speed != HPRT0_PRTSPD_HIGH_SPEED)
 {
 printf('HC %d: Enable split transactions
', ch_num);
 /* Enable split transactions */
 USBx_HC(ch_num)->HCSPLT = USB_OTG_HCSPLT_SPLITEN;
 /* Transaction position */
 USBx_HC(ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_0;
 USBx_HC(ch_num)->HCSPLT |= USB_OTG_HCSPLT_XACTPOS_1;
 /* Hub device address: For Now Hardcode to 1 */
 USBx_HC(ch_num)->HCSPLT |= USB_OTG_HCSPLT_HUBADDR_0;
 /* Port number: For Now Hardcode to Port 4 */
 USBx_HC(ch_num)->HCSPLT |= USB_OTG_HCSPLT_PRTADDR_2;
 printf('HC %d: HCSPLT: 0x%x
', ch_num, (USBx_HC(ch_num)->HCSPLT));
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

This is the debug output from two scenarios.

Full speed device directly without hub:

USB FULL speed device attached

DEBUG: Dev 0: Open IN CTRL pipe: 1, ep: 0x80, mps: 64 DEBUG: Dev 0: Open OUT CTRL pipe: 0, ep: 0x0, mps: 64 DEBUG: Dev 0: set state from 1 to 3 HC 0: OUT IRQ: 0x21 HC 0: OUT IRQ: 0x1 HC 0: OUT XFRC

HC 0: OUT IRQ: 0x2

HC 0: OUT CHH

Full speed device with hub:

USB FULL speed device attached

DEBUG: Dev 0: Open IN CTRL pipe: 4, ep: 0x80, mps: 64 HC 4: Enable split transactions HC 4: HCSPLT: 0x8000c084 DEBUG: Dev 0: Open OUT CTRL pipe: 3, ep: 0x0, mps: 64 HC 3: Enable split transactions HC 3: HCSPLT: 0x8000c084 DEBUG: Dev 0: set state from 1 to 3 HC 3: OUT IRQ: 0x20 HC 3: OUT ACK -> COMPLSPLT

As one can see, in the first scenario I get both a ACK and a XFRC interrupt following the first EP0 OUT Control packet. On the device side I can now see a EP OUTinterrupt that indicates that a request has been received.

In the second scenario I set SPLITEN, XACTPOS, HUBADDR and PRTADDR in theUSB_HC_Init function. The hub seems to send an ACK on the first start-split. But I don't see anything on the device side. And I am expecting either a ACK or a NYET interrupt (indicating a ACK or a NYET from the hub) following the complete-split.

So the question is, I'm I doing something wrong when I setup the HCSPLT register? Do I need to do something more other than setting up that register? Does the usb controller really work with split transactions?