1 /* 2 * Copyright (C) 2017-2024 Alibaba Group Holding Limited 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 /****************************************************************************** 20 * @file drv/qspi.h 21 * @brief Header File for QSPI Driver 22 * @version V1.0 23 * @date 8. Apr 2020 24 * @model qspi 25 ******************************************************************************/ 26 27 #ifndef _DRV_QSPI_H_ 28 #define _DRV_QSPI_H_ 29 30 #include <stdint.h> 31 #include <stdbool.h> 32 #include <drv/common.h> 33 #include <drv/dma.h> 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 /** 40 * \enum csi_qspi_clock_mode_t 41 * \brief QSPI clock mode 42 */ 43 typedef enum { 44 QSPI_CLOCK_MODE_0 = 0, ///< Clock Polarity 0, Clock Phase 0 45 QSPI_CLOCK_MODE_1, ///< Clock Polarity 0, Clock Phase 1 46 QSPI_CLOCK_MODE_2, ///< Clock Polarity 1, Clock Phase 0 47 QSPI_CLOCK_MODE_3, ///< Clock Polarity 1, Clock Phase 1 48 } csi_qspi_mode_t; 49 50 /** 51 * \enum csi_qspi_bus_width_t 52 * \brief QSPI bus width 53 */ 54 typedef enum { 55 QSPI_CFG_BUS_SINGLE = 0, ///< Single line 56 QSPI_CFG_BUS_DUAL, ///< Two line 57 QSPI_CFG_BUS_QUAD, ///< Four line 58 } csi_qspi_bus_width_t; 59 60 /** 61 * \enum csi_qspi_address_size_t 62 * \brief Address size in bits 63 */ 64 typedef enum { 65 QSPI_ADDRESS_8_BITS = 0, 66 QSPI_ADDRESS_16_BITS, 67 QSPI_ADDRESS_24_BITS, 68 QSPI_ADDRESS_32_BITS, 69 } csi_qspi_address_size_t; 70 71 /** 72 * \enum csi_qspi_alternate_bytes_size_t 73 * rief QSPI alternate bytes 74 */ 75 typedef enum { 76 QSPI_ALTERNATE_8_BITS = 0, 77 QSPI_ALTERNATE_16_BITS, 78 QSPI_ALTERNATE_24_BITS, 79 QSPI_ALTERNATE_32_BITS, 80 } csi_qspi_alt_size_t; 81 82 /** QSPI command 83 * 84 * Defines a frame format. It consists of instruction, address, alternative, dummy count and data 85 */ 86 typedef struct { 87 struct { 88 csi_qspi_bus_width_t bus_width; ///< Bus width for the instruction 89 uint8_t value; ///< Instruction value 90 bool disabled; ///< Instruction phase skipped if disabled is set to true 91 } instruction; 92 struct { 93 csi_qspi_bus_width_t bus_width; ///< Bus width for the address 94 csi_qspi_address_size_t size; ///< Address size 95 uint32_t value; ///< Address value 96 bool disabled; ///< Address phase skipped if disabled is set to true 97 } address; 98 struct { 99 csi_qspi_bus_width_t bus_width; ///< Bus width for alternative 100 csi_qspi_alt_size_t size; ///< Alternative size 101 uint32_t value; ///< Alternative value 102 bool disabled; ///< Alternative phase skipped if disabled is set to true 103 } alt; 104 uint8_t dummy_count; ///< Dummy cycles count 105 struct { 106 csi_qspi_bus_width_t bus_width; ///< Bus width for data 107 } data; 108 uint8_t ddr_enable; 109 } csi_qspi_command_t; 110 111 /** 112 * \enum csi_qspi_event_t 113 * \brief QSPI event 114 */ 115 typedef enum { 116 QSPI_EVENT_COMMAND_COMPLETE = 0, ///< Command completed 117 QSPI_EVENT_ERROR, ///< An error has occurred 118 } csi_qspi_event_t; 119 120 /** 121 * \struct csi_qspi_t 122 * \brief QSPI Handle Structure definition 123 */ 124 125 typedef struct csi_qspi csi_qspi_t; 126 struct csi_qspi { 127 csi_dev_t dev; ///< QSPI hw-device info 128 void (*callback)(csi_qspi_t *qspi, csi_qspi_event_t event, void *arg); ///< User callback function 129 void *arg; ///< QSPI custom designed param passed to evt_cb 130 uint8_t *tx_data; ///< Pointer to QSPI Tx transfer Buffer 131 uint32_t tx_size; ///< QSPI Tx Transfer size 132 uint8_t *rx_data; ///< Pointer to QSPI Rx transfer Buffer 133 uint32_t rx_size; ///< QSPI Rx Transfer size 134 void *send; ///< The send_async func 135 void *receive; ///< The receive_async func 136 void *send_receive; ///< The send_receive_async func 137 csi_state_t state; ///< Peripheral state 138 csi_dma_ch_t *tx_dma; 139 csi_dma_ch_t *rx_dma; 140 void *priv; 141 }; 142 143 /** 144 \brief Init QSPI ctrl block 145 1. Initializes the QSPI mode according to the specified parameters in the csi_qspi_init_t 146 2. Registers event callback function and user param for the callback 147 \param[in] qspi Handle of QSPI instance 148 \param[in] idx Index of instance 149 \return Error code 150 */ 151 csi_error_t csi_qspi_init(csi_qspi_t *qspi, uint32_t idx); 152 153 154 /** 155 \brief De-initialize QSPI Instance 156 stops operation and releases the software resources used by the Instance 157 \param[in] qspi Handle of QSPI instance 158 */ 159 void csi_qspi_uninit(csi_qspi_t *qspi); 160 161 /** 162 \brief Attach the callback handler to QSPI 163 \param[in] qspi Operate handle 164 \param[in] callback Callback function 165 \param[in] arg User can define it by himself as callback's param 166 \return Error code 167 */ 168 csi_error_t csi_qspi_attach_callback(csi_qspi_t *qspi, void *callback, void *arg); 169 170 /** 171 \brief Detach the callback handler 172 \param[in] qspi Operate handle 173 \return None 174 */ 175 void csi_qspi_detach_callback(csi_qspi_t *qspi); 176 177 /** 178 \brief Config qspi frequence 179 \param[in] qspi Handle of qspi instance 180 \param[in] hz QSPI frequence 181 \return The actual config frequency 182 */ 183 uint32_t csi_qspi_frequence(csi_qspi_t *qspi, uint32_t hz); 184 185 /** 186 \brief Config qspi mode 187 \param[in] qspi Handle of qspi instance 188 \param[in] mode QSPI mode 189 \return Error code 190 */ 191 csi_error_t csi_qspi_mode(csi_qspi_t *qspi, csi_qspi_mode_t mode); 192 193 /** 194 \brief Send an amount of data in blocking mode 195 \param[in] qspi QSPI handle 196 \param[in] cmd Structure that contains the command configuration information 197 \param[in] data Pointer to data buffer 198 \param[in] size Size of data to send 199 \param[in] timeout Time out duration 200 \return If send successful, this function shall return the num of data witch is sent successful 201 otherwise, the function shall return error code 202 */ 203 int32_t csi_qspi_send(csi_qspi_t *qspi, csi_qspi_command_t *cmd, const void *data, uint32_t size, uint32_t timeout); 204 205 /** 206 \brief Receive an amount of data in blocking mode 207 \param[in] qspi QSPI handle 208 \param[in] cmd Structure that contains the command configuration information 209 \param[out] data Pointer to data buffer 210 \param[in] size Size of data items to receive 211 \param[in] timeout Time out duration 212 \return If receive successful, this function shall return the num of data witch is received successfulful 213 otherwise, the function shall return error code 214 */ 215 int32_t csi_qspi_receive(csi_qspi_t *qspi, csi_qspi_command_t *cmd, void *data, uint32_t size, uint32_t timeout); 216 217 /** 218 \brief Transfer an amount of data in blocking mode 219 \param[in] qspi QSPI handle 220 \param[in] cmd Structure that contains the command configuration information 221 \param[in] tx_data Pointer to send data buffer 222 \param[out] rx_data Pointer to receive data buffer 223 \param[in] size Size of data to transfer 224 \param[in] timeout Time out duration 225 \return If transfer successful, this function shall return the num of data witch is transfer successfulful 226 otherwise, the function shall return error code 227 */ 228 int32_t csi_qspi_send_receive(csi_qspi_t *qspi, csi_qspi_command_t *cmd, const void *tx_data, void *rx_data, uint32_t size, uint32_t timeout); 229 230 /** 231 \brief Send an amount of data in async mode 232 \param[in] qspi QSPI handle 233 \param[in] cmd Structure that contains the command configuration information 234 \param[in] data Pointer to data buffer 235 \param[in] size Size of data to send 236 \return Data number send 237 */ 238 csi_error_t csi_qspi_send_async(csi_qspi_t *qspi, csi_qspi_command_t *cmd, const void *data, uint32_t size); 239 240 /** 241 \brief Receive an amount of data in async mode 242 \param[in] qspi QSPI handle 243 \param[in] cmd Structure that contains the command configuration information 244 \param[out] data Pointer to data buffer 245 \param[in] size Size of data items to receive 246 \return Data number received 247 */ 248 csi_error_t csi_qspi_receive_async(csi_qspi_t *qspi, csi_qspi_command_t *cmd, void *data, uint32_t size); 249 250 /** 251 \brief Transfer an amount of data in async mode 252 \param[in] qspi QSPI handle 253 \param[in] cmd Structure that contains the command configuration information 254 \param[in] tx_data Pointer to send data buffer 255 \param[out] rx_data Pointer to receive data buffer 256 \param[in] size Size of data to transfer 257 \return Data number transfered 258 */ 259 csi_error_t csi_qspi_send_receive_async(csi_qspi_t *qspi, csi_qspi_command_t *cmd, const void *tx_data, void *rx_data, uint32_t size); 260 261 /** 262 \brief Link DMA channel to qspi device 263 \param[in] qspi QSPI handle to operate 264 \param[in] tx_dma The DMA channel handle for send, when it is NULL means to unlink the channel 265 \param[in] rx_dma The DMA channel handle for receive, when it is NULL means to unlink the channel 266 \return Error code 267 */ 268 csi_error_t csi_qspi_link_dma(csi_qspi_t *qspi, csi_dma_ch_t *tx_dma, csi_dma_ch_t *rx_dma); 269 270 /** 271 \brief Get the state of qspi device 272 \param[in] qspi QSPI handle 273 \param[in] state QSPI state \ref csi_state_t 274 \return Error code 275 */ 276 csi_error_t csi_qspi_get_state(csi_qspi_t *qspi, csi_state_t *state); 277 278 /** 279 \brief Comfigure the memory mapped mode 280 \param[in] qspi QSPI handle 281 \param[in] cmd Structure that contains the command configuration information 282 \return Error code 283 */ 284 csi_error_t csi_qspi_memory_mapped(csi_qspi_t *qspi, csi_qspi_command_t *cmd); 285 286 /** 287 \brief Enable qspi power manage 288 \param[in] qspi QSPI handle to operate 289 \return Error code 290 */ 291 csi_error_t csi_qspi_enable_pm(csi_qspi_t *qspi); 292 293 /** 294 \brief Disable qspi power manage 295 \param[in] qspi QSPI handle to operate 296 \return None 297 */ 298 void csi_qspi_disable_pm(csi_qspi_t *qspi); 299 300 #ifdef __cplusplus 301 } 302 #endif 303 304 #endif /* _DRV_QSPI_H_*/ 305