Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
AD7190.cpp@0:49fe1d7a6628, 2014-01-28 (annotated)
- Committer:
- MarioPoneder
- Date:
- Tue Jan 28 09:42:48 2014 +0000
- Revision:
- 0:49fe1d7a6628
- Child:
- 1:00d6e45e037a
a
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| MarioPoneder | 0:49fe1d7a6628 | 1 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 2 | * @file AD7190.cpp | 
| MarioPoneder | 0:49fe1d7a6628 | 3 | * @brief Implementation of the AD7190 driver. | 
| MarioPoneder | 0:49fe1d7a6628 | 4 | * @author Mario Poneder | 
| MarioPoneder | 0:49fe1d7a6628 | 5 | * @date 28/01/2013 | 
| MarioPoneder | 0:49fe1d7a6628 | 6 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 7 | * This class is based on the implementation from Dan Nechita (Analog Devices). | 
| MarioPoneder | 0:49fe1d7a6628 | 8 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 9 | |
| MarioPoneder | 0:49fe1d7a6628 | 10 | /******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 11 | /***************************** Include Files **********************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 12 | /******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 13 | #include "AD7190.h" | 
| MarioPoneder | 0:49fe1d7a6628 | 14 | |
| MarioPoneder | 0:49fe1d7a6628 | 15 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 16 | * @brief Constructs the AD7190 class. This library is designed for single | 
| MarioPoneder | 0:49fe1d7a6628 | 17 | * slave operation. Therefore no chip-select pin is required. | 
| MarioPoneder | 0:49fe1d7a6628 | 18 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 19 | * @param rdy RDY (DOUT/RDY) | 
| MarioPoneder | 0:49fe1d7a6628 | 20 | * @param mosi DIN | 
| MarioPoneder | 0:49fe1d7a6628 | 21 | * @param miso DOUT (DOUT/RDY), must be a different pin than rdy. | 
| MarioPoneder | 0:49fe1d7a6628 | 22 | * @param sclk SCLK | 
| MarioPoneder | 0:49fe1d7a6628 | 23 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 24 | AD7190::AD7190(PinName rdy, PinName mosi, PinName miso, PinName sclk) | 
| MarioPoneder | 0:49fe1d7a6628 | 25 | : _rdy(rdy), _rdyInt(rdy), _spi(mosi, miso, sclk) | 
| MarioPoneder | 0:49fe1d7a6628 | 26 | { | 
| MarioPoneder | 0:49fe1d7a6628 | 27 | ; | 
| MarioPoneder | 0:49fe1d7a6628 | 28 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 29 | |
| MarioPoneder | 0:49fe1d7a6628 | 30 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 31 | * @brief This interrupt routine gets called after every finished conversion | 
| MarioPoneder | 0:49fe1d7a6628 | 32 | * in continous read mode. It reads 4 bytes of data, the sample takes | 
| MarioPoneder | 0:49fe1d7a6628 | 33 | * 3 bytes and the status register 1 byte. | 
| MarioPoneder | 0:49fe1d7a6628 | 34 | * Moreover the sample callback function, which has to to take the | 
| MarioPoneder | 0:49fe1d7a6628 | 35 | * parameters 'data' and 'channel', gets called. | 
| MarioPoneder | 0:49fe1d7a6628 | 36 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 37 | * @return None, because this is an interrupt routine. | 
| MarioPoneder | 0:49fe1d7a6628 | 38 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 39 | void AD7190::SampleInterrupt(void) | 
| MarioPoneder | 0:49fe1d7a6628 | 40 | { | 
| MarioPoneder | 0:49fe1d7a6628 | 41 | static unsigned long buffer; | 
| MarioPoneder | 0:49fe1d7a6628 | 42 | static unsigned char i; | 
| MarioPoneder | 0:49fe1d7a6628 | 43 | this->_rdyInt.fall(NULL); | 
| MarioPoneder | 0:49fe1d7a6628 | 44 | for(i = 1; i <= 4; i++) { | 
| MarioPoneder | 0:49fe1d7a6628 | 45 | buffer = (buffer << 8) + _spi.write(0x00); | 
| MarioPoneder | 0:49fe1d7a6628 | 46 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 47 | this->sampleCallbackFunction(buffer >> 8, buffer & 0x07); | 
| MarioPoneder | 0:49fe1d7a6628 | 48 | this->_rdyInt.fall(this, &AD7190::SampleInterrupt); | 
| MarioPoneder | 0:49fe1d7a6628 | 49 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 50 | |
| MarioPoneder | 0:49fe1d7a6628 | 51 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 52 | * @brief Starts the interrupt-driven sampling process and sets the AD7190's | 
| MarioPoneder | 0:49fe1d7a6628 | 53 | * continuous read mode flag. | 
| MarioPoneder | 0:49fe1d7a6628 | 54 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 55 | * @param sampleCallbackFunction Pointer to the sample callback function, | 
| MarioPoneder | 0:49fe1d7a6628 | 56 | * which has to to take the parameters 'data' | 
| MarioPoneder | 0:49fe1d7a6628 | 57 | * and 'channel'. | 
| MarioPoneder | 0:49fe1d7a6628 | 58 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 59 | * @return None. | 
| MarioPoneder | 0:49fe1d7a6628 | 60 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 61 | void AD7190::StartContinuousRead(pSampleCallback_t sampleCallbackFunction) | 
| MarioPoneder | 0:49fe1d7a6628 | 62 | { | 
| MarioPoneder | 0:49fe1d7a6628 | 63 | this->sampleCallbackFunction = sampleCallbackFunction; | 
| MarioPoneder | 0:49fe1d7a6628 | 64 | this->WaitRdyGoLow(); | 
| MarioPoneder | 0:49fe1d7a6628 | 65 | this->_spi.write(COMM_READ | COMM_CREAD | COMM_ADDR(REG_DATA)); | 
| MarioPoneder | 0:49fe1d7a6628 | 66 | this->_rdyInt.fall(this, &AD7190::SampleInterrupt); | 
| MarioPoneder | 0:49fe1d7a6628 | 67 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 68 | |
| MarioPoneder | 0:49fe1d7a6628 | 69 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 70 | * @brief Stops the interrupt-driven sampling process and disables the AD7190's | 
| MarioPoneder | 0:49fe1d7a6628 | 71 | * continuous read mode. | 
| MarioPoneder | 0:49fe1d7a6628 | 72 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 73 | * @return None. | 
| MarioPoneder | 0:49fe1d7a6628 | 74 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 75 | void AD7190::StopContinuousRead(void) | 
| MarioPoneder | 0:49fe1d7a6628 | 76 | { | 
| MarioPoneder | 0:49fe1d7a6628 | 77 | this->_rdyInt.fall(NULL); | 
| MarioPoneder | 0:49fe1d7a6628 | 78 | this->WaitRdyGoLow(); | 
| MarioPoneder | 0:49fe1d7a6628 | 79 | this->_spi.write(COMM_READ | COMM_ADDR(REG_DATA)); | 
| MarioPoneder | 0:49fe1d7a6628 | 80 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 81 | |
| MarioPoneder | 0:49fe1d7a6628 | 82 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 83 | * @brief Writes the specified contents to the specified on-chip register. | 
| MarioPoneder | 0:49fe1d7a6628 | 84 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 85 | * @param registerAddress Address of the register. | 
| MarioPoneder | 0:49fe1d7a6628 | 86 | * @param registerValue Contents to write. | 
| MarioPoneder | 0:49fe1d7a6628 | 87 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 88 | * @return None. | 
| MarioPoneder | 0:49fe1d7a6628 | 89 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 90 | void AD7190::SetRegisterValue(unsigned char registerAddress, unsigned long registerValue) | 
| MarioPoneder | 0:49fe1d7a6628 | 91 | { | 
| MarioPoneder | 0:49fe1d7a6628 | 92 | static unsigned char *dataPointer, bytesNr; | 
| MarioPoneder | 0:49fe1d7a6628 | 93 | dataPointer = (unsigned char*)®isterValue; | 
| MarioPoneder | 0:49fe1d7a6628 | 94 | |
| MarioPoneder | 0:49fe1d7a6628 | 95 | switch(registerAddress) { | 
| MarioPoneder | 0:49fe1d7a6628 | 96 | case REG_ID: | 
| MarioPoneder | 0:49fe1d7a6628 | 97 | case REG_GPOCON: | 
| MarioPoneder | 0:49fe1d7a6628 | 98 | bytesNr = 1; | 
| MarioPoneder | 0:49fe1d7a6628 | 99 | break; | 
| MarioPoneder | 0:49fe1d7a6628 | 100 | case REG_MODE: | 
| MarioPoneder | 0:49fe1d7a6628 | 101 | dataPointer += 2; | 
| MarioPoneder | 0:49fe1d7a6628 | 102 | case REG_CONF: | 
| MarioPoneder | 0:49fe1d7a6628 | 103 | registerValue |= (1 << 19); | 
| MarioPoneder | 0:49fe1d7a6628 | 104 | case REG_OFFSET: | 
| MarioPoneder | 0:49fe1d7a6628 | 105 | case REG_FULLSCALE: | 
| MarioPoneder | 0:49fe1d7a6628 | 106 | bytesNr = 3; | 
| MarioPoneder | 0:49fe1d7a6628 | 107 | break; | 
| MarioPoneder | 0:49fe1d7a6628 | 108 | default: | 
| MarioPoneder | 0:49fe1d7a6628 | 109 | bytesNr = 0; | 
| MarioPoneder | 0:49fe1d7a6628 | 110 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 111 | |
| MarioPoneder | 0:49fe1d7a6628 | 112 | this->_spi.write(COMM_WRITE | COMM_ADDR(registerAddress)); | 
| MarioPoneder | 0:49fe1d7a6628 | 113 | for(; bytesNr > 0; bytesNr--) { | 
| MarioPoneder | 0:49fe1d7a6628 | 114 | this->_spi.write(*dataPointer); | 
| MarioPoneder | 0:49fe1d7a6628 | 115 | registerAddress == REG_MODE ? dataPointer -- : dataPointer ++; | 
| MarioPoneder | 0:49fe1d7a6628 | 116 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 117 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 118 | |
| MarioPoneder | 0:49fe1d7a6628 | 119 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 120 | * @brief Reads the contents of the specified on-chip register. | 
| MarioPoneder | 0:49fe1d7a6628 | 121 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 122 | * @param registerAddress Address of the register. | 
| MarioPoneder | 0:49fe1d7a6628 | 123 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 124 | * @return Contents of the register. | 
| MarioPoneder | 0:49fe1d7a6628 | 125 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 126 | unsigned long AD7190::GetRegisterValue(unsigned char registerAddress) | 
| MarioPoneder | 0:49fe1d7a6628 | 127 | { | 
| MarioPoneder | 0:49fe1d7a6628 | 128 | static unsigned long buffer = 0; | 
| MarioPoneder | 0:49fe1d7a6628 | 129 | static unsigned char bytesNr, i; | 
| MarioPoneder | 0:49fe1d7a6628 | 130 | |
| MarioPoneder | 0:49fe1d7a6628 | 131 | switch (registerAddress) { | 
| MarioPoneder | 0:49fe1d7a6628 | 132 | case REG_STAT: | 
| MarioPoneder | 0:49fe1d7a6628 | 133 | case REG_ID: | 
| MarioPoneder | 0:49fe1d7a6628 | 134 | case REG_GPOCON: | 
| MarioPoneder | 0:49fe1d7a6628 | 135 | bytesNr = 1; | 
| MarioPoneder | 0:49fe1d7a6628 | 136 | break; | 
| MarioPoneder | 0:49fe1d7a6628 | 137 | case REG_MODE: | 
| MarioPoneder | 0:49fe1d7a6628 | 138 | case REG_CONF: | 
| MarioPoneder | 0:49fe1d7a6628 | 139 | case REG_DATA: | 
| MarioPoneder | 0:49fe1d7a6628 | 140 | case REG_OFFSET: | 
| MarioPoneder | 0:49fe1d7a6628 | 141 | case REG_FULLSCALE: | 
| MarioPoneder | 0:49fe1d7a6628 | 142 | bytesNr = 3; | 
| MarioPoneder | 0:49fe1d7a6628 | 143 | break; | 
| MarioPoneder | 0:49fe1d7a6628 | 144 | default: | 
| MarioPoneder | 0:49fe1d7a6628 | 145 | bytesNr = 0; | 
| MarioPoneder | 0:49fe1d7a6628 | 146 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 147 | |
| MarioPoneder | 0:49fe1d7a6628 | 148 | this->_spi.write(COMM_READ | COMM_ADDR(registerAddress)); | 
| MarioPoneder | 0:49fe1d7a6628 | 149 | for(i = 1; i <= bytesNr; i++) { | 
| MarioPoneder | 0:49fe1d7a6628 | 150 | buffer = (buffer << 8) + _spi.write(0x00); | 
| MarioPoneder | 0:49fe1d7a6628 | 151 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 152 | return buffer; | 
| MarioPoneder | 0:49fe1d7a6628 | 153 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 154 | |
| MarioPoneder | 0:49fe1d7a6628 | 155 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 156 | * @brief Initialises the SPI bus, resets the AD7190 and checks if it is | 
| MarioPoneder | 0:49fe1d7a6628 | 157 | * responding. | 
| MarioPoneder | 0:49fe1d7a6628 | 158 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 159 | * @return True, if the ADC is respondig | 
| MarioPoneder | 0:49fe1d7a6628 | 160 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 161 | bool AD7190::Init(void) | 
| MarioPoneder | 0:49fe1d7a6628 | 162 | { | 
| MarioPoneder | 0:49fe1d7a6628 | 163 | unsigned char regVal; | 
| MarioPoneder | 0:49fe1d7a6628 | 164 | |
| MarioPoneder | 0:49fe1d7a6628 | 165 | this->_spi.format(8, 3); | 
| MarioPoneder | 0:49fe1d7a6628 | 166 | this->_spi.frequency(10000000); | 
| MarioPoneder | 0:49fe1d7a6628 | 167 | this->Reset(); | 
| MarioPoneder | 0:49fe1d7a6628 | 168 | wait_ms(1); | 
| MarioPoneder | 0:49fe1d7a6628 | 169 | regVal = this->GetRegisterValue(REG_ID); | 
| MarioPoneder | 0:49fe1d7a6628 | 170 | |
| MarioPoneder | 0:49fe1d7a6628 | 171 | return (regVal & ID_MASK) == ID_AD7190 ; | 
| MarioPoneder | 0:49fe1d7a6628 | 172 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 173 | |
| MarioPoneder | 0:49fe1d7a6628 | 174 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 175 | * @brief Resets the AD7190. | 
| MarioPoneder | 0:49fe1d7a6628 | 176 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 177 | * @return None. | 
| MarioPoneder | 0:49fe1d7a6628 | 178 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 179 | void AD7190::Reset(void) | 
| MarioPoneder | 0:49fe1d7a6628 | 180 | { | 
| MarioPoneder | 0:49fe1d7a6628 | 181 | static unsigned char i; | 
| MarioPoneder | 0:49fe1d7a6628 | 182 | this->_spi.write(0x01); | 
| MarioPoneder | 0:49fe1d7a6628 | 183 | for(i = 0; i < 6; i++) { | 
| MarioPoneder | 0:49fe1d7a6628 | 184 | this->_spi.write(0xFF); | 
| MarioPoneder | 0:49fe1d7a6628 | 185 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 186 | } | 
| MarioPoneder | 0:49fe1d7a6628 | 187 | |
| MarioPoneder | 0:49fe1d7a6628 | 188 | /***************************************************************************//** | 
| MarioPoneder | 0:49fe1d7a6628 | 189 | * @brief Waits for the RDY (DOUT/RDY) pin to go low. | 
| MarioPoneder | 0:49fe1d7a6628 | 190 | * | 
| MarioPoneder | 0:49fe1d7a6628 | 191 | * @return None. | 
| MarioPoneder | 0:49fe1d7a6628 | 192 | *******************************************************************************/ | 
| MarioPoneder | 0:49fe1d7a6628 | 193 | void AD7190::WaitRdyGoLow(void) | 
| MarioPoneder | 0:49fe1d7a6628 | 194 | { | 
| MarioPoneder | 0:49fe1d7a6628 | 195 | for(; this->_rdy;); | 
| MarioPoneder | 0:49fe1d7a6628 | 196 | } |