Skip navigation
Home > All Places > WICED Studio Wi-Fi/Combo > WICED Studio Wi-Fi/Combo Forums > Blog
1 2 3 Previous Next

WICED Studio Wi-Fi/Combo Forums

113 posts


   We already provided a good document for how to use DCT functions, this topic here is just to have a simple implement.

    My test and description are based on 43907 board.


  • What is DCT

The content was described in the document, just copy it here. The DCT stores System and Application data persistently so that the device can use the information between power cycles. The layout of the data is extremely important,and may change between SDKs.

  • DCT Layout

     Normal DCT area

     # DCT1

     NORMAL_IMAGE_DCT_1_AREA_BASE   := 0x00008000   #  16k  (0x00004000)    

     # DCT2

     NORMAL_IMAGE_DCT_2_AREA_BASE   := 0x0000C000   #  16k  (0x00004000)


     OTA2 DCT area

     OTA2_IMAGE_APP_DCT_SAVE_AREA_BASE    := 0x00208000  # 16k  0x00004000

     OTA2_IMAGE_CURR_DCT_1_AREA_BASE      := 0x0020d000        #  16k  0x00004000

     OTA2_IMAGE_CURR_DCT_2_AREA_BASE      := 0x00211000        #  16k  0x00004000



Talking to two DCT area:

There are two DCT areas defined in the FLASH, designated as DCT1 and DCT2. When there are changes to the DCT, we use these in a flip-flop arrangement, copying the “current” DCT to the opposite area with the changes requested, then indicating that the “new” area is the “current” area. Then we mark the “old” area as not in use. This ensures that if power is lost in any part of the update procedure, there is a viable DCT area upon power up.


Description in the function API:

*  Validate and return the current DCT address

* - determine the SDK version of the DCT

* - determine which DCT is valid and most recent

* - update the DCT to DCT_BOOTLOADER_SDK_CURRENT if needed

* - return section to the current DCT address

* - if both DCTs invalid, create a valid DCT to use


Because every time we flashed the image into DCT1 area, and maybe the new image will have different sdk_ver,

so we need a check and compare flow, the logics are:

  1. Presume use_dct1=WICED_TRUE, then check if dct1 and dct2 area has valid sdk version.
  2. If two areas have same SDK version, check initial write flag.
  3. If dct1_sdk_version < dct2_sdk_version, make use_dct2 TRUE.
  4. Below code is to backup DCT info to the other area before modification.



  • DCT structure


If you read our DCT document in detail, you will find below structure is implemented and modified along with the SDK release.  DCT structure will be divided into three areas:

  1. From dct_header to dct_version, DO NOT MOVE.
  2. From the end of dct_version to the end of platform_dct_data_t, it is for handling additional requests. 
  3. The area after the end of platform_dct_data_t, it should be

DCT_APP_SECTION that is used often in different applications.



wiced_result_t wiced_dct_write( const void* data, dct_section_t section, uint32_t offset, uint32_t data_length )


     * There are 3 parts to updating the data (other than platform_dct_header_t and platform_dct_version_t which

     * are handled in the function wiced_dct_finish_new_dct() above)

     * 1) Data before the (section_start + offset) of the new data

*      A) Some new data is between dct_header and dct_version

*      B) Some new data is between dct_version and the end of platform_dct_data_t

*      C) Some new data is after platform_dct_data_t

     * 2) the new data (section_start + offset) size: data_length

     *      A) Some new data is between dct_header and dct_version

     *      B) Some new data is between dct_version and the end of platform_dct_data_t

     *      C) Some new data is after platform_dct_data_t

     * 3) Data after the (section_start + offset+ data_length) of the new data, up to the end of PLATFORM_DCT_COPY1_SIZE

     *      A) Some new data is between dct_header and dct_version

     *      B) Some new data is between dct_version and the end of platform_dct_data_t

     *      C) Some new data is after platform_dct_data_t


     * The code here is generic enough to handle all three cases without having to be maintained  B^)



If you have interests, please add more logs and test if the logic can match all your requests, and check if there exist bugs, thanks.


  • Two ways to be familiar with DCT usages.

          One is command_console:    

          Add below define into the makefile of the application like;

Add include in the file command_console_commands.h:

Add to COMMAND table:

After compiling and download we can get the results:


The other is DCT_read_write APP:

snip.dct_read_write-CYW943907AEVAL1F-debug download download_apps

we have very detailed instructions in the released sdk also, the name is




The following blog demonstrates a setup for conducting throughput test with coexistence enabled. The results of the conducted tests are also included thereby demonstrating the advantages of using coexistence. 2-wire SECI is used in this test for exchanging coexistence data among the two Cypress chips. More about SECI could be found in the following link: Overview of SECI.


The applications and the platforms used for throughput test are :

  1. Iperf application running in CYW943907WAE4
  2. Le_COC throughput application running in CYW20719Q40EVB_01(attached)




The diagram below depicts the pins and connections between the two boards:




Setting up CYW20719Q40EVB_01:


Any of the available(pins that are brought out in the platform) LHL GPIO pins can be configured to function as SECI. The LHL GPIOs WICED_P10 and WICED_P06(mapped to A0 and D8 respectively on CYW20719Q40EVB_01 ) are used as BT_SECI_OUT and BT_SECI_IN respectively in the attached BT throughput application.

To configure the LHL GPIOs as SECI, the following API is used:


wiced_bt_gpio_select_status_t wiced_hal_gpio_select_function(wiced_bt_gpio_numbers_t pin, wiced_bt_gpio_function_t function);


Eg: for configuring the LHL GPIOs, WICED_P10 and WICED_P06 as BT_SECI_OUT and BT_SECI_IN


wiced_hal_gpio_select_function(WICED_P10 , WICED_GCI_SECI_OUT);

wiced_hal_gpio_select_function(WICED_P06 ,WICED_GCI_SECI_IN );


And finally to enable coexistence in BT, the following API is used:

wiced_result_t wiced_bt_coex_enable( uint32_t seci_baud_rate );


Seci baud rate can be set to a maximum of 4M. In the attached example application, a baudrate of 3M is used.




The following code pic depicts the usage of the above mentioned APIs:


Finally flash the application on the BLE GATT server( CYW20719Q40EVB_01 ), and connect the device to a BLE client. CySmart BLE 4.2 USB dongle was used as the client in this throughput test. Make sure to enable notifications from the server, in the client using the CySmart application.

Setting up CYW943907WAE4 :


Change the last bit/LSB of boardflags parameter in the nvram.txt to 1.

Each boardflags parameter is 32 bit wide. The LSB corresponds to switching the BTCOEX.


Boardflag=0x0a0 => boardflags = 0x0a1

Following commands were used to setup the iperf in the AP and STA.


AP as UDP client(tx):

wl mpc 0

wl up

wl frameburst 1

start_ap tput open 0102 6

iperf -c -u -i1 -t10 -w8m -b10m

AP as TCP client(tx):

iperf -c -i1 -t10 -w8m


STA as UDP  server(rx):

wl mpc 0

wl up

join tput open 0102

iperf -s -u -i1 -8k

STA as TCP  server(rx):

iperf -s -i1 -8k


Finally throughput results here:

BLE and wifi thoughput without coexistence

UDP and TCP without BT interference and coex disabled

wifi data without BT interference and coex enabled



UDP throughput without BLE interference


[ ID] Interval       Transfer     Bandwidth        Jitter Lost/Total Datagrams

[  0] 0.0- 1.0 sec  1.20 MBytes  10.0 Mbits/sec   0.918 ms 0/  853 (0%)

[  0] 1.0- 2.0 sec  1.18 MBytes  9.93 Mbits/sec   0.949 ms 6/  850 (0.71%)

[  0] 2.0- 3.0 sec  1.19 MBytes  9.96 Mbits/sec   1.210 ms 2/  849 (0.24%)

[  0] 3.0- 4.0 sec  1.19 MBytes  10.0 Mbits/sec   0.982 ms 0/  852 (0%)

[  0] 4.0- 5.0 sec  1.19 MBytes  9.95 Mbits/sec   0.984 ms 3/  849 (0.35%)

[  0] 5.0- 6.0 sec  1.19 MBytes  9.97 Mbits/sec   1.407 ms 2/  850 (0.24%)

[  0] 6.0- 7.0 sec  1.18 MBytes  9.89 Mbits/sec   1.526 ms 4/  845 (0.47%)

[  0] 7.0- 8.0 sec  1.19 MBytes  9.95 Mbits/sec   1.005 ms 10/  856 (1.2%)

[  0] 8.0- 9.0 sec  1.19 MBytes  10.0 Mbits/sec   1.134 ms 0/  850 (0%)

[  0] 9.0-10.0 sec  1.19 MBytes  9.97 Mbits/sec   0.790 ms 3/  851 (0.35%)

[  0] 0.0-10.0 sec  11.9 MBytes  9.95 Mbits/sec   1.179 ms 31/ 8507 (0.36%)



TCP throughput without BLE interference and coex disabled


[  0]  0.0- 1.0 sec  1.01 MBytes  8.47 Mbits/sec

