|
ChibiOS/RT
2.5.1 |
|
Generic SPI Driver.
This module implements a generic SPI (Serial Peripheral Interface) driver allowing bidirectional and monodirectional transfers, complex atomic transactions are supported as well.
HAL_USE_SPI option must be enabled in halconf.h.The driver implements a state machine internally, not all the driver functionalities can be used in any moment, any transition not explicitly shown in the following diagram has to be considered an error and shall be captured by an assertion (if enabled).
The driver is not thread safe for performance reasons, if you need to access the SPI bus from multiple threads then use the spiAcquireBus() and spiReleaseBus() APIs in order to gain exclusive access.
Data Structures | |
| struct | SPIConfig |
| Driver configuration structure. More... | |
| struct | SPIDriver |
| Structure representing a SPI driver. More... | |
Functions | |
| void | spiInit (void) |
| SPI Driver initialization. | |
| void | spiObjectInit (SPIDriver *spip) |
Initializes the standard part of a SPIDriver structure. | |
| void | spiStart (SPIDriver *spip, const SPIConfig *config) |
| Configures and activates the SPI peripheral. | |
| void | spiStop (SPIDriver *spip) |
| Deactivates the SPI peripheral. | |
| void | spiSelect (SPIDriver *spip) |
| Asserts the slave select signal and prepares for transfers. | |
| void | spiUnselect (SPIDriver *spip) |
| Deasserts the slave select signal. | |
| void | spiStartIgnore (SPIDriver *spip, size_t n) |
| Ignores data on the SPI bus. | |
| void | spiStartExchange (SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) |
| Exchanges data on the SPI bus. | |
| void | spiStartSend (SPIDriver *spip, size_t n, const void *txbuf) |
| Sends data over the SPI bus. | |
| void | spiStartReceive (SPIDriver *spip, size_t n, void *rxbuf) |
| Receives data from the SPI bus. | |
| void | spiIgnore (SPIDriver *spip, size_t n) |
| Ignores data on the SPI bus. | |
| void | spiExchange (SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) |
| Exchanges data on the SPI bus. | |
| void | spiSend (SPIDriver *spip, size_t n, const void *txbuf) |
| Sends data over the SPI bus. | |
| void | spiReceive (SPIDriver *spip, size_t n, void *rxbuf) |
| Receives data from the SPI bus. | |
| void | spiAcquireBus (SPIDriver *spip) |
| Gains exclusive access to the SPI bus. | |
| void | spiReleaseBus (SPIDriver *spip) |
| Releases exclusive access to the SPI bus. | |
| CH_IRQ_HANDLER (10) | |
| IRQ 10 service routine. | |
| void | spi_lld_init (void) |
| Low level SPI driver initialization. | |
| void | spi_lld_start (SPIDriver *spip) |
| Configures and activates the SPI peripheral. | |
| void | spi_lld_stop (SPIDriver *spip) |
| Deactivates the SPI peripheral. | |
| void | spi_lld_select (SPIDriver *spip) |
| Asserts the slave select signal and prepares for transfers. | |
| void | spi_lld_unselect (SPIDriver *spip) |
| Deasserts the slave select signal. | |
| void | spi_lld_ignore (SPIDriver *spip, size_t n) |
| Ignores data on the SPI bus. | |
| void | spi_lld_exchange (SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) |
| Exchanges data on the SPI bus. | |
| void | spi_lld_send (SPIDriver *spip, size_t n, const void *txbuf) |
| Sends data over the SPI bus. | |
| void | spi_lld_receive (SPIDriver *spip, size_t n, void *rxbuf) |
| Receives data from the SPI bus. | |
| uint8_t | spi_lld_polled_exchange (SPIDriver *spip, uint8_t frame) |
| Exchanges one frame using a polled wait. | |
Variables | |
| SPIDriver | SPID1 |
| SPI1 driver identifier. | |
SPI configuration options | |
| #define | SPI_USE_WAIT TRUE |
| Enables synchronous APIs. | |
| #define | SPI_USE_MUTUAL_EXCLUSION TRUE |
Enables the spiAcquireBus() and spiReleaseBus() APIs. | |
Macro Functions | |
| #define | spiSelectI(spip) |
| Asserts the slave select signal and prepares for transfers. | |
| #define | spiUnselectI(spip) |
| Deasserts the slave select signal. | |
| #define | spiStartIgnoreI(spip, n) |
| Ignores data on the SPI bus. | |
| #define | spiStartExchangeI(spip, n, txbuf, rxbuf) |
| Exchanges data on the SPI bus. | |
| #define | spiStartSendI(spip, n, txbuf) |
| Sends data over the SPI bus. | |
| #define | spiStartReceiveI(spip, n, rxbuf) |
| Receives data from the SPI bus. | |
| #define | spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame) |
| Exchanges one frame using a polled wait. | |
Low Level driver helper macros | |
| #define | _spi_wait_s(spip) |
| Waits for operation completion. | |
| #define | _spi_wakeup_isr(spip) |
| Wakes up the waiting thread. | |
| #define | _spi_isr_code(spip) |
| Common ISR code. | |
Defines | |
| #define | STM8S_SPI_USE_SPI TRUE |
| SPI1 driver enable switch. | |
| #define | STM8S_SPI_ERROR_HOOK(spip) chSysHalt() |
| Overflow error hook. | |
Typedefs | |
| typedef struct SPIDriver | SPIDriver |
| Type of a structure representing an SPI driver. | |
| typedef void(* | spicallback_t )(SPIDriver *spip) |
| SPI notification callback type. | |
Enumerations | |
| enum | spistate_t { SPI_UNINIT = 0, SPI_STOP = 1, SPI_READY = 2, SPI_ACTIVE = 3, SPI_COMPLETE = 4 } |
| Driver state machine possible states. More... | |
| void spiInit | ( | void | ) |
SPI Driver initialization.
halInit(), there is no need to explicitly initialize the driver.Definition at line 61 of file spi.c.
References spi_lld_init().
Referenced by halInit().

