Processor Expert Dual Speed USB generated code missing speed detection

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Processor Expert Dual Speed USB generated code missing speed detection

560 Views
lucasrangit
Contributor III

I'm using Processor Expert 3.0.1.b150806, Kinetis Design Studio 3.0.0, and the KSDK 1.3.0 (1.0.0.b150914) and a K26 MCU. The MCU USB PHY supports high/full/low-speeds but the Processor Expert code does not produce code that works for High Speed.

 

The fsl_usb_descriptor options are "Low speed", "Full speed", and "Dual speed". Using Processor Expert to configure a Full-Speed USB descriptor (Device Speed) works. When configured for "Dual speed" both a "High speed" and a "Full speed" "Device description is created (I assume for backwards compatibility with USB 1.1).

 

An issue I found is the generated USB descriptor code (e.g. usbDsc1.c:USB_Desc_Get_Descriptor()) does not return the High Speed descriptor even when the USBHS_PORTSC1[HSP] indicates this is a High Speed port.

 

I suspect this is because there is no generated code that updates the variable usbDsc1_CurrentUsbSpeed, used by usbDsc1.c:USB_Desc_Get_Descriptor(), when the port is changed or reset.

 

As a workaround I added the following line to my main() before the Processor Expert's PE_low_level_init().

 

usbDsc1_USB_Desc_Set_Speed(0, USB_SPEED_HIGH); // first argument is not used

 

Is there a better way to fix this issue?

 

I could not find where the Processor Expert generated code comes from and patching the KSDK makes it difficult to version the project because changes are overridden by the KSDK installed on the developer's host. Can anyone point me in the right direction so I can put together a proper patch and validate it before sending it for review? Or are these Processor Expert components closed source?

Labels (1)
0 Kudos
1 Reply

337 Views
isaacavila
NXP Employee
NXP Employee

Hello Lucas,

Indeed, the right way to handle this is to call a "get_speed" function once a USB_DEV_EVENT_BUS_RESET is received in the USB App Device callback, after this, you have to set this speed value by using USB_Desc_Set_Speed.

Look at these two examples, one is dev_msd_disk_bm_twrk65f180m (compatible with MK26):

void USB_App_Device_Callback(uint8_t event_type, void* val, void* arg)

{

    if (event_type == USB_DEV_EVENT_BUS_RESET)

    {

        g_disk.start_app = FALSE;

        if (USB_OK == USB_Class_MSC_Get_Speed(g_disk.app_handle, &g_disk.speed))

        {

            USB_Desc_Set_Speed(g_disk.app_handle, g_disk.speed);

        }

    }

And for example, in PEx I created a MSD example with dual speed and this also has to be handled the same:

void msd1_application_callback(uint8_t event_type, void * val, void * arg)

      {

        switch (event_type) {

          case USB_DEV_EVENT_BUS_RESET:       /* BUS reset received */

            if (USB_OK == USB_Class_MSC_Get_Speed(msd1_MsdHandle, &g_device_speed)) {   

              usbDsc1_USB_Desc_Set_Speed(msd1_MsdHandle, g_device_speed);

            }   

            break;

In CDC project, this is also handled:

if (event_type == USB_DEV_EVENT_BUS_RESET)

    {

        start_app = FALSE;

        if (USB_OK == USB_Class_CDC_Get_Speed(handle, &g_cdc_device_speed))

        {

            USB_Desc_Set_Speed(handle, g_cdc_device_speed);

            if (USB_SPEED_HIGH == g_cdc_device_speed)

            {

                g_bulk_out_max_packet_size = HS_DIC_BULK_OUT_ENDP_PACKET_SIZE;

                g_bulk_in_max_packet_size = HS_DIC_BULK_IN_ENDP_PACKET_SIZE;

            }

            else

            {

                g_bulk_out_max_packet_size = FS_DIC_BULK_OUT_ENDP_PACKET_SIZE;

                g_bulk_in_max_packet_size = FS_DIC_BULK_IN_ENDP_PACKET_SIZE;

            }

        }

    }

So, this must be handled in USB_App_Device_Callback once the RESET event has been received, also, pay attention that Get speed functions is specific for used class and it will return the speed that is used according to the CONTROLLER_ID (KHCI or EHCI) that was used when USB_Class_Init was called.

Regards,

Isaac Avila

0 Kudos