[  0]  1.0- 2.0 sec  1.12 MBytes  9.36 Mbits/sec

[  0]  2.0- 3.0 sec  1020 KBytes  8.36 Mbits/sec

[  0]  3.0- 4.0 sec   947 KBytes  7.76 Mbits/sec

[  0]  4.0- 5.0 sec   859 KBytes  7.04 Mbits/sec

[  0]  5.0- 6.0 sec  1.11 MBytes  9.31 Mbits/sec

[  0]  6.0- 7.0 sec  24.4 KBytes   200 Kbits/sec

[  0]  7.0- 8.0 sec  14.3 KBytes   117 Kbits/sec

[  0]  8.0- 9.0 sec  9.98 KBytes  81.8 Kbits/sec

[  0]  9.0-10.0 sec  4.28 KBytes  35.0 Kbits/sec

[  0]  0.0-10.8 sec  6.05 MBytes  4.70 Mbits/sec


UDP throughput with BLE interference and coex disabled


[ ID] Interval       Transfer     Bandwidth        Jitter   Lost/Total Datagrams

[  0]  0.0- 1.0 sec   680 KBytes  5.57 Mbits/sec   4.734 ms  166/  640 (26%)

[  0]  1.0- 2.0 sec   111 KBytes   906 Kbits/sec   2.146 ms   41/  118 (35%)

[  0]  2.0- 3.0 sec  1.44 KBytes  11.8 Kbits/sec  74.137 ms   30/   31 (97%)

[  0]  3.0- 4.0 sec   375 KBytes  3.07 Mbits/sec   1.105 ms    0/  261 (0%)

[  0]  4.0- 5.0 sec   996 KBytes  8.16 Mbits/sec   3.488 ms   25/  719 (3.5%)

[  0]  5.0- 6.0 sec   291 KBytes  2.39 Mbits/sec   9.384 ms  283/  486 (58%)

[  0]  6.0- 7.0 sec   502 KBytes  4.12 Mbits/sec   6.382 ms    0/  350 (0%)

[  0]  7.0- 8.0 sec   601 KBytes  4.93 Mbits/sec   2.328 ms    5/  424 (1.2%)

[  0]  8.0- 9.0 sec  1.26 MBytes  10.5 Mbits/sec   0.854 ms    4/  901 (0.44%)

[  0]  0.0-10.0 sec  5.86 MBytes  4.94 Mbits/sec   1.252 ms  555/ 4736 (12%)


Observable packet drops seen in Wifi due to interference from  BLE


TCP throughput with BLE interference


[  0] 0.0- 1.0 sec  29.9 KBytes   245 Kbits/sec

[  0] 1.0- 2.0 sec   369 KBytes  3.03 Mbits/sec

[  0] 2.0- 3.0 sec   605 KBytes  4.96 Mbits/sec

[  0] 3.0- 4.0 sec  21.0 KBytes   172 Kbits/sec

[  0] 4.0- 5.0 sec   247 KBytes  2.03 Mbits/sec

[  0] 5.0- 6.0 sec   490 KBytes  4.01 Mbits/sec

[  0] 6.0- 7.0 sec  9.98 KBytes  81.8 Kbits/sec

[  0] 7.0- 8.0 sec  3.82 KBytes  31.3 Kbits/sec

[  0] 8.0- 9.0 sec  1.89 KBytes  15.5 Kbits/sec

[  0] 9.0-10.0 sec  8.55 KBytes  70.1 Kbits/sec

[  0] 10.0-11.0 sec  0.00 Bytes 0.00 bits/sec

[  0] 11.0-12.0 sec  2.85 KBytes 23.4 Kbits/sec

[  0] 12.0-13.0 sec  1.43 KBytes 11.7 Kbits/sec

[  0] 13.0-14.0 sec  4.28 KBytes 35.0 Kbits/sec

[  0] 0.0-14.3 sec  1.76 MBytes  1.03 Mbits/sec


UDP throughput with coex enabled


[  0] 0.0- 1.0 sec  1.20 MBytes  10.0 Mbits/sec   1.067 ms 0/  853 (0%)

[  0] 1.0- 2.0 sec  1.12 MBytes  9.36 Mbits/sec   0.895 ms 2/  798 (0.25%)

[  0] 2.0- 3.0 sec  1024 KBytes  8.38 Mbits/sec   1.135 ms 21/  734 (2.9%)

[  0] 3.0- 4.0 sec  1.26 MBytes  10.5 Mbits/sec   0.842 ms 2/  898 (0.22%)

[  0] 4.0- 5.0 sec  1.16 MBytes  9.76 Mbits/sec   0.985 ms 8/  838 (0.95%)

[  0] 5.0- 6.0 sec  1002 KBytes  8.21 Mbits/sec   0.952 ms 10/  708 (1.4%)

[  0] 6.0- 7.0 sec  1.40 MBytes  11.7 Mbits/sec   0.944 ms 28/ 1025 (2.7%)

[  0] 7.0- 8.0 sec  1.20 MBytes  10.1 Mbits/sec   1.131 ms 10/  865 (1.2%)

[  0] 8.0- 9.0 sec  1.09 MBytes  9.17 Mbits/sec   1.257 ms 4/  784 (0.51%)

[  0] 9.0-10.0 sec  1.24 MBytes  10.4 Mbits/sec   1.130 ms 25/  912 (2.7%)

[  0] 0.0-10.0 sec  11.6 MBytes  9.75 Mbits/sec   1.435 ms 111/ 8417 (1.3%)



TCP throughput with coex enabled


[  0] 0.0- 1.0 sec  3.55 MBytes  29.7 Mbits/sec

[  0] 1.0- 2.0 sec  3.61 MBytes  30.3 Mbits/sec

[  0] 2.0- 3.0 sec  3.46 MBytes  29.1 Mbits/sec

[  0] 3.0- 4.0 sec  3.05 MBytes  25.6 Mbits/sec

[  0] 4.0- 5.0 sec  16.4 KBytes   134 Kbits/sec

[  0] 5.0- 6.0 sec  2.14 KBytes  17.5 Kbits/sec

[  0] 6.0- 7.0 sec  2.02 MBytes  16.9 Mbits/sec

[  0] 7.0- 8.0 sec  2.93 MBytes  24.6 Mbits/sec

[  0] 8.0- 9.0 sec  1.42 MBytes  11.9 Mbits/sec

[  0] 9.0-10.0 sec  3.47 MBytes  29.1 Mbits/sec

[  0] 0.0-10.0 sec  23.5 MBytes  19.7 Mbits/sec



BLE throuhgput when coex not enabled


BLE througput with coex enabled


BT_activity_with _coex.png




Given the low priority setting for the BT custom profile(for client-server notification), the throughput saw a observable improvement in WiFi side and at the same time the BT side experienced a heavy throughput loss.

The cryptography core in CYW43907, also known as crypto, is a dedicated hardware core present in the applications processor. It is used for performing cryptographic operations such as encryption and hashing in dedicated engines. The following operations are supported:


AES module which supports CBC, ECB, CTR, CFB modes
DES module to support DES and 3DES encryption with ECB and CBC modes


MD5, SHA1, SHA224, and SHA256 to support HMAC


Using hardware crypto in WICED


The hwcrypto is used in mbedTLS cryptographic operations as well as secure boot. By default, hwcrypto is enabled for mbedTLS operations. The macro PLATFORM_HAS_HW_CRYPTO_SUPPORT is used for enabling hwcrypto for mbedTLS and it is defined in as shown below:

$(NAME)_SOURCES += platform_crypto.c

To disable hwcrypto, the above statements should be commented out. The PLATFORM_HAS_HW_CRYPTO_SUPPORT effectively enables the following macros in mbedtls/config.h:


The above macros are used for enabling hwcrypto APIs defined in files marked with _alt.c in mbedtls_open/library. For instance, when MBEDTLS_AES_ALT is enabled, the APIs present in aes_alt.c are enabled which would call the driver functions such as hw_aes_crypt() in platform_tiny_crypto.c.

An SPU message is processed by the crypto core. Its contains the following:


           INPUT HEADER                       OUTPUT HEADER

     +-------------------------+         +------------------------+

     | Message Header (MH )    |         | Message Header (MH)    |

     +-------------------------+         +------------------------+

     | Extended Header (EH)    |         | Extended Header (EH)   |

     +-------------------------+         +------------------------+

     | SCTX Header 0  (SCTX0)  |         | Output data : Payload  |

     +-------------------------+         +------------------------+

     | SCTX Header 1  (SCTX1)  |         | Status                 |

     +-------------------------+         +------------------------+

     | SCTX Header 2  (SCTX2)  |


     | BufferDescriptor (BDESC)|


     | Buffer Data (BD)        |


     | Input data : Payload    |


     | Status                  |



Where SCTX is the security context.


