Hi,
I use the board MCBSTM32Exl (http://www.keil.com/arm/mcbstm32exl/) and i wanna that my Board emulate a USB HID Keyboard (When i use the push-button User, the char 'Q' is send to my PC Host). For this, i studied the STMicroelectronics' library "USB full-speed device library" (www.st.com/.../um0424.zip) and adapted interruptions/GPIOs to use this Flibrary with my Board. Also, my PC recognize the device and i successed send data (I watched with a sniffer).
But, it's not like a keyboard, i tried to change the descriptor but it does'nt work (for exemple, my PC don't recognize the device)...
Have you any idea to help me ?
Regards, ealary.
1) Run Custom_HID project on uVision IDE, select "STM3210E-EVAL" at the target pulldown on the tool bar. ST's STM3210E-EVAL board is closer to MCBSTM32Exl - STM32F103ZG - Both boards mount 8MHz crystal - PB15 pin connects to "USB Disconnect" circuitry
2) Replace report descriptor to a keyboard one. You may take it from keybrd.hid example of HID Descriptor Tool
HID Descriptor Tool on USB.org www.usb.org/.../dt2_4.zip
\STM32_USB-FS-Device_Lib_V3.3.0\Project\Custom_HID\src\usb_desc.h #define CUSTOMHID_SIZ_REPORT_DESC 63
\STM32_USB-FS-Device_Lib_V3.3.0\Project\Custom_HID\src\usb_desc.c const uint8_t CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] = { // drag in from keybrd.hid example 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x95, 0x05, // REPORT_COUNT (5) 0x75, 0x01, // REPORT_SIZE (1) 0x05, 0x08, // USAGE_PAGE (LEDs) 0x19, 0x01, // USAGE_MINIMUM (Num Lock) 0x29, 0x05, // USAGE_MAXIMUM (Kana) 0x91, 0x02, // OUTPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x03, // REPORT_SIZE (3) 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0 // END_COLLECTION };
3) Put 8-bytes input report of keyboard over the interrupt IN endpoint, when a key makes and when the key breaks.
I explained on the contents of this input report in this topic on SiLabs forum, USB HID KEYBOARD www.cygnal.org/.../001381.html
On the ST's example, the report is sent to host using USB_SIL_Write(). You'll see a typical code in EXTI9_5_IRQHandler() (\STM32_USB-FS-Device_Lib_V3.3.0\Project\Custom_HID\src\stm32f10x_it.c)
In this file, DMA1_Channel1_IRQHandler() and EXTI15_10_IRQHandler() also put input reports using USB_SIL_Write(). You have to disable these IRQs, so that any spurious report doesn't come out.
4) Optionally, implement Set_Report( Output ) process. Host puts output reports for keyboard LED over Set_Report( Output ) request. In this post to ST forum, I showed Set_Report( Feature ) implementation.
my.st.com/.../Flat.aspx
In CustomHID_Data_Setup() routine, copy the lines on case SET_REPORT/case HID_FEATURE into case SET_REPORT/case HID_OUTPUT
4) Optionally, remove interrupt OUT endpoint from the config descriptor set Also delete routines relates to the interrupt OUT endpoint The interrupt OUT endpoint is not used on keyboard implementation.
Tsuneo
Hi, thank for your answer.
Into the usb_desc.c, should i change anything with the Report Descriptor ? (Like, wMaxPacketSize into the Endpoint Descriptor ?)
3) Put 8-bytes input report of keyboard over the interrupt IN endpoint, when a key makes and when the key breaks. Here, should i have change the buffer size in
\Custom_HID\src\stm32f10x_it.c __IO uint8_t Send_Buffer[2];
for
__IO uint8_t Send_Buffer[8];
or keep the Buffer[2] and use :
USB_SIL_Write(EP1_IN, (uint8_t*) Send_Buffer, 8);
inside EXTI9_5_IRQHandler(void)
Also, in the interrupt (EXTI9_5_IRQHandler), which type of data should i insert into the buffer to send the char 'Q' for exemple ?
Regards, ealary
> Into the usb_desc.c, should i change anything with the Report Descriptor ? (Like, wMaxPacketSize into the Endpoint Descriptor ?)
Ah yes, good catch. wMaxPacketSize of the interrupt IN endpoint descriptor increases to 8 bytes, to put the input report in single transaction.
Also, the buffer size for the input report increases into 8 bytes.
> which type of data should i insert into the buffer to send the char 'Q' for exemple ?
As explained on SiLabs forum ( www.cygnal.org/.../001381.html ),
At key push: input_report[8] = { 0x00, // modifier keys - nothing 0x00, // reserved 0x14, // keycode array[0] - key code of "Q" 0x00, // keycode array[1] 0x00, // keycode array[2] 0x00, // keycode array[3] 0x00, // keycode array[4] 0x00, // keycode array[5] } At key release: - all zeros: input_report[8] = { 0x00, // modifier keys - nothing 0x00, // reserved 0x00, // keycode array[0] 0x00, // keycode array[1] 0x00, // keycode array[2] 0x00, // keycode array[3] 0x00, // keycode array[4] 0x00, // keycode array[5] }
Oops, Increase the endpoint buffer size on the USB engine, too.
\STM32_USB-FS-Device_Lib_V3.3.0\Project\Custom_HID\src\usb_prop.c void CustomHID_Reset(void) { ... ... SetEPTxCount(ENDP1, 2); // <-- SetEPTxCount(ENDP1, 8)
Thank for your quick answer !
I applied the modifications (Report, Interrupt etc...) but now, when i watch my USB sniffer (USBlyzer), nothing is transmit...
Do you know why and how fixe that ?
Regards Ealary
1) Clean up wrong device instance(s) on registry On the PC Device Manager, do you see an extra keyboard, made by your device? If you wouldn't, unplug your device. a) And uninstall all the device instance(s) of VID/PID = 0x0483/0x5750, using USBDeview
USBDeview www.nirsoft.net/.../usb_devices_view.html
OR b) Assign another VID/PID on the device descriptor
2) Key interrupt ST's example sees the User Button on STM3210E-EVAL board which connects to PG8. Fortunately, Keil MCBSTM32Exl also has a User Button at PG8.
To enable interrupt on both edge,
\STM32_USB-FS-Device_Lib_V3.3.0\Utilities\STM32_EVAL\STM3210E_EVAL\stm3210e_eval.c void STM_EVAL_PBInit(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode) { ... ... if(Button != BUTTON_WAKEUP) { EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; if (Button == BUTTON_KEY) // <--- add these two lines EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; }
OR
You may poll this User Button in main loop, instead of interrupt And put above input reports at the state transition
Hi
Clean the wrong instance has successed. Now my board is recognizes like a Keyboard, thank you.
But now,when i push the button the char is alway send (Like when you keep push a key).
Do you know why ?
Regards, Ealary
Do you generate any key-up event?
My keyboard with the MCBSTM32Exl board work perfectly. But now, i need to emulate the Keyboard with a single microcontroller (STM32F103RC) into a protoboard to keep just the USB feature and can add more button. I have adapted the code of MCBSTM32 to the STM32F103RC. I modified the buttons placement with the EXTIs Line and the USB_DISCONNECT pin.
But when i connect the USB line, nothing is happen. My PC don't recognize the "device" and provide just the power into the protoboard. When i look the base board schematics of MCBSTM32, i see that the D+ and D- lines are PA11 and PA12 but i see nothing in the code about this lines...
How can i do to emulate my keyboard with the protoboard ?
Check the pin connections. Connection requirements for your custom USB board are, 1) PA12 for D+ on USB connector (pin 3), PA11 for D- (pin 2) 2) PB14 for "USB Disconnect" circuitry (*1) 3) 8MHz crystal
(*1) I wrote it's PB15 in my first post, but it was wrong. On both boards (MCBSTM32Exl and STM3210E-EVAL), PB14 is the "USB Disconnect" pin.
My pins connections is correct. That why i don't understand why my PC don't recognize the protoboard :/
How about other pins? 1) BOOT0 (pin 60) - GND 2) NRST (pin 7) - JTAG TRST
BOOT0 at GND NRST at JtagTRST...
It's not a firmware issue rather that hardware connection ?
Ealary.
> It's not a firmware issue rather that hardware connection ?
The difference of STM32F103RC from STM32F103ZG, related to your project, is just FLASH memory size. The binary of MCBSTM32Exl project should work on STM32F103RC.