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