summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nuttx/ChangeLog10
-rw-r--r--nuttx/arch/arm/src/sam34/sam_spi.c20
-rw-r--r--nuttx/arch/arm/src/sama5/sam_spi.c97
-rw-r--r--nuttx/configs/sama5d3x-ek/README.txt17
4 files changed, 100 insertions, 44 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 339e9d8a8..7548bb0ef 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5284,10 +5284,16 @@
and have several limitations: No DMA, no SPI1 support (2013-8-4).
* arch/arm/src/sama5/sam_spi.c and sam_spi.h: Now supports SPI1
and a register access debug option (2013-8-4).
- * configs/sama5d3x-ek/src/sam_spi.c: At board support for the
+ * configs/sama5d3x-ek/src/sam_spi.c: Add board support for the
AT25 serial flash (2013-8-4).
* configs/sama5d3x-ek/nsh/defconfig: FAT file system support is
now enabled by default (2013-8-5)
* confgis/sama5d3x-ek/src/sam_nsh.c: Automatically mount AT25
file system for NSH if so configured (2013-8-5).
-
+ * confgis/sama5d3x-ek/src/sam_nsh.c: Verified that the AT25 FLASH
+ works on the SAMA5D3x-EK boards and can support a FAT file system
+ (2013-8-5).
+ * arch/arm/src/sam34/sam_spi.c: Corrected an error in the SAM3/4
+ SPI driver while testing the SAMA5 SPI driver: If CONFIG_SPI_OWNBUS
+ is not set, the driver will not configure the SPI mode correctly
+ (2013-8-5).
diff --git a/nuttx/arch/arm/src/sam34/sam_spi.c b/nuttx/arch/arm/src/sam34/sam_spi.c
index d7366d98c..278eb55d2 100644
--- a/nuttx/arch/arm/src/sam34/sam_spi.c
+++ b/nuttx/arch/arm/src/sam34/sam_spi.c
@@ -896,6 +896,10 @@ FAR struct spi_dev_s *up_spiinitialize(int cs)
{
FAR struct sam_spidev_s *priv;
irqstate_t flags;
+#ifndef CONFIG_SPI_OWNBUS
+ uint32_t regaddr;
+ uint32_t regval;
+#endif
/* The support SAM parts have only a single SPI port */
@@ -985,6 +989,22 @@ FAR struct spi_dev_s *up_spiinitialize(int cs)
spi_dumpregs("After initialization");
}
+#ifndef CONFIG_SPI_OWNBUS
+ /* Set to mode=0 and nbits=8 and impossible frequency. It is only
+ * critical to do this if CONFIG_SPI_OWNBUS is not defined because in
+ * that case, the SPI will only be reconfigured if there is a change.
+ */
+
+ regaddr = g_csraddr[cs];
+ regval = getreg32(regaddr);
+ regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA | SPI_CSR_BITS_MASK);
+ regval |= (SPI_CSR_NCPHA | SPI_CSR_BITS(8));
+ putreg32(regval, regaddr);
+
+ priv->nbits = 8;
+ spivdbg("csr[%08x]=%08x\n", regaddr, regval);
+#endif
+
return &priv->spidev;
}
#endif /* CONFIG_SAM34_SPI0 */
diff --git a/nuttx/arch/arm/src/sama5/sam_spi.c b/nuttx/arch/arm/src/sama5/sam_spi.c
index fc12031ea..3199680b5 100644
--- a/nuttx/arch/arm/src/sama5/sam_spi.c
+++ b/nuttx/arch/arm/src/sama5/sam_spi.c
@@ -128,6 +128,8 @@ struct sam_spics_s
typedef void (*select_t)(enum spi_dev_e devid, bool selected);
+/* Chip select register offsetrs */
+
/* The overall state of one SPI controller */
struct sam_spidev_s
@@ -135,7 +137,6 @@ struct sam_spidev_s
uint32_t base; /* SPI controller register base address */
sem_t spisem; /* Assures mutually exclusive acess to SPI */
bool initialized; /* TRUE: Controller has been initialized */
- const uint32_t *csraddr; /* Addresses of CSR register */
select_t select; /* SPI select callout */
/* Debug stuff */
@@ -200,6 +201,14 @@ static void spi_recvblock(struct spi_dev_s *dev, void *buffer,
* Private Data
****************************************************************************/
+/* This array maps chip select numbers (0-3) to CSR register offsets */
+
+static const uint8_t g_csroffset[4] =
+{
+ SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR1_OFFSET,
+ SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR3_OFFSET
+};
+
#ifdef CONFIG_SAMA5_SPI0
/* SPI0 driver operations */
@@ -226,19 +235,11 @@ static const struct spi_ops_s g_spi0ops =
.registercallback = 0, /* Not implemented */
};
-/* This array maps chip select numbers (0-3) to CSR register addresses */
-
-static const uint32_t g_csraddr0[4] =
-{
- SAM_SPI0_CSR0, SAM_SPI0_CSR1, SAM_SPI0_CSR2, SAM_SPI0_CSR3
-};
-
/* This is the overall state of the SPI0 controller */
static struct sam_spidev_s g_spi0dev =
{
.base = SAM_SPI0_VBASE,
- .csraddr = g_csraddr0,
.select = sam_spi0select,
};
#endif
@@ -269,19 +270,11 @@ static const struct spi_ops_s g_spi1ops =
.registercallback = 0, /* Not implemented */
};
-/* This array maps chip select numbers (0-3) to CSR register addresses */
-
-static const uint32_t g_csraddr1[4] =
-{
- SAM_SPI1_CSR0, SAM_SPI1_CSR1, SAM_SPI1_CSR2, SAM_SPI1_CSR3
-};
-
/* This is the overall state of the SPI0 controller */
static struct sam_spidev_s g_spi1dev =
{
.base = SAM_SPI1_VBASE,
- .csraddr = g_csraddr1,
.select = sam_spi1select,
};
#endif
@@ -392,7 +385,7 @@ static inline void spi_putreg(struct sam_spidev_s *spi, uint32_t value,
}
#endif
- spi_putreg(spi, value, address);
+ putreg32(value, address);
}
/****************************************************************************
@@ -415,17 +408,17 @@ static void spi_dumpregs(struct sam_spidev_s *spi, const char *msg)
{
spivdbg("%s:\n", msg);
spivdbg(" MR:%08x SR:%08x IMR:%08x\n",
- spi_getreg(spi, SAM_SPI_MR_OFFSET),
- spi_getreg(spi, SAM_SPI_SR_OFFSET),
- spi_getreg(spi, SAM_SPI_IMR_OFFSET));
+ getreg32(spi->base + SAM_SPI_MR_OFFSET),
+ getreg32(spi->base + SAM_SPI_SR_OFFSET),
+ getreg32(spi->base + SAM_SPI_IMR_OFFSET));
spivdbg(" CSR0:%08x CSR1:%08x CSR2:%08x CSR3:%08x\n",
- spi_getreg(spi, SAM_SPI_CSR0_OFFSET),
- spi_getreg(spi, SAM_SPI_CSR1_OFFSET),
- spi_getreg(spi, SAM_SPI_CSR2_OFFSET),
- spi_getreg(spi, SAM_SPI_CSR3_OFFSET));
+ getreg32(spi->base + SAM_SPI_CSR0_OFFSET),
+ getreg32(spi->base + SAM_SPI_CSR1_OFFSET),
+ getreg32(spi->base + SAM_SPI_CSR2_OFFSET),
+ getreg32(spi->base + SAM_SPI_CSR3_OFFSET));
spivdbg(" WPCR:%08x WPSR:%08x\n",
- spi_getreg(spi, SAM_SPI_WPCR_OFFSET),
- spi_getreg(spi, SAM_SPI_WPSR_OFFSET));
+ getreg32(spi->base + SAM_SPI_WPCR_OFFSET),
+ getreg32(spi->base + SAM_SPI_WPSR_OFFSET));
}
#endif
@@ -642,7 +635,7 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
uint32_t dlybs;
uint32_t dlybct;
uint32_t regval;
- uint32_t regaddr;
+ unsigned int offset;
spivdbg("cs=%d frequency=%d\n", spics->cs, frequency);
@@ -677,8 +670,8 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
/* Save the new scbr value */
- regaddr = spi->csraddr[spics->cs];
- regval = getreg32(regaddr);
+ offset = (unsigned int)g_csroffset[spics->cs];
+ regval = spi_getreg(spi, offset);
regval &= ~(SPI_CSR_SCBR_MASK | SPI_CSR_DLYBS_MASK | SPI_CSR_DLYBCT_MASK);
regval |= scbr << SPI_CSR_SCBR_SHIFT;
@@ -711,12 +704,12 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev, uint32_t frequency)
dlybct = SAM_SPI_CLOCK / 200000 / 32;
regval |= dlybct << SPI_CSR_DLYBCT_SHIFT;
- putreg32(regval, regaddr);
+ spi_putreg(spi, regval, offset);
/* Calculate the new actual frequency */
actual = SAM_SPI_CLOCK / scbr;
- spivdbg("csr[%08x]=%08x actual=%d\n", regaddr, regval, actual);
+ spivdbg("csr[offset=%02x]=%08x actual=%d\n", offset, regval, actual);
/* Save the frequency setting */
@@ -749,7 +742,7 @@ static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode)
struct sam_spics_s *spics = (struct sam_spics_s *)dev;
struct sam_spidev_s *spi = spi_device(spics);
uint32_t regval;
- uint32_t regaddr;
+ unsigned int offset;
spivdbg("cs=%d mode=%d\n", spics->cs, mode);
@@ -769,8 +762,8 @@ static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode)
* 3 1 0
*/
- regaddr = spi->csraddr[spics->cs];
- regval = getreg32(regaddr);
+ offset = (unsigned int)g_csroffset[spics->cs];
+ regval = spi_getreg(spi, offset);
regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA);
switch (mode)
@@ -795,8 +788,8 @@ static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode)
return;
}
- putreg32(regval, regaddr);
- spivdbg("csr[%08x]=%08x\n", regaddr, regval);
+ spi_putreg(spi, regval, offset);
+ spivdbg("csr[offset=%02x]=%08x\n", offset, regval);
/* Save the mode so that subsequent re-configurations will be faster */
@@ -825,8 +818,8 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
{
struct sam_spics_s *spics = (struct sam_spics_s *)dev;
struct sam_spidev_s *spi = spi_device(spics);
- uint32_t regaddr;
uint32_t regval;
+ unsigned int offset;
spivdbg("cs=%d nbits=%d\n", spics->cs, nbits);
DEBUGASSERT(spics && nbits > 7 && nbits < 17);
@@ -846,13 +839,13 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
#endif
/* Yes... Set number of bits appropriately */
- regaddr = spi->csraddr[spics->cs];
- regval = getreg32(regaddr);
+ offset = (unsigned int)g_csroffset[spics->cs];
+ regval = spi_getreg(spi, offset);
regval &= ~SPI_CSR_BITS_MASK;
regval |= SPI_CSR_BITS(nbits);
- putreg32(regval, regaddr);
+ spi_putreg(spi, regval, offset);
- spivdbg("csr[%08x]=%08x\n", regaddr, regval);
+ spivdbg("csr[offset=%02x]=%08x\n", offset, regval);
/* Save the selection so the subsequence re-configurations will be faster */
@@ -1105,6 +1098,10 @@ struct spi_dev_s *up_spiinitialize(int port)
int csno = (port & __SPI_CS_MASK) >> __SPI_CS_SHIFT;
int spino = (port & __SPI_SPI_MASK) >> __SPI_SPI_SHIFT;
irqstate_t flags;
+#ifndef CONFIG_SPI_OWNBUS
+ uint32_t regval;
+ unsigned int offset;
+#endif
/* The support SAM parts have only a single SPI port */
@@ -1231,6 +1228,22 @@ struct spi_dev_s *up_spiinitialize(int port)
spi_dumpregs(spi, "After initialization");
}
+#ifndef CONFIG_SPI_OWNBUS
+ /* Set to mode=0 and nbits=8 and impossible frequency. It is only
+ * critical to do this if CONFIG_SPI_OWNBUS is not defined because in
+ * that case, the SPI will only be reconfigured if there is a change.
+ */
+
+ offset = (unsigned int)g_csroffset[csno];
+ regval = spi_getreg(spi, offset);
+ regval &= ~(SPI_CSR_CPOL | SPI_CSR_NCPHA | SPI_CSR_BITS_MASK);
+ regval |= (SPI_CSR_NCPHA | SPI_CSR_BITS(8));
+ spi_putreg(spi, regval, offset);
+
+ spics->nbits = 8;
+ spivdbg("csr[offset=%02x]=%08x\n", offset, regval);
+#endif
+
return &spics->spidev;
}
#endif /* CONFIG_SAMA5_SPI0 || CONFIG_SAMA5_SPI1 */
diff --git a/nuttx/configs/sama5d3x-ek/README.txt b/nuttx/configs/sama5d3x-ek/README.txt
index 38600f0c2..52b505a94 100644
--- a/nuttx/configs/sama5d3x-ek/README.txt
+++ b/nuttx/configs/sama5d3x-ek/README.txt
@@ -953,6 +953,21 @@ Configurations
NOTE that you must close JP1 on the Embest/Ronetix board in
order to enable the AT25 FLASH chip select.
+ You can then format the AT25 FLASH for a FAT file system and mount
+ the file system at /mnt/sdcard using these NSH commands:
+
+ nsh> mkfatfs /dev/mtdblock0
+ nsh> mount -t vfat /dev/mtdblock0 /mnt/sdcard
+
+ Then you an use the FLASH as a normal FAT file system:
+
+ nsh> echo "This is a test" >/mnt/sdcard/atest.txt
+ nsh> ls -l /mnt/sdcard
+ /mnt/sdcard:
+ -rw-rw-rw- 16 atest.txt
+ nsh> cat /mnt/sdcard/atest.txt
+ This is a test
+
STATUS:
2013-7-19: This configuration (as do the others) run at 396MHz.
The SAMA5D3 can run at 536MHz. I still need to figure out the
@@ -982,6 +997,8 @@ Configurations
generate occasional spurious interrupts in those same conditions
where the memory test fails! No idea why.
+ 2013-8-5: The AT25 configuration has been verified to be functional.
+
ostest:
This configuration directory, performs a simple OS test using
examples/ostest.