arch/mips/src/pic32mz/pic32mz-spi.c: Fix SPI Mode selection. CKE is the inversion of the CPHA.

This commit is contained in:
Ouss4 2019-07-21 15:57:06 -06:00 committed by Gregory Nutt
parent 1812d6f515
commit 145970a266
2 changed files with 107 additions and 82 deletions

View File

@ -77,10 +77,10 @@
#define PIC32MZ_SPI_BRGSET_OFFSET 0x0038 /* SPI baud rate set register */
#define PIC32MZ_SPI_BRGINV_OFFSET 0x003c /* SPI baud rate invert register */
#define PIC32MZ_SPI_CON2_OFFSET 0x0040 /* SPI control register 2*/
#define PIC32MZ_SPI_CON2CLR_OFFSET 0x0040 /* SPI control register 2*/
#define PIC32MZ_SPI_CON2SET_OFFSET 0x0040 /* SPI control register 2*/
#define PIC32MZ_SPI_CON2INV_OFFSET 0x0040 /* SPI control register 2*/
#define PIC32MZ_SPI_CON2_OFFSET 0x0040 /* SPI control register 2 */
#define PIC32MZ_SPI_CON2CLR_OFFSET 0x0044 /* SPI control clear register 2 */
#define PIC32MZ_SPI_CON2SET_OFFSET 0x0048 /* SPI control set register 2 */
#define PIC32MZ_SPI_CON2INV_OFFSET 0x004c /* SPI control invert register 2 */
/* SPI Peripheral Addresses *************************************************/

View File

