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" }