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