The WiFi chips on the Raspberry Pi boards are from the Broadcom BCM43xxx range, which has been taken over by Cypress, and renamed CYW43xxx. The Pi ZeroW uses the CYW43438, the PDF data sheet is here.
The obvious starting point for creating a new driver is the existing Linux driver, known as ‘Broadcom Full MAC’, or BRCMFMAC. The source is available here.
A more recent driver is included in the Cypress WICED development system. This is based on Eclipse, and is very comprehensive, covering a wide range of wireless chips and functionality.
A more compact version of the code is available as the Cypress Wifi Host Driver, which is intended for integration in real-time systems.
Another (highly unusual) WiFi driver is available for the Plan9 operating system, contained within a single file ether4330.c. This has a large number of unconventional operating-system dependencies, and would require significant modifications to run on a bare-metal platform, but is interesting as the author has succeeded in creating some remarkably compact code.
To see an example of an SPI interface with a CYW43439, take a look at my Zerowi standalone driver for the Raspberry Pi Pico W here.
It is great to have such a range of source-code available, but in practice it has been of minimal use in this project; even the simplest versions are exceedingly complex, with hidden dependencies & timing issues, so rather than simplifying existing code, I have written all the code from scratch.
Documentation on the Broadcom/Cypress chips is very limited; the data sheet gives minimal information about the chip internals. There is a programming manual, but that only available from Cypress under a confidentiality agreement. I haven’t had access to that document, as it would place severe restrictions on what I can write in this blog. So I have just used freely-available information, logic analysis, and a lot of trial-and-error.
With regard to a logic analyser, the requirements for this project are a bit demanding. The Raspberry Pi ZeroW takes nearly a minute to boot, so a recording of the hardware activity will be quite long, overflowing the memory of most logic analysers. So it is necessary to using a ‘streaming’ analyser, that can send data continuously to a PC’s hard disk; I’ve been using the DSLogic Basic from DreamSourceLab, as it can stream 8-bit values at 20 megasamples per second, and has an easy-to-use GUI based on Sigrok, but a simpler device streaming 10 megasamples per second might be adequate for most analysis tasks.
Sigrok pulseview (the open-source logic analyser GUI) has a built-in Secure Digital (SD) decoder, but this is of limited use on the Secure Digital I/O (SDIO) interface of the Broadcom/Cypress chips, so for analysis I export the data as a very large CSV file (over 5 gigabytes!), then use my own software tools written in the C language to analyse it – Python would be much too slow.
A variant of this analysis code has been used to draw the logic analyser diagrams for this blog – they are all derived from real-world data.
The data analysis tools run on a Windows PC, and have been compiled using gcc 7.4.0 or 8.2.0 from the cygwin project. I suspect the code would also run under Linux with minimal modifications, but haven’t had the time to try this out. The programs can be compiled directly from the command-line, e.g. to produce sd_decoder.exe:
gcc -Wall -o sd_decoder sd_decoder.c
If you want to understand the SDIO interface, the specifications are essential reading; they are available at the SD Association.
My source code is at https://github.com/jbentham/zerowi
Copyright (c) Jeremy P Bentham 2020. Please credit this blog if you use the information or software in it.
2 thoughts on “Zerowi bare-metal WiFi driver part 1: resources”
Hi, I’m the author of the Plan 9 ether4330 driver. In fact I had no access to any information or documentation about the chip; I worked only from the source code of the linux brcmfmac driver. If my version is compact, it’s because I ruthlessly stripped out all the verbosity of the linux driver which interleaves support for a whole family of different chips with different transport mechanisms. If you focus only on the specific configuration used on the Pi, it’s easier to make sense of. Some of the linux code was just too complex for me to follow by static analysis, so like you I did some experiments to look at the traffic between host and wifi chip. I did this at a high level, not with a logic analyser (don’t have one) but by instrumenting the linux driver to dump its sequence of commands to the system log, for example while initialising the chip and loading firmware.
Very impressive; I’m not really into Linux device drivers, so personally found the logic analyser approach easier, but it looks like I’m following a similar path to you – I’ll update my blog entry.
One question; can you say how much testing your code has gone through, e.g. high-speed and high-volume tests, to check for memory leaks or other stability problems? It’d be a shame if I more-or-less replicated what you’ve done, only to find that my code has the same problems as yours.