From 02facb856854703cd12b78e10cb75ac8c9cbfb55 Mon Sep 17 00:00:00 2001 From: Ron Evans Date: Fri, 11 Oct 2019 11:34:08 +0200 Subject: [PATCH] flash: add ability to perform 1200baud port reset for MCUs that can detect this in order to go into bootloader mode for flashing without pressing any buttons. Also add support for this to the Arduino Nano33 IoT board target Signed-off-by: Ron Evans --- go.mod | 3 +++ go.sum | 6 ++++++ main.go | 25 +++++++++++++++++++++++++ target.go | 5 +++++ targets/arduino-nano33.json | 3 ++- 5 files changed, 41 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 405de2ca..64668f6c 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,10 @@ go 1.11 require ( github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 + github.com/creack/goselect v0.1.0 // indirect github.com/marcinbor85/gohex v0.0.0-20180128172054-7a43cd876e46 + go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45 + golang.org/x/sys v0.0.0-20191010194322-b09406accb47 // indirect golang.org/x/tools v0.0.0-20190227180812-8dcc6e70cdef tinygo.org/x/go-llvm v0.0.0-20190818154551-95bc4ffe1add ) diff --git a/go.sum b/go.sum index 5f744434..341c3e5b 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,17 @@ github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI= github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= +github.com/creack/goselect v0.1.0 h1:4QiXIhcpSQF50XGaBsFzesjwX/1qOY5bOveQPmN9CXY= +github.com/creack/goselect v0.1.0/go.mod h1:gHrIcH/9UZDn2qgeTUeW5K9eZsVYCH6/60J/FHysWyE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/marcinbor85/gohex v0.0.0-20180128172054-7a43cd876e46 h1:wXG2bA8fO7Vv7lLk2PihFMTqmbT173Tje39oKzQ50Mo= github.com/marcinbor85/gohex v0.0.0-20180128172054-7a43cd876e46/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M= +go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45 h1:mACY1anK6HNCZtm/DK2Rf2ZPHggVqeB0+7rY9Gl6wyI= +go.bug.st/serial.v1 v0.0.0-20180827123349-5f7892a7bb45/go.mod h1:dRSl/CVCTf56CkXgJMDOdSwNfo2g1orOGE/gBGdvjZw= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47 h1:/XfQ9z7ib8eEJX2hdgFTZJ/ntt0swNk5oYBziWeTCvY= +golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190227180812-8dcc6e70cdef h1:ymc9FeDom3RIEA3coKokSllBB1hRcMT0tZ1W3Jf9Ids= golang.org/x/tools v0.0.0-20190227180812-8dcc6e70cdef/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/main.go b/main.go index 0778de46..3c169bf9 100644 --- a/main.go +++ b/main.go @@ -15,10 +15,13 @@ import ( "strconv" "strings" "syscall" + "time" "github.com/tinygo-org/tinygo/compiler" "github.com/tinygo-org/tinygo/interp" "github.com/tinygo-org/tinygo/loader" + + serial "go.bug.st/serial.v1" ) // commandError is an error type to wrap os/exec.Command errors. This provides @@ -418,6 +421,16 @@ func Flash(pkgName, target, port string, config *BuildConfig) error { return errors.New("no flash command specified - did you miss a -target flag?") } + // do we need port reset to put MCU into bootloader mode? + if spec.PortReset == "true" { + err := touchSerialPortAt1200bps(port) + if err != nil { + return &commandError{"failed to reset port", tmppath, err} + } + // give the target MCU a chance to restart into bootloader + time.Sleep(3 * time.Second) + } + // Create the command. flashCmd := spec.Flasher fileToken := "{" + fileExt[1:] + "}" @@ -549,6 +562,18 @@ func Run(pkgName, target string, config *BuildConfig) error { }) } +func touchSerialPortAt1200bps(port string) error { + // Open port + p, err := serial.Open(port, &serial.Mode{BaudRate: 1200}) + if err != nil { + return fmt.Errorf("opening port: %s", err) + } + defer p.Close() + + p.SetDTR(false) + return nil +} + // parseSize converts a human-readable size (with k/m/g suffix) into a plain // number. func parseSize(s string) (int64, error) { diff --git a/target.go b/target.go index ad701e83..c3fea39f 100644 --- a/target.go +++ b/target.go @@ -46,6 +46,7 @@ type TargetSpec struct { OCDDaemon []string `json:"ocd-daemon"` GDB string `json:"gdb"` GDBCmds []string `json:"gdb-initial-cmds"` + PortReset string `json:"flash-1200-bps-reset"` } // copyProperties copies all properties that are set in spec2 into itself. @@ -100,6 +101,9 @@ func (spec *TargetSpec) copyProperties(spec2 *TargetSpec) { if len(spec2.GDBCmds) != 0 { spec.GDBCmds = spec2.GDBCmds } + if spec2.PortReset != "" { + spec.PortReset = spec2.PortReset + } } // load reads a target specification from the JSON in the given io.Reader. It @@ -237,6 +241,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { Linker: "cc", GDB: "gdb", GDBCmds: []string{"run"}, + PortReset: "false", } if goos == "darwin" { spec.LDFlags = append(spec.LDFlags, "-Wl,-dead_strip") diff --git a/targets/arduino-nano33.json b/targets/arduino-nano33.json index eaad5879..839fd7c1 100644 --- a/targets/arduino-nano33.json +++ b/targets/arduino-nano33.json @@ -1,5 +1,6 @@ { "inherits": ["atsamd21g18a"], "build-tags": ["sam", "atsamd21g18a", "arduino_nano33"], - "flash": "bossac -d -i -e -w -v -R --port={port} --offset=0x2000 {bin}" + "flash": "bossac -d -i -e -w -v -R --port={port} --offset=0x2000 {bin}", + "flash-1200-bps-reset": "true" }