From e4240bf6962b7482e30976c138abb84f2eab4d85 Mon Sep 17 00:00:00 2001 From: smckown Date: Tue, 31 Mar 2009 17:20:49 +0000 Subject: [PATCH] Add the cpread utility --- src/examples/Makefile | 2 +- src/examples/cpread.c | 139 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 src/examples/cpread.c diff --git a/src/examples/Makefile b/src/examples/Makefile index 85f2190..e42f823 100644 --- a/src/examples/Makefile +++ b/src/examples/Makefile @@ -1,6 +1,6 @@ .PHONY: all -PROGS = cpmfg cpio cptwiddle +PROGS = cpmfg cpread cpio cptwiddle # LDFLAGS += -lusb all: $(PROGS) diff --git a/src/examples/cpread.c b/src/examples/cpread.c new file mode 100644 index 0000000..f5a5d8a --- /dev/null +++ b/src/examples/cpread.c @@ -0,0 +1,139 @@ +/** + * cpcfg.c + * + * Read the configuration of a cp2103-equipped device. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define VID 0x10c4 +#define PID 0xea60 + +/* CP2103 ioctls */ +#define IOCTL_GPIOGET 0x8000 /* Get gpio bits */ +#define IOCTL_GPIOSET 0x8001 /* Set gpio bits */ +#define IOCTL_GPIOBIC 0x8002 /* Clear specific gpio bit(s) */ +#define IOCTL_GPIOBIS 0x8003 /* Set specific gpio bit(s) */ + +/* CP210x ioctls principally used during initial device configuration */ +#define IOCTL_DEVICERESET 0x8004 /* Reset the cp210x */ +#define IOCTL_PORTCONFGET 0x8005 /* Get port configuration */ +#define IOCTL_PORTCONFSET 0x8006 /* Set port configuration */ +#define IOCTL_SETVID 0x8007 /* Set vendor id */ +#define IOCTL_SETPID 0x8008 /* Set product id */ +#define IOCTL_SETMFG 0x8009 /* Set manufacturer string */ +#define IOCTL_SETPRODUCT 0x800a /* Set product string */ +#define IOCTL_SETSERIAL 0x800b /* Set serial number string */ +#define IOCTL_SETDEVVER 0x800c /* set device version id */ +/* FIXME: where is IOCTL_SETMFG? */ + +/* CP2103 GPIO */ +#define GPIO_0 0x01 +#define GPIO_1 0x02 +#define GPIO_2 0x04 +#define GPIO_3 0x08 +#define GPIO_MASK (GPIO_0|GPIO_1|GPIO_2|GPIO_3) + +/* Port config definitions */ +typedef struct { + uint16_t mode; /* Push-pull = 1, Open-drain = 0 */ + uint16_t lowPower; + uint16_t latch; /* Logic high = 1, Logic low = 0 */ +} cp2101_port_state_t; + +typedef struct { + cp2101_port_state_t reset; + cp2101_port_state_t suspend; + uint8_t enhancedFxn; +} cp2101_port_config_t; + +#define PORT_CONFIG_LEN 13 /* Because sizeof() will pad to full words */ + +/* Used to pass variable sized buffers between user and kernel space (ioctls) */ +typedef struct { + char* buf; + size_t len; +} cp210x_buffer_t; + +void exit(int); + +int cpConnect(char* device) +{ + int ret, ioval; + int fd = open(device, O_RDWR); + if (fd < 0) { + fprintf(stderr, "cannot open %s\n", device); + exit(1); + } + printf("%s opened\n", device); + return fd; +} + +void cpDisconnect(int fd) +{ + if (fd >= 0) + close(fd); +} + +void printState(cp2101_port_state_t* state) +{ + printf("m:0x%02x lp:0x%02x l:0x%02x", state->mode, state->lowPower, + state->latch); +} + +void printConfig(cp2101_port_config_t* config) +{ + printf("config: reset: "); printState(&config->reset); + printf("\nconfig: suspend: "); printState(&config->reset); + printf("\nenhancedFxn: 0x%02x\n", config->enhancedFxn); +} + +void cpReset(int fd) +{ + int ret; + + /* Reset the part */ + if ((ret = ioctl(fd, IOCTL_DEVICERESET, 0))) { + fprintf(stderr, "device reset ioctl %d\n", ret); + exit(1); + } +} + +int main(int argc, char* argv[]) +{ + cp2101_port_config_t config; + uint8_t gpio = 0xff; + int ret; + int fd; + + if (argc != 2) { + fprintf(stderr, "usage: %s \n", argv[0]); + exit(1); + } + + fd = cpConnect(argv[1]); + + /* Read the current port configuration */ + if ((ret = ioctl(fd, IOCTL_PORTCONFGET, &config))) { + fprintf(stderr, "portconfget ioctl failed %d\n", ret); + return 1; + } + + /* Read the current gpio latches */ + if ((ret = ioctl(fd, IOCTL_GPIOGET, &gpio))) { + fprintf(stderr, "gpioget ioctl failed %d\n", ret); + return 1; + } + + printConfig(&config); + printf("gpio = 0x%0x\n", gpio); + + cpDisconnect(fd); + return 0; +} -- 2.39.2