f1: h103: drop duplicate usb_hid example.
This example was functionally similar to the "other" example, but had the actual functional mouse movement disabled. To reduce maintennance cost with slightly divergent examples, simply drop the less useful example.
This commit is contained in:
@@ -1,25 +0,0 @@
|
||||
##
|
||||
## This file is part of the libopencm3 project.
|
||||
##
|
||||
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
|
||||
##
|
||||
## This library is free software: you can redistribute it and/or modify
|
||||
## it under the terms of the GNU Lesser General Public License as published by
|
||||
## the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This library 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 Lesser General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU Lesser General Public License
|
||||
## along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
##
|
||||
|
||||
BINARY = usbhid
|
||||
|
||||
LDSCRIPT = ../stm32-h103.ld
|
||||
|
||||
include ../../Makefile.include
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
# README
|
||||
|
||||
This example implements a USB Human Interface Device (HID)
|
||||
to demonstrate the use of the USB device stack.
|
||||
|
||||
@@ -1,317 +0,0 @@
|
||||
/*
|
||||
* This file is part of the libopencm3 project.
|
||||
*
|
||||
* Copyright (C) 2010 Gareth McMullin <gareth@blacksphere.co.nz>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <libopencm3/stm32/rcc.h>
|
||||
#include <libopencm3/stm32/gpio.h>
|
||||
#include <libopencm3/cm3/systick.h>
|
||||
#include <libopencm3/usb/usbd.h>
|
||||
#include <libopencm3/usb/hid.h>
|
||||
|
||||
/* Define this to include the DFU APP interface. */
|
||||
#define INCLUDE_DFU_INTERFACE
|
||||
|
||||
#ifdef INCLUDE_DFU_INTERFACE
|
||||
#include <libopencm3/cm3/scb.h>
|
||||
#include <libopencm3/usb/dfu.h>
|
||||
#endif
|
||||
|
||||
const struct usb_device_descriptor dev = {
|
||||
.bLength = USB_DT_DEVICE_SIZE,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
.bcdUSB = 0x0200,
|
||||
.bDeviceClass = 0,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.bMaxPacketSize0 = 64,
|
||||
.idVendor = 0x0483,
|
||||
.idProduct = 0x5710,
|
||||
.bcdDevice = 0x0200,
|
||||
.iManufacturer = 1,
|
||||
.iProduct = 2,
|
||||
.iSerialNumber = 3,
|
||||
.bNumConfigurations = 1,
|
||||
};
|
||||
|
||||
static const uint8_t hid_report_descriptor[] = {
|
||||
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
|
||||
0x09, 0x02, /* USAGE (Mouse) */
|
||||
0xa1, 0x01, /* COLLECTION (Application) */
|
||||
0x09, 0x01, /* USAGE (Pointer) */
|
||||
0xa1, 0x00, /* COLLECTION (Physical) */
|
||||
0x05, 0x09, /* USAGE_PAGE (Button) */
|
||||
0x19, 0x01, /* USAGE_MINIMUM (Button 1) */
|
||||
0x29, 0x03, /* USAGE_MAXIMUM (Button 3) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x95, 0x03, /* REPORT_COUNT (3) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x81, 0x02, /* INPUT (Data,Var,Abs) */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0x75, 0x05, /* REPORT_SIZE (5) */
|
||||
0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */
|
||||
0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */
|
||||
0x09, 0x30, /* USAGE (X) */
|
||||
0x09, 0x31, /* USAGE (Y) */
|
||||
0x09, 0x38, /* USAGE (Wheel) */
|
||||
0x15, 0x81, /* LOGICAL_MINIMUM (-127) */
|
||||
0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */
|
||||
0x75, 0x08, /* REPORT_SIZE (8) */
|
||||
0x95, 0x03, /* REPORT_COUNT (3) */
|
||||
0x81, 0x06, /* INPUT (Data,Var,Rel) */
|
||||
0xc0, /* END_COLLECTION */
|
||||
0x09, 0x3c, /* USAGE (Motion Wakeup) */
|
||||
0x05, 0xff, /* USAGE_PAGE (Vendor Defined Page 1) */
|
||||
0x09, 0x01, /* USAGE (Vendor Usage 1) */
|
||||
0x15, 0x00, /* LOGICAL_MINIMUM (0) */
|
||||
0x25, 0x01, /* LOGICAL_MAXIMUM (1) */
|
||||
0x75, 0x01, /* REPORT_SIZE (1) */
|
||||
0x95, 0x02, /* REPORT_COUNT (2) */
|
||||
0xb1, 0x22, /* FEATURE (Data,Var,Abs,NPrf) */
|
||||
0x75, 0x06, /* REPORT_SIZE (6) */
|
||||
0x95, 0x01, /* REPORT_COUNT (1) */
|
||||
0xb1, 0x01, /* FEATURE (Cnst,Ary,Abs) */
|
||||
0xc0 /* END_COLLECTION */
|
||||
};
|
||||
|
||||
static const struct {
|
||||
struct usb_hid_descriptor hid_descriptor;
|
||||
struct {
|
||||
uint8_t bReportDescriptorType;
|
||||
uint16_t wDescriptorLength;
|
||||
} __attribute__((packed)) hid_report;
|
||||
} __attribute__((packed)) hid_function = {
|
||||
.hid_descriptor = {
|
||||
.bLength = sizeof(hid_function),
|
||||
.bDescriptorType = USB_DT_HID,
|
||||
.bcdHID = 0x0100,
|
||||
.bCountryCode = 0,
|
||||
.bNumDescriptors = 1,
|
||||
},
|
||||
.hid_report = {
|
||||
.bReportDescriptorType = USB_DT_REPORT,
|
||||
.wDescriptorLength = sizeof(hid_report_descriptor),
|
||||
},
|
||||
};
|
||||
|
||||
const struct usb_endpoint_descriptor hid_endpoint = {
|
||||
.bLength = USB_DT_ENDPOINT_SIZE,
|
||||
.bDescriptorType = USB_DT_ENDPOINT,
|
||||
.bEndpointAddress = 0x81,
|
||||
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
|
||||
.wMaxPacketSize = 4,
|
||||
.bInterval = 0x20,
|
||||
};
|
||||
|
||||
const struct usb_interface_descriptor hid_iface = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 0,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 1,
|
||||
.bInterfaceClass = USB_CLASS_HID,
|
||||
.bInterfaceSubClass = 1, /* boot */
|
||||
.bInterfaceProtocol = 2, /* mouse */
|
||||
.iInterface = 0,
|
||||
|
||||
.endpoint = &hid_endpoint,
|
||||
|
||||
.extra = &hid_function,
|
||||
.extralen = sizeof(hid_function),
|
||||
};
|
||||
|
||||
#ifdef INCLUDE_DFU_INTERFACE
|
||||
const struct usb_dfu_descriptor dfu_function = {
|
||||
.bLength = sizeof(struct usb_dfu_descriptor),
|
||||
.bDescriptorType = DFU_FUNCTIONAL,
|
||||
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
|
||||
.wDetachTimeout = 255,
|
||||
.wTransferSize = 1024,
|
||||
.bcdDFUVersion = 0x011A,
|
||||
};
|
||||
|
||||
const struct usb_interface_descriptor dfu_iface = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = 1,
|
||||
.bAlternateSetting = 0,
|
||||
.bNumEndpoints = 0,
|
||||
.bInterfaceClass = 0xFE,
|
||||
.bInterfaceSubClass = 1,
|
||||
.bInterfaceProtocol = 1,
|
||||
.iInterface = 0,
|
||||
|
||||
.extra = &dfu_function,
|
||||
.extralen = sizeof(dfu_function),
|
||||
};
|
||||
#endif
|
||||
|
||||
const struct usb_interface ifaces[] = {{
|
||||
.num_altsetting = 1,
|
||||
.altsetting = &hid_iface,
|
||||
#ifdef INCLUDE_DFU_INTERFACE
|
||||
}, {
|
||||
.num_altsetting = 1,
|
||||
.altsetting = &dfu_iface,
|
||||
#endif
|
||||
}};
|
||||
|
||||
const struct usb_config_descriptor config = {
|
||||
.bLength = USB_DT_CONFIGURATION_SIZE,
|
||||
.bDescriptorType = USB_DT_CONFIGURATION,
|
||||
.wTotalLength = 0,
|
||||
#ifdef INCLUDE_DFU_INTERFACE
|
||||
.bNumInterfaces = 2,
|
||||
#else
|
||||
.bNumInterfaces = 1,
|
||||
#endif
|
||||
.bConfigurationValue = 1,
|
||||
.iConfiguration = 0,
|
||||
.bmAttributes = 0xC0,
|
||||
.bMaxPower = 0x32,
|
||||
|
||||
.interface = ifaces,
|
||||
};
|
||||
|
||||
static const char *usb_strings[] = {
|
||||
"Black Sphere Technologies",
|
||||
"HID Demo",
|
||||
"DEMO",
|
||||
};
|
||||
|
||||
/* Buffer to be used for control requests. */
|
||||
uint8_t usbd_control_buffer[128];
|
||||
|
||||
static int hid_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len,
|
||||
void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
|
||||
{
|
||||
(void)complete;
|
||||
(void)usbd_dev;
|
||||
|
||||
if ((req->bmRequestType != 0x81) ||
|
||||
(req->bRequest != USB_REQ_GET_DESCRIPTOR) ||
|
||||
(req->wValue != 0x2200))
|
||||
return 0;
|
||||
|
||||
/* Handle the HID report descriptor. */
|
||||
*buf = (uint8_t *)hid_report_descriptor;
|
||||
*len = sizeof(hid_report_descriptor);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_DFU_INTERFACE
|
||||
static void dfu_detach_complete(usbd_device *usbd_dev, struct usb_setup_data *req)
|
||||
{
|
||||
(void)req;
|
||||
(void)usbd_dev;
|
||||
|
||||
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
|
||||
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_2_MHZ,
|
||||
GPIO_CNF_OUTPUT_PUSHPULL, GPIO10);
|
||||
gpio_set(GPIOA, GPIO10);
|
||||
scb_reset_core();
|
||||
}
|
||||
|
||||
static int dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len,
|
||||
void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
|
||||
{
|
||||
(void)buf;
|
||||
(void)len;
|
||||
(void)usbd_dev;
|
||||
|
||||
if ((req->bmRequestType != 0x21) || (req->bRequest != DFU_DETACH))
|
||||
return 0; /* Only accept class request. */
|
||||
|
||||
*complete = dfu_detach_complete;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void hid_set_config(usbd_device *usbd_dev, uint16_t wValue)
|
||||
{
|
||||
(void)wValue;
|
||||
(void)usbd_dev;
|
||||
|
||||
usbd_ep_setup(usbd_dev, 0x81, USB_ENDPOINT_ATTR_INTERRUPT, 4, NULL);
|
||||
|
||||
usbd_register_control_callback(
|
||||
usbd_dev,
|
||||
USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE,
|
||||
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
|
||||
hid_control_request);
|
||||
#ifdef INCLUDE_DFU_INTERFACE
|
||||
usbd_register_control_callback(
|
||||
usbd_dev,
|
||||
USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
|
||||
USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
|
||||
dfu_control_request);
|
||||
#endif
|
||||
|
||||
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB_DIV8);
|
||||
/* SysTick interrupt every N clock pulses: set reload to N-1 */
|
||||
systick_set_reload(99999);
|
||||
systick_interrupt_enable();
|
||||
systick_counter_enable();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
usbd_device *usbd_dev;
|
||||
|
||||
rcc_clock_setup_in_hsi_out_48mhz();
|
||||
|
||||
rcc_periph_clock_enable(RCC_GPIOC);
|
||||
|
||||
gpio_set(GPIOC, GPIO11);
|
||||
gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ,
|
||||
GPIO_CNF_OUTPUT_PUSHPULL, GPIO11);
|
||||
|
||||
usbd_dev = usbd_init(&st_usbfs_v1_usb_driver, &dev, &config, usb_strings, 3, usbd_control_buffer, sizeof(usbd_control_buffer));
|
||||
usbd_register_set_config_callback(usbd_dev, hid_set_config);
|
||||
|
||||
for (i = 0; i < 0x80000; i++)
|
||||
__asm__("nop");
|
||||
|
||||
gpio_clear(GPIOC, GPIO11);
|
||||
|
||||
while (1)
|
||||
usbd_poll(usbd_dev);
|
||||
}
|
||||
|
||||
#if 0 /* is this used? */
|
||||
void sys_tick_handler(void)
|
||||
{
|
||||
static int x = 0;
|
||||
static int dir = 1;
|
||||
uint8_t buf[4] = {0, 0, 0, 0};
|
||||
|
||||
buf[1] = dir;
|
||||
x += dir;
|
||||
if (x > 30)
|
||||
dir = -dir;
|
||||
if (x < -30)
|
||||
dir = -dir;
|
||||
|
||||
usbd_ep_write_packet(usbd_dev, 0x81, buf, 4);
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user