28#if (HAL_USE_SPI == TRUE) || defined(__DOXYGEN__)
38#define SPI_SELECT_MODE_NONE 0
41#define SPI_SELECT_MODE_PAD 1
42#define SPI_SELECT_MODE_PORT 2
43#define SPI_SELECT_MODE_LINE 3
44#define SPI_SELECT_MODE_LLD 4
58#if !defined(SPI_USE_SYNCHRONIZATION) || defined(__DOXYGEN__)
59#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
60#define SPI_USE_SYNCHRONIZATION FALSE
62#define SPI_USE_SYNCHRONIZATION SPI_USE_WAIT
69#if !defined(SPI_USE_ASSERT_ON_ERROR) || defined(__DOXYGEN__)
70#define SPI_USE_ASSERT_ON_ERROR TRUE
77#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
78#define SPI_USE_MUTUAL_EXCLUSION TRUE
85#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
86#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
94#if (SPI_SELECT_MODE != SPI_SELECT_MODE_NONE) && \
95 (SPI_SELECT_MODE != SPI_SELECT_MODE_PAD) && \
96 (SPI_SELECT_MODE != SPI_SELECT_MODE_PORT) && \
97 (SPI_SELECT_MODE != SPI_SELECT_MODE_LINE) && \
98 (SPI_SELECT_MODE != SPI_SELECT_MODE_LLD)
99#error "invalid SPI_SELECT_MODE setting"
104#if ((SPI_SELECT_MODE != SPI_SELECT_MODE_PAD) || \
105 (SPI_SELECT_MODE != SPI_SELECT_MODE_PORT) || \
106 (SPI_SELECT_MODE != SPI_SELECT_MODE_LINE)) && \
107 (HAL_USE_PAL != TRUE)
108#error "current SPI_SELECT_MODE requires HAL_USE_PAL"
148#if !defined(SPI_SUPPORTS_CIRCULAR)
149#error "SPI_SUPPORTS_CIRCULAR not defined in LLD"
152#if !defined(SPI_SUPPORTS_SLAVE_MODE)
153#error "SPI_SUPPORTS_SLAVE_MODE not defined in LLD"
160#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined(__DOXYGEN__)
166#if (SPI_SUPPORTS_SLAVE_MODE == TRUE) || defined(__DOXYGEN__)
180#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LINE) || defined(__DOXYGEN__)
186#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PORT
197#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PAD
225#if (SPI_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
231#if (SPI_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
237#if defined(SPI_DRIVER_EXT_FIELDS)
238 SPI_DRIVER_EXT_FIELDS
265#define spiIsBufferComplete(spip) ((bool)((spip)->state == SPI_COMPLETE))
267#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
275#define spiSelectI(spip) \
277 spi_lld_select(spip); \
288#define spiUnselectI(spip) \
290 spi_lld_unselect(spip); \
293#elif SPI_SELECT_MODE == SPI_SELECT_MODE_LINE
294#define spiSelectI(spip) \
296 palClearLine((spip)->config->ssline); \
299#define spiUnselectI(spip) \
301 palSetLine((spip)->config->ssline); \
304#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PORT
305#define spiSelectI(spip) \
307 palClearPort((spip)->config->ssport, (spip)->config->ssmask); \
310#define spiUnselectI(spip) \
312 palSetPort((spip)->config->ssport, (spip)->config->ssmask); \
315#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PAD
316#define spiSelectI(spip) \
318 palClearPad((spip)->config->ssport, (spip)->config->sspad); \
321#define spiUnselectI(spip) \
323 palSetPad((spip)->config->ssport, (spip)->config->sspad); \
326#elif SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
327#define spiSelectI(spip)
329#define spiUnselectI(spip)
345#define spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame)
354#define spiAbortI(spip) spiStopTransferI(spip, NULL)
363#define spiAbort(spip) spiStopTransfer(spip, NULL)
370#if (SPI_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
379#define __spi_wakeup_isr(spip, msg) { \
380 osalSysLockFromISR(); \
381 osalThreadResumeI(&(spip)->sync_transfer, msg); \
382 osalSysUnlockFromISR(); \
385#define __spi_wakeup_isr(spip, msg)
402#define __spi_isr_complete_code(spip) { \
403 if ((spip)->config->data_cb) { \
404 (spip)->state = SPI_COMPLETE; \
405 (spip)->config->data_cb(spip); \
406 if ((spip)->state == SPI_COMPLETE) \
407 (spip)->state = SPI_READY; \
410 (spip)->state = SPI_READY; \
412 __spi_wakeup_isr(spip, MSG_OK); \
427#define __spi_isr_half_code(spip) { \
428 if ((spip)->config->data_cb) { \
429 (spip)->config->data_cb(spip); \
446#define __spi_isr_full_code(spip) { \
447 if ((spip)->config->data_cb) { \
448 (spip)->state = SPI_COMPLETE; \
449 (spip)->config->data_cb(spip); \
450 if ((spip)->state == SPI_COMPLETE) { \
451 (spip)->state = SPI_ACTIVE; \
466#define __spi_isr_error_code(spip, msg) { \
467 if ((spip)->config->error_cb) { \
468 (spip)->config->error_cb(spip); \
470 __spi_wakeup_isr(spip, msg); \
490 const void *txbuf,
void *rxbuf);
492 const void *txbuf,
void *rxbuf);
499#if SPI_USE_SYNCHRONIZATION == TRUE
507#if SPI_USE_MUTUAL_EXCLUSION == TRUE
int32_t msg_t
Type of a message.
uint32_t sysinterval_t
Type of system time interval.
void * thread_reference_t
Type of a thread reference.
uint32_t mutex_t
Type of a mutex.
uint32_t ioportid_t
Port Identifier.
uint32_t ioportmask_t
Digital I/O port sized unsigned type.
uint32_t ioline_t
Type of an I/O line.
void spiSelect(SPIDriver *spip)
Asserts the slave select signal and prepares for transfers.
void spiReleaseBus(SPIDriver *spip)
Releases exclusive access to the SPI bus.
spistate_t
Driver state machine possible states.
#define spi_lld_driver_fields
Low level fields of the SPI driver structure.
#define spiStartReceiveI(spip, n, rxbuf)
Receives data from the SPI bus.
void spiSend(SPIDriver *spip, size_t n, const void *txbuf)
Sends data over the SPI bus.
void spiInit(void)
SPI Driver initialization.
void spiIgnore(SPIDriver *spip, size_t n)
Ignores data on the SPI bus.
struct hal_spi_config SPIConfig
Type of a SPI driver configuration structure.
#define spiStartExchangeI(spip, n, txbuf, rxbuf)
Exchanges data on the SPI bus.
#define spi_lld_config_fields
Low level fields of the SPI configuration structure.
void spiAcquireBus(SPIDriver *spip)
Gains exclusive access to the SPI bus.
void spiObjectInit(SPIDriver *spip)
Initializes the standard part of a SPIDriver structure.
void spiStartSend(SPIDriver *spip, size_t n, const void *txbuf)
Sends data over the SPI bus.
msg_t spiStart(SPIDriver *spip, const SPIConfig *config)
Configures and activates the SPI peripheral.
void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf)
Receives data from the SPI bus.
void spiStartIgnore(SPIDriver *spip, size_t n)
Ignores data on the SPI bus.
struct hal_spi_driver SPIDriver
Type of a structure representing an SPI driver.
#define spiStartSendI(spip, n, txbuf)
Sends data over the SPI bus.
void spiStop(SPIDriver *spip)
Deactivates the SPI peripheral.
#define spiStartIgnoreI(spip, n)
Ignores data on the SPI bus.
void spiReceive(SPIDriver *spip, size_t n, void *rxbuf)
Receives data from the SPI bus.
void spiUnselect(SPIDriver *spip)
Deasserts the slave select signal.
void spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf)
Exchanges data on the SPI bus.
void spiStartExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf)
Exchanges data on the SPI bus.
void(* spicb_t)(SPIDriver *spip)
SPI notification callback type.
msg_t spiStopTransfer(SPIDriver *spip, size_t *sizep)
Stops the ongoing SPI operation, if any.
msg_t spiStopTransferI(SPIDriver *spip, size_t *sizep)
Stops the ongoing SPI operation.
msg_t spiSynchronizeS(SPIDriver *spip, sysinterval_t timeout)
Synchronizes with current transfer completion.
msg_t spiSynchronize(SPIDriver *spip, sysinterval_t timeout)
Synchronizes with current transfer completion.
PLATFORM SPI (v2) subsystem low level driver header.
Driver configuration structure.
bool slave
Enables the slave mode.
spicb_t error_cb
Operation error callback or NULL.
ioportid_t ssport
The chip select port.
ioportmask_t ssmask
The chip select port mask.
spicb_t data_cb
Operation data callback or NULL.
bool circular
Enables the circular buffer mode.
uint_fast8_t sspad
The chip select pad number.
ioline_t ssline
The chip select line.
Structure representing an SPI driver.
const SPIConfig * config
Current configuration data.
thread_reference_t sync_transfer
Synchronization point for transfer.
mutex_t mutex
Mutex protecting the peripheral.
spistate_t state
Driver state.