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.
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.
The corresponding SDIO logs are as follows.
DIR: from Host, CMD:0x34, ARG:0x80020080 and 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 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.
DIR: from Slave, CMD:0x34, ARG:0x1080 and 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 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.
DIR: from Host, CMD:0x34, ARG:0x20000 and CRC:0x36
ATWILC’s response is as follows.
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).
The SDIO logs for above commands are as follows.
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).
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).
It has DIR from Host, CMD:0x34, ARG:0x80002202 and CRC:0x05 .
The response for the above command from ATWILC is as follows.
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.
The SDIO logs are as follows.
DIR: from Host, CMD:0x34, ARG:0x80000402 and CRC:0x4D
The response from ATWILC for above command is as follows.
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()
.
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.
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.
SDIO logs are as follows.
DIR: from Host, CMD:0x34, ARG:0x600 and CRC:0x52.
ATWILC’s response are as follows.
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.
SDIO logs are as follows.
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.
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.
DIR: from Host, CMD:0x34, ARG:0x80022202 and CRC:0x5B
ATWILC’s response is as follows.
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.
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.
Commands sent from host to ATWILC are as follows.
DIR: from Host, CMD:0x34, ARG:0x80000803 and CRC:0x30
ATWILC’s response is as follows.
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.
DIR: from Host, CMD:0x34, ARG:0x800 and CRC:0x30
ATWILC’s response is as follows.
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.
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.
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.
DIR: from Slave, CMD:0x34, ARG:0x1000 and CRC:0x1B
Next command sets data 0x00 (second byte of 0x3b00000) to address 0x10D0.
DIR: from Host, CMD:0x34, ARG:0x80021A00 and CRC:0x5A
ATWILCC response is as follows.
DIR: from Slave, CMD:0x34, ARG:0x1000 and CRC:0x1B
The next command sets data 0x3B (first byte of 0x3b00000) to address 0x10E0.
DIR: from Host, CMD:0x34, ARG:0x80021C3B and CRC:0x18
ATWILC’s response is as follows.
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.
DIR: from Host, CMD:0x35, ARG:0x4021E04 and CRC:0x73
ATWILC’s response is as follows.
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.
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.
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 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()
.