12 #define VERSION "0.5.1"
16 void usage(poptContext pc)
18 poptPrintHelp(pc, stderr, 0);
19 fprintf(stderr, "\nAvailable commands: \n"
23 "\twritefile [file] ...\n"
24 "\treadfile <len> [file] ...\n"
25 "\twritebyte <address> <byte>\n"
26 "\treadbyte <address>\n"
33 fprintf(stderr, "Received signal, exiting...\n");
37 void writechar(char datamem, char do_verify, int address, int byte)
40 if(datamem)writedata(address, byte);
41 else writecode(address, byte);
44 if(datamem)d = readdata(address);
45 else d = readcode(address);
48 fprintf(stderr, "Error verifying byte at offset 0x%x\n", address);
55 int writebin(FILE *fd, char do_verify, char datamem)
60 writechar(datamem, do_verify, i, fgetc(fd));
62 if(progress)fputc('.', stderr);
64 if(progress)fputc('\n', stderr);
68 int writehex(FILE *fd, char do_verify, char datamem)
70 int length; int addr1, addr2; int type;
73 int checksum1, checksum2;
80 if(fscanf(fd, ":%2x%2x%2x%2x", &length, &addr1, &addr2, &type) < 3) {
81 fprintf(stderr, "Error reading intel hex file, line %d\n", i);
91 address = addr1 * 0x100 + addr2;
95 if(type == 2) continue;
97 for(j = 0; j < length; j++) {
98 if(fscanf(fd, "%2x", &byte) < 1) {
99 fprintf(stderr, "Error reading byte %d in intel hex file, line %d\n", j, i);
105 writechar(datamem,do_verify,address+j,byte);
108 if(fscanf(fd, "%2x", &checksum2) < 1) {
109 fprintf(stderr, "Error reading checksum in intel hex file, line %d\n", i);
114 if((0x100 - (checksum1 & 0xFF)) != checksum2) {
115 fprintf(stderr, "Warning: checksums do NOT match in intel hex file, line %d\n"
117 "File may be corrupt\n", i, 0x100 - (checksum1 & 0xFF), checksum2);
123 if(byte != '\n' && byte != '\r') {
129 if(progress)fputc('.', stderr);
131 if(progress)fputc('\n', stderr);
136 int main(int argc, const char **argv)
138 int datamem = 0, codemem = 0, verbose = 0, do_verify = 0, ignore_chk = 0;
141 char *format = "auto";
143 char c, print_usage = 1;
144 struct poptOption long_options[] = {
146 { "data-memory", 'd', POPT_ARG_NONE, &datamem, 0, "Write specified file to data memory" },
147 { "code-memory", 'c', POPT_ARG_NONE, &codemem, 0, "Write specified file to code memory (default)" },
148 { "format", 'f', POPT_ARG_STRING, &format, 0, "File format (auto,hex,bin)" },
149 { "ignore-chk", 'i', POPT_ARG_NONE, &ignore_chk, 0, "Don't wait for CHK to confirm RST" },
150 { "progress", 'P', POPT_ARG_NONE, &progress, 0, "Print progress dots" },
151 { "verify", 'V', POPT_ARG_NONE, &do_verify, 0, "Verify written bytes" },
152 { "port", 'p', POPT_ARG_STRING, NULL, 'p', "Address of serial port to use [3f8]" },
153 { "rcfile", 'r', POPT_ARG_STRING, &rcfile, 0, "Use rc file from specified location" },
154 { "verbose", 'v', POPT_ARG_NONE, &verbose, 0, "Be verbose" },
160 pc = poptGetContext(NULL, argc, argv, long_options, POPT_CONTEXT_KEEP_FIRST);
161 poptSetOtherOptionHelp(pc, "command [file-to-write]");
163 while ((c = poptGetNextOpt(pc)) != -1) {
165 case 'p': newserport = strtol(poptGetOptArg(pc), NULL, 16); break;
170 rcfile = malloc(strlen(getenv("HOME")) + 20);
171 snprintf(rcfile, strlen(getenv("HOME")) + 20, "%s/.at89progrc", getenv("HOME"));
175 if(readrcfile(rcfile) != 0) return 1;
178 if(newserport != -1)serport = newserport;
180 if(ioperm(serport, 7, 1) == -1)
183 fprintf(stderr, "Run at89prog with IO port access\n");
187 if(ioperm(0x80, 1, 1) == -1)
193 signal(SIGINT, quit);
194 signal(SIGSEGV, quit);
196 poptGetArg(pc); /* drop argv[0] */
204 if(!activate() && !ignore_chk)
206 fprintf(stderr, "RST set, but CHK is low\n");
210 if(!strcmp(poptPeekArg(pc), "reset"))
214 if(verbose) fprintf(stderr, "Microcontroller has been reset.\n");
215 } else if(!strcmp(poptPeekArg(pc), "erase"))
220 if(verbose) fprintf(stderr, "Microcontroller memory has been erased.\n");
221 } else if(!strcmp(poptPeekArg(pc), "lock"))
225 lock_level = atoi(poptGetArg(pc));
230 if(verbose) fprintf(stderr, "Locked at level %d\n", lock_level);
231 } else if(!strcmp(poptPeekArg(pc), "writefile"))
236 while(poptPeekArg(pc)) {
238 const char *filename = poptGetArg(pc);
240 if(!strcmp(filename, "-")) fd = stdin;
242 fd = fopen(filename, "r");
244 fprintf(stderr, "Unable to open file %s, ignoring.\n", filename);
249 firstchar = getc(fd);
250 ungetc(firstchar, fd);
252 if(!strcmp(format, "hex") || (!strcmp(format, "auto") && firstchar == ':'))errors = writehex(fd, do_verify, datamem);
253 else if(!strcmp(format, "auto") || !strcmp(format, "bin"))errors = writebin(fd, do_verify, datamem);
255 fprintf(stderr, "Unknown format %s, ignoring file\n", format);
260 if(!errors && verbose)fprintf(stderr, "File %s programmed correctly\n", filename);
261 else if(verbose)fprintf(stderr, "File %s programmed with %d errors\n", filename, errors);
264 } else if(!strcmp(poptPeekArg(pc), "readfile")) {
269 if(!poptPeekArg(pc)) {
270 fprintf(stderr, "readfile needs at least one argument (number of bytes to read\n");
275 len = atol(poptGetArg(pc));
277 if(!poptPeekArg(pc)) fd = stdout;
279 fd = fopen(poptGetArg(pc), "w+");
287 if(!strcmp(format, "bin"))fprintf(stderr, "Warning: writing in binary mode\n");
289 for(i = 0; i < len; i++) {
290 if(datamem)fputc(readdata(i), fd);
291 else fputc(readcode(i), fd);
292 if(progress)fputc('.', stderr);
295 if(progress)fputc('\n', stderr);
297 if(verbose)fprintf(stderr, "%d bytes read\n", len);
299 } else if(!strcmp(poptPeekArg(pc), "writebyte")) {
303 if(!poptPeekArg(pc)) {
304 fprintf(stderr, "writebyte requires 2 arguments\n");
308 address = strtol(poptGetArg(pc), NULL, 16);
310 if(!poptPeekArg(pc)) {
311 fprintf(stderr, "writebyte requires 2 arguments\n");
315 byte = strtol(poptGetArg(pc), NULL, 16);
317 writechar(datamem, do_verify, address, byte);
318 if(verbose)fprintf(stderr, "%x written to %x\n", byte, address);
319 } else if(!strcmp(poptPeekArg(pc), "readbyte")) {
323 if(!poptPeekArg(pc)) {
324 fprintf(stderr, "writebyte requires 2 arguments\n");
328 address = strtol(poptGetArg(pc), NULL, 16);
330 if(datamem) printf("%x\n", readdata(address));
331 else printf("%x\n", readcode(address));
332 } else if(!strcmp(poptPeekArg(pc), "version")) {
333 fprintf(stderr, "at89prog - a AT89S8252 programmer over the serial port\n");
334 fprintf(stderr, " Version "VERSION"\n");
335 fprintf(stderr, " (C) 2003 Jelmer Vernooij <jelmer@samba.org>\n");
336 fprintf(stderr, " Published under the GNU GPL\n");
339 fprintf(stderr, "Unknown command %s\n", poptGetArg(pc));