diff options
-rw-r--r-- | nuttx/ChangeLog | 10 | ||||
-rw-r--r-- | nuttx/arch/arm/src/sam34/sam_spi.c | 20 | ||||
-rw-r--r-- | nuttx/arch/arm/src/sama5/sam_spi.c | 97 | ||||
-rw-r--r-- | nuttx/configs/sama5d3x-ek/README.txt | 17 |
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. |