| void spiObjectInit | ( | SPIDriver * | spip | ) |
Initializes the standard part of a SPIDriver structure.
| [out] | spip | pointer to the SPIDriver object |
Definition at line 73 of file spi.c.
References SPIDriver::config, SPIDriver::mutex, SPI_STOP, SPIDriver::state, and SPIDriver::thread.
Referenced by spi_lld_init().
Configures and activates the SPI peripheral.
Definition at line 100 of file spi.c.
References SPIDriver::config, spi_lld_start(), SPI_READY, SPI_STOP, and SPIDriver::state.

| void spiStop | ( | SPIDriver * | spip | ) |
Deactivates the SPI peripheral.
| [in] | spip | pointer to the SPIDriver object |
Definition at line 122 of file spi.c.
References spi_lld_stop(), spi_lld_unselect(), SPI_READY, SPI_STOP, and SPIDriver::state.

| void spiSelect | ( | SPIDriver * | spip | ) |
Asserts the slave select signal and prepares for transfers.
| [in] | spip | pointer to the SPIDriver object |
Definition at line 142 of file spi.c.
References SPI_READY, spiSelectI, and SPIDriver::state.
| void spiUnselect | ( | SPIDriver * | spip | ) |
Deasserts the slave select signal.
The previously selected peripheral is unselected.
| [in] | spip | pointer to the SPIDriver object |
Definition at line 160 of file spi.c.
References SPI_READY, spiUnselectI, and SPIDriver::state.
| void spiStartIgnore | ( | SPIDriver * | spip, |
| size_t | n | ||
| ) |
Ignores data on the SPI bus.
This asynchronous function starts the transmission of a series of idle words on the SPI bus and ignores the received data.
spiSelect() or spiSelectI(). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to be ignored |
Definition at line 183 of file spi.c.
References SPI_READY, spiStartIgnoreI, and SPIDriver::state.
| void spiStartExchange | ( | SPIDriver * | spip, |
| size_t | n, | ||
| const void * | txbuf, | ||
| void * | rxbuf | ||
| ) |
Exchanges data on the SPI bus.
This asynchronous function starts a simultaneous transmit/receive operation.
spiSelect() or spiSelectI(). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to be exchanged |
| [in] | txbuf | the pointer to the transmit buffer |
| [out] | rxbuf | the pointer to the receive buffer |
Definition at line 210 of file spi.c.
References SPI_READY, spiStartExchangeI, and SPIDriver::state.
| void spiStartSend | ( | SPIDriver * | spip, |
| size_t | n, | ||
| const void * | txbuf | ||
| ) |
Sends data over the SPI bus.
This asynchronous function starts a transmit operation.
spiSelect() or spiSelectI(). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to send |
| [in] | txbuf | the pointer to the transmit buffer |
Definition at line 237 of file spi.c.
References SPI_READY, spiStartSendI, and SPIDriver::state.
| void spiStartReceive | ( | SPIDriver * | spip, |
| size_t | n, | ||
| void * | rxbuf | ||
| ) |
Receives data from the SPI bus.
This asynchronous function starts a receive operation.
spiSelect() or spiSelectI(). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to receive |
| [out] | rxbuf | the pointer to the receive buffer |
Definition at line 263 of file spi.c.
References SPI_READY, spiStartReceiveI, and SPIDriver::state.
| void spiIgnore | ( | SPIDriver * | spip, |
| size_t | n | ||
| ) |
Ignores data on the SPI bus.
This synchronous function performs the transmission of a series of idle words on the SPI bus and ignores the received data.
SPI_USE_WAIT must be enabled. end_cb = NULL).| [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to be ignored |
Definition at line 289 of file spi.c.
References _spi_wait_s, SPIDriver::config, SPIConfig::end_cb, SPI_READY, spiStartIgnoreI, and SPIDriver::state.
| void spiExchange | ( | SPIDriver * | spip, |
| size_t | n, | ||
| const void * | txbuf, | ||
| void * | rxbuf | ||
| ) |
Exchanges data on the SPI bus.
This synchronous function performs a simultaneous transmit/receive operation.
SPI_USE_WAIT must be enabled. end_cb = NULL). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to be exchanged |
| [in] | txbuf | the pointer to the transmit buffer |
| [out] | rxbuf | the pointer to the receive buffer |
Definition at line 319 of file spi.c.
References _spi_wait_s, SPIDriver::config, SPIConfig::end_cb, SPI_READY, spiStartExchangeI, and SPIDriver::state.
| void spiSend | ( | SPIDriver * | spip, |
| size_t | n, | ||
| const void * | txbuf | ||
| ) |
Sends data over the SPI bus.
This synchronous function performs a transmit operation.
SPI_USE_WAIT must be enabled. end_cb = NULL). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to send |
| [in] | txbuf | the pointer to the transmit buffer |
Definition at line 350 of file spi.c.
References _spi_wait_s, SPIDriver::config, SPIConfig::end_cb, SPI_READY, spiStartSendI, and SPIDriver::state.
| void spiReceive | ( | SPIDriver * | spip, |
| size_t | n, | ||
| void * | rxbuf | ||
| ) |
Receives data from the SPI bus.
This synchronous function performs a receive operation.
SPI_USE_WAIT must be enabled. end_cb = NULL). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to receive |
| [out] | rxbuf | the pointer to the receive buffer |
Definition at line 378 of file spi.c.
References _spi_wait_s, SPIDriver::config, SPIConfig::end_cb, SPI_READY, spiStartReceiveI, and SPIDriver::state.
| void spiAcquireBus | ( | SPIDriver * | spip | ) |
Gains exclusive access to the SPI bus.
This function tries to gain ownership to the SPI bus, if the bus is already being used then the invoking thread is queued.
SPI_USE_MUTUAL_EXCLUSION must be enabled.| [in] | spip | pointer to the SPIDriver object |
Definition at line 405 of file spi.c.
References SPIDriver::mutex.
| void spiReleaseBus | ( | SPIDriver * | spip | ) |
Releases exclusive access to the SPI bus.
SPI_USE_MUTUAL_EXCLUSION must be enabled.| [in] | spip | pointer to the SPIDriver object |
| CH_IRQ_HANDLER | ( | 10 | ) |
IRQ 10 service routine.
Definition at line 61 of file spi_lld.c.
References _spi_isr_code, SPIDriver::rxcnt, SPIDriver::rxptr, STM8S_SPI_ERROR_HOOK, SPIDriver::txcnt, and SPIDriver::txptr.
| void spi_lld_init | ( | void | ) |
Low level SPI driver initialization.
Definition at line 113 of file spi_lld.c.
References spiObjectInit().
Referenced by spiInit().

