Appendix C – ATWILC SDIO Protocol Example

After successfully loading the ATWILC module, enter if config wlan0 up command to bring up the Wi-Fi interface. It initializes ATWILC SDIO, reads the Chip ID, downloads Wi-Fi firmware and brings up the WLAN interface.

Upon calling if config wlan0 up command, wilc_mac_open() function is invoked first, in which wilc_wlan_initialize() is called to initialize WLAN interface wilc_wlan_init calls the corresponding hif_init() to bring up HIF layer. If SDIO interface is used wilc_sdio_init( ) is called and if SPI interface is used wilc_spi_init() is called. The sequence of SDIO packets while initializing WLAN interface in the ATWILC3000 is described in this section.

As per ATWILC’s driver implementation, the first command to send in wilc_sdio_init( ) function is as follows.

Figure . Enable CSA

CSA Enable bit controls access to the Code Storage Area for this function. If this bit is cleared to 0, then any read or write access to the CSA shall be blocked. If this bit is set to 1, then access to the CSA is allowed. This bit is cleared to 0 upon reset. The code will set 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

DIR: from Host, CMD:0x34, ARG:0x80020080 and 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 a ‘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 Slave

DIR: from Slave, CMD:0x34, ARG:0x1080 and 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 a ‘0’
  • Register address as 0x10
  • Write data as 0x80 (same data which is sent in previous packet)
  • CRC as ‘0x5A’
  • End bit as ‘1’

Since RAW flag is set, the same register is read immediately to make sure if the bit is set. Read command from the host is as follows.

Figure . Read CSA Command from Host

DIR: from Host, CMD:0x34, ARG:0x20000 and CRC:0x36

ATWILC’s response is as follows.

Figure . Read CSA Response from Slave

DIR: from Slave, CMD:0x34, ARG:0x10C7 and CRC:0x01. From the above log, C7 is returned as the data which has CSA Enable bit as set.

Set function 0 block size as 512 in address 0x10-0x11 which is in Card Common Control Registers (CCCR) of 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

DIR: from Host, CMD:0x34, ARG:0x80002000 and 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 Slave

DIR: from Slave, CMD:0x34, ARG:0x1000 and 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

It has DIR from Host, CMD:0x34, ARG:0x80002202 and CRC:0x05 .

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

Figure . Set Function 0 Block Size Response from Slave

It has DIR: from Slave, CMD:0x34, ARG:0x1002 and CRC:0x09

After setting function 0 block size successfully, enable function 1 by setting IOE1 bit (I/O enable) in Card Common Control Registers, with address as 0x02 and data as 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

DIR: from Host, CMD:0x34, ARG:0x80000402 and CRC:0x4D

The response from ATWILC for above command is as follows.

Figure . Enable Function1 I/O Register Response from Slave

DIR: from Slave, CMD:0x34, ARG:0x1002 and CRC:0x09

If RAW flag is set as ‘1’, register with address ‘0x02’ is read using sdio_readb() function immediately after writing using sdio_writeb().

Figure . Read Function1 I/O Register Command from Host

It has DIR: from Host, CMD:0x34, ARG:0x400 which has R/W flag as 0, function number as 0, RAW flag a ‘0’, register address as 0x02, read data as 0x00 and CRC:0x44

Response from ATWILC is as follows.

Figure . Read Function1 I/O Register Response from Slave

As per CMD52 response R5, argument value of 0x00001002 which has response flag as 0x10, read data as 0x02. The read data is as same as the one written previously. This means function 1 is enabled (IE1) in CCCR.

After enabling function 1 as above, make sure function 1 is ready by reading IOR1 bit (I/O Ready) in CCCR with address 0x03. The register must return value of 0x02 to set the IOR1 bit.

Figure . Read Function1 IOR Register

SDIO logs are as follows.

Figure . Read Function1 IOR Register Command from Host

DIR: from Host, CMD:0x34, ARG:0x600 and CRC:0x52.

ATWILC’s response are as follows.

Figure . Read Function1 IOR Register Response from Slave

DIR: from Slave, CMD:0x34, ARG:0x1002 and CRC:0x09.

From above argument, read data is returned as ‘0x02’ which means IOR1 is set and function 1 is up.

Set 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

