How can I configure an USB HID Keyboard Output Endpoint with KDS processor expert ?

cancel
Showing results for 
Search instead for 
Did you mean: 

How can I configure an USB HID Keyboard Output Endpoint with KDS processor expert ?

Jump to solution
3,194 Views
Contributor III

Hello,

I'm developing an application with MKL26Z256VLH4 in order to realize an USB Keyboard.

Actually I succeded in configuring an Input endpoint with KDS processor expert and in this way Host can receive the Keys from Keyboard.

The USB class that I used is the HID type.

I need to receive from Host the control commands in order to switch ON or OFF the LEDS of the Keyboard: Num Lock, Caps Lock, etc.

How can I configure an Output Endpoint with KDS processor expert?

All my attempts have been unsuccesful.

I try to add an "Rx transfer" in the ENDPOINT properties but PE doesn't generate the code.

Thanks in advance.

Best regards.

Daniele

0 Kudos
1 Solution
218 Views
Contributor III

Hello Isaac,

Hello Mark,

with your precious indications, all the problems about the LED status have been resolved.

We want to thank you for all your help.

Fernando and Daniele

Only one note about the compiler:

Sometimes the HIDK1.c modified with your indications is overwritten by KDS with the original one.

View solution in original post

0 Kudos
14 Replies
218 Views
NXP Employee
NXP Employee

Hello Daniele,

do you need to receive only information about LEDs status? (Num, Caps, Scroll, etc). If so, this information is received in control endpoint (endpoint zero) and you do not need to add an aditional OUT endpoint.

In this case, you can manage this information in USB_App_Class_Callback and attend the USB_HID_SET_REPORT_REQUEST request:

case USB_HID_SET_REPORT_REQUEST:

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

     {

          g_led_report = *(*data + index);

     }

     *size = 0;

     break;

I tested keyboard example for newest KSDK version. It is located at <KSDK_1_3>\examples\frdmkl26z\demo_apps\usb\device\hid\hid_keyboard and this worked well. (In KSDK 1.2 there was an bug related to this functionality but this was fixed in KSDK 1.3).

Is this what you need? Or you really need to add an OUT endpoint.

I hope this can help,

Best Regards,

Isaac

0 Kudos
218 Views
Contributor III

Hello Isaac,

we’ll try to summarize our activities from the beginning.

In order to realize our USB Keyboard application we used the example provided by Erich Styger “Using the FRDM-KL25Z as USB Keyboard” developing the project with KDS version 2.0 (without KSDK) and the microcontroller MKL26Z256VLH4.  With this work, we developed an USB Keyboard that transmits keys correctly but that doesn’t’ receive LED status.

After your answer in the forum (29 July 2015) in which you suggested to analyze “A demo project of USB HID bi-directional generic device for Kinetis SDK 1.1.0” we imported our original project under KDS 3.0 and KSDK 1.2 but the LED status continued to not work and additionally we experienced compilation problems, some of them listed below:

1. Errors about the three timers “error in main timing”.

2. Error about the UART baud rate “timing setting failed”.

3. No supported KSDK libraries for our microcontroller MKL26Z256VLH4.

After your indications provided four days ago, we tried to use endpoint zero, the function “USB_App_Class_Callback” and service the “USB_HID_SET_REPORT_REQUEST” request without success.

We found the instruction “case USB_HID_SET_REPORT_REQUEST” in the following files: “HIDK1.c” and “usb_hid.c” and tried to insert your code in them but the instruction was never activated.

After your last indication that in KSDK 1.2 there was a bug related to this functionality and that it was fixed in KSDK 1.3 we are going to install the newer SDK version (1.3) and retry your indications.

If even this attempt will fail, we will follow your document “Creating a New USB project with KSDK and Processor Expert support in KDS” hoping to gain access to all USB functions.

We’ll keep you promptly informed on our progress.

Thanking you in advance for all your attention,

Best Regards, Fernando and Daniele

0 Kudos
218 Views
Specialist V

Hello Daniele

As a reminder (I see that you have invested several months so far trying to get the various examples working).

