ChibiOS  21.6.0
hal_wspi.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_wspi.h
19  * @brief WSPI Driver macros and structures.
20  *
21  * @addtogroup WSPI
22  * @{
23  */
24 
25 #ifndef HAL_WSPI_H
26 #define HAL_WSPI_H
27 
28 #if (HAL_USE_WSPI == TRUE) || defined(__DOXYGEN__)
29 
30 /*===========================================================================*/
31 /* Driver constants. */
32 /*===========================================================================*/
33 
34 /*===========================================================================*/
35 /* Driver pre-compile time settings. */
36 /*===========================================================================*/
37 
38 /**
39  * @name WSPI configuration options
40  * @{
41  */
42 /**
43  * @brief Enables synchronous APIs.
44  * @note Disabling this option saves both code and data space.
45  */
46 #if !defined(WSPI_USE_WAIT) || defined(__DOXYGEN__)
47 #define WSPI_USE_WAIT TRUE
48 #endif
49 
50 /**
51  * @brief Enables the @p wspiAcquireBus() and @p wspiReleaseBus() APIs.
52  * @note Disabling this option saves both code and data space.
53  */
54 #if !defined(WSPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
55 #define WSPI_USE_MUTUAL_EXCLUSION TRUE
56 #endif
57 /** @} */
58 
59 /*===========================================================================*/
60 /* Derived constants and error checks. */
61 /*===========================================================================*/
62 
63 /*===========================================================================*/
64 /* Driver data structures and types. */
65 /*===========================================================================*/
66 
67 /**
68  * @brief Driver state machine possible states.
69  */
70 typedef enum {
71  WSPI_UNINIT = 0, /**< Not initialized. */
72  WSPI_STOP = 1, /**< Stopped. */
73  WSPI_READY = 2, /**< Ready. */
74  WSPI_SEND = 3, /**< Sending data. */
75  WSPI_RECEIVE = 4, /**< Receiving data. */
76  WSPI_COMPLETE = 5, /**< Asynchronous operation complete. */
77  WSPI_MEMMAP = 6 /**< In memory mapped mode. */
78 } wspistate_t;
79 
80 /**
81  * @brief Type of a structure representing an WSPI driver.
82  */
83 typedef struct hal_wspi_driver WSPIDriver;
84 
85 /**
86  * @brief Type of a structure representing an WSPI driver configuration.
87  */
88 typedef struct hal_wspi_config WSPIConfig;
89 
90 /**
91  * @brief Type of a WSPI notification callback.
92  *
93  * @param[in] wspip pointer to the @p WSPIDriver object triggering the
94  * callback
95  */
96 typedef void (*wspicallback_t)(WSPIDriver *wspip);
97 
98 /**
99  * @brief Type of a WSPI command descriptor.
100  */
101 typedef struct {
102  /**
103  * @brief Transfer configuration field.
104  */
105  uint32_t cfg;
106  /**
107  * @brief Command phase data.
108  */
109  uint32_t cmd;
110  /**
111  * @brief Address phase data.
112  */
113  uint32_t addr;
114  /**
115  * @brief Alternate phase data.
116  */
117  uint32_t alt;
118  /**
119  * @brief Number of dummy cycles to be inserted.
120  */
121  uint32_t dummy;
123 
124 /* Including the low level driver header, it exports information required
125  for completing types.*/
126 #include "hal_wspi_lld.h"
127 
128 #if !defined(WSPI_SUPPORTS_MEMMAP)
129 #error "low level does not define WSPI_SUPPORTS_MEMMAP"
130 #endif
131 
132 #if !defined(WSPI_DEFAULT_CFG_MASKS)
133 #error "low level does not define WSPI_DEFAULT_CFG_MASKS"
134 #endif
135 
136 /**
137  * @brief Driver configuration structure.
138  */
140  /**
141  * @brief Operation complete callback or @p NULL.
142  */
144  /**
145  * @brief Operation error callback or @p NULL.
146  */
148  /* End of the mandatory fields.*/
149  wspi_lld_config_fields;
150 };
151 
152 /**
153  * @brief Structure representing an WSPI driver.
154  */
156  /**
157  * @brief Driver state.
158  */
160  /**
161  * @brief Current configuration data.
162  */
164 #if (WSPI_USE_WAIT == TRUE) || defined(__DOXYGEN__)
165  /**
166  * @brief Waiting thread.
167  */
169 #endif /* WSPI_USE_WAIT */
170 #if (WSPI_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
171  /**
172  * @brief Mutex protecting the peripheral.
173  */
175 #endif /* WSPI_USE_MUTUAL_EXCLUSION */
176 #if defined(WSPI_DRIVER_EXT_FIELDS)
177  WSPI_DRIVER_EXT_FIELDS
178 #endif
179  /* End of the mandatory fields.*/
180  wspi_lld_driver_fields;
181 };
182 
183 /*===========================================================================*/
184 /* Driver macros. */
185 /*===========================================================================*/
186 
187 #if (WSPI_DEFAULT_CFG_MASKS == TRUE) || defined(__DOXYGEN__)
188 /**
189  * @name Transfer options
190  * @note The low level driver has the option to override the following
191  * definitions and use its own ones. In must take care to use
192  * the same name for the same function or compatibility is not
193  * ensured.
194  * @{
195  */
196 #define WSPI_CFG_CMD_MODE_MASK (7LU << 0LU)
197 #define WSPI_CFG_CMD_MODE_NONE (0LU << 0LU)
198 #define WSPI_CFG_CMD_MODE_ONE_LINE (1LU << 0LU)
199 #define WSPI_CFG_CMD_MODE_TWO_LINES (2LU << 0LU)
200 #define WSPI_CFG_CMD_MODE_FOUR_LINES (3LU << 0LU)
201 #define WSPI_CFG_CMD_MODE_EIGHT_LINES (4LU << 0LU)
202 
203 #define WSPI_CFG_CMD_DTR (1LU << 3LU)
204 
205 #define WSPI_CFG_CMD_SIZE_MASK (3LU << 4LU)
206 #define WSPI_CFG_CMD_SIZE_8 (0LU << 4LU)
207 #define WSPI_CFG_CMD_SIZE_16 (1LU << 4LU)
208 #define WSPI_CFG_CMD_SIZE_24 (2LU << 4LU)
209 #define WSPI_CFG_CMD_SIZE_32 (3LU << 4LU)
210 
211 #define WSPI_CFG_ADDR_MODE_MASK (7LU << 8LU)
212 #define WSPI_CFG_ADDR_MODE_NONE (0LU << 8LU)
213 #define WSPI_CFG_ADDR_MODE_ONE_LINE (1LU << 8LU)
214 #define WSPI_CFG_ADDR_MODE_TWO_LINES (2LU << 8LU)
215 #define WSPI_CFG_ADDR_MODE_FOUR_LINES (3LU << 8LU)
216 #define WSPI_CFG_ADDR_MODE_EIGHT_LINES (4LU << 8LU)
217 
218 #define WSPI_CFG_ADDR_DTR (1LU << 11LU)
219 
220 #define WSPI_CFG_ADDR_SIZE_MASK (3LU << 12LU)
221 #define WSPI_CFG_ADDR_SIZE_8 (0LU << 12LU)
222 #define WSPI_CFG_ADDR_SIZE_16 (1LU << 12LU)
223 #define WSPI_CFG_ADDR_SIZE_24 (2LU << 12LU)
224 #define WSPI_CFG_ADDR_SIZE_32 (3LU << 12LU)
225 
226 #define WSPI_CFG_ALT_MODE_MASK (7LU << 16LU)
227 #define WSPI_CFG_ALT_MODE_NONE (0LU << 16LU)
228 #define WSPI_CFG_ALT_MODE_ONE_LINE (1LU << 16LU)
229 #define WSPI_CFG_ALT_MODE_TWO_LINES (2LU << 16LU)
230 #define WSPI_CFG_ALT_MODE_FOUR_LINES (3LU << 16LU)
231 #define WSPI_CFG_ALT_MODE_EIGHT_LINES (4LU << 16LU)
232 
233 #define WSPI_CFG_ALT_DTR (1LU << 19LU)
234 
235 #define WSPI_CFG_ALT_SIZE_MASK (3LU << 20LU)
236 #define WSPI_CFG_ALT_SIZE_8 (0LU << 20LU)
237 #define WSPI_CFG_ALT_SIZE_16 (1LU << 20LU)
238 #define WSPI_CFG_ALT_SIZE_24 (2LU << 20LU)
239 #define WSPI_CFG_ALT_SIZE_32 (3LU << 20LU)
240 
241 #define WSPI_CFG_DATA_MODE_MASK (7LU << 24LU)
242 #define WSPI_CFG_DATA_MODE_NONE (0LU << 24LU)
243 #define WSPI_CFG_DATA_MODE_ONE_LINE (1LU << 24LU)
244 #define WSPI_CFG_DATA_MODE_TWO_LINES (2LU << 24LU)
245 #define WSPI_CFG_DATA_MODE_FOUR_LINES (3LU << 24LU)
246 #define WSPI_CFG_DATA_MODE_EIGHT_LINES (4LU << 24LU)
247 
248 #define WSPI_CFG_DATA_DTR (1LU << 27LU)
249 
250 #define WSPI_CFG_DQS_ENABLE (1LU << 29LU)
251 
252 #define WSPI_CFG_SIOO (1LU << 31LU)
253 
254 #define WSPI_CFG_ALL_DTR (WSPI_CFG_CMD_DTR | \
255  WSPI_CFG_ADDR_DTR | \
256  WSPI_CFG_ALT_DTR | \
257  WSPI_CFG_DATA_DTR)
258 /** @} */
259 #endif /* WSPI_USE_DEFAULT_CFG_MASKS == TRUE */
260 
261 /**
262  * @name Macro Functions
263  * @{
264  */
265 /**
266  * @brief Sends a command without data phase.
267  * @post At the end of the operation the configured callback is invoked.
268  *
269  * @param[in] wspip pointer to the @p WSPIDriver object
270  * @param[in] cmdp pointer to the command descriptor
271  *
272  * @iclass
273  */
274 #define wspiStartCommandI(wspip, cmdp) { \
275  osalDbgAssert(((cmdp)->cfg & WSPI_CFG_DATA_MODE_MASK) == \
276  WSPI_CFG_DATA_MODE_NONE, \
277  "data mode specified"); \
278  (wspip)->state = WSPI_SEND; \
279  wspi_lld_command(wspip, cmdp); \
280 }
281 
282 /**
283  * @brief Sends data over the WSPI bus.
284  * @details This asynchronous function starts a transmit operation.
285  * @post At the end of the operation the configured callback is invoked.
286  *
287  * @param[in] wspip pointer to the @p WSPIDriver object
288  * @param[in] cmdp pointer to the command descriptor
289  * @param[in] n number of bytes to send or zero if no data phase
290  * @param[in] txbuf the pointer to the transmit buffer
291  *
292  * @iclass
293  */
294 #define wspiStartSendI(wspip, cmdp, n, txbuf) { \
295  osalDbgAssert(((cmdp)->cfg & WSPI_CFG_DATA_MODE_MASK) != \
296  WSPI_CFG_DATA_MODE_NONE, \
297  "data mode required"); \
298  (wspip)->state = WSPI_SEND; \
299  wspi_lld_send(wspip, cmdp, n, txbuf); \
300 }
301 
302 /**
303  * @brief Receives data from the WSPI bus.
304  * @details This asynchronous function starts a receive operation.
305  * @post At the end of the operation the configured callback is invoked.
306  *
307  * @param[in] wspip pointer to the @p WSPIDriver object
308  * @param[in] cmdp pointer to the command descriptor
309  * @param[in] n number of bytes to receive or zero if no data phase
310  * @param[out] rxbuf the pointer to the receive buffer
311  *
312  * @iclass
313  */
314 #define wspiStartReceiveI(wspip, cmdp, n, rxbuf) { \
315  osalDbgAssert(((cmdp)->cfg & WSPI_CFG_DATA_MODE_MASK) != \
316  WSPI_CFG_DATA_MODE_NONE, \
317  "data mode required"); \
318  (wspip)->state = WSPI_RECEIVE; \
319  wspi_lld_receive(wspip, cmdp, n, rxbuf); \
320 }
321 
322 #if (WSPI_SUPPORTS_MEMMAP == TRUE) || defined(__DOXYGEN__)
323 /**
324  * @brief Maps in memory space a WSPI flash device.
325  * @pre The memory flash device must be initialized appropriately
326  * before mapping it in memory space.
327  *
328  * @param[in] wspip pointer to the @p WSPIDriver object
329  * @param[in] cmdp pointer to the command descriptor
330  * @param[out] addrp pointer to the memory start address of the mapped
331  * flash or @p NULL
332  *
333  * @iclass
334  */
335 #define wspiMapFlashI(wspip, cmdp, addrp) \
336  wspi_lld_map_flash(wspip, cmdp, addrp)
337 
338 /**
339  * @brief Maps in memory space a WSPI flash device.
340  * @post The memory flash device must be re-initialized for normal
341  * commands exchange.
342  *
343  * @param[in] wspip pointer to the @p WSPIDriver object
344  *
345  * @iclass
346  */
347 #define wspiUnmapFlashI(wspip) \
348  wspi_lld_unmap_flash(wspip)
349 #endif /* WSPI_SUPPORTS_MEMMAP == TRUE */
350 /** @} */
351 
352 /**
353  * @name Low level driver helper macros
354  * @{
355  */
356 #if (WSPI_USE_WAIT == TRUE) || defined(__DOXYGEN__)
357 /**
358  * @brief Wakes up the waiting thread.
359  *
360  * @param[in] wspip pointer to the @p WSPIDriver object
361  * @param[in] msg the wakeup message
362  *
363  * @notapi
364  */
365 #define _wspi_wakeup_isr(wspip, msg) { \
366  osalSysLockFromISR(); \
367  osalThreadResumeI(&(wspip)->thread, msg); \
368  osalSysUnlockFromISR(); \
369 }
370 #else /* !WSPI_USE_WAIT */
371 #define _wspi_wakeup_isr(wspip, msg)
372 #endif /* !WSPI_USE_WAIT */
373 
374 /**
375  * @brief Common ISR code.
376  * @details This code handles the portable part of the ISR code:
377  * - Callback invocation.
378  * - Waiting thread wakeup, if any.
379  * - Driver state transitions.
380  * .
381  * @note This macro is meant to be used in the low level drivers
382  * implementation only.
383  *
384  * @param[in] wspip pointer to the @p WSPIDriver object
385  *
386  * @notapi
387  */
388 #define _wspi_isr_code(wspip) { \
389  if ((wspip)->config->end_cb) { \
390  (wspip)->state = WSPI_COMPLETE; \
391  (wspip)->config->end_cb(wspip); \
392  if ((wspip)->state == WSPI_COMPLETE) \
393  (wspip)->state = WSPI_READY; \
394  } \
395  else \
396  (wspip)->state = WSPI_READY; \
397  _wspi_wakeup_isr(wspip, MSG_OK); \
398 }
399 
400 /**
401  * @brief Common error ISR code.
402  * @details This code handles the portable part of the ISR code:
403  * - Callback invocation.
404  * - Waiting thread wakeup, if any.
405  * - Driver state transitions.
406  * .
407  * @note This macro is meant to be used in the low level drivers
408  * implementation only.
409  *
410  * @param[in] wspip pointer to the @p WSPIDriver object
411  *
412  * @notapi
413  */
414 #define _wspi_error_code(wspip) { \
415  if ((wspip)->config->error_cb) { \
416  (wspip)->state = WSPI_COMPLETE; \
417  (wspip)->config->error_cb(wspip); \
418  if ((wspip)->state == WSPI_COMPLETE) \
419  (wspip)->state = WSPI_READY; \
420  } \
421  else \
422  (wspip)->state = WSPI_READY; \
423  _wspi_wakeup_isr(wspip, MSG_RESET); \
424 }
425 /** @} */
426 
427 /*===========================================================================*/
428 /* External declarations. */
429 /*===========================================================================*/
430 
431 #ifdef __cplusplus
432 extern "C" {
433 #endif
434  void wspiInit(void);
435  void wspiObjectInit(WSPIDriver *wspip);
436  void wspiStart(WSPIDriver *wspip, const WSPIConfig *config);
437  void wspiStop(WSPIDriver *wspip);
438  void wspiStartCommand(WSPIDriver *wspip, const wspi_command_t *cmdp);
439  void wspiStartSend(WSPIDriver *wspip, const wspi_command_t *cmdp,
440  size_t n, const uint8_t *txbuf);
441  void wspiStartReceive(WSPIDriver *wspip, const wspi_command_t *cmdp,
442  size_t n, uint8_t *rxbuf);
443 #if WSPI_USE_WAIT == TRUE
444  bool wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp);
445  bool wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp,
446  size_t n, const uint8_t *txbuf);
447  bool wspiReceive(WSPIDriver *wspip, const wspi_command_t *cmdp,
448  size_t n, uint8_t *rxbuf);
449 #endif
450 #if WSPI_SUPPORTS_MEMMAP == TRUE
451 void wspiMapFlash(WSPIDriver *wspip,
452  const wspi_command_t *cmdp,
453  uint8_t **addrp);
454 void wspiUnmapFlash(WSPIDriver *wspip);
455 #endif
456 #if WSPI_USE_MUTUAL_EXCLUSION == TRUE
457  void wspiAcquireBus(WSPIDriver *wspip);
458  void wspiReleaseBus(WSPIDriver *wspip);
459 #endif
460 #ifdef __cplusplus
461 }
462 #endif
463 
464 #endif /* HAL_USE_WSPI == TRUE */
465 
466 #endif /* HAL_WSPI_H */
467 
468 /** @} */
wspi_command_t
Type of a WSPI command descriptor.
Definition: hal_wspi.h:101
wspi_command_t::addr
uint32_t addr
Address phase data.
Definition: hal_wspi.h:113
wspiAcquireBus
void wspiAcquireBus(WSPIDriver *wspip)
Gains exclusive access to the WSPI bus.
Definition: hal_wspi.c:384
wspiStart
void wspiStart(WSPIDriver *wspip, const WSPIConfig *config)
Configures and activates the WSPI peripheral.
Definition: hal_wspi.c:91
wspiStartSend
void wspiStartSend(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, const uint8_t *txbuf)
Sends a command with data over the WSPI bus.
Definition: hal_wspi.c:165
wspiUnmapFlash
void wspiUnmapFlash(WSPIDriver *wspip)
Unmaps from memory space a WSPI flash device.
Definition: hal_wspi.c:357
WSPI_COMPLETE
@ WSPI_COMPLETE
Definition: hal_wspi.h:76
wspicallback_t
void(* wspicallback_t)(WSPIDriver *wspip)
Type of a WSPI notification callback.
Definition: hal_wspi.h:96
wspi_command_t::dummy
uint32_t dummy
Number of dummy cycles to be inserted.
Definition: hal_wspi.h:121
hal_wspi_driver::thread
thread_reference_t thread
Waiting thread.
Definition: hal_wspi.h:168
wspiStop
void wspiStop(WSPIDriver *wspip)
Deactivates the WSPI peripheral.
Definition: hal_wspi.c:116
wspiReleaseBus
void wspiReleaseBus(WSPIDriver *wspip)
Releases exclusive access to the WSPI bus.
Definition: hal_wspi.c:400
wspiStartReceive
void wspiStartReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, uint8_t *rxbuf)
Sends a command then receives data over the WSPI bus.
Definition: hal_wspi.c:191
wspiInit
void wspiInit(void)
WSPI Driver initialization.
Definition: hal_wspi.c:56
ch_thread
Structure representing a thread.
Definition: chobjects.h:156
wspiObjectInit
void wspiObjectInit(WSPIDriver *wspip)
Initializes the standard part of a WSPIDriver structure.
Definition: hal_wspi.c:68
hal_wspi_driver
Structure representing an WSPI driver.
Definition: hal_wspi.h:155
WSPI_MEMMAP
@ WSPI_MEMMAP
Definition: hal_wspi.h:77
hal_wspi_config::error_cb
wspicallback_t error_cb
Operation error callback or NULL.
Definition: hal_wspi.h:147
hal_wspi_driver::mutex
mutex_t mutex
Mutex protecting the peripheral.
Definition: hal_wspi.h:174
wspiReceive
bool wspiReceive(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, uint8_t *rxbuf)
Sends a command then receives data over the WSPI bus.
Definition: hal_wspi.c:296
wspiSend
bool wspiSend(WSPIDriver *wspip, const wspi_command_t *cmdp, size_t n, const uint8_t *txbuf)
Sends a command with data over the WSPI bus.
Definition: hal_wspi.c:258
hal_wspi_config
Driver configuration structure.
Definition: hal_wspi.h:139
ch_mutex
Mutex structure.
Definition: chmtx.h:57
wspi_command_t::alt
uint32_t alt
Alternate phase data.
Definition: hal_wspi.h:117
WSPI_SEND
@ WSPI_SEND
Definition: hal_wspi.h:74
hal_wspi_lld.h
PLATFORM WSPI subsystem low level driver header.
WSPI_READY
@ WSPI_READY
Definition: hal_wspi.h:73
wspiCommand
bool wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp)
Sends a command without data phase.
Definition: hal_wspi.c:222
WSPI_STOP
@ WSPI_STOP
Definition: hal_wspi.h:72
WSPI_RECEIVE
@ WSPI_RECEIVE
Definition: hal_wspi.h:75
wspi_command_t::cfg
uint32_t cfg
Transfer configuration field.
Definition: hal_wspi.h:105
wspi_command_t::cmd
uint32_t cmd
Command phase data.
Definition: hal_wspi.h:109
WSPI_UNINIT
@ WSPI_UNINIT
Definition: hal_wspi.h:71
hal_wspi_driver::config
const WSPIConfig * config
Current configuration data.
Definition: hal_wspi.h:163
wspiStartCommand
void wspiStartCommand(WSPIDriver *wspip, const wspi_command_t *cmdp)
Sends a command without data phase.
Definition: hal_wspi.c:141
hal_wspi_driver::state
wspistate_t state
Driver state.
Definition: hal_wspi.h:159
hal_wspi_config::end_cb
wspicallback_t end_cb
Operation complete callback or NULL.
Definition: hal_wspi.h:143
wspistate_t
wspistate_t
Driver state machine possible states.
Definition: hal_wspi.h:70
wspiMapFlash
void wspiMapFlash(WSPIDriver *wspip, const wspi_command_t *cmdp, uint8_t **addrp)
Maps in memory space a WSPI flash device.
Definition: hal_wspi.c:331