ChibiOS/HAL  6.1.0
hal_qspi.h
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 
17 /**
18  * @file hal_qspi.h
19  * @brief QSPI Driver macros and structures.
20  *
21  * @addtogroup QSPI
22  * @{
23  */
24 
25 #ifndef HAL_QSPI_H
26 #define HAL_QSPI_H
27 
28 #if (HAL_USE_QSPI == TRUE) || defined(__DOXYGEN__)
29 
30 /*===========================================================================*/
31 /* Driver constants. */
32 /*===========================================================================*/
33 
34 /**
35  * @name Transfer options
36  * @{
37  */
38 #define QSPI_CFG_CMD_MASK (0xFFLU << 0LU)
39 #define QSPI_CFG_CMD(n) ((n) << 0LU)
40 #define QSPI_CFG_CMD_MODE_MASK (3LU << 8LU)
41 #define QSPI_CFG_CMD_MODE_NONE (0LU << 8LU)
42 #define QSPI_CFG_CMD_MODE_ONE_LINE (1LU << 8LU)
43 #define QSPI_CFG_CMD_MODE_TWO_LINES (2LU << 8LU)
44 #define QSPI_CFG_CMD_MODE_FOUR_LINES (3LU << 8LU)
45 #define QSPI_CFG_ADDR_MODE_MASK (3LU << 10LU)
46 #define QSPI_CFG_ADDR_MODE_NONE (0LU << 10LU)
47 #define QSPI_CFG_ADDR_MODE_ONE_LINE (1LU << 10LU)
48 #define QSPI_CFG_ADDR_MODE_TWO_LINES (2LU << 10LU)
49 #define QSPI_CFG_ADDR_MODE_FOUR_LINES (3LU << 10LU)
50 #define QSPI_CFG_ADDR_SIZE_MASK (3LU << 12LU)
51 #define QSPI_CFG_ADDR_SIZE_8 (0LU << 12LU)
52 #define QSPI_CFG_ADDR_SIZE_16 (1LU << 12LU)
53 #define QSPI_CFG_ADDR_SIZE_24 (2LU << 12LU)
54 #define QSPI_CFG_ADDR_SIZE_32 (3LU << 12LU)
55 #define QSPI_CFG_ALT_MODE_MASK (3LU << 14LU)
56 #define QSPI_CFG_ALT_MODE_NONE (0LU << 14LU)
57 #define QSPI_CFG_ALT_MODE_ONE_LINE (1LU << 14LU)
58 #define QSPI_CFG_ALT_MODE_TWO_LINES (2LU << 14LU)
59 #define QSPI_CFG_ALT_MODE_FOUR_LINES (3LU << 14LU)
60 #define QSPI_CFG_ALT_SIZE_MASK (3LU << 16LU)
61 #define QSPI_CFG_ALT_SIZE_8 (0LU << 16LU)
62 
63 #define QSPI_CFG_ALT_SIZE_16 (1LU << 16LU)
64 #define QSPI_CFG_ALT_SIZE_24 (2LU << 16LU)
65 #define QSPI_CFG_ALT_SIZE_32 (3LU << 16LU)
66 #define QSPI_CFG_DUMMY_CYCLES_MASK (0x1FLU << 18LU)
67 #define QSPI_CFG_DUMMY_CYCLES(n) ((n) << 18LU)
68 #define QSPI_CFG_DATA_MODE_MASK (3LU << 24LU)
69 #define QSPI_CFG_DATA_MODE_NONE (0LU << 24LU)
70 #define QSPI_CFG_DATA_MODE_ONE_LINE (1LU << 24LU)
71 #define QSPI_CFG_DATA_MODE_TWO_LINES (2LU << 24LU)
72 #define QSPI_CFG_DATA_MODE_FOUR_LINES (3LU << 24LU)
73 #define QSPI_CFG_SIOO (1LU << 28LU)
74 #define QSPI_CFG_DDRM (1LU << 31LU)
75 /** @} */
76 
77 /*===========================================================================*/
78 /* Driver pre-compile time settings. */
79 /*===========================================================================*/
80 
81 /**
82  * @name QSPI configuration options
83  * @{
84  */
85 /**
86  * @brief Enables synchronous APIs.
87  * @note Disabling this option saves both code and data space.
88  */
89 #if !defined(QSPI_USE_WAIT) || defined(__DOXYGEN__)
90 #define QSPI_USE_WAIT TRUE
91 #endif
92 
93 /**
94  * @brief Enables the @p qspiAcquireBus() and @p qspiReleaseBus() APIs.
95  * @note Disabling this option saves both code and data space.
96  */
97 #if !defined(QSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
98 #define QSPI_USE_MUTUAL_EXCLUSION TRUE
99 #endif
100 /** @} */
101 
102 /*===========================================================================*/
103 /* Derived constants and error checks. */
104 /*===========================================================================*/
105 
106 /*===========================================================================*/
107 /* Driver data structures and types. */
108 /*===========================================================================*/
109 
110 /**
111  * @brief Driver state machine possible states.
112  */
113 typedef enum {
114  QSPI_UNINIT = 0, /**< Not initialized. */
115  QSPI_STOP = 1, /**< Stopped. */
116  QSPI_READY = 2, /**< Ready. */
117  QSPI_ACTIVE = 3, /**< Exchanging data. */
118  QSPI_COMPLETE = 4, /**< Asynchronous operation complete. */
119  QSPI_MEMMAP = 5 /**< In memory mapped mode. */
120 } qspistate_t;
121 
122 /**
123  * @brief Type of a QSPI command descriptor.
124  */
125 typedef struct {
126  uint32_t cfg;
127  uint32_t addr;
128  uint32_t alt;
130 
131 #include "hal_qspi_lld.h"
132 
133 #if !defined(QSPI_SUPPORTS_MEMMAP)
134 #error "low level does not define QSPI_SUPPORTS_MEMMAP"
135 #endif
136 
137 /*===========================================================================*/
138 /* Driver macros. */
139 /*===========================================================================*/
140 
141 /**
142  * @name Macro Functions
143  * @{
144  */
145 /**
146  * @brief Sends a command without data phase.
147  * @post At the end of the operation the configured callback is invoked.
148  *
149  * @param[in] qspip pointer to the @p QSPIDriver object
150  * @param[in] cmdp pointer to the command descriptor
151  *
152  * @iclass
153  */
154 #define qspiStartCommandI(qspip, cmdp) { \
155  osalDbgAssert(((cmdp)->cfg & QSPI_CFG_DATA_MODE_MASK) == \
156  QSPI_CFG_DATA_MODE_NONE, \
157  "data mode specified"); \
158  (qspip)->state = QSPI_ACTIVE; \
159  qspi_lld_command(qspip, cmdp); \
160 }
161 
162 /**
163  * @brief Sends data over the QSPI bus.
164  * @details This asynchronous function starts a transmit operation.
165  * @post At the end of the operation the configured callback is invoked.
166  *
167  * @param[in] qspip pointer to the @p QSPIDriver object
168  * @param[in] cmdp pointer to the command descriptor
169  * @param[in] n number of bytes to send or zero if no data phase
170  * @param[in] txbuf the pointer to the transmit buffer
171  *
172  * @iclass
173  */
174 #define qspiStartSendI(qspip, cmdp, n, txbuf) { \
175  osalDbgAssert(((cmdp)->cfg & QSPI_CFG_DATA_MODE_MASK) != \
176  QSPI_CFG_DATA_MODE_NONE, \
177  "data mode required"); \
178  (qspip)->state = QSPI_ACTIVE; \
179  qspi_lld_send(qspip, cmdp, n, txbuf); \
180 }
181 
182 /**
183  * @brief Receives data from the QSPI bus.
184  * @details This asynchronous function starts a receive operation.
185  * @post At the end of the operation the configured callback is invoked.
186  *
187  * @param[in] qspip pointer to the @p QSPIDriver object
188  * @param[in] cmdp pointer to the command descriptor
189  * @param[in] n number of bytes to receive or zero if no data phase
190  * @param[out] rxbuf the pointer to the receive buffer
191  *
192  * @iclass
193  */
194 #define qspiStartReceiveI(qspip, cmdp, n, rxbuf) { \
195  osalDbgAssert(((cmdp)->cfg & QSPI_CFG_DATA_MODE_MASK) != \
196  QSPI_CFG_DATA_MODE_NONE, \
197  "data mode required"); \
198  (qspip)->state = QSPI_ACTIVE; \
199  qspi_lld_receive(qspip, cmdp, n, rxbuf); \
200 }
201 
202 #if (QSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
203 /**
204  * @brief Maps in memory space a QSPI flash device.
205  * @pre The memory flash device must be initialized appropriately
206  * before mapping it in memory space.
207  *
208  * @param[in] qspip pointer to the @p QSPIDriver object
209  * @param[in] cmdp pointer to the command descriptor
210  * @param[out] addrp pointer to the memory start address of the mapped
211  * flash or @p NULL
212  *
213  * @iclass
214  */
215 #define qspiMapFlashI(qspip, cmdp, addrp) \
216  qspi_lld_map_flash(qspip, cmdp, addrp)
217 
218 /**
219  * @brief Maps in memory space a QSPI flash device.
220  * @post The memory flash device must be re-initialized for normal
221  * commands exchange.
222  *
223  * @param[in] qspip pointer to the @p QSPIDriver object
224  *
225  * @iclass
226  */
227 #define qspiUnmapFlashI(qspip) \
228  qspi_lld_unmap_flash(qspip)
229 #endif /* QSPI_SUPPORTS_MEMMAP == TRUE */
230 /** @} */
231 
232 /**
233  * @name Low level driver helper macros
234  * @{
235  */
236 #if (QSPI_USE_WAIT == TRUE) || defined(__DOXYGEN__)
237 /**
238  * @brief Wakes up the waiting thread.
239  *
240  * @param[in] qspip pointer to the @p QSPIDriver object
241  *
242  * @notapi
243  */
244 #define _qspi_wakeup_isr(qspip) { \
245  osalSysLockFromISR(); \
246  osalThreadResumeI(&(qspip)->thread, MSG_OK); \
247  osalSysUnlockFromISR(); \
248 }
249 #else /* !QSPI_USE_WAIT */
250 #define _qspi_wakeup_isr(qspip)
251 #endif /* !QSPI_USE_WAIT */
252 
253 /**
254  * @brief Common ISR code.
255  * @details This code handles the portable part of the ISR code:
256  * - Callback invocation.
257  * - Waiting thread wakeup, if any.
258  * - Driver state transitions.
259  * .
260  * @note This macro is meant to be used in the low level drivers
261  * implementation only.
262  *
263  * @param[in] qspip pointer to the @p QSPIDriver object
264  *
265  * @notapi
266  */
267 #define _qspi_isr_code(qspip) { \
268  if ((qspip)->config->end_cb) { \
269  (qspip)->state = QSPI_COMPLETE; \
270  (qspip)->config->end_cb(qspip); \
271  if ((qspip)->state == QSPI_COMPLETE) \
272  (qspip)->state = QSPI_READY; \
273  } \
274  else \
275  (qspip)->state = QSPI_READY; \
276  _qspi_wakeup_isr(qspip); \
277 }
278 /** @} */
279 
280 /*===========================================================================*/
281 /* External declarations. */
282 /*===========================================================================*/
283 
284 #ifdef __cplusplus
285 extern "C" {
286 #endif
287  void qspiInit(void);
288  void qspiObjectInit(QSPIDriver *qspip);
289  void qspiStart(QSPIDriver *qspip, const QSPIConfig *config);
290  void qspiStop(QSPIDriver *qspip);
291  void qspiStartCommand(QSPIDriver *qspip, const qspi_command_t *cmdp);
292  void qspiStartSend(QSPIDriver *qspip, const qspi_command_t *cmdp,
293  size_t n, const uint8_t *txbuf);
294  void qspiStartReceive(QSPIDriver *qspip, const qspi_command_t *cmdp,
295  size_t n, uint8_t *rxbuf);
296 #if QSPI_USE_WAIT == TRUE
297  void qspiCommand(QSPIDriver *qspip, const qspi_command_t *cmdp);
298  void qspiSend(QSPIDriver *qspip, const qspi_command_t *cmdp,
299  size_t n, const uint8_t *txbuf);
300  void qspiReceive(QSPIDriver *qspip, const qspi_command_t *cmdp,
301  size_t n, uint8_t *rxbuf);
302 #endif
303 #if QSPI_SUPPORTS_MEMMAP == TRUE
304 void qspiMapFlash(QSPIDriver *qspip,
305  const qspi_command_t *cmdp,
306  uint8_t **addrp);
307 void qspiUnmapFlash(QSPIDriver *qspip);
308 #endif
309 #if QSPI_USE_MUTUAL_EXCLUSION == TRUE
310  void qspiAcquireBus(QSPIDriver *qspip);
311  void qspiReleaseBus(QSPIDriver *qspip);
312 #endif
313 #ifdef __cplusplus
314 }
315 #endif
316 
317 #endif /* HAL_USE_QSPI == TRUE */
318 
319 #endif /* HAL_QSPI_H */
320 
321 /** @} */
void qspiStartSend(QSPIDriver *qspip, const qspi_command_t *cmdp, size_t n, const uint8_t *txbuf)
Sends a command with data over the QSPI bus.
Definition: hal_qspi.c:165
void qspiUnmapFlash(QSPIDriver *qspip)
Unmaps from memory space a QSPI flash device.
Definition: hal_qspi.c:339
void qspiObjectInit(QSPIDriver *qspip)
Initializes the standard part of a QSPIDriver structure.
Definition: hal_qspi.c:68
void qspiReleaseBus(QSPIDriver *qspip)
Releases exclusive access to the QSPI bus.
Definition: hal_qspi.c:382
Driver configuration structure.
Definition: hal_qspi_lld.h:83
void qspiStartCommand(QSPIDriver *qspip, const qspi_command_t *cmdp)
Sends a command without data phase.
Definition: hal_qspi.c:141
void qspiStart(QSPIDriver *qspip, const QSPIConfig *config)
Configures and activates the QSPI peripheral.
Definition: hal_qspi.c:91
void qspiReceive(QSPIDriver *qspip, const qspi_command_t *cmdp, size_t n, uint8_t *rxbuf)
Sends a command then receives data over the QSPI bus.
Definition: hal_qspi.c:281
void qspiStartReceive(QSPIDriver *qspip, const qspi_command_t *cmdp, size_t n, uint8_t *rxbuf)
Sends a command then receives data over the QSPI bus.
Definition: hal_qspi.c:191
PLATFORM QSPI subsystem low level driver header.
void qspiSend(QSPIDriver *qspip, const qspi_command_t *cmdp, size_t n, const uint8_t *txbuf)
Sends a command with data over the QSPI bus.
Definition: hal_qspi.c:249
void qspiAcquireBus(QSPIDriver *qspip)
Gains exclusive access to the QSPI bus.
Definition: hal_qspi.c:366
Structure representing an QSPI driver.
Definition: hal_qspi_lld.h:94
void qspiMapFlash(QSPIDriver *qspip, const qspi_command_t *cmdp, uint8_t **addrp)
Maps in memory space a QSPI flash device.
Definition: hal_qspi.c:313
void qspiCommand(QSPIDriver *qspip, const qspi_command_t *cmdp)
Sends a command without data phase.
Definition: hal_qspi.c:219
qspistate_t
Driver state machine possible states.
Definition: hal_qspi.h:113
void qspiStop(QSPIDriver *qspip)
Deactivates the QSPI peripheral.
Definition: hal_qspi.c:116
void qspiInit(void)
QSPI Driver initialization.
Definition: hal_qspi.c:56
Type of a QSPI command descriptor.
Definition: hal_qspi.h:125