SAMV7 SPI: Revise support for Peripheral Chip Select Decoding to address up to 15 slaved

This commit is contained in:
Frank Benkert 2016-02-25 08:13:33 -06:00 committed by Gregory Nutt
parent f1a196cd40
commit 2980985933
3 changed files with 107 additions and 22 deletions

View File

@ -738,6 +738,12 @@ endchoice # SPI1 Configuration
if SAMV7_SPI_MASTER
comment "SPI Master Configuration"
config SAMV7_SPI_CS_DECODING
bool "SPI Peripheral Chip Select Decoding"
default n
---help---
Use Peripheral Chip Select Decoding on SPI Master
config SAMV7_SPI_DMA
bool "SPI DMA"
default n

View File

@ -297,13 +297,24 @@ 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 */
/* This array maps chip select numbers (0-3 or 1-15) to CSR register offsets */
#if defined(CONFIG_SAMV7_SPI_CS_DECODING)
static const uint8_t g_csroffset[16] =
{
0, /* the CS counts from 1 to 15 */
SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR0_OFFSET,
SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET, SAM_SPI_CSR1_OFFSET,
SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR2_OFFSET,
SAM_SPI_CSR3_OFFSET, SAM_SPI_CSR3_OFFSET, SAM_SPI_CSR3_OFFSET
};
#else
static const uint8_t g_csroffset[4] =
{
SAM_SPI_CSR0_OFFSET, SAM_SPI_CSR1_OFFSET,
SAM_SPI_CSR2_OFFSET, SAM_SPI_CSR3_OFFSET
};
#endif
#ifdef CONFIG_SAMV7_SPI0_MASTER
/* SPI0 driver operations */
@ -581,7 +592,11 @@ static inline void spi_flush(struct sam_spidev_s *spi)
* registers. A chip select number is used for indexing and identifying
* chip selects. However, the chip select information is represented by
* a bit set in the SPI registers. This function maps those chip select
* numbers to the correct bit set:
* numbers to the correct bit set.
*
* The SAMx7 Processors can handle the chip selects in two different modes.
* The first and default mode assigns one of the four chip select pins
* to one hardware slave. In this mode the function behaviors like:
*
* CS Returned Spec Effective
* No. PCS Value NPCS
@ -591,17 +606,28 @@ static inline void spi_flush(struct sam_spidev_s *spi)
* 2 0011 x011 1011
* 3 0111 0111 0111
*
* The second mode, activated via CONFIG_SAMV7_SPI_CS_DECODING uses the four
* chip select pins in "encoded mode" which means, that up to 15 slaves can
* be selected via an additional multiplex electronic to decode the values
* represented by the four lines. In that mode this function returns the
* Bitmask the chip select number represents itself.
*
* Input Parameters:
* spics - Device-specific state data
*
* Returned Value:
* None
* Bitmask the pcs part of the SPI data transfer register should be switched
* to for the chip select used.
*
****************************************************************************/
static inline uint32_t spi_cs2pcs(struct sam_spics_s *spics)
{
#ifndef CONFIG_SAMV7_SPI_CS_DECODING
return ((uint32_t)1 << (spics->cs)) - 1;
#else
return spics->cs;
#endif
}
/****************************************************************************
@ -1855,7 +1881,14 @@ FAR struct spi_dev_s *sam_spibus_initialize(int port)
/* Configure the SPI mode register */
#if defined(CONFIG_SAMV7_SPI_CS_DECODING)
/* Enable Peripheral Chip Select Decoding? */
spi_putreg(spi, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PCSDEC,
SAM_SPI_MR_OFFSET);
#else
spi_putreg(spi, SPI_MR_MSTR | SPI_MR_MODFDIS, SAM_SPI_MR_OFFSET);
#endif
/* And enable the SPI */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/samv7/sam_spi.h
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -63,26 +63,72 @@
* sam_spibus_initialize().
*/
#define __SPI_CS_SHIFT (0) /* Bits 0-1: SPI chip select number */
#define __SPI_CS_MASK (3 << __SPI_CS_SHIFT)
# define __SPI_CS0 (0 << __SPI_CS_SHIFT)
# define __SPI_CS1 (1 << __SPI_CS_SHIFT)
# define __SPI_CS2 (2 << __SPI_CS_SHIFT)
# define __SPI_CS3 (3 << __SPI_CS_SHIFT)
#define __SPI_SPI_SHIFT (2) /* Bit 2: SPI controller number */
#define __SPI_SPI_MASK (1 << __SPI_SPI_SHIFT)
# define __SPI_SPI0 (0 << __SPI_SPI_SHIFT) /* SPI0 */
# define __SPI_SPI1 (1 << __SPI_SPI_SHIFT) /* SPI1 */
#ifdef CONFIG_SAMV7_SPI_CS_DECODING
#define SPI0_CS0 (__SPI_SPI0 | __SPI_CS0)
#define SPI0_CS1 (__SPI_SPI0 | __SPI_CS1)
#define SPI0_CS2 (__SPI_SPI0 | __SPI_CS2)
#define SPI0_CS3 (__SPI_SPI0 | __SPI_CS3)
# define __SPI_CS_SHIFT (0) /* Bits 0-3: SPI chip select number */
# define __SPI_CS_MASK (15 << __SPI_CS_SHIFT)
#define SPI1_CS0 (__SPI_SPI1 | __SPI_CS0)
#define SPI1_CS1 (__SPI_SPI1 | __SPI_CS1)
#define SPI1_CS2 (__SPI_SPI1 | __SPI_CS2)
#define SPI1_CS3 (__SPI_SPI1 | __SPI_CS3)
# define __SPI_SPI_SHIFT (4) /* Bit 4: SPI controller number */
# define __SPI_SPI_MASK (1 << __SPI_SPI_SHIFT)
# define __SPI_SPI0 (0 << __SPI_SPI_SHIFT) /* SPI0 */
# define __SPI_SPI1 (1 << __SPI_SPI_SHIFT) /* SPI1 */
# define SPI0_CS1 (__SPI_SPI0 | 1)
# define SPI0_CS2 (__SPI_SPI0 | 2)
# define SPI0_CS3 (__SPI_SPI0 | 3)
# define SPI0_CS4 (__SPI_SPI0 | 4)
# define SPI0_CS5 (__SPI_SPI0 | 5)
# define SPI0_CS6 (__SPI_SPI0 | 6)
# define SPI0_CS7 (__SPI_SPI0 | 7)
# define SPI0_CS8 (__SPI_SPI0 | 8)
# define SPI0_CS9 (__SPI_SPI0 | 9)
# define SPI0_CS10 (__SPI_SPI0 | 10)
# define SPI0_CS11 (__SPI_SPI0 | 11)
# define SPI0_CS12 (__SPI_SPI0 | 12)
# define SPI0_CS13 (__SPI_SPI0 | 13)
# define SPI0_CS14 (__SPI_SPI0 | 14)
# define SPI0_CS15 (__SPI_SPI0 | 15)
# define SPI1_CS1 (__SPI_SPI1 | 1)
# define SPI1_CS2 (__SPI_SPI1 | 2)
# define SPI1_CS3 (__SPI_SPI1 | 3)
# define SPI1_CS4 (__SPI_SPI1 | 4)
# define SPI1_CS5 (__SPI_SPI1 | 5)
# define SPI1_CS6 (__SPI_SPI1 | 6)
# define SPI1_CS7 (__SPI_SPI1 | 7)
# define SPI1_CS8 (__SPI_SPI1 | 8)
# define SPI1_CS9 (__SPI_SPI1 | 9)
# define SPI1_CS10 (__SPI_SPI1 | 10)
# define SPI1_CS11 (__SPI_SPI1 | 11)
# define SPI1_CS12 (__SPI_SPI1 | 12)
# define SPI1_CS13 (__SPI_SPI1 | 13)
# define SPI1_CS14 (__SPI_SPI1 | 14)
# define SPI1_CS15 (__SPI_SPI1 | 15)
#else /* CONFIG_SAMV7_SPI_CS_DECODING */
# define __SPI_CS_SHIFT (0) /* Bits 0-1: SPI chip select number */
# define __SPI_CS_MASK (3 << __SPI_CS_SHIFT)
# define __SPI_CS0 (0 << __SPI_CS_SHIFT)
# define __SPI_CS1 (1 << __SPI_CS_SHIFT)
# define __SPI_CS2 (2 << __SPI_CS_SHIFT)
# define __SPI_CS3 (3 << __SPI_CS_SHIFT)
# define __SPI_SPI_SHIFT (2) /* Bit 2: SPI controller number */
# define __SPI_SPI_MASK (1 << __SPI_SPI_SHIFT)
# define __SPI_SPI0 (0 << __SPI_SPI_SHIFT) /* SPI0 */
# define __SPI_SPI1 (1 << __SPI_SPI_SHIFT) /* SPI1 */
# define SPI0_CS0 (__SPI_SPI0 | __SPI_CS0)
# define SPI0_CS1 (__SPI_SPI0 | __SPI_CS1)
# define SPI0_CS2 (__SPI_SPI0 | __SPI_CS2)
# define SPI0_CS3 (__SPI_SPI0 | __SPI_CS3)
# define SPI1_CS0 (__SPI_SPI1 | __SPI_CS0)
# define SPI1_CS1 (__SPI_SPI1 | __SPI_CS1)
# define SPI1_CS2 (__SPI_SPI1 | __SPI_CS2)
# define SPI1_CS3 (__SPI_SPI1 | __SPI_CS3)
#endif /* CONFIG_SAMV7_SPI_CS_DECODING */
/****************************************************************************
* Public Types