You can get complete industrial proven USB-HID for keyboards in the uTasker KL26 project that will allow you to complete the work with no further delays (and mix with other composite classes) - you can also simulate the operation for study or software auditing purposes in its KL26 simulator.

The control of the status outputs is in fact very simple and I have attached descriptors (in attached file) as well as the endpoint 0 callback function (code snippet below) which controls the LED status. You may be able to see something so that you can patch one of the various frameworks and examples that you have been experimenting with to solve it in your case.

Generally, however, I wouldn't expect the USB interface part of a keyboard to consume more that a day of actual work effort in a project development.

Regards

Mark

// Endpoint 0 call-back for any non-supported control transfers.
// This can be called with either setup frame content (iType != 0) or with data belonging to following OUT frames.
// TERMINATE_ZERO_DATA must be returned to setup tokens with NO further data, when there is no response sent.
// BUFFER_CONSUMED_EXPECT_MORE is returned when extra data is to be received.
// STALL_ENDPOINT should be returned if the request in the setup frame is not expected.
// Return BUFFER_CONSUMED in all other cases.
//
// If further data is to be received, this may arrive in multiple frames and the call-back needs to manage this to be able to know when the data is complete
//
static int control_callback(unsigned char *ptrData, unsigned short length, int iType)
{
    int iRtn = BUFFER_CONSUMED;
    switch (iType) {

    case STATUS_STAGE_RECEPTION:                                         // this is the status stage of a control transfer - it confirms that the exchange has completed and can be ignored if not of interest to us
        return BUFFER_CONSUMED;
    case SETUP_DATA_RECEPTION:
        {             USB_SETUP_HEADER *ptrSetup = (USB_SETUP_HEADER *)ptrData;    // interpret the received data as a setup header
            if ((ptrSetup->bmRequestType & ~STANDARD_DEVICE_TO_HOST) != REQUEST_INTERFACE_CLASS) { // 0x21
                return STALL_ENDPOINT;                                   // stall on any unsupported request types
            }
            usExpectedData = ptrSetup->wLength[0];                       // the amount of additional data which is expected to arrive from the host belonging to this request
            usExpectedData |= (ptrSetup->wLength[1] << 8);
            if (ptrSetup->bmRequestType & STANDARD_DEVICE_TO_HOST) {     // request for information
                usExpectedData = 0;                                      // no data expected to be received by us
                switch (ptrSetup->bRequest) {
                case USB_REQUEST_GET_DESCRIPTOR:                         // standard request
                    if (ptrSetup->wValue[1] == DESCRIPTOR_TYPE_REPORT) {
                        fnWrite(USB_control, (unsigned char *)&ucKeyboardReport, sizeof(ucKeyboardReport)); // return directly (non-buffered)
                    }
                    else {
                        return STALL_ENDPOINT;                           // not supported
                    }
                    break;
                default:
                    return STALL_ENDPOINT;                               // stall on any unsupported requests
                }
            }
            else {                                                       // command
                iRtn = TERMINATE_ZERO_DATA;                              // acknowledge receipt of the request if we have no data to return (default)
                switch (ptrSetup->bRequest) {
                case HID_SET_IDLE:                                       // 0x0a - this can silence a report
                    break;                                               // answer with zero data
                case HID_SET_REPORT:                                     // 0x09 - set report
                    return BUFFER_CONSUMED_EXPECT_MORE;                  // the present buffer has been consumed but extra data is subsequently expected
                default:
                    return STALL_ENDPOINT;                               // stall on any unsupported requests
                }
            }
            if (length <= sizeof(USB_SETUP_HEADER)) {
                return iRtn;                                             // no extra data in this frame
            }
            length -= sizeof(USB_SETUP_HEADER);                          // header handled
            ptrData += sizeof(USB_SETUP_HEADER);
        }
        // Fall through intentionally
        //
    default:                                                             // OUT_DATA_RECEPTION
        if (usExpectedData != 0) {
            // Handle and control commands here
            //
            switch (ucCollectingMode) {
            default:
                fnSetKeyboardOutput(*ptrData);                           // assumed to be set report with a single byte content
                break;
            }
            ucCollectingMode = 0;                                        // reset to avoid repeat of command when subsequent, invalid commands are received
            if (length >= usExpectedData) {
                usExpectedData = 0;                                      // all of the expected data belonging to this transfer has been received
                return TERMINATE_ZERO_DATA;
            }
            else {
                usExpectedData -= length;                                // remaining length to be received before transaction has completed
            }
            return BUFFER_CONSUMED_EXPECT_MORE;
        }
        break;
    }
    return iRtn;
}