The DMA descriptors to SPU-M have the following format:

     INPUT DMA Descriptors                           OUTPUT DMA Descriptors

    +--------------------------+                    +--------------------------+

    | Header                   |                    | Header                   |

    | (MH + EH + SCTX0 + SCTX1 |                    | (MH + EH + BDA )         |

    |  SCTX2 + SCTX3)          |                    +--------------------------+

    +--------------------------+                    | start_aligned_buffer@    |

    | Payload 1                |                    | (PLATFORM_L1_CACHE_BYTES |

    | (MAX_DMA_BUFFER_SIZE)    |                    +--------------------------+

    +--------------------------+                    | Payload 1                |

    | Payload 2*               |                    | (MAX_DMA_BUFFER_SIZE)    |

    | (MAX_DMA_BUFFER_SIZE)    |                    +--------------------------+

    +--------------------------+                    | Payload 2*               |

    | Payload 3*               |                    | (MAX_DMA_BUFFER_SIZE)    |

    | (MAX_DMA_BUFFER_SIZE)    |                    +--------------------------+

    +--------------------------+                    | Payload 3*               |

    | Payload 4*               |                    | (MAX_DMA_BUFFER_SIZE)    |

    | (MAX_DMA_BUFFER_SIZE)    |                    +--------------------------+

    +--------------------------+                    | Payload 4*               |

    | STATUS                   |                    | (BYTES_IN_WORD)          |

    | (BYTES_IN_WORD)          |                    +--------------------------+

    +--------------------------+                    | end_aligned_buffer@      |

                                                    | (MAX_DMA_BUFFER_SIZE)    |


                                                    | HASH_OUTPUT#             |

                                                    | (BYTES_IN_WORD)          |


                                                    | STATUS                   |

                                                    | (BYTES_IN_WORD)          |


    * * : Payload2/3/4 only required if Payload1/2/3 > MAX_DMA_BUFFER_SIZE
    * # : Hash output present only if cmd.hash_output is Not NULL
    * @ : Start/end aligned buffer is needed to ensure that the Start address and size of DMA is
    *     PLATFORM_L1_CACHE_BYTES aligned

The following macros are defined in platform_tiny_crypto.c:


MAX_DMA_BUFFER_SIZE: This is the maximum size of DMA descriptor buffer which is 16kB. If the DMA payload size exceeds MAX_DMA_BUFFER_SIZE, it is split into chunks of MAX_DMA_BUFFER_SIZE. This is implemented in hwcrypto_split_dma_data() called in populate_input_descriptors().


MAX_TX_DMADESCRIPTOS: This is the maximum size of input DMA descriptors as shown in the format above. Its value is 1 (header) +  4 (payload) + 1 (padded hash input) + 1 (status)


MAX_RX_DMADESCRIPTOS: This is the maximum size of output DMA descriptors as shown in the format above. Its value is 1 (header) +  4 (payload) + 2 (aligned payload buffers) + 1 (hashoutput) + 1 (status)


HWCRYPTO_MAX_PAYLOAD_SIZE: This is the maximum hwcrypto payload size that the SPU-M can handle at a time during cryptographic operation.


Other macros specific to encryption and hashing have been listed in crypto_api.h.


A sample WICED code for testing AES-CBC using hwcrypto has been attached.

This blog discusses the different binaries that are downloaded in CYW943907AEVAL1F EVK when the board is programmed using WICED SDK. This blog also addresses the procedure of creating a single binary suitable for manufacturing. Please note that the manufacturing image procedure is explained for ota2 compatible image. The same method can be followed to create a similar image for generic case(non OTA2).



The different binaries needed for programming a CYW943907AEVAL1F EVK are

1. Bootloader

2. DCT



5. APPLICATION(There can be multiple applications APP0, APP1, APP2)


During a normal build process, the files which are downloaded can be viewed by including VERBOSE=1 in the make target. The downloaded files from the build log are shown below:

1. DCT

Downloading DCT ... build/<snip_name>-CYW943907AEVAL1F/DCT.bin @ SFLASH_DCT_LOC=0x00008000

2. The Bootloader file is:


3. Filesystem is created with

./tools/common/Win32/mk_wicedfs32 build/<snip_name>-CYW943907AEVAL1F/filesystem.bin build/<snip_name>-CYW943907AEVAL1F/resources/Staging/

and downloaded

Downloading resources filesystem ... build/<snip_name>-CYW943907AEVAL1F/filesystem.bin at sector 17  size <filesystem_size>...

4. Downloading Application

Downloading APP0 build/<snip_name>-CYW943907AEVAL1F/binary/<snip_name>-CYW943907AEVAL1F.stripped.elf @ sector <filesystem_start_address + filesystem_size> address xxx size <filesystem_size>...


Downloading apps lookup table in ... build/<snip_name>-CYW943907AEVAL1F/APPS.bin @ 0x00010000 size


How are the addresses determined for programming the binaries/files?

>> The memory map is defined in <WICED- SDK>\43xxx_Wi-Fi\platforms\CYW943907AEVAL1F\

The starting address of filesytem is given as:

In /43xxx_Wi-Fi/platforms/CYW943907AEVAL1F/,

NORMAL_IMAGE_APPS_AREA_BASE := 0x00011000 i.e, 69632 d


In /43xxx_Wi-Fi/WICED/platform/MCU/BCM4390x/



Hence APPS_START_SECTOR=69632/4096 = 17


The starting address of application stripped.elf is obtained by adding the filesystem size to APPS_START_SECTOR.

Kindly check the BUILD_APPS_RULES in 43xxx_Wi-Fi/tools/makefiles/ for understanding the computation of starting sectors.



The manufacturing image is a single image suitable for download during manufacturing.

WICED has implemmenttaion for creating manufacturing image suitable for OTA2. It follows the memory map defined in 43xxx_Wi-Fi\platforms\CYW943907AEVAL1F\

The image is created using "ota2_manuf_image" in the make target.


How is the manufacturing image created and which files are included in it?

>> Please look for ota2_manuf_image target in 43xxx_Wi-Fi\tools\makefiles\

First a manufacturing config file is created.


The config file is than appended with information of other required binaries. One such example is:


The config file is then passed to a tool which creates the image. The image is filled with 0xFF for unused parts of the FLASH



The  $(CREATE_FLASH_IMAGE_TOOL) is located @43xxx_Wi-Fi\tools\common\<OS>\mk_wiced_ota2_image32.exe

WICED currently has support for sflash from the following manufacturers.

  3. SST
  4. EON
  5. ISSI

You can get a list of all the supported sflash in CYW43907 with External SFLASH in WICED . If you want to add support for any other part number from the existing supported flash manufacturers in WICED SDK, you can follow the steps mentioned below. In this example, I have added support for N25Q128A flash from MICRON.


For ST based platforms:

  • Please add the SFLASH_ID from the part number datasheet in 43xxx_Wi-Fi/libraries/drivers/spi_flash/spi_flash_internal.h

    #define SFLASH_ID_MX25L8006E           ( (uint32_t) 0xC22014 )

    #define SFLASH_ID_MX25L1606E           ( (uint32_t) 0xC22015 )

    #define SFLASH_ID_MX25L6433F           ( (uint32_t) 0xC22017 )

    #define SFLASH_ID_MX25L12835F          ( (uint32_t) 0xC22018 )

    #define SFLASH_ID_MX25L25635F          ( (uint32_t) 0xC22019 )

    #define SFLASH_ID_MX25U1635F           ( (uint32_t) 0xC22535 )

    #define SFLASH_ID_MX66U51235F          ( (uint32_t) 0xC2253A )

    #define SFLASH_ID_SST25VF080B          ( (uint32_t) 0xBF258E )

    #define SFLASH_ID_EN25QH16             ( (uint32_t) 0x1C3015 )

    #define SFLASH_ID_ISSI25CQ032          ( (uint32_t) 0x7F9D46 )

    #define SFLASH_ID_N25Q512A             ( (uint32_t) 0x20BB20 )

    #define SFLASH_ID_ISSI25LP064          ( (uint32_t) 0x9D6017 )

    #define SFLASH_ID_N25Q064A             ( (uint32_t) 0x20BA17 )

    #define SFLASH_ID_W25Q64FV             ( (uint32_t) 0xEF4017 )

    #define SFLASH_ID_CY15B104Q            ( (uint32_t) 0x7F7F7F )

    +#define SFLASH_ID_N25Q128A             ( (uint32_t) 0x20BA18 )


    #define SFLASH_ID_DEFAULT              ( (uint32_t) 0x000000 )


  • Then try adding the size of the new part number in 43xxx_Wi-Fi/libraries/drivers/spi_flash/spi_flash_internal.h


   #define SFLASH_SIZE_1MByte                0x100000

   #define SFLASH_SIZE_2MByte                0x200000

   #define SLFASH_SIZE_32MByte               0x2000000

   #define SFLASH_SIZE_64MByte               0x4000000

   #define SFLASH_SIZE_512KByte              0x80000

   #define SFLASH_SIZE_16MByte               0x1000000


  • Add the device name in the sflash_device_id_size structure in the following manner


         device_id_to_flash_size_t sflash_device_id_size [SFLASH_ID_MAX_PARTS] =


                { SFLASH_ID_MX25L8006E,  SFLASH_SIZE_1MByte   },

                { SFLASH_ID_MX25L1606E,  SFLASH_SIZE_2MByte   },

                { SFLASH_ID_MX25L25635F, SLFASH_SIZE_32MByte  },

                { SFLASH_ID_MX25U1635F,  SFLASH_SIZE_2MByte   },

                { SFLASH_ID_SST25VF080B, SFLASH_SIZE_1MByte   },

                { SFLASH_ID_EN25QH16,    SFLASH_SIZE_2MByte   },

                { SFLASH_ID_N25Q512A,    SFLASH_SIZE_64MByte  },

                { SFLASH_ID_CY15B104Q,   SFLASH_SIZE_512KByte },

                { SFLASH_ID_N25Q128A,    SFLASH_SIZE_16MByte  }




  • If you are using WINBOND, ISSI, CYPRESS flash, you have to add SFLASH_SUPPORT_WINBOND_PARTS in 43xxx_Wi-Fi/libraries/drivers/spi_flash/ or as a part of GLOBAL_DEFINES in your <platform>.mk file



For 4390x based platform


To add a new part with the already supported sflash chips for 4390x platform, you have to make the necessary modifications in 43xxx_Wi-Fi/WICED/platform/MCU/BCM4390x/peripherals/spi_flash.


  • Just like ST based platforms, you need to add the SFLASH_ID in 43xxx_Wi-Fi/WICED/platform/MCU/BCM4390x/peripherals/spi_flash/spi_flash.h


      #define SFLASH_ID_MX25L8006E           SFLASHID( 0xC2, 0x20, 0x14 )


      #define SFLASH_ID_MX25L1606E           SFLASHID( 0xC2, 0x20, 0x15 )


      #define SFLASH_ID_MX25L6433F           SFLASHID( 0xC2, 0x20, 0x17 )


      #define SFLASH_ID_MX25L12835F          SFLASHID( 0xC2, 0x20, 0x18 )


      #define SFLASH_ID_MX25L25635F          SFLASHID( 0xC2, 0x20, 0x19 )


      #define SFLASH_ID_MX25U1635F           SFLASHID( 0xC2, 0x25, 0x35 )


      #define SFLASH_ID_MX66U51235F          SFLASHID( 0xC2, 0x25, 0x3A )


      #define SFLASH_ID_SST25VF080B          SFLASHID( 0xBF, 0x25, 0x8E )


      #define SFLASH_ID_EN25QH16             SFLASHID( 0x1C, 0x30, 0x15 )


      #define SFLASH_ID_ISSI25CQ032          SFLASHID( 0x7F, 0x9D, 0x46 )


      #define SFLASH_ID_N25Q512A             SFLASHID( 0x20, 0xBB, 0x20 )


      #define SFLASH_ID_ISSI25LP064          SFLASHID( 0x9D, 0x60, 0x17 )


      #define SFLASH_ID_N25Q064A             SFLASHID( 0x20, 0xBA, 0x17 )


      #define SFLASH_ID_W25Q64FV             SFLASHID( 0xEF, 0x40, 0x17 )


      #define SFLASH_ID_S25FL064L            SFLASHID( 0x01, 0x60, 0x17 )


      #define SFLASH_ID_S25FL128L            SFLASHID( 0x01, 0x60, 0x18 )


      #define SFLASH_ID_S25FL256L            SFLASHID( 0x01, 0x60, 0x19 )


      #define SFLASH_ID_N25Q128A             SFLASHID( 0x20, 0xBA, 0x18 )


      #define SFLASH_ID_DEFAULT              SFLASHID( 0x00, 0x00, 0x00 )



  • In 43xxx_Wi-Fi/WICED/platform/MCU/BCM4390x/peripherals/spi_flash/spi_flash.c, you have to add the part number information in sflash_capabilities_tables structure.


              { SFLASH_ID_N25Q064A,       { 8*MBYTE,    256,  .action = &micron_action,   .speed_advance = &micron_speed_config } },

              { SFLASH_ID_N25Q128A,       { 16*MBYTE,   256,  .action = &micron_action,   .speed_advance = &micron_speed_config } },


  •      If you are using any flash other than macronix flash, you have to add support in <platform_name>.mk file in the following manner.



Debugging Notes:

  • Please check for DEBUG_PRINT macro in 43xxx_Wi-Fi/apps/waf/sflash_write/sflash_write.c. Once you enable this macro, you should be able to see debug prints in the UART terminal where you should look for SFLASH ID and SFLASH size. If the support is correctly added, these two fields will show you the correct SFLASH ID and the size that you have added following the above mentioned steps.

          SFLASH Device ID ( 0x20ba18)
     SFLASH Size      ( 0x1000000)

  • The micron flash (N25Q128A) I have added in this example needed a 100k pull up resistor in the RESET pin as specified by the datasheet. Please check similar things in the datasheet of the flash you plan to add.
  • This blog post does not cover the porting effort of flash from a different manufacturer, in which case, you have to add the read, write, erase source code in the spi_flash.c for which you can refer to the already existing implementations.

Disclaimer: The attached demo code is developed to provide a reference to the customer, it has not been extensively tested. Also, it does not perform all the functionalities included in hello_client app available for Bluetooth devices in WICED SDK.



The Hello client demo app available for CYW20706, CYW20719 and CYW20735 in WICED SDK, is designed to connect and access services of the Hello sensor device. This post discusses about an example, which allows WiFi-BT Combo devices to act as a central device (client).



Extract the project in the attached zip file in /43xxx_Wi-Fi/apps/snip/snip/Bluetooth/ directory. Program the device using the ble_hello_client project. After programming, WICED device scans for the available Bluetooth devices. UUID and device name of the ble_hello_sensor project is already defined in application (ble_hello_client.c). WICED device recognizes the desired device and tries to connect to it, invoking the connection up callback.


Note that ble_hello_sensor should be running and advertising to test the client functionality. Both Combo and Bluetooth chips can be used for Hello sensor app. Be ensured that the UUID and device name of the Hello sensor device is correctly mentioned in Hello client app.


  We have some snip ,test codes in SDK release, this blog is showing how to use snip.dct_read_write, snip.apsta, snip.GPIO to finish one application. And the function is to join different AP by pressing user button. It will help you to understand how to join AP , how to read/write DCT area, be familiar with rule of GPIO operation. Test is based on Wiced release on CYW954907AEVAL1F EVB.



  1. STA join one AP, and ping , this is the APSTA from snip .
  2. Because CYW54907 has big internal flash and ram, so apsta includes COMMAN_CONSOLE function,

       you can type <status> to check the interface like below:

3. If you want to use command console ,really need big memory (2MB and above), and you need to enable it in makefile:


If you want to use the DCT mac address, you need to enable it in makefile:


Some other useful commands are showed here.

4. ADD user_1, user_2 GPIO test code into APSTA.

to find platform_gpio_buttons define in platform.c and platform.h

Below are some structure relationships in the code.

You will see real user_1, user_2 connections in the pdf circuit.


About user_1 and user_2 button initialization, these two pins are already set to INPUT_PULL_UP by default in the boot stage of the board,so you don’t need to initialize them again as a GPIO.

5.     Add DCT read code into APSTA.

  • Show notes about DCT usage
  • With the DCT in external FLASH, the second argument is ignored. For clarity, always use WICED_TRUE ---- This is for 54907 because DCT is in external flash.


  • wiced_dct_read_lock() and wiced_dct_read_unlock() need to be used with a couple.  But you do not need to call wiced_dct_read_lock() in order to write date to DCT.


  • DCT structure will be used by bootloader also , the sub-structure platform_dct_header_t, which is always at the start of the DCT area of the FLASH.
  • From SDK-3.7.0, it is possible to upgrade the DCT layout when doing SDK upgrading .
  • There are two DCT areas defined in the FLASH, designated as DCT1 and DCT2. we use this in a flip-flop arrangement. When need to update DCT area, we copy the “current” DCT to the opposite area , then indicate that “new” area is the “current” area. The “old ” area is viable DCT area.


    Below is the wifi config section printed:


6. Adding code to switch AP

  • IOCTL command description.
    • If you want to input “wl down” when DUT is in STA mode, call this function.


    • If you want to input “wl disassoc”, call this function


    • If you want to input an IOCTL command with value or not, please use below interface:

                 And it is better to add some wwd_wlan_status judge before jumping into  calling.


7. add all functions into apsta code:

    The steps are:

  1. to check the Button pressed status.
  2. to disassociate the AP.
  3. Network down.
  4. to write DCT to update the AP ssid which will be joined.
  5. to print the DCT updated.
  6. Network up, join the AP.






WICED Device Configuration Table (DCT) Users Guide



  We divide the SDK code into different module or library for specific function, and Hierarchical software design also is useful for the code maintenance. This blog is to show the log setting for different module.  Please see below architecture from SDK release document. Our aim is to print useful logs when issue happens,  upload one module picture from SDK release .


  • HOW TO Print LOGS
  1. To use “printf” directly, this is very convenient for the debug, but not easy to make a good management for the logs added. Some basic knowledge of print is in this link


     #include <stdio.h>

     int main()


        char ch = 'A';

        char str[20] = "";

        float flt = 10.234;

        int no = 150;

        double dbl = 20.123456;                         

        printf("Character is %c \n", ch);

        printf("String is %s \n" , str);

        printf("Float value is %f \n", flt);

        printf("Integer value is %d\n" , no);

        printf("Double value is %lf \n", dbl);

        printf("Octal value is %o \n", no);

        printf("Hexadecimal value is %x \n", no);

        return 0;



·    %d got replaced by value of an integer variable  (no),

·       %c got replaced by value of a character variable  (ch),

·       %f got replaced by value of a float variable  (flt),

·       %lf got replaced by value of a double variable  (dbl),

·       %s got replaced by value of a string variable  (str),

·       %o got replaced by a octal value corresponding to integer variable  (no),

·       %x got replaced by a hexadecimal value corresponding to integer variable

·       \n got replaced by a newline.


2.     In wwd_debug.h, wwd_debug.c , wiced_defaults.h

We defined Macros to control the log output for different MODULE.

Modules are Application, library, Webserver , Network, RTOS,

Security , WPS, Supplicant, Wiced , WWD(Wiced wi-fi Driver) .


We have good instructions and warnings for the log setting:


*  If printing is enabled, the stack of each thread that uses printing

* must be increased to at least 4 kBytes since the printf function uses

a lot of memory (including dynamic memory)

/* Select which group of functions are allowed to print */

/* WPRINT_ENABLE_<MODULE>_ERROR - Enable print messages in the respective <MODULE> that are present


* For instance, if WPRINT_ENABLE_WWD_ERROR is enabled, then trace messages that are under

* WPRINT_WWD_ERROR will be printed. This directive shall also result in an ASSERT if the target is built in DEBUG                                 mode.

* WPRINT_ENABLE_<MODULE>_DEBUG - Enable print messages in the respective module that are present as


* For instance, if WPRINT_ENABLE_WWD_DEBUG is enabled, then trace messages that are under

* WPRINT_WWD_DEBUG will be printed.


* WPRINT_ENABLE_<MODULE>_INFO - Enable print messages in the respective module that are present as


* For instance, if WPRINT_ENABLE_WWD_INFO is enabled, then trace messages that are under

* WPRINT_WWD_INFO will be printed.


If you disable all the logs, there will have a compiled error, so please keep this one at least:

#define WPRINT_ENABLE_APP_INFO           /* Application prints */



So general debug sequence for log enable:

    • Enable WPRINT_ENABLE_MODULE_INFO to track the process.
    • If found an error was printed out, check which module , then enable DEBUG and ERROR mode also. Be noted, Debug compile will go to an assert if enable ERROR layer .
    • Find the bug position , add more debug info by using the same level log print.

I think if you want to manage the log clearly , you can define one MACRO to just add your debug info ,like           #define WPRINT_ENABLE_BUG_DEBUG_INFO , after issue is fixed you can disable it .Another log print mode :


3.     Wiced_log_setting, it is often used on application area.

If you want to close the log , please change the log to WICED_LOG_OFF, the logs added in      the application will be disabled. And strongly suggest to use this debug info in application debug stage.

Log initialize at application_start and enum structure.

         wiced_log_init(WICED_LOG_INFO, render_log_output, wiced_time_get_time);

         wiced_log_msg(WLF_DEF, WICED_LOG_NOTICE, "wiced logging system is initialized\n");


typedef enum


    WICED_LOG_OFF = 0,











    WICED_LOG_PRINTF, /* Identifies log messages generated by wiced_log_printf calls */





b: How to write to STDOUT .

use this function:

Enable time output with log together.


STM32F469 porting in WICED

Posted by GauravS_31 Moderator Oct 10, 2018



The purpose of this document is to enable the WICED community to support a new MCU device using existing WICED Wi-Fi Driver (WWD) supported in WICED Studio. It allows user to use the MCU of their choice to achieve required system performance and cost goals. Though this document describes how to use a different MCU, Cypress community provides support only on the platforms/MCUs that are officially supported in WICED Studio. To learn more about the platforms/MCUs supported in WICED Studio, please refer to the WICED Studio Technical Brief. If you need support while porting to a different MCU, we recommend you to reach out to our partners.


This document covers the porting instructions with an example of Cypress’s Wi-Fi and Bluetooth combo device CYW4343W and ST MCU STM32F469.  Example leverages STM32F469-DISCO board as it has an SD card interface that makes it easy to access SDIO lines.





This document assumes that you have basic understanding of WICED Studio and WICED Software Stack. The following document is a set of instructions / guidelines, which could vary based on the MCU chosen. The resultant platform files have not gone through the standard validation or testing done on platforms which are part of standard WICED Studio release.



Modifications required in WICED Studio


Steps involved in supporting a new MCU update existing files available in WICED that are used for other MCUs/Platforms.


1. Creating your own platform directory

The platform folder “CYW94343WWCD3” is placed in 43xxx_Wi-Fi/platforms as shown in Figure 1.



Figure 1 Platform directory

CYW94343WWCD3 folder.jpg

It would contain the files necessary to access the host processor peripherals, their configuration, Wi-Fi NVRAM settings, platform makefile.


a. platform.h: Declaration of GPIOs, LEDs, peripherals and corresponding IRQs are provided here. It is a good practice to first create a platform pin definitions table in platform.h. This table would map the WICED pin name to the exact pin name of the STM32 host processor. It is basically provided in commented form. For instance, the WICED pin name WICED_GPIO_1 is mapped to STM32 port pin G10 as shown in Figure 2.


Figure 2 Platform pin definitions

CYW4343WWCD3 platform pin definitions image.jpg

This will help us determine the total number of WICED pins which in turn would help us to define the enum wiced_gpio_t. This enum basically contains the list of WICED pin names which would be mapped to STM32 port pins in platform.c. Likewise peripheral pins such as SPI, I2C, UART are defined using the enums wiced_spi_t, wiced_i2c_t, wiced_uart_t. The total pins to be defined must be known before defining an enum.


To allow UART terminal printing, we would need to assign the STDIO_UART used for UART standard I/O to the appropriate WICED UART pin defined above.


b. platform.c: source file describing the GPIO organization which includes the Wi-Fi control pins, strapping options, essential peripherals like debug UART initialization. Customer also needs to be careful about defining the structures specific to their peripheral requirement. They can refer to the expected structure format in existing WICED supported platforms; e.g for STM32F4xx host MCU: 43xxx_Wi-Fi/WICED/platform/MCU/STM32F4xx/peripherals/platform_mcu_peripheral.h. This structure format is also dependent on the host MCU and peripheral choice.


This is where we define the mapping of WICED pin names to the corresponding STM32 port pins as shown in Figure 3.


Figure 3 GPIO pin table

GPIO pin table.jpg

Similarly, the Wi-Fi control pins and Wi-Fi SDIO pins are as shown in Figure 4


Figure 4 Wi-Fi control pins and SDIO pins

Wi-Fi control pins and SDIO pins.jpg

It is important to note that the WWD enums shown above have already been defined in the WWD driver and they are used during Wi-Fi initialization.

Next the WICED peripheral structure would need to be defined so that it captures all the information required for its initialization and subsequent operation. This would typically include the WICED pin names defined earlier, peripheral driver constants, register flags. The peripheral driver library is specific to a host processor, in this case, it is available in stm32f4xx.h. For instance, a typical UART peripheral is defined in Figure 5 for STM32F4XX.

Figure 5 UART peripheral configuration

UART peripherals and runtime drivers.jpg

As shown above, the WICED pin name WICED_UART_1 is defined above. The UART tx and rx pins have been mapped to the appropriate WICED GPIO pins defined earlier. The UART port is mapped to USART3 which is defined in stm32f4xx.h as a register address. The DMA configuration shown above was found from the TRM of STM32F469.

The hardware connections should be strictly made as per the mapping defined above.

The external devices such as LED, buttons, STDIO UART need to be initialized using the function platform_init_external_devices(). This function is called during MCU initialization.

The interrupt handler for a peripheral is defined using WWD_RTOS_DEFINE_ISR() and mapped to ISR using WWD_RTOS_MAP_ISR().


c. wifi_nvram_image.h: This is the nvram file for the WLAN module. This is supplied by the module partner. Since we are using the same Murata module used in NEB1DX_01platform, the nvram file can be interchangeably used.


d. platform_config.h: Clock configuration for the host MCU is provided here. For the host processor, the CPU clock frequency (CPU_CLOCK_HZ), crystal source (HSE_SOURCE), system clock divider constants (AHB_CLOCK_DIVIDER, APB1_CLOCK_DIVIDER, APB2_CLOCK_DIVIDER), PLL constants (PLL_SOURCE, PLL_M_CONSTANT, PLL_N_CONSTANT, PLL_P_CONSTANT, PLL_Q_CONSTANT, PLL_R_CONSTANT), system clock source (SYSTEM_CLOCK_SOURCE), systick clock source (SYSTICK_CLOCK_SOURCE), internal flash constants (INT_FLASH_WAIT_STATE, PLATFORM_STM32_VOLTAGE_2V7_TO_3V6), watchdog (DBG_WATCHDOG_TIMEOUT_MULTIPLIER) are used for configuring the host STM32F469. For the STM32F469 MCU, STM32CubeMX ( - STM32Cube initialization code generator - STMicroelectronics ) software was used. Using the STM32CubeMX tool, customers can select the target host MCU and the peripherals required for their use-case. The interactive tool also provides the option to correctly configure the clock based on the clock configuration in STM32CubeMX. The macros for Wi-Fi options WICED_WIFI_USE_GPIO_FOR_BOOTSTRAP_1, WICED_WIFI_OOB_IRQ_GPIO_PIN, WICED_USE_WIFI_POWER_PIN, WICED_USE_WIFI_32K_CLOCK_MCO and WICED_USE_WIFI_POWER_PIN_ACTIVE_HIGH need to be correctly defined as they would be used during WICED initialization. Please make sure to remove or comment out USES_RESOURCE_FILESYSTEM macro as we are putting all the resources in internal flash.


e. <platform_name>.mk: This is the platform makefile which contains information on the WLAN chip and host processor as well as Wi-Fi bus interface used which is SDIO for this module. Since the internal flash is enough to accommodate both Wi-Fi FW and clm blob, we have treated the memory resources as DIRECT RESOURCES (RESOURCES_LOCATION?= RESOURCES_IN_DIRECT_RESOURCES) which will build the WLAN FW and CLM blob along with the main application and put it in internal flash. The HSE_VALUE is the external crystal frequency used for clocking the host processor which is 8 MHz.


Creating these platform files require thorough knowledge of the host MCU. It is strongly advised to go through the datasheet and Technical Reference Manual (TRM) of the host MCU first.


We have interfaced the STM32F469 MCU to the Murata Type1DX through SDIO interface for which platform files should provide the correct pin mapping. To ease up the debugging, one UART port was used for which the DMA configuration, correct clock configuration, crystal selection, PLL settings need to be taken care of in platform files.


Essential points:


a. Wi-Fi control pins: These pins are used during initialization of WICED (43xxx_Wi-Fi/WICED/platform/MCU/wwd_platform_separate_mcu.c); hence the created platform file(s) should mention these pins.


b. Wi-Fi SDIO bus pins: For 4-bit SDIO transfer, data transfer lines (D0-D3), SDIO_CMD, SDIO_CLK along with the provision for OOB_IRQ should be provided in the platform definition. (43xxx_Wi-Fi/WICED/platform/MCU/STM32F4xx/WWD/wwd_SDIO.c).


Points to Check:


If the UART port is not working as expected, check the HW pins, PLL settings, crystal selection made in platform.config.h. To understand the clock organization better, the user can check-out 43xxx_Wi-Fi/WICED/platform/MCU/STM32F4xx/peripherals/libraries/system_stm32f4xx.c.


2. Creating the Memory map

The memory map for the host MCU can be generally found in 43xxx_Wi-Fi/WICED/platform/MCU/STM32F4xx/GCC as shown in Figure 6.


Figure 6 Memory map STM32F469

Memory map STM32F469.jpg

The user can create their own linker-script based on the memory organization of the host MCU. (STM32CubeMx software can be used to check the memory organization, but proper modification to the linker script is up-to user’s competence).


3. Modifying the common platform structure


The user must add the number of UART ports, number of SPI ports (if used) etc. for the target platform in 43xxx_Wi-Fi/WICED/platform/MCU/STM32F4xx/peripherals/platform_mcu_peripheral.h.


The number of flash sectors for the host MCU need to be specified separately as well in 43xxx_Wi-Fi/WICED/platform/MCU/STM32F4xx/WAF directory. The macro PLATFORM_APP_END_SECTOR needs to be defined because it would be used during the process of loading a new program and DCT into internal flash. For STM32F469, the macro was defined as per the information specified in the TRM.


As the source files for STM32F4xx series is already present in WICED Studio, we have enabled the platform_name macro (STM32F469_479xx) in 43xxx_Wi-Fi/WICED/platform/MCU/STM32F4xx/peripherals/libraries/stm32f4xx.h.


TP1: At this point, the compilation with WICED build system should pass for the created platform. The build statement should be snip.<test_basic>-<platform_name>


4. Adding the SDIO interface


If the compilation is successful, you can build and download scan application using snip.scan-CYW94343WWCD3 download run. We did not use download_apps in the build statement because we have placed our resources including WLAN firmware and CLM blob in internal flash memory. If you have used ST-Link, you can refer to the post Adding ST-Link support in WICED to enable ST-Link support in WICED. After the programming is successful, you can check the UART terminal output. If the terminal does not print the WLAN MAC address, WLAN firmware and WLAN CLM details, it means that WLAN interface was not initialised. A typical scenario is as shown in Figure 7.


Figure 7 WLAN interface not working

Stuck at creating packet pools.jpg

Check where the execution is getting stuck. You can enable the macro WPRINT_ENABLE_WWD_DEBUG to enable WWD debug prints. If SDIO bus does not initialize (check comment in WWD), make sure WL_REG_ON pin on the Murata module is connected to the pin defined by the index WWD_PIN_POWER in platform.c. Check SDIO clock control register for further debugging. Use SLOW_SDIO_CLK and SDIO_1_BIT in <platform_name>.mk file. 


If it is stuck at waiting on HT clock, the LPO has not been configured correctly. The LPO_IN pin needs to be connected to external source defined by the index WWD_PIN_32K_CLK defined in platform.c.


If you are getting stuck in F2, FIFO underflow could be a probable cause. Check the SDIO_STA (interrupt status) register to debug the issue. You can check wwd_sdio.c and wwd_bus_protocol.c. You can consider disabling the interrupt received flag SDIO_MASK_SDIOITIE from the SDIO mask register in STM32F4xx/WWD/wwd_sdio.c. In that case, the function wwd_bus_packet_available_to_read() would have to be commented out because this function would check for interrupt by reading the IntStatus register of the WLAN chip.


The patch file “WWD_changes.patch” contains the specific changes made to WWD driver discussed above which can be applied.



Test & Debug


a. Debugging and testing the SDIO interface

The WWD contains debug prints to indicate error or failure in function execution inside WWD. To enable WWD debugging, go to wiced_defaults.h and enable the following macros:


#define WPRINT_ENABLE_WWD_INFO         /* Wiced Wi-Fi Driver prints */




Whenever the host processor needs to initialize or access the WLAN interface, it uses the SDIO interface and SDIO packets are transmitted/received across the interface. It is possible to evaluate the WWD and SDIO bus TX/RX statistics at any WWD function call to understand if there were any issues in the WWD and SDIO bus transactions. It basically provides us two types of statistics:


WWD Stats: This is encapsulated in the structure wwd_stats_t and it captures the TX/RX stats at WWD driver.


typedef struct


uint32_t tx_total;      /* Total number of TX packets sent from WWD */

uint32_t rx_total;      /* Total number of RX packets received at WWD */

uint32_t tx_no_mem;     /* Number of times WWD could not send due to no buffer */

uint32_t rx_no_mem;     /* Number of times WWD could not receive due to no buffer */

uint32_t tx_fail;       /* Number of times TX packet failed */

uint32_t no_credit;     /* Number of times WWD could not send due to no credit */

uint32_t flow_control;  /* Number of times WWD Flow control is enabled */

} wwd_stats_t;


