mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-07-26 10:38:41 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 26aa664c80 | |||
| 2d644c8b60 |
+4
-1
@@ -11,7 +11,10 @@ func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration)
|
||||
return net.ErrWiFiMissingSSID
|
||||
}
|
||||
|
||||
d.SetWifiMode(WifiModeClient)
|
||||
if err := d.SetWifiMode(WifiModeClient); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return d.ConnectToAP(ssid, pass, 10)
|
||||
}
|
||||
|
||||
|
||||
+47
-26
@@ -28,6 +28,8 @@ import (
|
||||
"tinygo.org/x/drivers/net"
|
||||
)
|
||||
|
||||
const CRLF = "\r\n"
|
||||
|
||||
// Device wraps UART connection to the ESP8266/ESP32.
|
||||
type Device struct {
|
||||
bus drivers.UART
|
||||
@@ -37,10 +39,10 @@ type Device struct {
|
||||
|
||||
// data received from a TCP/UDP connection forwarded by the ESP8266/ESP32
|
||||
socketdata []byte
|
||||
}
|
||||
|
||||
// ActiveDevice is the currently configured Device in use. There can only be one.
|
||||
var ActiveDevice *Device
|
||||
// dump extra data to console?
|
||||
Debug bool
|
||||
}
|
||||
|
||||
// New returns a new espat driver. Pass in a fully configured UART bus.
|
||||
func New(b drivers.UART) *Device {
|
||||
@@ -48,9 +50,9 @@ func New(b drivers.UART) *Device {
|
||||
}
|
||||
|
||||
// Configure sets up the device for communication.
|
||||
func (d Device) Configure() {
|
||||
ActiveDevice = &d
|
||||
net.ActiveDevice = ActiveDevice
|
||||
func (d *Device) Configure() {
|
||||
// set the configured Device in use. There can only be one.
|
||||
net.UseDriver(d)
|
||||
}
|
||||
|
||||
// Connected checks if there is communication with the ESP8266/ESP32.
|
||||
@@ -59,10 +61,7 @@ func (d *Device) Connected() bool {
|
||||
|
||||
// handle response here, should include "OK"
|
||||
_, err := d.Response(100)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Write raw bytes to the UART.
|
||||
@@ -80,21 +79,33 @@ const pause = 300
|
||||
|
||||
// Execute sends an AT command to the ESP8266/ESP32.
|
||||
func (d Device) Execute(cmd string) error {
|
||||
_, err := d.Write([]byte("AT" + cmd + "\r\n"))
|
||||
data := "AT" + cmd
|
||||
if d.Debug {
|
||||
debugprintln(data)
|
||||
}
|
||||
_, err := d.Write([]byte(data + CRLF))
|
||||
return err
|
||||
}
|
||||
|
||||
// Query sends an AT command to the ESP8266/ESP32 that returns the
|
||||
// current value for some configuration parameter.
|
||||
func (d Device) Query(cmd string) (string, error) {
|
||||
_, err := d.Write([]byte("AT" + cmd + "?\r\n"))
|
||||
data := "AT" + cmd + "?"
|
||||
if d.Debug {
|
||||
debugprintln(data)
|
||||
}
|
||||
_, err := d.Write([]byte(data + CRLF))
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Set sends an AT command with params to the ESP8266/ESP32 for a
|
||||
// configuration value to be set.
|
||||
func (d Device) Set(cmd, params string) error {
|
||||
_, err := d.Write([]byte("AT" + cmd + "=" + params + "\r\n"))
|
||||
data := "AT" + cmd + "=" + params
|
||||
if d.Debug {
|
||||
debugprintln(data)
|
||||
}
|
||||
_, err := d.Write([]byte(data + CRLF))
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -103,6 +114,10 @@ func (d Device) Version() []byte {
|
||||
d.Execute(Version)
|
||||
r, err := d.Response(100)
|
||||
if err != nil {
|
||||
if d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
|
||||
return []byte("unknown")
|
||||
}
|
||||
return r
|
||||
@@ -152,17 +167,17 @@ func (d *Device) ReadSocket(b []byte) (n int, err error) {
|
||||
// The call will retry for up to timeout milliseconds before returning nothing.
|
||||
func (d *Device) Response(timeout int) ([]byte, error) {
|
||||
// read data
|
||||
var size int
|
||||
var start, end int
|
||||
pause := 100 // pause to wait for 100 ms
|
||||
retries := timeout / pause
|
||||
pause := 10 * time.Millisecond
|
||||
starting := time.Now()
|
||||
|
||||
for {
|
||||
size = d.bus.Buffered()
|
||||
|
||||
if size > 0 {
|
||||
if size := d.bus.Buffered(); size > 0 {
|
||||
end += size
|
||||
d.bus.Read(d.response[start:end])
|
||||
_, err := d.bus.Read(d.response[start:end])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if "+IPD" then read socket data
|
||||
if strings.Contains(string(d.response[:end]), "+IPD") {
|
||||
@@ -172,12 +187,15 @@ func (d *Device) Response(timeout int) ([]byte, error) {
|
||||
|
||||
// if "OK" then the command worked
|
||||
if strings.Contains(string(d.response[:end]), "OK") {
|
||||
return d.response[start:end], nil
|
||||
if d.Debug {
|
||||
debugprintln(string(d.response[:end]))
|
||||
}
|
||||
return d.response[:end], nil
|
||||
}
|
||||
|
||||
// if "Error" then the command failed
|
||||
if strings.Contains(string(d.response[:end]), "ERROR") {
|
||||
return d.response[start:end], errors.New("response error:" + string(d.response[start:end]))
|
||||
return d.response[:end], errors.New("response error:" + string(d.response[:end]))
|
||||
}
|
||||
|
||||
// if anything else, then keep reading data in?
|
||||
@@ -185,12 +203,11 @@ func (d *Device) Response(timeout int) ([]byte, error) {
|
||||
}
|
||||
|
||||
// wait longer?
|
||||
retries--
|
||||
if retries == 0 {
|
||||
return nil, errors.New("response timeout error:" + string(d.response[start:end]))
|
||||
if time.Since(starting) > time.Duration(timeout)*time.Millisecond {
|
||||
return nil, errors.New("response timeout error:" + string(d.response[:end]))
|
||||
}
|
||||
|
||||
time.Sleep(time.Duration(pause) * time.Millisecond)
|
||||
time.Sleep(pause)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,3 +237,7 @@ func (d *Device) parseIPD(end int) error {
|
||||
func (d *Device) IsSocketDataAvailable() bool {
|
||||
return len(d.socketdata) > 0 || d.bus.Buffered() > 0
|
||||
}
|
||||
|
||||
func debugprintln(msg string) {
|
||||
println("[DEBUG] " + msg)
|
||||
}
|
||||
|
||||
+50
-12
@@ -19,6 +19,9 @@ func (d *Device) GetDNS(domain string) (string, error) {
|
||||
d.Set(TCPDNSLookup, "\""+domain+"\"")
|
||||
resp, err := d.Response(1000)
|
||||
if err != nil {
|
||||
if d.Debug {
|
||||
println(string(resp))
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
if !strings.Contains(string(resp), ":") {
|
||||
@@ -36,13 +39,17 @@ func (d *Device) GetDNS(domain string) (string, error) {
|
||||
// Currently only supports single connection mode.
|
||||
func (d *Device) ConnectTCPSocket(addr, port string) error {
|
||||
protocol := "TCP"
|
||||
val := "\"" + protocol + "\",\"" + addr + "\"," + port + ",120"
|
||||
val := "\"" + protocol + "\"," + addr + "," + port + ",120"
|
||||
err := d.Set(TCPConnect, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, e := d.Response(3000)
|
||||
r, e := d.Response(3000)
|
||||
if e != nil {
|
||||
if d.Debug {
|
||||
println(string(r))
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
@@ -51,13 +58,17 @@ func (d *Device) ConnectTCPSocket(addr, port string) error {
|
||||
// ConnectUDPSocket creates a new UDP connection for the ESP8266/ESP32.
|
||||
func (d *Device) ConnectUDPSocket(addr, sendport, listenport string) error {
|
||||
protocol := "UDP"
|
||||
val := "\"" + protocol + "\",\"" + addr + "\"," + sendport + "," + listenport + ",2"
|
||||
val := "\"" + protocol + "\"," + addr + "," + sendport + "," + listenport + ",2"
|
||||
err := d.Set(TCPConnect, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, e := d.Response(3000)
|
||||
r, e := d.Response(3000)
|
||||
if e != nil {
|
||||
if d.Debug {
|
||||
println(string(r))
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
@@ -67,11 +78,15 @@ func (d *Device) ConnectUDPSocket(addr, sendport, listenport string) error {
|
||||
// Currently only supports single connection mode.
|
||||
func (d *Device) ConnectSSLSocket(addr, port string) error {
|
||||
protocol := "SSL"
|
||||
val := "\"" + protocol + "\",\"" + addr + "\"," + port + ",120"
|
||||
val := "\"" + protocol + "\"," + addr + "," + port + ",120"
|
||||
d.Set(TCPConnect, val)
|
||||
// this operation takes longer, so wait up to 6 seconds to complete.
|
||||
_, err := d.Response(6000)
|
||||
r, err := d.Response(6000)
|
||||
if err != nil {
|
||||
if d.Debug {
|
||||
println(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -83,8 +98,12 @@ func (d *Device) DisconnectSocket() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, e := d.Response(pause)
|
||||
r, e := d.Response(pause)
|
||||
if e != nil {
|
||||
if d.Debug {
|
||||
println(string(r))
|
||||
}
|
||||
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
@@ -95,7 +114,11 @@ func (d *Device) DisconnectSocket() error {
|
||||
func (d *Device) SetMux(mode int) error {
|
||||
val := strconv.Itoa(mode)
|
||||
d.Set(TCPMultiple, val)
|
||||
_, err := d.Response(pause)
|
||||
r, err := d.Response(pause)
|
||||
if err != nil && d.Debug {
|
||||
println(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -110,7 +133,11 @@ func (d *Device) GetMux() ([]byte, error) {
|
||||
func (d *Device) SetTCPTransferMode(mode int) error {
|
||||
val := strconv.Itoa(mode)
|
||||
d.Set(TransmissionMode, val)
|
||||
_, err := d.Response(pause)
|
||||
r, err := d.Response(pause)
|
||||
if err != nil && d.Debug {
|
||||
println(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -123,12 +150,19 @@ func (d *Device) GetTCPTransferMode() ([]byte, error) {
|
||||
// StartSocketSend gets the ESP8266/ESP32 ready to receive TCP/UDP socket data.
|
||||
func (d *Device) StartSocketSend(size int) error {
|
||||
val := strconv.Itoa(size)
|
||||
d.Set(TCPSend, val)
|
||||
err := d.Set(TCPSend, val)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// when ">" is received, it indicates
|
||||
// ready to receive data
|
||||
r, err := d.Response(2000)
|
||||
r, err := d.Response(500)
|
||||
if err != nil {
|
||||
if d.Debug {
|
||||
println(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
if strings.Contains(string(r), ">") {
|
||||
@@ -142,6 +176,10 @@ func (d *Device) StartSocketSend(size int) error {
|
||||
func (d *Device) EndSocketSend() error {
|
||||
d.Write([]byte("+++"))
|
||||
|
||||
_, err := d.Response(pause)
|
||||
r, err := d.Response(pause)
|
||||
if err != nil && d.Debug {
|
||||
println(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
+53
-8
@@ -25,7 +25,11 @@ func (d *Device) GetWifiMode() ([]byte, error) {
|
||||
func (d *Device) SetWifiMode(mode int) error {
|
||||
val := strconv.Itoa(mode)
|
||||
d.Set(WifiMode, val)
|
||||
_, err := d.Response(pause)
|
||||
r, err := d.Response(pause)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -43,8 +47,12 @@ func (d *Device) ConnectToAP(ssid, pwd string, ws int) error {
|
||||
val := "\"" + ssid + "\",\"" + pwd + "\""
|
||||
d.Set(ConnectAP, val)
|
||||
|
||||
_, err := d.Response(ws * 1000)
|
||||
r, err := d.Response(ws * 1000)
|
||||
if err != nil {
|
||||
if d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -53,7 +61,11 @@ func (d *Device) ConnectToAP(ssid, pwd string, ws int) error {
|
||||
// DisconnectFromAP disconnects the ESP8266/ESP32 from the current access point.
|
||||
func (d *Device) DisconnectFromAP() error {
|
||||
d.Execute(Disconnect)
|
||||
_, err := d.Response(1000)
|
||||
r, err := d.Response(1000)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -68,7 +80,11 @@ func (d *Device) GetClientIP() (string, error) {
|
||||
func (d *Device) SetClientIP(ipaddr string) error {
|
||||
val := "\"" + ipaddr + "\""
|
||||
d.Set(ConnectAP, val)
|
||||
_, err := d.Response(500)
|
||||
r, err := d.Response(500)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -78,6 +94,10 @@ func (d *Device) SetClientIP(ipaddr string) error {
|
||||
func (d *Device) GetAPConfig() (string, error) {
|
||||
d.Query(SoftAPConfigCurrent)
|
||||
r, err := d.Response(100)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
|
||||
return string(r), err
|
||||
}
|
||||
|
||||
@@ -89,7 +109,11 @@ func (d *Device) SetAPConfig(ssid, pwd string, ch, security int) error {
|
||||
ecnval := strconv.Itoa(security)
|
||||
val := "\"" + ssid + "\",\"" + pwd + "\"," + chval + "," + ecnval
|
||||
d.Set(SoftAPConfigCurrent, val)
|
||||
_, err := d.Response(1000)
|
||||
r, err := d.Response(1000)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -97,6 +121,9 @@ func (d *Device) SetAPConfig(ssid, pwd string, ch, security int) error {
|
||||
func (d *Device) GetAPClients() (string, error) {
|
||||
d.Query(ListConnectedIP)
|
||||
r, err := d.Response(100)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
return string(r), err
|
||||
}
|
||||
|
||||
@@ -104,6 +131,9 @@ func (d *Device) GetAPClients() (string, error) {
|
||||
func (d *Device) GetAPIP() (string, error) {
|
||||
d.Query(SetSoftAPIPCurrent)
|
||||
r, err := d.Response(100)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
return string(r), err
|
||||
}
|
||||
|
||||
@@ -111,7 +141,10 @@ func (d *Device) GetAPIP() (string, error) {
|
||||
func (d *Device) SetAPIP(ipaddr string) error {
|
||||
val := "\"" + ipaddr + "\""
|
||||
d.Set(SetSoftAPIPCurrent, val)
|
||||
_, err := d.Response(500)
|
||||
r, err := d.Response(500)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -120,6 +153,9 @@ func (d *Device) SetAPIP(ipaddr string) error {
|
||||
func (d *Device) GetAPConfigFlash() (string, error) {
|
||||
d.Query(SoftAPConfigFlash)
|
||||
r, err := d.Response(100)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
return string(r), err
|
||||
}
|
||||
|
||||
@@ -132,7 +168,10 @@ func (d *Device) SetAPConfigFlash(ssid, pwd string, ch, security int) error {
|
||||
ecnval := strconv.Itoa(security)
|
||||
val := "\"" + ssid + "\",\"" + pwd + "\"," + chval + "," + ecnval
|
||||
d.Set(SoftAPConfigFlash, val)
|
||||
_, err := d.Response(1000)
|
||||
r, err := d.Response(1000)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -141,6 +180,9 @@ func (d *Device) SetAPConfigFlash(ssid, pwd string, ch, security int) error {
|
||||
func (d *Device) GetAPIPFlash() (string, error) {
|
||||
d.Query(SetSoftAPIPFlash)
|
||||
r, err := d.Response(100)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
return string(r), err
|
||||
}
|
||||
|
||||
@@ -149,6 +191,9 @@ func (d *Device) GetAPIPFlash() (string, error) {
|
||||
func (d *Device) SetAPIPFlash(ipaddr string) error {
|
||||
val := "\"" + ipaddr + "\""
|
||||
d.Set(SetSoftAPIPFlash, val)
|
||||
_, err := d.Response(500)
|
||||
r, err := d.Response(500)
|
||||
if err != nil && d.Debug {
|
||||
debugprintln(string(r))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user