1 /*
2 * avrdude - A Downloader/Uploader for AVR device programmers
3 * Copyright (C) 2011 Brett Hagman
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /* $Id: wiring.c 1321 2014-06-13 20:07:40Z awachtler $ */
20
21 /*
22 * avrdude interface for Wiring bootloaders
23 *
24 * http://wiring.org.co/
25 *
26 * The Wiring bootloader uses a near-complete STK500v2 protocol.
27 * (Only ISP specific programming commands are not implemented
28 * e.g. chip erase).
29 * DTR and RTS signals are diddled to set the board into programming mode.
30 *
31 * Also includes an extended parameter to introduce a delay after opening
32 * to accommodate multi-layered programmers/bootloaders. If the extended
33 * parameter 'snooze' > 0, then no DTR/RTS toggle takes place, and
34 * AVRDUDE will wait that amount of time in milliseconds before syncing.
35 *
36 * Unfortunately, there is no way to easily chain private programmer data
37 * when we "inherit" programmer types as we have (stk500v2). Sooooo, a
38 * *cringe* global variable is used to store the snooze time.
39 */
40
41 #include "ac_cfg.h"
42
43 #include <stdio.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <unistd.h>
47
48 #include "avrdude.h"
49 #include "libavrdude.h"
50
51 #include "stk500v2_private.h"
52 #include "stk500v2.h"
53 #include "wiring.h"
54
55 /*
56 * Private data for this programmer.
57 */
58 struct wiringpdata
59 {
60 /*
61 * We just have the single snooze integer to carry around for now.
62 */
63 int snoozetime;
64 };
65
66
67 /* wiringpdata is our private data */
68 /* pdata is stk500v2's private data (inherited) */
69
70 #define WIRINGPDATA(x) ((struct wiringpdata *)(x))
71
72 #define STK500V2PDATA(pgm) ((struct pdata *)(pgm->cookie))
73
74
wiring_setup(PROGRAMMER * pgm)75 static void wiring_setup(PROGRAMMER * pgm)
76 {
77 void *mycookie;
78
79 /*
80 * First, have STK500v2 backend allocate its own private data.
81 */
82 stk500v2_setup(pgm);
83
84 /*
85 * Now prepare our data
86 */
87 if ((mycookie = malloc(sizeof(struct wiringpdata))) == 0) {
88 avrdude_message(MSG_INFO, "%s: wiring_setup(): Out of memory allocating private data\n",
89 progname);
90 exit(1);
91 }
92 memset(mycookie, 0, sizeof(struct wiringpdata));
93 WIRINGPDATA(mycookie)->snoozetime = 0;
94
95 /*
96 * Store our own cookie in a safe place for the time being.
97 */
98 STK500V2PDATA(pgm)->chained_pdata = mycookie;
99 }
100
wiring_teardown(PROGRAMMER * pgm)101 static void wiring_teardown(PROGRAMMER * pgm)
102 {
103 void *mycookie;
104
105 mycookie = STK500V2PDATA(pgm)->chained_pdata;
106
107 free(mycookie);
108
109 stk500v2_teardown(pgm);
110 }
111
wiring_parseextparms(PROGRAMMER * pgm,LISTID extparms)112 static int wiring_parseextparms(PROGRAMMER * pgm, LISTID extparms)
113 {
114 LNODEID ln;
115 const char *extended_param;
116 int rv = 0;
117 void *mycookie = STK500V2PDATA(pgm)->chained_pdata;
118
119 for (ln = lfirst(extparms); ln; ln = lnext(ln)) {
120 extended_param = ldata(ln);
121
122 if (strncmp(extended_param, "snooze=", strlen("snooze=")) == 0) {
123 int newsnooze;
124 if (sscanf(extended_param, "snooze=%i", &newsnooze) != 1 ||
125 newsnooze < 0) {
126 avrdude_message(MSG_INFO, "%s: wiring_parseextparms(): invalid snooze time '%s'\n",
127 progname, extended_param);
128 rv = -1;
129 continue;
130 }
131 avrdude_message(MSG_NOTICE2, "%s: wiring_parseextparms(): snooze time set to %d ms\n",
132 progname, newsnooze);
133 WIRINGPDATA(mycookie)->snoozetime = newsnooze;
134
135 continue;
136 }
137
138 avrdude_message(MSG_INFO, "%s: wiring_parseextparms(): invalid extended parameter '%s'\n",
139 progname, extended_param);
140 rv = -1;
141 }
142
143 return rv;
144 }
145
wiring_open(PROGRAMMER * pgm,char * port)146 static int wiring_open(PROGRAMMER * pgm, char * port)
147 {
148 int timetosnooze;
149 void *mycookie = STK500V2PDATA(pgm)->chained_pdata;
150 union pinfo pinfo;
151
152 strcpy(pgm->port, port);
153 pinfo.baud = pgm->baudrate ? pgm->baudrate: 115200;
154 serial_open(port, pinfo, &pgm->fd);
155
156 /* If we have a snoozetime, then we wait and do NOT toggle DTR/RTS */
157
158 if (WIRINGPDATA(mycookie)->snoozetime > 0) {
159 timetosnooze = WIRINGPDATA(mycookie)->snoozetime;
160
161 avrdude_message(MSG_NOTICE2, "%s: wiring_open(): snoozing for %d ms\n",
162 progname, timetosnooze);
163 while (timetosnooze--)
164 usleep(1000);
165 avrdude_message(MSG_NOTICE2, "%s: wiring_open(): done snoozing\n",
166 progname);
167 } else {
168 /* Perform Wiring programming mode RESET. */
169 /* This effectively *releases* both DTR and RTS. */
170 /* i.e. both DTR and RTS rise to a HIGH logic level */
171 /* since they are active LOW signals. */
172
173 avrdude_message(MSG_NOTICE2, "%s: wiring_open(): releasing DTR/RTS\n",
174 progname);
175
176 serial_set_dtr_rts(&pgm->fd, 0);
177 usleep(50*1000);
178
179 /* After releasing for 50 milliseconds, DTR and RTS */
180 /* are asserted (i.e. logic LOW) again. */
181
182 avrdude_message(MSG_NOTICE2, "%s: wiring_open(): asserting DTR/RTS\n",
183 progname);
184
185 serial_set_dtr_rts(&pgm->fd, 1);
186 usleep(50*1000);
187 }
188
189 /* drain any extraneous input */
190 stk500v2_drain(pgm, 0);
191
192 if (stk500v2_getsync(pgm) < 0)
193 return -1;
194
195 return 0;
196 }
197
wiring_close(PROGRAMMER * pgm)198 static void wiring_close(PROGRAMMER * pgm)
199 {
200 serial_set_dtr_rts(&pgm->fd, 0);
201 serial_close(&pgm->fd);
202 pgm->fd.ifd = -1;
203 }
204
205 const char wiring_desc[] = "http://wiring.org.co/, Basically STK500v2 protocol, with some glue to trigger the bootloader.";
206
wiring_initpgm(PROGRAMMER * pgm)207 void wiring_initpgm(PROGRAMMER * pgm)
208 {
209 /* The Wiring bootloader uses a near-complete STK500v2 protocol. */
210
211 stk500v2_initpgm(pgm);
212
213 strcpy(pgm->type, "Wiring");
214 pgm->open = wiring_open;
215 pgm->close = wiring_close;
216
217 pgm->setup = wiring_setup;
218 pgm->teardown = wiring_teardown;
219 pgm->parseextparams = wiring_parseextparms;
220 }
221
222