Skip to content

Commit a34b7f0

Browse files
committed
Code.
1 parent 2e36ade commit a34b7f0

File tree

8 files changed

+804
-0
lines changed

8 files changed

+804
-0
lines changed

.github/workflows/cmake.yml

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
name: CMake
2+
3+
on:
4+
push:
5+
pull_request:
6+
release:
7+
types: [created]
8+
9+
env:
10+
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
11+
BUILD_TYPE: Release
12+
13+
jobs:
14+
build:
15+
name: ${{matrix.name}}
16+
strategy:
17+
matrix:
18+
include:
19+
- os: ubuntu-20.04
20+
name: Linux
21+
cache-key: linux
22+
cmake-args: '-DPIMORONI_PICO_PATH=$GITHUB_WORKSPACE/pimoroni-pico -DPICO_SDK_PATH=$GITHUB_WORKSPACE/pico-sdk -DCMAKE_INSTALL_PREFIX=$GITHUB_WORKSPACE/install'
23+
apt-packages: clang-tidy gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlib
24+
25+
runs-on: ${{matrix.os}}
26+
27+
env:
28+
PICO_SDK_PATH: $GITHUB_WORKSPACE/pico-sdk
29+
PIMORONI_PICO_LIBS: $GITHUB_WORKSPACE/pimoroni-pico
30+
RELEASE_FILE: ${{github.event.repository.name}}-${{github.event.release.tag_name}}
31+
32+
steps:
33+
- name: Checkout Code
34+
uses: actions/checkout@v3
35+
with:
36+
path: project
37+
38+
# Checkout the Pimoroni Pico Libraries
39+
- name: Checkout Pimoroni Pico Libraries
40+
uses: actions/checkout@v3
41+
with:
42+
repository: pimoroni/pimoroni-pico
43+
path: pimoroni-pico
44+
45+
# Checkout the Pico SDK
46+
- name: Checkout Pico SDK
47+
uses: actions/checkout@v3
48+
with:
49+
repository: raspberrypi/pico-sdk
50+
path: pico-sdk
51+
submodules: false
52+
53+
# HACK: Update Tiny USB
54+
- name: Update Tiny USB
55+
shell: bash
56+
run: |
57+
cd $GITHUB_WORKSPACE/pico-sdk/
58+
git submodule update --init
59+
cd lib/tinyusb
60+
git pull origin master
61+
62+
# Linux deps
63+
- name: Install deps
64+
if: runner.os == 'Linux'
65+
run: |
66+
sudo apt update && sudo apt install ${{matrix.apt-packages}}
67+
68+
- name: Create Build Environment
69+
run: cmake -E make_directory ${{runner.workspace}}/build
70+
71+
- name: Configure CMake
72+
shell: bash
73+
working-directory: ${{runner.workspace}}/build
74+
run: cmake $GITHUB_WORKSPACE/project -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCPACK_PACKAGE_FILE_NAME=${{env.RELEASE_FILE}} ${{matrix.cmake-args}}
75+
76+
- name: Build
77+
working-directory: ${{runner.workspace}}/build
78+
shell: bash
79+
run: |
80+
cmake --build . --config $BUILD_TYPE -j 2
81+
82+
- name: Build Release Packages
83+
if: github.event_name == 'release'
84+
working-directory: ${{runner.workspace}}/build
85+
shell: bash
86+
run: |
87+
cmake --build . --config $BUILD_TYPE --target package -j 2
88+
89+
- name: Upload .zip
90+
if: github.event_name == 'release'
91+
uses: actions/upload-release-asset@v1
92+
env:
93+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
94+
with:
95+
asset_path: ${{runner.workspace}}/build/${{env.RELEASE_FILE}}.zip
96+
upload_url: ${{github.event.release.upload_url}}
97+
asset_name: ${{env.RELEASE_FILE}}.zip
98+
asset_content_type: application/zip
99+
100+
- name: Upload .tar.gz
101+
if: github.event_name == 'release'
102+
uses: actions/upload-release-asset@v1
103+
env:
104+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
105+
with:
106+
asset_path: ${{runner.workspace}}/build/${{env.RELEASE_FILE}}.tar.gz
107+
upload_url: ${{github.event.release.upload_url}}
108+
asset_name: ${{env.RELEASE_FILE}}.tar.gz
109+
asset_content_type: application/octet-stream

