A collection of Analog Devices drivers for the mbed platform

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AD7798.cpp Source File

AD7798.cpp

00001 /***************************************************************************//**
00002  *   @file   AD7798.c
00003  *   @brief  Implementation of AD7798 Driver.
00004  *   @author
00005 ********************************************************************************
00006  * Copyright 2012(c) Analog Devices, Inc.
00007  *
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without
00011  * modification, are permitted provided that the following conditions are met:
00012  *  - Redistributions of source code must retain the above copyright
00013  *    notice, this list of conditions and the following disclaimer.
00014  *  - Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in
00016  *    the documentation and/or other materials provided with the
00017  *    distribution.
00018  *  - Neither the name of Analog Devices, Inc. nor the names of its
00019  *    contributors may be used to endorse or promote products derived
00020  *    from this software without specific prior written permission.
00021  *  - The use of this software may or may not infringe the patent rights
00022  *    of one or more patent holders.  This license does not release you
00023  *    from the requirement that you obtain separate licenses from these
00024  *    patent holders to use this software.
00025  *  - Use of the software either in source or binary form, must be run
00026  *    on or directly connected to an Analog Devices Inc. component.
00027  *
00028  * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
00029  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
00030  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00031  * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
00032  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00033  * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
00034  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00035  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00036  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00037  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00038  *
00039 ********************************************************************************
00040  *   SVN Revision: 577
00041 *******************************************************************************/
00042 
00043 /******************************************************************************/
00044 /* Include Files                                                              */
00045 /******************************************************************************/
00046 #include "AD7798.h"             // AD7798 definitions.
00047 #include <stdio.h>
00048 
00049 
00050 /***************************************************************************//**
00051  * @brief Initializes the AD7798 and checks if the device is present.
00052  *
00053  * @param None.
00054  *
00055  * @return status - Result of the initialization procedure.
00056  *                  Example: 1 - if initialization was successful (ID is 0x0B).
00057  *                           0 - if initialization was unsuccessful.
00058 *******************************************************************************/
00059 AD7798::AD7798( PinName CS, PinName MOSI, PinName MISO, PinName SCK):
00060     /*miso(MISO),*/ ad7798(MOSI, MISO, SCK), cs(CS)
00061 {
00062     cs = true; // cs is active low
00063     ad7798.format(8, _SPI_MODE);
00064 }
00065 uint8_t AD7798::init(void)
00066 {
00067     unsigned char status = 0x1;
00068 
00069     if ((get_register_value (AD7798_REG_ID, 1) & 0x0F) != AD7798_ID) {
00070         status = 0x0;
00071     }
00072 
00073     return(status);
00074 }
00075 
00076 /***************************************************************************//**
00077  * @brief Sends 32 consecutive 1's on SPI in order to reset the part.
00078  *
00079  * @param None.
00080  *
00081  * @return  None.
00082 *******************************************************************************/
00083 void AD7798::frequency(int hz)
00084 {
00085     ad7798.frequency(hz);
00086 }
00087 void AD7798::reset(void)
00088 {
00089     unsigned char dataToSend[4] = {0xFF, 0xFF, 0xFF, 0xFF};
00090 
00091     spi_write(dataToSend, 4);
00092 
00093     wait_ms(500);
00094 
00095 }
00096 /***************************************************************************//**
00097  * @brief Reads the value of the selected register
00098  *
00099  * @param regAddress - The address of the register to read.
00100  * @param size - The size of the register to read.
00101  *
00102  * @return data - The value of the selected register register.
00103 *******************************************************************************/
00104 uint16_t AD7798::get_register_value(uint8_t regAddress, uint8_t size, bool toggle_cs)
00105 {
00106     unsigned char data[size];
00107     uint16_t receivedData = 0x00;
00108     unsigned char byte;
00109 
00110     data[0] = AD7798_COMM_READ |  AD7798_COMM_ADDR(regAddress);
00111 
00112     spi_read(data, size, toggle_cs);
00113 
00114     receivedData = data[0];
00115 
00116     if(size > 1) {
00117 
00118         for(byte = 1; byte < size; byte++) {
00119             receivedData = (receivedData << (byte * 8) | data[byte]);
00120         }
00121     }
00122     return receivedData;
00123 }
00124 /***************************************************************************//**
00125  * @brief Writes the value to the register
00126  *
00127  * @param -  regAddress - The address of the register to write to.
00128  * @param -  regValue - The value to write to the register.
00129  * @param -  size - The size of the register to write.
00130  *
00131  * @return  None.
00132 *******************************************************************************/
00133 void AD7798::set_register_value(uint8_t regAddress, uint16_t regValue,
00134                                 uint8_t size, bool toggle_cs)
00135 {
00136     uint8_t data[size + 1];
00137     uint8_t byte;
00138     uint16_t mask;
00139 
00140     data[0] = AD7798_COMM_WRITE |  AD7798_COMM_ADDR(regAddress);
00141 
00142     if(size == 1) {
00143 
00144         mask = 0x00FF;
00145 
00146     } else {
00147 
00148         mask = 0xFF00;
00149     }
00150 
00151     for(byte = 1; byte <= size; byte++) {
00152         data[byte] = (uint8_t)((regValue & mask) >> ((size - byte) * 8));
00153         mask = mask >> (byte * 8);
00154     }
00155 
00156     spi_write(data, (1 + size), toggle_cs);
00157 
00158 
00159 }
00160 /***************************************************************************//**
00161  * @brief Reads /RDY bit of status reg.
00162  *
00163  * @param None.
00164  *
00165  * @return rdy  - 0 if RDY is 1.
00166  *              - 1 if RDY is 0.
00167 *******************************************************************************/
00168 uint8_t AD7798::ready(void)
00169 {
00170 
00171     while((get_register_value( AD7798_REG_STAT, 1) & 0x80) != 0x80);
00172 
00173     return(1);
00174 }
00175 
00176 /***************************************************************************//**
00177  * @brief Sets the operating mode of AD7798.
00178  *
00179  * @param mode - Mode of operation.
00180  *
00181  * @return  None.
00182 *******************************************************************************/
00183 void AD7798::set_mode(uint8_t mode)
00184 {
00185     unsigned long command;
00186     command = get_register_value(AD7798_REG_MODE, 2);
00187     command &= ~AD7798_MODE_SEL(0xFF);
00188     command |= AD7798_MODE_SEL(mode);
00189     set_register_value(
00190         AD7798_REG_MODE,
00191         command,
00192         2
00193     );
00194 }
00195 /***************************************************************************//**
00196  * @brief Selects the channel of AD7798.
00197  *
00198  * @param  channel - ADC channel selection.
00199  *
00200  * @return  None.
00201 *******************************************************************************/
00202 void AD7798::set_channel(uint8_t channel)
00203 {
00204     unsigned long command;
00205     command = get_register_value(AD7798_REG_CONF, 2);
00206     command &= ~AD7798_CONF_CHAN(0xFF);
00207     command |= AD7798_CONF_CHAN(channel);
00208     set_register_value(
00209         AD7798_REG_CONF,
00210         command,
00211         2
00212     );
00213 }
00214 
00215 /***************************************************************************//**
00216  * @brief  Sets the gain of the In-Amp.
00217  *
00218  * @param  gain - Gain.
00219  *
00220  * @return  None.
00221 *******************************************************************************/
00222 void AD7798::set_gain(uint16_t gain)
00223 {
00224     uint16_t command;
00225     command = get_register_value(AD7798_REG_CONF, 2);
00226     command &= ~AD7798_CONF_GAIN(0xFF);
00227     command |= AD7798_CONF_GAIN(gain);
00228     set_register_value(
00229         AD7798_REG_CONF,
00230         command,
00231         2
00232     );
00233 }
00234 
00235 void AD7798::set_filter(uint8_t filter)
00236 {
00237     unsigned long command;
00238     command = get_register_value(AD7798_REG_MODE, 2);
00239     command &= ~AD7798_MODE_RATE(0x0F);
00240     command |= AD7798_MODE_RATE(filter);
00241     set_register_value(
00242         AD7798_REG_MODE,
00243         command,
00244         2
00245     );
00246 }
00247 /***************************************************************************//**
00248  * @brief Enables or disables the reference detect function.
00249  *
00250  * @param state - State of the reference detect function.
00251  *               Example: 0 - Reference detect disabled.
00252  *                        1 - Reference detect enabled.
00253  *
00254  * @return None.
00255 *******************************************************************************/
00256 void AD7798::set_reference(uint8_t state)
00257 {
00258     unsigned long command = 0;
00259     command = get_register_value(AD7798_REG_CONF, 2);
00260     command &= ~AD7798_CONF_REFDET(1);
00261     command |= AD7798_CONF_REFDET(state);
00262     set_register_value(AD7798_REG_CONF,
00263                        command,
00264                        2);
00265 }
00266 
00267 void AD7798::set_coding_mode(uint8_t mode)
00268 {
00269     uint16_t command;
00270 
00271     command = get_register_value(AD7798_REG_CONF, 2);
00272 
00273     if(mode == AD7798_BIPOLAR) {
00274 
00275         command &= ~AD7798_CONF_UNIPOLAR;
00276 
00277     } else if(mode == AD7798_UNIPOLAR) {
00278 
00279         command |= AD7798_CONF_UNIPOLAR;
00280     }
00281     set_register_value(
00282         AD7798_REG_CONF,
00283         command,
00284         2
00285     );
00286 }
00287 
00288 void AD7798::set_burnout_current(uint8_t select)
00289 {
00290     uint16_t command;
00291 
00292     command = get_register_value(AD7798_REG_CONF, 2);
00293 
00294     if(select == AD7798_DISABLE)
00295         command &= ~AD7798_CONF_BO_EN;
00296     else if(select == AD7798_ENABLE)
00297         command |= AD7798_CONF_BO_EN;
00298 
00299     set_register_value(
00300         AD7798_REG_CONF,
00301         command,
00302         2
00303     );
00304 }
00305 
00306 uint8_t AD7798::spi_read(uint8_t *data, uint8_t bytes_number, bool toggle_cs)
00307 {
00308     cs = false & toggle_cs;
00309     data[0] = ad7798.write(data[0]);
00310     for(uint8_t byte = 1; byte <= bytes_number; byte++) {
00311         data[byte - 1] = ad7798.write(data[byte]);
00312     }
00313     cs = true & toggle_cs;
00314     return bytes_number;
00315 }
00316 uint8_t AD7798::spi_write(uint8_t *data, uint8_t bytes_number, bool toggle_cs)
00317 {
00318     cs = false & toggle_cs;
00319     for(uint8_t byte = 0; byte < bytes_number; byte++) {
00320         ad7798.write(data[byte]);
00321     }
00322     cs = true & toggle_cs;
00323     return bytes_number;
00324 }
00325 
00326 void AD7798::read_data(uint8_t adcChannel, uint16_t *adcData)
00327 {
00328 
00329     uint8_t channel;
00330 
00331     channel = 0x80 | adcChannel;
00332 
00333     cs = 0;
00334 
00335     set_register_value(AD7798_REG_MODE, 0x200A, 2);//, false);
00336     uint16_t regVal = 0;
00337     while( (regVal & channel) != channel) {
00338         regVal = get_register_value( AD7798_REG_STAT, 1);//, false);
00339     }
00340 
00341     //timer_sleep(200);
00342     wait_ms(200); // ???
00343 
00344     *adcData = get_register_value(AD7798_REG_DATA, 2);//, false);
00345 
00346     cs = 1;
00347 
00348 
00349 
00350 }