arch/mips/src/pic32mz/pic32mz-spi.c: Fix SPI Mode selection. CKE is the inversion of the CPHA.
This commit is contained in:
parent
1812d6f515
commit
145970a266
@ -77,10 +77,10 @@
|
|||||||
#define PIC32MZ_SPI_BRGSET_OFFSET 0x0038 /* SPI baud rate set register */
|
#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_BRGINV_OFFSET 0x003c /* SPI baud rate invert register */
|
||||||
|
|
||||||
#define PIC32MZ_SPI_CON2_OFFSET 0x0040 /* SPI control register 2*/
|
#define PIC32MZ_SPI_CON2_OFFSET 0x0040 /* SPI control register 2 */
|
||||||
#define PIC32MZ_SPI_CON2CLR_OFFSET 0x0040 /* SPI control register 2*/
|
#define PIC32MZ_SPI_CON2CLR_OFFSET 0x0044 /* SPI control clear register 2 */
|
||||||
#define PIC32MZ_SPI_CON2SET_OFFSET 0x0040 /* SPI control register 2*/
|
#define PIC32MZ_SPI_CON2SET_OFFSET 0x0048 /* SPI control set register 2 */
|
||||||
#define PIC32MZ_SPI_CON2INV_OFFSET 0x0040 /* SPI control register 2*/
|
#define PIC32MZ_SPI_CON2INV_OFFSET 0x004c /* SPI control invert register 2 */
|
||||||
|
|
||||||
/* SPI Peripheral Addresses *************************************************/
|
/* SPI Peripheral Addresses *************************************************/
|
||||||
|
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* All SPI peripherals are clocked by PBCLK2 */
|
/* All SPI peripherals are clocked by PBCLK2 */
|
||||||
|
|
||||||
#define BOARD_PBCLOCK BOARD_PBCLK2
|
#define BOARD_PBCLOCK BOARD_PBCLK2
|
||||||
@ -70,6 +71,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* This structure describes the fixed (ROM-able) configuration of the SPI
|
/* This structure describes the fixed (ROM-able) configuration of the SPI
|
||||||
* peripheral.
|
* peripheral.
|
||||||
*/
|
*/
|
||||||
@ -110,6 +112,7 @@ struct pic32mz_dev_s
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* Low-level register access */
|
/* Low-level register access */
|
||||||
|
|
||||||
#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG
|
#ifdef CONFIG_PIC32MZ_SPI_REGDEBUG
|
||||||
@ -137,7 +140,8 @@ static void spi_exchange8(FAR struct pic32mz_dev_s *priv,
|
|||||||
/* SPI methods */
|
/* SPI methods */
|
||||||
|
|
||||||
static int spi_lock(FAR struct spi_dev_s *dev, bool lock);
|
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_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 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);
|
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
|
#endif
|
||||||
.sdipps = BOARD_SDI1_PPS,
|
.sdipps = BOARD_SDI1_PPS,
|
||||||
.sdopps = PPS_OUTPUT_REGVAL(BOARD_SDO1_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 =
|
static struct pic32mz_dev_s g_spi1dev =
|
||||||
{
|
{
|
||||||
.spidev = { &g_spi1ops },
|
.spidev =
|
||||||
.config = &g_spi1config,
|
{
|
||||||
|
&g_spi1ops
|
||||||
|
},
|
||||||
|
.config = &g_spi1config
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -246,7 +253,10 @@ static const struct pic32mz_config_s g_spi2config =
|
|||||||
|
|
||||||
static struct pic32mz_dev_s g_spi2dev =
|
static struct pic32mz_dev_s g_spi2dev =
|
||||||
{
|
{
|
||||||
.spidev = { &g_spi2ops },
|
.spidev =
|
||||||
|
{
|
||||||
|
&g_spi2ops
|
||||||
|
},
|
||||||
.config = &g_spi2config,
|
.config = &g_spi2config,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -292,7 +302,10 @@ static const struct pic32mz_config_s g_spi3config =
|
|||||||
|
|
||||||
static struct pic32mz_dev_s g_spi3dev =
|
static struct pic32mz_dev_s g_spi3dev =
|
||||||
{
|
{
|
||||||
.spidev = { &g_spi3ops },
|
.spidev =
|
||||||
|
{
|
||||||
|
&g_spi3ops
|
||||||
|
},
|
||||||
.config = &g_spi3config,
|
.config = &g_spi3config,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -338,7 +351,10 @@ static const struct pic32mz_config_s g_spi4config =
|
|||||||
|
|
||||||
static struct pic32mz_dev_s g_spi4dev =
|
static struct pic32mz_dev_s g_spi4dev =
|
||||||
{
|
{
|
||||||
.spidev = { &g_spi4ops },
|
.spidev =
|
||||||
|
{
|
||||||
|
&g_spi4ops
|
||||||
|
},
|
||||||
.config = &g_spi4config,
|
.config = &g_spi4config,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -384,7 +400,10 @@ static const struct pic32mz_config_s g_spi5config =
|
|||||||
|
|
||||||
static struct pic32mz_dev_s g_spi5dev =
|
static struct pic32mz_dev_s g_spi5dev =
|
||||||
{
|
{
|
||||||
.spidev = { &g_spi5ops },
|
.spidev =
|
||||||
|
{
|
||||||
|
&g_spi5ops
|
||||||
|
},
|
||||||
.config = &g_spi5config,
|
.config = &g_spi5config,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -430,7 +449,10 @@ static const struct pic32mz_config_s g_spi6config =
|
|||||||
|
|
||||||
static struct pic32mz_dev_s g_spi6dev =
|
static struct pic32mz_dev_s g_spi6dev =
|
||||||
{
|
{
|
||||||
.spidev = { &g_spi6ops },
|
.spidev =
|
||||||
|
{
|
||||||
|
&g_spi6ops
|
||||||
|
},
|
||||||
.config = &g_spi6config,
|
.config = &g_spi6config,
|
||||||
};
|
};
|
||||||
#endif
|
#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 */
|
/* 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 */
|
/* Save information about the new access */
|
||||||
@ -532,7 +554,7 @@ static uint32_t spi_getreg(FAR struct pic32mz_dev_s *priv,
|
|||||||
{
|
{
|
||||||
/* Yes.. */
|
/* Yes.. */
|
||||||
|
|
||||||
_info("%08lx->%08lx\n",
|
spiinfo("%08lx->%08lx\n",
|
||||||
(unsigned long)regaddr, (unsigned long)regval);
|
(unsigned long)regaddr, (unsigned long)regval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,7 +596,7 @@ static void spi_putaddr(FAR struct pic32mz_dev_s *priv, uintptr_t regaddr,
|
|||||||
{
|
{
|
||||||
/* Yes.. */
|
/* Yes.. */
|
||||||
|
|
||||||
_info("%08lx<-%08lx\n",
|
spiinfo("%08lx<-%08lx\n",
|
||||||
(unsigned long)regaddr, (unsigned long)regval);
|
(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);
|
spiinfo("nbytes: %d\n", nbytes);
|
||||||
while (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)
|
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);
|
while ((spi_getreg(priv, PIC32MZ_SPI_STAT_OFFSET) & SPI_STAT_SPIRBE) != 0);
|
||||||
#else
|
#else
|
||||||
/* Wait for the SPIRBF bit in the SPI Status Register to be set to 1. In
|
/* 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);
|
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;
|
FAR struct pic32mz_dev_s *priv = (FAR struct pic32mz_dev_s *)dev;
|
||||||
uint32_t divisor;
|
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)
|
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;
|
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);
|
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:
|
* CON Register mapping:
|
||||||
* CPOL=0 corresponds to CON:CKP=0; CPOL=1 corresponds to CON:CKP=1
|
* 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
|
* In addition, the CON register supports SMP: SPI Data Input Sample
|
||||||
* Phase bit:
|
* 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.
|
* Which is hardcoded to 1.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
regval = spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET);
|
|
||||||
regval &= ~(SPI_CON_CKP | SPI_CON_CKE);
|
|
||||||
|
|
||||||
switch (mode)
|
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;
|
break;
|
||||||
|
|
||||||
case SPIDEV_MODE1: /* CPOL=0; CPHA=1 */
|
case SPIDEV_MODE1: /* CPOL=0; CPHA=1 => CKP=0; CKE=0 */
|
||||||
regval |= SPI_CON_CKE;
|
spi_putreg(priv, PIC32MZ_SPI_CONCLR_OFFSET, SPI_CON_CKP);
|
||||||
|
spi_putreg(priv, PIC32MZ_SPI_CONCLR_OFFSET, SPI_CON_CKE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPIDEV_MODE2: /* CPOL=1; CPHA=0 */
|
case SPIDEV_MODE2: /* CPOL=1; CPHA=0 => CKP=1; CKE=1 */
|
||||||
regval |= SPI_CON_CKP;
|
spi_putreg(priv, PIC32MZ_SPI_CONSET_OFFSET, SPI_CON_CKP);
|
||||||
|
spi_putreg(priv, PIC32MZ_SPI_CONSET_OFFSET, SPI_CON_CKE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SPIDEV_MODE3: /* CPOL=1; CPHA=1 */
|
case SPIDEV_MODE3: /* CPOL=1; CPHA=1 => CKP=1; CKE=0 */
|
||||||
regval |= (SPI_CON_CKP | SPI_CON_CKE);
|
spi_putreg(priv, PIC32MZ_SPI_CONSET_OFFSET, SPI_CON_CKP);
|
||||||
|
spi_putreg(priv, PIC32MZ_SPI_CONCLR_OFFSET, SPI_CON_CKE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -964,10 +989,9 @@ static void spi_setmode(FAR struct spi_dev_s *dev, enum spi_mode_e mode)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
spi_putreg(priv, PIC32MZ_SPI_CON_OFFSET, regval);
|
spiinfo("CON: %08x\n", spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET));
|
||||||
spiinfo("CON: %08x\n", regval);
|
|
||||||
|
|
||||||
/* 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;
|
priv->mode = mode;
|
||||||
}
|
}
|
||||||
@ -1009,11 +1033,11 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
|||||||
}
|
}
|
||||||
else if (nbits == 16)
|
else if (nbits == 16)
|
||||||
{
|
{
|
||||||
setting = SPI_CON_MODE_8BIT;
|
setting = SPI_CON_MODE_16BIT;
|
||||||
}
|
}
|
||||||
else if (nbits == 32)
|
else if (nbits == 32)
|
||||||
{
|
{
|
||||||
setting = SPI_CON_MODE_8BIT;
|
setting = SPI_CON_MODE_32BIT;
|
||||||
}
|
}
|
||||||
else
|
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_getreg(priv, PIC32MZ_SPI_CON_OFFSET);
|
||||||
regval &= ~SPI_CON_MODE_MASK;
|
regval &= ~SPI_CON_MODE_MASK;
|
||||||
regval |= setting;
|
regval |= setting;
|
||||||
regval = spi_getreg(priv, PIC32MZ_SPI_CON_OFFSET);
|
spi_putreg(priv, PIC32MZ_SPI_CON_OFFSET, regval);
|
||||||
spiinfo("CON: %08x\n", regval);
|
spiinfo("CON: %08x\n", regval);
|
||||||
|
|
||||||
/* Save the selection so the subsequence re-configurations will be
|
/* 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:
|
* Input Parameters:
|
||||||
* dev - Device-specific state data
|
* dev - Device-specific state data
|
||||||
* txbuffer - A pointer to the buffer of data to be sent
|
* txbuffer - A pointer to the buffer of data to be sent
|
||||||
* rxbuffer - A pointer to the buffer in which to recieve data
|
* rxbuffer - A pointer to the buffer in which to receive data
|
||||||
* nwords - the length of data that to be exchanged in units of words.
|
* nwords - The length of data that to be exchanged in units of words.
|
||||||
* The wordsize is determined by the number of bits-per-word
|
* The wordsize is determined by the number of bits-per-word
|
||||||
* selected for the SPI interface. If nbits <= 8, the data is
|
* selected for the SPI interface. If nbits <= 8, the data is
|
||||||
* packed into uint8_t's; if nbits >8, the data is packed into
|
* 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:
|
* Input Parameters:
|
||||||
* dev - Device-specific state data
|
* 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
|
* nwords - the length of data that can be received in the buffer in
|
||||||
* number of words. The wordsize is determined by the number of
|
* number of words. The wordsize is determined by the number of
|
||||||
* bits-per-word selected for the SPI interface. If nbits <= 8,
|
* 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
|
* Initialize the selected SPI port
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* Port number (for hardware that has mutiple SPI interfaces)
|
* Port number (for hardware that has multiple SPI interfaces)
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* 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.
|
* 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. */
|
/* Set the ENHBUF bit if using Enhanced Buffer mode. */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user