Bus stats: This is encapsulated in the structure wwd_bus_stats_t and it contains information on SDIO TX/RX packet stats at the interface.


typedef struct


uint32_t cmd52;             /* Number of cmd52 reads/writes issued */

uint32_t cmd53_read;        /* Number of cmd53 reads */

uint32_t cmd53_write;       /* Number of cmd53 writes */

uint32_t cmd52_fail;        /* Number of cmd52 read/write fails */

uint32_t cmd53_read_fail;   /* Number of cmd53 read fails */

uint32_t cmd53_write_fail;  /* Number of cmd53 write fails */

uint32_t oob_intrs;         /* Number of OOB interrupts generated by wlan chip */

uint32_t sdio_intrs;        /* Number of SDIO interrupts generated by wlan chip */

uint32_t error_intrs;       /* Number of SDIO error interrupts generated by wlan chip */

uint32_t read_aborts;       /* Number of times read aborts are called */

} wwd_bus_stats_t;


The function wwd_print_stats ( wiced_bool_t reset_after_print ) evaluates the WWD packet stats and SDIO bus stats at the interface. To enable this function, enable the macro WWD_ENABLE_STATS in wiced_defaults.h. As an example, the wwd_print_stats(WICED_FALSE) is called inside SDIO/wwd_bus_protocol.c after WLAN firmware download wwd_bus_sdio_download_firmware( ) and before waiting for F2 to be ready.


Figure 8 Testing WWD stats

testing WWD stats.jpg

The results are shown below:


Working interface


WWD Stats..

tx_total:0, rx_total:0, tx_no_mem:0, rx_no_mem:0

tx_fail:0, no_credit:0, flow_control:0

Bus Stats..

cmd52:151, cmd53_read:0, cmd53_write:29

cmd52_fail:0, cmd53_read_fail:0, cmd53_write_fail:0

oob_intrs:0, sdio_intrs:151, error_intrs:0, read_aborts:0


Non-working interface

WWD Stats..

tx_total:0, rx_total:0, tx_no_mem:0, rx_no_mem:0

tx_fail:0, no_credit:0, flow_control:0

Bus Stats..

cmd52:151, cmd53_read:0, cmd53_write:29

cmd52_fail:0, cmd53_read_fail:0, cmd53_write_fail:0

oob_intrs:0, sdio_intrs:30, error_intrs:0, read_aborts:0


We can see that in a non-working interface, the number of sdio_intrs is far less than those in a working interface. So basically, the WWD packet stats would help us in characterizing the SDIO interface.


b. Testing i-perf statistics

To test the network performance of the added platform, a basic i-perf throughput test was done in normal environment between the WICED platform and a WIN 10 PC. The WIN 10 PC was set up as TCP server and the test.iperf_app was used to set up a TCP client in the WICED side (WICED board TX and PC is the RX here).


