STM32 and EFM32 SPI drivers adopted an incompatible conventions somewhere along the line. The set the number of bits to negative when calling SPI_SETBITS which had the magical side-effect of setting LSB first order of bit transmission. This is not only a hokey way to pass control information but is supported by no other SPI drivers.
This change three things: (1) It adds HWFEAT_LSBFIRST as a new H/W feature. (2) It changes the implementations of SPI_SETBITS in the STM32 and EFM32 derivers so that negated bit numbers are simply errors and it adds the SPI_HWFEATURES method that can set the LSB bit order, and (3) It changes all calls with negative number of bits from all drivers: The number of bits is now always positive and SPI_HWFEATUREs is called with HWFEAT_LSBFIRST to set the bit order.
This commit is contained in:
parent
986c568d34
commit
7d4cb73bd6
@ -185,6 +185,10 @@ static uint32_t spi_setfrequency(struct spi_dev_s *dev,
|
||||
uint32_t frequency);
|
||||
static void spi_setmode(struct spi_dev_s *dev, enum spi_mode_e mode);
|
||||
static void spi_setbits(struct spi_dev_s *dev, int nbits);
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint8_t spi_status(struct spi_dev_s *dev, enum spi_dev_e devid);
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
static int spi_cmddata(struct spi_dev_s *dev, enum spi_dev_e devid,
|
||||
@ -218,7 +222,7 @@ static const struct spi_ops_s g_spiops =
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = 0,
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = spi_status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
@ -976,47 +980,16 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
|
||||
const struct efm32_spiconfig_s *config;
|
||||
uint32_t regval;
|
||||
uint32_t setting;
|
||||
bool lsbfirst;
|
||||
|
||||
spiinfo("nbits=%d\n", nbits);
|
||||
|
||||
DEBUGASSERT(priv && priv->config);
|
||||
config = priv->config;
|
||||
|
||||
/* Bit order is encoded by the sign of nbits */
|
||||
/* Has the number of bits changed? */
|
||||
|
||||
if (nbits < 0)
|
||||
if (nbits != priv->nbits)
|
||||
{
|
||||
/* LSB first */
|
||||
|
||||
lsbfirst = true;
|
||||
nbits = -nbits;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MSH first */
|
||||
|
||||
lsbfirst = false;
|
||||
}
|
||||
|
||||
/* Has the number of bits or the bit order changed? */
|
||||
|
||||
if (nbits != priv->nbits || lsbfirst != priv->lsbfirst)
|
||||
{
|
||||
/* Set the new bit order */
|
||||
|
||||
regval = spi_getreg(config, EFM32_USART_CTRL_OFFSET);
|
||||
if (lsbfirst)
|
||||
{
|
||||
regval &= ~USART_CTRL_MSBF;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval |= USART_CTRL_MSBF;
|
||||
}
|
||||
|
||||
spi_putreg(config, EFM32_USART_CTRL_OFFSET, regval);
|
||||
|
||||
/* Select the new number of bits */
|
||||
|
||||
switch (nbits)
|
||||
@ -1086,11 +1059,72 @@ static void spi_setbits(struct spi_dev_s *dev, int nbits)
|
||||
* faster
|
||||
*/
|
||||
|
||||
priv->nbits = nbits;
|
||||
priv->lsbfirst = lsbfirst;
|
||||
priv->nbits = nbits;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_hwfeatures
|
||||
*
|
||||
* Description:
|
||||
* Set hardware-specific feature flags.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* flags - H/W feature flags
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) if the selected H/W features are enabled; A negated errno
|
||||
* value if any H/W feature is not supportable.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
||||
{
|
||||
struct efm32_spidev_s *priv = (struct efm32_spidev_s *)dev;
|
||||
const struct efm32_spiconfig_s *config;
|
||||
uint32_t regval;
|
||||
bool lsbfirst;
|
||||
|
||||
spiinfo("features=%08x\n", features);
|
||||
|
||||
DEBUGASSERT(priv && priv->config);
|
||||
config = priv->config;
|
||||
|
||||
/* Bit order is encoded by the sign of nbits */
|
||||
|
||||
lsbfirst = ((hwfeatures & HWFEAT_LSBFIRST) != 0);
|
||||
|
||||
/* Has the number of bits or the bit order changed? */
|
||||
|
||||
if (lsbfirst != priv->lsbfirst)
|
||||
{
|
||||
/* Set the new bit order */
|
||||
|
||||
regval = spi_getreg(config, EFM32_USART_CTRL_OFFSET);
|
||||
if (lsbfirst)
|
||||
{
|
||||
regval &= ~USART_CTRL_MSBF;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval |= USART_CTRL_MSBF;
|
||||
}
|
||||
|
||||
spi_putreg(config, EFM32_USART_CTRL_OFFSET, regval);
|
||||
|
||||
/* Save the selection so the subsequence re-configurations will be
|
||||
* faster
|
||||
*/
|
||||
|
||||
priv->lsbfirst = lsbfirst;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_status
|
||||
*
|
||||
|
@ -222,6 +222,10 @@ 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 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);
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
@ -249,7 +253,7 @@ static const struct spi_ops_s g_sp1iops =
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = 0, /* Not supported */
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi1status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
@ -292,6 +296,9 @@ static const struct spi_ops_s g_sp2iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi2status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi2cmddata,
|
||||
@ -333,6 +340,9 @@ static const struct spi_ops_s g_sp3iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi3status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi3cmddata,
|
||||
@ -374,6 +384,9 @@ static const struct spi_ops_s g_sp4iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi4status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi4cmddata,
|
||||
@ -415,6 +428,9 @@ static const struct spi_ops_s g_sp5iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi5status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi5cmddata,
|
||||
@ -456,6 +472,9 @@ static const struct spi_ops_s g_sp6iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi6status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi3cmddata,
|
||||
@ -1136,24 +1155,14 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
|
||||
switch (nbits)
|
||||
{
|
||||
case -8:
|
||||
setbits = SPI_CR1_LSBFIRST;
|
||||
clrbits = SPI_CR1_DFF;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
setbits = 0;
|
||||
clrbits = SPI_CR1_DFF | SPI_CR1_LSBFIRST;
|
||||
break;
|
||||
|
||||
case -16:
|
||||
setbits = SPI_CR1_DFF | SPI_CR1_LSBFIRST;
|
||||
clrbits = 0;
|
||||
clrbits = SPI_CR1_DFF;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
setbits = SPI_CR1_DFF;
|
||||
clrbits = SPI_CR1_LSBFIRST;
|
||||
clrbits = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1170,6 +1179,52 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_hwfeatures
|
||||
*
|
||||
* Description:
|
||||
* Set hardware-specific feature flags.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* flags - H/W feature flags
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) if the selected H/W features are enabled; A negated errno
|
||||
* value if any H/W feature is not supportable.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint16_t setbits;
|
||||
uint16_t clrbits;
|
||||
|
||||
spiinfo("features=%08x\n", features);
|
||||
|
||||
/* Transfer data LSB first? */
|
||||
|
||||
if ((hwfeatures & HWFEAT_LSBFIRST) != 0)
|
||||
{
|
||||
setbits = SPI_CR1_LSBFIRST;
|
||||
clrbits = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits = 0;
|
||||
clrbits = SPI_CR1_LSBFIRST;
|
||||
}
|
||||
|
||||
spi_modifycr1(priv, 0, SPI_CR1_SPE);
|
||||
spi_modifycr1(priv, setbits, clrbits);
|
||||
spi_modifycr1(priv, SPI_CR1_SPE, 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: spi_send
|
||||
*
|
||||
|
@ -203,6 +203,10 @@ 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 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);
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
@ -230,7 +234,7 @@ static const struct spi_ops_s g_sp1iops =
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = 0, /* Not supported */
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi1status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
@ -273,6 +277,9 @@ static const struct spi_ops_s g_sp2iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi2status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi2cmddata,
|
||||
@ -314,6 +321,9 @@ static const struct spi_ops_s g_sp3iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi3status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi3cmddata,
|
||||
@ -355,6 +365,9 @@ static const struct spi_ops_s g_sp4iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi4status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi4cmddata,
|
||||
@ -396,6 +409,9 @@ static const struct spi_ops_s g_sp5iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi5status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi5cmddata,
|
||||
@ -437,6 +453,9 @@ static const struct spi_ops_s g_sp6iops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32_spi6status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32_spi3cmddata,
|
||||
@ -1219,10 +1238,8 @@ 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)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint16_t setbitscr1;
|
||||
uint16_t clrbitscr1;
|
||||
uint16_t setbitscr2;
|
||||
uint16_t clrbitscr2;
|
||||
uint16_t setbits;
|
||||
uint16_t clrbits;
|
||||
int savbits = nbits;
|
||||
|
||||
spiinfo("nbits=%d\n", nbits);
|
||||
@ -1231,21 +1248,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
|
||||
if (nbits != priv->nbits)
|
||||
{
|
||||
/* Yes... Set CR1/2 appropriately */
|
||||
/* Negative sign means LSBFIRST, set this in CR1*/
|
||||
|
||||
if (nbits < 0)
|
||||
{
|
||||
setbitscr1 = SPI_CR1_LSBFIRST;
|
||||
clrbitscr1 = 0;
|
||||
nbits = -nbits;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbitscr1 = 0;
|
||||
clrbitscr1 = SPI_CR1_LSBFIRST;
|
||||
}
|
||||
|
||||
/* Yes... Set CR2 appropriately */
|
||||
/* Set the number of bits (valid range 4-16) */
|
||||
|
||||
if (nbits < 4 || nbits > 16)
|
||||
@ -1253,8 +1256,8 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
return;
|
||||
}
|
||||
|
||||
clrbitscr2 = SPI_CR2_DS_MASK;
|
||||
setbitscr2 = SPI_CR2_DS_VAL(nbits);
|
||||
clrbits = SPI_CR2_DS_MASK;
|
||||
setbits = SPI_CR2_DS_VAL(nbits);
|
||||
|
||||
/* If nbits is <=8, then we are in byte mode and FRXTH shall be set
|
||||
* (else, transaction will not complete).
|
||||
@ -1262,16 +1265,15 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
|
||||
if (nbits < 9)
|
||||
{
|
||||
setbitscr2 |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 1 byte */
|
||||
setbits |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 1 byte */
|
||||
}
|
||||
else
|
||||
{
|
||||
clrbitscr2 |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 2 bytes */
|
||||
clrbits |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 2 bytes */
|
||||
}
|
||||
|
||||
spi_modifycr1(priv, 0, SPI_CR1_SPE);
|
||||
spi_modifycr1(priv, setbitscr1, clrbitscr1);
|
||||
spi_modifycr2(priv, setbitscr2, clrbitscr2);
|
||||
spi_modifycr2(priv, setbits, clrbits);
|
||||
spi_modifycr1(priv, SPI_CR1_SPE, 0);
|
||||
|
||||
/* Save the selection so the subsequence re-configurations will be faster */
|
||||
@ -1280,6 +1282,55 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_hwfeatures
|
||||
*
|
||||
* Description:
|
||||
* Set hardware-specific feature flags.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* flags - H/W feature flags
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) if the selected H/W features are enabled; A negated errno
|
||||
* value if any H/W feature is not supportable.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint16_t setbitscr1;
|
||||
uint16_t clrbitscr1;
|
||||
uint16_t setbitscr2;
|
||||
uint16_t clrbitscr2;
|
||||
int savbits = nbits;
|
||||
|
||||
spiinfo("features=%08x\n", features);
|
||||
|
||||
/* Transfer data LSB first? */
|
||||
|
||||
if ((hwfeatures & HWFEAT_LSBFIRST) != 0)
|
||||
{
|
||||
setbits = SPI_CR1_LSBFIRST;
|
||||
clrbits = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits = 0;
|
||||
clrbits = SPI_CR1_LSBFIRST;
|
||||
}
|
||||
|
||||
spi_modifycr1(priv, 0, SPI_CR1_SPE);
|
||||
spi_modifycr1(priv, setbits, clrbits);
|
||||
spi_modifycr1(priv, SPI_CR1_SPE, 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: spi_send
|
||||
*
|
||||
|
@ -203,6 +203,10 @@ 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 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);
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev,
|
||||
spi_hwfeatures_t features);
|
||||
#endif
|
||||
static uint16_t spi_send(FAR struct spi_dev_s *dev, uint16_t wd);
|
||||
static void spi_exchange(FAR struct spi_dev_s *dev, FAR const void *txbuffer,
|
||||
FAR void *rxbuffer, size_t nwords);
|
||||
@ -230,7 +234,7 @@ static const struct spi_ops_s g_spi1ops =
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = 0, /* Not supported */
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32l4_spi1status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
@ -274,6 +278,9 @@ static const struct spi_ops_s g_spi2ops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32l4_spi2status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32l4_spi2cmddata,
|
||||
@ -315,6 +322,9 @@ static const struct spi_ops_s g_spi3ops =
|
||||
.setfrequency = spi_setfrequency,
|
||||
.setmode = spi_setmode,
|
||||
.setbits = spi_setbits,
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
.hwfeatures = spi_hwfeatures,
|
||||
#endif
|
||||
.status = stm32l4_spi3status,
|
||||
#ifdef CONFIG_SPI_CMDDATA
|
||||
.cmddata = stm32l4_spi3cmddata,
|
||||
@ -1092,8 +1102,8 @@ 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)
|
||||
{
|
||||
FAR struct stm32l4_spidev_s *priv = (FAR struct stm32l4_spidev_s *)dev;
|
||||
uint16_t setbits1, setbits2;
|
||||
uint16_t clrbits1, clrbits2;
|
||||
uint16_t setbits;
|
||||
uint16_t clrbits;
|
||||
int savbits = nbits;
|
||||
|
||||
spiinfo("nbits=%d\n", nbits);
|
||||
@ -1102,21 +1112,7 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
|
||||
if (nbits != priv->nbits)
|
||||
{
|
||||
/* Yes... Set CR1/2 appropriately */
|
||||
/* Negative sign means LSBFIRST, set this in CR1*/
|
||||
|
||||
if (nbits < 0)
|
||||
{
|
||||
setbits1 = SPI_CR1_LSBFIRST;
|
||||
clrbits1 = 0;
|
||||
nbits = -nbits;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits1 = 0;
|
||||
clrbits1 = SPI_CR1_LSBFIRST;
|
||||
}
|
||||
|
||||
/* Yes... Set CR2 appropriately */
|
||||
/* Set the number of bits (valid range 4-16) */
|
||||
|
||||
if (nbits < 4 || nbits > 16)
|
||||
@ -1124,8 +1120,8 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
return;
|
||||
}
|
||||
|
||||
clrbits2 = SPI_CR2_DS_MASK;
|
||||
setbits2 = SPI_CR2_DS_VAL(nbits);
|
||||
clrbits = SPI_CR2_DS_MASK;
|
||||
setbits = SPI_CR2_DS_VAL(nbits);
|
||||
|
||||
/* If nbits is <=8, then we are in byte mode and FRXTH shall be set
|
||||
* (else, transaction will not complete).
|
||||
@ -1133,16 +1129,15 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
|
||||
if (nbits < 9)
|
||||
{
|
||||
setbits2 |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 1 byte */
|
||||
setbits |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 1 byte */
|
||||
}
|
||||
else
|
||||
{
|
||||
clrbits2 |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 2 bytes */
|
||||
clrbits |= SPI_CR2_FRXTH; /* RX FIFO Threshold = 2 bytes */
|
||||
}
|
||||
|
||||
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE);
|
||||
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits1, clrbits1);
|
||||
spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits2, clrbits2);
|
||||
spi_modifycr(STM32L4_SPI_CR2_OFFSET, priv, setbits, clrbits);
|
||||
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0);
|
||||
|
||||
/* Save the selection so the subsequence re-configurations will be faster */
|
||||
@ -1151,6 +1146,52 @@ static void spi_setbits(FAR struct spi_dev_s *dev, int nbits)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: spi_hwfeatures
|
||||
*
|
||||
* Description:
|
||||
* Set hardware-specific feature flags.
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* flags - H/W feature flags
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) if the selected H/W features are enabled; A negated errno
|
||||
* value if any H/W feature is not supportable.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SPI_HWFEATURES
|
||||
static int spi_hwfeatures(FAR struct spi_dev_s *dev, spi_hwfeatures_t features)
|
||||
{
|
||||
FAR struct stm32_spidev_s *priv = (FAR struct stm32_spidev_s *)dev;
|
||||
uint16_t setbits;
|
||||
uint16_t clrbits;
|
||||
|
||||
spiinfo("features=%08x\n", features);
|
||||
|
||||
/* Transfer data LSB first? */
|
||||
|
||||
if ((hwfeatures & HWFEAT_LSBFIRST) != 0)
|
||||
{
|
||||
setbits = SPI_CR1_LSBFIRST;
|
||||
clrbits = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits = 0;
|
||||
clrbits = SPI_CR1_LSBFIRST;
|
||||
}
|
||||
|
||||
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, 0, SPI_CR1_SPE);
|
||||
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, setbits, clrbits);
|
||||
spi_modifycr(STM32L4_SPI_CR1_OFFSET, priv, SPI_CR1_SPE, 0);
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: spi_send
|
||||
*
|
||||
|
@ -59,7 +59,11 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration */
|
||||
/* H/W features must be enabled in order to support LSB first operation */
|
||||
|
||||
#ifndef CONFIG_SPI_HWFEATURES
|
||||
# error CONFIG_SPI_HWFEATURES=y required by this driver
|
||||
#endif
|
||||
|
||||
/* Cisplay resolution */
|
||||
|
||||
@ -103,7 +107,7 @@
|
||||
/* Other misc settings */
|
||||
|
||||
#define MEMLCD_SPI_FREQUENCY 2250000
|
||||
#define MEMLCD_SPI_BITS (-8)
|
||||
#define MEMLCD_SPI_BITS 8
|
||||
#define MEMLCD_SPI_MODE SPIDEV_MODE0
|
||||
|
||||
#define LS_BIT (1 << 0)
|
||||
@ -281,12 +285,12 @@ static void memlcd_select(FAR struct spi_dev_s *spi)
|
||||
|
||||
SPI_SETMODE(spi, MEMLCD_SPI_MODE);
|
||||
SPI_SETBITS(spi, MEMLCD_SPI_BITS);
|
||||
(void)SPI_HWFEATURES(spi, 0);
|
||||
# ifdef CONFIG_MEMLCD_SPI_FREQUENCY
|
||||
(void)SPI_HWFEATURES(spi, HWFEAT_LSBFIRST);
|
||||
#ifdef CONFIG_MEMLCD_SPI_FREQUENCY
|
||||
(void)SPI_SETFREQUENCY(spi, CONFIG_MEMLCD_SPI_FREQUENCY);
|
||||
# else
|
||||
#else
|
||||
(void)SPI_SETFREQUENCY(spi, MEMLCD_SPI_FREQUENCY);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -56,6 +56,13 @@
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
/* H/W features must be enabled in order to support LSB first operation */
|
||||
|
||||
#ifndef CONFIG_SPI_HWFEATURES
|
||||
# error CONFIG_SPI_HWFEATURES=y required by this driver
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_WL_PN532_DEBUG
|
||||
# define pn532err _err
|
||||
# define pn532info _info
|
||||
@ -145,8 +152,8 @@ static void pn532_lock(FAR struct spi_dev_s *spi)
|
||||
(void)SPI_LOCK(spi, true);
|
||||
|
||||
SPI_SETMODE(spi, SPIDEV_MODE0);
|
||||
SPI_SETBITS(spi, -8);
|
||||
(void)SPI_HWFEATURES(spi, 0);
|
||||
SPI_SETBITS(spi, 8);
|
||||
(void)SPI_HWFEATURES(spi, HWFEAT_LSBFIRST);
|
||||
(void)SPI_SETFREQUENCY(spi, CONFIG_PN532_SPI_FREQ);
|
||||
}
|
||||
|
||||
@ -160,8 +167,8 @@ static inline void pn532_configspi(FAR struct spi_dev_s *spi)
|
||||
/* Configure SPI for the PN532 module. */
|
||||
|
||||
SPI_SETMODE(spi, SPIDEV_MODE0);
|
||||
SPI_SETBITS(spi, -8);
|
||||
(void)SPI_HWFEATURES(spi, 0);
|
||||
SPI_SETBITS(spi, 8);
|
||||
(void)SPI_HWFEATURES(spi, HWFEAT_LSBFIRST);
|
||||
(void)SPI_SETFREQUENCY(spi, CONFIG_PN532_SPI_FREQ);
|
||||
}
|
||||
|
||||
|
@ -175,9 +175,7 @@
|
||||
*
|
||||
* Input Parameters:
|
||||
* dev - Device-specific state data
|
||||
* nbits - The number of bits requests.
|
||||
* If value is greater > 0 then it implies MSB first
|
||||
* If value is below < 0, then it implies LSB first with -nbits
|
||||
* nbits - The number of bits in an SPI word.
|
||||
*
|
||||
* Returned Value:
|
||||
* none
|
||||
@ -225,6 +223,8 @@
|
||||
* Do not set the LASTXFER-Bit at the last word of the next
|
||||
* exchange, Flag is auto-resetting after the next LASTXFER
|
||||
* condition. (see spi_exchange)
|
||||
* Bit 4: HWFEAT_LSBFIRST
|
||||
* Data transferred LSB first (default is MSB first)
|
||||
*/
|
||||
|
||||
# ifdef CONFIG_SPI_CRCGENERATION
|
||||
@ -237,6 +237,8 @@
|
||||
# define HWFEAT_ESCAPE_LASTXFER (1 << 3)
|
||||
# endif
|
||||
|
||||
# define HWFEAT_LSBFIRST (1 << 4)
|
||||
|
||||
#else
|
||||
/* Any attempt to select hardware features with CONFIG_SPI_HWFEATURES
|
||||
* deselected will return an -ENOSYS error.
|
||||
|
Loading…
Reference in New Issue
Block a user