Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic keyboard support #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading