Skip to content

Commit 7aba7a3

Browse files
committed
add hid-mouse
1 parent 95ebbf0 commit 7aba7a3

File tree

14 files changed

+240
-65
lines changed

14 files changed

+240
-65
lines changed

.github/workflows/arm-gcc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
fail-fast: false
1717
matrix:
1818
os: [ubuntu-24.04]
19-
app: [hid-keyboard]
19+
app: [hid-keyboard, hid-mouse]
2020
board: [frdmk22f]
2121
preset: [release]
2222
runs-on: ${{ matrix.os }}

.vscode/tasks.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"version": "2.0.0",
3+
"tasks": [
4+
{
5+
"label": "West update",
6+
"group": {
7+
"kind": "none",
8+
"isDefault": true
9+
},
10+
"options": {
11+
"cwd": "${workspaceFolder}"
12+
},
13+
"type": "process",
14+
"command": "west",
15+
"args": [
16+
"update"
17+
]
18+
},
19+
{
20+
"label": "West patch",
21+
"group": {
22+
"kind": "none",
23+
"isDefault": true
24+
},
25+
"options": {
26+
"cwd": "${workspaceFolder}"
27+
},
28+
"type": "process",
29+
"command": "west",
30+
"args": [
31+
"patch"
32+
],
33+
"dependsOrder": "sequence",
34+
"dependsOn": [
35+
"West update"
36+
]
37+
}
38+
]
39+
}

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ command:
1111
```shell
1212
# initialize my-workspace for the usb-keyboard (main branch)
1313
west init -m https://github.com/IntergatedCircuits/c2usb-mcux-examples c2usb-workspace
14-
cd c2usb-workspace
14+
cd c2usb-mcux-workspace
1515
# update mcuxsdk modules
1616
west update
1717
west patch
@@ -25,9 +25,14 @@ In the latter case open the `projects.code-workspace` file in vscode.
2525
### hid-keyboard
2626

2727
A straightforward USB HID keyboard. Use the button on the board to trigger a caps lock press,
28-
and observe as the host changes the caps lock state on the board's LED. When suspended,
28+
and observe as the host changes the caps lock state on the board's red LED. When suspended,
2929
the button press triggers a remote wakeup request.
3030

31+
### hid-mouse
32+
33+
A USB HID mouse, with high-resolution scrolling support. The red LED lights up if the host enables this feature.
34+
The board's SW2 button scrolls down.
35+
3136
## Building and running
3237

3338
To build an application, run the following command:

common/demo_keyboard.hpp

Lines changed: 0 additions & 53 deletions
This file was deleted.

hid-keyboard/CMakeLists.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@ include("${SdkRootDirPath}/CMakeLists.txt")
1414
mcux_add_macro(
1515
CC "-DUSB_STACK_BM"
1616
)
17-
18-
target_include_directories(${PROJECT_NAME} PUBLIC
19-
"${CMAKE_CURRENT_LIST_DIR}/../common"
17+
target_link_libraries(${PROJECT_NAME} PUBLIC
18+
c2usb-example-hid
2019
)
2120
mcux_add_source(
2221
SOURCES

hid-keyboard/main.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ extern "C"
88
#include "fsl_port.h"
99
#endif
1010
}
11-
#include "demo_keyboard.hpp"
1211
#include "port/nxp/mcux_mac.hpp"
12+
#include "simple_keyboard.hpp"
1313
#include "usb/df/class/hid.hpp"
1414
#include "usb/df/device.hpp"
1515

@@ -56,8 +56,8 @@ extern "C" void USB_DeviceClockInit(void)
5656

5757
auto& keyboard_app()
5858
{
59-
static demo_keyboard kb(
60-
[](const demo_keyboard::kb_leds_report& report)
59+
static simple_keyboard<> kb(
60+
[](const simple_keyboard<>::kb_leds_report& report)
6161
{
6262
GPIO_PinWrite(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PIN,
6363
!report.leds.test(hid::page::leds::CAPS_LOCK));
@@ -108,8 +108,8 @@ int main(void)
108108

109109
static usb::df::hid::function usb_kb{keyboard_app(), usb::hid::boot_protocol_mode::KEYBOARD};
110110
static const auto single_config = usb::df::config::make_config(
111-
usb::df::config::header(usb::df::config::power::bus(100, true), "myconfig"),
112-
usb::df::hid::config(usb_kb, usb::speed::FULL, usb::endpoint::address(0x81), 50));
111+
usb::df::config::header(usb::df::config::power::bus(100, true), "hid-keyboard"),
112+
usb::df::hid::config(usb_kb, usb::speed::FULL, usb::endpoint::address(0x81), 1));
113113
device().set_config(single_config);
114114
device().open();
115115
device().set_power_event_delegate(

hid-mouse/.vscode

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../common/.vscode/

hid-mouse/CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
cmake_minimum_required(VERSION 3.22.0)
2+
3+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
4+
set(CMAKE_CXX_STANDARD 20)
5+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
6+
set(EXTRA_MCUX_MODULES ${CMAKE_CURRENT_LIST_DIR}/../../c2usb)
7+
include("${SdkRootDirPath}/cmake/extension/mcux.cmake")
8+
project(
9+
hid-mouse
10+
LANGUAGES ASM C CXX
11+
)
12+
include("${SdkRootDirPath}/CMakeLists.txt")
13+
14+
mcux_add_macro(
15+
CC "-DUSB_STACK_BM"
16+
)
17+
target_link_libraries(${PROJECT_NAME} PUBLIC
18+
c2usb-example-hid
19+
)
20+
mcux_add_source(
21+
SOURCES
22+
main.cpp
23+
)
24+
25+
mcux_convert_binary(
26+
BINARY "${APPLICATION_BINARY_DIR}/${MCUX_SDK_PROJECT_NAME}.bin"
27+
)

hid-mouse/CMakePresets.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../common/CMakePresets.json

hid-mouse/main.cpp

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
extern "C"
2+
{
3+
#include "board.h"
4+
#include "fsl_gpio.h"
5+
#include "pin_mux.h"
6+
7+
#if defined(FSL_FEATURE_SOC_PORT_COUNT) && (FSL_FEATURE_SOC_PORT_COUNT)
8+
#include "fsl_port.h"
9+
#endif
10+
}
11+
#include "high_resolution_mouse.hpp"
12+
#include "port/nxp/mcux_mac.hpp"
13+
#include "usb/df/class/hid.hpp"
14+
#include "usb/df/device.hpp"
15+
16+
auto& mac()
17+
{
18+
static std::array<uint8_t, 128> buffer;
19+
static auto mac{usb::df::nxp::mcux_mac::khci()};
20+
mac.set_control_buffer(buffer);
21+
return mac;
22+
}
23+
24+
extern "C" void USB0_IRQHandler(void)
25+
{
26+
mac().handle_irq();
27+
SDK_ISR_EXIT_BARRIER;
28+
}
29+
30+
extern "C" void BOARD_InitBootPins(void);
31+
extern "C" void BOARD_InitHardware(void)
32+
{
33+
BOARD_InitBootClocks();
34+
BOARD_InitBootPins();
35+
BOARD_InitLEDsPins();
36+
BOARD_InitBUTTONsPins();
37+
#if (defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) || \
38+
(!defined(FSL_FEATURE_SOC_PORT_COUNT))
39+
GPIO_SetPinInterruptConfig(BOARD_SW2_GPIO, BOARD_SW2_GPIO_PIN, kGPIO_InterruptEitherEdge);
40+
#else
41+
PORT_SetPinInterruptConfig(BOARD_SW2_PORT, BOARD_SW2_GPIO_PIN, kPORT_InterruptEitherEdge);
42+
#endif
43+
EnableIRQ(BOARD_SW2_IRQ);
44+
// BOARD_InitDebugConsole();
45+
}
46+
47+
extern "C" void USB_DeviceClockInit(void)
48+
{
49+
#if ((defined FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && \
50+
(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED))
51+
CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U);
52+
#else
53+
CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
54+
#endif /* FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED */
55+
}
56+
57+
auto& mouse_app()
58+
{
59+
static high_resolution_mouse<> m(
60+
[](const high_resolution_mouse<>::resolution_multiplier_report& report)
61+
{ GPIO_PinWrite(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PIN, report.resolutions == 0); });
62+
return m;
63+
}
64+
65+
static high_resolution_mouse<>::mouse_report mouse_report{};
66+
67+
auto& device()
68+
{
69+
static constexpr usb::product_info prinfo{0x1FC9, "NXP", 0x0091, "c2usb hid-mouse",
70+
usb::version("1.0")};
71+
static usb::df::device_instance<usb::speed::FULL> device{mac(), prinfo};
72+
return device;
73+
}
74+
75+
extern "C" void BOARD_SW2_IRQ_HANDLER(void)
76+
{
77+
#if (defined(FSL_FEATURE_PORT_HAS_NO_INTERRUPT) && FSL_FEATURE_PORT_HAS_NO_INTERRUPT) || \
78+
(!defined(FSL_FEATURE_SOC_PORT_COUNT))
79+
/* Clear external interrupt flag. */
80+
GPIO_GpioClearInterruptFlags(BOARD_SW2_GPIO, 1U << BOARD_SW2_GPIO_PIN);
81+
#else
82+
/* Clear external interrupt flag. */
83+
GPIO_PortClearInterruptFlags(BOARD_SW2_GPIO, 1U << BOARD_SW2_GPIO_PIN);
84+
#endif
85+
bool pressed = GPIO_PinRead(BOARD_SW2_GPIO, BOARD_SW2_GPIO_PIN) == 0;
86+
if (pressed)
87+
{
88+
SysTick_Config(MSEC_TO_COUNT((mouse_app().multiplier_report().high_resolution() ? 10 : 100),
89+
SystemCoreClock));
90+
}
91+
else
92+
{
93+
SysTick->CTRL &= ~_VAL2FLD(SysTick_CTRL_ENABLE, 1);
94+
}
95+
switch (device().power_state())
96+
{
97+
case usb::power::state::L2_SUSPEND:
98+
if (pressed)
99+
{
100+
device().remote_wakeup();
101+
}
102+
break;
103+
case usb::power::state::L0_ON:
104+
mouse_report.wheel_y = pressed ? -1 : 0;
105+
mouse_app().send(mouse_report);
106+
break;
107+
default:
108+
break;
109+
}
110+
SDK_ISR_EXIT_BARRIER;
111+
}
112+
113+
extern "C" void SysTick_Handler(void)
114+
{
115+
if (device().power_state() != usb::power::state::L0_ON)
116+
{
117+
return;
118+
}
119+
mouse_app().send(mouse_report);
120+
SDK_ISR_EXIT_BARRIER;
121+
}
122+
123+
int main(void)
124+
{
125+
BOARD_InitHardware();
126+
USB_DeviceClockInit();
127+
128+
static usb::df::hid::function usb_mouse{mouse_app()};
129+
static const auto single_config = usb::df::config::make_config(
130+
usb::df::config::header(usb::df::config::power::bus(100, true), "hid mouse"),
131+
usb::df::hid::config(usb_mouse, usb::speed::FULL, usb::endpoint::address(0x81), 1));
132+
device().set_config(single_config);
133+
device().open();
134+
device().set_power_event_delegate(
135+
[](usb::df::device& dev, usb::df::device::event ev)
136+
{
137+
GPIO_PinWrite(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PIN,
138+
dev.power_state() != usb::power::state::L0_ON);
139+
});
140+
141+
while (true)
142+
{
143+
__WFI();
144+
}
145+
}

0 commit comments

Comments
 (0)