SDK_2.0 No num lock, scroll lock, and caps lock LED USB control info received.  

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

SDK_2.0 No num lock, scroll lock, and caps lock LED USB control info received.  

Jump to solution
2,210 Views
mwais
Contributor II

In the Kientis expert SDK_2.0 generated examples code there is a USB mouse & keyboard composite example.  The USB stack does not provide a way to receive the num lock, scroll lock, and caps lock LED control info from  the host. The keyboard example in SDK 1.3 does receive data receive data from the host for  numlock, scroll lock, and caps lock LED control.

 

Is there a newer version of SDK_2.0 that has actually “fixes” the issue with receiving the num lock, scroll lock, and caps lock LED control issue on for the USB mouse & keyboard composite example?

 

Matt

Labels (1)
1 Solution
1,667 Views
lylezhu2012
NXP Employee
NXP Employee

Hi Matt,

These is a misstake in usb hid keyboard report descriptor.

The LED page value is 0x08. but the code is 0x01 in source code. So the host will not send set report reuqest to the keyboard when any lock key is pressed. So you can do follow change: Change the value 0x01 to 0x08 (line 327 in file usb_device_descriptor.c) of the var. g_UsbDeviceHidKeyboardReportDescriptor. And then apply the ken's changes.

We will fix this issue in following release.

Such as:

    0x95U, 0x05U, /* Report count (5U) */
    0x75U, 0x01U, /* Report Size (1U) */

    0x05U, 0x01U 0x08U, /* Usage Page (Page# for LEDs) */
    0x19U, 0x01U, /* Usage Minimum (1U) */
    0x29U, 0x05U, /* Usage Maximum (5U) */

View solution in original post

12 Replies
1,667 Views
mwais
Contributor II

Brad, Kan, & Lele,

This works and resolved the issue! 

Works on FRDM-KL43Z and my own target platform for the MKL27Z256 using SDK 2.0 Framework.

Thank you all,

--Matt

0 Kudos
1,667 Views
bonzo
NXP Employee
NXP Employee

This works for me.

Thank you.

--Brad

0 Kudos
1,668 Views
lylezhu2012
NXP Employee
NXP Employee

Hi Matt,

These is a misstake in usb hid keyboard report descriptor.

The LED page value is 0x08. but the code is 0x01 in source code. So the host will not send set report reuqest to the keyboard when any lock key is pressed. So you can do follow change: Change the value 0x01 to 0x08 (line 327 in file usb_device_descriptor.c) of the var. g_UsbDeviceHidKeyboardReportDescriptor. And then apply the ken's changes.

We will fix this issue in following release.

Such as:

    0x95U, 0x05U, /* Report count (5U) */
    0x75U, 0x01U, /* Report Size (1U) */

    0x05U, 0x01U 0x08U, /* Usage Page (Page# for LEDs) */
    0x19U, 0x01U, /* Usage Minimum (1U) */
    0x29U, 0x05U, /* Usage Maximum (5U) */

1,667 Views
bonzo
NXP Employee
NXP Employee

Kan,

This is Brad and I'm the FAE supporting Matt.

I have tried your suggestions using a FRDM-KL27 + KSDK 2.0 + KDS 3.2 + Win7 64-bit + US Keyboard

I have the exact same results.  The CapsLock key does not get acknowledged.  Setting breakpoints inside the keyboard callback routine are not recognized.

Using my USB analyzer and monitoring my normal keyboard connection, I discovered that the CapsLock, etc, sends out a Class_Specific_Device_Request and not any data-out request.  This is the result of pressing the CapLock key.  I get the same result if I use the on-screen keyboard as well.

If I then monitor the USB connection to the FRDM-KL27,  a Class_Specific_Device_Request is never issued.   So I'm not sure what the problem is.  It seems that Windows may not recognize the FRDM-KL27 as a keyboard device but as generic HID. 

0 Kudos
1,667 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Matt,

This patch has been tested with the demo of usb_device_composite_hid_mouse_hid_keyboard\bm\iar on frdm-k66f, and it works well on my side, so if you still have issue with it, would you please provide more details regarding your issue?

Thanks for your patience!


Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,667 Views
mwais
Contributor II

Hi Kan,

Generated project using Kinetis Expert for windows: see vault below:

pastedImage_0.png

Unzipped SDK 2.0  to this folder: C:\Freescale\SDK_2.0_MKL43Z256xxx4

Using FRDM-KL43Z board.  Imported project: dev_composite_hid_mouse_hid_keyboard_bm_frdmkl43z

located at:

C:\Freescale\SDK_2.0_MKL43Z256xxx4\boards\frdmkl43z\usb_examples\usb_device_composite_hid_mouse_hid_keyboard

Added your code above to hid_keyboard.c:

usb_status_t USB_DeviceHidKeyboardCallback(class_handle_t handle, uint32_t event, void *param)

{

.....

        case kUSB_DeviceHidEventSetReport:

        if (s_UsbDeviceComposite->attach)

        {

            uint32_t index = 0;

            uint8_t *buff = NULL;

            g_output_report = (usb_device_hid_report_struct_t *)param;

            buff = g_output_report->reportBuffer;

            printf("kUSB_DeviceHidEventSetReport!\r\n");

            printf("Report ID: %d\r\n", g_output_report->reportId);

            printf("Report Type: %d\r\n", g_output_report->reportType);

            printf("Printing %d received data:\r\n", (uint8_t)g_output_report->reportLength);

            for (index = 0; index < g_output_report->reportLength; index++)

            {

                printf(" 0x%X ", buff[index]);

            }

            printf("\r\n");

            error = kStatus_USB_Success;

        }

        break;

        case kUSB_DeviceHidEventRequestReportBuffer:

        if (s_UsbDeviceComposite->attach)

        {

            g_output_report = (usb_device_hid_report_struct_t *)param;

            if (g_output_report->reportLength <= sizeof(s_UsbDeviceHidReportBuffer))

            {

                g_output_report->reportBuffer = &s_UsbDeviceHidReportBuffer[0];

                error = kStatus_USB_Success;

            }

            else

            {

                error = kStatus_USB_InvalidRequest;

            }

        }

Pressed "caps lock key" several times and did not see the buffer printed to the terminal :

pastedImage_9.png

Matt

0 Kudos
1,667 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Matt,

I have checked with the USB stack team, and they provided the following solution for your issue, please refer to it for details.

For set report request, there are two events, kUSB_DeviceHidEventRequestReportBuffer and kUSB_DeviceHidEventSetReport, can be used to implement the corresponding functionality.


The event
kUSB_DeviceHidEventRequestReportBuffer will be received at first when the host sends a set report request, it is used by the stack to get the buffer from application to receive the report data sent by the host. Along with this event, a parameter (type is void*) is provided, and this parameter needs to be cast to a pointer to usb_device_hid_report_struct_t. The report data length is kept in field usb_device_hid_report_struct_t::reportLength. Users need to fill in a valid buffer address to usb_device_hid_report_struct_t::
reportBuffer

And then the event kUSB_DeviceHidEventSetReport will be received after the report data is received, same as before, a parameter is provided and need to be cast to a pointer to usb_device_hid_report_struct_t, the report data is kept in field usb_device_hid_report_struct_t:: reportBuffer.

The detail information please refer to the description of the structure usb_device_hid_report_struct_t.

I drafted a simple code for these two events.

static usb_device_hid_report_struct_t* g_output_report; /* Global variable */

static uint8_t s_UsbDeviceHidReportBuffer[HS_HID_KEYBOARD_INTERRUPT_IN_PACKET_SIZE];

        case kUSB_DeviceHidEventRequestReportBuffer:

if (s_UsbDeviceComposite->attach)

{

g_output_report = (usb_device_hid_report_struct_t *)param;

if (g_output_report->reportLength <= sizeof(s_UsbDeviceHidReportBuffer))

{

g_output_report->reportBuffer = &s_UsbDeviceHidReportBuffer[0];

error = kStatus_USB_Success;

}

else

{

error = kStatus_USB_InvalidRequest;

}

}

break;

        case kUSB_DeviceHidEventSetReport:

if (s_UsbDeviceComposite->attach)

{

uint32_t index = 0;

uint8_t *buff = NULL;

g_output_report = (usb_device_hid_report_struct_t *)param;

buff = g_output_report->reportBuffer;

printf("kUSB_DeviceHidEventSetReport!\r\n");

printf("Report ID: %d\r\n", g_output_report->reportId);

printf("Report Type: %d\r\n", g_output_report->reportType);

printf("Printing %d received data:\r\n", (uint8_t)g_output_report->reportLength);

for (index = 0; index < g_output_report->reportLength; index++) {

printf(" 0x%X ", buff[index]);

}

printf("\r\n");

error = kStatus_USB_Success;

}

break;

Hope that helps,


Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,667 Views
mwais
Contributor II

Hi Kan,

Thank you for your feedback.

Unfortunately, this will not resolve the issue.  However, adding  this code will work for retrieving the control endpoint event. should it actually get to the usb_status_t USB_DeviceHidEvent(void *handle, uint32_t event, void *param) function. Setting a break point or doing a printf(); in this function to capture a "LOCK" event from the  host never occurs.

To verify use use your normal keyboard press anyone of the "lock" keys(numlock, scrolllock, or capslock) this will cause the host to broadcast down the control endpoint to all attached keyboards the "lock" led status.  This event never occurs in the SDK 2.0 USB stack.

Thanks,

Matt

0 Kudos
1,667 Views
mjbcswitzerland
Specialist V

Hi Matt

I did analyse one of the solutions but they change quite a lot between releases so there is no version management or real compatibility. The code is not easy to follow because it is based on call-back tables which are difficult to follow and the host SETUP frames were passed (in the said case) to the application not when they were received but only when the returned zero data frame was acknowledged, which made it even more difficult to follow.

It depends on what is more important for you, either your main interest is in repairing/extending the examples that are given or in  developing a reliable product. If you are no allowed to purchase solutions you are welcome to have a complimentaty project license for the uTasker project as long as you don't need personal professional support (which is what the fee is mainly for) - free support is still available either here or on the uTasker forum. This may be more intersting for your company in case you prefer a complete working solution that operates on any Kinetis parts with USB (no porting required) and can be used with any of the popular tools (IAR, Kein, KDS, CW, Crossworks, Atollic, Green Hills etc.) and also allows you to simulate the complete USB operation with an accurate USB engine simulator in Visual Studio. Typically project development, testing and debugging of this part and complete projects can be performed with a level of efficiency and quality several times greater than using traditional techniques. The USB solution has a track record of 8 years on Freescale Coldfire and Kinetis devices so proven reliability and efficiency in many industrial products, which may also prove valuable in comparison to basing designs on examples that may or may not be fully operational.

P.S. You can also get some more details about composite device operation and keyboard testing, including its capability to generate keystroke sequences from code or files at up to 1'000 strokes a second or with controllable inter-stroke timing: http://www.utasker.com/kinetis/USB_Device.html

Regards

Mark

0 Kudos
1,667 Views
mwais
Contributor II

SDK_1.3_MKL27Z256xxx4 or SDK_1.3_MKL43Z256xxx4

Will receive LED (rpt buffer) data via callback from host as shown.(this callback occurs if caps lock status changes)

uint8_t USB_App_Class_Callback(

    uint8_t request,

    uint16_t value,

    uint8_t ** data,

    uint32_t* size,

    void* arg

    )

{

.

.

.

case USB_HID_SET_REPORT_REQUEST:

        for (index = 0; index < (*size); index++)

        { /* copy the report sent by the host */

            //g_keyboard.rpt_buf[index] = *(*data + index);

        }

        *size = 0;

        break;

.

.

.

}

SDK_2.0_MKL27Z256xxx4 or SDK_2.0_MKL43Z256xxx4

Will not receive data via callback from host (callback never occurs if caps lock status changes)

usb_status_t USB_DeviceHidKeyboardCallback(class_handle_t handle, uint32_t event, void *param)

{

    usb_status_t error = kStatus_USB_Error;

    switch (event)

    {

        case kUSB_DeviceHidEventSendResponse:

            if (s_UsbDeviceComposite->attach)

            {

                return USB_DeviceHidKeyboardAction();

            }

            break;

        case kUSB_DeviceHidEventGetReport:

        case kUSB_DeviceHidEventSetReport:

        case kUSB_DeviceHidEventRequestReportBuffer:

            error = kStatus_USB_InvalidRequest;

            break;

        case kUSB_DeviceHidEventGetIdle:

        case kUSB_DeviceHidEventGetProtocol:

        case kUSB_DeviceHidEventSetIdle:

        case kUSB_DeviceHidEventSetProtocol:

            break;

        default:

            break;

    }

    return error;

}

I chose  use the SDK_2.0  framework because it already has the composite USB device for Keyboard & mouse example code.  SDK_1.3 does not.

​Matt

0 Kudos
1,667 Views
mjbcswitzerland
Specialist V

Hi

There may have been a similar discussion at

https://community.freescale.com/message/540167#comment-540167

If you don't find a solution you can simply use the uTasker USB project which includes keyboard/mouse/CDC/RNDIS/MSD/audio composites (and any mixture of these) as a complete solution rather than just examples.

You may find a reference that directly runs on your board at http://www.utasker.com/kinetis.html

Regards

Mark

0 Kudos
1,667 Views
mwais
Contributor II

Hi Mark,

Thank you for comment. However, I had already reviewed the discussion you mention above.  My issue is with SDK 2.0  that specifically has the USB keyboard & mouse composite example.  The  "lock" led status is available via  "g_keyboard.rpt_buf[index] " as indicated above on the standalone keyboard examples using SDK 1.3 or SDK 1.2.  It appears the "USB_App_Class_Callback" was eliminated or replaced with a callback that doesn't provide access to the  "g_keyboard.rpt_buf[index] ".  Also, I have dug deep into the bowls of the USB stack that comes with SDK 2.0 and it appears there is no mechanism that monitors input from the host control endpoint when configured as a HID device.

It appears the "uTasker" solutions have costs associated with them.  This is not an option.

Regards,

Matt

0 Kudos