static void fnSetKeyboardOutput(unsigned char ucOutputs)                 // assumed to be set report with a single byte content
{
    // Directly change the state of outputs according to the states
    //
    if (ucOutputs & 0x01) {
        _SETBITS(B, LED_1);
    }
    else {
        _CLEARBITS(B, LED_1);
    }
    if (ucOutputs & 0x02) {
        _SETBITS(B, LED_2);
    }
    else {
        _CLEARBITS(B, LED_2);
    }
}

0 Kudos
218 Views
Contributor III

Hello Isaac,

according to the post dated 12 October 2015, we have installed the newer SDK 1.3 and KDS 3.0 retrying your indications without success, so we have followed your document “Creating a New USB project with KSDK and Processor Expert support in KDS” in order to gain access to all USB functions.

These attempts have generated many problems: the major of them is that the old PE components become not available, so we have to substitute them with others components that are not equivalent and in addition, the names and the parameters of the functions related with the new PE components are different compared to the original ones.

In a few words, our project is not more compatible.

So, to make it compatible, we should have to modify our project heavily, not only renaming all the functions calls but even changing the associated parameters.

Given that, our product should be released in mass production in a few days, we can’t walk through this way (we have spent more of one month on this project).

For this reason we are asking you for a great help: we attached again our well-functioning project (except for the leds) developed with KDS 2.0 and without SDK support. Starting from this, could you modify it (with KDS 2.0 and without SDK support) in order to receive the led status?

If this feature will be not implemented in our project, we’ll have serious problems with our product mass production and in the next future we will be forced to change the microcontroller turning to other manufacturers.

Obviously we are at your disposal for any clarification.

Thank you in advance for all your precious cooperation.

Best Regards, Fernando and Daniele.

0 Kudos
218 Views
NXP Employee
NXP Employee

Hello Daniele,

As I've already told you, this feature is managed in USB_App_Param_Callback, when USB_HID_SET_REPORT report is received. I have modified your HIDK1.c file (and a minor modification in Cpu.c file in order to initialize RGB LED in FRDM board) in order to receive report from Host and validate which Lock is enabled (Numb, Caps, etc).

I turn on every LED per every lock key so i can corroborate that data is received correctly.

I attach these two files. I hope this can help you.

Best Regards,

Isaac

----------------------------------------------------------------------------------------------------------------------------------------

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

----------------------------------------------------------------------------------------------------------------------------------------

0 Kudos
218 Views
Specialist V

I just realised why it was so difficult to follow what it was doing.

The application call back is not called when the USB_HID_SET_REPORT arrives from the host but is instead called after the zero data ack that it had returned to the host has been acknowledged by the host.

This means that it is one interrupt handling later. I wonder whether there is a (logical) reason for this?

Regards

Mark

0 Kudos
218 Views
Contributor III

We are going to try all of your indications...

Thanking you in advance for all your attention,

Best Regards, Fernando and Daniele

0 Kudos
218 Views
Specialist V

Hello Daniele

When I checked out your code yesterday I noticed that it was using the Freescale Vendor ID and a PID of 0x0101. This looks like the default value in the reference.

If this is indeed so and you don't have an agreement with Freescale to use this for your product it is worth checking that you have a solution for your mass production product, which yor write will commence shipping shortly.

Without a valid VID/PID the product would otherwise be 'illegal' and your company could be fined.

VID can be purchased as explained here:

http://www.usb.org/developers/vendor/

You can also contact your Freescale Sales representative to discuss being assigned a Freescae/Motorola PID as long as your quantities are not too high.

Regards

