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.
AD7124.cpp
00001 /** 00002 * @file AD7124.cpp 00003 * @brief Source file for AD7124 ADC 00004 * @author Analog Devices Inc. 00005 * 00006 * For support please go to: 00007 * Github: https://github.com/analogdevicesinc/mbed-adi 00008 * Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers 00009 * Product: http://www.analog.com/ad7124 00010 * More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all 00011 00012 ******************************************************************************** 00013 * Copyright 2016(c) Analog Devices, Inc. 00014 * 00015 * All rights reserved. 00016 * 00017 * Redistribution and use in source and binary forms, with or without 00018 * modification, are permitted provided that the following conditions are met: 00019 * - Redistributions of source code must retain the above copyright 00020 * notice, this list of conditions and the following disclaimer. 00021 * - Redistributions in binary form must reproduce the above copyright 00022 * notice, this list of conditions and the following disclaimer in 00023 * the documentation and/or other materials provided with the 00024 * distribution. 00025 * - Neither the name of Analog Devices, Inc. nor the names of its 00026 * contributors may be used to endorse or promote products derived 00027 * from this software without specific prior written permission. 00028 * - The use of this software may or may not infringe the patent rights 00029 * of one or more patent holders. This license does not release you 00030 * from the requirement that you obtain separate licenses from these 00031 * patent holders to use this software. 00032 * - Use of the software either in source or binary form, must be run 00033 * on or directly connected to an Analog Devices Inc. component. 00034 * 00035 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR 00036 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, 00037 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 00038 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, 00039 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00040 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR 00041 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00042 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00043 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00044 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00045 * 00046 ********************************************************************************/ 00047 00048 #include <stdint.h> 00049 #include "mbed.h" 00050 #include "AD7124.h" 00051 00052 /** 00053 * @brief AD7790 constructor, sets CS pin and SPI format 00054 * @param CS - (optional)chip select of the AD7790 00055 * @param MOSI - (optional)pin of the SPI interface 00056 * @param MISO - (optional)pin of the SPI interface 00057 * @param SCK - (optional)pin of the SPI interface 00058 */ 00059 AD7124::AD7124(PinName CS, 00060 PinName MOSI, 00061 PinName MISO, 00062 PinName SCK) : 00063 miso(MISO), ad7124(MOSI, MISO, SCK), cs(CS) 00064 { 00065 cs = true; // cs is active low 00066 ad7124.format(8, _SPI_MODE); 00067 this->regs = ad7124_regs; 00068 this->useCRC = false; 00069 } 00070 00071 /** 00072 * @brief Set AD7790 SPI frequency 00073 * @param hz - SPI bus frequency in hz 00074 * @return none 00075 */ 00076 void AD7124::frequency(int hz) 00077 { 00078 ad7124.frequency(hz); 00079 } 00080 00081 /** 00082 * @brief Resets the AD7790 00083 * @return none 00084 */ 00085 /*void AD7124::reset() 00086 { 00087 ad7124.format(8, _SPI_MODE); 00088 cs = false; 00089 wait_us(_DELAY_TIMING); 00090 ad7124.write(_RESET); 00091 ad7124.write(_RESET); 00092 ad7124.write(_RESET); 00093 ad7124.write(_RESET); 00094 ad7124.write(_RESET); 00095 ad7124.write(_RESET); 00096 ad7124.write(_RESET); 00097 ad7124.write(_RESET); 00098 wait_us(_DELAY_TIMING); 00099 cs = true; 00100 //_continous_conversion = true; 00101 }*/ 00102 /** 00103 * @brief Reads a register of the AD7790 00104 * @param address - address of the register 00105 * @return value of the register 00106 */ 00107 uint16_t AD7124::read_reg(uint8_t address) 00108 { 00109 uint16_t data = address << 8; 00110 data |= _DUMMY_BYTE; 00111 data |= _READ_FLAG; 00112 return write_spi(data); 00113 } 00114 00115 /** 00116 * @brief Writes a register of the AD7790 00117 * @param address - address of the register 00118 * @param reg_val - value to be written 00119 * @return none 00120 * 00121 */ 00122 void AD7124::write_reg(uint8_t address, uint8_t reg_val) 00123 { 00124 uint16_t spi_data = address << 8; 00125 spi_data |= reg_val; 00126 write_spi(spi_data); 00127 } 00128 00129 /** 00130 * @brief Writes 16bit data to the AD7790 SPI interface 00131 * @param reg_val to be written 00132 * @return data returned by the AD7790 00133 */ 00134 uint16_t AD7124::write_spi(uint16_t reg_val) 00135 { 00136 uint16_t data_result; 00137 uint8_t upper_byte = (reg_val >> 8) & 0xFF; 00138 uint8_t lower_byte = reg_val & 0xFF; 00139 ad7124.format(8, _SPI_MODE); 00140 cs = false; 00141 data_result = (ad7124.write(upper_byte) << 8); 00142 data_result |= ad7124.write(lower_byte); 00143 cs = true; 00144 return data_result; 00145 } 00146 00147 00148 00149 /***************************************************************************//** 00150 * @brief Reads the value of the specified register without checking if the 00151 * device is ready to accept user requests. 00152 * 00153 * @param device - The handler of the instance of the driver. 00154 * @param pReg - Pointer to the register structure holding info about the 00155 * register to be read. The read value is stored inside the 00156 * register structure. 00157 * 00158 * @return Returns 0 for success or negative error code. 00159 *******************************************************************************/ 00160 int32_t AD7124::NoCheckReadRegister(ad7124_st_reg* pReg) 00161 { 00162 int32_t ret = 0; 00163 uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 00164 uint8_t i = 0; 00165 uint8_t check8 = 0; 00166 uint8_t msgBuf[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 00167 00168 00169 check8 = useCRC; 00170 00171 /* Build the Command word */ 00172 buffer[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD | 00173 AD7124_COMM_REG_RA(pReg->addr); 00174 00175 /* Read data from the device */ 00176 ret = SPI_Read(buffer, 00177 ((useCRC != AD7124_DISABLE_CRC) ? pReg->size + 1 00178 : pReg->size) + 1); 00179 if(ret < 0) 00180 return ret; 00181 00182 /* Check the CRC */ 00183 if(check8 == AD7124_USE_CRC) { 00184 msgBuf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD | 00185 AD7124_COMM_REG_RA(pReg->addr); 00186 for(i = 1; i < pReg->size + 2; ++i) { 00187 msgBuf[i] = buffer[i]; 00188 } 00189 check8 = ComputeCRC8 (msgBuf, pReg->size + 2); 00190 } 00191 00192 if(check8 != 0) { 00193 /* ReadRegister checksum failed. */ 00194 return COMM_ERR; 00195 } 00196 00197 /* Build the result */ 00198 pReg->value = 0; 00199 for(i = 1; i < pReg->size + 1; i++) { 00200 pReg->value <<= 8; 00201 pReg->value += buffer[i]; 00202 } 00203 00204 return ret; 00205 } 00206 00207 /***************************************************************************//** 00208 * @brief Writes the value of the specified register without checking if the 00209 * device is ready to accept user requests. 00210 * 00211 * @param device - The handler of the instance of the driver. 00212 * @param reg - Register structure holding info about the register to be written 00213 * 00214 * @return Returns 0 for success or negative error code. 00215 *******************************************************************************/ 00216 int32_t AD7124::NoCheckWriteRegister(ad7124_st_reg reg) 00217 { 00218 int32_t ret = 0; 00219 int32_t regValue = 0; 00220 uint8_t wrBuf[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 00221 uint8_t i = 0; 00222 uint8_t crc8 = 0; 00223 00224 00225 /* Build the Command word */ 00226 wrBuf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_WR | 00227 AD7124_COMM_REG_RA(reg.addr); 00228 00229 /* Fill the write buffer */ 00230 regValue = reg.value; 00231 for(i = 0; i < reg.size; i++) { 00232 wrBuf[reg.size - i] = regValue & 0xFF; 00233 regValue >>= 8; 00234 } 00235 00236 /* Compute the CRC */ 00237 if(useCRC != AD7124_DISABLE_CRC) { 00238 crc8 = ComputeCRC8 (wrBuf, reg.size + 1); 00239 wrBuf[reg.size + 1] = crc8; 00240 } 00241 00242 /* Write data to the device */ 00243 ret = SPI_Write(wrBuf, 00244 (useCRC != AD7124_DISABLE_CRC) ? reg.size + 2 00245 : reg.size + 1); 00246 00247 return ret; 00248 } 00249 00250 /***************************************************************************//** 00251 * @brief Reads the value of the specified register only when the device is ready 00252 * to accept user requests. If the device ready flag is deactivated the 00253 * read operation will be executed without checking the device state. 00254 * 00255 * @param device - The handler of the instance of the driver. 00256 * @param pReg - Pointer to the register structure holding info about the 00257 * register to be read. The read value is stored inside the 00258 * register structure. 00259 * 00260 * @return Returns 0 for success or negative error code. 00261 *******************************************************************************/ 00262 int32_t AD7124::ReadRegister(ad7124_st_reg* pReg) 00263 { 00264 int32_t ret; 00265 00266 if (pReg->addr != ERR_REG && check_ready) { 00267 ret = WaitForSpiReady (spi_rdy_poll_cnt); 00268 if (ret < 0) 00269 return ret; 00270 } 00271 ret = NoCheckReadRegister(pReg); 00272 00273 return ret; 00274 } 00275 00276 /***************************************************************************//** 00277 * @brief Writes the value of the specified register only when the device is 00278 * ready to accept user requests. If the device ready flag is deactivated 00279 * the write operation will be executed without checking the device state. 00280 * 00281 * @param device - The handler of the instance of the driver. 00282 * @param reg - Register structure holding info about the register to be written 00283 * 00284 * @return Returns 0 for success or negative error code. 00285 *******************************************************************************/ 00286 int32_t AD7124::WriteRegister(ad7124_st_reg pReg) 00287 { 00288 int32_t ret; 00289 00290 if (check_ready) { 00291 ret = WaitForSpiReady (spi_rdy_poll_cnt); 00292 if (ret < 0) 00293 return ret; 00294 } 00295 ret = NoCheckWriteRegister(pReg); 00296 00297 return ret; 00298 } 00299 00300 /***************************************************************************//** 00301 * @brief Reads and returns the value of a device register. The read value is 00302 * also stored in software register list of the device. 00303 * 00304 * @param device - The handler of the instance of the driver. 00305 * @param reg - Which register to read from. 00306 * @param pError - Pointer to the location where to store the error code if an 00307 * error occurs. Stores 0 for success or negative error code. 00308 * Does not store anything if pErorr = NULL; 00309 * 00310 * @return Returns the value read from the specified register. 00311 *******************************************************************************/ 00312 uint32_t AD7124::ReadDeviceRegister(enum ad7124_registers reg) 00313 { 00314 ReadRegister(®s[reg]); 00315 return (regs[reg].value); 00316 } 00317 00318 /***************************************************************************//** 00319 * @brief Writes the specified value to a device register. The value to be 00320 * written is also stored in the software register list of the device. 00321 * 00322 * @param device - The handler of the instance of the driver. 00323 * @param reg - Which register to write to. 00324 * @param value - The value to be written to the reigster of the device. 00325 * 00326 * @return Returns 0 for success or negative error code. 00327 *******************************************************************************/ 00328 int32_t AD7124::WriteDeviceRegister(enum ad7124_registers reg, uint32_t value) 00329 { 00330 regs[reg].value = value; 00331 return(WriteRegister(regs[reg])); 00332 } 00333 00334 /***************************************************************************//** 00335 * @brief Resets the device. 00336 * 00337 * @param device - The handler of the instance of the driver. 00338 * 00339 * @return Returns 0 for success or negative error code. 00340 *******************************************************************************/ 00341 int32_t AD7124::Reset() 00342 { 00343 int32_t ret = 0; 00344 uint8_t wrBuf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 00345 00346 ret = SPI_Write( wrBuf, 8); 00347 00348 00349 return ret; 00350 } 00351 00352 /***************************************************************************//** 00353 * @brief Waits until the device can accept read and write user actions. 00354 * 00355 * @param device - The handler of the instance of the driver. 00356 * @param timeout - Count representing the number of polls to be done until the 00357 * function returns. 00358 * 00359 * @return Returns 0 for success or negative error code. 00360 *******************************************************************************/ 00361 int32_t AD7124::WaitForSpiReady (uint32_t timeout) 00362 { 00363 ad7124_st_reg *regs; 00364 int32_t ret; 00365 int8_t ready = 0; 00366 00367 regs = this->regs; 00368 00369 while(!ready && --timeout) { 00370 /* Read the value of the Error Register */ 00371 ret = ReadRegister(®s[AD7124_Error]); 00372 if(ret < 0) 00373 return ret; 00374 00375 /* Check the SPI IGNORE Error bit in the Error Register */ 00376 ready = (regs[AD7124_Error].value & 00377 AD7124_ERR_REG_SPI_IGNORE_ERR) == 0; 00378 } 00379 00380 return timeout ? 0 : TIMEOUT; 00381 } 00382 00383 /***************************************************************************//** 00384 * @brief Waits until a new conversion result is available. 00385 * 00386 * @param device - The handler of the instance of the driver. 00387 * @param timeout - Count representing the number of polls to be done until the 00388 * function returns if no new data is available. 00389 * 00390 * @return Returns 0 for success or negative error code. 00391 *******************************************************************************/ 00392 int32_t AD7124::WaitForConvReady (uint32_t timeout) 00393 { 00394 ad7124_st_reg *regs; 00395 int32_t ret; 00396 int8_t ready = 0; 00397 00398 regs = this->regs; 00399 00400 while(!ready && --timeout) { 00401 /* Read the value of the Status Register */ 00402 ret = ReadRegister(®s[AD7124_Status]); 00403 if(ret < 0) 00404 return ret; 00405 00406 /* Check the RDY bit in the Status Register */ 00407 ready = (regs[AD7124_Status].value & 00408 AD7124_STATUS_REG_RDY) == 0; 00409 wait_ms(1); 00410 } 00411 00412 return timeout ? 0 : TIMEOUT; 00413 } 00414 00415 bool AD7124::get_miso() 00416 { 00417 return miso.read(); 00418 } 00419 00420 /***************************************************************************//** 00421 * @brief Reads the conversion result from the device. 00422 * 00423 * @param device - The handler of the instance of the driver. 00424 * @param pData - Pointer to store the read data. 00425 * 00426 * @return Returns 0 for success or negative error code. 00427 *******************************************************************************/ 00428 int32_t AD7124::ReadData ( int32_t* pData) 00429 { 00430 int32_t ret = 0; 00431 uint8_t check8 = 0; 00432 uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 00433 uint8_t i = 0; 00434 uint8_t msgBuf[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 00435 ad7124_st_reg *pReg; 00436 00437 if( !pData) 00438 return INVALID_VAL; 00439 00440 pReg = ®s[AD7124_Data]; 00441 00442 /* Build the Command word */ 00443 buffer[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD | 00444 AD7124_COMM_REG_RA(pReg->addr); 00445 00446 00447 /* Read data from the device */ 00448 ret = SPI_Read(buffer, 00449 ((useCRC != AD7124_DISABLE_CRC) ? pReg->size + 1 00450 : pReg->size) + 2); 00451 00452 if(ret < 0) 00453 return ret; 00454 00455 /* Check the CRC */ 00456 if(check8 == AD7124_USE_CRC) { 00457 msgBuf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD | 00458 AD7124_COMM_REG_RA(pReg->addr); 00459 for(i = 1; i < pReg->size + 2; ++i) { 00460 msgBuf[i] = buffer[i]; 00461 } 00462 check8 = ComputeCRC8 (msgBuf, pReg->size + 3); 00463 } 00464 00465 if(check8 != 0) { 00466 /* ReadRegister checksum failed. */ 00467 return COMM_ERR; 00468 } 00469 00470 /* Build the result */ 00471 *pData = 0; 00472 for(i = 1; i < pReg->size + 2; i++) { 00473 *pData <<= 8; 00474 *pData += buffer[i]; 00475 } 00476 wait_ms(500); 00477 return ret; 00478 } 00479 00480 /***************************************************************************//** 00481 * @brief Computes the CRC checksum for a data buffer. 00482 * 00483 * @param pBuf - Data buffer 00484 * @param bufSize - Data buffer size in bytes 00485 * 00486 * @return Returns the computed CRC checksum. 00487 *******************************************************************************/ 00488 uint8_t AD7124::ComputeCRC8 (uint8_t * pBuf, uint8_t bufSize) 00489 { 00490 uint8_t i = 0; 00491 uint8_t crc = 0; 00492 00493 while(bufSize) { 00494 for(i = 0x80; i != 0; i >>= 1) { 00495 if(((crc & 0x80) != 0) != ((*pBuf & i) != 0)) { /* MSB of CRC register XOR input Bit from Data */ 00496 crc <<= 1; 00497 crc ^= AD7124_CRC8_POLYNOMIAL_REPRESENTATION; 00498 } else { 00499 crc <<= 1; 00500 } 00501 } 00502 pBuf++; 00503 bufSize--; 00504 } 00505 return crc; 00506 } 00507 00508 00509 /***************************************************************************//** 00510 * @brief Updates the device SPI interface settings. 00511 * 00512 * @param device - The handler of the instance of the driver. 00513 * 00514 * @return None. 00515 *******************************************************************************/ 00516 void AD7124::UpdateDevSpiSettings () 00517 { 00518 ad7124_st_reg *regs; 00519 00520 regs = this->regs; 00521 00522 if (regs[AD7124_Error_En].value & AD7124_ERREN_REG_SPI_IGNORE_ERR_EN) { 00523 check_ready = 1; 00524 } else { 00525 check_ready = 0; 00526 } 00527 } 00528 00529 /***************************************************************************//** 00530 * @brief Initializes the AD7124. 00531 * 00532 * @param device - The handler of the instance of the driver. 00533 * @param slave_select - The Slave Chip Select Id to be passed to the SPI calls. 00534 * @param regs - The list of registers of the device (initialized or not) to be 00535 * added to the instance of the driver. 00536 * 00537 * @return Returns 0 for success or negative error code. 00538 *******************************************************************************/ 00539 int32_t AD7124::Setup () 00540 { 00541 int32_t ret; 00542 uint8_t regNr; 00543 00544 00545 spi_rdy_poll_cnt = 25000; 00546 00547 /* Initialize the SPI communication. */ 00548 /*ret = SPI_Init(0, 2500000, 1, 0); 00549 if (ret < 0) 00550 return ret;*/ 00551 00552 /* Reset the device interface.*/ 00553 ret = Reset(); 00554 if (ret < 0) 00555 return ret; 00556 00557 check_ready = 1; 00558 00559 /* Initialize registers AD7124_ADC_Control through AD7124_Filter_7. */ 00560 for(regNr = static_cast<uint8_t>(AD7124_Status); (regNr < static_cast<uint8_t>(AD7124_Offset_0)) && !(ret < 0); 00561 regNr++) { 00562 if (regs[regNr].rw == AD7124_RW) { 00563 ret = WriteRegister(regs[regNr]); 00564 if (ret < 0) 00565 break; 00566 } 00567 00568 /* Get CRC State and device SPI interface settings */ 00569 if (regNr == AD7124_Error_En) { 00570 UpdateDevSpiSettings (); 00571 } 00572 } 00573 00574 return ret; 00575 } 00576 00577 uint8_t AD7124::SPI_Read(uint8_t *data, uint8_t bytes_number) 00578 { 00579 cs = false; 00580 for(uint8_t byte = 0; byte < bytes_number; byte++) { 00581 data[byte] = ad7124.write(data[byte]); 00582 } 00583 cs = true; 00584 return bytes_number; 00585 } 00586 00587 uint8_t AD7124::SPI_Write(uint8_t *data, uint8_t bytes_number) 00588 { 00589 cs = false; 00590 for(uint8_t byte = 0; byte < bytes_number; byte++) { 00591 ad7124.write(data[byte]); 00592 } 00593 00594 cs = true; 00595 return bytes_number; 00596 00597 }
Generated on Tue Jul 12 2022 17:59:51 by
1.7.2
CN0357 - Toxic gas measurement
CN0216 - Weight Scale