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
解決済! 解決策の投稿を見る。
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.
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
Best Regards, Fernando and Daniele
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); } }
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.
Obviously we are at your disposal for any clarification.
Best Regards, Fernando and Daniele.
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!
----------------------------------------------------------------------------------------------------------------------------------------
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
Best Regards, Fernando and Daniele
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
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.
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)
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
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
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
Best Regards,
Iva
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