.gitignore

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

CMakeLists.txt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
cmake_minimum_required(VERSION 3.12)
2+
3+
set(NAME usb-gamepads)
4+
set(FAMILY rp2040)
5+
set(BOARD pico_sdk)
6+
7+
include(pico_sdk_import.cmake)
8+
include(pimoroni_pico_import.cmake)
9+
10+
# Gooey boilerplate
11+
project(${NAME} C CXX ASM)
12+
set(CMAKE_C_STANDARD 11)
13+
set(CMAKE_CXX_STANDARD 17)
14+
15+
# Initialize the SDK
16+
pico_sdk_init()
17+
18+
# Include Pimoroni libraries
19+
include(drivers/rgbled/rgbled)
20+
21+
# Add your source files
22+
add_executable(${NAME})
23+
24+
target_sources(${NAME} PUBLIC
25+
${CMAKE_CURRENT_LIST_DIR}/main.cpp
26+
${CMAKE_CURRENT_LIST_DIR}/usb_descriptors.c
27+
)
28+
29+
target_include_directories(${NAME} PUBLIC
30+
${CMAKE_CURRENT_LIST_DIR}
31+
)
32+
33+
target_link_libraries(${NAME} PUBLIC
34+
pico_stdlib pico_unique_id rgbled tinyusb_device tinyusb_board
35+
)
36+
37+
# create map/bin/hex file etc.
38+
pico_add_extra_outputs(${NAME})
39+
40+
# Set up files for the release packages
41+
install(FILES
42+
${CMAKE_CURRENT_BINARY_DIR}/${NAME}.uf2
43+
${CMAKE_CURRENT_LIST_DIR}/README.md
44+
DESTINATION .
45+
)
46+
47+
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
48+
set(CPACK_GENERATOR "ZIP" "TGZ")
49+
include(CPack)

