@@ -51,6 +51,10 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
51
51
return nil , fmt .Errorf ("opening sketch: %s" , err )
52
52
}
53
53
54
+ if req .GetBurnBootloader () && req .GetProgrammer () == "" {
55
+ return nil , fmt .Errorf ("no programmer specified for burning bootloader" )
56
+ }
57
+
54
58
// FIXME: make a specification on how a port is specified via command line
55
59
port := req .GetPort ()
56
60
if port == "" && sketch != nil && sketch .Metadata != nil {
@@ -90,6 +94,16 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
90
94
var uploadToolName string
91
95
var uploadToolPlatform * cores.PlatformRelease
92
96
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
+
93
107
if programmerID := req .GetProgrammer (); programmerID != "" {
94
108
programmer = boardPlatform .Programmers [programmerID ]
95
109
if programmer == nil {
@@ -153,13 +167,25 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
153
167
if v , ok := uploadProperties .GetOk ("program.params.verbose" ); ok {
154
168
uploadProperties .Set ("program.verbose" , v )
155
169
}
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
+ }
156
176
} else {
157
177
if v , ok := uploadProperties .GetOk ("upload.params.quiet" ); ok {
158
178
uploadProperties .Set ("upload.verbose" , v )
159
179
}
160
180
if v , ok := uploadProperties .GetOk ("program.params.quiet" ); ok {
161
181
uploadProperties .Set ("program.verbose" , v )
162
182
}
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
+ }
163
189
}
164
190
165
191
// Set properties for verify
@@ -172,29 +198,31 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
172
198
}
173
199
174
200
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
+ }
184
211
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" )
190
220
}
191
- uploadProperties .SetPath ("build.path" , importPath )
192
- uploadProperties .Set ("build.project_name" , sketch .Name + ".ino" )
193
221
194
222
// If not using programmer perform some action required
195
223
// to set the board in bootloader mode
196
224
actualPort := port
197
- if programmer == nil {
225
+ if programmer == nil && ! burnBootloader {
198
226
// Perform reset via 1200bps touch if requested
199
227
if uploadProperties .GetBoolean ("upload.use_1200bps_touch" ) {
200
228
ports , err := serial .GetPortsList ()
@@ -250,8 +278,14 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
250
278
}
251
279
252
280
// 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 {
255
289
if err := runTool ("program.pattern" , uploadProperties , outStream , errStream , req .GetVerbose ()); err != nil {
256
290
return nil , fmt .Errorf ("programming error: %s" , err )
257
291
}
0 commit comments