Bare metal BCM43438 Driver
Hi,
I aim to port bare metal wifi driver for bcm43438. I did search in raspberrypi/linux repository but couldn't find any mention of bcm43438. Can any one point me to the correct source? I checked net/wireless/broadcom/ directory.
I aim to port bare metal wifi driver for bcm43438. I did search in raspberrypi/linux repository but couldn't find any mention of bcm43438. Can any one point me to the correct source? I checked net/wireless/broadcom/ directory.
Let there be some light .../\...
Re: Bare metal BCM43438 Driver
Brcmfmac is the driver used for all the Cypress chips. The particular chip type is handled by the firmware that is loaded onto them at boot.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.
Re: Bare metal BCM43438 Driver
The Ultibo guys have managed to get Bluetooth working by loading the Cypress binary blobs.
Two versions, one for the older chip, one for the new P3A/B+ RF combo chip.
WiFi is harder to do, something about crypto?
The fun part was getting a Microbit talking to the PI vi BT.
https://ultibo.org/forum/viewtopic.php? ... ooth#p8638
The priority is high to get WiFi working and Garry and co may be able to do it but it is not simple
https://ultibo.org/wiki/Current_Status
I am unaware if anyone has got WiFi working in baremetal, apart from some USB dongles or UART versions.
Two versions, one for the older chip, one for the new P3A/B+ RF combo chip.
WiFi is harder to do, something about crypto?
The fun part was getting a Microbit talking to the PI vi BT.
https://ultibo.org/forum/viewtopic.php? ... ooth#p8638
The priority is high to get WiFi working and Garry and co may be able to do it but it is not simple
https://ultibo.org/wiki/Current_Status
I am unaware if anyone has got WiFi working in baremetal, apart from some USB dongles or UART versions.
I'm dancing on Rainbows.
Raspberries are not Apples or Oranges
Raspberries are not Apples or Oranges
Re: Bare metal BCM43438 Driver
I suspect that porting brcmfmac was just too much, it's a lot of spagetti code. Not aware of any crypto in there that might be problematic.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.
Re: Bare metal BCM43438 Driver
I understand it to be the handling of WEP/WPA/WPA2 in establishing a connection which is the challenge as it's a lot of work with few resources to do that. So an issue within the protocol stack rather than with the firmware or chip.
Ultibo took the decision that WiFi will be 'all or nothing' and do not intend to provide an implementation which would work but only with unsecured access points.
Ultibo is wired ethernet only for now. If one wants WiFi that has to be through a mini-router or similar, or via an ESP add-on. Unfortunately that means the Zero W and the 3A+ can't be used how it would be desirable to use them; standalone using WiFi.
Re: Bare metal BCM43438 Driver
Thanks all for the replies. I will at least read the code and understand how it works.
Let there be some light .../\...
Re: Bare metal BCM43438 Driver
Guys is it feasible to copy all the object files related to wifi driver from linux build and create static library and use it in bare metal projects?
We can provide implementations of functions which are called from linux WiFi driver.
We can provide implementations of functions which are called from linux WiFi driver.
Let there be some light .../\...
-
- Posts: 16
- Joined: Fri Aug 03, 2012 6:34 pm
Re: Bare metal BCM43438 Driver
Its probably a lot easier to just reimplement the driver to fit your OS.
However there is very little documentation about the module and despite my driver for the arasan controller working fine and the commands being transmitted on the wire, for some reason the chip does not respond to any SDIO command I send it.
Does it need some other clock or so?
PS: I am working on the BCM43430A1 on the Pi Zero W but I assume Rpi3+ will be similar.
However there is very little documentation about the module and despite my driver for the arasan controller working fine and the commands being transmitted on the wire, for some reason the chip does not respond to any SDIO command I send it.
Does it need some other clock or so?
PS: I am working on the BCM43430A1 on the Pi Zero W but I assume Rpi3+ will be similar.
Re: Bare metal BCM43438 Driver
Is it the same driver as implemented by LdB here https://github.com/LdB-ECM/Raspberry-Pi ... r/SD_FAT32.Thalhammer wrote: ↑Wed Jul 31, 2019 12:09 pmdespite my driver for the arasan controller working fine
Do you have any reference documentation to start with Wifi driver?
EDIT:
I am very much interested in reimplantation but I fear I do not have understanding of wifi stack. I think it needs WPA implementations as well.
Let there be some light .../\...
-
- Posts: 16
- Joined: Fri Aug 03, 2012 6:34 pm
Re: Bare metal BCM43438 Driver
No its a custom implementation to fit my OS (I write a C++ RTOS, so no userspace etc and class oriented) but his code was one of the references I used.
The only things I currently have is the datasheet of the chip (very little usefull information), the official brcmfmac source of the linux driver and a dump of the traffic between module and kernel on boot.
However I didn't find a clk line, so the official saleae sdio analyser does not work and my attempts at a custom analyser which uses the edges on the commandline to detect clockspeed were not really successful, so that dump is not really that useful.
I never implemented WPA and so on but I did some work with injecting wifi frames from linux in the past so I know the basics.
Also I think there is a chance that you won't even have to deal with it (I.e. it is handled by the broadcom chip, I read that there is more or less a complete wifi stack in the firmware but I dont know if it is used by linux).
I tried to copy the init sequence used by linux but for some reason the card does not respond to any sdio command I send (they all timeout).
The basics is the following:
WL_ON needs to be high (gpio41 on pizerow).
Arasan is configured on pin 34-39 and uses 4 bit mode with 400kHz Operation during init and 25MHz during actual transmission.
I did not get anything working (yet) and moved on to some other projects with more information (Videocore and Bluetooth stack) to get my head free.
if you manage to get anything working feel free to share code or if you need help I am happy to help.
The only things I currently have is the datasheet of the chip (very little usefull information), the official brcmfmac source of the linux driver and a dump of the traffic between module and kernel on boot.
However I didn't find a clk line, so the official saleae sdio analyser does not work and my attempts at a custom analyser which uses the edges on the commandline to detect clockspeed were not really successful, so that dump is not really that useful.
I never implemented WPA and so on but I did some work with injecting wifi frames from linux in the past so I know the basics.
Also I think there is a chance that you won't even have to deal with it (I.e. it is handled by the broadcom chip, I read that there is more or less a complete wifi stack in the firmware but I dont know if it is used by linux).
I tried to copy the init sequence used by linux but for some reason the card does not respond to any sdio command I send (they all timeout).
The basics is the following:
WL_ON needs to be high (gpio41 on pizerow).
Arasan is configured on pin 34-39 and uses 4 bit mode with 400kHz Operation during init and 25MHz during actual transmission.
I did not get anything working (yet) and moved on to some other projects with more information (Videocore and Bluetooth stack) to get my head free.
if you manage to get anything working feel free to share code or if you need help I am happy to help.
Re: Bare metal BCM43438 Driver
Thalhammer wrote: ↑Wed Jul 31, 2019 4:32 pmNo its a custom implementation to fit my OS (I write a C++ RTOS, so no userspace etc and class oriented) but his code was one of the references I used.
The only things I currently have is the datasheet of the chip (very little usefull information), the official brcmfmac source of the linux driver and a dump of the traffic between module and kernel on boot.
However I didn't find a clk line, so the official saleae sdio analyser does not work and my attempts at a custom analyser which uses the edges on the commandline to detect clockspeed were not really successful, so that dump is not really that useful.
I never implemented WPA and so on but I did some work with injecting wifi frames from linux in the past so I know the basics.
Also I think there is a chance that you won't even have to deal with it (I.e. it is handled by the broadcom chip, I read that there is more or less a complete wifi stack in the firmware but I dont know if it is used by linux).
I tried to copy the init sequence used by linux but for some reason the card does not respond to any sdio command I send (they all timeout).
The basics is the following:
WL_ON needs to be high (gpio41 on pizerow).
Arasan is configured on pin 34-39 and uses 4 bit mode with 400kHz Operation during init and 25MHz during actual transmission.
I did not get anything working (yet) and moved on to some other projects with more information (Videocore and Bluetooth stack) to get my head free.
if you manage to get anything working feel free to share code or if you need help I am happy to help.
Can you post the link of linux code and chip datasheet?
Where did you find information regarding broadcomm chip firmware for WiFi?
It will be super easy if we can leverage that
Let there be some light .../\...
-
- Posts: 16
- Joined: Fri Aug 03, 2012 6:34 pm
Re: Bare metal BCM43438 Driver
Broadcoms WIFI division was bought by Cypress and the provide some of the documentation. You can find the datasheet here:
https://www.cypress.com/file/298706/download
Linux driver is called brcmfmac and its source is here:
https://github.com/torvalds/linux/tree/ ... 1/brcmfmac
https://www.cypress.com/file/298706/download
Linux driver is called brcmfmac and its source is here:
https://github.com/torvalds/linux/tree/ ... 1/brcmfmac
Re: Bare metal BCM43438 Driver
Thalhammer wrote: ↑Thu Aug 01, 2019 8:15 pmBroadcoms WIFI division was bought by Cypress and the provide some of the documentation. You can find the datasheet here:
https://www.cypress.com/file/298706/download
Linux driver is called brcmfmac and its source is here:
https://github.com/torvalds/linux/tree/ ... 1/brcmfmac
I see this post https://www.raspberrypi.org/forums/view ... 4#p1306878 which says RPI3B uses CYW43438 chip not CYW4334X.
Edit:
Github issues which mention RPI3 WiFi chip:
https://github.com/raspberrypi/firmware/issues/784 ==> CYW43438 indentifies itself as CYW43430 hence no mention of BCM43438 in any of the driver source code.
https://github.com/raspberrypi/linux/issues/2485
Binary closed source firmware is loaded in chip to provide low level functionality.
Does anyone know how is this binary firmware loaded to Wifi chip? I don;t see any SDIO start up sequence in brcmfmac driver source code.
Let there be some light .../\...
Re: Bare metal BCM43438 Driver
The SDIO code is separated in Linux from the Wi-Fi driver code in the MMC subsystem.
Re: Bare metal BCM43438 Driver
@Thalhammer
Do you know how to load firmware in the chip? Is there any documentation on how to use wifi over SDIO? Datasheet talks about boot up sequence for gSPI interface in detail but none for SDIO.
https://github.com/torvalds/linux/blob/ ... dio.c#L592 Is the the command sequence are you trying to start wifi 3v3 mode?
If you could post the code you were trying it will be helpful.
Thanks
Do you know how to load firmware in the chip? Is there any documentation on how to use wifi over SDIO? Datasheet talks about boot up sequence for gSPI interface in detail but none for SDIO.
https://github.com/torvalds/linux/blob/ ... dio.c#L592 Is the the command sequence are you trying to start wifi 3v3 mode?
If you could post the code you were trying it will be helpful.
Thanks
Let there be some light .../\...
-
- Posts: 16
- Joined: Fri Aug 03, 2012 6:34 pm
Re: Bare metal BCM43438 Driver
Sorry for the late reply.
I only tracked it in digital mode, but as far as I know the 1.8v mode on the rpi is broken so I assume its 3.3v.
BCM43430 = CYW43430 because Cypress bought Broadcom's wifi division and changed the names.
I mostly have a proof of concept/testbed I use to toy around with it, but no real code.
I only try to replicate the commands sent by the linux driver.
I only tracked it in digital mode, but as far as I know the 1.8v mode on the rpi is broken so I assume its 3.3v.
BCM43430 = CYW43430 because Cypress bought Broadcom's wifi division and changed the names.
I mostly have a proof of concept/testbed I use to toy around with it, but no real code.
I only try to replicate the commands sent by the linux driver.
Re: Bare metal BCM43438 Driver
I had forgotten about this thread but by weird events I ran across this yesterday which may be of some help
https://blog.quarkslab.com/reverse-engi ... psets.html
https://blog.quarkslab.com/reverse-engi ... psets.html
-
- Posts: 16
- Joined: Fri Aug 03, 2012 6:34 pm
Re: Bare metal BCM43438 Driver
While its a pretty interesting read, I don't think its of much use for us, as there is no information in the sdio communication with the host.
Maybe we could instrument the linux driver with more logging and check it using this way ?
Or is there some kernel option to dump all sdio traffic ?
Maybe we could instrument the linux driver with more logging and check it using this way ?
Or is there some kernel option to dump all sdio traffic ?
Re: Bare metal BCM43438 Driver
I dumped 2 types of bcm43438 sdio traffic .Thalhammer wrote: ↑Fri Aug 16, 2019 10:03 pmMaybe we could instrument the linux driver with more logging and check it using this way ?
Or is there some kernel option to dump all sdio traffic ?
1. add some debug print to drivers/mmc/core/sdio_ops.c and core.c.
https://github.com/eggman/raspberrypi/b ... io_log.txt
2. brcmfmac driver have trace option. enable BRCM_TRACING in kernel config file.
https://github.com/eggman/raspberrypi/b ... ce_log.txt
And I write some baremetal sdio code. but not test on real hardware. I only tested my modified qemu.
https://github.com/eggman/raspberrypi/t ... pi3/sdio03
Re: Bare metal BCM43438 Driver
Hey can you share your steps. I built brcmfmac kernel module, but if failed while loading .ko file using insmod with error "invalid symbol found".eggmansan wrote: Sat Aug 17, 2019 3:33 am
Maybe we could instrument the linux driver with more logging and check it using this way ?
Or is there some kernel option to dump all sdio traffic ?
I dumped 2 types of bcm43438 sdio traffic .
1. add some debug print to drivers/mmc/core/sdio_ops.c and core.c.
https://github.com/eggman/raspberrypi/b ... io_log.txt
2. brcmfmac driver have trace option. enable BRCM_TRACING in kernel config file.
https://github.com/eggman/raspberrypi/b ... ce_log.txt
And I write some baremetal sdio code. but not test on real hardware. I only tested my modified qemu.
https://github.com/eggman/raspberrypi/t ... pi3/sdio03
Code: Select all
uname -r
4.19.66-v7l+
Code: Select all
git clone --depth=1 --branch rpi-4.19.y https://github.com/raspberrypi/linux
I tried compiling using
Code: Select all
make -j4 modules
Let there be some light .../\...
Re: Bare metal BCM43438 Driver
Not bare metal strictly speaking, but the Plan 9 driver is another alternative example you might want to look at for information. It's under 2400 lines of C, so it should be a bit easier to follow than the Linux brcmfmac driver. To write the Plan 9 driver without a device spec, I had to read all the brcmfmac code which is a 32,000+ line spaghetti of support for multiple chips and interface methods: not an experience I would recommend for pleasure.
Plan 9 driver source is at https://9p.io/sources/contrib/miller/9/bcm/ether4330.c, depends on the emmc driver (another 529 lines) in https://9p.io/sources/contrib/miller/9/bcm/emmc.c for sdio support.
Plan 9 driver source is at https://9p.io/sources/contrib/miller/9/bcm/ether4330.c, depends on the emmc driver (another 529 lines) in https://9p.io/sources/contrib/miller/9/bcm/emmc.c for sdio support.
Re: Bare metal BCM43438 Driver
Thank you sir. I think it will help me writing small driver for this sdio wifi chip.9pi wrote: ↑Tue Aug 27, 2019 1:12 pmNot bare metal strictly speaking, but the Plan 9 driver is another alternative example you might want to look at for information. It's under 2400 lines of C, so it should be a bit easier to follow than the Linux brcmfmac driver. To write the Plan 9 driver without a device spec, I had to read all the brcmfmac code which is a 32,000+ line spaghetti of support for multiple chips and interface methods: not an experience I would recommend for pleasure.
Plan 9 driver source is at https://9p.io/sources/contrib/miller/9/bcm/ether4330.c, depends on the emmc driver (another 529 lines) in https://9p.io/sources/contrib/miller/9/bcm/emmc.c for sdio support.
Thanks for this l, now I can trace the source code.eggmansan wrote:I dumped 2 types of bcm43438 sdio traffic .Thalhammer wrote: ↑Fri Aug 16, 2019 10:03 pmMaybe we could instrument the linux driver with more logging and check it using this way ?
Or is there some kernel option to dump all sdio traffic ?
1. add some debug print to drivers/mmc/core/sdio_ops.c and core.c.
https://github.com/eggman/raspberrypi/b ... io_log.txt
2. brcmfmac driver have trace option. enable BRCM_TRACING in kernel config file.
https://github.com/eggman/raspberrypi/b ... ce_log.txt
And I write some baremetal sdio code. but not test on real hardware. I only tested my modified qemu.
https://github.com/eggman/raspberrypi/t ... pi3/sdio03
Let there be some light .../\...
Re: Bare metal BCM43438 Driver
I tried this code in steps It didn't work for me in first step itself.9pi wrote: ↑Tue Aug 27, 2019 1:12 pmNot bare metal strictly speaking, but the Plan 9 driver is another alternative example you might want to look at for information. It's under 2400 lines of C, so it should be a bit easier to follow than the Linux brcmfmac driver. To write the Plan 9 driver without a device spec, I had to read all the brcmfmac code which is a 32,000+ line spaghetti of support for multiple chips and interface methods: not an experience I would recommend for pleasure.
Plan 9 driver source is at https://9p.io/sources/contrib/miller/9/bcm/ether4330.c, depends on the emmc driver (another 529 lines) in https://9p.io/sources/contrib/miller/9/bcm/emmc.c for sdio support.
I have LdB's code which reads SD card using EMMC (sdhci controller), so I tried first decoupling SD card from EMMC using following code
Code: Select all
uint32_t i;
for(i = 48; i <= 53; i++)
select_alt_func(i, Alt0);
for(i = 34; i <= 39; i++){
select_alt_func(i, Alt3);
if(i == 34)
disable_pulling(i); // Pull off
else
pullup_pin(i);
}
// ----- Pull up Pull Down code
#define PERIPHERAL_BASE 0x3F000000UL
#define GPIO_BASE ((volatile __attribute__((aligned(4))) uint32_t*)(uintptr_t)(PERIPHERAL_BASE + 0x200000))
#define SET_GPIO_ALT(g,a) *(GPIO_BASE + (((g)/10))) |= (((a)<=3?(a) + 4:(a)==4?3:2)<<(((g)%10)*3))
typedef enum {
Alt0 = 0x4,
Alt1 = 0x5,
Alt2 = 0x6,
Alt3 = 0x7,
Alt4 = 0x3,
Alt5 = 0x2,
} alt_func;
/* GPIO regs */
enum {
Set0 = 0x1c>>2,
Clr0 = 0x28>>2,
Lev0 = 0x34>>2,
PUD = 0x94>>2,
Off = 0x0,
Pulldown= 0x1,
Pullup = 0x2,
PUDclk0 = 0x98>>2,
PUDclk1 = 0x9c>>2,
};
void select_alt_func(uint32_t bcm_pin, alt_func alt_fun) {
SET_GPIO_ALT(bcm_pin, alt_fun);
}
void pullup_pin(uint32_t bcm_pin) {
volatile uint32_t *gp, *reg;
uint32_t mask;
gp = GPIO_BASE;
reg = &gp[PUDclk0 + bcm_pin/32];
mask = 1 << (bcm_pin % 32);
gp[PUD] = Pullup;
delay(150);
*reg = mask;
delay(150);
*reg = 0;
}
void pulldown_pin(uint32_t bcm_pin)
{
volatile uint32_t *gp, *reg;
uint32_t mask;
gp = GPIO_BASE;
reg = &gp[PUDclk0 + bcm_pin/32];
mask = 1 << (bcm_pin % 32);
gp[PUD] = Pulldown;
delay(150);
*reg = mask;
delay(150);
*reg = 0;
}
void disable_pulling(uint32_t bcm_pin)
{
volatile uint32_t *gp, *reg;
uint32_t mask;
gp = GPIO_BASE;
reg = &gp[PUDclk0 + bcm_pin/32];
mask = 1 << (bcm_pin % 32);
gp[PUD] = Off;
delay(150);
*reg = mask;
delay(150);
*reg = 0;
}
I tried to send
Code: Select all
(CMD5)IO_SEND_OP_COND, CMD52(RESET) by writing CIA(function = 00h) register (02h) wifi(bit 7) = 1
@9pi Am I missing something?
------------_Edit I found the Issue -----
in select_alt_func I am passing actual Alt func values as per datasheet, this MACRO takes 0 for Alt0.
I am able to select the card and read write using CMD52.
I am wondering where are the definition for these function calls like below
Code: Select all
cfgw(Sbaddr+1, addr>>16);
cfgw(Sbaddr+2, addr>>24);
PS: I tried using plan9 on virtual box to clone the sources, I couldn't use it properly.
Thanks,
zeo
Let there be some light .../\...
Re: Bare metal BCM43438 Driver
Those are static functions defined earlier in the same file, ether4330.czeoneo wrote: ↑Sun Sep 01, 2019 1:11 pm
I am wondering where are the definition for these function calls like belowI tried searching there is no way I could clone your sources repository. Please let me know if you can help me with that.Code: Select all
cfgw(Sbaddr+1, addr>>16); cfgw(Sbaddr+2, addr>>24);
Plan 9 convention is always to align the name of functions being defined in column 1, so should be easy to find in any editor. cfgw ultimately calls sdio.cmd which is defined in emmc.c sdio table as emmccmd().
Re: Bare metal BCM43438 Driver
I'm really happy to see people taking an interest in this again. I looked into doing this 6 months ago or more and got stuck with the inscrutable code for the WiFi chip. So I said screw it and I started on a different approach. I'm building a little hat with an ESP8266 on it, talking to the RPi over SPI. Still in process, but it's promising. I've leveraged some code to let 2 ESP's talk over SPI and have gotten the RPi speaking the same dialect of SPI as the ESP after some hours with the logic analyzer.
It's still very much a work in progress, but you can see how far I've gotten here:
https://github.com/cmarrin/placid
In particular look at:
https://github.com/cmarrin/placid/tree/ ... ESPRPiWifi
For the ESP code and:
https://github.com/cmarrin/placid/blob/ ... iFiSPI.cpp
for the RPi side of the SPI interface
One issue is that the very best you can hope for out of an SPI channel is a few Mbps. So it will never be gigabit ethernet! But it would be a hard system to beat at $5 for a RPi Zero without WiFi, and $2 for an ESP.
It's still very much a work in progress, but you can see how far I've gotten here:
https://github.com/cmarrin/placid
In particular look at:
https://github.com/cmarrin/placid/tree/ ... ESPRPiWifi
For the ESP code and:
https://github.com/cmarrin/placid/blob/ ... iFiSPI.cpp
for the RPi side of the SPI interface
One issue is that the very best you can hope for out of an SPI channel is a few Mbps. So it will never be gigabit ethernet! But it would be a hard system to beat at $5 for a RPi Zero without WiFi, and $2 for an ESP.