aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2017-09-03 15:48:09 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2017-09-03 15:48:09 +0000
commit9d9a04e4645b9f4b70e74dd4245a1412e82c902a (patch)
treefd48c875d30f2895654697ef6562c19dd6189282 /os
parent4b148d3cbcd338dd5d72fac683e712f448d08341 (diff)
downloadChibiOS-9d9a04e4645b9f4b70e74dd4245a1412e82c902a.tar.gz
ChibiOS-9d9a04e4645b9f4b70e74dd4245a1412e82c902a.tar.bz2
ChibiOS-9d9a04e4645b9f4b70e74dd4245a1412e82c902a.zip
SPI driver improvements.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10545 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/include/hal_spi.h83
-rw-r--r--os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c6
-rw-r--r--os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.h32
-rw-r--r--os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c6
-rw-r--r--os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h32
5 files changed, 139 insertions, 20 deletions
diff --git a/os/hal/include/hal_spi.h b/os/hal/include/hal_spi.h
index 9e4b46425..3795bf828 100644
--- a/os/hal/include/hal_spi.h
+++ b/os/hal/include/hal_spi.h
@@ -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.
diff --git a/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c b/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
index 067651691..3cae1a9e7 100644
--- a/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
+++ b/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.c
@@ -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.
diff --git a/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.h b/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.h
index 2f3435ea2..b2755f31b 100644
--- a/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.h
+++ b/os/hal/ports/STM32/LLD/SPIv1/hal_spi_lld.h
@@ -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.
+ */
+ ioportid_t ssline;
+#endif
+#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PORT) || defined(__DOXYGEN__)
/**
- * @brief The chip select line port.
+ * @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);
diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
index faa5fa1cc..6adc0b920 100644
--- a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
+++ b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.c
@@ -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.
diff --git a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h
index a3565655f..99587c8fe 100644
--- a/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h
+++ b/os/hal/ports/STM32/LLD/SPIv2/hal_spi_lld.h
@@ -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.
+ */
+ 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 port.
+ * @brief The chip select port mask.
+ */
+ 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 line pad number.
+ * @brief The chip select pad number.
*/
- uint16_t sspad;
+ 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);