Port BCM43438(WiFi+BLE) to Photon

Hi guys,

I am working hard to port the Photon firmware for BCM43438 WiFi+BLE chip. Below is the link to the topic about the questions I’v met before:

But now I want to create this topic to focus on all of the questions I or anyone will meet on the way porting the firmware for BCM43438 WiFi+BLE chip.

Here I list the questions those make me confused by now:

  1. The structure platform_system_flags_t is to store the system flags. What’s the meaning of the members NVMEM_SPARK_Reset_SysFlag, OTA_FLASHED_Status_SysFlag and StartupMode_SysFlag in this structure?
  2. How to Generate the DCT image and download into internal flash?
  3. What’s the WICED SDK version the Photon firmware based on?

Best regards

1 Like

Sorry for the silence - I was on vacation for 2 weeks and have only managed to plough through over 500 unread topics.

  1. the NVMEM_SPARK_Reset_SysFlag is set in the bootloader as a signal that a factory reset has been performed. OTA_FLASHED_Status_SysFlag is set after a successful OTA update. The value is reported to the cloud and then the value cleared.

  2. The DCT image can be pulled from an existing device, or simply left blank and the system will initialize it. It is 2 16kB sectors at 0x8004000, which can be written using JTAG.

  3. The photon is based on WICED SDK 3.3.0.

Cheers! :smile:

Hi @mdma ,

Appreciate for your kindly help! :blush:
Now we can make our board connect to Particle cloud. As the flash memory has been changed, we have to burn the Tinker application via dfu-util, instead of OTA. The Tinker application also worked well, since I can using the Particle App to control its side pins.

Here I summarize the questions I have met since last post:

  1. I first build the apsta snip in WICED SDK 3.3.1 using FreeRTOS & LwIP configuration and got the WICED libraries. Regarding to the STM32F2xx.a for Photon, I think there should be two additional week functions in wwd_resources.o, which are wwd_wifi_image_resources() and wwd_nvram_image_resources(). And there are also two additional functions in wiced_dct_internal_common.o, which are dct_read_app_data() and dct_write_app_data(). Regarding to the WWD_for_SDIO_FreeRTOS.a for Photon, there has a function wwd_wifi_join_cancel() in wwd_wifi.o, which is missing in WICED SDK 3.3.1. If I’m right, could you please offer me the implementation code of these functions? Now I just replace these related object files with those compiled for Photon.

  2. Except that changing the bsrk_heep variable to be external in common_GCC.a, have you made any other change in it?

  3. After smart config completed, it crashed when destruct the http server, so I have to use the lib_http_server.a for Photon to fix this. What do you think will cause this problem? Heap? Stack?

  4. Since I burned the Tinker application via dfu-util, the CRC was not be appended to the end of the user module, so I force it to be true when verifying the CRC of the user module. But when calling the module_user_pre_init() to copy the initial value to the .data session, it blocked in app_setup_and_loop() ->HAL_Core_Init() -> wiced_core_init() -> wiced_platform_init(). Ram issue?

  5. When it ran into wiced_network_up() to join AP, it will crash the USB, being an unknown device. After my digging, This happened when it was going to take a semaphore “join_sema” in function wwd_wifi_join(), which in file wwd_wifi.c.

Thanks in advance!


I can send you a diff of our changes. Please send me your email in a PM and I’ll get them to you so that should take care of points 1 and 2.

I’m afraid I don’t have any answers to the other questions - since you’re running quite a different setup it’s difficult to guess how this might cause it to fail. I can only assume it might be from mixing libraries form the different SDK versions, so hopefully the patch of our changes will help you there.


Hi @mdma,

The patch did help me a lot and I finally resolved all of the problems. Thanks a lot!

Now I’m trying to upload the user application to our board using web IDE. I tried flashing a blink-an-led when my board is running the tinker firmware, but my board didn’t change the RGB color, though the web IDE said flash successfully. Then I reset my board. After it connecting to the cloud and running the tinker app for a while, it began OTA automatically with magenta toggling. But it finally stop toggling the magenta and reset to run the tinker app.

I downloaded the corresponding firmware.bin from web IDE and burned it to user part via dfu-util, which address start from 0x080a0000. Then I reset my board and it just gave a white pulse and then it crashed when calling the module_user_init(). Maybe it called some dynalibs from system-part1 and system-part2 in constructors but the system-part2 in my firmware starts from 0x080c0000. BTW, bellowing is my firmware structure:
system-part1: 0x08020000 - 0x080a0000 (512K)
user-part: 0x080a0000 - 0x080c0000 (128K)
system-part2: 0x080c0000 - 08100000 (256K)

Do you have any idea to deal with the problem? And I think we have to face the situation that our firmware framework is different from Photon, but we need to use your web IDE to flash applications.


Where does the OTA image get copied to?

If you’ve not done it already you should bump the version of system firmware so that you don’t get updates from the cloud, since these will be for the original firmware, not your modified firmware. Alternatively (and most ideal) is to compile the bootloader, system and application firmware with a different PLATFORM_ID.

@mdma The OTA image gets copied to an external serial flash. Does the web IDE compile application according to the PLATFORM_ID?

Update: Can we now apply a PLATFORM_ID from particle?

Sure. Please take a look in build/paltform-id.mk in the repo and email me the details as you want there and I’ll add it to the file with the next available platform ID.

(For testing, there’s no harm if you simply edit that file and add your own platform ID with a high number, say 65001.)

Yes, Particle Build (WebIDE) compiles according to platform. In particular, if you compile for the photon, the application module will be looking for dynamic link tables in the system-part2 region of the photon, namely 0x8060000. Until the backend is in place you should compile your application locally so that it is looking for the dynamic link tables in the correct place (0x80c0000)

