View previous topic :: View next topic |
Author |
Message |
spilz
Joined: 30 Jan 2012 Posts: 220
|
[solved] 18F47J53 dual USB mode : uart /hid |
Posted: Sun Nov 26, 2017 9:41 am |
|
|
Hello
I would like to know if there is a way to switch the USB mode from hid to uart and from uart to hid.
I use uart as debug, but now I need to use the USB port as hid keyboard, but still want to be able to use uart for debug when needed.
A solution with a selection on start is ok for my use (if a jumper is set on startup -> uart, else -> hid).
Someone know how to do or if it's not possible ?
Thanks for your help.
Regards
Last edited by spilz on Tue Nov 28, 2017 3:01 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Sun Nov 26, 2017 11:28 am |
|
|
I'd setup the device in dual mode (composite).
There is nothing to stop you setting the device up in composite mode, so it is both a HID and CDC device.
There is a kb/mouse example composite device supplied with the compiler. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Sun Nov 26, 2017 12:42 pm |
|
|
Thanks for your reply
I thought it was not possible, so it's a very good news if I can do it
Actually I tried to do it with the example kb/mouse but I thought it was possible only because both are hid, i don't see where I composite mode is set. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Sun Nov 26, 2017 1:29 pm |
|
|
You would need to take a composite descriptor, like the one here:
<https://bitbucket.org/sparkbuzz/pic32_usb.x/src>
and put the CDC and HID values your device wants in place of the values used.
The example shows how you talk to the endpoints. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Sun Nov 26, 2017 1:39 pm |
|
|
I saw an other exemple file which seems doing exactly what I need : ex_usb_hid_and_cdc.c
I'm able to compile, but only uart work, hid seems not working :(
I maybe miss understand Something and what hid should do on this exemple... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Sun Nov 26, 2017 2:23 pm |
|
|
The HID in that example just sends the ADC value as an output, and operates three LED's from the value received. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Sun Nov 26, 2017 2:28 pm |
|
|
ho I see,
I thought it act as a keyboard :(
I tried to change the my_hid_demo(void) function by a KB function, but it doesn't work.
I guess the solution is the composite descriptor you talk about but I don't know enough USB to understand it :( |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Sun Nov 26, 2017 3:09 pm |
|
|
I don't really understand why usb_desc_key_cdc.h doesn't work as descriptor :( |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Sun Nov 26, 2017 4:39 pm |
|
|
I found an example I didn't see before : ex_usb_keyboard_and_cdc.c
It does exactly what I need
It works alone, but when I try to add it on my personal project, keyboard seems never be released, I can change the key pressed, but can't release it :(
Any idea what can do it ? or solve it ?
regards |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Mon Nov 27, 2017 1:44 am |
|
|
You do understand how a keyboard works in Windows?.
Note how the keyboard_task in the example puts the packet, even if there is no character to send. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Mon Nov 27, 2017 2:35 am |
|
|
If I understand right, the HID should send the key which are pressed, if no key are pressed, it should send only null value.
In my personal code, I try to ask only one time keyboard_task but the key stays like pressed.
I tried to call an other time keyboard_task with only null value, but doesn't solve the issue :( |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Mon Nov 27, 2017 4:16 am |
|
|
You need to send three null bytes, not just a single null.
The packet sent has the modifier keys, then the padding, and finally the key array. Both the modifier key value, and the key array have to be 0 to say everything has released, so a three byte packet.
So
tx_msg[2]=0;
tx_msg[0]=0;
Then the usb_put_packet. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Mon Nov 27, 2017 3:49 pm |
|
|
Ok, I found my mistake:
I sent the second usb_put_packet with null values too fast, adding delay_ms(10) solve the issue
Now I need to understand how I can do several keys pressed:
LeftShift + LeftWindows + LeftAlt + 'b'
But I don't know where to find the value of each key.
For LeftShift + LeftAlt + 'b' , I tried to send HID values:
Code: |
tx_msg[0]=0;
tx_msg[1]=0;
tx_msg[2]=5; // for 'b'
tx_msg[3]=2; // for LeftShift ??
tx_msg[4]=4; // for LeftAlt ??
tx_msg[5]=0;
tx_msg[6]=0; |
(I didn't find LeftWindows value).
But it doesn't work :( |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19557
|
|
Posted: Tue Nov 28, 2017 2:27 am |
|
|
The shift keys are the key 'modifiers'. Byte 0 in the transmission.
Code: |
typedef enum
{
KB_MODIFIER_LEFT_CTRL = 1,
KB_MODIFIER_LEFT_SHIFT = 2,
KB_MODIFIER_LEFT_ALT = 4,
KB_MODIFIER_LEFT_GUI = 8,
KB_MODIFIER_RIGHT_CTRL = 16,
KB_MODIFIER_RIGHT_SHIFT = 32,
KB_MODIFIER_RIGHT_ALT = 64,
KB_MODIFIER_RIGHT_GUI = 128
} kb_modifier_t;
|
The 'Windows' key is the GUI define.
So KB_MODIFIER_LEFT_SHIFT | KB_MODIFIER_LEFT_GUI | KB_MODIFIER_LEFT_ALT, sent in 'modifier'. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Tue Nov 28, 2017 3:00 am |
|
|
Thank you Ttelmah, it works now |
|
|
|