DIR: from Host, CMD:0x34, ARG:0x80022000 and 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 Function1 Block Size Response from Slave

DIR: from Slave, CMD:0x34, ARG:0x1000 and CRC:0x1B

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

Figure . Set Function1 Block Size Command from Host

DIR: from Host, CMD:0x34, ARG:0x80022202 and CRC:0x5B

ATWILC’s response is as follows.

Figure . Set Function1 Block Size Response from Slave

DIR: from Slave, CMD:0x34, ARG:0x1002 and CRC:0x09

Set Interrupt enable for function 1. To set this IEN1 and IENM bit in CCCR register in address 0x04 needs to be set.

Figure . Card Common Control Registers (CCCR) with Address 0x04

IENx: Interrupt Enable for function x. If this bit is cleared to 0, any interrupt from this function shall not be sent to the host. If this bit is set to 1, then this function’s interrupt shall be sent to the host if the master 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 shall be sent to the host. If this bit is set to 1, then any function’s interrupt shall be sent to the host.

Figure . Enable Function0 Interrupt

Commands sent from host to ATWILC are as follows.

Figure . Enable Function0 Interrupt Command from Host

DIR: from Host, CMD:0x34, ARG:0x80000803 and CRC:0x30

ATWILC’s response is as follows.

Figure . Enable Function0 Interrupt Response from Slave

DIR: from Slave, CMD:0x34, ARG:0x1003 and CRC:0x00

Since RAW flag is set as 1, the same register is read again to make sure IE1 and IENM bits are set. Commands sent from host to ATWILC are as follows.

Figure . Read Function0 Interrupt Enable Command from Host

DIR: from Host, CMD:0x34, ARG:0x800 and CRC:0x30

ATWILC’s response is as follows.

Figure . Read Function0 Interrupt Enable Response from Slave

DIR: from Slave, CMD:0x34, ARG:0x1003 and CRC:0x00. From above log, it is returning the data as 0x03 which indicates 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 register with address 0x3b0000 to see if the Chip ID is ATWILC3000 and if it is not, then read register with address 0x1000 to get ATWILC1000 Chip ID. wilc->hif_func->hif_read_reg() will call either wilc_sdio_read_reg() or wilc_spi_read_reg() based on the host interface used.

Since SDIO interface is used, wilc_sdio_read_reg() will be called. Address 0xF0-0xFF is reserved for Vendor Unique registers and CMD52 is used to access these registers and for others CMD53 is used.

Before read/write operation, address pointer to Function CSA needs to be set first. These three bytes make up a 24-bit pointer to the desired byte in the CSA to read or write. CSA is already enabled in previous commands. Address 0x10C-0x10E holds pointer to Function 1 Code Storage Area (CSA).

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

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

DIR: from Host, CMD:0x34, ARG:0x80021800 and 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 Slave

DIR: from Slave, CMD:0x34, ARG:0x1000 and CRC:0x1B

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

DIR: from Host, CMD:0x34, ARG:0x80021A00 and CRC:0x5A

ATWILCC response is as follows.

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

DIR: from Slave, CMD:0x34, ARG:0x1000 and 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

DIR: from Host, CMD:0x34, ARG:0x80021C3B and CRC:0x18

ATWILC’s response is as follows.

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

DIR: from Slave, CMD:0x34, ARG:0x103B and CRC:0x63

Send CMD53 to read data from above set address 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

DIR: from Host, CMD:0x35, ARG:0x4021E04 and CRC:0x73

ATWILC’s response is as follows.

Figure . CMD53 Read Response from Slave

DIR: from Slave, CMD:0x35, ARG:0x1000 and 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 Slave

sdio_init() function is executed successfully and the response from ATWILC is successfully sent to the host. The ATWILC Initialization is done successfully. This can be seen in 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 AWILC1000 or ATWILC3000. It is performed using two functions wilc_wlan_get_firmware() and wilc_firmware_download(). Once the firmware is downloaded successfully, start the firmware using linux_wlan_start_firmware() function. If there is an error in starting the firmware, this function will return a negative value.

Once firmware is started successfully, the firmware version can be seen from kernel log. Configure firmware parameters such as operation mode, BSS type, power management and so on., in linux_wlan_init_test_config().

Figure . ifconfig wlan0 up Command Logs