Appendix C – WILC SDIO Protocol Example
After successfully loading the WILC module, enter the if config wlan0 up
command to bring up the Wi-Fi® interface. It initializes WILC SDIO, reads the Chip ID, downloads Wi-Fi firmware and brings up the WLAN interface.
Upon calling the if config wlan0 up
command, the wilc_mac_open()
function is invoked first, in which wilc_wlan_initialize()
is called to initialize the WLAN interface wilc_wlan_init
, which calls the corresponding hif_init()
to bring up the HIF layer. If the SDIO interface is used, wilc_sdio_init( )
is called, and if the SPI interface is used, wilc_spi_init()
is called. The sequence of SDIO packets sent while initializing the WLAN interface is described in this section.
As per WILC’s driver implementation, the first command to send in the wilc_sdio_init( )
function is as follows.

The Code Storage Area (CSA) Enable bit controls access to the Code Storage Area for this function. Clearing this bit to ‘0
’ blocks any read or write access to the CSA. Setting this bit to ‘1
’allows access to the CSA. Upon Reset, this bit is cleared to ‘0
’. The code sets the 7th bit of Function Basic Registers (FBR) of function 0 with address 0x100
to enable CSA.
0x100
The corresponding SDIO logs are as follows.
Direction: From Host
Command: 0x34
Argument: 0x80020080
CRC: 0x6C
- Command starts with Start bit as ‘
0
’ - Direction as ‘
1
’ that is from host - CMD52 identifier as 110100b
- Argument value of
0x80020080
which has R/W flag as ‘1
’ - Function number as 0
- RAW flag as ‘
0
’ - Register address as
0x10
- Write data as 0x80 (which sets CSA Enable bit of above said register)
- CRC as
0x6C
- End bit as ‘
1
’
ATWILC’s response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1080
CRC: 0x5A
- Start bit as ‘
0
’ - Dir ‘
0
’ which is from card to host - CMD52 identifier as 110100b
- Argument value of
0x00001080
which has response flag as0x10
- Function number as 0
- RAW flag as ‘
0
’ - Register address as
0x10
- Write data as 0x80 (same data which is sent in previous packet)
- CRC as
0x5A
- End bit as ‘
1
’
The RAW flag is set; therefore, the same register is read immediately to make sure the bit is set. The read command from the host is as follows:
Direction: From Host
Command: 0x34
Argument: 0x20000
CRC: 0x36
ATWILC’s response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x10C7
CRC: 0x01
From the above log, C7 is returned as the data that has the CSA Enable bit set.
Set the Function 0 block size as 512 in address 0x10-0x11
, which is in the Card Common Control Registers (CCCR) of the Common I/O Area (CIA).
0x10-0x11


The SDIO logs for above commands are as follows:
Direction: From Host
Command: 0x34
Argument: 0x80002000
CRC: 0x01
The response for the above command from ATWILC is as follows. It is sent for address 0x10
, with data as 0x00
(lower byte of 512, 0x0200
).
Direction: From Client
Command: 0x34
Argument: 0x1000
CRC: 0x1B
The next CMD52 is sent for address 0x11
, with data as 0x02
(higher byte of 512, 0x0200
).
Direction: From Host
Command: 0x34
Argument: 0x80002202
CRC: 0x05
The response for the above command from ATWILC is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1002
CRC: 0x09
After setting the Function 0 block size successfully, enable Function 1 by setting the IOE1 bit (I/O enable) in the Card Common Control Registers, with address 0x02
and data 0x02
.
0x02
and 0x03
The SDIO logs are as follows:
Direction: From Host
Command: 0x34
Argument: 0x80000402
CRC: 0x4D
The response from ATWILC for above command is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1002
CRC: 0x09
If the RAW flag is set as ‘1
’, the register with address 0x02
is read using the sdio_readb()
function immediately after writing using sdio_writeb()
.
Direction: From Host
Command: 0x34
Argument: 0x400
CRC: 0x44
The R/W flag is ‘0
’, the function number is 0, the RAW flag is ‘0
’, the register address is 0x02
, the read data are 0x00
and CRC:0x44
.
The response from ATWILC is as follows:
As per CMD52 response R5, the argument value of 0x00001002
has the response flag as 0x10
and the read data as 0x02
. The read data are the same as the one written previously. This means Function 1 is enabled (IE1) in CCCR.
After enabling Function 1 as above, ensure Function 1 is ready by reading the IOR1 bit (I/O Ready) in CCCR with the address 0x03
. The register must return the value of 0x02
to set the IOR1 bit.
The SDIO logs are as follows:
Direction: From Host
Command: 0x34
Argument: 0x600
CRC: 0x52
ATWILC’s response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1002
CRC: 0x09
From the above argument, read data are returned as 0x02
, which means IOR1 is set and Function 1 is up.
Set the Function 1 block size as WILC_SDIO_BLOCK_SIZE
, which is 512. Address 0x110-0x111
holds I/O block size for Function 1. This is sent as two CMD52 commands.
SDIO logs are as follows:
Direction: From Host
Command: 0x34
Argument: 0x80022000
CRC: 0x5F
The above command set data is 0x00
(last byte of 512, 0x0200
) to address 0x110
.
ATWILC’s response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1000
CRC: 0x1B
The next command set data are 0x02
(first byte of 512, 0x0200
) to address 0x111
.
Direction: From Host
Command: 0x34
Argument: 0x80022202
CRC: 0x5B
ATWILC’s response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1002
CRC: 0x09
Set Interrupt enable for Function 1. To set this, the IEN1 and IENM bit in the CCCR register in address 0x04
needs to be set.
0x04
IENx: Interrupt Enable for Function x. Setting this bit to ‘0
’ prevents any interrupt from this function from being sent to the host. Setting this bit to ‘1
’ allows this function’s interrupt to be sent to the host provided that the host Interrupt Enable (Bit 0) is also set to ‘1
’.
IENM: R/W Interrupt Enable Master. If this bit is cleared to ‘0
’, no interrupts from this card are sent to the host. If this bit is set to ‘1
’, any function’s interrupt is sent to the host.
Commands sent from host to ATWILC are as follows:
Direction: From Host
Command: 0x34
Argument: 0x80000803
CRC: 0x30
ATWILC’s response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1003
CRC: 0x00
ATWILC’s response is as follows:
The RAW flag is set as ‘1
’; therefore, the same register is read again to ensure the IE1 and IENM bits are set. Commands sent from host to ATWILC are as follows:
Direction: From Host
Command: 0x34
Argument: 0x800
CRC: 0x30
ATWILC’s response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1003
CRC: 0x00
From the above log, it is returning the data as 0x03
, which indicates the IE1 and IENM bits are set.
Read chip ID from the device to know if the device is ATWILC1000 or ATWILC3000.

