Open efectn opened 2 years ago
Hmm? Maybe we need PIO support first?
https://github.com/raspberrypi/pico-sdk/tree/master/src/rp2_common/cyw43_driver
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:
picow
?)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.
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
I've got a couple of Pico W here as well. Ready to help testing
Is someone already working on this?
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.
Does the introduction of the Pico W warrant a separate page from the current Pico page (https://tinygo.org/docs/reference/microcontrollers/pico/)?
Seems that still the Wifi module of raspberry pi pico is not supported. Any plans to implement this?
is it plan to be supported this year ?
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".
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
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.
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.
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).
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 😅
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.
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
@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).
@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.
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:
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.
@soypat happy to contribute testing or cgo translation if needed - otherwise I’m cheering your work from the sidelines
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:
tinygo build --target=pico
producing hello.elf
outputtinygo flash --target=pico
was unable to shift it over the Pico on NixOS due to whatevertinygo flash --work --target=pico && sudo cp <WORK/main.uf2> ~/usb
did the trick, but no blinking LEDAs @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.
@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.
@soypat how’s the TCP + ethernet work going? Need coding help? Is the bounty resolved?
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!
Time for a little update about your favorite microcontroller's wifi chip Go driver!
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)
One can run a blinky program using the new version. There's a test program that displays this functionality in action.
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!
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.
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:
Reading through the code and comparing with the reference for any differences. This is without a doubt the most helpful task one can do:
bus.go
- if one opens this file one can find links to the reference implementations. Most Go functions have similar, if not identical names to their rust counterpart (yes, even snake_case identifiers!)Porting code! Not all functions have been written. There's some low hanging fruits, like AP functions such as start_ap
.
This last month has been hard- but switching from reading C to reading rust has given me a second wind of sorts. From what I can tell we are very near from being able to send and receive ethernet packets with the rust rewrite.
By looking at the data on the bus there seems to be differences between what we read over the wlan interface. This could be due to non-reproducibility... that said we are not reading Async packets correctly, so there's likely a bug somewhere there. This could be happening anywhere between wlan_read
and check_status
... but that's anyone's guess
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.
Time for a little update-
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.
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.
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.
This is incredible progress thank you so much @soypat and @scottfeldman :heart_eyes:
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:
```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 ```
Go @soypat! Nice job on the DEBUG output, love it. slog rocks.
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:
.template
part of the extension so it's a normal Go filegit 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:
Gave it a quick try, echo works! Amazing stuff!
``` ... 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 ```
Tested the HTTP example on my Pico W and it's working nicely. This is great stuff @soypat !
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.
@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?
@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!
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/