Enable using PCS of Kinetis' PUSHR register to select the periphery for
the SPI communication. There are two things we need to do for that:
1. When writing PUSHR register, write both -- command information (upper
16 bit) and data (lower 16 bit) at once.
2. We need a way to set the `pcs` member (used when writing to PUSHR
register) of the private `kinetis_spidev_s` structure from the
board specific `kinetis_spi[n]select` procedure.
---
arch/arm/src/kinetis/kinetis_spi.c | 51 +++++++++++++++++++++++++++++-
arch/arm/src/kinetis/kinetis_spi.h | 30 ++++++++++++++++++
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/arch/arm/src/kinetis/kinetis_spi.c
b/arch/arm/src/kinetis/kinetis_spi.c
index f74a24325a..c757189746 100644
--- a/arch/arm/src/kinetis/kinetis_spi.c
+++ b/arch/arm/src/kinetis/kinetis_spi.c
@@ -104,6 +104,7 @@ struct kinetis_spidev_s
uint8_t nbits; /* Width of word in bits (8 to 16) */
uint8_t mode; /* Mode 0,1,2,3 */
uint8_t ctarsel; /* Which CTAR */
+ int8_t pcs; /* Which PCS (0-5) to use or -1. */
#ifdef CONFIG_KINETIS_SPI_DMA
volatile uint32_t rxresult; /* Result of the RX DMA */
volatile uint32_t txresult; /* Result of the TX DMA */
@@ -233,6 +234,7 @@ static struct kinetis_spidev_s g_spi0dev =
.spibase = KINETIS_SPI0_BASE,
.lock = NXMUTEX_INITIALIZER,
.ctarsel = KINETIS_SPI_CTAR0_OFFSET,
+ .pcs = -1,
#ifdef CONFIG_KINETIS_SPI_DMA
# ifdef CONFIG_KINETIS_SPI0_DMA
.rxch = KINETIS_DMA_REQUEST_SRC_SPI0_RX,
@@ -288,6 +290,7 @@ static struct kinetis_spidev_s g_spi1dev =
.spibase = KINETIS_SPI1_BASE,
.lock = NXMUTEX_INITIALIZER,
.ctarsel = KINETIS_SPI_CTAR0_OFFSET,
+ .pcs = -1,
#ifdef CONFIG_KINETIS_SPI_DMA
# ifdef CONFIG_KINETIS_SPI1_DMA
.rxch = KINETIS_DMA_REQUEST_SRC_SPI1_RX,
@@ -343,6 +346,7 @@ static struct kinetis_spidev_s g_spi2dev =
.spibase = KINETIS_SPI2_BASE,
.lock = NXMUTEX_INITIALIZER,
.ctarsel = KINETIS_SPI_CTAR0_OFFSET,
+ .pcs = -1,
#ifdef CONFIG_KINETIS_SPI_DMA
# ifdef CONFIG_KINETIS_SPI2_DMA
.rxch = KINETIS_DMA_REQUEST_SRC_FTM3_CH6__SPI2_RX,
@@ -1116,7 +1120,15 @@ static uint16_t spi_send_data(struct kinetis_spidev_s
*priv, uint16_t wd,
/* Write the data to transmitted to the SPI Data Register */
- spi_putreg16(priv, KINETIS_SPI_PUSHR_OFFSET, SPI_PUSHR_TXDATA(wd));
+ if (0 <= priv->pcs)
+ {
+ spi_putreg(priv, KINETIS_SPI_PUSHR_OFFSET,
+ SPI_PUSHR_PCS(priv->pcs) | SPI_PUSHR_TXDATA(wd));
+ }
+ else
+ {
+ spi_putreg16(priv, KINETIS_SPI_PUSHR_OFFSET, SPI_PUSHR_TXDATA(wd));
+ }
/* Wait until transfer completes and the data is in the RX FIFO */
@@ -1822,4 +1834,41 @@ struct spi_dev_s *kinetis_spibus_initialize(int port)
return &priv->spidev;
}
+/****************************************************************************
+ * Name: kinetis_spisetpcs
+ *
+ * Description:
+ * Set which Periphery Chip Select (PCS, 0-5) to use for the given SPI dev.
+ *
+ * Rationale:
+ * We can use PCS field of the Kinetis' PUSHR register to select periphery
+ * chips, provided that the relevant PIN is set with the appropriate ALT
+ * configuration.
+ *
+ * However, both, command information and data, must be write to the PUSHR
+ * at once. Therefore, kinetis_spidev_s contains pcs member that store
+ * information about which PCS to use. But kinetis_spidev_s is private and
+ * so we need some public way to set pcs.
+ *
+ * kinetis_spisetpcs is to be used from within the kinetis_spi[n]select
+ * procedures when Kinetis' PCS are to be used.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * which - Which Periphery Chip Select (PCS, 0-5) to use or -1.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void kinetis_spisetpcs(struct spi_dev_s *dev, int8_t which)
+{
+ struct kinetis_spidev_s *priv = (struct kinetis_spidev_s *)dev;
+
+ DEBUGASSERT(which <= 5);
+
+ priv->pcs = which;
+}
+
#endif /* CONFIG_KINETIS_SPI0 || CONFIG_KINETIS_SPI1 || CONFIG_KINETIS_SPI2 */
diff --git a/arch/arm/src/kinetis/kinetis_spi.h
b/arch/arm/src/kinetis/kinetis_spi.h
index 972d35b1c6..c21bd3641d 100644
--- a/arch/arm/src/kinetis/kinetis_spi.h
+++ b/arch/arm/src/kinetis/kinetis_spi.h
@@ -72,6 +72,36 @@ struct spi_dev_s;
struct spi_dev_s *kinetis_spibus_initialize(int bus);
+/****************************************************************************
+ * Name: kinetis_spisetpcs
+ *
+ * Description:
+ * Set which Periphery Chip Select (PCS, 0-5) to use for the given SPI dev.
+ *
+ * Rationale:
+ * We can use PCS field of the Kinetis' PUSHR register to select periphery
+ * chips, provided that the relevant PIN is set with the appropriate ALT
+ * configuration.
+ *
+ * However, both, command information and data, must be write to the PUSHR
+ * at once. Therefore, kinetis_spidev_s contains pcs member that store
+ * information about which PCS to use. But kinetis_spidev_s is private and
+ * so we need some public way to set pcs.
+ *
+ * kinetis_spisetpcs is to be used from within the kinetis_spi[n]select
+ * procedures when Kinetis' PCS are to be used.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * which - Which Periphery Chip Select (PCS, 0-5) to use or -1.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void kinetis_spisetpcs(struct spi_dev_s *dev, int8_t which);
+
/****************************************************************************
* Name:
* kinetis_spi[n]select, kinetis_spi[n]status, and kinetis_spi[n]cmddata
--
2.47.3