tinygo-org / tinygo

Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
https://tinygo.org
Other
14.72k stars 859 forks source link

Support for Raspberry Pi Pico W with Wireless #2947

Open efectn opened 2 years ago

efectn commented 2 years ago

Pico W has been released today with included wirless chip. It would be great if tinygo supports it. It uses CYW43439 as wireless chip.

https://www.raspberrypi.com/news/raspberry-pi-pico-w-your-6-iot-platform/

sago35 commented 2 years ago

Hmm? Maybe we need PIO support first?

https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/cyw43_driver

kenbell commented 2 years ago

I've got my hands on one. Using the Pico target in tinygo does the basics (as you'd expect):

Wireless (obviously) not tested.

To properly support will need at least:

charathram commented 1 year ago

If this is worked on, and requires someone to test, I'm more than happy to commit some time to test on a Pico W.

pobochiigo commented 1 year ago

If this is worked on, and requires someone to test, I'm more than happy to commit some time to test on a Pico W.

Ready to participate in testing as well

rgerardi commented 1 year ago

I've got a couple of Pico W here as well. Ready to help testing

sago35 commented 1 year ago

https://github.com/georgerobotics/cyw43-driver

asap2Go commented 1 year ago

Is someone already working on this?

quaintdev commented 1 year ago

Guys anyone working on this? I think the supply chain issues at least for Pico W seems to be resolved as they are available everywhere now.

andoks commented 1 year ago