main.cpp

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/*
2+
* The MIT License (MIT)
3+
*
4+
* Copyright (c) 2019 Ha Thach (tinyusb.org)
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*
24+
*/
25+
26+
#include <stdlib.h>
27+
#include <stdio.h>
28+
#include <string.h>
29+
30+
#include "bsp/board.h"
31+
#include "tusb.h"
32+
33+
//--------------------------------------------------------------------+
34+
// MACRO CONSTANT TYPEDEF PROTYPES
35+
//--------------------------------------------------------------------+
36+
37+
// Interface index depends on the order in configuration descriptor
38+
enum {
39+
ITF_KEYBOARD = 0,
40+
ITF_MOUSE = 1
41+
};
42+
43+
/* Blink pattern
44+
* - 250 ms : device not mounted
45+
* - 1000 ms : device mounted
46+
* - 2500 ms : device is suspended
47+
*/
48+
enum {
49+
BLINK_NOT_MOUNTED = 250,
50+
BLINK_MOUNTED = 1000,
51+
BLINK_SUSPENDED = 2500,
52+
};
53+
54+
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
55+
56+
void led_blinking_task(void);
57+
void hid_task(void);
58+
59+
/*------------- MAIN -------------*/
60+
int main(void)
61+
{
62+
board_init();
63+
64+
// init device stack on configured roothub port
65+
tud_init(BOARD_TUD_RHPORT);
66+
67+
while (1)
68+
{
69+
tud_task(); // tinyusb device task
70+
led_blinking_task();
71+
72+
hid_task();
73+
}
74+
75+
return 0;
76+
}
77+
78+
//--------------------------------------------------------------------+
79+
// Device callbacks
80+
//--------------------------------------------------------------------+
81+
82+
// Invoked when device is mounted
83+
void tud_mount_cb(void)
84+
{
85+
blink_interval_ms = BLINK_MOUNTED;
86+
}
87+
88+
// Invoked when device is unmounted
89+
void tud_umount_cb(void)
90+
{
91+
blink_interval_ms = BLINK_NOT_MOUNTED;
92+
}
93+
94+
// Invoked when usb bus is suspended
95+
// remote_wakeup_en : if host allow us to perform remote wakeup
96+
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
97+
void tud_suspend_cb(bool remote_wakeup_en)
98+
{
99+
(void) remote_wakeup_en;
100+
blink_interval_ms = BLINK_SUSPENDED;
101+
}
102+
103+
// Invoked when usb bus is resumed
104+
void tud_resume_cb(void)
105+
{
106+
blink_interval_ms = BLINK_MOUNTED;
107+
}
108+
109+
//--------------------------------------------------------------------+
110+
// USB HID
111+
//--------------------------------------------------------------------+
112+
113+
void hid_task(void)
114+
{
115+
// Poll every 10ms
116+
const uint32_t interval_ms = 10;
117+
static uint32_t start_ms = 0;
118+
119+
if ( board_millis() - start_ms < interval_ms) return; // not enough time
120+
start_ms += interval_ms;
121+
122+
uint32_t const btn = board_button_read();
123+
124+
// Remote wakeup
125+
if ( tud_suspended() && btn )
126+
{
127+
// Wake up host if we are in suspend mode
128+
// and REMOTE_WAKEUP feature is enabled by host
129+
tud_remote_wakeup();
130+
}
131+
132+
/*------------- Keyboard -------------*/
133+
if ( tud_hid_n_ready(ITF_KEYBOARD) )
134+
{
135+
// use to avoid send multiple consecutive zero report for keyboard
136+
static bool has_key = false;
137+
138+
if ( btn )
139+
{
140+
uint8_t keycode[6] = { 0 };
141+
keycode[0] = HID_KEY_A;
142+
143+
tud_hid_n_keyboard_report(ITF_KEYBOARD, 0, 0, keycode);
144+
145+
has_key = true;
146+
}else
147+
{
148+
// send empty key report if previously has key pressed
149+
if (has_key) tud_hid_n_keyboard_report(ITF_KEYBOARD, 0, 0, NULL);
150+
has_key = false;
151+
}
152+
}
153+
154+
/*------------- Mouse -------------*/
155+
if ( tud_hid_n_ready(ITF_MOUSE) )
156+
{
157+
if ( btn )
158+
{
159+
int8_t const delta = 5;
160+
161+
// no button, right + down, no scroll pan
162+
tud_hid_n_mouse_report(ITF_MOUSE, 0, 0x00, delta, delta, 0, 0);
163+
}
164+
}
165+
}
166+
167+
168+
// Invoked when received GET_REPORT control request
169+
// Application must fill buffer report's content and return its length.
170+
// Return zero will cause the stack to STALL request
171+
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
172+
{
173+
// TODO not Implemented
174+
(void) itf;
175+
(void) report_id;
176+
(void) report_type;
177+
(void) buffer;
178+
(void) reqlen;
179+
180+
return 0;
181+
}
182+
183+
// Invoked when received SET_REPORT control request or
184+
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
185+
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
186+
{
187+
// TODO set LED based on CAPLOCK, NUMLOCK etc...
188+
(void) itf;
189+
(void) report_id;
190+
(void) report_type;
191+
(void) buffer;
192+
(void) bufsize;
193+
}
194+
195+
//--------------------------------------------------------------------+
196+
// BLINKING TASK
197+
//--------------------------------------------------------------------+
198+
void led_blinking_task(void)
199+
{
200+
static uint32_t start_ms = 0;
201+
static bool led_state = false;
202+
203+
// Blink every interval ms
204+
if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
205+
start_ms += blink_interval_ms;
206+
207+
board_led_write(led_state);
208+
led_state = 1 - led_state; // toggle
209+
}

0 commit comments

Comments
 (0)