Skip to content

Commit

Permalink
Basic keyboard support
Browse files Browse the repository at this point in the history
- new detection mode for keyboard support
- when the click or motion detection mode is selected it primarily searches for a boot mouse interface
- when the key detection mode is selected it primarily searches for a boot keyboard interface
-
  • Loading branch information
RockyZeroFour committed Apr 10, 2024
1 parent 84a8216 commit e1fc9ed
Show file tree
Hide file tree
Showing 8 changed files with 511 additions and 53 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ set(USB_Sources
src/usb/usbh_pipes.c
src/usb/usbh_hid.c
src/usb/usbh_hid_mouse.c
src/usb/usbh_hid_keyboard.c
)

add_definitions(
Expand Down
7 changes: 5 additions & 2 deletions src/gfx_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,12 @@ void gfx_set_byte_offsets_text(void)
hid_data_location_t * button = xlat_get_button_location();
hid_data_location_t * x = xlat_get_x_location();
hid_data_location_t * y = xlat_get_y_location();
hid_data_location_t * key = xlat_get_key_location();

if (button->found && x->found && y->found) {
sprintf(text, "Data: click@%d motion@%d,%d", button->byte_offset, x->byte_offset, y->byte_offset);
if (button->found && x->found && y->found && XLAT_MODE_KEY != xlat_get_mode()) {
sprintf(text, "Mouse Data: click@%d motion@%d,%d", button->byte_offset, x->byte_offset, y->byte_offset);
} else if (key->found && XLAT_MODE_KEY == xlat_get_mode()) {
sprintf(text, "Keyboard Data: pressed@%d", key->byte_offset);
} else {
// offsets not found
sprintf(text, "Data: offsets not found");
Expand Down
29 changes: 19 additions & 10 deletions src/gfx_settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,21 @@ static void event_handler(lv_event_t* e)
else if (obj == (lv_obj_t *)detection_dropdown) {
// Detection mode changed
uint16_t sel = lv_dropdown_get_selected(obj);
if (sel == 0) {
// Click
xlat_set_mode(XLAT_MODE_CLICK);
} else {
// Motion
xlat_set_mode(XLAT_MODE_MOTION);

switch (sel) {
// Motion [M]
case 1:
xlat_set_mode(XLAT_MODE_MOTION);
break;

// Key [K]
case 2:
xlat_set_mode(XLAT_MODE_KEY);
break;

// Click [M]
default:
xlat_set_mode(XLAT_MODE_CLICK);
}
}
else {
Expand Down Expand Up @@ -146,14 +155,14 @@ void gfx_settings_create_page(lv_obj_t *previous_screen)
lv_obj_add_event_cb((struct _lv_obj_t *) trigger_dropdown, event_handler, LV_EVENT_VALUE_CHANGED, NULL);


// Click vs. motion detection label
// Click, motion & key detection label
lv_obj_t *detection_mode = lv_label_create(settings_screen);
lv_label_set_text(detection_mode, "Detection Mode:");
lv_obj_align_to(detection_mode, trigger_label, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 30);

// Click vs. motion detection dropdown
// Click, motion & key detection dropdown
detection_dropdown = (lv_dropdown_t *) lv_dropdown_create(settings_screen);
lv_dropdown_set_options((lv_obj_t *) detection_dropdown, "Click\nMotion");
lv_dropdown_set_options((lv_obj_t *) detection_dropdown, "Click [M]\nMotion [M]\nKey [K]");
lv_obj_add_event_cb((struct _lv_obj_t *) detection_dropdown, event_handler, LV_EVENT_VALUE_CHANGED, NULL);

// If we don't add this label, the y-value of the last item will be 0
Expand Down Expand Up @@ -222,7 +231,7 @@ void gfx_settings_create_page(lv_obj_t *previous_screen)
lv_dropdown_set_selected((lv_obj_t *) debounce_dropdown, debounce_index);

// Display current detection mode
lv_dropdown_set_selected((lv_obj_t *) detection_dropdown, xlat_get_mode() == XLAT_MODE_MOTION);
lv_dropdown_set_selected((lv_obj_t *) detection_dropdown, xlat_get_mode());


// Display current detection edge
Expand Down
6 changes: 4 additions & 2 deletions src/usb/usbh_hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "usbh_hid_parser.h"
#include "xlat.h"
#include "usbh_hid_mouse.h"
#include "usbh_hid_keyboard.h"


static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost);
Expand Down Expand Up @@ -65,8 +66,8 @@ static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost)
uint8_t num = 0U;
uint8_t interface;

// First try to find a Mouse interface, specifically:
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, HID_MOUSE_BOOT_CODE);
// First try to find a Mouse or Keyboard interface depending on the detection mode, specifically:
interface = USBH_FindInterface(phost, phost->pActiveClass->ClassCode, HID_BOOT_CODE, (XLAT_MODE_KEY == xlat_get_mode()) ? HID_KEYBRD_BOOT_CODE : HID_MOUSE_BOOT_CODE);

// Broaden the search criteria to no specific protocol
if (interface == 0xFFU) {
Expand Down Expand Up @@ -113,6 +114,7 @@ static USBH_StatusTypeDef USBH_HID_InterfaceInit(USBH_HandleTypeDef *phost)
/*Decode Bootclass Protocol: Mouse or Keyboard, see HID_KEYBRD_BOOT_CODE, HID_MOUSE_BOOT_CODE */
if (phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol == HID_KEYBRD_BOOT_CODE) {
USBH_UsrLog("KeyBoard device found! (iface: %d)", interface);
HID_Handle->Init = USBH_HID_KeyboardInit;
} else if (phost->device.CfgDesc.Itf_Desc[interface].bInterfaceProtocol == HID_MOUSE_BOOT_CODE) {
USBH_UsrLog("Mouse device found! (iface: %d)", interface);
HID_Handle->Init = USBH_HID_MouseInit;
Expand Down
245 changes: 245 additions & 0 deletions src/usb/usbh_hid_keyboard.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
/*
* Copyright (c) 2015 STMicroelectronics.
* Copyright (c) 2023 Finalmouse, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/


/* BSPDependencies
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
- "stm32xxxxx_{eval}{discovery}_io.c"
- "stm32xxxxx_{eval}{discovery}{adafruit}_lcd.c"
- "stm32xxxxx_{eval}{discovery}_sdram.c"
EndBSPDependencies */

/* Includes ------------------------------------------------------------------*/
#include "usbh_hid_keyboard.h"
#include "usbh_hid_parser.h"


/** @addtogroup USBH_LIB
* @{
*/

/** @addtogroup USBH_CLASS
* @{
*/

/** @addtogroup USBH_HID_CLASS
* @{
*/

/** @defgroup USBH_HID_KEYBOARD
* @brief This file includes HID Layer Handlers for USB Host HID class.
* @{
*/

/** @defgroup USBH_HID_KEYBOARD_Private_TypesDefinitions
* @{
*/
/**
* @}
*/


/** @defgroup USBH_HID_KEYBOARD_Private_Defines
* @{
*/
/**
* @}
*/


/** @defgroup USBH_HID_KEYBOARD_Private_Macros
* @{
*/
/**
* @}
*/

/** @defgroup USBH_HID_KEYBOARD_Private_FunctionPrototypes
* @{
*/
static USBH_StatusTypeDef USBH_HID_KeyboardDecode(USBH_HandleTypeDef *phost);

/**
* @}
*/


/** @defgroup USBH_HID_KEYBOARD_Private_Variables
* @{
*/
HID_KEYBOARD_Info_TypeDef keyboard_info;
uint8_t keyboard_report_data[USBH_HID_KEYBOARD_REPORT_SIZE];
uint8_t keyboard_rx_report_buf[USBH_HID_KEYBOARD_REPORT_SIZE];

/* Structures defining how to access items in a HID keyboard report */
/* Access key 1 state. */
static const HID_Report_ItemTypedef prop_k1 =
{
keyboard_report_data, /*data*/
1, /*size*/
0, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min value device can report*/
1, /*max value device can report*/
1 /*resolution*/
};

/* Access key 2 state. */
static const HID_Report_ItemTypedef prop_k2 =
{
keyboard_report_data, /*data*/
1, /*size*/
1, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min value device can report*/
1, /*max value device can report*/
1 /*resolution*/
};

/* Access key 3 state. */
static const HID_Report_ItemTypedef prop_k3 =
{
keyboard_report_data, /*data*/
1, /*size*/
2, /*shift*/
0, /*count (only for array items)*/
0, /*signed?*/
0, /*min value read can return*/
1, /*max value read can return*/
0, /*min vale device can report*/
1, /*max value device can report*/
1 /*resolution*/
};


/**
* @}
*/


/** @defgroup USBH_HID_KEYBOARD_Private_Functions
* @{
*/

/**
* @brief USBH_HID_KeyboardInit
* The function init the HID keyboard.
* @param phost: Host handle
* @retval USBH Status
*/
USBH_StatusTypeDef USBH_HID_KeyboardInit(USBH_HandleTypeDef *phost)
{
uint32_t i;
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;

keyboard_info.keys[0] = 0U;
keyboard_info.keys[1] = 0U;
keyboard_info.keys[2] = 0U;

for (i = 0U; i < sizeof(keyboard_report_data); i++)
{
keyboard_report_data[i] = 0U;
keyboard_rx_report_buf[i] = 0U;
}

if (HID_Handle->length > sizeof(keyboard_report_data))
{
HID_Handle->length = (uint16_t)sizeof(keyboard_report_data);
}
HID_Handle->pData = keyboard_rx_report_buf;

if ((HID_QUEUE_SIZE * sizeof(keyboard_report_data)) > sizeof(phost->device.Data)) {
return USBH_FAIL;
} else {
USBH_HID_FifoInit(&HID_Handle->fifo, phost->device.Data, (uint16_t)(HID_QUEUE_SIZE * sizeof(keyboard_report_data)));
}

return USBH_OK;
}

/**
* @brief USBH_HID_GetKeyboardInfo
* The function return keyboard information.
* @param phost: Host handle
* @retval keyboard information
*/
HID_KEYBOARD_Info_TypeDef *USBH_HID_GetKeyboardInfo(USBH_HandleTypeDef *phost)
{
if (USBH_HID_KeyboardDecode(phost) == USBH_OK)
{
return &keyboard_info;
}
else
{
return NULL;
}
}

/**
* @brief USBH_HID_KeyboardDecode
* The function decode keyboard data.
* @param phost: Host handle
* @retval USBH Status
*/
static USBH_StatusTypeDef USBH_HID_KeyboardDecode(USBH_HandleTypeDef *phost)
{
HID_HandleTypeDef *HID_Handle = (HID_HandleTypeDef *) phost->pActiveClass->pData;

if ((HID_Handle->length == 0U) || (HID_Handle->fifo.buf == NULL))
{
return USBH_FAIL;
}
/*Fill report */
if (USBH_HID_FifoRead(&HID_Handle->fifo, &keyboard_report_data, HID_Handle->length) == HID_Handle->length)
{
/*Decode report */
keyboard_info.keys[0] = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &prop_k1, 0U);
keyboard_info.keys[1] = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &prop_k2, 0U);
keyboard_info.keys[2] = (uint8_t)HID_ReadItem((HID_Report_ItemTypedef *) &prop_k3, 0U);

return USBH_OK;
}
return USBH_FAIL;
}

/**
* @}
*/

/**
* @}
*/

/**
* @}
*/

/**
* @}
*/


/**
* @}
*/
Loading

0 comments on commit e1fc9ed

Please sign in to comment.