1
1
package programmer
2
2
3
+ import (
4
+ "time"
5
+
6
+ "github.com/facchinm/go-serial"
7
+ "github.com/pkg/errors"
8
+ )
9
+
3
10
type logger interface {
4
- Info ()
5
- Debug ()
11
+ Debug (args ... interface {})
12
+ Info (args ... interface {})
13
+ }
14
+
15
+ func debug (l logger , args ... interface {}) {
16
+ if l != nil {
17
+ l .Debug (args ... )
18
+ }
19
+ }
20
+
21
+ func info (l logger , args ... interface {}) {
22
+ if l != nil {
23
+ l .Info (args ... )
24
+ }
6
25
}
7
26
8
27
// Auth contains username and password used for a network upload
@@ -24,5 +43,109 @@ type Extra struct {
24
43
25
44
// Do performs a command on a port with a board attached to it
26
45
func Do (port , board , path , commandline string , extra Extra , l logger ) {
46
+ debug (l , port , board , path , commandline )
47
+ if extra .Network {
48
+ doNetwork ()
49
+ } else {
50
+ doSerial (port , extra , l )
51
+ }
52
+ }
53
+
54
+ func doNetwork () {}
55
+
56
+ func doSerial (port string , extra Extra , l logger ) {
57
+ // some boards needs to be resetted
58
+ if extra .Use1200bpsTouch {
59
+ port , _ = reset (port , extra .WaitForUploadPort , l )
60
+ }
61
+ }
62
+
63
+ // reset opens the port at 1200bps. It returns the new port name (which could change
64
+ // sometimes) and an error (usually because the port listing failed)
65
+ func reset (port string , wait bool , l logger ) (string , error ) {
66
+ info (l , "Restarting in bootloader mode" )
67
+
68
+ // Get port list before reset
69
+ ports , err := serial .GetPortsList ()
70
+ debug (l , "Get port list before reset" )
71
+ debug (l , ports , err )
72
+ if err != nil {
73
+ return "" , errors .Wrapf (err , "Get port list before reset" )
74
+ }
75
+
76
+ // Open port
77
+ mode := & serial.Mode {
78
+ BaudRate : 1200 ,
79
+ Vmin : 0 ,
80
+ Vtimeout : 1 ,
81
+ }
82
+ p , err := serial .OpenPort (port , mode )
83
+ debug (l , "Open port" , port )
84
+ debug (l , p , err )
85
+ if err != nil {
86
+ return "" , errors .Wrapf (err , "Open port %s" , port )
87
+ }
88
+
89
+ // Set DTR
90
+ err = p .SetDTR (false )
91
+ debug (l , "Set DTR" )
92
+ debug (l , err )
93
+ p .Close ()
94
+
95
+ // Wait for port to disappear and reappear
96
+ if wait {
97
+ port = waitReset (ports , l )
98
+ }
99
+
100
+ return port , nil
101
+ }
102
+
103
+ // waitReset is meant to be called just after a reset. It watches the ports connected
104
+ // to the machine until a port disappears and reappears. The port name could be different
105
+ // so it returns the name of the new port.
106
+ func waitReset (beforeReset []string , l logger ) string {
107
+ var port string
108
+ timeout := false
109
+
110
+ go func () {
111
+ time .Sleep (10 * time .Second )
112
+ timeout = true
113
+ }()
114
+
115
+ // Wait for the port to disappear
116
+ debug (l , "Wait for the port to disappear" )
117
+ for {
118
+ ports , err := serial .GetPortsList ()
119
+ port = differ (ports , beforeReset )
120
+ debug (l , ".." , ports , beforeReset , err , port )
121
+
122
+ if port != "" {
123
+ break
124
+ }
125
+ if timeout {
126
+ debug (l , ports , err , port )
127
+ break
128
+ }
129
+ time .Sleep (time .Millisecond * 100 )
130
+ }
131
+
132
+ // Wait for the port to reappear
133
+ debug (l , "Wait for the port to reappear" )
134
+ afterReset , _ := serial .GetPortsList ()
135
+ for {
136
+ ports , err := serial .GetPortsList ()
137
+ port = differ (ports , afterReset )
138
+ debug (l , ".." , ports , afterReset , err , port )
139
+ if port != "" {
140
+ time .Sleep (time .Millisecond * 500 )
141
+ break
142
+ }
143
+ if timeout {
144
+ debug (l , "timeout" )
145
+ break
146
+ }
147
+ time .Sleep (time .Millisecond * 100 )
148
+ }
27
149
150
+ return port
28
151
}
0 commit comments