gateware

A collection of little open source FPGA hobby projects
git clone http://frotz.net/git/gateware.git
Log | Files | Refs | README

udebug.c (4610B)


      1 // Copyright 2018, Brian Swetland <swetland@frotz.net>
      2 // Licensed under the Apache License, Version 2.0.
      3 
      4 #include <ctype.h>
      5 #include <errno.h>
      6 #include <stdint.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <string.h>
     10 #include <termios.h>
     11 #include <unistd.h>
     12 
     13 #include <sys/fcntl.h>
     14 
     15 #include "crc8.h"
     16 
     17 int openserial(const char *device, unsigned speed) {
     18 	struct termios tio;
     19 	int fd;
     20 
     21 	/* open the serial port non-blocking to avoid waiting for cd */
     22 	if ((fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) {
     23 		return -1;
     24 	}
     25 
     26         memset(&tio, 0, sizeof(tio));
     27         tio.c_iflag |= IGNBRK | IGNPAR; // ignore break, ignore parity/frame err
     28         tio.c_cflag |= CS8 | CREAD | CLOCAL; // 8bit, enable rx, no modem lines
     29         tio.c_cc[VMIN] = 1; // min chars to read
     30         tio.c_cc[VTIME] = 0; // blocking read
     31         cfmakeraw(&tio);
     32         cfsetispeed(&tio, speed);
     33         cfsetospeed(&tio, speed);
     34 
     35 	if (tcsetattr(fd, TCSAFLUSH, &tio)) {
     36 		fprintf(stderr, "error: cannot set serial port attributes: %d %s\n", errno, strerror(errno));
     37 		close(fd);
     38 		return -1;
     39 	}
     40 
     41 	return fd;
     42 }
     43 
     44 void cmd(int fd, unsigned cmd, unsigned data) {
     45 	uint8_t msg[7];
     46 	msg[0] = 0xCD;
     47 	msg[1] = cmd;
     48 	msg[2] = data;
     49 	msg[3] = data >> 8;
     50 	msg[4] = data >> 16;
     51 	msg[5] = data >> 24;
     52 	msg[6] = crc8(0xFF, msg, 6);
     53 	write(fd, msg, 7);
     54 }
     55 
     56 void cmd_wr_u8(int fd, uint32_t addr, uint8_t* p, size_t len) {
     57 	if (len > 4096) {
     58 		return;
     59 	}
     60 	uint8_t data[4097*7];
     61 	uint8_t* msg = data;
     62 
     63 	msg[0] = 0xCD;
     64 	msg[1] = 0x01;
     65 	msg[2] = addr;
     66 	msg[3] = addr >> 8;
     67 	msg[4] = addr >> 16;
     68 	msg[5] = addr >> 24;
     69 	msg[6] = crc8(0xFF, msg, 6);
     70 	msg += 7;
     71 
     72 	while (len-- > 0) {
     73 		msg[0] = 0xCD;
     74 		msg[1] = 0x00;
     75 		msg[2] = *p++;
     76 		msg[3] = 0x00;
     77 		msg[4] = 0x00;
     78 		msg[5] = 0x00;
     79 		msg[6] = crc8(0xFF, msg, 6);
     80 		msg += 7;
     81 	}
     82 	write(fd, data, msg - data);
     83 }
     84 
     85 void cmd_wr_u16(int fd, uint32_t addr, uint16_t* p, size_t len) {
     86 	if (len > 4096) {
     87 		return;
     88 	}
     89 	uint8_t data[4097*7];
     90 	uint8_t* msg = data;
     91 
     92 	msg[0] = 0xCD;
     93 	msg[1] = 0x01;
     94 	msg[2] = addr;
     95 	msg[3] = addr >> 8;
     96 	msg[4] = addr >> 16;
     97 	msg[5] = addr >> 24;
     98 	msg[6] = crc8(0xFF, msg, 6);
     99 	msg += 7;
    100 
    101 	while (len-- > 0) {
    102 		msg[0] = 0xCD;
    103 		msg[1] = 0x00;
    104 		msg[2] = *p;
    105 		msg[3] = *p >> 8;
    106 		msg[4] = 0x00;
    107 		msg[5] = 0x00;
    108 		msg[6] = crc8(0xFF, msg, 6);
    109 		msg += 7;
    110 		p++;
    111 	}
    112 	write(fd, data, msg - data);
    113 }
    114 
    115 int usage(void) {
    116 	fprintf(stderr,
    117 		"usage:   udebug <port> <command>*\n"
    118 		"\n"
    119 		"command: -load <addr> <hexfile>     - write hex file\n"
    120 		"         -write <addr> <value>...   - write wolds\n"
    121 		"         -reset                     - processor RST=1\n"
    122 		"         -run                       - processor RST=0\n"
    123 		"         -error                     - cause link error\n"
    124 		"         -clear                     - clear link error\n"
    125 	       );
    126 	return -1;
    127 }
    128 
    129 int main(int argc, char **argv) {
    130 	uint16_t addr;
    131 	uint16_t data[4096];
    132 	size_t n;
    133 
    134 	if (argc < 2) {
    135 		return usage();
    136 	}
    137 
    138 	int sfd = openserial(argv[1], B1000000);
    139 	if (sfd < 0) {
    140 		fprintf(stderr, "error: cannot open serial port '%s'\n", argv[1]);
    141 		return -1;
    142 	}
    143 
    144 	argc -= 2;
    145 	argv += 2;
    146 	while (argc > 0) {
    147 		if (!strcmp(argv[0], "-load")) {
    148 			if (argc < 3) {
    149 				return usage();
    150 			}
    151 			char buf[1024];
    152 			addr = strtoul(argv[1], 0, 16);
    153 			FILE *fp = fopen(argv[2], "r");
    154 			if (fp == NULL) {
    155 				fprintf(stderr, "error: cannot open '%s'\n", argv[3]);
    156 				return -1;
    157 			}
    158 			n = 0;
    159 			while (fgets(buf, 1024, fp)) {
    160 				if (!isalnum(buf[0])) continue;
    161 				if (n == 4096) return -1;
    162 				data[n++] = strtoul(buf, 0, 16);
    163 			}
    164 			fclose(fp);
    165 			cmd_wr_u16(sfd, addr, data, n);
    166 			argc -= 3;
    167 			argv += 3;
    168 		} else if (!strcmp(argv[0], "-write")) {
    169 			if (argc < 3) {
    170 				return usage();
    171 			}
    172 			addr = strtoul(argv[1], 0, 16);
    173 			argc -= 2;
    174 			argv += 2;
    175 			n = 0;
    176 			while (argc > 0) {
    177 				if (argv[0][0] == '-') {
    178 					break;
    179 				}
    180 				if (argv[0][0] == '/') {
    181 					char *s = argv[0] + 1;
    182 					while (*s != 0) {
    183 						if (n == 4096) return -1;
    184 						data[n++] = *s++;
    185 					}
    186 				} else {
    187 					if (n == 4096) return -1;
    188 					data[n++] = strtoul(argv[0], 0, 16);
    189 				}
    190 				argc--;
    191 				argv++;
    192 			}
    193 			cmd_wr_u16(sfd, addr, data, n);
    194 		} else if (!strcmp(argv[0], "-reset")) {
    195 			data[0] = 1;
    196 			cmd_wr_u16(sfd, 0xF000, data, 1);
    197 			argc--;
    198 			argv++;
    199 		} else if (!strcmp(argv[0], "-run")) {
    200 			data[0] = 0;
    201 			cmd_wr_u16(sfd, 0xF000, data, 1);
    202 			argc--;
    203 			argv++;
    204 		} else if (!strcmp(argv[0], "-error")) {
    205 			cmd(sfd, 0xFF, 0);
    206 			argc--;
    207 			argv++;
    208 		} else if (!strcmp(argv[0], "-clear")) {
    209 			cmd(sfd, 0x02, 0);
    210 			argc--;
    211 			argv++;
    212 		} else {
    213 			usage();
    214 		}
    215 	}
    216 
    217 	close(sfd);
    218 	return 0;
    219 }