SPI driver improvements.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10545 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
Giovanni Di Sirio 2017-09-03 15:48:09 +00:00
parent 4b148d3cbc
commit 9d9a04e464
5 changed files with 139 additions and 20 deletions

View File

@ -31,6 +31,19 @@
/* Driver constants. */
/*===========================================================================*/
/**
* @name Chip Select modes
* @{
*/
#define SPI_SELECT_MODE_NONE 0 /** @brief @p spiSelect() and
@p spiUnselect() do
nothing. */
#define SPI_SELECT_MODE_PAD 1 /** @brief Legacy mode. */
#define SPI_SELECT_MODE_PORT 2 /** @brief Fastest mode. */
#define SPI_SELECT_MODE_LINE 3 /** @brief Packed mode. */
#define SPI_SELECT_MODE_LLD 4 /** @brief LLD-defined mode.*/
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@ -44,7 +57,7 @@
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
#define SPI_USE_WAIT TRUE
#define SPI_USE_WAIT TRUE
#endif
/**
@ -52,7 +65,15 @@
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE
#define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif
/**
* @brief Enables the use of the .
* @note Disabling this option saves both code and data space.
*/
#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__)
#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD
#endif
/** @} */
@ -60,6 +81,14 @@
/* Derived constants and error checks. */
/*===========================================================================*/
#if (SPI_SELECT_MODE != SPI_SELECT_MODE_NONE) && \
(SPI_SELECT_MODE != SPI_SELECT_MODE_PAD) && \
(SPI_SELECT_MODE != SPI_SELECT_MODE_PORT) && \
(SPI_SELECT_MODE != SPI_SELECT_MODE_LINE) && \
(SPI_SELECT_MODE != SPI_SELECT_MODE_LLD)
#error "invalid SPI_SELECT_MODE setting"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@ -85,6 +114,7 @@ typedef enum {
* @name Macro Functions
* @{
*/
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
/**
* @brief Asserts the slave select signal and prepares for transfers.
*
@ -92,9 +122,10 @@ typedef enum {
*
* @iclass
*/
#define spiSelectI(spip) { \
#define spiSelectI(spip) \
do { \
spi_lld_select(spip); \
}
} while (false)
/**
* @brief Deasserts the slave select signal.
@ -104,9 +135,49 @@ typedef enum {
*
* @iclass
*/
#define spiUnselectI(spip) { \
#define spiUnselectI(spip) \
do { \
spi_lld_unselect(spip); \
}
} while (false)
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_LINE
#define spiSelectI(spip) \
do { \
palClearLine(spip->config->ssline); \
} while (false)
#define spiUnselectI(spip) \
do { \
palSetLine(spip->config->ssline); \
} while (false)
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PORT
#define spiSelectI(spip) \
do { \
palClearPort(spip->config->ssport, spip->config->ssmask); \
} while (false)
#define spiUnselectI(spip) \
do { \
palSetPort(spip->config->ssport, spip->config->ssmask); \
} while (false)
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PAD
#define spiSelectI(spip) \
do { \
palClearPad(spip->config->ssport, spip->config->sspad); \
} while (false)
#define spiUnselectI(spip) \
do { \
palSetPad(spip->config->ssport, spip->config->sspad); \
} while (false)
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
#define spiSelectI(spip)
#define spiUnselectI(spip)
#endif
/**
* @brief Ignores data on the SPI bus.

View File

@ -476,6 +476,7 @@ void spi_lld_stop(SPIDriver *spip) {
}
}
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
/**
* @brief Asserts the slave select signal and prepares for transfers.
*
@ -485,7 +486,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
palClearPad(spip->config->ssport, spip->config->sspad);
/* No implementation on STM32.*/
}
/**
@ -498,8 +499,9 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
palSetPad(spip->config->ssport, spip->config->sspad);
/* No implementation on STM32.*/
}
#endif
/**
* @brief Ignores data on the SPI bus.

View File

@ -396,6 +396,10 @@
#define STM32_DMA_REQUIRED
#endif
#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
#error "SPI_SELECT_MODE_LLD not supported by this driver"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@ -421,15 +425,33 @@ typedef struct {
* @brief Operation complete callback or @p NULL.
*/
spicallback_t end_cb;
/* End of the mandatory fields.*/
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LINE) || defined(__DOXYGEN__)
/**
* @brief The chip select line port.
* @brief The chip select line.
*/
ioportid_t ssline;
#endif
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PORT) || defined(__DOXYGEN__)
/**
* @brief The chip select port.
*/
ioportid_t ssport;
/**
* @brief The chip select line pad number.
* @brief The chip select port mask.
*/
uint16_t sspad;
uint8fast_t ssmask;
#endif
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PAD) || defined(__DOXYGEN__)
/**
* @brief The chip select port.
*/
ioportid_t ssport;
/**
* @brief The chip select pad number.
*/
uint_fast8_t sspad;
#endif
/* End of the mandatory fields.*/
/**
* @brief SPI CR1 register initialization data.
*/
@ -528,8 +550,10 @@ extern "C" {
void spi_lld_init(void);
void spi_lld_start(SPIDriver *spip);
void spi_lld_stop(SPIDriver *spip);
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip);
#endif
void spi_lld_ignore(SPIDriver *spip, size_t n);
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf);

View File

@ -478,6 +478,7 @@ void spi_lld_stop(SPIDriver *spip) {
}
}
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
/**
* @brief Asserts the slave select signal and prepares for transfers.
*
@ -487,7 +488,7 @@ void spi_lld_stop(SPIDriver *spip) {
*/
void spi_lld_select(SPIDriver *spip) {
palClearPad(spip->config->ssport, spip->config->sspad);
/* No implementation on STM32.*/
}
/**
@ -500,8 +501,9 @@ void spi_lld_select(SPIDriver *spip) {
*/
void spi_lld_unselect(SPIDriver *spip) {
palSetPad(spip->config->ssport, spip->config->sspad);
/* No implementation on STM32.*/
}
#endif
/**
* @brief Ignores data on the SPI bus.

View File

@ -396,6 +396,10 @@
#define STM32_DMA_REQUIRED
#endif
#if SPI_SELECT_MODE == SPI_SELECT_MODE_LLD
#error "SPI_SELECT_MODE_LLD not supported by this driver"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@ -421,15 +425,33 @@ typedef struct {
* @brief Operation complete callback or @p NULL.
*/
spicallback_t end_cb;
/* End of the mandatory fields.*/
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LINE) || defined(__DOXYGEN__)
/**
* @brief The chip select line port.
* @brief The chip select line.
*/
ioportid_t ssline;
#endif
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PORT) || defined(__DOXYGEN__)
/**
* @brief The chip select port.
*/
ioportid_t ssport;
/**
* @brief The chip select line pad number.
* @brief The chip select port mask.
*/
uint16_t sspad;
uint8fast_t ssmask;
#endif
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PAD) || defined(__DOXYGEN__)
/**
* @brief The chip select port.
*/
ioportid_t ssport;
/**
* @brief The chip select pad number.
*/
uint_fast8_t sspad;
#endif
/* End of the mandatory fields.*/
/**
* @brief SPI CR1 register initialization data.
*/
@ -528,8 +550,6 @@ extern "C" {
void spi_lld_init(void);
void spi_lld_start(SPIDriver *spip);
void spi_lld_stop(SPIDriver *spip);
void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip);
void spi_lld_ignore(SPIDriver *spip, size_t n);
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf);