@@ -51,6 +51,10 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
5151 return nil , fmt .Errorf ("opening sketch: %s" , err )
5252 }
5353
54+ if req .GetBurnBootloader () && req .GetProgrammer () == "" {
55+ return nil , fmt .Errorf ("no programmer specified for burning bootloader" )
56+ }
57+
5458 // FIXME: make a specification on how a port is specified via command line
5559 port := req .GetPort ()
5660 if port == "" && sketch != nil && sketch .Metadata != nil {
@@ -90,6 +94,16 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
9094 var uploadToolName string
9195 var uploadToolPlatform * cores.PlatformRelease
9296 var programmer * cores.Programmer
97+
98+ burnBootloader := req .GetBurnBootloader ()
99+ if burnBootloader {
100+ uploadToolName = boardProperties .Get ("bootloader.tool" )
101+ uploadToolPlatform = boardPlatform
102+ if uploadToolName == "" {
103+ return nil , fmt .Errorf ("cannot get programmer tool: undefined 'bootloader.tool' in boards.txt" )
104+ }
105+ }
106+
93107 if programmerID := req .GetProgrammer (); programmerID != "" {
94108 programmer = boardPlatform .Programmers [programmerID ]
95109 if programmer == nil {
@@ -153,13 +167,25 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
153167 if v , ok := uploadProperties .GetOk ("program.params.verbose" ); ok {
154168 uploadProperties .Set ("program.verbose" , v )
155169 }
170+ if v , ok := uploadProperties .GetOk ("erase.params.verbose" ); ok {
171+ uploadProperties .Set ("erase.verbose" , v )
172+ }
173+ if v , ok := uploadProperties .GetOk ("bootloader.params.verbose" ); ok {
174+ uploadProperties .Set ("bootloader.verbose" , v )
175+ }
156176 } else {
157177 if v , ok := uploadProperties .GetOk ("upload.params.quiet" ); ok {
158178 uploadProperties .Set ("upload.verbose" , v )
159179 }
160180 if v , ok := uploadProperties .GetOk ("program.params.quiet" ); ok {
161181 uploadProperties .Set ("program.verbose" , v )
162182 }
183+ if v , ok := uploadProperties .GetOk ("erase.params.quiet" ); ok {
184+ uploadProperties .Set ("erase.verbose" , v )
185+ }
186+ if v , ok := uploadProperties .GetOk ("bootloader.params.quiet" ); ok {
187+ uploadProperties .Set ("bootloader.verbose" , v )
188+ }
163189 }
164190
165191 // Set properties for verify
@@ -172,29 +198,31 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
172198 }
173199
174200 var importPath * paths.Path
175- if importDir := req .GetImportDir (); importDir != "" {
176- importPath = paths .New (importDir )
177- } else {
178- // TODO: Create a function to obtain importPath from sketch
179- importPath = sketch .FullPath
180- // Add FQBN (without configs part) to export path
181- fqbnSuffix := strings .Replace (fqbn .StringWithoutConfig (), ":" , "." , - 1 )
182- importPath = importPath .Join ("build" ).Join (fqbnSuffix )
183- }
201+ if ! burnBootloader {
202+ if importDir := req .GetImportDir (); importDir != "" {
203+ importPath = paths .New (importDir )
204+ } else {
205+ // TODO: Create a function to obtain importPath from sketch
206+ importPath = sketch .FullPath
207+ // Add FQBN (without configs part) to export path
208+ fqbnSuffix := strings .Replace (fqbn .StringWithoutConfig (), ":" , "." , - 1 )
209+ importPath = importPath .Join ("build" ).Join (fqbnSuffix )
210+ }
184211
185- if ! importPath .Exist () {
186- return nil , fmt .Errorf ("compiled sketch not found in %s" , importPath )
187- }
188- if ! importPath .IsDir () {
189- return nil , fmt .Errorf ("expected compiled sketch in directory %s, but is a file instead" , importPath )
212+ if ! importPath .Exist () {
213+ return nil , fmt .Errorf ("compiled sketch not found in %s" , importPath )
214+ }
215+ if ! importPath .IsDir () {
216+ return nil , fmt .Errorf ("expected compiled sketch in directory %s, but is a file instead" , importPath )
217+ }
218+ uploadProperties .SetPath ("build.path" , importPath )
219+ uploadProperties .Set ("build.project_name" , sketch .Name + ".ino" )
190220 }
191- uploadProperties .SetPath ("build.path" , importPath )
192- uploadProperties .Set ("build.project_name" , sketch .Name + ".ino" )
193221
194222 // If not using programmer perform some action required
195223 // to set the board in bootloader mode
196224 actualPort := port
197- if programmer == nil {
225+ if programmer == nil && ! burnBootloader {
198226 // Perform reset via 1200bps touch if requested
199227 if uploadProperties .GetBoolean ("upload.use_1200bps_touch" ) {
200228 ports , err := serial .GetPortsList ()
@@ -250,8 +278,14 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
250278 }
251279
252280 // Build recipe for upload
253- var recipe string
254- if programmer != nil {
281+ if burnBootloader {
282+ if err := runTool ("erase.pattern" , uploadProperties , outStream , errStream , req .GetVerbose ()); err != nil {
283+ return nil , fmt .Errorf ("chip erase error: %s" , err )
284+ }
285+ if err := runTool ("bootloader.pattern" , uploadProperties , outStream , errStream , req .GetVerbose ()); err != nil {
286+ return nil , fmt .Errorf ("burn bootloader error: %s" , err )
287+ }
288+ } else if programmer != nil {
255289 if err := runTool ("program.pattern" , uploadProperties , outStream , errStream , req .GetVerbose ()); err != nil {
256290 return nil , fmt .Errorf ("programming error: %s" , err )
257291 }
0 commit comments