Mark

0 Kudos
219 Views
Contributor III

Hello Isaac,

Hello Mark,

with your precious indications, all the problems about the LED status have been resolved.

We want to thank you for all your help.

Fernando and Daniele

Only one note about the compiler:

Sometimes the HIDK1.c modified with your indications is overwritten by KDS with the original one.

View solution in original post

0 Kudos
218 Views
Specialist V

Hi Daniele

I took a look at your project and couldn't see that there was any support for the class OUT request (it was just being acked with a zero out data packet).

Not knowing how the stack and its generation tools need to be configured to do it I just patched it with a few lines of code. The built project is attached (as binary, SREC and elf so that you can probably load one of them to your board).

The CAPS lock key will set your orange LED and maybe another key will set the green (or yellow?) one on your board - I don't know which one because I just set a bit for it but you should be able to verify that it operates.

Regards

Mark

Kinetis: http://www.utasker.com/kinetis.html

KL26: http://www.utasker.com/kinetis/FRDM-KL26Z.html / http://www.utasker.com/kinetis/TEENSY_LC.html

For the complete "out-of-the-box" Kinetis experience and faster time to market

:smileyinfo: Out-of-the-box support for 46 Kinetis boards and 10 IDEs (460 combinations from a single code source with no porting required)

0 Kudos
218 Views
NXP Employee
NXP Employee

Hi Daniele,

Remember that it is neccessary to modify usb_descriptors and some other files in order to establish bi-directional communication using HID class. (Here is an example using KSDK, maybe it could be useful A demo project of USB HID bi-directional generic device for Kinetis SDK 1.1.0 )

Could you please attach your code?

I will try to find why it is not working.

Best Regards,

Isaac

0 Kudos
218 Views
Contributor III

Hi Isaac,

first of all I would thank you for your prompt answer.

The first step has been to analyse your example "A demo project of USB HID bi-directional generic device for Kinetis SDK 1.1.0".

Then, I installed KSDK v1.1.0 on my PC but reading the release notes I found that it didn't support my processor MKL26Z256VLH4 so I installed the current version KSDK v1.2.0. Doing that, it has been necessary to change KDS from the version 2.0.0 to 3.0.0.

In the next step I imported my project inside KDS with the following results:

- some errors has been generated that there weren't before (Example: errors on timer parameters and UART baud rates);

- Trying to use specific KSDK 1.2.0 library components with the processor MKL26Z256VLH4 the compiler reports that it doesn't support them;

- Trying to add (forcing) the component "fsl_usb_device_hid" class the compiler reports the following message "Component is not available for given processor"

I attach the exported KDS 2.0.0 project in order to find the problem.

Thanking in advance for all your attention,

Best Regards.
Daniele

0 Kudos
218 Views
NXP Employee
NXP Employee

Hello Daniele,

You should have correctly set linker flag, target flags, choosen ARM family, instruction set...

Please, look at the article, it could help you

Kinetis Design Studio: Migrating KDS V2.0.0 Projects to GNU Tools for ARM Embedded (Launchpad, KDS V...

Best Regards,

Iva

0 Kudos
218 Views
Specialist V

Hello Daniele

I can't help with PE generated code but if you don't find a method and prefer a complete and proven solution for USB-HID Keyboard on the KL26 (also mixed with other composite devices) this is available in the uTaskert KL25 project - see links below.

Here are some details about composite device configuration and keyboard testing:

µTasker USB Device Configuration

For controlling status LEDs etc. the routine

void fnSetKeyboardOutput(unsigned char ucOutputs);

is called each time the set report on the OUT endpoint is received, where the user simply adds code to control outputs etc.

The keyboard input is either controlled by key scanning or by a software queue, which allows software to generate input to the PC at a rate of up to 1k key-strokes per second.

The project builds directly with KDS (and most other popular IDEs).

Regards

Mark

Kinetis: µTasker Kinetis support

KL26: µTasker Kinetis FRDM-KL26Z support / µTasker Kinetis Teensy LC support

For the complete "out-of-the-box" Kinetis experience and faster time to market

0 Kudos