[rtems commit] bsp/atsam: Fix handling of slow SPI speeds.

Christian Mauderer christianm at rtems.org
Thu Aug 9 06:38:46 UTC 2018


Module:    rtems
Branch:    master
Commit:    8e6cfccf8c8f4313117a86a36b69532b1bf81545
Changeset: http://git.rtems.org/rtems/commit/?id=8e6cfccf8c8f4313117a86a36b69532b1bf81545

Author:    Christian Mauderer <christian.mauderer at embedded-brains.de>
Date:      Mon Aug  6 10:29:14 2018 +0200

bsp/atsam: Fix handling of slow SPI speeds.

This patch fixes an overflow in the frequency calculation of the SPI
driver for slow SPI speeds.

---

 bsps/arm/atsam/spi/atsam_spi_bus.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/bsps/arm/atsam/spi/atsam_spi_bus.c b/bsps/arm/atsam/spi/atsam_spi_bus.c
index 35f44f5..b40fa56 100644
--- a/bsps/arm/atsam/spi/atsam_spi_bus.c
+++ b/bsps/arm/atsam/spi/atsam_spi_bus.c
@@ -85,6 +85,23 @@ static uint8_t atsam_calculate_dlybcs(uint16_t delay_in_us)
     (BOARD_MCK / delay_in_us) : 0xFF;
 }
 
+static uint32_t atsam_calculate_scbr(uint32_t speed_hz)
+{
+  uint32_t scbr;
+
+  scbr = BOARD_MCK / speed_hz;
+  if (scbr > 0x0FF) {
+    /* Best estimation we can offer with the hardware. */
+    scbr = 0x0FF;
+  }
+  if (scbr == 0) {
+    /* SCBR = 0 isn't allowed. */
+    scbr = 1;
+  }
+
+  return scbr;
+}
+
 static void atsam_set_phase_and_polarity(uint32_t mode, uint32_t *csr)
 {
   uint32_t mode_mask = mode & SPI_MODE_3;
@@ -109,11 +126,13 @@ static void atsam_set_phase_and_polarity(uint32_t mode, uint32_t *csr)
 static void atsam_configure_spi(atsam_spi_bus *bus)
 {
   uint8_t delay_cs;
+  uint32_t scbr;
   uint32_t csr = 0;
   uint32_t mode = 0;
   uint32_t cs = bus->base.cs;
 
   delay_cs = atsam_calculate_dlybcs(bus->base.delay_usecs);
+  scbr = atsam_calculate_scbr(bus->base.speed_hz);
 
   mode |= SPI_MR_DLYBCS(delay_cs);
   mode |= SPI_MR_MSTR;
@@ -137,7 +156,7 @@ static void atsam_configure_spi(atsam_spi_bus *bus)
   csr =
     SPI_DLYBCT(1000, BOARD_MCK) |
     SPI_DLYBS(1000, BOARD_MCK) |
-    SPI_SCBR(bus->base.speed_hz, BOARD_MCK) |
+    SPI_CSR_SCBR(scbr) |
     SPI_CSR_BITS(bus->base.bits_per_word - 8);
 
   atsam_set_phase_and_polarity(bus->base.mode, &csr);



More information about the vc mailing list