* device.
*/
+#include <fcntl.h>
#include <netinet/in.h>
#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
+#include <unistd.h>
+#include "../cp210x.h"
#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);
void cpSetStr(int fd, unsigned int ioctlno, char* string, size_t len)
{
int ret;
- cp210x_buffer_t buf = { buf: string, len: len };
+ struct cp210x_buffer buf = { buf: (unsigned char *)string, len: len };
ret = ioctl(fd, ioctlno, &buf);
if (ret) {
}
}
-void cpSetLeds(int fd)
+void cpSetPortConf(int fd, int nopullups)
{
int ret;
- cp2101_port_config_t config;
+ struct cp210x_port_config config;
/* Read the current port configuration */
- if ((ret = ioctl(fd, IOCTL_PORTCONFGET, &config))) {
+ if ((ret = ioctl(fd, CP210x_IOCTL_PORTCONFGET, &config))) {
fprintf(stderr, "portconfget ioctl failed %d\n", ret);
exit(1);
}
- /* Set the current port configuration; turn on GPIO_0 and GPIO_1 to get
- * activity LEDs. GPIO_2 and GPIO_3 are set for 'regular' gpio.
+ /* This section assumes the device is currently at factory defaults. If
+ * not, first run 'cpfactory'. The only delta from factory defaults is to
+ * activate the activity pin functions for GPIOs 0 and 1. Most boards
+ * require the use of weak pull-ups, including TMI's RWS.
+ *
+ * GPIO mapping:
+ * GPIO_0 -> TX activity, active low
+ * GPIO_1 -> RX activity, active low
+ * GPIO_2 -> MSP430 UC_TCK
+ * GPIO_3 -> MSP430 UC_RST
+ *
*/
- config.reset.mode &= ~0x0300;
- config.suspend.mode &= ~0x0300;
- config.reset.latch |= 0x0300;
- config.enhancedFxn |= 0x03;
- config.enhancedFxn &= ~0x10; /* turn off weak pullups */
- if ((ret = ioctl(fd, IOCTL_PORTCONFSET, &config))) {
+ config.enhancedFxn |= 0x13;
+ if (nopullups)
+ config.enhancedFxn &= ~0x10;
+
+ if ((ret = ioctl(fd, CP210x_IOCTL_PORTCONFSET, &config))) {
fprintf(stderr, "portconfset ioctl failed %d\n", ret);
exit(1);
}
int ret;
/* Reset the part */
- if ((ret = ioctl(fd, IOCTL_DEVICERESET, 0))) {
+ if ((ret = ioctl(fd, CP210x_IOCTL_DEVICERESET, 0))) {
fprintf(stderr, "device reset ioctl %d\n", ret);
exit(1);
}
}
+void usage(char* program)
+{
+ fprintf(stderr, "usage: %s [--nopullups] <tty> <mfg> <part#> <sn#>\n",
+ program);
+}
+
int main(int argc, char* argv[])
{
- /* char newmfg[255] = "Company Name"; */
- char newprod[255] = "CompanyName ";
+ /* char newmfg[255]; */
+ char newprod[255];
char newsn[255];
int fd;
+ int nopullups = 0;
- if (argc != 4) {
- fprintf(stderr, "usage: %s <tty> <part#> <sn#>\n", argv[0]);
- exit(1);
+ if (argc < 5 || argc > 6) {
+ usage(argv[0]);
+ exit(1);
}
- strcat(newprod, argv[2]);
- strcpy(newsn, argv[3]);
- fd = cpConnect(argv[1]);
+ if (argc == 6) {
+ if (strncmp(argv[1], "--n", 3) == 0)
+ nopullups = 1;
+ else {
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ /* strcpy(newmfg, argv[nopullups + 2]);
+ * strcpy(newprod, argv[nopullups + 3]);
+ */
+ snprintf(newprod, sizeof(newprod), "%s %s", argv[nopullups + 2],
+ argv[nopullups + 3]);
+ strcpy(newsn, argv[nopullups + 4]);
+ fd = cpConnect(argv[nopullups + 1]);
/* SiLabs doesn't allow set of mfg string on cp210x.
- * cpSetStr(fd, IOCTL_SETMFG, newmfg, strlen(newmfg));
+ * cpSetStr(fd, CP210x_IOCTL_SETMFG, newmfg, strlen(newmfg));
*/
- cpSetStr(fd, IOCTL_SETPRODUCT, newprod, strlen(newprod));
- cpSetStr(fd, IOCTL_SETSERIAL, newsn, strlen(newsn));
- cpSetLeds(fd);
+ cpSetStr(fd, CP210x_IOCTL_SETPRODUCT, newprod, strlen(newprod));
+ cpSetStr(fd, CP210x_IOCTL_SETSERIAL, newsn, strlen(newsn));
+ cpSetPortConf(fd, nopullups);
cpReset(fd);
cpDisconnect(fd);
printf("done\n");