Read the register at address 0x1
. If the chip ID is not WILCS02, proceed to check other device IDs. Next, read the register at address 0x3b0000
to determine if the chip ID is ATWILC3000. If it is not, read the register at address 0x1000
to obtain the ATWILC1000 chip ID. The function wilc->hif_func->hif_read_reg()
will call either wilc_sdio_read_reg()
or wilc_spi_read_reg()
, depending on the host interface used.
The SDIO interface is used; therefore, wilc_sdio_read_reg()
will be called. The address range 0xF0-0xFF
is reserved for Vendor Unique registers accessed using CMD52, while other registers use CMD53.
Before performing read/write operations, set the address pointer to Function CSA. This pointer consists of three bytes, forming a 24-bit pointer to the desired byte in the CSA for reading or writing. The CSA was enabled in previous commands. The address range 0x10C-0x10E
holds the pointer to Function 1 CSA.

The following commands set address 0x3b000000
to address 0x10C-0x10E
:
Direction: From Host
Command: 0x34
Argument: 0x80021800
CRC: 0x4C
It sets data 0x00
(last byte of 0x3b00000
) to address 0x10C0
.
ATWILC’s response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1000
CRC: 0x1B
The next command sets data 0x00 (second byte of 0x3b00000
) to address 0x10D0
.
Direction: From Host
Command: 0x34
Argument: 0x80021A00
CRC: 0x5A
ATWILCC response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x1000
CRC: 0x1B
The next command sets data 0x3B
(first byte of 0x3b00000
) to address 0x10E0
.
Direction: From Host
Command: 0x34
Argument: 0x80021C3B
CRC: 0x18
ATWILC’s response is as follows:
Direction: From Client
Command: 0x34
Argument: 0x103B
CRC: 0x63
Send CMD53 to read data from the set address above by using byte transfer (Block mode=0
). The address 0x10F is a data access window to Function 1 Code Storage Area (CSA). Byte count for this transfer is set as 4.
Direction: From Host
Command: 0x35
Argument: 0x4021E04
CRC: 0x73
ATWILC’s response is as follows:
Direction: From Client
Command: 0x35
Argument: 0x1000
CRC: 0x2D
CHIP ID is returned from ATWILC using DAT[0]:DAT[3] lines. For example, ATWILC3000 Chip ID is 003000D0 and is returned as follows. Start and end bits, as well as the CRC bits, are transmitted for every one of the DAT lines. CRC bits are calculated and checked for every DAT line individually.
The sdio_init()
function is executed successfully, and the response from ATWILC is successfully sent to the host. The ATWILC Initialization is done successfully. This is located in the kernel logs as follows:
IRQ GPIO is requested and initialized in the function init_irq().
After this, kernel threads are initialized for transmission and debugging using the wlan_initialize_threads()
function. Its logs are as follows:
Download the Wi-Fi® firmware based on device WILCS02, AWILC1000 or ATWILC3000. It is performed using two functions wilc_wlan_get_firmware()
and wilc_firmware_download()
. After the firmware is downloaded successfully, start the firmware using the wilc_start_firmware()
function. If there is an error in starting the firmware, this function will return a negative value.
After the firmware is started successfully, the firmware version is located in the kernel log. Configure the firmware parameters such as operation mode, BSS type, power management and so on, in wilc_init_fw_config()
.