@mdma Thanks a lot and I’ll email you the platform details if we are ready to declare our board.

Now I’m trying to modify the bootloader to support updating WICED DCT using dfu-util. I changed the protected area ranging from 0x08000000 to 0x08004000:
#define DFU_MAL_IS_PROTECTED_AREA(add) (uint8_t)(((add >= 0x08000000) && (add < 0x08004000))? 1:0). But when I updating the WICED DCT from 0x08004000, I got an error on command line: “Last page at 0x08005da7 is not writeable”, where the 0x08005da7 is the last byte’s address of the DCT. I did try many ways to figure out where I was wrong, but no luck. Hope for your help!

According to the source code, the WICED system DCT is immediately followed by Photon application DCT, right? Though I see there are reserved 1K bytes between them in dct_hal.h.

Edit: The dfu-util command is : dfu-util -d 2b04:d006 -a 0 -s 0x08004000 -D DCT.bin

The dfu region is not writable directly. For that you’d need to also change the flags in the dfu descriptor. If is possible to write to the application dct area using -a 1 to select the DCT memory region.

I just want to update WICED DCT, but the -a 1 option only select the application DCT area and it will place the code above the address 0x08004000 + sizeof(platform_dct_data_t). What do you mean

Does it include region 0x08004000 - 0x08020000? Or just from 0x08000000 to 08004000?

@mdma I can now update WICED DCT using dfu-util by modifying the internal flash interface descriptor flag FLASH_IF_STRING. Thank you so much.

Here are two questions:

  1. Does every Photon device use the same pair of private & public key? If not, it must have to do mass work on generating RSA key for every device.
  2. When enable using external serial flash, why the FAC, BKP and OTA images should begin with address 0x4000? Does the space <0x4000 reserve for other purpose?

Edit: Regarding to point 2, Should I think that the reason why the external flash stores firmware begin with 0x4000, is to avoid the address space conflict with DCT, when using dfu-util to upload data to external flash? Since the valid address space in DFU bootloader for DCT is 0x0000 to 0x4000. If I want to program date to external flash from 0x0, for example, the bootloader will redirect the data to DCT address space. Please figure me out if I’m wrong. Thanks.


  1. Devices use the same public key for the server, but generate their own private key, so you can prepare the same image for all devices, just be sure the private key region is uninitialized.

  2. I don’t recall the answer, but the engineer that worked on it reported a problem when writing to block 0. If you are using external flash for backup regions, please test well, since it’s not received any attention from us since January - this was a placeholder while we were developing the modular system. We don’t use it now everything can fit in internal flash.


Hi, @mdma,

After digging the DFU bootloader for few days, I found there may have a bug in usbd_dfu_mal.c, especially when enabling the DFU interface for external serial flash. The index of a DFU interface to communicate with dfu-util is generated by local function MAL_CheckAdd(), instead of using the index set by dfu-util command line parameter -a ?.

Since the valid address of the external serial flash is from 0x00000000 to 0x00200000, part of them are the same with internal DCT interface, i.e. from 0x00000000 to 0x00004000. Thus, for example, if I want to download image to external flash from 0x00000001 using dfu-util command:

dfu-util -d 2b04:d006 -a 2 -s 0x1 -D 43438A1.bin

it will download this image to both internal DCT memory space and external serial flash from relative address 0x01. This is true because I read the data out in DCT and external serial flash by using dfu-util command:

dfu-util -d 2b04:d006 -a 1 -s 0x1 -U 43438A1-verify.bin
dfu-util -d 2b04:d006 -a 2 -s 0x1 -U 43438A1-verify.bin

I added a parameter uint32_t Idx to the DFU MAL APIs, which to receive the interface index from dfu-util, instead of generating locally. I tested it through and it won’t download the image to the wrong memory space. In the usbd_dfu_core.c, I delivered the interface index using the variable usbd_dfu_AltSet. For example:

MAL_Erase(usbd_dfu_AltSet, Pointer);

But I’m not sure if I was right, though it downloaded the system part 1, system part 2, user part, server public key successfully, etc. So please help ask your colleague who wrote the DFU bootloader for the answer to make me more confident.

Thank you so much.


This sounds great, and makes perfect sense, and is quite possibly why the original developer decided not to use the first external flash page.

If you want to, please submit a pull request so I can review and eventually merge the code.

Thanks :smile:

(btw, please use another platform ID - using 6 is already reserved for the Photon, so best use another one! You’re welcome to grab the next available one in build/platform-id.mk and flesh out the details and submit that in your pull request.)

That’s a good news for us! I’ll reorganize my code and finally submit a pull request. It’s grateful that you can support our platform on your GitHub!


1 Like

Hello, @mdma,
I too am working with the WICED SDK source (v3.4.0), and noticed there are a few missing definitions (e.g., wiced_network_up_cancel, wiced_interface_up). Could you send me the diff file?
Also, will 3.4.0 be ported to the photon anytime soon?

Thank you,

where did you get 3.4.0 from? I searched the Broadcom community forum but didn’t find anything there. We are waiting for Broadcom to release the SDK with a permissive license so we can distribute the files.

Great to hear!
We are only using 3.4.0 to resolve an issue with our hw setup (SPI communication with the BCM43438). For all purposes the diff with respect to 3.3.1 is fine: would it be possible to receive it via PM?


Hi @mdma, I’v sorted the source code to support our platform and created a pull request on GitHub:

Please take a look and comment it if you have any question.


1 Like