| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- // Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include "sdmmc_cmd.h"
- #include "driver/sdmmc_host.h"
- #include "driver/sdmmc_defs.h"
- #include "soc/host_reg.h"
- /*
- * NOTE: This component is for example purpose only. Assertion fails if any of
- * the preconditions (connections, grounding, slave data preparation, etc.) is
- * not met.
- * Please do check and handle the return value in your real product.
- */
- #define ESP_ERR_NOT_FINISHED 0x201
- /** Context used by the ``esp_slave`` component.
- */
- typedef struct {
- sdmmc_card_t* card; ///< Initialized sdmmc_cmd card
- uint16_t buffer_size;
- ///< All data that do not fully fill a buffer is still counted as one buffer. E.g. 10 bytes data costs 2 buffers if the size is 8 bytes per buffer.
- ///< Buffer size of the slave pre-defined between host and slave before communication.
- uint16_t block_size;
- ///< If this is too large, it takes time to send stuff bits; while if too small, intervals between blocks cost much.
- ///< Should be set according to length of data, and larger than ``TRANS_LEN_MAX/511``.
- ///< Block size of the SDIO function 1. After the initialization this will hold the value the slave really do. Valid value is 1-2048.
- size_t tx_sent_buffers; ///< Counter hold the amount of buffers already sent to ESP32 slave. Should be set to 0 when initialization.
- size_t rx_got_bytes; ///< Counter hold the amount of bytes already received from ESP32 slave. Should be set to 0 when initialization.
- } esp_slave_context_t;
- /** Initialize ``esp_slave_context_t`` by this macro.
- */
- #define ESP_SLAVE_DEFAULT_CONTEXT(card) (esp_slave_context_t){\
- .card = card, \
- .block_size = 0x200, \
- .buffer_size = 128, \
- .tx_sent_buffers = 0, \
- .rx_got_bytes = 0, \
- }
- /** SDIO Initialize process of a ESP32 slave device.
- *
- * @param context Context of the ``esp_slave`` component. Send to other functions later.
- *
- * @return
- * - ESP_OK if success
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_init_io(esp_slave_context_t *context);
- /** Wait for interrupt of a ESP32 slave device.
- *
- * @param context Context of the ``esp_slave`` component.
- *
- * @return
- * - ESP_OK if success
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_wait_for_ioready(esp_slave_context_t *context);
- /** Get buffer num for the host to send data to the slave. The buffers are size of ``buffer_size``.
- *
- * @param context Context of the component.
- * @param tx_num Output of buffer num that host can send data to ESP32 slave.
- *
- * @return
- * - ESP_OK Success
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_get_tx_buffer_num(esp_slave_context_t *context, uint32_t* tx_num);
- /** Get amount of data the ESP32 slave preparing to send to host.
- *
- * @param context Context of the component.
- * @param rx_size Output of data size to read from slave.
- *
- * @return
- * - ESP_OK Success
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_get_rx_data_size(esp_slave_context_t *context, uint32_t* rx_size);
- /** Reset the counters of this component. Usually you don't need to do this unless you know the slave is reset.
- *
- * @param context Context of the component.
- */
- inline static void esp_slave_reset_cnt(esp_slave_context_t *context)
- {
- context->rx_got_bytes = 0;
- context->tx_sent_buffers = 0;
- }
- /** Send a packet to the ESP32 slave. The slave receive the packet into buffers whose size is ``buffer_size`` in the context.
- *
- * @param context Context of the component.
- * @param start Start address of the packet to send
- * @param length Length of data to send, if the packet is over-size, the it will be divided into blocks and hold into different buffers automatically.
- * @param wait_ms Time to wait before timeout, in ms.
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_TIMEOUT No buffer to use, or error ftrom SDMMC host controller
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_send_packet(esp_slave_context_t *context, const void* start, size_t length, uint32_t wait_ms);
- /** Get a packet from ESP32 slave.
- *
- * @param context Context of the component.
- * @param[out] out_data Data output address
- * @param size The size of the output buffer, if the buffer is smaller than the size of data to receive from slave, the driver returns ``ESP_ERR_NOT_FINISHED``
- * @param[out] out_length Output of length the data actually received from slave.
- * @param wait_ms Time to wait before timeout, in ms.
- *
- * @return
- * - ESP_OK Success, all the data are read from the slave.
- * - ESP_ERR_NOT_FINISHED Read success, while there're data remaining.
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_get_packet(esp_slave_context_t *context, void* out_data, size_t size, size_t *out_length, uint32_t wait_ms);
- /** wait for an interrupt of the slave
- *
- * @param context Context of the component.
- * @param wait Ticks to wait.
- *
- * @return
- * - ESP_ERR_NOT_SUPPORTED Currently our driver doesnot support SDIO with SPI interface.
- * - ESP_OK If interrupt triggered.
- * - ESP_ERR_TIMEOUT No interrupts before timeout.
- */
- inline static esp_err_t esp_slave_wait_int(esp_slave_context_t *context, TickType_t wait)
- {
- return sdmmc_io_wait_int(context->card, wait);
- }
- /** Clear interrupt bits of ESP32 slave. All the bits set in the mask will be cleared, while other bits will stay the same.
- *
- * @param context Context of the component.
- * @param intr_mask Mask of interrupt bits to clear.
- *
- * @return
- * - ESP_OK Success
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_clear_intr(esp_slave_context_t *context, uint32_t intr_mask);
- /** Get interrupt bits of ESP32 slave.
- *
- * @param context Context of the component.
- * @param intr_raw Output of the raw interrupt bits. Set to NULL if only masked bits are read.
- * @param intr_st Output of the masked interrupt bits. set to NULL if only raw bits are read.
- *
- * @return
- * - ESP_OK Success
- * - ESP_INVALID_ARG if both ``intr_raw`` and ``intr_st`` are NULL.
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_get_intr(esp_slave_context_t *context, uint32_t *intr_raw, uint32_t *intr_st);
- /** Set interrupt enable bits of ESP32 slave. The slave only sends interrupt on the line when there is a bit both the raw status and the enable are set.
- *
- * @param context Context of the component.
- * @param ena_mask Mask of the interrupt bits to enable.
- *
- * @return
- * - ESP_OK Success
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_set_intr_ena(esp_slave_context_t *context, uint32_t ena_mask);
- /** Get interrupt enable bits of ESP32 slave.
- *
- * @param context Context of the component.
- * @param ena_mask_o Output of interrupt bit enable mask.
- *
- * @return
- * - ESP_OK Success
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_get_intr_ena(esp_slave_context_t *context, uint32_t *ena_mask_o);
- /** Write general purpose R/W registers (8-bit) of ESP32 slave.
- *
- * @param context Context of the component.
- * @param addr Address of register to write. Valid address: 0-27, 32-63 (28-31 reserved).
- * @param value Value to write to the register.
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Address not valid.
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_write_reg(esp_slave_context_t *context, uint8_t addr, uint8_t value, uint8_t* value_o);
- /** Read general purpose R/W registers (8-bit) of ESP32 slave.
- *
- * @param context Context of the component.
- * @param add Address of register to read. Valid address: 0-27, 32-63 (28-31 reserved, return interrupt bits on read).
- * @param value Output value read from the register.
- *
- * @return
- * - ESP_OK Success
- * - ESP_ERR_INVALID_ARG Address not valid.
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_read_reg(esp_slave_context_t *context, uint8_t add, uint8_t *value_o);
- /** Send interrupts to slave. Each bit of the interrupt will be triggered.
- *
- * @param context Context of the component.
- * @param intr_mask Mask of interrupt bits to send to slave.
- *
- * @return
- * - ESP_OK Success
- * - One of the error codes from SDMMC host controller
- */
- esp_err_t esp_slave_send_slave_intr(esp_slave_context_t *context, uint8_t intr_mask);
|