1 // Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef _DRIVER_SDIO_SLAVE_H_ 16 #define _DRIVER_SDIO_SLAVE_H_ 17 18 #include "esp_osal/esp_osal.h" 19 #include "esp_err.h" 20 #include "sys/queue.h" 21 22 #include "hal/sdio_slave_types.h" 23 #include "soc/sdio_slave_periph.h" 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 #define SDIO_SLAVE_RECV_MAX_BUFFER (4096-4) 30 31 typedef void(*sdio_event_cb_t)(uint8_t event); 32 33 34 /// Configuration of SDIO slave 35 typedef struct { 36 sdio_slave_timing_t timing; ///< timing of sdio_slave. see `sdio_slave_timing_t`. 37 sdio_slave_sending_mode_t sending_mode; ///< mode of sdio_slave. `SDIO_SLAVE_MODE_STREAM` if the data needs to be sent as much as possible; `SDIO_SLAVE_MODE_PACKET` if the data should be sent in packets. 38 int send_queue_size; ///< max buffers that can be queued before sending. 39 size_t recv_buffer_size; 40 ///< If buffer_size is too small, it costs more CPU time to handle larger number of buffers. 41 ///< If buffer_size is too large, the space larger than the transaction length is left blank but still counts a buffer, and the buffers are easily run out. 42 ///< Should be set according to length of data really transferred. 43 ///< 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. 44 ///< Buffer size of the slave pre-defined between host and slave before communication. All receive buffer given to the driver should be larger than this. 45 sdio_event_cb_t event_cb; ///< when the host interrupts slave, this callback will be called with interrupt number (0-7). 46 uint32_t flags; ///< Features to be enabled for the slave, combinations of ``SDIO_SLAVE_FLAG_*``. 47 #define SDIO_SLAVE_FLAG_DAT2_DISABLED BIT(0) /**< It is required by the SD specification that all 4 data 48 lines should be used and pulled up even in 1-bit mode or SPI mode. However, as a feature, the user can specify 49 this flag to make use of DAT2 pin in 1-bit mode. Note that the host cannot read CCCR registers to know we don't 50 support 4-bit mode anymore, please do this at your own risk. 51 */ 52 #define SDIO_SLAVE_FLAG_HOST_INTR_DISABLED BIT(1) /**< The DAT1 line is used as the interrupt line in SDIO 53 protocol. However, as a feature, the user can specify this flag to make use of DAT1 pin of the slave in 1-bit 54 mode. Note that the host has to do polling to the interrupt registers to know whether there are interrupts from 55 the slave. And it cannot read CCCR registers to know we don't support 4-bit mode anymore, please do this at 56 your own risk. 57 */ 58 #define SDIO_SLAVE_FLAG_INTERNAL_PULLUP BIT(2) /**< Enable internal pullups for enabled pins. It is required 59 by the SD specification that all the 4 data lines should be pulled up even in 1-bit mode or SPI mode. Note that 60 the internal pull-ups are not sufficient for stable communication, please do connect external pull-ups on the 61 bus. This is only for example and debug use. 62 */ 63 } sdio_slave_config_t; 64 65 /** Handle of a receive buffer, register a handle by calling ``sdio_slave_recv_register_buf``. Use the handle to load the buffer to the 66 * driver, or call ``sdio_slave_recv_unregister_buf`` if it is no longer used. 67 */ 68 typedef void *sdio_slave_buf_handle_t; 69 70 /** Initialize the sdio slave driver 71 * 72 * @param config Configuration of the sdio slave driver. 73 * 74 * @return 75 * - ESP_ERR_NOT_FOUND if no free interrupt found. 76 * - ESP_ERR_INVALID_STATE if already initialized. 77 * - ESP_ERR_NO_MEM if fail due to memory allocation failed. 78 * - ESP_OK if success 79 */ 80 esp_err_t sdio_slave_initialize(sdio_slave_config_t *config); 81 82 /** De-initialize the sdio slave driver to release the resources. 83 */ 84 void sdio_slave_deinit(void); 85 86 /** Start hardware for sending and receiving, as well as set the IOREADY1 to 1. 87 * 88 * @note The driver will continue sending from previous data and PKT_LEN counting, keep data received as well as start receiving from current TOKEN1 counting. 89 * See ``sdio_slave_reset``. 90 * 91 * @return 92 * - ESP_ERR_INVALID_STATE if already started. 93 * - ESP_OK otherwise. 94 */ 95 esp_err_t sdio_slave_start(void); 96 97 /** Stop hardware from sending and receiving, also set IOREADY1 to 0. 98 * 99 * @note this will not clear the data already in the driver, and also not reset the PKT_LEN and TOKEN1 counting. Call ``sdio_slave_reset`` to do that. 100 */ 101 void sdio_slave_stop(void); 102 103 /** Clear the data still in the driver, as well as reset the PKT_LEN and TOKEN1 counting. 104 * 105 * @return always return ESP_OK. 106 */ 107 esp_err_t sdio_slave_reset(void); 108 109 /*--------------------------------------------------------------------------- 110 * Receive 111 *--------------------------------------------------------------------------*/ 112 /** Register buffer used for receiving. All buffers should be registered before used, and then can be used (again) in the driver by the handle returned. 113 * 114 * @param start The start address of the buffer. 115 * 116 * @note The driver will use and only use the amount of space specified in the `recv_buffer_size` member set in the `sdio_slave_config_t`. 117 * All buffers should be larger than that. The buffer is used by the DMA, so it should be DMA capable and 32-bit aligned. 118 * 119 * @return The buffer handle if success, otherwise NULL. 120 */ 121 sdio_slave_buf_handle_t sdio_slave_recv_register_buf(uint8_t *start); 122 123 /** Unregister buffer from driver, and free the space used by the descriptor pointing to the buffer. 124 * 125 * @param handle Handle to the buffer to release. 126 * 127 * @return ESP_OK if success, ESP_ERR_INVALID_ARG if the handle is NULL or the buffer is being used. 128 */ 129 esp_err_t sdio_slave_recv_unregister_buf(sdio_slave_buf_handle_t handle); 130 131 /** Load buffer to the queue waiting to receive data. The driver takes ownership of the buffer until the buffer is returned by 132 * ``sdio_slave_send_get_finished`` after the transaction is finished. 133 * 134 * @param handle Handle to the buffer ready to receive data. 135 * 136 * @return 137 * - ESP_ERR_INVALID_ARG if invalid handle or the buffer is already in the queue. Only after the buffer is returened by 138 * ``sdio_slave_recv`` can you load it again. 139 * - ESP_OK if success 140 */ 141 esp_err_t sdio_slave_recv_load_buf(sdio_slave_buf_handle_t handle); 142 143 /** Get received data if exist. The driver returns the ownership of the buffer to the app. 144 * 145 * @param handle_ret Handle to the buffer holding received data. Use this handle in ``sdio_slave_recv_load_buf`` to receive in the same buffer again. 146 * @param[out] out_addr Output of the start address, set to NULL if not needed. 147 * @param[out] out_len Actual length of the data in the buffer, set to NULL if not needed. 148 * @param wait Time to wait before data received. 149 * 150 * @note Call ``sdio_slave_load_buf`` with the handle to re-load the buffer onto the link list, and receive with the same buffer again. 151 * The address and length of the buffer got here is the same as got from `sdio_slave_get_buffer`. 152 * 153 * @return 154 * - ESP_ERR_INVALID_ARG if handle_ret is NULL 155 * - ESP_ERR_TIMEOUT if timeout before receiving new data 156 * - ESP_OK if success 157 */ 158 esp_err_t sdio_slave_recv(sdio_slave_buf_handle_t* handle_ret, uint8_t **out_addr, size_t *out_len, TickType_t wait); 159 160 /** Retrieve the buffer corresponding to a handle. 161 * 162 * @param handle Handle to get the buffer. 163 * @param len_o Output of buffer length 164 * 165 * @return buffer address if success, otherwise NULL. 166 */ 167 uint8_t* sdio_slave_recv_get_buf(sdio_slave_buf_handle_t handle, size_t *len_o); 168 169 /*--------------------------------------------------------------------------- 170 * Send 171 *--------------------------------------------------------------------------*/ 172 /** Put a new sending transfer into the send queue. The driver takes ownership of the buffer until the buffer is returned by 173 * ``sdio_slave_send_get_finished`` after the transaction is finished. 174 * 175 * @param addr Address for data to be sent. The buffer should be DMA capable and 32-bit aligned. 176 * @param len Length of the data, should not be longer than 4092 bytes (may support longer in the future). 177 * @param arg Argument to returned in ``sdio_slave_send_get_finished``. The argument can be used to indicate which transaction is done, 178 * or as a parameter for a callback. Set to NULL if not needed. 179 * @param wait Time to wait if the buffer is full. 180 * 181 * @return 182 * - ESP_ERR_INVALID_ARG if the length is not greater than 0. 183 * - ESP_ERR_TIMEOUT if the queue is still full until timeout. 184 * - ESP_OK if success. 185 */ 186 esp_err_t sdio_slave_send_queue(uint8_t* addr, size_t len, void* arg, TickType_t wait); 187 188 /** Return the ownership of a finished transaction. 189 * @param out_arg Argument of the finished transaction. Set to NULL if unused. 190 * @param wait Time to wait if there's no finished sending transaction. 191 * 192 * @return ESP_ERR_TIMEOUT if no transaction finished, or ESP_OK if succeed. 193 */ 194 esp_err_t sdio_slave_send_get_finished(void** out_arg, TickType_t wait); 195 196 /** Start a new sending transfer, and wait for it (blocked) to be finished. 197 * 198 * @param addr Start address of the buffer to send 199 * @param len Length of buffer to send. 200 * 201 * @return 202 * - ESP_ERR_INVALID_ARG if the length of descriptor is not greater than 0. 203 * - ESP_ERR_TIMEOUT if the queue is full or host do not start a transfer before timeout. 204 * - ESP_OK if success. 205 */ 206 esp_err_t sdio_slave_transmit(uint8_t* addr, size_t len); 207 208 /*--------------------------------------------------------------------------- 209 * Host 210 *--------------------------------------------------------------------------*/ 211 /** Read the spi slave register shared with host. 212 * 213 * @param pos register address, 0-27 or 32-63. 214 * 215 * @note register 28 to 31 are reserved for interrupt vector. 216 * 217 * @return value of the register. 218 */ 219 uint8_t sdio_slave_read_reg(int pos); 220 221 /** Write the spi slave register shared with host. 222 * 223 * @param pos register address, 0-11, 14-15, 18-19, 24-27 and 32-63, other address are reserved. 224 * @param reg the value to write. 225 * 226 * @note register 29 and 31 are used for interrupt vector. 227 * 228 * @return ESP_ERR_INVALID_ARG if address wrong, otherwise ESP_OK. 229 */ 230 esp_err_t sdio_slave_write_reg(int pos, uint8_t reg); 231 232 /** Get the interrupt enable for host. 233 * 234 * @return the interrupt mask. 235 */ 236 sdio_slave_hostint_t sdio_slave_get_host_intena(void); 237 238 /** Set the interrupt enable for host. 239 * 240 * @param mask Enable mask for host interrupt. 241 */ 242 void sdio_slave_set_host_intena(sdio_slave_hostint_t mask); 243 244 /** Interrupt the host by general purpose interrupt. 245 * 246 * @param pos Interrupt num, 0-7. 247 * 248 * @return 249 * - ESP_ERR_INVALID_ARG if interrupt num error 250 * - ESP_OK otherwise 251 */ 252 esp_err_t sdio_slave_send_host_int(uint8_t pos); 253 254 /** Clear general purpose interrupt to host. 255 * 256 * @param mask Interrupt bits to clear, by bit mask. 257 */ 258 void sdio_slave_clear_host_int(sdio_slave_hostint_t mask); 259 260 /** Wait for general purpose interrupt from host. 261 * 262 * @param pos Interrupt source number to wait for. 263 * is set. 264 * @param wait Time to wait before interrupt triggered. 265 * 266 * @note this clears the interrupt at the same time. 267 * 268 * @return ESP_OK if success, ESP_ERR_TIMEOUT if timeout. 269 */ 270 esp_err_t sdio_slave_wait_int(int pos, TickType_t wait); 271 272 273 #ifdef __cplusplus 274 } 275 #endif 276 277 #endif /*_DRIVER_SDIO_SLAVE_H */ 278