[PATCH 2/5] bsp/atsam: Allow to use a decoder for SPI CS.

Christian Mauderer christian.mauderer at embedded-brains.de
Mon Feb 12 13:39:37 UTC 2018


The SPI controller supports a decoder connected to the chip select
lines. This patch allows to use this mode.
---
 bsps/arm/atsam/include/bsp/atsam-spi.h          | 13 +++++---
 c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c  | 41 ++++++++++++++++---------
 c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c | 26 +++++++++++-----
 3 files changed, 54 insertions(+), 26 deletions(-)

diff --git a/bsps/arm/atsam/include/bsp/atsam-spi.h b/bsps/arm/atsam/include/bsp/atsam-spi.h
index 548dd544f4..4bfa6c3a1e 100644
--- a/bsps/arm/atsam/include/bsp/atsam-spi.h
+++ b/bsps/arm/atsam/include/bsp/atsam-spi.h
@@ -21,12 +21,17 @@
 extern "C" {
 #endif /* __cplusplus */
 
+typedef struct {
+  uint8_t     spi_peripheral_id;
+  const Pin  *pins;
+  Spi        *spi_regs;
+  size_t      pin_count;
+  bool        chip_select_decode;
+} atsam_spi_config;
+
 int spi_bus_register_atsam(
   const char *bus_path,
-  uint8_t     spi_peripheral_id,
-  Spi        *spi_regs,
-  const Pin  *pins,
-  size_t      pin_count
+  const atsam_spi_config *config
 );
 
 #ifdef __cplusplus
diff --git a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c
index 5c6cdc2af7..24850c8327 100644
--- a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c
+++ b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c
@@ -49,6 +49,7 @@ typedef struct {
   uint32_t dma_rx_channel;
   int transfer_in_progress;
   bool chip_select_active;
+  bool chip_select_decode;
 } atsam_spi_bus;
 
 static void atsam_spi_wakeup_task(atsam_spi_bus *bus)
@@ -91,17 +92,27 @@ static void atsam_configure_spi(atsam_spi_bus *bus)
 {
   uint8_t delay_cs;
   uint32_t csr = 0;
+  uint32_t mode = 0;
+  uint32_t cs = bus->base.cs;
 
   delay_cs = atsam_calculate_dlybcs(bus->base.delay_usecs);
 
+  mode |= SPI_MR_DLYBCS(delay_cs);
+  mode |= SPI_MR_MSTR;
+  mode |= SPI_MR_MODFDIS;
+  if (bus->chip_select_decode) {
+    mode |= SPI_MR_PCS(bus->base.cs);
+    mode |= SPI_MR_PCSDEC;
+    cs /= 4;
+  } else {
+    mode |= SPI_PCS(bus->base.cs);
+  }
+
   SPID_Configure(
     &bus->spi,
     bus->spi.pSpiHw,
     bus->spi.spiId,
-    (SPI_MR_DLYBCS(delay_cs) |
-      SPI_MR_MSTR |
-      SPI_MR_MODFDIS |
-      SPI_PCS(bus->base.cs)),
+    mode,
     &XDMAD_Instance
   );
 
@@ -113,7 +124,7 @@ static void atsam_configure_spi(atsam_spi_bus *bus)
 
   atsam_set_phase_and_polarity(bus->base.mode, &csr);
 
-  SPI_ConfigureNPCS(bus->spi.pSpiHw, bus->base.cs, csr);
+  SPI_ConfigureNPCS(bus->spi.pSpiHw, cs, csr);
 }
 
 static void atsam_spi_start_dma_transfer(
@@ -141,7 +152,11 @@ static void atsam_spi_do_transfer(
 
     bus->chip_select_active = true;
 
-    SPI_ChipSelect(pSpiHw, 1 << msg->cs);
+    if (bus->chip_select_decode) {
+      pSpiHw->SPI_MR = (pSpiHw->SPI_MR & ~SPI_MR_PCS_Msk) | SPI_MR_PCS(msg->cs);
+    } else {
+      SPI_ChipSelect(pSpiHw, 1 << msg->cs);
+    }
     SPI_Enable(pSpiHw);
   }
 
@@ -389,10 +404,7 @@ static void atsam_spi_init_xdma(atsam_spi_bus *bus)
 
 int spi_bus_register_atsam(
   const char *bus_path,
-  uint8_t     spi_peripheral_id,
-  Spi        *spi_regs,
-  const Pin  *pins,
-  size_t      pin_count
+  const atsam_spi_config *config
 )
 {
   atsam_spi_bus *bus;
@@ -410,11 +422,12 @@ int spi_bus_register_atsam(
   bus->base.speed_hz = bus->base.max_speed_hz;
   bus->base.delay_usecs = 1;
   bus->base.cs = 1;
-  bus->spi.spiId = spi_peripheral_id;
-  bus->spi.pSpiHw = spi_regs;
+  bus->spi.spiId = config->spi_peripheral_id;
+  bus->spi.pSpiHw = config->spi_regs;
+  bus->chip_select_decode = config->chip_select_decode;
 
-  PIO_Configure(pins, pin_count);
-  PMC_EnablePeripheral(spi_peripheral_id);
+  PIO_Configure(config->pins, config->pin_count);
+  PMC_EnablePeripheral(config->spi_peripheral_id);
   atsam_configure_spi(bus);
   atsam_spi_init_xdma(bus);
 
diff --git a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c
index 09440f263f..ca18f8ec35 100644
--- a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c
+++ b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_init.c
@@ -66,12 +66,17 @@ int atsam_register_spi_0(void)
     PIN_SPI0_CLOCK
   };
 
+  static const atsam_spi_config config = {
+    .spi_peripheral_id = ID_SPI0,
+    .spi_regs = SPI0,
+    .pins = pins,
+    .pin_count = RTEMS_ARRAY_SIZE(pins),
+    .chip_select_decode = false
+  };
+
   return spi_bus_register_atsam(
     ATSAM_SPI_0_BUS_PATH,
-    ID_SPI0,
-    SPI0,
-    pins,
-    RTEMS_ARRAY_SIZE(pins)
+    &config
   );
 }
 
@@ -90,11 +95,16 @@ int atsam_register_spi_1(void)
     PIN_SPI1_CLOCK
   };
 
+  static const atsam_spi_config config = {
+    .spi_peripheral_id = ID_SPI1,
+    .spi_regs = SPI1,
+    .pins = pins,
+    .pin_count = RTEMS_ARRAY_SIZE(pins),
+    .chip_select_decode = false
+  };
+
   return spi_bus_register_atsam(
     ATSAM_SPI_1_BUS_PATH,
-    ID_SPI1,
-    SPI1,
-    pins,
-    RTEMS_ARRAY_SIZE(pins)
+    &config
   );
 }
-- 
2.13.6



More information about the devel mailing list