text: /****************************************************************************
   * include/nuttx/sensors/ads1242.h
   *
   *   Copyright (C) 2016, DS-Automotion GmbH. All rights reserved.
   *   Author: Alexander Entinger <a.entinger@ds-automotion.com>
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   * 3. Neither the name NuttX nor the names of its contributors may be
   *    used to endorse or promote products derived from this software
   *    without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
   * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
   * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   * POSSIBILITY OF SUCH DAMAGE.
   *
   ****************************************************************************/
  
  #ifndef NUTTX_INCLUDE_NUTTX_ANALOG_ADS1242_H_
  #define NUTTX_INCLUDE_NUTTX_ANALOG_ADS1242_H_
  
  /****************************************************************************
   * Included Files
   ****************************************************************************/
  
  #include <nuttx/config.h>
  #include <nuttx/fs/ioctl.h>
  #include <nuttx/spi/spi.h>
  
  #if defined(CONFIG_SPI) && defined(CONFIG_ADC_ADS1242)
  
  /****************************************************************************
   * Pre-processor Definitions
   ****************************************************************************/
  
  /* IOCTL Commands ***********************************************************/
  
  #define ANIOC_ADS2142_READ                    _ANIOC(0x0001)  /* Arg: uint32_t *value */
  #define ANIOC_ADS2142_SET_GAIN                _ANIOC(0x0002)  /* Arg: uint8_t value */
  #define ANIOC_ADS2142_SET_POSITIVE_INPUT      _ANIOC(0x0003)  /* Arg: uint8_t value */
  #define ANIOC_ADS2142_SET_NEGATIVE_INPUT      _ANIOC(0x0004)  /* Arg: uint8_t value */
  #define ANIOC_ADS2142_IS_DATA_READY           _ANIOC(0x0005)  /* Arg: bool *value */
  #define ANIOC_ADS2142_DO_SYSTEM_OFFSET_CALIB  _ANIOC(0x0006)  /* Arg: None */
  
  /* ADS1242 REGISTER *********************************************************/
  
  #define ADS1242_REG_SETUP               (0x00)  /* Setup Register */
  #define ADS1242_REG_MUX                 (0x01)  /* Multiplexer Control Register */
  #define ADS1242_REG_ACR                 (0x02)  /* Analog Control Register */
  #define ADS1242_REG_ODAC                (0x03)  /* Offset DAC */
  #define ADS1242_REG_DIO                 (0x04)  /* Data I/O */
  #define ADS1242_REG_DIR                 (0x05)  /* Direction Control for Data I/O */
  #define ADS1242_REG_IOCON               (0x06)  /* I/O Configuration Register */
  
  /* ADS1242 REGISTER Bit Definitions *****************************************/
  
  /* SETUP */
  #define ADS1242_REG_SETUP_BIT_BOCS      (1 << 3)
  #define ADS1242_REG_SETUP_BIT_PGA2      (1 << 2)
  #define ADS1242_REG_SETUP_BIT_PGA1      (1 << 1)
  #define ADS1242_REG_SETUP_BIT_PGA0      (1 << 0)
  /* MUX */
  #define ADS1242_REG_MUX_BIT_PSEL3       (1 << 7)
  #define ADS1242_REG_MUX_BIT_PSEL2       (1 << 6)
  #define ADS1242_REG_MUX_BIT_PSEL1       (1 << 5)
  #define ADS1242_REG_MUX_BIT_PSEL0       (1 << 4)
  #define ADS1242_REG_MUX_BIT_NSEL3       (1 << 3)
  #define ADS1242_REG_MUX_BIT_NSEL2       (1 << 2)
  #define ADS1242_REG_MUX_BIT_NSEL1       (1 << 1)
  #define ADS1242_REG_MUX_BIT_NSEL0       (1 << 0)
  /* ACR */
  #define ADS1242_REG_ACR_BIT_nDRDY       (1 << 7)
  #define ADS1242_REG_ACR_BIT_UnB         (1 << 6)
  #define ADS1242_REG_ACR_BIT_SPEED       (1 << 5)
  #define ADS1242_REG_ACR_BIT_BUFEN       (1 << 4)
  #define ADS1242_REG_ACR_BIT_BITORDER    (1 << 3)
  #define ADS1242_REG_ACR_BIT_RANGE       (1 << 2)
  #define ADS1242_REG_ACR_BIT_DR1         (1 << 1)
  #define ADS1242_REG_ACR_BIT_DR0         (1 << 0)
  
  /* ADS1242 SPI COMMANDS *****************************************************/
  
  #define ADS1242_CMD_READ_DATA           (0x01)
  #define ADS1242_CMD_READ_REGISTER       (0x10)
  #define ADS1242_CMD_WRITE_REGISTER      (0x50)
  #define ADS1242_CMD_SELF_OFFSET_CALIB   (0xF1)
  #define ADS1242_CMD_SELF_GAIN_CALIB     (0xf2)
  #define ADS1242_CMD_SYSTEM_OFFSET_CALIB (0xf3)
  #define ADS1242_CMD_RESET               (0xfe)
  
  /* SPI BUS PARAMETERS *******************************************************/
  
  /* 100 kHz, SCLK period has to be at least 4 x tOsc period of ADS1242
   * oscillator circuit.
   */
  
  #define ADS1242_SPI_FREQUENCY   (100000)
  
  /* Device uses SPI Mode 1: CKPOL = 0, CKPHA = 1 */
  
  #define ADS1242_SPI_MODE        (SPIDEV_MODE1)
  
  /****************************************************************************
   * Public Types
   ****************************************************************************/
  
  typedef enum
  {
    ADS1242_x1     = 0,
    ADS1242_x2     = ADS1242_REG_SETUP_BIT_PGA0,
    ADS1242_x4     = ADS1242_REG_SETUP_BIT_PGA1,
    ADS1242_x8     = ADS1242_REG_SETUP_BIT_PGA1 | ADS1242_REG_SETUP_BIT_PGA0,
    ADS1242_x16    = ADS1242_REG_SETUP_BIT_PGA2,
    ADS1242_x32    = ADS1242_REG_SETUP_BIT_PGA2 | ADS1242_REG_SETUP_BIT_PGA0,
    ADS1242_x64    = ADS1242_REG_SETUP_BIT_PGA2 | ADS1242_REG_SETUP_BIT_PGA1,
    ADS1242_x128   = ADS1242_REG_SETUP_BIT_PGA2 | ADS1242_REG_SETUP_BIT_PGA1 |
                     ADS1242_REG_SETUP_BIT_PGA0
  } ADS1242_GAIN_SELECTION;
  
  typedef enum
  {
    ADS1242_P_AIN0 = 0,
    ADS1242_P_AIN1 = ADS1242_REG_MUX_BIT_PSEL0,
    ADS1242_P_AIN2 = ADS1242_REG_MUX_BIT_PSEL1,
    ADS1242_P_AIN3 = ADS1242_REG_MUX_BIT_PSEL1 | ADS1242_REG_MUX_BIT_PSEL0,
    ADS1242_P_AIN4 = ADS1242_REG_MUX_BIT_PSEL2,
    ADS1242_P_AIN5 = ADS1242_REG_MUX_BIT_PSEL2 | ADS1242_REG_MUX_BIT_PSEL0,
    ADS1242_P_AIN6 = ADS1242_REG_MUX_BIT_PSEL2 | ADS1242_REG_MUX_BIT_PSEL1,
    ADS1242_P_AIN7 = ADS1242_REG_MUX_BIT_PSEL2 | ADS1242_REG_MUX_BIT_PSEL1 |
                     ADS1242_REG_MUX_BIT_PSEL0,
  } ADS1242_POSITIVE_INPUT_SELECTION;
  
  typedef enum
  {
    ADS1242_N_AIN0 = 0,
    ADS1242_N_AIN1 = ADS1242_REG_MUX_BIT_NSEL0,
    ADS1242_N_AIN2 = ADS1242_REG_MUX_BIT_NSEL1,
    ADS1242_N_AIN3 = ADS1242_REG_MUX_BIT_NSEL1 | ADS1242_REG_MUX_BIT_NSEL0,
    ADS1242_N_AIN4 = ADS1242_REG_MUX_BIT_NSEL2,
    ADS1242_N_AIN5 = ADS1242_REG_MUX_BIT_NSEL2 | ADS1242_REG_MUX_BIT_NSEL0,
    ADS1242_N_AIN6 = ADS1242_REG_MUX_BIT_NSEL2 | ADS1242_REG_MUX_BIT_NSEL1,
    ADS1242_N_AIN7 = ADS1242_REG_MUX_BIT_NSEL2 | ADS1242_REG_MUX_BIT_NSEL1 |
                     ADS1242_REG_MUX_BIT_NSEL0,
  } ADS1242_NEGATIVE_INPUT_SELECTION;
  
  /****************************************************************************
   * Public Function Prototypes
   ****************************************************************************/
  
  #ifdef __cplusplus
  #define EXTERN extern "C"
  extern "C"
  {
  #else
  #define EXTERN extern
  #endif
  
  /****************************************************************************
   * Name: ads1242_register
   *
   * Description:
   *   Register the ADS1242 character device as 'devpath'
   *
   * Input Parameters:
   *   devpath - The full path to the driver to register. E.g., "/dev/ads1242"
   *   spi - An instance of the SPI interface to use to communicate with ADS1242
   *   osc_freq_hz - The frequency of the ADS1242 oscillator in Hz. Required for
   *   calculating the minimum delay periods when accessing the device via SPI.
   *
   *
   * Returned Value:
   *   Zero (OK) on success; a negated errno value on failure.
   *
   ****************************************************************************/
  
  int ads1242_register(FAR const char *devpath, FAR struct spi_dev_s *spi,
                       uint32_t const osc_freq_hz);
  
  #undef EXTERN
  #ifdef __cplusplus
  }
  #endif
  
  #endif /* CONFIG_SPI && CONFIG_ADC_ADS1242 */
  #endif /* NUTTX_INCLUDE_NUTTX_ANALOG_ADS1242_H_ */
  