PC Side:


Run the command prompt in the i-perf directory and use the following command


iperf -s -w 655k


WICED Setup:

Build and download the test.iperf_app with the following packet pools settings in the






iperf -c <ip_address of server> -w 655k


The throughput number we achieved for TCP client-server architecture is 5.66 Mbits/sec as shown in Figure 9.


Figure 9 I-Perf throughput

The help article for iperf set-up in WICED platform can be found at 43xxx_Wi-Fi/apps/test/iperf_app/README-Iperf.pdf.


General bringup issues


HT Avail Timeout

  • Caused due to wrong nvram.txt or the firmware.
  • Check the firmware matches the chip revision.
  • Check the LPO_IN connection.


Interrupt's not working/IOCTL timeout

  • Disable OOB and try with in band interrupt first.
  • For OOB, make sure that the GPIO number is provided correctly


Throughput Issues


  • Check whether we have enough bus level throughput.
  • Check whether the connection is made with proper capability. [11ac, 11n..80MHz, 40MHz etc]
  • Open air congestion might be a problem. Try it in a RF chamber.
  • Check the operating rate [wl rate].
  • Check the rssi value to see whether Antenna is proper [wl rssi].


This blog provides a guideline to add support ST-Link (ST Micro’s programming & debug hardware) in an existing WICED SDK framework.