@ -63,6 +63,7 @@
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* All SPI peripherals are clocked by PBCLK2 */
#define BOARD_PBCLOCK BOARD_PBCLK2
@ -70,6 +71,7 @@
/****************************************************************************
* Private Types
****************************************************************************/
/* This structure describes the fixed (ROM-able) configuration of the SPI
* peripheral.
*/
@ -110,6 +112,7 @@ struct pic32mz_dev_s
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* Low-level register access */
#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG
@ -137,7 +140,8 @@ static void spi_exchange8(FAR struct pic32mz_dev_s *priv,
/* SPI methods */
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency);
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
uint32_t frequency);
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode);
static void spi_setbits(FAR struct spi_dev_s *dev, int nbits);
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t ch);
@ -195,13 +199,16 @@ static const struct pic32mz_config_s g_spi1config =
#endif
.sdipps = BOARD_SDI1_PPS,
.sdopps = PPS_OUTPUT_REGVAL(BOARD_SDO1_PPS),
.sdoreg = PPS_OUTPUT_REGADDR(BOARD_SDO1_PPS),
.sdoreg = PPS_OUTPUT_REGADDR(BOARD_SDO1_PPS)
};
static struct pic32mz_dev_s g_spi1dev =
{
.spidev = { &g_spi1ops },
.config = &g_spi1config,
.spidev =
{
&g_spi1ops
},
.config = &g_spi1config
};
#endif
@ -246,7 +253,10 @@ static const struct pic32mz_config_s g_spi2config =
static struct pic32mz_dev_s g_spi2dev =
{
.spidev = { &g_spi2ops },
.spidev =
{
&g_spi2ops
},
.config = &g_spi2config,
};
#endif
@ -292,7 +302,10 @@ static const struct pic32mz_config_s g_spi3config =
static struct pic32mz_dev_s g_spi3dev =
{
.spidev = { &g_spi3ops },
.spidev =
{
&g_spi3ops
},
.config = &g_spi3config,
};
#endif
@ -338,7 +351,10 @@ static const struct pic32mz_config_s g_spi4config =
static struct pic32mz_dev_s g_spi4dev =
{
.spidev = { &g_spi4ops },
.spidev =
{
&g_spi4ops
},
.config = &g_spi4config,
};
#endif
@ -384,7 +400,10 @@ static const struct pic32mz_config_s g_spi5config =
static struct pic32mz_dev_s g_spi5dev =
{
.spidev = { &g_spi5ops },
.spidev =
{
&g_spi5ops
},
.config = &g_spi5config,
};
#endif
@ -430,7 +449,10 @@ static const struct pic32mz_config_s g_spi6config =
static struct pic32mz_dev_s g_spi6dev =
{
.spidev = { &g_spi6ops },
.spidev =
{
&g_spi6ops
},
.config = &g_spi6config,
};
#endif
@ -482,7 +504,7 @@ static bool spi_checkreg(struct pic32mz_dev_s *priv, uintptr_t regaddr,
{
/* Yes... show how many times we did it */
_info("...[Repeats %d times]...\n", priv->ntimes);
spiinfo("...[Repeats %d times]...\n", priv->ntimes);
}
/* Save information about the new access */
@ -532,7 +554,7 @@ static uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv,
{
/* Yes.. */
_info("%08lx->%08lx\n",
spiinfo("%08lx->%08lx\n",
(unsigned long)regaddr, (unsigned long)regval);
}
@ -574,7 +596,7 @@ static void spi_putaddr(FAR struct pic32mz_dev_s *priv, uintptr_t regaddr,
{
/* Yes.. */
_info("%08lx<-%08lx\n",
spiinfo("%08lx<-%08lx\n",
(unsigned long)regaddr, (unsigned long)regval);
}
@ -641,7 +663,7 @@ static void spi_exchange8(FAR struct pic32mz_dev_s *priv,
spiinfo("nbytes: %d\n", nbytes);
while (nbytes)
{
/* Write the data to transmitted to the SPI Data Register */
/* Write the data to be transmitted to the SPI Data Register */
if (txbuffer)
{
@ -663,7 +685,8 @@ static void spi_exchange8(FAR struct pic32mz_dev_s *priv,
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
#else
/* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
* normal mode, the SPIRBF bit will be set when receive data is available.
* normal mode, the SPIRBF bit will be set when receive data is
* available.
*/
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBF) == 0);
@ -822,7 +845,8 @@ static int spi_lock(FAR struct spi_dev_s *dev, bool lock)
*
****************************************************************************/
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev,
uint32_t frequency)
{
FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev;
uint32_t divisor;
@ -901,7 +925,6 @@ static uint32_t spi_setfrequency(FAR struct spi_dev_s *dev, uint32_t frequency)
static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
{
FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev;
uint32_t regval;
spiinfo("Old mode: %d New mode: %d\n", priv->mode, mode);
@ -928,7 +951,7 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
*
* CON Register mapping:
* CPOL=0 corresponds to CON:CKP=0; CPOL=1 corresponds to CON:CKP=1
* CPHA=0 corresponds to CON:CKE=1; CPHA=1 corresponds to CON:CKE=1
* CPHA=0 corresponds to CON:CKE=1; CPHA=1 corresponds to CON:CKE=0
*
* In addition, the CON register supports SMP: SPI Data Input Sample
* Phase bit:
@ -939,24 +962,26 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
* Which is hardcoded to 1.
*/
regval = spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET);
regval &= ~(SPI_CON_CKP | SPI_CON_CKE);
switch (mode)
{
case SPIDEV_MODE0: /* CPOL=0; CPHA=0 */
case SPIDEV_MODE0: /* CPOL=0; CPHA=0 => CKP=0; CKE=1 */
spi_putreg(priv, PIC32MZ_SPI_CONCLR_OFFSET, SPI_CON_CKP);
spi_putreg(priv, PIC32MZ_SPI_CONSET_OFFSET, SPI_CON_CKE);
break;
case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */
regval |= SPI_CON_CKE;
case SPIDEV_MODE1: /* CPOL=0; CPHA=1 => CKP=0; CKE=0 */
spi_putreg(priv, PIC32MZ_SPI_CONCLR_OFFSET, SPI_CON_CKP);
spi_putreg(priv, PIC32MZ_SPI_CONCLR_OFFSET, SPI_CON_CKE);
break;
case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */
regval |= SPI_CON_CKP;
case SPIDEV_MODE2: /* CPOL=1; CPHA=0 => CKP=1; CKE=1 */
spi_putreg(priv, PIC32MZ_SPI_CONSET_OFFSET, SPI_CON_CKP);
spi_putreg(priv, PIC32MZ_SPI_CONSET_OFFSET, SPI_CON_CKE);
break;
case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */
regval |= (SPI_CON_CKP | SPI_CON_CKE);
case SPIDEV_MODE3: /* CPOL=1; CPHA=1 => CKP=1; CKE=0 */
spi_putreg(priv, PIC32MZ_SPI_CONSET_OFFSET, SPI_CON_CKP);
spi_putreg(priv, PIC32MZ_SPI_CONCLR_OFFSET, SPI_CON_CKE);
break;
default:
@ -964,10 +989,9 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
return;
}
spi_putreg(priv, PIC32MZ_SPI_CON_OFFSET, regval);
spiinfo("CON: %08x\n", regval);
spiinfo("CON: %08x\n", spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET));
/* Save the mode so that subsequent re-configuratins will be faster */
/* Save the mode so that subsequent re-configurations will be faster */
priv->mode = mode;
}
@ -1009,11 +1033,11 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
}
else if (nbits == 16)
{
setting = SPI_CON_MODE_8BIT;
setting = SPI_CON_MODE_16BIT;
}
else if (nbits == 32)
{
setting = SPI_CON_MODE_8BIT;
setting = SPI_CON_MODE_32BIT;
}
else
{
@ -1024,7 +1048,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
regval = spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET);
regval &= ~SPI_CON_MODE_MASK;
regval |= setting;
regval = spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET);
spi_putreg(priv, PIC32MZ_SPI_CON_OFFSET, regval);
spiinfo("CON: %08x\n", regval);
/* Save the selection so the subsequence re-configurations will be
@ -1095,8 +1119,8 @@ static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd)
* Input Parameters:
* dev - Device-specific state data
* txbuffer - A pointer to the buffer of data to be sent
* rxbuffer - A pointer to the buffer in which to recieve data
* nwords - the length of data that to be exchanged in units of words.
* rxbuffer - A pointer to the buffer in which to receive data
* nwords - The length of data that to be exchanged in units of words.
* The wordsize is determined by the number of bits-per-word
* selected for the SPI interface. If nbits <= 8, the data is
* packed into uint8_t's; if nbits >8, the data is packed into
@ -1167,7 +1191,7 @@ static void spi_sndblock(FAR struct spi_dev_s *dev, FAR const void *buffer,
*
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the buffer in which to recieve data
* buffer - A pointer to the buffer in which to receive data
* nwords - the length of data that can be received in the buffer in
* number of words. The wordsize is determined by the number of
* bits-per-word selected for the SPI interface. If nbits <= 8,
@ -1200,10 +1224,10 @@ static void spi_recvblock(FAR struct spi_dev_s *dev, FAR void *buffer,
* Initialize the selected SPI port
*
* Input Parameters:
* Port number (for hardware that has mutiple SPI interfaces)
* Port number (for hardware that has multiple SPI interfaces)
*
* Returned Value:
* Valid SPI device structure reference on succcess; a NULL on failure
* Valid SPI device structure reference on success; a NULL on failure
*
****************************************************************************/
@ -1338,7 +1362,8 @@ FAR struct spi_dev_s *pic32mz_spibus_initialize(int port)
* board-specific pic32mz_spiNselect() interface.
*/
regval = (SPI_CON_MSTEN | SPI_CON_SMP | SPI_CON_MODE_8BIT | SPI_CON_ON);
regval = (SPI_CON_MSTEN | SPI_CON_SMP | SPI_CON_MODE_8BIT |
SPI_CON_CKE | SPI_CON_ON);
/* Set the ENHBUF bit if using Enhanced Buffer mode. */