ChibiOS/HAL 9.0.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 */
70typedef 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. */
79
80/**
81 * @brief Type of a structure representing an WSPI driver.
82 */
84
85/**
86 * @brief Type of a structure representing an WSPI driver configuration.
87 */
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 */
96typedef void (*wspicallback_t)(WSPIDriver *wspip);
97
98/**
99 * @brief Type of a WSPI command descriptor.
100 */
101typedef 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.*/
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.*/
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
432extern "C" {
433#endif
434 void wspiInit(void);
435 void wspiObjectInit(WSPIDriver *wspip);
436 msg_t 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
451void wspiMapFlash(WSPIDriver *wspip,
452 const wspi_command_t *cmdp,
453 uint8_t **addrp);
454void 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/** @} */
int32_t msg_t
Type of a message.
Definition osal.h:159
void * thread_reference_t
Type of a thread reference.
Definition osal.h:186
uint32_t mutex_t
Type of a mutex.
Definition osal.h:229
#define wspi_lld_driver_fields
Low level fields of the WSPI driver structure.
void wspiObjectInit(WSPIDriver *wspip)
Initializes the standard part of a WSPIDriver structure.
Definition hal_wspi.c:68
void wspiMapFlash(WSPIDriver *wspip, const wspi_command_t *cmdp, uint8_t **addrp)
Maps in memory space a WSPI flash device.
Definition hal_wspi.c:346
#define wspi_lld_config_fields
Low level fields of the WSPI configuration structure.
struct hal_wspi_driver WSPIDriver
Type of a structure representing an WSPI driver.
Definition hal_wspi.h:83
void wspiAcquireBus(WSPIDriver *wspip)
Gains exclusive access to the WSPI bus.
Definition hal_wspi.c:399
wspistate_t
Driver state machine possible states.
Definition hal_wspi.h:70
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:180
void wspiInit(void)
WSPI Driver initialization.
Definition hal_wspi.c:56
void wspiStartCommand(WSPIDriver *wspip, const wspi_command_t *cmdp)
Sends a command without data phase.
Definition hal_wspi.c:156
msg_t wspiStart(WSPIDriver *wspip, const WSPIConfig *config)
Configures and activates the WSPI peripheral.
Definition hal_wspi.c:92
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:311
void wspiReleaseBus(WSPIDriver *wspip)
Releases exclusive access to the WSPI bus.
Definition hal_wspi.c:415
bool wspiCommand(WSPIDriver *wspip, const wspi_command_t *cmdp)
Sends a command without data phase.
Definition hal_wspi.c:237
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:273
void wspiUnmapFlash(WSPIDriver *wspip)
Unmaps from memory space a WSPI flash device.
Definition hal_wspi.c:372
void(* wspicallback_t)(WSPIDriver *wspip)
Type of a WSPI notification callback.
Definition hal_wspi.h:96
struct hal_wspi_config WSPIConfig
Type of a structure representing an WSPI driver configuration.
Definition hal_wspi.h:88
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:206
void wspiStop(WSPIDriver *wspip)
Deactivates the WSPI peripheral.
Definition hal_wspi.c:131
@ WSPI_COMPLETE
Definition hal_wspi.h:76
@ WSPI_SEND
Definition hal_wspi.h:74
@ WSPI_STOP
Definition hal_wspi.h:72
@ WSPI_MEMMAP
Definition hal_wspi.h:77
@ WSPI_UNINIT
Definition hal_wspi.h:71
@ WSPI_RECEIVE
Definition hal_wspi.h:75
@ WSPI_READY
Definition hal_wspi.h:73
PLATFORM WSPI subsystem low level driver header.
Driver configuration structure.
Definition hal_wspi.h:139
wspicallback_t error_cb
Operation error callback or NULL.
Definition hal_wspi.h:147
wspicallback_t end_cb
Operation complete callback or NULL.
Definition hal_wspi.h:143
Structure representing an WSPI driver.
Definition hal_wspi.h:155
const WSPIConfig * config
Current configuration data.
Definition hal_wspi.h:163
thread_reference_t thread
Waiting thread.
Definition hal_wspi.h:168
wspistate_t state
Driver state.
Definition hal_wspi.h:159
mutex_t mutex
Mutex protecting the peripheral.
Definition hal_wspi.h:174
Type of a WSPI command descriptor.
Definition hal_wspi.h:101
uint32_t dummy
Number of dummy cycles to be inserted.
Definition hal_wspi.h:121
uint32_t cfg
Transfer configuration field.
Definition hal_wspi.h:105
uint32_t alt
Alternate phase data.
Definition hal_wspi.h:117
uint32_t addr
Address phase data.
Definition hal_wspi.h:113
uint32_t cmd
Command phase data.
Definition hal_wspi.h:109