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.

Figure . Enable CSA

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.

Figure . Function Basic Register with Address 0x100

The corresponding SDIO logs are as follows.

Figure . Enable CSA Command from Host

Direction: From Host

Command: 0x34

Argument: 0x80020080

CRC: 0x6C

As per CMD52 format:
  • 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:

Figure . Enable CSA Response from Client

Direction: From Client

Command: 0x34

Argument: 0x1080

CRC: 0x5A

As per CMD52 response R5,
  • Start bit as ‘0
  • Dir ‘0’ which is from card to host
  • CMD52 identifier as 110100b
  • Argument value of 0x00001080 which has response flag as 0x10
  • 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:

Figure . Read CSA Command from Host

Direction: From Host

Command: 0x34

Argument: 0x20000

CRC: 0x36

ATWILC’s response is as follows:

Figure . Read CSA Response from Client

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).

Figure . CCCR Register with Address 0x10-0x11
Figure . Set Function 0 Block Size Command from Host
The above function is sent as two commands from the host.

The SDIO logs for above commands are as follows:

Figure . Set Function 0 Block Size Command from Host

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).

Figure . Set Function 0 Block Size Response from Client

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).

Figure . Set Function 0 Block Size Command from Host

Direction: From Host

Command: 0x34

Argument: 0x80002202

CRC: 0x05

The response for the above command from ATWILC is as follows:

Figure . Set Function 0 Block Size Response from Client

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.

Figure . CCCR Register with Address 0x02 and 0x03
Figure . Enable Function1 I/O Register

The SDIO logs are as follows:

Figure . Enable Function1 I/O Register Command from Host

Direction: From Host

Command: 0x34

Argument: 0x80000402

CRC: 0x4D

The response from ATWILC for above command is as follows:

Figure . Enable Function1 I/O Register Response from Client

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().

Figure . Read Function1 I/O Register Command from Host

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:

Figure . Read Function1 I/O Register Response from Client

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.

Figure . Read Function1 IOR Register

The SDIO logs are as follows:

Figure . Read Function1 IOR Register Command from Host

Direction: From Host

Command: 0x34

Argument: 0x600

CRC: 0x52

ATWILC’s response is as follows:

Figure . Read Function1 IOR Register Response from Client

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.

Figure . Set Function1 Block Size

SDIO logs are as follows:

Figure . Set Function1 Block Size Command from Host

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:

Figure . Set Function 1 Block Size Response from Client

Direction: From Client

Command: 0x34

Argument: 0x1000

CRC: 0x1B

The next command set data are 0x02 (first byte of 512, 0x0200) to address 0x111.

Figure . Set Function1 Block Size Command from Host

Direction: From Host

Command: 0x34

Argument: 0x80022202

CRC: 0x5B

ATWILC’s response is as follows:

Figure . Set Function 1 Block Size Response from Client

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.

Figure . Card Common Control Registers (CCCR) with Address 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.

Figure . Enable Function 0 Interrupt

Commands sent from host to ATWILC are as follows:

Figure . Enable Function 0 Interrupt Command from Host

Direction: From Host

Command: 0x34

Argument: 0x80000803

CRC: 0x30

ATWILC’s response is as follows:

Figure . Enable Function 0 Interrupt Response from Client

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:

Figure . Read Function 0 Interrupt Enable Command from Host

Direction: From Host

Command: 0x34

Argument: 0x800

CRC: 0x30

ATWILC’s response is as follows:

Figure . Read Function 0 Interrupt Enable Response from Client

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.

Figure . Read Chip ID from the Device

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.

Figure . WILC SDIO Read Register

The following commands set address 0x3b000000 to address 0x10C-0x10E:

Figure . Set Pointer to Function 1 Code Storage Area Command from the Host

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:

Figure . Set Pointer to Function 1 Code Storage Area Response from the Client

Direction: From Client

Command: 0x34

Argument: 0x1000

CRC: 0x1B

The next command sets data 0x00 (second byte of 0x3b00000) to address 0x10D0.

Figure . Set Pointer to Function 1 Code Storage Area Command from the Host

Direction: From Host

Command: 0x34

Argument: 0x80021A00

CRC: 0x5A

ATWILCC response is as follows:

Figure . Set Pointer to Function 1 Code Storage Area Response from the Client

Direction: From Client

Command: 0x34

Argument: 0x1000

CRC: 0x1B

The next command sets data 0x3B (first byte of 0x3b00000) to address 0x10E0.

Figure . Set Pointer to Function 1 Code Storage Area Command from the Host

Direction: From Host

Command: 0x34

Argument: 0x80021C3B

CRC: 0x18

ATWILC’s response is as follows:

Figure . Set Pointer to Function 1 Code Storage Area Response from the Client

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.

Figure . CMD53 to Read Data from Host

Direction: From Host

Command: 0x35

Argument: 0x4021E04

CRC: 0x73

ATWILC’s response is as follows:

Figure . CMD53 Read Response from Client

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.

Figure . CHIPID Response from Client

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:

Figure . ifconfig wlan0 up Command Logs

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:

Figure . ifconfig wlan0 up Command Logs

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().

Figure . ifconfig wlan0 up Command Logs