Closed bilogic closed 5 years ago
Hey, The report is indeed the length of the key state for nKRO . Here's an explanation on how the descriptors and report work: https://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/
Have a look at keypress_handles.c
to understand how the reports work better in my implementation, but basically for key presses the value in index 0 of the report is for modifier keys (shift, ctrl etc) , index 1 is for led status keys (caps lock, num lock , etc) and the rest are for general key presses.
Keep in mind the if you are sending reports directly to the queues you need to make sure you are sending the right type of report (Consumer, mouse or keyboard) to the right queue, they all have different lengths and data for each index (take a look at hal_ble.c
to see the different queues) .
The easiest way to just send key strokes would basically be to edit the key_reports
function in mk32_main.cpp
. Instead of scanning the matrix. edit the report state according to the keys you would like to send and send them to thekeyboard_q
.
If you would like to change the size of the reports without changing the size of the pads you can edit the report map (REPORT_COUNT_BYTES
in 'keyboard_config.h') in hid_device_le_prf.c
and split the report_state to smaller chunks sent consecutively (just make sure the size of the report you are sending to the queuecorresponds to the REPORT_COUNT_BYTES
you have modified, REPORT_COUNT_BYTES
correspond to the "general" keystrokes, so the report size will be always be larger by 2 indexes for modifier and led status keys). do not change REPORT_LEN
though, just add another buffer to split the reports before sending them to the keyboard queue).
EDIT:I just noticed The code you quoted is for sending key reports via the encoder. the encoder has the option to send keystrokes as well, but because we already have a report dedicated for the keyboard the easiest way to send a keyboard report via the encoder is to simply use the queue we already have enabled.
Hi,
Thanks for all the info, I will try and follow through.
Earlier, I managed to take inputs from the serial monitor and tried to send out as keystrokes
typedef enum
{
PRESS = 0,
RELEASE,
PRESS_RELEASE,
RELEASE_ALL
} keyboard_action;
typedef struct keyboard_command
{
/** @brief type of this keyboard action */
keyboard_action type;
/** list of keycodes+modfiers to be pressed/released.
* @note Low byte contains the keycode, high byte any modifiers
* */
uint16_t keycode;
} keyboard_command_t;
...
case '3':
keycode = KC_AUDIO_VOL_DOWN;
if ((keycode >= KC_MEDIA_NEXT_TRACK) && (keycode <= KC_AUDIO_VOL_DOWN))
{
media_control_send(keycode);
media_control_release(keycode);
ESP_LOGI(CONSOLE_UART_TAG, "media: vol-");
}
break;
case '4':
keycode = KC_AUDIO_VOL_UP;
if ((keycode >= KC_MEDIA_NEXT_TRACK) && (keycode <= KC_AUDIO_VOL_DOWN))
{
media_control_send(keycode);
media_control_release(keycode);
ESP_LOGI(CONSOLE_UART_TAG, "media: vol+");
}
break;
default:
ESP_LOGI(CONSOLE_UART_TAG, "received: %d/'%c'", character, character);
keyboardCmd.type = PRESS; // 0 aka no modifiers
keyboardCmd.keycode = character;
xQueueSend(keyboard_q, (void *)&keyboardCmd, (TickType_t)0);
keyboardCmd.type = PRESS; // 0 aka no modifiers
keyboardCmd.keycode = 0;
xQueueSend(keyboard_q, (void *)&keyboardCmd, (TickType_t)0);
break;
keypress_handles.c
)Hey,
In the default case you are sending a KeyboardCmd struct which is not what the queue expects, you need to send a uint8_t
array with lengthREPORT_LEN
and assign the keycode you would like to send to one of the indexes (except index 0 or 1 which are reserved as I stated before).
for example:
uint8_t current_report[REPORT_LEN] = {0};
current_report[2] = KC_Q;
xQueueSend(keyboard_q, (void *)¤t_report, (TickType_t)0);
regarding the media control functions on keypress, thank you for noticing, I need to alter them because of the updated Bluetooth components, though I did update them for the encoders, so for example for volume up (for volume up set bit 7 instead of 6:
uint8_t media_state[2]={0};
SET_BIT(media_state[0],6);
xQueueSend(media_q,(void*)&media_state, (TickType_t) 0);
Hope this helps
Hi,
This works now:
case '3':
SET_BIT(media_state[0], 7);
xQueueSend(media_q, (void *)&media_state, (TickType_t)0);
media_state[0] = 0;
xQueueSend(media_q, (void *)&media_state, (TickType_t)0);
ESP_LOGI(CONSOLE_UART_TAG, "media: vol-");
break;
case '4':
SET_BIT(media_state[0], 6);
xQueueSend(media_q, (void *)&media_state, (TickType_t)0);
// vTaskDelay(5 / portTICK_PERIOD_MS);
media_state[0] = 0;
xQueueSend(media_q, (void *)&media_state, (TickType_t)0);
ESP_LOGI(CONSOLE_UART_TAG, "media: vol+");
break;
default:
uint8_t current_report[REPORT_LEN] = {0};
current_report[2] = KC_Q;
xQueueSend(keyboard_q, (void *)¤t_report, (TickType_t)0);
current_report[2] = 0;
xQueueSend(keyboard_q, (void *)¤t_report, (TickType_t)0);
ESP_LOGI(CONSOLE_UART_TAG, "normal: %d/'%c'", character, character);
break;
vTaskDelay(5 / portTICK_PERIOD_MS);
required for key depressing? (I saw this in media_control_send()
of keypress_handles.c
)character
to keycode? (keycode_conv.c
has a char_to_keycode()
but it does nothing) I can write the code if you can help me understand where to read the correct keymap etc.keyboard_config.h
, what about the pins for the matrix/keys themselves?Thank you!
Hi,
I'm trying to test the code and simulate key strokes without having to build an actual keyboard first.
https://github.com/Galzai/MK32/blob/37fb87100272915e3a93eb6e8c0dcbcecef880fe/components/r_encoder/r_encoder.c#L92-L98
https://github.com/Galzai/MK32/blob/37fb87100272915e3a93eb6e8c0dcbcecef880fe/components/r_encoder/r_encoder.c#L37
key_state
is declared to be the length ofREPORT_LEN
which is 53 Any example of the format/values ofkey_state
? It seems awfully long to send just 1 key or is it for nKRO?It is my understanding that
xQueueSend()
will triggerxQueueReceive()
inhalBLETask_keyboard()
=>hid_dev_send_report()
=>esp_ble_gatts_send_indicate()
, but that is where I get lost, I cannot find much info about sending key strokes usingesp_ble_gatts_send_indicate()
.Thank you.