| void spi_lld_start | ( | SPIDriver * | spip | ) |
Configures and activates the SPI peripheral.
| [in] | spip | pointer to the SPIDriver object |
Definition at line 127 of file spi_lld.c.
References SPIDriver::config, and SPIConfig::cr1.
Referenced by spiStart().
| void spi_lld_stop | ( | SPIDriver * | spip | ) |
| void spi_lld_select | ( | SPIDriver * | spip | ) |
Asserts the slave select signal and prepares for transfers.
| [in] | spip | pointer to the SPIDriver object |
Definition at line 166 of file spi_lld.c.
References SPIDriver::config, palClearPad, SPIConfig::sspad, and SPIConfig::ssport.
| void spi_lld_unselect | ( | SPIDriver * | spip | ) |
Deasserts the slave select signal.
The previously selected peripheral is unselected.
| [in] | spip | pointer to the SPIDriver object |
Definition at line 179 of file spi_lld.c.
References SPIDriver::config, palSetPad, SPIConfig::sspad, and SPIConfig::ssport.
Referenced by spiStop().
| void spi_lld_ignore | ( | SPIDriver * | spip, |
| size_t | n | ||
| ) |
Ignores data on the SPI bus.
This function transmits a series of idle words on the SPI bus and ignores the received data. This function can be invoked even when a slave select signal has not been yet asserted.
| [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to be ignored |
Definition at line 195 of file spi_lld.c.
References SPIDriver::rxcnt, SPIDriver::rxptr, SPIDriver::txcnt, and SPIDriver::txptr.
| void spi_lld_exchange | ( | SPIDriver * | spip, |
| size_t | n, | ||
| const void * | txbuf, | ||
| void * | rxbuf | ||
| ) |
Exchanges data on the SPI bus.
This asynchronous function starts a simultaneous transmit/receive operation.
| [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to be exchanged |
| [in] | txbuf | the pointer to the transmit buffer |
| [out] | rxbuf | the pointer to the receive buffer |
Definition at line 218 of file spi_lld.c.
References SPIDriver::rxcnt, SPIDriver::rxptr, SPIDriver::txcnt, and SPIDriver::txptr.
| void spi_lld_send | ( | SPIDriver * | spip, |
| size_t | n, | ||
| const void * | txbuf | ||
| ) |
Sends data over the SPI bus.
This asynchronous function starts a transmit operation.
| [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to send |
| [in] | txbuf | the pointer to the transmit buffer |
Definition at line 240 of file spi_lld.c.
References SPIDriver::rxcnt, SPIDriver::rxptr, SPIDriver::txcnt, and SPIDriver::txptr.
| void spi_lld_receive | ( | SPIDriver * | spip, |
| size_t | n, | ||
| void * | rxbuf | ||
| ) |
Receives data from the SPI bus.
This asynchronous function starts a receive operation.
| [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to receive |
| [out] | rxbuf | the pointer to the receive buffer |
Definition at line 261 of file spi_lld.c.
References SPIDriver::rxcnt, SPIDriver::rxptr, SPIDriver::txcnt, and SPIDriver::txptr.
| uint8_t spi_lld_polled_exchange | ( | SPIDriver * | spip, |
| uint8_t | frame | ||
| ) |
Exchanges one frame using a polled wait.
This synchronous function exchanges one frame using a polled synchronization method. This function is useful when exchanging small amount of data on high speed channels, usually in this situation is much more efficient just wait for completion using polling than suspending the thread waiting for an interrupt.
| [in] | spip | pointer to the SPIDriver object |
| [in] | frame | the data frame to send over the SPI bus |
| #define SPI_USE_WAIT TRUE |
| #define SPI_USE_MUTUAL_EXCLUSION TRUE |
Enables the spiAcquireBus() and spiReleaseBus() APIs.
| #define spiSelectI | ( | spip | ) |
{ \
spi_lld_select(spip); \
}
Asserts the slave select signal and prepares for transfers.
| [in] | spip | pointer to the SPIDriver object |
Definition at line 103 of file spi.h.
Referenced by spiSelect().
| #define spiUnselectI | ( | spip | ) |
{ \
spi_lld_unselect(spip); \
}
Deasserts the slave select signal.
The previously selected peripheral is unselected.
| [in] | spip | pointer to the SPIDriver object |
Definition at line 115 of file spi.h.
Referenced by spiUnselect().
| #define spiStartIgnoreI | ( | spip, | |
| n | |||
| ) |
{ \
(spip)->state = SPI_ACTIVE; \
spi_lld_ignore(spip, n); \
}
Ignores data on the SPI bus.
This asynchronous function starts the transmission of a series of idle words on the SPI bus and ignores the received data.
spiSelect() or spiSelectI(). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to be ignored |
Definition at line 132 of file spi.h.
Referenced by spiIgnore(), and spiStartIgnore().
| #define spiStartExchangeI | ( | spip, | |
| n, | |||
| txbuf, | |||
| rxbuf | |||
| ) |
{ \
(spip)->state = SPI_ACTIVE; \
spi_lld_exchange(spip, n, txbuf, rxbuf); \
}
Exchanges data on the SPI bus.
This asynchronous function starts a simultaneous transmit/receive operation.
spiSelect() or spiSelectI(). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to be exchanged |
| [in] | txbuf | the pointer to the transmit buffer |
| [out] | rxbuf | the pointer to the receive buffer |
Definition at line 154 of file spi.h.
Referenced by spiExchange(), and spiStartExchange().
| #define spiStartSendI | ( | spip, | |
| n, | |||
| txbuf | |||
| ) |
{ \
(spip)->state = SPI_ACTIVE; \
spi_lld_send(spip, n, txbuf); \
}
Sends data over the SPI bus.
This asynchronous function starts a transmit operation.
spiSelect() or spiSelectI(). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to send |
| [in] | txbuf | the pointer to the transmit buffer |
Definition at line 174 of file spi.h.
Referenced by spiSend(), and spiStartSend().
| #define spiStartReceiveI | ( | spip, | |
| n, | |||
| rxbuf | |||
| ) |
{ \
(spip)->state = SPI_ACTIVE; \
spi_lld_receive(spip, n, rxbuf); \
}
Receives data from the SPI bus.
This asynchronous function starts a receive operation.
spiSelect() or spiSelectI(). | [in] | spip | pointer to the SPIDriver object |
| [in] | n | number of words to receive |
| [out] | rxbuf | the pointer to the receive buffer |
Definition at line 194 of file spi.h.
Referenced by spiReceive(), and spiStartReceive().
| #define spiPolledExchange | ( | spip, | |
| frame | |||
| ) | spi_lld_polled_exchange(spip, frame) |
Exchanges one frame using a polled wait.
This synchronous function exchanges one frame using a polled synchronization method. This function is useful when exchanging small amount of data on high speed channels, usually in this situation is much more efficient just wait for completion using polling than suspending the thread waiting for an interrupt.
| [in] | spip | pointer to the SPIDriver object |
| [in] | frame | the data frame to send over the SPI bus |
| #define _spi_wait_s | ( | spip | ) |
{ \
chDbgAssert((spip)->thread == NULL, \
"_spi_wait(), #1", "already waiting"); \
(spip)->thread = chThdSelf(); \
chSchGoSleepS(THD_STATE_SUSPENDED); \
}
Waits for operation completion.
This function waits for the driver to complete the current operation.
| [in] | spip | pointer to the SPIDriver object |
Definition at line 232 of file spi.h.
Referenced by spiExchange(), spiIgnore(), spiReceive(), and spiSend().
| #define _spi_wakeup_isr | ( | spip | ) |
{ \
if ((spip)->thread != NULL) { \
Thread *tp = (spip)->thread; \
(spip)->thread = NULL; \
chSysLockFromIsr(); \
chSchReadyI(tp); \
chSysUnlockFromIsr(); \
} \
}
Wakes up the waiting thread.
| [in] | spip | pointer to the SPIDriver object |
| #define _spi_isr_code | ( | spip | ) |
{ \
if ((spip)->config->end_cb) { \
(spip)->state = SPI_COMPLETE; \
(spip)->config->end_cb(spip); \
if ((spip)->state == SPI_COMPLETE) \
(spip)->state = SPI_READY; \
} \
else \
(spip)->state = SPI_READY; \
_spi_wakeup_isr(spip); \
}
Common ISR code.
This code handles the portable part of the ISR code:
| [in] | spip | pointer to the SPIDriver object |
Definition at line 274 of file spi.h.
Referenced by CH_IRQ_HANDLER().
| #define STM8S_SPI_USE_SPI TRUE |
| #define STM8S_SPI_ERROR_HOOK | ( | spip | ) | chSysHalt() |
Overflow error hook.
The default action is to stop the system.
Definition at line 56 of file spi_lld.h.
Referenced by CH_IRQ_HANDLER().
| typedef void(* spicallback_t)(SPIDriver *spip) |
| enum spistate_t |