Skip to content

Commit ed0963c

Browse files
committed
Start porting avrdude for uno wifi rev2
1 parent df070ca commit ed0963c

File tree

3 files changed

+212
-5
lines changed

3 files changed

+212
-5
lines changed
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
package avrdude
2+
3+
import (
4+
"bytes"
5+
"errors"
6+
"io/ioutil"
7+
"log"
8+
"os/exec"
9+
"path/filepath"
10+
11+
"github.com/arduino-libraries/WiFi101-FirmwareUpdater/context"
12+
serial "go.bug.st/serial.v1"
13+
//"go.bug.st/serial.v1/enumerator"
14+
"time"
15+
)
16+
17+
type Avrdude struct {
18+
}
19+
20+
func (b *Avrdude) Flash(ctx *context.Context, filename string) error {
21+
log.Println("Flashing " + filename)
22+
23+
err := invokeAvrdude([]string{ctx.ProgrammerPath, "-C" + filepath.Join(filepath.Dir(ctx.ProgrammerPath), "..", "etc/avrdude.conf"), "-v", "-patmega4809", "-cxplainedmini_updi", "-Pusb", "-b115200", "-e", "-D", "-Uflash:w:" + filename + ":i"})
24+
25+
time.Sleep(3 * time.Second)
26+
return err
27+
}
28+
29+
func (b *Avrdude) DumpAndFlash(ctx *context.Context, filename string) (string, error) {
30+
log.Println("Flashing " + filename)
31+
dir, err := ioutil.TempDir("", "wifiFlasher_dump")
32+
err = invokeAvrdude([]string{ctx.ProgrammerPath, "-C" + filepath.Join(filepath.Dir(ctx.ProgrammerPath), "..", "etc/avrdude.conf"), "-v", "-patmega4809", "-cxplainedmini_updi", "-Pusb", "-b115200", "-D", "-Uflash:r:" + filepath.Join(dir, "dump.bin") + ":i"})
33+
log.Println("Original sketch saved at " + filepath.Join(dir, "dump.bin"))
34+
if err != nil {
35+
return "", err
36+
}
37+
err = invokeAvrdude([]string{ctx.ProgrammerPath, "-C" + filepath.Join(filepath.Dir(ctx.ProgrammerPath), "..", "etc/avrdude.conf"), "-v", "-patmega4809", "-cxplainedmini_updi", "-Pusb", "-b115200", "-e", "-D", "-Uflash:w:" + filename + ":i"})
38+
time.Sleep(3 * time.Second)
39+
40+
return filepath.Join(dir, "dump.bin"), err
41+
}
42+
43+
func invokeAvrdude(args []string) error {
44+
cmd := exec.Command(args[0], args[1:]...)
45+
var out bytes.Buffer
46+
var stderr bytes.Buffer
47+
cmd.Stdout = &out
48+
cmd.Stderr = &stderr
49+
err := cmd.Run()
50+
log.Println(out.String())
51+
log.Println(stderr.String())
52+
return err
53+
}
54+
55+
func touchSerialPortAt1200bps(port string) error {
56+
log.Println("Touching port " + port + " at 1200bps")
57+
58+
// Open port
59+
p, err := serial.Open(port, &serial.Mode{BaudRate: 1200})
60+
if err != nil {
61+
return errors.New("Open port " + port)
62+
}
63+
defer p.Close()
64+
65+
// Set DTR
66+
err = p.SetDTR(false)
67+
log.Println("Set DTR off")
68+
if err != nil {
69+
return errors.New("Can't set DTR")
70+
}
71+
72+
// Wait a bit to allow restart of the board
73+
time.Sleep(200 * time.Millisecond)
74+
75+
return nil
76+
}
77+
78+
// reset opens the port at 1200bps. It returns the new port name (which could change
79+
// sometimes) and an error (usually because the port listing failed)
80+
func reset(port string, wait bool) (string, error) {
81+
log.Println("Restarting in bootloader mode")
82+
83+
// Get port list before reset
84+
ports, err := serial.GetPortsList()
85+
log.Println("Get port list before reset")
86+
if err != nil {
87+
return "", errors.New("Get port list before reset")
88+
}
89+
90+
// Touch port at 1200bps
91+
err = touchSerialPortAt1200bps(port)
92+
if err != nil {
93+
return "", errors.New("1200bps Touch")
94+
}
95+
96+
// Wait for port to disappear and reappear
97+
if wait {
98+
port = waitReset(ports, port)
99+
}
100+
101+
return port, nil
102+
}
103+
104+
// waitReset is meant to be called just after a reset. It watches the ports connected
105+
// to the machine until a port disappears and reappears. The port name could be different
106+
// so it returns the name of the new port.
107+
func waitReset(beforeReset []string, originalPort string) string {
108+
var port string
109+
timeout := false
110+
111+
go func() {
112+
time.Sleep(10 * time.Second)
113+
timeout = true
114+
}()
115+
116+
for {
117+
ports, _ := serial.GetPortsList()
118+
port = differ(ports, beforeReset)
119+
120+
if port != "" {
121+
break
122+
}
123+
if timeout {
124+
break
125+
}
126+
time.Sleep(time.Millisecond * 100)
127+
}
128+
129+
// Wait for the port to reappear
130+
log.Println("Wait for the port to reappear")
131+
afterReset, _ := serial.GetPortsList()
132+
for {
133+
ports, _ := serial.GetPortsList()
134+
port = differ(ports, afterReset)
135+
if port != "" {
136+
time.Sleep(time.Millisecond * 500)
137+
break
138+
}
139+
if timeout {
140+
break
141+
}
142+
time.Sleep(time.Millisecond * 100)
143+
}
144+
145+
// try to upload on the existing port if the touch was ineffective
146+
if port == "" {
147+
port = originalPort
148+
}
149+
150+
return port
151+
}
152+
153+
func waitPort(beforeReset []string, originalPort string) string {
154+
var port string
155+
timeout := false
156+
157+
go func() {
158+
time.Sleep(10 * time.Second)
159+
timeout = true
160+
}()
161+
162+
for {
163+
ports, _ := serial.GetPortsList()
164+
port = differ(ports, beforeReset)
165+
166+
if port != "" {
167+
break
168+
}
169+
if timeout {
170+
break
171+
}
172+
time.Sleep(time.Millisecond * 100)
173+
}
174+
175+
// try to upload on the existing port if the touch was ineffective
176+
if port == "" {
177+
port = originalPort
178+
}
179+
180+
return port
181+
}
182+
183+
// differ returns the first item that differ between the two input slices
184+
func differ(slice1 []string, slice2 []string) string {
185+
m := map[string]int{}
186+
187+
for _, s1Val := range slice1 {
188+
m[s1Val] = 1
189+
}
190+
for _, s2Val := range slice2 {
191+
m[s2Val] = m[s2Val] + 1
192+
}
193+
194+
for mKey, mVal := range m {
195+
if mVal == 1 {
196+
return mKey
197+
}
198+
}
199+
200+
return ""
201+
}

