add CDC interface
This commit is contained in:
parent
47b70f4584
commit
3ae95c20cf
|
@ -23,6 +23,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "stm32f0xx_hal.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -32,6 +34,13 @@
|
|||
|
||||
#include "usb_descriptors.h"
|
||||
|
||||
#define BUTTON1_PORT GPIOA
|
||||
#define BUTTON1_PIN GPIO_PIN_5
|
||||
#define BUTTON1_STATE_ACTIVE 0
|
||||
#define BUTTON2_PORT GPIOA
|
||||
#define BUTTON2_PIN GPIO_PIN_7
|
||||
#define BUTTON2_STATE_ACTIVE 0
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF PROTYPES
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -51,15 +60,38 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
|||
|
||||
void led_blinking_task(void);
|
||||
void hid_task(void);
|
||||
void cdc_task(void);
|
||||
|
||||
static void board_supplement_init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = BUTTON1_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(BUTTON1_PORT, &GPIO_InitStruct);
|
||||
GPIO_InitStruct.Pin = BUTTON2_PIN;
|
||||
HAL_GPIO_Init(BUTTON2_PORT, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
uint32_t board_button1_read(void) {
|
||||
return BUTTON1_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON1_PORT, BUTTON1_PIN);
|
||||
}
|
||||
|
||||
uint32_t board_button2_read(void) {
|
||||
return BUTTON2_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON2_PORT, BUTTON2_PIN);
|
||||
}
|
||||
|
||||
/*------------- MAIN -------------*/
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
|
||||
board_supplement_init();
|
||||
// init device stack on configured roothub port
|
||||
tud_init(BOARD_TUD_RHPORT);
|
||||
|
||||
board_uart_write("\r\npasskey v2\r\n", 14);
|
||||
|
||||
if (board_init_after_tusb) {
|
||||
board_init_after_tusb();
|
||||
}
|
||||
|
@ -70,6 +102,7 @@ int main(void)
|
|||
led_blinking_task();
|
||||
|
||||
hid_task();
|
||||
cdc_task();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,6 +137,49 @@ void tud_resume_cb(void)
|
|||
blink_interval_ms = tud_mounted() ? BLINK_MOUNTED : BLINK_NOT_MOUNTED;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB CDC
|
||||
//--------------------------------------------------------------------+
|
||||
void cdc_task(void) {
|
||||
// connected() check for DTR bit
|
||||
// Most but not all terminal client set this when making connection
|
||||
// if ( tud_cdc_connected() )
|
||||
{
|
||||
// connected and there are data available
|
||||
if (tud_cdc_available()) {
|
||||
// read data
|
||||
char buf[64];
|
||||
uint32_t count = tud_cdc_read(buf, sizeof(buf));
|
||||
(void) count;
|
||||
|
||||
// Echo back
|
||||
// Note: Skip echo by commenting out write() and write_flush()
|
||||
// for throughput test e.g
|
||||
// $ dd if=/dev/zero of=/dev/ttyACM0 count=10000
|
||||
tud_cdc_write(buf, count);
|
||||
tud_cdc_write_flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked when cdc when line state changed e.g connected/disconnected
|
||||
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
|
||||
(void) itf;
|
||||
(void) rts;
|
||||
|
||||
// TODO set some indicator
|
||||
if (dtr) {
|
||||
// Terminal connected
|
||||
} else {
|
||||
// Terminal disconnected
|
||||
}
|
||||
}
|
||||
|
||||
// Invoked when CDC interface received data from host
|
||||
void tud_cdc_rx_cb(uint8_t itf) {
|
||||
(void) itf;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USB HID
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -125,6 +201,7 @@ static void send_hid_report(uint8_t report_id, uint32_t btn)
|
|||
uint8_t keycode[6] = { 0 };
|
||||
keycode[0] = HID_KEY_A;
|
||||
|
||||
board_uart_write("K", 1);
|
||||
tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, keycode);
|
||||
has_keyboard_key = true;
|
||||
}else
|
||||
|
@ -136,64 +213,6 @@ static void send_hid_report(uint8_t report_id, uint32_t btn)
|
|||
}
|
||||
break;
|
||||
|
||||
case REPORT_ID_MOUSE:
|
||||
{
|
||||
int8_t const delta = 5;
|
||||
|
||||
// no button, right + down, no scroll, no pan
|
||||
tud_hid_mouse_report(REPORT_ID_MOUSE, 0x00, delta, delta, 0, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case REPORT_ID_CONSUMER_CONTROL:
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report
|
||||
static bool has_consumer_key = false;
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
// volume down
|
||||
uint16_t volume_down = HID_USAGE_CONSUMER_VOLUME_DECREMENT;
|
||||
tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &volume_down, 2);
|
||||
has_consumer_key = true;
|
||||
}else
|
||||
{
|
||||
// send empty key report (release key) if previously has key pressed
|
||||
uint16_t empty_key = 0;
|
||||
if (has_consumer_key) tud_hid_report(REPORT_ID_CONSUMER_CONTROL, &empty_key, 2);
|
||||
has_consumer_key = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case REPORT_ID_GAMEPAD:
|
||||
{
|
||||
// use to avoid send multiple consecutive zero report for keyboard
|
||||
static bool has_gamepad_key = false;
|
||||
|
||||
hid_gamepad_report_t report =
|
||||
{
|
||||
.x = 0, .y = 0, .z = 0, .rz = 0, .rx = 0, .ry = 0,
|
||||
.hat = 0, .buttons = 0
|
||||
};
|
||||
|
||||
if ( btn )
|
||||
{
|
||||
report.hat = GAMEPAD_HAT_UP;
|
||||
report.buttons = GAMEPAD_BUTTON_A;
|
||||
tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report));
|
||||
|
||||
has_gamepad_key = true;
|
||||
}else
|
||||
{
|
||||
report.hat = GAMEPAD_HAT_CENTERED;
|
||||
report.buttons = 0;
|
||||
if (has_gamepad_key) tud_hid_report(REPORT_ID_GAMEPAD, &report, sizeof(report));
|
||||
has_gamepad_key = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
@ -209,7 +228,7 @@ void hid_task(void)
|
|||
if ( board_millis() - start_ms < interval_ms) return; // not enough time
|
||||
start_ms += interval_ms;
|
||||
|
||||
uint32_t const btn = board_button_read();
|
||||
uint32_t const btn = board_button1_read();
|
||||
|
||||
// Remote wakeup
|
||||
if ( tud_suspended() && btn )
|
||||
|
@ -303,4 +322,6 @@ void led_blinking_task(void)
|
|||
|
||||
board_led_write(led_state);
|
||||
led_state = 1 - led_state; // toggle
|
||||
|
||||
board_uart_write(".", 1);
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
|
||||
//------------- CLASS -------------//
|
||||
#define CFG_TUD_HID 1
|
||||
#define CFG_TUD_CDC 0
|
||||
#define CFG_TUD_CDC 1
|
||||
#define CFG_TUD_MSC 0
|
||||
#define CFG_TUD_MIDI 0
|
||||
#define CFG_TUD_VENDOR 0
|
||||
|
@ -100,6 +100,13 @@
|
|||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
||||
#define CFG_TUD_HID_EP_BUFSIZE 16
|
||||
|
||||
// CDC FIFO size of TX and RX
|
||||
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
|
||||
// CDC Endpoint transfer buffer size, more is faster
|
||||
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -27,17 +27,8 @@
|
|||
#include "tusb.h"
|
||||
#include "usb_descriptors.h"
|
||||
|
||||
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
|
||||
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
|
||||
*
|
||||
* Auto ProductID layout's Bitmap:
|
||||
* [MSB] HID | MSC | CDC [LSB]
|
||||
*/
|
||||
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
|
||||
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
|
||||
_PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )
|
||||
|
||||
#define USB_VID 0xCafe
|
||||
#define USB_PID 0x8861
|
||||
#define USB_VID 0x1d50
|
||||
#define USB_BCD 0x0200
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -48,9 +39,9 @@ tusb_desc_device_t const desc_device =
|
|||
.bLength = sizeof(tusb_desc_device_t),
|
||||
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||
.bcdUSB = USB_BCD,
|
||||
.bDeviceClass = 0x00,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bDeviceClass = TUSB_CLASS_HID,
|
||||
.bDeviceSubClass = HID_SUBCLASS_NONE,
|
||||
.bDeviceProtocol = HID_ITF_PROTOCOL_KEYBOARD,
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
|
||||
.idVendor = USB_VID,
|
||||
|
@ -78,9 +69,6 @@ uint8_t const * tud_descriptor_device_cb(void)
|
|||
uint8_t const desc_hid_report[] =
|
||||
{
|
||||
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )),
|
||||
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE )),
|
||||
TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL )),
|
||||
TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD ))
|
||||
};
|
||||
|
||||
// Invoked when received GET HID REPORT DESCRIPTOR
|
||||
|
@ -99,12 +87,17 @@ uint8_t const * tud_hid_descriptor_report_cb(uint8_t instance)
|
|||
enum
|
||||
{
|
||||
ITF_NUM_HID,
|
||||
ITF_NUM_CDC,
|
||||
ITF_NUM_CDC_DATA,
|
||||
ITF_NUM_TOTAL
|
||||
};
|
||||
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN)
|
||||
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_DESC_LEN + TUD_CDC_DESC_LEN)
|
||||
|
||||
#define EPNUM_HID 0x81
|
||||
#define EPNUM_HID 0x81
|
||||
#define EPNUM_CDC_NOTIF 0x82
|
||||
#define EPNUM_CDC_OUT 0x03
|
||||
#define EPNUM_CDC_IN 0x83
|
||||
|
||||
uint8_t const desc_configuration[] =
|
||||
{
|
||||
|
@ -112,7 +105,11 @@ uint8_t const desc_configuration[] =
|
|||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||
|
||||
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_NONE, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5)
|
||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 0, HID_ITF_PROTOCOL_KEYBOARD, sizeof(desc_hid_report), EPNUM_HID, CFG_TUD_HID_EP_BUFSIZE, 5),
|
||||
|
||||
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 0, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, CFG_TUD_CDC_EP_BUFSIZE),
|
||||
|
||||
};
|
||||
|
||||
#if TUD_OPT_HIGH_SPEED
|
||||
|
@ -128,9 +125,9 @@ tusb_desc_device_qualifier_t const desc_device_qualifier =
|
|||
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
|
||||
.bcdUSB = USB_BCD,
|
||||
|
||||
.bDeviceClass = 0x00,
|
||||
.bDeviceSubClass = 0x00,
|
||||
.bDeviceProtocol = 0x00,
|
||||
.bDeviceClass = TUSB_CLASS_HID,
|
||||
.bDeviceSubClass = HID_SUBCLASS_NONE,
|
||||
.bDeviceProtocol = HID_ITF_PROTOCOL_KEYBOARD,
|
||||
|
||||
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||
.bNumConfigurations = 0x01,
|
||||
|
@ -190,8 +187,8 @@ enum {
|
|||
char const *string_desc_arr[] =
|
||||
{
|
||||
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
||||
"TinyUSB", // 1: Manufacturer
|
||||
"TinyUSB Device", // 2: Product
|
||||
"CuVoodoo", // 1: Manufacturer
|
||||
"passkey v2", // 2: Product
|
||||
NULL, // 3: Serials will use unique ID if possible
|
||||
};
|
||||
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
enum
|
||||
{
|
||||
REPORT_ID_KEYBOARD = 1,
|
||||
REPORT_ID_MOUSE,
|
||||
REPORT_ID_CONSUMER_CONTROL,
|
||||
REPORT_ID_GAMEPAD,
|
||||
REPORT_ID_COUNT
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue