/**
* cpio.c
*
- * Set cp2103 GPIO_0 and GPIO_1 for LED connection to get RX/TX activity.
- * Watch out, the tty is hardcoded.
+ * Configure the and GPIO configuration for a cp2103-equipped device.
*/
#include <netinet/in.h>
#include <sys/stat.h>
#include <fcntl.h>
-#define IOCTL_DEVICERESET 0x8004 /* Get port configuration */
+#define IOCTL_DEVICERESET 0x8004 /* Reset the cp210x */
#define IOCTL_PORTCONFGET 0x8005 /* Get port configuration */
#define IOCTL_PORTCONFSET 0x8006 /* Set port configuration */
+/* Port config definitions */
typedef struct {
- uint16_t mode;
+ uint16_t mode; /* Push-pull = 1, Open-drain = 0 */
uint16_t lowPower;
- uint16_t latch;
-} cp2103_port_state_t;
+ uint16_t latch; /* Logic high = 1, Logic low = 0 */
+} cp2101_port_state_t;
typedef struct {
- cp2103_port_state_t reset;
- cp2103_port_state_t suspend;
+ cp2101_port_state_t reset;
+ cp2101_port_state_t suspend;
uint8_t enhancedFxn;
-} cp2103_port_config_t;
+} cp2101_port_config_t;
+
+void exit(int);
int cpConnect(char* device)
{
int ret, ioval;
int fd = open(device, O_RDWR);
if (fd < 0) {
- fprintf(stderr, "cannot open tty\n");
- return -1;
+ fprintf(stderr, "cannot open %s\n", device);
+ exit(1);
}
- printf("tty opened\n");
+ printf("%s opened\n", device);
return fd;
}
close(fd);
}
-int main(int argc, char* argv[])
+void cpSetPortConf(int fd, int pullups)
{
- int fd;
- cp2103_port_config_t config;
int ret;
-
- if (argc != 2) {
- fprintf(stderr, "usage: %s <tty>\n", argv[0]);
- return 1;
- }
-
- /* open */
- if ((fd = cpConnect(argv[1])) < 0)
- return 1;
+ cp2101_port_config_t config;
/* Read the current port configuration */
if ((ret = ioctl(fd, IOCTL_PORTCONFGET, &config))) {
fprintf(stderr, "portconfget ioctl failed %d\n", ret);
- return 1;
+ exit(1);
}
- /* Set the current port configuration; turn on GPIO_0 and GPIO_1 to get
- * activity LEDs.
+ /* 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. Some boards may
+ * require weak pull-ups, but not 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.reset.mode |= 0x0800; /* GPIO_3 gets push-pull driver */
+ config.enhancedFxn |= (pullups) ? 0x13 : 0x03;
+
if ((ret = ioctl(fd, IOCTL_PORTCONFSET, &config))) {
fprintf(stderr, "portconfset ioctl failed %d\n", ret);
- return 1;
+ exit(1);
}
+}
+
+void cpReset(int fd)
+{
+ int ret;
- /* Reset the part so the changes take effect. */
+ /* Reset the part */
if ((ret = ioctl(fd, IOCTL_DEVICERESET, 0))) {
fprintf(stderr, "device reset ioctl %d\n", ret);
- return 1;
+ exit(1);
+ }
+}
+
+void usage(char* program)
+{
+ fprintf(stderr, "usage: %s [--pullups] <tty> <mfg> <part#> <sn#>\n",
+ program);
+}
+
+int main(int argc, char* argv[])
+{
+ int fd;
+ int pullups = 0;
+
+ if (argc < 2 || argc > 3) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (argc == 3) {
+ if (strncmp(argv[1], "--p", 3) == 0)
+ pullups = 1;
+ else {
+ usage(argv[0]);
+ exit(1);
+ }
}
+ fd = cpConnect(argv[pullups + 1]);
+ cpSetPortConf(fd, pullups);
+ cpReset(fd);
cpDisconnect(fd);
+ printf("done\n");
return 0;
}
}
}
-void cpSetLeds(int fd)
+void cpSetPortConf(int fd, int pullups)
{
int ret;
cp2101_port_config_t config;
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. Some boards may
+ * require weak pull-ups, but not 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 */
- config.enhancedFxn |= 0x10; /* turn on weak pullups */
+ config.reset.mode |= 0x0800; /* GPIO_3 gets push-pull driver */
+ config.enhancedFxn |= (pullups) ? 0x13 : 0x03;
+
if ((ret = ioctl(fd, IOCTL_PORTCONFSET, &config))) {
fprintf(stderr, "portconfset ioctl failed %d\n", ret);
exit(1);
}
}
+void usage(char* program)
+{
+ fprintf(stderr, "usage: %s [--pullups] <tty> <mfg> <part#> <sn#>\n",
+ program);
+}
+
int main(int argc, char* argv[])
{
/* char newmfg[255]; */
char newprod[255];
char newsn[255];
int fd;
+ int pullups = 0;
+
+ if (argc < 5 || argc > 6) {
+ usage(argv[0]);
+ exit(1);
+ }
- if (argc != 5) {
- fprintf(stderr, "usage: %s <tty> <mfg> <part#> <sn#>\n", argv[0]);
- exit(1);
+ if (argc == 6) {
+ if (strncmp(argv[1], "--p", 3) == 0)
+ pullups = 1;
+ else {
+ usage(argv[0]);
+ exit(1);
+ }
}
- /* strcpy(newmfg, argv[2]);
- * strcpy(newprod, argv[3]);
+ /* strcpy(newmfg, argv[pullups + 2]);
+ * strcpy(newprod, argv[pullups + 3]);
*/
- snprintf(newprod, sizeof(newprod), "%s %s", argv[2], argv[3]);
- strcpy(newsn, argv[4]);
- fd = cpConnect(argv[1]);
+ snprintf(newprod, sizeof(newprod), "%s %s", argv[pullups + 2],
+ argv[pullups + 3]);
+ strcpy(newsn, argv[pullups + 4]);
+ fd = cpConnect(argv[pullups + 1]);
/* SiLabs doesn't allow set of mfg string on cp210x.
* cpSetStr(fd, IOCTL_SETMFG, newmfg, strlen(newmfg));
*/
cpSetStr(fd, IOCTL_SETPRODUCT, newprod, strlen(newprod));
cpSetStr(fd, IOCTL_SETSERIAL, newsn, strlen(newsn));
- cpSetLeds(fd);
+ cpSetPortConf(fd, pullups);
cpReset(fd);
cpDisconnect(fd);
printf("done\n");