src/github.com/arduino-libraries/WiFi101-FirmwareUpdater/nina/flasher.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,8 @@ func (flasher *Flasher) Md5sum(data []byte) error {
237237

238238
func OpenSerial(portName string) (serial.Port, error) {
239239
mode := &serial.Mode{
240-
BaudRate: 230400,
241-
Vtimeout: 200,
240+
BaudRate: 115200,
241+
Vtimeout: 255,
242242
Vmin: 0,
243243
}
244244

@@ -257,5 +257,7 @@ func OpenFlasher(portName string) (*Flasher, error) {
257257
port: port,
258258
}
259259

260+
time.Sleep(2 * time.Second)
261+
260262
return flasher, err
261263
}

src/github.com/arduino-libraries/WiFi101-FirmwareUpdater/nina/main.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@ package nina
2121

2222
import (
2323
"fmt"
24-
"github.com/arduino-libraries/WiFi101-FirmwareUpdater/bossac"
25-
"github.com/arduino-libraries/WiFi101-FirmwareUpdater/context"
2624
"io/ioutil"
2725
"log"
2826
"os"
2927
"path/filepath"
3028
"strconv"
3129
"strings"
32-
//"github.com/arduino-libraries/WiFi101-FirmwareUpdater/avrdude"
30+
31+
"github.com/arduino-libraries/WiFi101-FirmwareUpdater/avrdude"
32+
"github.com/arduino-libraries/WiFi101-FirmwareUpdater/bossac"
33+
"github.com/arduino-libraries/WiFi101-FirmwareUpdater/context"
3334
)
3435

3536
var f *Flasher
@@ -43,6 +44,9 @@ func Run(ctx context.Context) {
4344
if strings.Contains(filepath.Base(ctx.ProgrammerPath), "bossac") {
4445
programmer = &bossac.Bossac{}
4546
}
47+
if strings.Contains(filepath.Base(ctx.ProgrammerPath), "avrdude") {
48+
programmer = &avrdude.Avrdude{}
49+
}
4650

4751
if ctx.FWUploaderBinary != "" {
4852
log.Println("Flashing firmware uploader")

0 commit comments

Comments
 (0)