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