mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
discovery-stm32f072: discovery USB GPIO test
Wire up the discovery's four LEDs and one user button as GPIOs that can be written and read using the new USB GPIO driver. This also adds an extra tool called usb_gpio that provides control of GPIOs from the linux command line. Signed-off-by: Anton Staaf <robotboy@chromium.org> BRANCH=None BUG=None TEST=cd board/discovery-stm32f072 ; make flash cd extra/usb_gpio ; make usb_gpio write 0x1e 0x00 Change-Id: I15115f82b15b6c35d1a34b83b7114a6bfa6a3d67 Reviewed-on: https://chromium-review.googlesource.com/218270 Reviewed-by: Anton Staaf <robotboy@chromium.org> Commit-Queue: Anton Staaf <robotboy@chromium.org> Tested-by: Anton Staaf <robotboy@chromium.org>
This commit is contained in:
committed by
chrome-internal-fetch
parent
46102d3b4e
commit
c9e71277b4
@@ -9,6 +9,7 @@
|
||||
#include "hooks.h"
|
||||
#include "registers.h"
|
||||
#include "task.h"
|
||||
#include "usb_gpio.h"
|
||||
#include "util.h"
|
||||
|
||||
void button_event(enum gpio_signal signal);
|
||||
@@ -27,6 +28,28 @@ void button_event(enum gpio_signal signal)
|
||||
count++;
|
||||
}
|
||||
|
||||
static enum gpio_signal const usb_gpio_list[] = {
|
||||
GPIO_USER_BUTTON,
|
||||
GPIO_LED_U,
|
||||
GPIO_LED_D,
|
||||
GPIO_LED_L,
|
||||
GPIO_LED_R,
|
||||
};
|
||||
|
||||
USB_GPIO_CONFIG(usb_gpio,
|
||||
usb_gpio_list,
|
||||
USB_IFACE_GPIO,
|
||||
USB_EP_GPIO)
|
||||
|
||||
const void *const usb_strings[] = {
|
||||
[USB_STR_DESC] = usb_string_desc,
|
||||
[USB_STR_VENDOR] = USB_STRING_DESC("Google Inc."),
|
||||
[USB_STR_PRODUCT] = USB_STRING_DESC("discovery-stm32f072"),
|
||||
[USB_STR_VERSION] = USB_STRING_DESC("v1.0"),
|
||||
};
|
||||
|
||||
BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT);
|
||||
|
||||
/* Initialize board. */
|
||||
static void board_init(void)
|
||||
{
|
||||
|
||||
@@ -27,12 +27,13 @@
|
||||
#define CONFIG_STM_HWTIMER32
|
||||
#define CONFIG_HW_CRC
|
||||
#define CONFIG_USB
|
||||
#define CONFIG_USB_GPIO
|
||||
|
||||
#undef CONFIG_WATCHDOG_HELP
|
||||
#undef CONFIG_LID_SWITCH
|
||||
|
||||
/* USB configuration */
|
||||
#define CONFIG_USB_PID 0x5009
|
||||
#define CONFIG_USB_PID 0x500f
|
||||
|
||||
/*
|
||||
* Allow dangerous commands all the time, since we don't have a write protect
|
||||
@@ -61,11 +62,13 @@ enum usb_strings {
|
||||
|
||||
/* USB interface indexes (use define rather than enum to expand them) */
|
||||
#define USB_IFACE_STREAM 0
|
||||
#define USB_IFACE_COUNT 1
|
||||
#define USB_IFACE_GPIO 1
|
||||
#define USB_IFACE_COUNT 2
|
||||
|
||||
/* USB endpoint indexes (use define rather than enum to expand them) */
|
||||
#define USB_EP_CONTROL 0
|
||||
#define USB_EP_STREAM 1
|
||||
#define USB_EP_COUNT 2
|
||||
#define USB_EP_GPIO 2
|
||||
#define USB_EP_COUNT 3
|
||||
|
||||
#endif /* __BOARD_H */
|
||||
|
||||
@@ -39,15 +39,6 @@ USB_STREAM_CONFIG(usb_stream1,
|
||||
in_ready,
|
||||
out_ready)
|
||||
|
||||
const void *const usb_strings[] = {
|
||||
[USB_STR_DESC] = usb_string_desc,
|
||||
[USB_STR_VENDOR] = USB_STRING_DESC("Google Inc."),
|
||||
[USB_STR_PRODUCT] = USB_STRING_DESC("discovery-stm32f072"),
|
||||
[USB_STR_VERSION] = NULL /* filled at runtime */,
|
||||
};
|
||||
|
||||
BUILD_ASSERT(ARRAY_SIZE(usb_strings) == USB_STR_COUNT);
|
||||
|
||||
struct stream_console_state {
|
||||
size_t wrote;
|
||||
};
|
||||
|
||||
1
extra/usb_gpio/.gitignore
vendored
Normal file
1
extra/usb_gpio/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
usb_gpio
|
||||
34
extra/usb_gpio/Makefile
Normal file
34
extra/usb_gpio/Makefile
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
PROGRAM := usb_gpio
|
||||
SOURCE := $(PROGRAM).c
|
||||
LIBS :=
|
||||
LFLAGS :=
|
||||
CFLAGS := -std=gnu99 \
|
||||
-g3 \
|
||||
-O3 \
|
||||
-Wall \
|
||||
-Werror \
|
||||
-Wpointer-arith \
|
||||
-Wcast-align \
|
||||
-Wcast-qual \
|
||||
-Wundef \
|
||||
-Wsign-compare \
|
||||
-Wredundant-decls \
|
||||
-Wmissing-declarations
|
||||
|
||||
#
|
||||
# Add libusb-1.0 required flags
|
||||
#
|
||||
LIBS += $(shell pkg-config --libs libusb-1.0)
|
||||
CFLAGS += $(shell pkg-config --cflags libusb-1.0)
|
||||
|
||||
$(PROGRAM): $(SOURCE) Makefile
|
||||
gcc $(CFLAGS) $(SOURCE) $(LFLAGS) $(LIBS) -o $@
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -rf $(PROGRAM) *~
|
||||
158
extra/usb_gpio/usb_gpio.c
Normal file
158
extra/usb_gpio/usb_gpio.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include <libusb.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define CHECK(expression) \
|
||||
({ \
|
||||
int error__ = (expression); \
|
||||
\
|
||||
if (error__ != 0) { \
|
||||
fprintf(stderr, \
|
||||
"libusb error: %s:%d %s\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
libusb_error_name(error__)); \
|
||||
return error__; \
|
||||
} \
|
||||
\
|
||||
error__; \
|
||||
})
|
||||
|
||||
#define TRANSFER_TIMEOUT_MS 100
|
||||
|
||||
static int gpio_write(libusb_device_handle *device,
|
||||
uint32_t set_mask,
|
||||
uint32_t clear_mask)
|
||||
{
|
||||
uint8_t command[8];
|
||||
int transfered;
|
||||
|
||||
command[0] = (set_mask >> 0) & 0xff;
|
||||
command[1] = (set_mask >> 8) & 0xff;
|
||||
command[2] = (set_mask >> 16) & 0xff;
|
||||
command[3] = (set_mask >> 24) & 0xff;
|
||||
|
||||
command[4] = (clear_mask >> 0) & 0xff;
|
||||
command[5] = (clear_mask >> 8) & 0xff;
|
||||
command[6] = (clear_mask >> 16) & 0xff;
|
||||
command[7] = (clear_mask >> 24) & 0xff;
|
||||
|
||||
CHECK(libusb_bulk_transfer(device,
|
||||
LIBUSB_ENDPOINT_OUT | 2,
|
||||
command,
|
||||
sizeof(command),
|
||||
&transfered,
|
||||
TRANSFER_TIMEOUT_MS));
|
||||
|
||||
if (transfered != sizeof(command)) {
|
||||
fprintf(stderr,
|
||||
"Failed to transfer full command "
|
||||
"(sent %d of %d bytes)\n",
|
||||
transfered,
|
||||
(int)sizeof(command));
|
||||
return LIBUSB_ERROR_OTHER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gpio_read(libusb_device_handle *device, uint32_t *mask)
|
||||
{
|
||||
uint8_t response[4];
|
||||
int transfered;
|
||||
|
||||
/*
|
||||
* The first query does triggers the sampling of the GPIO values, the
|
||||
* second query reads them back.
|
||||
*/
|
||||
CHECK(libusb_bulk_transfer(device,
|
||||
LIBUSB_ENDPOINT_IN | 2,
|
||||
response,
|
||||
sizeof(response),
|
||||
&transfered,
|
||||
TRANSFER_TIMEOUT_MS));
|
||||
|
||||
CHECK(libusb_bulk_transfer(device,
|
||||
LIBUSB_ENDPOINT_IN | 2,
|
||||
response,
|
||||
sizeof(response),
|
||||
&transfered,
|
||||
TRANSFER_TIMEOUT_MS));
|
||||
|
||||
if (transfered != sizeof(response)) {
|
||||
fprintf(stderr,
|
||||
"Failed to transfer full response "
|
||||
"(read %d of %d bytes)\n",
|
||||
transfered,
|
||||
(int)sizeof(response));
|
||||
return LIBUSB_ERROR_OTHER;
|
||||
}
|
||||
|
||||
*mask = (response[0] << 0 |
|
||||
response[1] << 8 |
|
||||
response[2] << 16 |
|
||||
response[3] << 24);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
libusb_context *context;
|
||||
libusb_device_handle *device;
|
||||
uint16_t vendor_id = 0x18d1;
|
||||
uint16_t product_id = 0x500f;
|
||||
|
||||
if (!(argc == 2 && strcmp(argv[1], "read") == 0) &&
|
||||
!(argc == 4 && strcmp(argv[1], "write") == 0)) {
|
||||
puts("Usage: usb_gpio read\n"
|
||||
" usb_gpio write <set_mask> <clear_mask>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
CHECK(libusb_init(&context));
|
||||
|
||||
device = libusb_open_device_with_vid_pid(context,
|
||||
vendor_id,
|
||||
product_id);
|
||||
|
||||
if (device == NULL) {
|
||||
fprintf(stderr,
|
||||
"Unable to find device 0x%04x:0x%04x\n",
|
||||
vendor_id,
|
||||
product_id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
CHECK(libusb_set_auto_detach_kernel_driver(device, 1));
|
||||
CHECK(libusb_claim_interface(device, 0));
|
||||
|
||||
if (argc == 2 && strcmp(argv[1], "read") == 0) {
|
||||
uint32_t mask;
|
||||
|
||||
CHECK(gpio_read(device, &mask));
|
||||
|
||||
printf("GPIO mask: 0x%08x\n", mask);
|
||||
}
|
||||
|
||||
if (argc == 4 && strcmp(argv[1], "write") == 0) {
|
||||
uint32_t set_mask = strtol(argv[2], NULL, 0);
|
||||
uint32_t clear_mask = strtol(argv[3], NULL, 0);
|
||||
|
||||
CHECK(gpio_write(device, set_mask, clear_mask));
|
||||
}
|
||||
|
||||
libusb_close(device);
|
||||
libusb_exit(context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user