Consider this document as a guideline, which has not been extensively tested and the procedure mentioned below could differ for different versions of WICED Studio & ST-Link.




ST-Link is the on-board programmer used to program the code in ST MCU, details of which can be found at ST website. WICED uses OpenOCD to download the programs to the target MCU (ST host MCU, CYW43907, PSoC 6). In most of the standard WICED EVBs, an FTDI chip (FT2232H) has been used to provide the USB-UART  / USB-JTAG bridge functionality which is what has been the standard download procedure followed by the OpenOCD in WICED.




Brief Introduction about OpenOCD

Open On-Chip Debugger (OpenOCD) is a free open-source project that facilitates downloading, debugging by using a debug adapter like ST-Link, FT2232H etc. OpenOCD works either by using commands or by using configuration files. When configuration is done and a connection to the target is established, OpenOCD will start running as a daemon in the background. The OpenOCD directory file has a folder called “scripts”. In this folder, you will see "interface", "board", and "target" folders. These are pretty much the only folders you need.

  • Interface: Configuration files for hardware adapters, for example “stlink-v2-1.cfg”.
  • Board: Configuration files for common development boards like “stm32f469discovery.cfg” .. etc. You can see that these files reuse configuration files from interface and target.
  • Target: Configuration files for MCU Chips.

For detailed understanding of OpenOCD procedure and syntax, one can find their documentation at




WICED Download and debug procedure:

  In WICED, an OpenOCD command is put into the .gdbinit file by the makefile system during compilation.
Wiced Eclipse has an optional component "GDB Hardware Debugging" installed.  This allows it to instruct GDB to access a "GDB remote protocol server" via TCP.
Hence when Eclipse starts a debug session, it starts GDB, which in turn causes the .gdbinit OpenOCD command to be executed. OpenOCD is a "GDB remote protocol server", and next, Eclipse instructs GDB to connect to it.
During the startup of OpenOCD, it uses various JTAG & ARM protocols to interrogate the target chip. Once this initial interrogation is done, OpenOCD receives requests over TCP from GDB and services those requests on the target chip as needed details about this remote GDB can be found at GDB documentation.



How to add support for ST-Link:

WICED Environment uses the makefiles, configuration files as located in 43xxx_Wi-Fi/tools/makefiles and 43xxx_Wi-Fi/tools/OpenOCD respectively to download the code to the target MCU. Some changes have been made in the makefiles responsible for the download process and rest of the modifications were done in the OpenOCD directory, details of which can be found in the attached. Please note that modifying the existing makefiles, OpenOCD directory to enable ST-Link support is a one-way approach; i.e, you can’t program the other WICED boards (using a FT2232H chip) normally without restoring both directories back to the one shipped with SDK. So, it’s always recommended to make a back-up of the directories before replacing them with the attached.