Does the introduction of the Pico W warrant a separate page from the current Pico page (https://tinygo.org/docs/reference/microcontrollers/pico/)?

rtitz commented 1 year ago

Seems that still the Wifi module of raspberry pi pico is not supported. Any plans to implement this?

MushiTheMoshi commented 1 year ago

is it plan to be supported this year ?

soypat commented 1 year ago

Like @sago35 said, PIO would go a long way to having wifi as envisioned by the Raspberry Pi engineers since the CY43's SPI data in and out are shared by pin 24 of the pico, so peripheral SPI is not a possibility. I'm out of my element when it comes to PIO, very excited about it (bought a logic analyzer recently with 500MHz sampling for PIO debugging in future).

The other option is using software SPI, which I will try to test out the pico W once I get back from vacations and settled in. That may take while to get working, if at all possible- that depends on how far the software spi can go and what the cy43 interface can tolerate.

I've documented helpful info in a repo for anyone interested in maybe helping out https://github.com/soypat/cyw43439. I've bought 10 of these Pico W's with hopes that wifi will work on it in the near future, for some definition of "near".

soypat commented 1 year ago

Little update. Work on the aforementioned repo is coming along nicely. I've managed to communicate with the CYW43439 and read from its general purpose registers. I have but one blocker: The gSPI to communicate via the backplane interface. I have replicated the backplane communications the best I can to my knowledge. The I/O of my implementation and the pico-sdk looks identical when looking at the verbose log of gSPI communications but I keep getting data-unavailable status on backplane writes. I must have a off-by-one error somewhere.

To solve this as fast and painless as possible I have fast tracked the delivery of a new logic analyzer I bought a couple months ago. The one I'm using now is a Logic Saleae 8 which has 100MHz sampling frequency which is too low to debug the pico-sdk's implementation of the gSPI (they use PIO). The new logic analyzer arrives 6th of March according to DHL. As soon as I get it and my buddy @trippas at work solders some test leads to the pico-w's<->CYW43439 SPI bus I'll be ready to tackle this problem again.

If we're being optimistic I might have it by this months end. But who knows really. I'd really like to have it early march for some things I want to test at work...

We should also get the Netdev2 #3452 PR ready by then which needs some more work

Crocmagnon commented 1 year ago

Supporting Pico W should also lead a long way to supporting Pimoroni Badger 2040 W, which is basically a Badger 2040 with a Pico W and a few other tweaks.

soypat commented 1 year ago

Seeing I gave a few bold statements in my last comment I think a follow up is deserving.

The difficulty of porting the wifi driver was more than I had imagined. Not because the act of porting is hard but because small mistakes can cost a lot of time. Most of the time I have spent developing can be traced to several != that should have been a == in code, or a conversion of a integer that should be LittleEndian, not BigEndian.

That said, today I've reached a major milestone. I have succesfully initialized the on-board wifi chip and controlled the GPIOs on it- which means now users are able to turn the Pico W's LED on and off via TinyGo code.[^A] This also validates most of the IO of the wifi chip.

What remains is implementing the wifi logic. This means porting over lots of functions which make use of the already ported IO. I'll be taking a short break from developing this for now. If anyone is interested in helping out in the effort please reach out at the Gophers Slack .[^B]

[^A]: Link to the blinky example. Note: The initialization duration is around 20 seconds. [^B]: https://invite.slack.golangbridge.org/, find me as Patricio Whittingslow or on the #tinygo-dev channel.

aykevl commented 1 year ago

To solve this as fast and painless as possible I have fast tracked the delivery of a new logic analyzer I bought a couple months ago. The one I'm using now is a Logic Saleae 8 which has 100MHz sampling frequency which is too low to debug the pico-sdk's implementation of the gSPI (they use PIO).

Probably useless advice by now, but the way I usually solve this is by lowering the clock speed. Usually there is a single place where the clock speed is controlled. I would assume there is something similar for PIO.

(I have a Logic 4 which has a sample rate of 25MHz, so can read up to 8MHz or so).

soypat commented 1 year ago

I did take a look around the code but it was not immediately apparent where i could tinker with the baud. Ended up using it as an excuse to get myself my very own logic analyzer 😅

soypat commented 1 year ago

Dropped a bounty for the implementation of Wifi with the pico, was much more than what I could take on. Apparently also needs a lwip like library which I'm unfamiliar with implementations in Go.

cmol commented 1 year ago

Dropped a bounty for the implementation of Wifi with the pico, was much more than what I could take on. Apparently also needs a lwip like library which I'm unfamiliar with implementations in Go.

@soypat What do you have working currently and where can that be found? It might make it easier to scope out what is missing. I think it's unlikely that we will have an implementation of lwip in go, but maybe we can wrap it. I'm not sure if tinygo is wrapping other C libraries currently?

Edit: Seems like it's doable making the initial wrappers: https://github.com/xlab/c-for-go

soypat commented 1 year ago

@cmol It's all in the cyw43439 repo. Issue has more information here: https://github.com/soypat/cyw43439/issues/1.

lwip stand-in can be brought to Go via one of the following:

I am not sure which way would be the best. I'm far from being a Cgo power user. I usually port stuff manually when it's small enough. lwip is 88k lines long... So judging from this data, I think rewriting lwip is out of the question.

But- could it be rewritten from scratch? 88k sounds like a lot but keep in mind we can avoid a lot of complexity in TCP if we stick to the basics. My ether-swtch implementation was once working for the ENC28J60 which let me host http pages on an arduino uno back in the day and thats only 750 lines of code (excluding tests). What's more, there's a rust implementation of TCP in just under 750 lines of code (what a coincidence!), and there's a video series howing how the programmer did it.

So lwip might seem scary- but I think the TCP/ethernet marshaller could prove to be the easiest part of this whole shenanigan since it could be kept as simple as possible and it would be really easy to test (no need for hardware; test on your PC/laptop).

cmol commented 1 year ago

@soypat I think my biggest worry with a rewrite is supporting a full IPv4 and IPv6 stack including all the DHCP / SLAAC stuff. I'm not sure how lwip works though, so the idea of generating wrappers might sound easier than it is.

I'll do some reading on lwip to see if it's possible to wrap it (my guess is that the python implementation does that).

Honestly, Ethernet, IPv6 and UDP would likely be the simple start since we would not need connections or handshakes or anything, but wrapping a well know and maintained lib is likely better in the long run.

timboldt commented 1 year ago

LwIP is a bit of PITA, but it supports three different levels of abstraction - the lowest being a threadless callback model.

I'd also suggest looking at what Earle Philhower did for the Arduino adaptation. He built a shim on top of the CYW43 library:

https://github.com/earlephilhower/arduino-pico/blob/master/libraries/lwIP_CYW43/src/utility/CYW43shim.cpp

soypat commented 1 year ago

Honestly, Ethernet, IPv6 and UDP would likely be the simple start since we would not need connections or handshakes or anything, but wrapping a well know and maintained lib is likely better in the long run.

Wrapping lwip would be very nice. That said, as far as the bounty goes I'd want focus hard on having a solid ethernet interface on the CYW43439, even if it means incomplete TCP support. This would be the first step to having good TCP support- if the ethernet layer is shaky then the TCP can't possibly perform well.

I guess we could organize a bounty to get TCP/UDP/IP up to speed after the current one ends.

Notargets commented 1 year ago

@soypat happy to contribute testing or cgo translation if needed - otherwise I’m cheering your work from the sidelines

marcofeltmann commented 1 year ago

As I did the whole worst-case-of-everything-run the PicoW != Pico just somewhat freaked me out.

Running NixOS and neovim rendered things not working at all:

As @kenbell stated correctly the LED is not GP25 but WL_GPIO0 on the embedded Infineon 43439 wireless chip. In fact I wasn't able to find GP25 on the pinout documentation, thus it may be used for the wireless chip: See https://datasheets.raspberrypi.com/picow/PicoW-A4-Pinout.pdf

So rewriting the Blinky to GP22 with an external LED and tinygo flash --work --target=pico && sudo cp <WORK/main.uf2> ~/usb finally made the LED blink.

For the flashing I'll bring the setup to GopherConEU and we can figure it out.

For the Blinky I'd love to see the --target=picow support with machine.LED := machine.WL_GPIO0 for beginners, so even if things sum up they won't get upset for the non-functional sample.

soypat commented 1 year ago

@marcofeltmann See the cyw43439 library for a blinky on the pico w. We're working on this with @scottfeldman, still needs some more work before it is ready to integrate with tinygo.

Notargets commented 1 year ago

@soypat how’s the TCP + ethernet work going? Need coding help? Is the bounty resolved?

soypat commented 1 year ago

Hey @Notargets! I've put a pause on the TCP+Ethernet work (dgrams) for now until the ethernet interface is up on the CYW43439 which would greatly help me debug it since working with linux TUN/TAP did not work too well for me. If you want to pick it back up feel free to do so, just be aware as soon as cyw43439 driver is finished I plan on going back to work on it again. Think it'd be great to have lots of people working on it since there is separation of concerns between different protocol implementations, we can work in parallel on TCP/IP and ARP without stepping on our toes. So far dgrams consists of decoding/encoding of tcp/ip packets and a non-functional TCP/IP stack.

One thing to note- to facilitate development we will be moving dgrams into its own subpackage withing cyw43439 so we don't have to manage go versions between two separate repos, which I feel would complicate things. If you are willing to help out with TCP/IP, DHCP or any other interesting internet protocol feel free to file an issue under cyw43439/issues so we can plan the development out!

soypat commented 10 months ago

Time for a little update about your favorite microcontroller's wifi chip Go driver!

Switching reference - Bye C, hello Rust

Thanks to some of @scottfeldman 's key insight we've switched References. Initially we were taking inspiration from Damien's cyw43-driver + Pico-SDK mix. This began taking a toll after hitting a certain project size as the source code was hard to follow at times.

It's been barely more than a week since I heard Scott mention the Rust CYW43439 implementation at (embassy-rs) as being "really clean". After taking a look myself it did not take me long to convince myself to switch over to using the rust implementation as the reference- and I can't stress enough how much more easier and pleasant rust is to read than C. Even was able to find a bug in the rust implementation.

You can now find the latest rewrite under the cyrw directory in the repo (stands for CY ReWrite)

Rusty blink

One can run a blinky program using the new version. There's a test program that displays this functionality in action.

Wifi

Since we are switching references we are leaving a lot of progress on the original driver. We had even got the C driver to connect to a wifi network a couple weeks ago!

That said, it's been barely a week with the rust rewrite and we've already made it farther than 2 months in with the original driver. I think we're making the right choice. The new implementation is much easier to follow and has a readable reference, which in itself might not sound like much but I feel there is huge value in it. The rust version is active and is still receiving updates. I've talked with the lead maintainer and the guy is super helpful, even with the most basic of questions. I've asked about everything from basics on generic type instantiation on rust structs all the way to the internals of embassy-rs, and always gotten a quick, helpful response over at the matrix.to channel.

I think there's room to work hand in hand with the rust community to make the best of the Pico W hardware!

Hello... C? Again?!

So... we might not be completely done with C. The rust implementation is great and all but it makes heavy use of asynchronous APIs for Ioctl calls. This can be hard to follow at times since the driver initialization stops being linear. The Rust reference also sometimes takes shortcuts (rarely) and leaves room for questions... in that case we can always recur to the source- the wifi-host-driver.

This is the mother of all drivers- the rust implementation uses it as reference. If I'm not mistaken, even Damien's cyw43-driver is based off the WHD. I've occasionally fallen back to reading the WHD when I'm unsure on how the rust version is doing things.

Vacations / Help wanted

I'm taking a 2 week vacation starting 26 of August and coming back 10 of September. That means that development will slow down by some- it also means things will be more stable.

Dear reader, if you stand to benefit greatly from this driver like myself or anyone who writes embedded Go code and loves cheap, flexible, general purpose compute microcontrollers- consider lending a hand!

Things that help:

I think the bug above may very well be the last "hard" bug left (if it really is the last bug behind ioctl calls). The rest of the rust driver is pretty straightforward and simple, relying on the ioctl calls as the backbone of all communications.

soypat commented 9 months ago

Time for a little update-

It's alive

After a very succesful bughunt led by @scottfeldman, we now have a fully functional Ethernet interface working on the Pico W #14-- both as a wifi client and with access point functionality (#18) (again, thanks @scottfeldman).

We have implemented our own lightweight IP stack with working DHCP over UDP support (17) and have a working TCP socket (#19) implementation which still needs stateful logic.

What does this mean?

It is not done. This still cannot be used for solving problems as the APIs are still experimental and subject to change. What can be done is testing! @cmol has been lending a hand by running the DHCP client example (info below) and actually found that the same program that does not crash for us crashes for him. It'd be interesting to see if others can start testing with their own Tinygo+PicoW setup to see if there are any latent bugs.

Steps going forward

I'm quite busy the coming weeks preparing for Gophercon 2023 where I'll be giving a talk so it might be a couple weeks before I can resume work.

@scottfeldman will be working on adding more functionality to the Pico W, so that would include like Wifi Scan and any remaining AP/STA functionality we are missing.

Click to see more on the DHCP example ### More on the DHCP example NOTE: You have to add a `secret.go` file based on the template file in the directory with your wifi credentials for the program to work! Flash the [DHCP example](https://github.com/soypat/cyw43439/tree/main/examples/dhcp) by running ``` tinygo flash -monitor -target pico -stack-size=8kb -size short ./examples/dhcp/ ``` This will attach your terminal to the pico W and you'll see a lot of logs printed out. Look for the one that says: ``` ======== DHCP done, your IP: 192.168.1.145 ======== ``` After that the Pico W will turn on it's LED every time it receives a packet. You can try running `ping` linux/windows utility from terminal to turn on the LED: ``` $ ping 192.168.1.145 PING 192.168.1.145 (192.168.1.145) 56(84) bytes of data. From 192.168.1.147 icmp_seq=1 Destination Host Unreachable From 192.168.1.147 icmp_seq=2 Destination Host Unreachable From 192.168.1.147 icmp_seq=3 Destination Host Unreachable From 192.168.1.147 icmp_seq=5 Destination Host Unreachable From 192.168.1.147 icmp_seq=6 Destination Host Unreachable ^C --- 192.168.1.145 ping statistics --- 7 packets transmitted, 0 received, +5 errors, 100% packet loss, time 6143ms pipe 4 ``` The pico W will not respond to ping packets, but will flash it's LED.
deadprogram commented 9 months ago

This is incredible progress thank you so much @soypat and @scottfeldman :heart_eyes:

trichner commented 9 months ago

First off: Amazing work! This is a dream come true.

I've done the least I can do and tried the DHCP sample.

Works for me! :partying_face:

Logs & Details

```shell ~/w/cyw43439 (main)> tinygo version tinygo version 0.29.0 linux/amd64 (using go version go1.20.7 and LLVM version 16.0.6) ~/w/cyw43439 (main)> tinygo flash -monitor -target pico -stack-size=8kb -size short ./examples/dhcp/ code data bss | flash ram 368508 2832 6440 | 371340 9272 Connected to /dev/ttyACM0. Press Ctrl-C to exit. starting program INFO Init:start slog.Level=DEBUG DEBUG read back bus ctl got=177 DEBUG current bus ctl00010030writing:000300b1 got:feedbead DEBUG flashing firmware chip_id=43439 fwlen=230321 DEBUG bp_write addr=0 last16=442030312d39353536366436612d30f0 DEBUG bp_write:done status=no status DEBUG flashing nvram DEBUG bp_write addr=523540 last16=006274635f6d6f64653d31000000636f DEBUG bp_write:done status=no status DEBUG core up CY43 hndarm_armr addr: 0x18003000, cr4_idx: 0 CY43 000000.001 CY43 RTE (SDIO-CDC) 7.95.62 (b03806e CY) on BCM43439 r5 @ 37.4/81.6/81.6MHz CY43 000000.003 sdpcmdcdc0: Broadcom SDPCMD CDC driver CY43 000000.008 reclaim section 0: Returned 46156 bytes to the heap CY43 000000.012 wlc_bmac_info_init: host_enab 1 CY43 000000.037 wl0: wlc_ampdu_tx_set: AGG Mode = MAC+Ucode txmaxpkts 64 txmaxpkts_agg 0 CY43 000000.048 wl0: wlc_channels_commit: no valid channel for "#n" nbands 1 bandlocked 0 CY43 000000.053 wl0: Broadcom BCM43439 802.11 Wireless Controller 7.95.62 (b03806e CY) CY43 000000.055 TCAM: 256 used: 77 exceed:0 CY43 000000.058 reclaim section 1: Returned 86104 bytes to the heap DEBUG base init done DEBUG initControl clm_len=4752 DEBUG sendIoctl kind=2 cmd=SET_VAR len=1044 DEBUG rx len=256 hdr=asyncev ERROR rxEvent err=BDC header invalid length plen=244 bdc=&{Flags:179 Priority:68 Flags2:104 DataOffset:192} event=&{EthHeader:{Destination:[0 0 0 0 0 0] Source:[0 0 0 0 0 0] SizeOrEtherType:0} EventHeader:{Subtype:0 Length:0 Version:0 OUI:[0 0 0] UserSubtype:0} Message:{Version:0 Flags:0 EventType:SET_SSID Status:0 Reason:0 AuthType:0 DataLen:0 Addr:[0 0 0 0 0 0] IFName:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] IFIdx:0 BSSCfgIdx:0}} ERROR rx err=BDC header invalid length DEBUG tryPoll:ignore_spurious err=BDC header invalid length DEBUG rx len=256 hdr=asyncev ERROR rxEvent err=BDC header invalid length plen=244 bdc=&{Flags:179 Priority:68 Flags2:104 DataOffset:192} event=&{EthHeader:{Destination:[0 0 0 0 0 0] Source:[0 0 0 0 0 0] SizeOrEtherType:0} EventHeader:{Subtype:0 Length:0 Version:0 OUI:[0 0 0] UserSubtype:0} Message:{Version:0 Flags:0 EventType:SET_SSID Status:0 Reason:0 AuthType:0 DataLen:0 Addr:[0 0 0 0 0 0] IFName:[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] IFIdx:0 BSSCfgIdx:0}} ERROR rx err=BDC header invalid length DEBUG tryPoll:ignore_spurious err=BDC header invalid length DEBUG rx len=1072 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=1044 DEBUG rx len=1072 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=1044 DEBUG rx len=1072 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=1044 DEBUG rx len=1072 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=676 DEBUG rx len=704 hdr=ctl DEBUG clmload:done DEBUG sendIoctl kind=0 cmd=GET_VAR len=15 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=15 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=10 DEBUG rx len=258 hdr=ctl DEBUG sendIoctl kind=0 cmd=GET_VAR len=14 DEBUG rx len=258 hdr=ctl DEBUG MAC mac=28:cd:c1:06:ce:27 DEBUG sendIoctl kind=2 cmd=SET_VAR len=20 DEBUG rx len=256 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_ANTDIV len=4 DEBUG rx len=256 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=15 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=19 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=15 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=46 DEBUG rx len=258 hdr=ctl DEBUG sendIoctl kind=2 cmd=UP len=0 DEBUG rx len=256 hdr=ctl CY43 000001.495 wl0: wl_open DEBUG sendIoctl kind=2 cmd=SET_GMODE len=4 DEBUG rx len=256 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_BAND len=4 DEBUG rx len=256 hdr=ctl DEBUG set_power_management mode=PowerSave DEBUG sendIoctl kind=2 cmd=SET_VAR len=18 DEBUG rx len=258 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=15 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=17 DEBUG rx len=257 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_PM len=4 DEBUG rx len=256 hdr=ctl INFO joinWpa2 ssid=Haakon len(pass)=12 DEBUG sendIoctl kind=2 cmd=SET_VAR len=19 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_WSEC len=4 DEBUG rx len=256 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=23 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=31 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_VAR len=27 DEBUG rx len=259 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_WSEC_PMK len=68 DEBUG rx len=256 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_INFRA len=4 DEBUG rx len=256 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_AUTH len=4 DEBUG rx len=256 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_WPA_AUTH len=4 DEBUG rx len=256 hdr=ctl DEBUG sendIoctl kind=2 cmd=SET_SSID len=36 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=asyncev DEBUG rx len=260 hdr=asyncev INFO rxEvent:success event=AUTH DEBUG rx len=259 hdr=asyncev DEBUG rx len=261 hdr=asyncev DEBUG rx len=258 hdr=asyncev DEBUG rx len=260 hdr=asyncev DEBUG rx len=260 hdr=asyncev DEBUG rx len=258 hdr=asyncev INFO rxEvent:success event=SET_SSID MAC: 28:cd:c1:06:ce:27 CY43 000005.124 wl0: link up (wl0) Trying DoDHCP INFO HandleEth dstlen=1500 DEBUG tx len=590 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 DEBUG rx len=364 hdr=data DEBUG Stack.RecvEth:start plen=342 INFO UDP packet stored plen=300 INFO HandleEth dstlen=1500 DEBUG tx len=590 DEBUG rx len=365 hdr=data DEBUG Stack.RecvEth:start plen=343 INFO UDP packet stored plen=301 DHCP did not complete, state=2 DEBUG rx len=260 hdr=data DEBUG Stack.RecvEth:start plen=86 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 Trying DoDHCP INFO HandleEth dstlen=1500 DEBUG tx len=590 DEBUG rx len=364 hdr=data DEBUG Stack.RecvEth:start plen=342 INFO UDP packet stored plen=300 INFO HandleEth dstlen=1500 DEBUG tx len=590 DEBUG rx len=365 hdr=data DEBUG Stack.RecvEth:start plen=343 INFO UDP packet stored plen=301 INFO HandleEth dstlen=1500 ======== DHCP done, your IP: 192.168.16.143 ======== finished init OK INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=265 hdr=data DEBUG Stack.RecvEth:start plen=243 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=92 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=92 DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=92 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=258 hdr=data DEBUG Stack.RecvEth:start plen=60 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl DEBUG rx len=260 hdr=data DEBUG Stack.RecvEth:start plen=86 INFO GPIOSet wlGPIO=0 value=true DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl INFO GPIOSet wlGPIO=0 value=false DEBUG sendIoctl kind=2 cmd=SET_VAR len=16 DEBUG rx len=256 hdr=ctl ```

scottfeldman commented 9 months ago

Go @soypat! Nice job on the DEBUG output, love it. slog rocks.

soypat commented 6 months ago

TCP is working with reconnection! https://github.com/soypat/cyw43439/pull/24#issuecomment-1846480418

To run clone the repo and edit the examples/tcpserver/secrets.go.template file:

git clone git@github.com:soypat/cyw43439.git
cd cyw43439
# Edit the `secrets.go.template` file betwixt these steps!
tinygo flash -target=pico -opt=1 -stack-size=8kb -size=short -monitor ./examples/tcpserver/

Please, please PLEASE load all issues related to the wifi chip or the TCP stack in the cyw43439 issue tracker or the seqs issue tracker!

I'm leaving a program to help y'all test the TCP stack:

TCP Client (click to show) ```go // Modify IP below to match the one assigned by DHCP! package main import ( "fmt" "net" "net/netip" "time" ) func main() { const server = "192.168.1.120:1234" // Edit this to match the result of the DHCP Request. Leave the :1234 there though! raddr := netip.MustParseAddrPort(server) conn, err := net.DialTCP("tcp", nil, net.TCPAddrFromAddrPort(raddr)) if err != nil { panic(err) } // wait a second for SYN/ACK stuff. time.Sleep(time.Second) dd := make([]byte, 1024) go func() { for { time.Sleep(time.Second) n, err := conn.Read(dd) if err != nil { fmt.Println("rerr", err.Error()) } if n > 0 { fmt.Printf("read %q\n", string(dd[:n])) } } }() for { _, err = conn.Write([]byte("hello")) if err != nil { fmt.Println("werr", err.Error()) } time.Sleep(time.Second) } } ```
trichner commented 6 months ago

Gave it a quick try, echo works! Amazing stuff!

tcp

Logs

``` ... start listening on: 192.168.16.143:1234 time=1970-01-01T00:00:18.877Z level=DEBUG msg=ARP:recv op=2 time=1970-01-01T00:00:18.878Z level=DEBUG msg=ARP:send isReply=true time=1970-01-01T00:00:36.064Z level=DEBUG msg=ARP:recv op=2 time=1970-01-01T00:00:36.065Z level=DEBUG msg=ARP:send isReply=true time=1970-01-01T00:00:36.115Z level=DEBUG msg=TCP:recv opt=20 ipopt=0 payload=0 time=1970-01-01T00:00:36.116Z level=INFO msg=TCP:rx-statechange port=1234 old=SynSent new=SynRcvd rxflags=[SYN] time=1970-01-01T00:00:36.117Z level=DEBUG msg=TCP:send plen=54 time=1970-01-01T00:00:36.170Z level=DEBUG msg=TCP:recv opt=0 ipopt=0 payload=0 time=1970-01-01T00:00:36.170Z level=INFO msg=TCP:rx-statechange port=1234 old=SynRcvd new=Established rxflags=[ACK] time=1970-01-01T00:00:42.452Z level=DEBUG msg=TCP:recv opt=0 ipopt=0 payload=3 time=1970-01-01T00:00:42.453Z level=DEBUG msg=TCP:send plen=54 time=1970-01-01T00:00:42.455Z level=DEBUG msg=TCP:send plen=57 time=1970-01-01T00:00:42.507Z level=DEBUG msg=TCP:recv opt=0 ipopt=0 payload=0 time=1970-01-01T00:00:42.508Z level=DEBUG msg=TCP:send plen=54 time=1970-01-01T00:00:48.486Z level=DEBUG msg=TCP:recv opt=0 ipopt=0 payload=13 time=1970-01-01T00:00:48.487Z level=DEBUG msg=TCP:send plen=54 time=1970-01-01T00:00:48.488Z level=DEBUG msg=TCP:send plen=67 time=1970-01-01T00:00:48.541Z level=DEBUG msg=TCP:recv opt=0 ipopt=0 payload=0 time=1970-01-01T00:00:48.542Z level=DEBUG msg=TCP:send plen=54 ```

soypat commented 6 months ago

HTTP is now supported (here's a video on TinyGo slack channel) and here's the code. Note that the method of setting wifi credentials has changed- see the README for more information.

Bluetooth is still not being worked on at the time being.

rgerardi commented 6 months ago

Tested the HTTP example on my Pico W and it's working nicely. This is great stuff @soypat !

Kytech commented 4 months ago

Bluetooth is still not being worked on at the time being.

It it safe to say that the most straightforward option for implementing bluetooth on the pico would be to do something similar as what has been done with the nordic semi bluetooth chipsets in tinygo/bluetooth where we just wrap an existing certified bluetooth stack's C headers? If I recall right, the pi foundation indicated that they negotiated a license deal with the bluetooth stack they use for the pico W so that pi pico owners (business or individual) don't need to purchase a separate license for commercial use, so I don't see much of a disadvantage of wrapping that certified stack.

I might be working on a project in the near-ish future on the pico W where I'd like to get tinygo with bluetooth running on the board, so if that does happen, I'd be happy to contribute back any work if I do continue down that route.

soypat commented 4 months ago

@Kytech The first step would be to implement the low level unexported functions in cyw43439 for bluetooth control. We can take inspiration from cyw43 repository to implement these since I don't think there's a Rust version yet :disappointed: . I'm not familiar enough with the tinygo/bluetooth internals, but I guess we could then choose to wrap the API with it?

Kytech commented 4 months ago

@soypat makes sense. I am thinking we'd wrap the low-level implementation with the high-level APIs exposed by TinyGo, based on what I've seen from the tinygo/bluetooth repo's codebase. I'll have to see if there's any progress on a rust version by the time I am looking into this. Thanks for the info!