--- /dev/null
+ESP SDIO slave protocol
+=======================
+
+The protocol is based on Function 1 access by CMD52 and CMD53, offering 3 services: (1) sending and receiving FIFO, (2) 52 8-bit R/W
+register shared by host and slave, (3) 8 general purpose interrupt sources from host to slave and 8 in the oppsite direction.
+
+The host should access the registers below as described to communicate with slave.
+
+Slave register table
+--------------------
+
+32-bit
+^^^^^^^
+- 0x044 (TOKEN_RDATA): in which bit 27-16 holds the receiving buffer number.
+- 0x058 (INT_ST): holds the interrupt source bits from slave to host.
+- 0x060 (PKT_LEN): holds the accumulated length (by byte) to be sent from slave to host.
+- 0x0D4 (INT_CLR): write 1 to clear interrupt bits corresponding to INT_ST.
+- 0x0DC (INT_ENA): mask bits for interrupts from slave to host.
+
+8-bit
+^^^^^
+Shared general purpose registers:
+
+- 0x06C-0x077: R/W registers 0-11 shared by slave and host.
+- 0x07A-0x07B: R/W registers 14-15 shared by slave and host.
+- 0x07E-0x07F: R/W registers 18-19 shared by slave and host.
+- 0x088-0x08B: R/W registers 24-27 shared by slave and host.
+- 0x09C-0x0BB: R/W registers 32-63 shared by slave and host.
+
+Interrupt Registers:
+- 0x08D (SLAVE_INT): bits for host to interrupt slave. auto clear.
+
+FIFO (sending and receiving)
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+0x090 - 0x1F7FF are reserved for FIFOs.
+
+.. note:: This includes the CMD52 and CMD53 (block mode or byte mode).
+
+ The function number should be set to 1, OP Code should be set to 1 (for CMD53).
+
+ The slave will respond with the length according to the length field in CMD53 (1 of CMD52), with the data longer
+ than *requested length* filled with 0 (sending) or discard (receiving).
+
+Interrupts
+----------
+
+For the host interrupts, the slave raise the interrupt by pulling DAT1 line down at a proper time (level sensitive).
+The host detect this and read the INT_ST register to see the source. Then the host can clear it by writing the INT_CLR
+register and do something with the interrupt. The host can also mask unneeded sources by clearing the bits in INT_ENA
+register corresponding to the sources. If all the sources are cleared (or masked), the DAT1 line goes inactive.
+
+``sdio_slave_hostint_t`` (:doc:`sdio_slave`) shows the bit definition corresponding to host interrupt sources.
+
+For the slave interrupts, the host send transfers to write the SLAVE_INT register. Once a bit is written from 0 to 1,
+the slave hardware and driver will detect it and inform the app.
+
+Receiving FIFO
+--------------
+
+To write the receiving FIFO in the slave, host should work in the following steps:
+
+1. Read the TOKEN1 field (bits 27-16) of TOKEN_RDATA (0x044) register. The buffer number remaining is TOKEN1 minus
+ the number of buffers used by host.
+2. Make sure the buffer number is sufficient (*buffer_size* * *buffer_num* is greater than data to write, *buffer_size*
+ is pre-defined between the host and the slave before the communication starts). Or go back to step 1 until the buffer
+ is enough.
+3. Write to the FIFO address with CMD53. Note that the *requested length* should not be larger than calculated in step 2,
+ and the FIFO address is related to *rquested length*.
+4. Calculate used buffers, note that non-full buffer at the tail should be seen as one that is used.
+
+Sending FIFO
+------------
+
+To read the sending FIFO in the slave, host should work in the following steps:
+
+1. Wait for the interrupt line to be active (optional, low by default).
+2. Read (poll) the interrupt bits in INT_ST register to see whether new packets exists.
+3. If new packets are ready, reads the PKT_LEN reg. The data length to read from slave is PKT_LEN minuses the length
+ that has been read from the host. If the PKT_LEN is not larger than used, wait and poll until the slave is ready and
+ update the PKT_LEN.
+4. Read from the FIFO with CMD53. Note that the *requested length* should not be larger than calculated in step3, and
+ the FIFO address is related to *requested length*.
+5. Recored read length.
+
--- /dev/null
+SDIO Card Slave Driver
+======================
+
+Overview
+--------
+
+.. note:: At the moment, this code has been proven to work on the Wrover-Kit V3. Earlier versions of the Wrover-Kit
+ and other development kits are electrically incompatible with this code. Functionality on other devboards is untested.
+
+The ESP32 SDIO Card peripherals (Host, Slave) shares two sets of pins as below table.
+The first set is usually occupied by SPI0 bus which is responsible for the SPI flash holding the code to run.
+This means SDIO slave driver can only runs on the second set of pins while SDIO host is not using it.
+
++----------+-------+-------+
+| Pin Name | Slot1 | Slot2 |
++ +-------+-------+
+| | GPIO Number |
++==========+=======+=======+
+| CLK | 6 | 14 |
++----------+-------+-------+
+| CMD | 11 | 15 |
++----------+-------+-------+
+| DAT0 | 7 | 2 |
++----------+-------+-------+
+| DAT1 | 8 | 4 |
++----------+-------+-------+
+| DAT2 | 9 | 12 |
++----------+-------+-------+
+| DAT3 | 10 | 13 |
++----------+-------+-------+
+
+The SDIO slave can run under 3 modes: SPI, 1-bit SD and 4-bit SD modes, which is detected automatically by the
+hardware. According to the SDIO specification, the host initialize the slave into SD mode by first sending CMD0 with
+DAT3 pin high, while initialize the slave into SPI mode by sending CMD0 with CS pin (the same pin as DAT3) low. After the
+initialization, the host can enable the 4-bit SD mode by writing CCCR register 0x07 by CMD52. All the bus detection
+process are handled by the slave peripheral.
+
+The host has to communicate with the slave by an ESP-slave-specific protocol. The slave driver offers 3 services over
+Function 1 access by CMD52 and CMD53: (1) a sending FIFO and a receiving FIFO, (2) 52 8-bit R/W registers shared by
+host and slave, (3) 16 interrupt sources (8 from host to slave, and 8 from slave to host).
+
+Terminology
+^^^^^^^^^^^
+
+The SDIO slave driver uses the following terms:
+
+- Transfer: a transfer is always started by a command token from the host, and may contain a reply and several data
+ blocks. ESP32 slave software is based on transfers.
+- Sending: slave to host transfers.
+- Receiving: host to slave transfers.
+
+.. note:: Register names in ESP Rechnical Reference Manual are oriented from the point of view of the host, i.e. 'rx'
+ registers refer to sending, while 'tx' registers refer to receiving. We're not using `tx` or `rx` in the driver to
+ avoid ambiguities.
+
+- FIFO: specific address in Function 1 that can be access by CMD53 to read/write large amount of data. The address is
+ related to the length requested to read from/write to the slave in a single transfer:
+ *requested length* = 0x1F800-address.
+- Ownership: When the driver takes ownership of a buffer, it means the driver can randomly read/write the buffer
+ (mostly by the hardware). The application should not read/write the buffer until the ownership is returned to the
+ application. If the application reads from a buffer owned by a receiving driver, the data read can be random; if
+ the application writes to a buffer owned by a sending driver, the data sent may be corrupted.
+- Requested length: The length requested in one transfer determined by the FIFO address.
+- Transfer length: The length requested in one transfer determined by the CMD53 byte/block count field.
+
+.. note:: Requested length is different from the transfer length. ESP32 slave DMA base on the *requested length* rather
+ than the *transfer length*. The *transfer length* should be no shorter than the *requested length*, and the rest
+ part will be filled with 0 (sending) or discard (receiving).
+
+- Receiving buffer size: The buffer size is pre-defined between the host and the slave before communication starts.
+ Slave application has to set the buffer size during initialization by the ``recv_buffer_size`` member of
+ ``sdio_slave_config_t``.
+- Interrupts: the esp32 slave support interrupts in two directions: from host to slave (called slave interrupts below)
+ and from slave to host (called host interrupts below). See more in :ref:`interrupts`.
+- Registers: specific address in Function 1 access by CMD52 or CMD53.
+
+ESP SDIO Slave Protocol
+^^^^^^^^^^^^^^^^^^^^^^^
+
+The communication protocol slave used to communicate with the host is ESP32 specific, please refer to
+:doc:`esp_slave_protocol`, or example :example:`peripherals/sdio` for designing a host.
+
+.. toctree::
+ :hidden:
+
+ esp_slave_protocol
+
+.. _interrupts:
+
+Interrupts
+^^^^^^^^^^
+
+There are interrupts from host to slave, and from slave to host to help communicating conveniently.
+
+Slave Interrupts
+""""""""""""""""
+
+The host can interrupt the slave by writing any one bit in the register 0x08D. Once any bit of the register is
+set, an interrupt is raised and the SDIO slave driver calls the callback function defined in the ``slave_intr_cb`` member
+in the ``sdio_slave_config_t`` structure.
+
+.. note:: The callback function is called in the ISR, do not use any delay, loop or spinlock in the callback.
+
+There's another set of functions can be used. You can call ``sdio_slave_wait_int`` to wait for an interrupt within a
+certain time, or call ``sdio_slave_clear_int`` to clear interrupts from host. The callback function can work with the
+wait functions perfectly.
+
+Host Interrupts
+"""""""""""""""
+
+The slave can interrupt the host by an interrupt line (at certain time) which is level sensitive. When the host see the
+interrupt line pulled down, it may read the slave interrupt status register, to see the interrupt source. Host can clear
+interrupt bits, or choose to disable a interrupt source. The interrupt line will hold active until all the sources are
+cleared or disabled.
+
+There are several dedicated interrupt sources as well as general purpose sources. see ``sdio_slave_hostint_t`` for
+more information.
+
+Shared Registers
+^^^^^^^^^^^^^^^^
+
+There are 52 8-bit R/W shared registers to share information between host and slave. The slave can write or read the
+registers at any time by ``sdio_slave_read_reg`` and ``sdio_slave_write_reg``. The host can access (R/W) the register by CMD52 or CMD53.
+
+Receiving FIFO
+^^^^^^^^^^^^^^
+
+When the host is going to send the slave some packets, it has to check whether the slave is ready to receive by reading
+the buffer number of slave.
+
+To allow the host sending data to the slave, the application has to load buffers to the slave driver by the following steps:
+
+1. Register the buffer by calling ``sdio_slave_recv_register_buf``, and get the handle of the registered buffer. The driver
+ will allocate memory for the linked-list descriptor needed to link the buffer onto the hardware.
+2. Load buffers onto the driver by passing the buffer handle to ``sdio_slave_recv_load_buf``.
+3. Call ``sdio_slave_recv`` to get the received data. If non-blocking call is needed, set ``wait=0``.
+4. Pass the handle of processed buffer back to the driver by ``sdio_recv_load_buf`` again.
+
+.. note:: To avoid overhead from copying data, the driver itself doesn't have any buffer inside, the application is
+ responsible to offer new buffers in time. The DMA will automatically store received data to the buffer.
+
+Sending FIFO
+^^^^^^^^^^^^
+
+Each time the slave has data to send, it raises an interrupt and the host will request for the packet length. There are
+two sending modes:
+
+- Stream Mode: when a buffer is loaded to the driver, the buffer length will be counted into the packet length requested
+ by host in the incoming communications. Regardless previous packets are sent or not. This means the host can get data
+ of several buffers in one transfer.
+- Packet Mode: the packet length is updated packet by packet, and only when previous packet is sent. This means that the
+ host can only get data of one buffer in one transfer.
+
+.. note:: To avoid overhead from copying data, the driver itself doesn't have any buffer inside. Namely, the DMA takes
+ data directly from the buffer provided by the application. The application should not touch the buffer until the
+ sending is finished.
+
+The sending mode can be set in the ``sending_mode`` member of ``sdio_slave_config_t``, and the buffer numbers can be
+set in the ``send_queue_size``. All the buffers are restricted to be no larger than 4092 bytes. Though in the stream
+mode several buffers can be sent in one transfer, each buffer is still counted as one in the queue.
+
+The application can call ``sdio_slave_transmit`` to send packets. In this case the function returns when the transfer
+is sucessfully done, so the queue is not fully used. When higher effeciency is required, the application can use the
+following functions instead:
+
+1. Pass buffer information (address, length, as well as an ``arg`` indicating the buffer) to ``sdio_slave_send_queue``.
+ If non-blocking call is needed, set ``wait=0``. If the ``wait`` is not ``portMAX_DELAY`` (wait until success),
+ application has to check the result to know whether the data is put in to the queue or discard.
+
+2. Call ``sdio_slave_send_get_finished`` to get and deal with a finished transfer. A buffer should be keep unmodified
+ until returned from ``sdio_slave_send_get_finished``. This means the buffer is actually sent to the host, rather
+ than just staying in the queue.
+
+There are several ways to use the ``arg`` in the queue parameter:
+
+ 1. Directly point ``arg`` to a dynamic-allocated buffer, and use the ``arg`` to free it when transfer finished.
+ 2. Wrap transfer informations in a transfer structure, and point ``arg`` to the structure. You can use the
+ structure to do more things like::
+
+ typedef struct {
+ uint8_t* buffer;
+ size_t size;
+ int id;
+ }sdio_transfer_t;
+
+ //and send as:
+ sdio_transfer_t trans = {
+ .buffer = ADDRESS_TO_SEND,
+ .size = 8,
+ .id = 3, //the 3rd transfer so far
+ };
+ sdio_slave_send_queue(trans.buffer, trans.size, &trans, portMAX_DELAY);
+
+ //... maybe more transfers are sent here
+
+ //and deal with finished transfer as:
+ sdio_transfer_t* arg = NULL;
+ sdio_slave_send_get_finished((void**)&arg, portMAX_DELAY);
+ ESP_LOGI("tag", "(%d) successfully send %d bytes of %p", arg->id, arg->size, arg->buffer);
+ some_post_callback(arg); //do more things
+
+ 3. Working with the receiving part of this driver, point ``arg`` to the receive buffer handle of this buffer. So
+ that we can directly use the buffer to receive data when it's sent::
+
+ uint8_t buffer[256]={1,2,3,4,5,6,7,8};
+ sdio_slave_buf_handle_t handle = sdio_slave_recv_register_buf(buffer);
+ sdio_slave_send_queue(buffer, 8, handle, portMAX_DELAY);
+
+ //... maybe more transfers are sent here
+
+ //and load finished buffer to receive as
+ sdio_slave_buf_handle_t handle = NULL;
+ sdio_slave_send_get_finished((void**)&handle, portMAX_DELAY);
+ sdio_slave_recv_load_buf(handle);
+
+ More about this, see :example:`peripherals/sdio`.
+
+Application Example
+-------------------
+
+Slave/master communication: :example:`peripherals/sdio`.
+
+API Reference
+-------------
+
+.. include:: /_build/inc/sdio_slave.inc
+