Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 67 additions & 3 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,68 @@
// Package espradio provides support for the ESP32-S2 and ESP32-S3 microcontrollers.
// It is based on the ESP-IDF framework and provides access to Wi-Fi and Bluetooth.
// The package is designed to be used with the TinyGo compiler.
// Package espradio provides wireless support for Espressif microcontrollers
// when used with the TinyGo compiler.
//
// The package wraps the Espressif Wi-Fi blobs and exposes both lower-level
// 1:1 bindings and higher-level Go APIs for common use cases such as:
//
// - station and soft-AP Wi-Fi
// - scanning
// - raw Ethernet/netdev integration
// - ESP-NOW datagram communication
//
// ESP-NOW can be used directly through the thin wrapper functions, or through

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add this as an example in examples/espnow? That should also build that example as part of the smoke tests. Also makes it a lot easier to try it and use it for things.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Example added.

// the higher-level managed API returned by NewESPNow. The managed API maps each
// remote peer to a Peer that implements net.PacketConn.
//
// For applications that prefer a stream-like API over packet-oriented reads and
// writes, Peer can also be wrapped with PeerStream via peer.Stream().
//
// Example usage:
//
// func main() {
// if err := espradio.Enable(espradio.Config{}); err != nil {
// panic(err)
// }
// if err := espradio.Start(); err != nil {
// panic(err)
// }
//
// now, err := espradio.NewESPNow(espradio.ESPNowConfig{})
// if err != nil {
// panic(err)
// }
// defer now.Close()
//
// peer, err := now.AddPeer(espradio.PeerConfig{
// Address: espradio.ESPNowAddr{0x24, 0x6f, 0x28, 0xaa, 0xbb, 0xcc},
// If: espradio.WiFiInterfaceSTA,
// })
// if err != nil {
// panic(err)
// }
// defer peer.Close()
//
// if _, err := peer.WriteTo([]byte("hello"), nil); err != nil {
// panic(err)
// }
//
// buf := make([]byte, espradio.ESPNowMaxDataLength)
// n, addr, err := peer.ReadFrom(buf)
// if err != nil {
// panic(err)
// }
// println("received", n, "bytes from", addr.String())
//
// stream := peer.Stream()
// if _, err := stream.Write([]byte("streamed payload")); err != nil {
// panic(err)
// }
//
// broadcast, err := now.Broadcast()
// if err != nil {
// panic(err)
// }
// if _, err := broadcast.WriteTo([]byte("announcement"), nil); err != nil {
// panic(err)
// }
// }
package espradio // import "tinygo.org/x/espradio"
2 changes: 1 addition & 1 deletion error.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (e Error) Error() string {
return "espradio: unknown flash error"
case e >= C.ESP_ERR_MESH_BASE:
return "espradio: unknown mesh error"
case e >= C.ESP_ERR_ESPNOW_BASE:
case e >= C.ESP_ERR_ESPNOW_BASE && e <= C.ESP_ERR_ESPNOW_CHAN:
switch e {
case C.ESP_ERR_ESPNOW_NOT_INIT:
return "espradio: esp-now not initialized"
Expand Down
30 changes: 22 additions & 8 deletions espnow.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ type ESPNowSendReport struct {
}

var (
espNowMu sync.RWMutex
espNowRecvHandler func(ESPNowReceive)
espNowSendHandler func(ESPNowSendReport)
espNowMu sync.RWMutex
espNowRecvHandler func(ESPNowReceive)
espNowSendHandler func(ESPNowSendReport)
activeManagedESPNow *ESPNow
)

// ESPNowInit initializes the ESP-NOW subsystem and registers callback trampolines.
Expand Down Expand Up @@ -239,8 +240,9 @@ func copyMAC(ptr *C.uint8_t) [ESPNowAddressLength]byte {
func espradio_on_esp_now_recv(srcAddr, destAddr *C.uint8_t, rssi C.int, channel, secondaryChannel C.uint8_t, noiseFloor C.int, timestamp C.uint32_t, data *C.uint8_t, dataLen C.int) {
espNowMu.RLock()
handler := espNowRecvHandler
manager := activeManagedESPNow
espNowMu.RUnlock()
if handler == nil {
if handler == nil && manager == nil {
return
}

Expand All @@ -256,24 +258,36 @@ func espradio_on_esp_now_recv(srcAddr, destAddr *C.uint8_t, rssi C.int, channel,
if data != nil && dataLen > 0 {
event.Data = C.GoBytes(unsafe.Pointer(data), dataLen)
}
handler(event)
if handler != nil {
handler(event)
}
if manager != nil {
manager.handleReceive(event)
}
}

//export espradio_on_esp_now_send
func espradio_on_esp_now_send(destAddr, srcAddr *C.uint8_t, ifidx C.wifi_interface_t, rate C.wifi_phy_rate_t, txStatus C.wifi_tx_status_t, status C.esp_now_send_status_t) {
espNowMu.RLock()
handler := espNowSendHandler
manager := activeManagedESPNow
espNowMu.RUnlock()
if handler == nil {
if handler == nil && manager == nil {
return
}

handler(ESPNowSendReport{
report := ESPNowSendReport{
DestinationAddress: copyMAC(destAddr),
SourceAddress: copyMAC(srcAddr),
If: WiFiInterface(ifidx),
Rate: uint32(rate),
TxStatus: ESPNowSendStatus(txStatus),
Status: ESPNowSendStatus(status),
})
}
if handler != nil {
handler(report)
}
if manager != nil {
manager.handleSend(report)
}
}
Loading
Loading