In the example implementation, a custom JTAG macro was defined in the platform makefile ( in the following way.




Based on the custom JTAG macro, openocd binary (openocd-all-brcm-libftdi.exe), as located in 43xxx_Wi-Fi/tools/OpenOCD/Win32/openocd-all-brcm-libftdi.exe expects a <custom JTAG macro>.cfg file in the 43xxx_Wi-Fi/tools/OpenOCD directory as shown in the figure below.

In this case, the stm32f469discovery.cfg file was copied from 43xxx_Wi-Fi/tools/OpenOCD/scripts/board/stm32f469discovery.cfg directory to the 43xxx_Wi-Fi/tools/OpenOCD directory. This stm32f469discovery.cfg has all the necessary interface, transport, target, reset_config specified. For a created platform, customer needs to create their own .cfg file based on the JTAG macro chosen and place them in 43xxx_Wi-Fi/tools/OpenOCD directory. If the created .cfg file has some error, a good place to start the debug procedure would be the openocd log generated as part of the build system which can be found at 43xxx_Wi-Fi/build/openocd_log.txt.


Refer to the files attached to this blog. We suggest you do a ‘Diff’ of the existing WICED Studio files and the attached files to understand the changes.


    We shared four ways to set wifi mac address,  this blog is to show the process .

    Test is based on CYW954907AEVAL1F .


  • DCT  mode:
  2. 43xxx_Wi-Fi\generated_mac_address.txt

     Modify the address in the directory , it works.

     #define NVRAM_GENERATED_MAC_ADDRESS "macaddr=00:A0:50:38:f6:35"

     #define DCT_GENERATED_MAC_ADDRESS "\x00\xA0\x50\xe8\xf3\x48"

     #define DCT_GENERATED_ETHERNET_MAC_ADDRESS "\x00\xA0\x50\xe5\xf3\x47"


  • OTP mode
  2. Need to clean the building, then make again.


    Starting WICED vWiced_006.002.001.0002

    Platform CYW954907AEVAL1F initialised

    Started ThreadX v5.8

    Initialising NetX_Duo v5.10_sp3

    Creating Packet pools

     WLAN MAC Address : B8:D7:AF:4D:1D:D6

     WLAN Firmware    : wl0: May 15 2018 19:39:17 version (r689934) FWID 01-d6f88905

     WLAN CLM         : API: 12.2 Data: 9.10.74 Compiler: 1.31.3 ClmImport: 1.36.3 Creation: 2018-05-15 19:33:15


  1. Let us to go to MFG mode to check the OTP area.

        Have a test with mfg mode:

       test.mfg_test-CYW954907AEVAL1F download download_apps run

  • Modify it in NVRAM:
  • 43xxx_Wi-Fi\platforms\CYW954907AEVAL1F\board_revision\P101

     static const char wifi_nvram_image[] =

      "sromrev=11" "\x00"

      "vendid=0x14e4"                                                      "\x00"

      "devid=0x43d0" "\x00"

      "macaddr=00:A0:50:38:f6:35" "\x00"


  2. Do nothing, clean and build again.
  3. The mac address still is WLAN MAC Address : B8:D7:AF:4D:1D:D6

I do not find anywhere to fix the MAC address into nvram setting, so I presume OTP priority is higher than NVRAM,  if OTP existed the NVRAM mac address will be ignored .



  1. Enable the define in app makefile: GLOBAL_DEFINES     += MAC_ADDRESS_SET_BY_HOST
  2. Modify the code, add simple test:
  3. 43xxx_Wi-Fi\WICED\platform\MCU\BCM4390x\

    4. bcm4390x_platform.c

wwd_result_t host_platform_get_mac_address( wiced_mac_t* mac )



    wiced_mac_t* temp_mac;

    wiced_result_t result;

    result = wiced_dct_read_lock( (void**)&temp_mac, WICED_FALSE, DCT_WIFI_CONFIG_SECTION, OFFSETOF(platform_dct_wifi_config_t, mac_address), sizeof(mac->octet) );

    if ( result != WICED_SUCCESS )


        return (wwd_result_t) result;


    memcpy( mac->octet, temp_mac, sizeof(mac->octet) );

       mac->octet[0]= 0x00;

       mac->octet[1]= 0x11;

       mac->octet[2]= 0x22;

       mac->octet[3]= 0x33;

       mac->octet[4]= 0x44;

       mac->octet[5]= 0x55;

    wiced_dct_read_unlock( temp_mac, WICED_FALSE );




    return WWD_SUCCESS;



Starting WICED vWiced_006.002.001.0002

Platform CYW954907AEVAL1F initialised

Started ThreadX v5.8

Initialising NetX_Duo v5.10_sp3

Creating Packet pools

WLAN MAC Address : 00:11:22:33:44:55

WLAN Firmware    : wl0: May 15 2018 19:39:17 version (r689934) FWID 01-d6f88905

WLAN CLM         : API: 12.2 Data: 9.10.74 Compiler: 1.31.3 ClmImport: 1.36.3 Creation: 2018-05-15 19:33:15

Console app

   We have different options in the command input line for setting a global define. Below topic is a simple explanation for these inputs.

Actually you can also get most of them from the  makefile.  We also provide examples after wiced studio installed.


  • snip.scan-BCM943362WCD4

        Build for release


  • snip.apsta-BCM943362WCD4-debug


       It means if you want to use Jtag or Jlink to have a debug, you need to add this option to get a debug image.


  • snip.apsta-BCM943340WCD1-FreeRTOS-LwIP download run

       Keyword : FreeRTOS-LwIP download run

It means use FreeRTOS system, LwIP network protocol and use the default USB-JTAG programming interface.


  • demo.aws_iot.shadow-BCM94343W_AVN download_apps download run


If you want to download app into external flash by using SFLASH_WRITER_APP, you need to enable this option.


  • snip.scan-BCM943362WCD4-FreeRTOS-LwIP-SDIO download run

        Keyword:  FreeRTOS-LwIP-SDIO

It means using FreeRTOS system, LwIP network protocol, SDIO interface for communication.


  • snip.scan-BCM943362WCD4-ThreadX-NetX_Duo-SDIO download run

        Keyword:  ThreadX-NetX_Duo-SDIO

It means using Threadx OS system, Netx network protocol, SDIO interface communication.


  • snip.scan-BCM943362WCD4-ThreadX-NetX-SPI download run

       Keyword:  ThreadX-NetX-SPI

It means using Threadx OS system, Netx network protocol, SPI communication interface.


  • test.wifi_join-CYW954907AEVAL1F VERBOSE=1 download run

       Keyword: VERBOSE=1

It means compile and download log will output with a more detailed logs.


we also have some other options like  [JTAG=xxx]  [no_dct] [JOBS=x] ,  below comments are important for input compile options:


    * Component names are case sensitive

    * 'WICED', 'SDIO', 'SPI' and 'debug' are reserved component names

    * Component names MUST NOT include space or '-' characters

    * Building for release is assumed unless '-debug' is appended to the target

    * Some platforms may only support a single interface bus option


Below are instructions for OTA2, please refer to the document carefully .


Key words are:

//Build an OTA2 Update Image suitable for upgrade server:




//Build an OTA2 Factory Reset Image suitable for manufacturing FLASHing of the device:




//It includes waf/ota2_bootloader, OTA2_factory_reset_image.bin, waf/ota2_failsafe, DCT, Application LUT, ota2_extract, and the application




// Below is for secure flash and version management.






//show update from version of the SDK.



//There were optional structures in the System DCT that are now always included. They are the Bluetooth (BT), Peer to Peer (P2P) and Over The Air 2 (OTA2) sub-structures. This information must also be designated so that the code knows which (if any) of the optional structures were used in the original application build DCT.






WICED Over The Air (OTA) v2 Firmware update Users Guide


TCP stream API

Posted by PriyaM_16 Moderator Jul 29, 2018

WICED provides multiple APIs to implement a TCP connection. This blog discusses the TCP stream_read/write APIs which are more convenient for receiving/sending a large chunk of data.

The usual flow of sending TCP packets is: packet creation-> write data into packet-> set the end of the data portion-> send the packet -> delete the packet.

This method of sending TCP packets turns out to be cumbersome for large chunk of data as one has to go back and forth between packet creation and deletion. The TCP stream APIs provide a better way to stream successive data without worrying about the packet boundaries. The TCP stream APIs takes care of creating the packet and sending it unless the entire buffer is sent. The following diagram gives a simple overview of differences between existing APIs and stream APIs:


Please refer the wiced_tcpip.h file in 43xxx_Wi-Fi\include dir for description of the provided TCP APIs. Some of the stream APIs are listed below:

wiced_result_t wiced_tcp_stream_init( wiced_tcp_stream_t* tcp_stream, wiced_tcp_socket_t* socket );

wiced_result_t wiced_tcp_stream_write( wiced_tcp_stream_t* tcp_stream, const void* data, uint32_t data_length );

wiced_result_t wiced_tcp_stream_write_resource( wiced_tcp_stream_t* tcp_stream, const resource_hnd_t* res_id );

wiced_result_t wiced_tcp_stream_read( wiced_tcp_stream_t* tcp_stream, void* buffer, uint16_t buffer_length, uint32_t timeout );

wiced_result_t wiced_tcp_stream_read_with_count( wiced_tcp_stream_t* tcp_stream, void* buffer, uint16_t buffer_length, uint32_t timeout, uint32_t* read_count );

wiced_result_t wiced_tcp_stream_flush( wiced_tcp_stream_t* tcp_stream );


Please find attached the tcp_client application modified to use the wiced_tcp_stream_write() API.

This blog dicusses the download procedure on CYW43907 using external JTAG device - Jlink Segger in WICED SDK 6.2 and future releases.  Blog Downloading and debugging CYW43907 using Jlink Segger is valid only for SDKs prior to WICED SDK 6.2.


The hardware connections to connect CYW943907AEVAL1F's JTAG with j-link are tabulated below:



Segger jlink





































The switches in SW4 on CYW943907AEVAL1F need to be closed to use an external JTAG. (By default the switches are open)



To Download the application, we need J-Link tool: Please download J-Link tool from SEGGER website and install it. As CYW4390x was not a part of the supported devices list of SEGGER J-LInk, we need to make use of flashloader tool from SEGGER to drive the sflash of CYW4390x. Please copy flashloader_CYW4390x_QSPI.elf as attached here to the Devices/Cypress/ folder in Segger Installation directory (should look something like this: C:\Program Files (x86)\SEGGER\JLink_V640\Devices\Cypress). Modify JLInkDevices.xml in the same directory for adding CYW4390x in support list.




        <ChipInfo Vendor="Cypress" Name="CYW43907" Core="JLINK_CORE_CORTEX_R4" WorkRAMAddr="0x004A0000" WorkRAMSize="0x00100000" JLinkScriptFile="Devices/Broadcom/BCM43907.JLinkScript" />

        <FlashBankInfo Name="QSPI Flash" BaseAddr="0x14000000" MaxSize="0x08000000" Loader="Devices/Cypress/flashloader_CYW4390x_QSPI.elf" LoaderType="FLASH_ALGO_TYPE_OPEN" />





For programming the image via J-Link connector, the JLink path need to be declared in WICED build string. Add the path of JLink.exe from the downloaded J-Link tool.


Example: For downloading test.console application, make the target as follows

test.console-CYW943907AEVAL1F JTAG=jlink-native  JLINK_PATH="C:/Program\ Files\ \(x86\)/SEGGER/JLink_V630c/" JLINK_EXE="JLink.exe" download run


To debug through J-Link, you need to create your own J-Link debug configuration in WICED Studio, details about which can be found out in the attached document.


     The difference between Signal mode and Direct mode is: we only need to connect the EVB with the test AP created by AP, then AP will have a menu to test TX and RX related. Its aim is to figure out if the actual running power is matching what you want, RX path has no RF de-sense in a normal running mode.   If signal mode passed all the RF standard, we can have a confidence that current RF path include TX and RX, current RF configuration like NVRAM have no critical issues.  We can move the product into next long-run function tests.


  • Which EVB is for the tests?

I choose 43340 because it has 2.4G and 5G together.

  • How to set 8860C before test.

       1. Set the static IP address


    2.  configuration .


Which means creating a AP at 153 channel with 6M rate and power is -15dbm.

After AP created we use command to join the AP, then we can do the test .



  • Which application is needed for the tests?

I used the command console for the test because we can use a lot of embedded commands to join a specific AP and do some command input. 

And we are using the normal firmware for the test, please see the command output.

         test.console-BCM943340WCD1 download run


  • Which commands are needed before the tests?

After connection established “scan_suppress 1” , “roam_disable ” are preferred .

PM = 0 is good to be set also.

In command console:

Usage: scan_disable <1 = disable scan|0 = enable scan>

> scan_disable 1

If you didn’t have this command, please add it according another blog.


  • How to change country for a test ?

Please input “set country ”, then get channel , choose one channel to do connection with the AP created by instrument.

     > get_country

         Country is US (US/0)

     > set_country CN/0

     > get_country

         Country is CN (CN/0)

     > get_channels

          1  2  3 4  5  6  7  8 9  10  11 12  13  149 153  157  161 165  >

  • TX test results


Filter Blog

By date:
By tag: