All drivers that use SPI must call SPI_LOCK and SPI_UNLOCK. This is not optional.

This commit is contained in:
Gregory Nutt
2016-05-26 14:56:10 -06:00
parent d5a4f85893
commit 3e7b2d617a
4 changed files with 226 additions and 34 deletions
+85 -9
View File
@@ -1,9 +1,10 @@
/************************************************************************************
* arch/drivers/analog/ad5410.c
*
* Copyright (C) 2010, 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2011 Li Zhuoyi. All rights reserved.
* Author: Li Zhuoyi <lzyy.cn@gmail.com>
* History: 0.1 2011-08-05 initial version
* Gregory Nutt <gnutt@nuttx.org>
*
* This file is a part of NuttX:
*
@@ -85,6 +86,9 @@ struct up_dev_s
* ad_private Function Prototypes
****************************************************************************/
static void dac_lock(FAR struct spi_dev_s *spi);
static void dac_unlock(FAR struct spi_dev_s *spi);
/* DAC methods */
static void dac_reset(FAR struct dac_dev_s *dev);
@@ -121,62 +125,134 @@ static struct dac_dev_s g_dacdev =
* ad_private Functions
****************************************************************************/
/* Reset the DAC device. Called early to initialize the hardware. This
/****************************************************************************
* Name: dac_lock
*
* Description:
* Lock and configure the SPI bus.
*
****************************************************************************/
static void dac_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_SETFREQUENCY(spi, 400000);
}
/****************************************************************************
* Name: dac_unlock
*
* Description:
* Unlock the SPI bus.
*
****************************************************************************/
static void dac_unlock(FAR struct spi_dev_s *spi)
{
(void)SPI_LOCK(spi, false);
}
/****************************************************************************
* Name: dac_reset
*
* Description:
* Reset the DAC device. Called early to initialize the hardware. This
* is called, before ao_setup() and on error conditions.
*/
*
****************************************************************************/
static void dac_reset(FAR struct dac_dev_s *dev)
{
}
/* Configure the DAC. This method is called the first time that the DAC
/****************************************************************************
* Name: dac_setup
*
* Description:
* Configure the DAC. This method is called the first time that the DAC
* device is opened. This will occur when the port is first opened.
* This setup includes configuring and attaching DAC interrupts. Interrupts
* are all disabled upon return.
*/
*
****************************************************************************/
static int dac_setup(FAR struct dac_dev_s *dev)
{
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
FAR struct spi_dev_s *spi = priv->spi;
dac_lock(spi);
SPI_SELECT(spi, priv->devno, true);
SPI_SEND(spi, AD5410_REG_CMD);
SPI_SEND(spi, (AD5410_CMD_OUTEN | AD5410_CMD_420MA) >> 8);
SPI_SEND(spi, AD5410_CMD_OUTEN | AD5410_CMD_420MA);
SPI_SELECT(spi, priv->devno, false);
dac_unlock(spi);
return OK;
}
/* Disable the DAC. This method is called when the DAC device is closed.
/****************************************************************************
* Name: dac_shutdown
*
* Description:
* Disable the DAC. This method is called when the DAC device is closed.
* This method reverses the operation the setup method.
*/
*
****************************************************************************/
static void dac_shutdown(FAR struct dac_dev_s *dev)
{
}
/* Call to enable or disable TX interrupts */
/****************************************************************************
* Name: dac_txint
*
* Description:
* Call to enable or disable TX interrupts
*
****************************************************************************/
static void dac_txint(FAR struct dac_dev_s *dev, bool enable)
{
}
/****************************************************************************
* Name: dac_send
*
* Description:
*
****************************************************************************/
static int dac_send(FAR struct dac_dev_s *dev, FAR struct dac_msg_s *msg)
{
FAR struct up_dev_s *priv = (FAR struct up_dev_s *)dev->ad_priv;
FAR struct spi_dev_s *spi = priv->spi;
dac_lock(spi);
SPI_SELECT(spi, priv->devno, true);
SPI_SEND(spi, AD5410_REG_WR);
SPI_SEND(spi, (uint8_t)(msg->am_data >> 24));
SPI_SEND(spi, (uint8_t)(msg->am_data >> 16));
SPI_SELECT(spi, priv->devno, false);
dac_unlock(spi);
dac_txdone(&g_dacdev);
return 0;
}
/* All ioctl calls will be routed through this method */
/****************************************************************************
* Name: dac_ioctl
*
* Description:
* All ioctl calls will be routed through this method
*
****************************************************************************/
static int dac_ioctl(FAR struct dac_dev_s *dev, int cmd, unsigned long arg)
{
+62 -18
View File
@@ -2,8 +2,10 @@
* drivers/sensors/ads1242.c
* Character driver for the MCP3426 Differential Input 16 Bit Delta/Sigma ADC
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2015 DS-Automotion GmbH. All rights reserved.
* Author: Alexander Entinger <a.entinger@ds-automotion.com>
* Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -70,6 +72,8 @@ struct ads1242_dev_s
/* SPI Helpers */
static void ads1242_lock(FAR struct spi_dev_s *spi);
static void ads1242_unlock(FAR struct spi_dev_s *spi);
static void ads1242_reset(FAR struct ads1242_dev_s *dev);
static void ads1242_performSelfGainCalibration(
FAR struct ads1242_dev_s *dev);
@@ -128,19 +132,50 @@ static const struct file_operations g_ads1242_fops =
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ads1242_lock
*
* Description:
* Lock and configure the SPI bus.
*
****************************************************************************/
static void ads1242_lock(FAR struct spi_dev_s *spi)
{
(void)SPI_LOCK(spi, true);
SPI_SETMODE(spi, ADS1242_SPI_MODE);
SPI_SETBITS(spi, 8);
(void)SPI_HWFEATURES(spi, 0);
SPI_SETFREQUENCY(spi, ADS1242_SPI_FREQUENCY);
}
/****************************************************************************
* Name: ads1242_unlock
*
* Description:
* Unlock the SPI bus.
*
****************************************************************************/
static void ads1242_unlock(FAR struct spi_dev_s *spi)
{
(void)SPI_LOCK(spi, false);
}
/****************************************************************************
* Name: ads1242_reset
****************************************************************************/
static void ads1242_reset(FAR struct ads1242_dev_s *dev)
{
ads1242_lock(dev->spi);
SPI_SELECT(dev->spi, 0, true); /* Set nADC_SPI_CS to low which selects the ADS1242 */
SPI_SEND(dev->spi, ADS1242_CMD_RESET);/* Issue reset command */
SPI_SELECT(dev->spi, 0, false); /* Set nADC_SPI_CS to high which deselects the ADS1242 */
up_mdelay(100); /* Wait a little so the device has time to perform a proper reset */
ads1242_unlock(dev->spi);
}
/****************************************************************************
@@ -149,11 +184,13 @@ static void ads1242_reset(FAR struct ads1242_dev_s *dev)
static void ads1242_performSelfGainCalibration(FAR struct ads1242_dev_s *dev)
{
ads1242_lock(dev->spi);
SPI_SELECT(dev->spi, 0, true);
SPI_SEND(dev->spi, ADS1242_CMD_SELF_GAIN_CALIB);
SPI_SELECT(dev->spi, 0, false);
ads1242_unlock(dev->spi);
}
/****************************************************************************
@@ -162,11 +199,13 @@ static void ads1242_performSelfGainCalibration(FAR struct ads1242_dev_s *dev)
static void ads1242_performSelfOffsetCalibration(FAR struct ads1242_dev_s *dev)
{
ads1242_lock(dev->spi);
SPI_SELECT(dev->spi, 0, true);
SPI_SEND(dev->spi, ADS1242_CMD_SELF_OFFSET_CALIB);
SPI_SELECT(dev->spi, 0, false);
ads1242_unlock(dev->spi);
}
/****************************************************************************
@@ -176,11 +215,13 @@ static void ads1242_performSelfOffsetCalibration(FAR struct ads1242_dev_s *dev)
static void
ads1242_performSystemOffsetCalibration(FAR struct ads1242_dev_s *dev)
{
ads1242_lock(dev->spi);
SPI_SELECT(dev->spi, 0, true);
SPI_SEND(dev->spi, ADS1242_CMD_SYSTEM_OFFSET_CALIB);
SPI_SELECT(dev->spi, 0, false);
ads1242_unlock(dev->spi);
}
/****************************************************************************
@@ -190,8 +231,9 @@ ads1242_performSystemOffsetCalibration(FAR struct ads1242_dev_s *dev)
static void ads1242_read_conversion_result(FAR struct ads1242_dev_s *dev,
FAR uint32_t *conversion_result)
{
SPI_SELECT(dev->spi, 0, true);
ads1242_lock(dev->spi);
SPI_SELECT(dev->spi, 0, true);
SPI_SEND(dev->spi, ADS1242_CMD_READ_DATA);
/* Delay between last SCLK edge for DIN and first SCLK edge for DOUT:
@@ -212,6 +254,8 @@ static void ads1242_read_conversion_result(FAR struct ads1242_dev_s *dev,
*conversion_result |= ((uint32_t)(SPI_SEND(dev->spi, 0xFF))) << 0;
SPI_SELECT(dev->spi, 0, false);
ads1242_unlock(dev->spi);
}
/****************************************************************************
@@ -227,11 +271,15 @@ static void ads1242_read_conversion_result(FAR struct ads1242_dev_s *dev,
static void ads1242_write_reg(FAR struct ads1242_dev_s *dev,
uint8_t const reg_addr, uint8_t const reg_value)
{
ads1242_lock(dev->spi);
SPI_SELECT(dev->spi, 0, true);
SPI_SEND(dev->spi, ADS1242_CMD_WRITE_REGISTER | reg_addr);
SPI_SEND(dev->spi, 0x00); /* Write 1 Byte */
SPI_SEND(dev->spi, reg_value);
SPI_SELECT(dev->spi, 0, false);
ads1242_unlock(dev->spi);
}
/****************************************************************************
@@ -248,6 +296,8 @@ static void ads1242_write_reg(FAR struct ads1242_dev_s *dev,
static void ads1242_read_reg(FAR struct ads1242_dev_s *dev,
uint8_t const reg_addr, FAR uint8_t *reg_value)
{
ads1242_lock(dev->spi);
SPI_SELECT(dev->spi, 0, true);
SPI_SEND(dev->spi, ADS1242_CMD_READ_REGISTER | reg_addr);
SPI_SEND(dev->spi, 0x00); /* Read 1 Byte */
@@ -261,6 +311,8 @@ static void ads1242_read_reg(FAR struct ads1242_dev_s *dev,
*reg_value = SPI_SEND(dev->spi, 0xFF);
SPI_SELECT(dev->spi, 0, false);
ads1242_unlock(dev->spi);
}
/****************************************************************************
@@ -562,14 +614,6 @@ int ads1242_register(FAR const char *devpath, FAR struct spi_dev_s *spi,
kmm_free(priv);
}
/* setup SPI frequency */
SPI_SETFREQUENCY(spi, ADS1242_SPI_FREQUENCY);
/* Setup SPI mode */
SPI_SETMODE(spi, ADS1242_SPI_MODE);
return ret;
}
+36
View File
@@ -83,6 +83,9 @@ struct max31855_dev_s
* Private Function Prototypes
****************************************************************************/
static void max31855_lock(FAR struct spi_dev_s *spi);
static void max31855_unlock(FAR struct spi_dev_s *spi);
/* Character driver methods */
static int max31855_open(FAR struct file *filep);
@@ -112,6 +115,37 @@ static const struct file_operations g_max31855fops =
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: max31855_lock
*
* Description:
* Lock and configure the SPI bus.
*
****************************************************************************/
static void max31855_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_SETFREQUENCY(spi, 400000);
}
/****************************************************************************
* Name: max31855_unlock
*
* Description:
* Unlock the SPI bus.
*
****************************************************************************/
static void max31855_unlock(FAR struct spi_dev_s *spi)
{
(void)SPI_LOCK(spi, false);
}
/****************************************************************************
* Name: max31855_open
*
@@ -167,6 +201,7 @@ static ssize_t max31855_read(FAR struct file *filep, FAR char *buffer, size_t bu
/* Enable MAX31855's chip select */
max31855_lock(priv->spi);
SPI_SELECT(priv->spi, SPIDEV_TEMPERATURE, true);
/* Read temperature */
@@ -176,6 +211,7 @@ static ssize_t max31855_read(FAR struct file *filep, FAR char *buffer, size_t bu
/* Disable MAX31855's chip select */
SPI_SELECT(priv->spi, SPIDEV_TEMPERATURE, false);
max31855_unlock(priv->spi);
regval = (regmsb & 0xFF000000) >> 24;
regval |= (regmsb & 0xFF0000) >> 8;
+36
View File
@@ -80,6 +80,9 @@ struct max6675_dev_s
* Private Function Prototypes
****************************************************************************/
static void max6675_lock(FAR struct spi_dev_s *spi)
static void max6675_unlock(FAR struct spi_dev_s *spi)
/* Character driver methods */
static int max6675_open(FAR struct file *filep);
@@ -108,6 +111,37 @@ static const struct file_operations g_max6675fops =
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: max6675_lock
*
* Description:
* Lock and configure the SPI bus.
*
****************************************************************************/
static void max6675_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_SETFREQUENCY(spi, 400000);
}
/****************************************************************************
* Name: max6675_unlock
*
* Description:
* Unlock the SPI bus.
*
****************************************************************************/
static void max6675_unlock(FAR struct spi_dev_s *spi)
{
(void)SPI_LOCK(spi, false);
}
/****************************************************************************
* Name: max6675_open
*
@@ -163,6 +197,7 @@ static ssize_t max6675_read(FAR struct file *filep, FAR char *buffer, size_t buf
/* Enable MAX6675's chip select */
max6675_lock(priv->spi);
SPI_SELECT(priv->spi, SPIDEV_TEMPERATURE, true);
/* Read temperature */
@@ -172,6 +207,7 @@ static ssize_t max6675_read(FAR struct file *filep, FAR char *buffer, size_t buf
/* Disable MAX6675's chip select */
SPI_SELECT(priv->spi, SPIDEV_TEMPERATURE, false);
max6675_unlock(priv->spi);
regval = (regmsb & 0xFF00) >> 8;
regval |= (regmsb & 0xFF) << 8;