Program files for Example program for EVAL-AD7768-1
Dependencies: platform_drivers
Revision 1:260e834a8dc1, committed 2021-09-24
- Comitter:
- Kjansen
- Date:
- Fri Sep 24 15:14:06 2021 +0100
- Parent:
- 0:4f174385050d
- Commit message:
- Adding released source code of ad7768-1
Deleting the redefinition of data_capture_ops
Changed in this revision
--- a/AD7768-1.lib Thu Sep 02 14:02:38 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://os.mbed.com/teams/AnalogDevices/code/AD7768-1/#4a104d4b01bc
--- a/LICENSE.md Thu Sep 02 14:02:38 2021 +0000 +++ b/LICENSE.md Fri Sep 24 15:14:06 2021 +0100 @@ -1,205 +1,14 @@ -Analog Devices, Inc. (ADI) -Source Code Software License Agreement -20210129-LWSCMOS-CTSLA -BEFORE YOU SELECT THE "I ACCEPT" BUTTON AT THE BOTTOM OF THIS WINDOW, CAREFULLY READ THE TERMS AND CONDITIONS SET FORTH BELOW. BY SELECTING THE "I ACCEPT" BUTTON BELOW, OR DOWNLOADING, REPRODUCING, DISTRIBUTING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS SET FORTH BELOW. IF YOU DO NOT AGREE TO ALL OF THE TERMS AND CONDITIONS, SELECT THE 'I DO NOT ACCEPT' BUTTON AND YOU MUST NOT DOWNLOAD, INSTALL OR OTHERWISE USE THE SOFTWARE. - -DOWNLOADING, REPRODUCING, DISTRIBUTING OR OTHERWISE USING THE SOFTWARE CONSTITUTES ACCEPTANCE OF THIS LICENSE. THE SOFTWARE MAY NOT BE USED EXCEPT AS EXPRESSLY AUTHORIZED UNDER THIS LICENSE. - -The software is protected by copyright law and international copyright treaties. - -1. License: Subject to the terms and conditions of this license, the software may be reproduced, modified and distributed in source code and object code form. - -2. Conditions: -(a) Any distribution of the software must include a complete copy of this license and retain all copyright and other proprietary notices. The software that is distributed (including modified versions of the software) shall be subject to the terms and conditions of this license. -(b) The software may not be combined or merged with other software in any manner that would cause the software to become subject to terms and conditions which differ from those of this license. -(c) The software is licensed solely and exclusively for use with processors / products manufactured by or for ADI. -(d) Licensee shall not use the name or any trademark of ADI (including those of its licensors) or any contributor to endorse or promote products without prior written consent of the owner of the name or trademark. The term �contributor� means any person or entity that modifies or distributes the software. -(e) Modified versions of the Software must be conspicuously marked as such. -(f) Use of the software may or may not infringe patent rights of one or more patent holders. This license does not alleviate the obligation to obtain separate licenses from patent holders to use the software. -(g) All rights not expressly granted hereunder are reserved. -(h) This license shall be governed by the laws of Massachusetts, without regard to its conflict of laws rules. The software shall only be used in compliance with all applicable laws and regulations, including without limitation export control laws. - -3. WARRANTY DISCLAIMER: THE SOFTWARE AND ANY RELATED INFORMATION AND/OR ADVICE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT REPRESENTATIONS, GUARANTEES OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, ORAL OR WRITTEN, INCLUDING WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. There is no obligation to provide software support or updates. The Software is not fault-tolerant and is not intended for use in high risk applications, including without limitation in the operation of nuclear facilities, aircraft navigation or control systems, air traffic control, life support machines, weapons systems, autonomous driving or other safety critical automotive applications, or any other application in which the failure of the software could lead to death, personal injury, or severe physical or environmental damages. The software is not authorized to be used under such circumstances. - -4. LIMITATION OF LIABILITY: TO THE MAXIMUM EXTENT PERMITTED BY LAW ADI (INCLUDING ITS LICENSORS) AND CONTRIBUTORS SHALL NOT BE LIABLE FOR ANY DAMAGES ARISING FROM OR RELATED TO THE SOFTWARE, ITS USE OR ANY RELATED INFORMATION AND/OR SERVICES, INCLUDING BUT NOT LIMITED TO ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, EXEMPLARY, CONSEQUENTIAL OR ANALOGOUS DAMAGES (INCLUDING WITHOUT LIMITATION ANY DAMAGES RESULTING FROM LOSS OF USE, DATA, REVENUE, PROFITS, OR SAVINGS, COMPUTER DAMAGE OR ANY OTHER CAUSE), UNDER ANY LEGAL THEORY (INCLUDING WITHOUT LIMITATION CONTRACT, WARRANTY, TORT, NEGLIGENCE, STRICT OR PRODUCT LIABILITY), EVEN IF IT HAS BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. Some jurisdictions do not permit the exclusion or limitation of liability for consequential, incidental or other damages, and, as such, some portion of the above limitation may not apply. In such jurisdictions, liability is limited to the greatest extent permitted by law. -5. Third Party Software: The software may be accompanied by or include software made available by one or more third parties (Third Party Software). Each portion of Third Party Software is subject to its own separate software license terms and conditions (�Third Party Licenses�). The Third Party Licenses for Third Party Software delivered with the software are set forth or identified (by url or otherwise) in (i) Appendix A to this license (if any), (ii) the applicable software header or footer text, (iii) a text file located in the directory of the applicable Third Party Software component and/or (iv) such other location customarily used for licensing terms. The use of each portion of Third Party Software is subject to the Third Party Licenses, and you agree that your use of any Third Party Software is bound by the applicable Third Party License. You agree to review and comply with all applicable Third Party Licenses prior to any use or distribution of any Third Party Software. Third Party Software is provided on an �as is� basis without any representation, warranty or liability of any kind. ADI (including its licensors) and contributors shall have no liability or responsibility for the operation or performance of the Third Party Software and shall not be liable for any damages, costs, or expenses, direct or indirect, arising out of the performance or failure to perform of the Third Party Software. ADI (including its licensors) and contributors shall be entitled to the benefit of any and all limitations of liability and disclaimers of warranties contained in the Third Party Licenses. For the avoidance of doubt, this license does not alter, limit or expand the terms and conditions of, or rights granted to you pursuant to, Third Party Licenses. - -Appendix A - Third Party License - -Mbed-OS - -Download page:https://github.com/ARMmbed/mbed-os/ -Online license: https://github.com/ARMmbed/mbed-os/blob/master/LICENSE-apache-2.0.txt - - -Apache License 2.0 - -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. +Copyright (c) 2020 Analog Devices, Inc. All rights reserved. -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + - 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. + - Modified versions of the software must be conspicuously marked as such. + - This software is licensed solely and exclusively for use with processors/products manufactured by or for Analog Devices, Inc. + - This software may not be combined or merged with other code in any manner that would cause the software to become subject to terms and conditions which differ from those listed here. + - Neither the name of Analog Devices, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + - The use of this software may or may not infringe the patent rights of one or more patent holders. This license does not release you from the requirement that you obtain separate licenses from these patent holders to use this software. -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. +THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; 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. -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - - +2020-02-24-7CBSD SLA
--- a/README.txt Thu Sep 02 14:02:38 2021 +0000 +++ b/README.txt Fri Sep 24 15:14:06 2021 +0100 @@ -1,45 +1,42 @@ Evaluation Boards/Products Supported ------------------------------------ -EVAL-AD1234 (AD1234) -EVAL-AD1256 (AD1256) -<< add more here >> - +EVAL-AD7768-1 + Overview -------- -These code files provide drivers to interface with AD1234 and communicate with -EVAL-AD1234 board. This code was developed and tested on SDP-K1 controller board -https://os.mbed.com/platforms/SDP_K1/. - -Product details: https://www.analog.com/en/products/ad1234.html -Eval board details: https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/EVAL-AD1234.html - - +This is a IIO based firmware application to evalute the AD7768-1 device. +This code was developed and tested on SDP-K1 controller board: https://os.mbed.com/platforms/SDP_K1/. +Use of Mbed platform allows code to port on other Mbed supported target boards with little or no modifications. + +Product details: https://www.analog.com/en/products/ad7768-1.html +Product Evaluation board details: https://www.analog.com/en/design-center/reference-designs/circuits-from-the-lab/cn0540.html +User Guide for this code: https://wiki.analog.com/resources/eval/user-guides/circuits-from-the-lab/cn0540 +Communication Protocol: SPI + + Hardware Setup -------------- -Required: SDP-K1, EVAL-AD1234, USB cable, 12 V power supply, 60 MHz external -clock supply. -Plug in the EVAL-AD124 board on SDP-K1 board (or any other Mbed enabled -controller board) using the SDP connector and screws. +Required: SDP-K1 (or alternative Mbed enabled controller board), EVAL-CN0540-ARDZ board and USB cable. +Plug in the EVAL-CN0540-ARDZ board on SDP-K1 board (or any other Mbed enabled controller board) Connect SDP-K1 board to the PC using the USB cable. - - + + How to Get Started ------------------ Open Mbed online compiler. https://ide.mbed.com/compiler -Import Code into compiler from here: https://os.mbed.com/teams/AnalogDevices/code/EVAL-AD1234/ -instructions on how to import code are here: https://os.mbed.com/docs/mbed-os/v5.12/tools/importing-code.html -Compile code. Drag and drop binary into SDP-K1 controller board. Find detailed instructions -here: https://os.mbed.com/docs/mbed-os/v5.12/tools/getting-your-program-on-your-board.html -Open Tera Term (or alternative), select 9600 baud rate, and the applicable COM port to see the -list of options. - -A detailed user guide on how to use SDP-K1 board on Mbed platform is available -here: https://wiki.analog.com/resources/tools-software/mbed - - +Import Code into compiler from here: https://os.mbed.com/teams/AnalogDevices/code/EVAL-AD7768-1/ +instructions on how to import code are here: https://os.mbed.com/docs/mbed-os/v6.8/build-tools/importing-code.html +Compile code. Drag and drop binary into SDP-K1 controller board. Find detailed +instructions here: https://os.mbed.com/docs/mbed-os/v6.8/build-tools/getting-your-program-on-your-board.html +Open Tera Term (or alternative), select 230400 baud rate, and the applicable COM +port to see the list of options. + + Notes ----- -If using Win 7, install serial drivers for Mbed. https://os.mbed.com/docs/mbed-os/v5.12/tutorials/windows-serial-driver.html +If using Win 7, install serial drivers for Mbed. https://os.mbed.com/docs/mbed-os/v6.8/program-setup/windows-serial-driver.html A detailed user guide on SDP-K1 controller board is available here https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/SDP-K1.html. - - \ No newline at end of file + + +Copyright (c) 2021 Analog Devices, Inc. All rights reserved. +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/.mbedignore Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,62 @@ +no-OS/ad5758-sdz/ +no-OS/AD6673-EBZ/ +no-OS/AD9250-EBZ/ +no-OS/adum7701_fmc/ +no-OS/ci/ +no-OS/common_drivers/ +no-OS/device_drivers/ +no-OS/doc/ +no-OS/drivers/accel/ +no-OS/drivers/afe/ +no-OS/drivers/axi_core/ +no-OS/drivers/adc/ad4* +no-OS/drivers/adc/ad6* +no-OS/drivers/adc/ad70* +no-OS/drivers/adc/ad71* +no-OS/drivers/adc/ad72* +no-OS/drivers/adc/ad73* +no-OS/drivers/adc/ad74* +no-OS/drivers/adc/ad76* +no-OS/drivers/adc/ad776* +no-OS/drivers/adc/ad7779/ +no-OS/drivers/adc/ad7780/ +no-OS/drivers/adc/ad7799/ +no-OS/drivers/adc/ad79* +no-OS/drivers/adc/ad9* +no-OS/drivers/adc/adaq7980/ +no-OS/drivers/adc/ltc2312/ +no-OS/drivers/adc/adc_demo/ +no-OS/drivers/adc-dac/ +no-OS/drivers/instr-amplif/ +no-OS/drivers/cdc/ +no-OS/drivers/dac/ +no-OS/drivers/ecg/ +no-OS/drivers/frequency/ +no-OS/drivers/gpio/ +no-OS/drivers/gyro/ +no-OS/drivers/i2c/ +no-OS/drivers/impedance-analyzer/ +no-OS/drivers/io-expander/ +no-OS/drivers/mux/ +no-OS/drivers/photo-electronic/ +no-OS/drivers/platform/ +no-OS/drivers/potentiometer/ +no-OS/drivers/rf-transceiver/ +no-OS/drivers/sd-card/ +no-OS/drivers/spi/ +no-OS/drivers/temperature/ +no-OS/iio/ +no-OS/legacy/ +no-OS/libraries/fatfs/ +no-OS/libraries/mbedtls/ +no-OS/libraries/mqtt/ +no-OS/util/crc8.c +no-OS/util/crc16.c +no-OS/util/crc24.c +no-OS/network/ +no-OS/projects/ +no-OS/scripts/ +no-OS/tools/ +no-OS/v4l2_config/ +libtinyiiod/ci/ +libtinyiiod/example.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681.c Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,1847 @@ +/***************************************************************************//** + * @file ad77681.c + * @brief Implementation of AD7768-1 Driver. + * @author SPopa (stefan.popa@analog.com) +******************************************************************************** + * Copyright 2017(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, 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. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include "stdio.h" +#include "stdlib.h" +#include "stdbool.h" +#include <string.h> +#include "ad77681.h" +#include "error.h" +#include "delay.h" + +/******************************************************************************/ +/************************** Functions Implementation **************************/ +/******************************************************************************/ +/** + * Compute CRC8 checksum. + * @param data - The data buffer. + * @param data_size - The size of the data buffer. + * @param init_val - CRC initial value. + * @return CRC8 checksum. + */ +uint8_t ad77681_compute_crc8(uint8_t *data, + uint8_t data_size, + uint8_t init_val) +{ + uint8_t i; + uint8_t crc = init_val; + + while (data_size) { + for (i = 0x80; i != 0; i >>= 1) { + if (((crc & 0x80) != 0) != ((*data & i) != 0)) { + crc <<= 1; + crc ^= AD77681_CRC8_POLY; + } else + crc <<= 1; + } + data++; + data_size--; + } + return crc; +} + +/** + * Compute XOR checksum. + * @param data - The data buffer. + * @param data_size - The size of the data buffer. + * @param init_val - CRC initial value. + * @return XOR checksum. + */ +uint8_t ad77681_compute_xor(uint8_t *data, + uint8_t data_size, + uint8_t init_val) +{ + uint8_t crc = init_val; + uint8_t buf[3]; + uint8_t i; + + for (i = 0; i < data_size; i++) { + buf[i] = *data; + crc ^= buf[i]; + data++; + } + return crc; +} + +/** + * Read from device. + * @param dev - The device structure. + * @param reg_addr - The register address. + * @param reg_data - The register data. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_spi_reg_read(struct ad77681_dev *dev, + uint8_t reg_addr, + uint8_t *reg_data) +{ + int32_t ret; + uint8_t crc; + uint8_t buf[3], crc_buf[2]; + uint8_t buf_len = (dev->crc_sel == AD77681_NO_CRC) ? 2 : 3; + + buf[0] = AD77681_REG_READ(reg_addr); + buf[1] = 0x00; + + ret = spi_write_and_read(dev->spi_desc, buf, buf_len); + if (ret < 0) + return ret; + + /* XOR or CRC checksum for read transactions */ + if (dev->crc_sel != AD77681_NO_CRC) { + crc_buf[0] = AD77681_REG_READ(reg_addr); + crc_buf[1] = buf[1]; + + if (dev->crc_sel == AD77681_XOR) + /* INITIAL_CRC is 0, when ADC is not in continuous-read mode */ + crc = ad77681_compute_xor(crc_buf, 2, INITIAL_CRC); + else if(dev->crc_sel == AD77681_CRC) + /* INITIAL_CRC is 0, when ADC is not in continuous-read mode */ + crc = ad77681_compute_crc8(crc_buf, 2, INITIAL_CRC); + + /* In buf[2] is CRC from the ADC */ + if (crc != buf[2]) + ret = FAILURE; +#ifdef CRC_DEBUG + printf("\n%x\t%x\tCRC/XOR: %s\n", crc, + buf[2], ((crc != buf[2]) ? "FAULT" : "OK")); +#endif /* CRC_DEBUG */ + } + + reg_data[0] = AD77681_REG_READ(reg_addr); + memcpy(reg_data + 1, buf + 1, ARRAY_SIZE(buf) - 1); + + return ret; +} + +/** + * Write to device. + * @param dev - The device structure. + * @param reg_addr - The register address. + * @param reg_data - The register data. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_spi_reg_write(struct ad77681_dev *dev, + uint8_t reg_addr, + uint8_t reg_data) +{ + uint8_t buf[3]; + /* Buffer length in case of checksum usage */ + uint8_t buf_len = (dev->crc_sel == AD77681_NO_CRC) ? 2 : 3; + + buf[0] = AD77681_REG_WRITE(reg_addr); + buf[1] = reg_data; + + /* CRC only for read transactions, CRC and XOR for write transactions*/ + if (dev->crc_sel != AD77681_NO_CRC) + buf[2] = ad77681_compute_crc8(buf, 2, INITIAL_CRC); + + return spi_write_and_read(dev->spi_desc, buf, buf_len); +} + +/** + * SPI read from device using a mask. + * @param dev - The device structure. + * @param reg_addr - The register address. + * @param mask - The mask. + * @param data - The register data. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_spi_read_mask(struct ad77681_dev *dev, + uint8_t reg_addr, + uint8_t mask, + uint8_t *data) +{ + uint8_t reg_data[3]; + int32_t ret; + + ret = ad77681_spi_reg_read(dev, reg_addr, reg_data); + *data = (reg_data[1] & mask); + + return ret; +} + +/** + * SPI write to device using a mask. + * @param dev - The device structure. + * @param reg_addr - The register address. + * @param mask - The mask. + * @param data - The register data. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_spi_write_mask(struct ad77681_dev *dev, + uint8_t reg_addr, + uint8_t mask, + uint8_t data) +{ + uint8_t reg_data[3]; + int32_t ret; + + ret = ad77681_spi_reg_read(dev, reg_addr, reg_data); + reg_data[1] &= ~mask; + reg_data[1] |= data; + ret |= ad77681_spi_reg_write(dev, reg_addr, reg_data[1]); + + return ret; +} + +/** + * Helper function to get the number of rx bytes + * @param dev - The device structure. + * @return rx_buf_len - the number of rx bytes + */ +uint8_t ad77681_get_rx_buf_len(struct ad77681_dev *dev) +{ + uint8_t rx_buf_len = 0; + uint8_t data_len = 0; + uint8_t crc = 0; + uint8_t status_bit = 0; + + data_len = 3; + crc = (dev->crc_sel == AD77681_NO_CRC) ? 0 : 1; // 1 byte for crc + status_bit = dev->status_bit; // one byte for status + + rx_buf_len = data_len + crc + status_bit; + + return rx_buf_len; +} + +/** + * Helper function to get the number of SPI 16bit frames for INTERRUPT ADC DATA READ + * @param dev - The device structure. + * @return frame_16bit - the number of 16 bit SPI frames + */ +uint8_t ad77681_get_frame_byte(struct ad77681_dev *dev) +{ + /* number of 8bit frames */ + uint8_t frame_bytes; + if (dev->conv_len == AD77681_CONV_24BIT) + frame_bytes = 3; + else + frame_bytes = 2; + if (dev->crc_sel != AD77681_NO_CRC) + frame_bytes++; + if (dev->status_bit) + frame_bytes++; + + dev->data_frame_byte = frame_bytes; + + return frame_bytes; +} + +/** + * Read conversion result from device. + * @param dev - The device structure. + * @param adc_data - The conversion result data + * @param mode - Data read mode + * Accepted values: AD77681_REGISTER_DATA_READ + * AD77681_CONTINUOUS_DATA_READ + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_spi_read_adc_data(struct ad77681_dev *dev, + uint8_t *adc_data, + enum ad77681_data_read_mode mode) +{ + uint8_t buf[6], crc_xor, add_buff; + int32_t ret; + + if (mode == AD77681_REGISTER_DATA_READ) { + buf[0] = AD77681_REG_READ(AD77681_REG_ADC_DATA); + add_buff = 1; + } else { + buf[0] = 0x00; + add_buff = 0; + } + buf[1] = 0x00; /* added 2 more array places for max data length read */ + buf[2] = 0x00; /* For register data read */ + buf[3] = 0x00; /* register address + 3 bytes of data (24bit format) + Status bit + CRC */ + buf[4] = 0x00; /* For continuous data read */ + buf[5] = 0x00; /* 3 bytes of data (24bit format) + Status bit + CRC */ + + + ret = spi_write_and_read(dev->spi_desc, buf, dev->data_frame_byte + add_buff); + if (ret < 0) + return ret; + + if (dev->crc_sel != AD77681_NO_CRC) { + if (dev->crc_sel == AD77681_CRC) + crc_xor = ad77681_compute_crc8(buf + add_buff, dev->data_frame_byte - 1, + INITIAL_CRC_CRC8); + else + crc_xor = ad77681_compute_xor(buf + add_buff, dev->data_frame_byte - 1, + INITIAL_CRC_XOR); + + if (crc_xor != buf[dev->data_frame_byte - (1 - add_buff)]) { + printf("%s: CRC Error.\n", __func__); + ret = FAILURE; + } +#ifdef CRC_DEBUG + printf("\n%x\t%x\tCRC/XOR: %s\n", crc_xor, + buf[dev->data_frame_byte - (1 - add_buff)], + ((crc_xor != buf[dev->data_frame_byte - (1 - add_buff)]) ? "FAULT" : "OK")); +#endif /* CRC_DEBUG */ + } + + /* Fill the adc_data buffer */ + memcpy(adc_data, buf, ARRAY_SIZE(buf)); + + return ret; +} + +/** + * CRC and status bit handling after each readout form the ADC + * @param dev - The device structure. + * @param *data_buffer - 16-bit buffer readed from the ADC containing the CRC, + * data and the stattus bit. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_CRC_status_handling(struct ad77681_dev *dev, + uint16_t *data_buffer) +{ + int32_t ret = 0; + uint8_t status_byte = 0, checksum = 0, checksum_byte = 0, checksum_buf[5], + checksum_length = 0, i; + char print_buf[50]; + + /* Status bit handling */ + if (dev->status_bit) { + /* 24bit ADC data + 8bit of status = 2 16bit frames */ + if (dev->conv_len == AD77681_CONV_24BIT) + status_byte = data_buffer[1] & 0xFF; + /* 16bit ADC data + 8bit of status = 2 16bit frames */ + else + status_byte = data_buffer[1] >> 8; + } + + /* Checksum bit handling */ + if (dev->crc_sel != AD77681_NO_CRC) { + if ((dev->status_bit == true) & (dev->conv_len == AD77681_CONV_24BIT)) { + /* 24bit ADC data + 8bit of status + 8bit of CRC = 3 16bit frames */ + checksum_byte = data_buffer[2] >> 8; + checksum_length = 4; + } else if ((dev->status_bit == true) & (dev->conv_len == AD77681_CONV_16BIT)) { + /* 16bit ADC data + 8bit of status + 8bit of CRC = 2 16bit frames */ + checksum_byte = data_buffer[1] & 0xFF; + checksum_length = 3; + } else if ((dev->status_bit == false) & (dev->conv_len == AD77681_CONV_24BIT)) { + /* 24bit ADC data + 8bit of CRC = 2 16bit frames */ + checksum_byte = data_buffer[1] & 0xFF; + checksum_length = 3; + } else if ((dev->status_bit == false) & (dev->conv_len == AD77681_CONV_16BIT)) { + /* 16bit ADC data + 8bit of CRC = 2 16bit frames */ + checksum_byte = data_buffer[1] >> 8; + checksum_length = 2; + } + + for (i = 0; i < checksum_length; i++) { + if (i % 2) + checksum_buf[i] = data_buffer[i / 2] & 0xFF; + else + checksum_buf[i] = data_buffer[i / 2] >> 8; + } + + if (dev->crc_sel == AD77681_CRC) + checksum = ad77681_compute_crc8(checksum_buf, checksum_length, + INITIAL_CRC_CRC8); + else if (dev->crc_sel == AD77681_XOR) + checksum = ad77681_compute_xor(checksum_buf, checksum_length, INITIAL_CRC_XOR); + + if (checksum != checksum_byte) + ret = FAILURE; + +#ifdef CRC_DEBUG + + char ok[3] = { 'O', 'K' }, fault[6] = { 'F', 'A', 'U', 'L', 'T' }; + sprintf(print_buf, "\n%x\t%x\t%x\tCRC %s", checksum_byte, checksum, status_byte, + ((ret == FAILURE) ? (fault) : (ok))); + printf(print_buf); + +#endif /* CRC_DEBUG */ + } + + return ret; +} + +/** + * Conversion from measured data to voltage + * @param dev - The device structure. + * @param raw_code - ADC raw code measurements + * @param voltage - Converted ADC code to voltage + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_data_to_voltage(struct ad77681_dev *dev, + uint32_t *raw_code, + double *voltage) +{ + int32_t converted_data; + + if (*raw_code & 0x800000) + converted_data = (int32_t)((0xFF << 24) | *raw_code); + else + converted_data = (int32_t)((0x00 << 24) | *raw_code); + + /* ((2*Vref)*code)/2^24 */ + *voltage = (double)(((2.0 * (((double)(dev->vref)) / 1000.0)) / + AD7768_FULL_SCALE) * converted_data); + + return SUCCESS; +} + +/** + * Update ADCs sample rate depending on MCLK, MCLK_DIV and filter settings + * @param dev - The device structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_update_sample_rate(struct ad77681_dev *dev) +{ + uint8_t mclk_div; + uint16_t osr; + + /* Finding out MCLK divider */ + switch (dev->mclk_div) { + case AD77681_MCLK_DIV_16: + mclk_div = 16; + break; + case AD77681_MCLK_DIV_8: + mclk_div = 8; + break; + case AD77681_MCLK_DIV_4: + mclk_div = 4; + break; + case AD77681_MCLK_DIV_2: + mclk_div = 2; + break; + default: + return FAILURE; + break; + } + + /* Finding out decimation ratio */ + switch (dev->filter) { + case (AD77681_SINC5 | AD77681_FIR): + /* Decimation ratio of FIR or SINC5 (x32 to x1024) */ + switch (dev->decimate) { + case AD77681_SINC5_FIR_DECx32: + osr = 32; + break; + case AD77681_SINC5_FIR_DECx64: + osr = 64; + break; + case AD77681_SINC5_FIR_DECx128: + osr = 128; + break; + case AD77681_SINC5_FIR_DECx256: + osr = 256; + break; + case AD77681_SINC5_FIR_DECx512: + osr = 512; + break; + case AD77681_SINC5_FIR_DECx1024: + osr = 1024; + break; + default: + return FAILURE; + break; + } + break; + /* Decimation ratio of SINC5 x8 */ + case AD77681_SINC5_DECx8: + osr = 8; + break; + /* Decimation ratio of SINC5 x16 */ + case AD77681_SINC5_DECx16: + osr = 16; + break; + /* Decimation ratio of SINC3 */ + case AD77681_SINC3: + osr = (dev->sinc3_osr + 1) * 32; + break; + default: + return FAILURE; + break; + } + + /* Sample rate to Hz */ + dev->sample_rate = (dev->mclk / (osr*mclk_div)) * 1000; + + return SUCCESS; +} + +/** + * Get SINC3 filter oversampling ratio register value based on user's inserted + * output data rate ODR + * @param dev - The device structure. + * @param sinc3_dec_reg - Returned closest value of SINC3 register + * @param sinc3_odr - Desired output data rage + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_SINC3_ODR(struct ad77681_dev *dev, + uint16_t *sinc3_dec_reg, + float sinc3_odr) +{ + uint8_t mclk_div; + float odr; + + if (sinc3_odr < 0) + return FAILURE; + + switch (dev->mclk_div) { + case AD77681_MCLK_DIV_16: + mclk_div = 16; + break; + case AD77681_MCLK_DIV_8: + mclk_div = 8; + break; + case AD77681_MCLK_DIV_4: + mclk_div = 4; + break; + case AD77681_MCLK_DIV_2: + mclk_div = 2; + break; + default: + return FAILURE; + break; + } + + odr = ((float)(dev->mclk * 1000.0) / (sinc3_odr * (float)(32 * mclk_div))) - 1; + + /* Sinc3 oversamplig register has 13 bits, biggest value = 8192 */ + if (odr < 8193) + *sinc3_dec_reg = (uint16_t)(odr); + else + return FAILURE; + + return SUCCESS; +} + +/** + * Set the power consumption mode of the ADC core. + * @param dev - The device structure. + * @param mode - The power mode. + * Accepted values: AD77681_ECO + * AD77681_MEDIAN + * AD77681_FAST + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_power_mode(struct ad77681_dev *dev, + enum ad77681_power_mode mode) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_POWER_CLOCK, + AD77681_POWER_CLK_PWRMODE_MSK, + AD77681_POWER_CLK_PWRMODE(mode)); + + if (ret == SUCCESS) + dev->power_mode = mode; + + return ret; +} + +/** + * Set the MCLK divider. + * @param dev - The device structure. + * @param clk_div - The MCLK divider. + * Accepted values: AD77681_MCLK_DIV_16 + * AD77681_MCLK_DIV_8 + * AD77681_MCLK_DIV_4 + * AD77681_MCLK_DIV_2 + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_mclk_div(struct ad77681_dev *dev, + enum ad77681_mclk_div clk_div) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_POWER_CLOCK, + AD77681_POWER_CLK_MCLK_DIV_MSK, + AD77681_POWER_CLK_MCLK_DIV(clk_div)); + + if (ret == SUCCESS) + dev->mclk_div = clk_div; + + return ret; +} + +/** + * Set the VCM output. + * @param dev - The device structure. + * @param VCM_out - The VCM output voltage. + * Accepted values: AD77681_VCM_HALF_VCC + * AD77681_VCM_2_5V + * AD77681_VCM_2_05V + * AD77681_VCM_1_9V + * AD77681_VCM_1_65V + * AD77681_VCM_1_1V + * AD77681_VCM_0_9V + * AD77681_VCM_OFF + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_VCM_output(struct ad77681_dev *dev, + enum ad77681_VCM_out VCM_out) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_ANALOG2, + AD77681_ANALOG2_VCM_MSK, + AD77681_ANALOG2_VCM(VCM_out)); + + if (ret == SUCCESS) + dev->VCM_out = VCM_out; + + return ret; +} + +/** + * Set the AIN- precharge buffer. + * @param dev - The device structure. + * @param AINn - The negative analog input precharge buffer selector + * Accepted values: AD77681_AINn_ENABLED + * AD77681_AINn_DISABLED + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_AINn_buffer(struct ad77681_dev *dev, + enum ad77681_AINn_precharge AINn) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_ANALOG, + AD77681_ANALOG_AIN_BUF_NEG_OFF_MSK, + AD77681_ANALOG_AIN_BUF_NEG_OFF(AINn)); + + if (ret == SUCCESS) + dev->AINn = AINn; + + return ret; +} + +/** + * Set the AIN+ precharge buffer. + * @param dev - The device structure. + * @param AINp - The positive analog input precharge buffer selector + * Accepted values: AD77681_AINp_ENABLED + * AD77681_AINp_DISABLED + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_AINp_buffer(struct ad77681_dev *dev, + enum ad77681_AINp_precharge AINp) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_ANALOG, + AD77681_ANALOG_AIN_BUF_POS_OFF_MSK, + AD77681_ANALOG_AIN_BUF_POS_OFF(AINp)); + + if (ret == SUCCESS) + dev->AINp = AINp; + + return ret; +} + +/** + * Set the REF- reference buffer + * @param dev - The device structure. + * @param REFn - The negative reference buffer selector + * Accepted values: AD77681_BUFn_DISABLED + * AD77681_BUFn_ENABLED + * AD77681_BUFn_FULL_BUFFER_ON + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_REFn_buffer(struct ad77681_dev *dev, + enum ad77681_REFn_buffer REFn) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_ANALOG, + AD77681_ANALOG_REF_BUF_NEG_MSK, + AD77681_ANALOG_REF_BUF_NEG(REFn)); + + if (ret == SUCCESS) + dev->REFn = REFn; + + return ret; +} + +/** + * Set the REF+ reference buffer + * @param dev - The device structure. + * @param REFp - The positive reference buffer selector + * Accepted values: AD77681_BUFp_DISABLED + * AD77681_BUFp_ENABLED + * AD77681_BUFp_FULL_BUFFER_ON + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_REFp_buffer(struct ad77681_dev *dev, + enum ad77681_REFp_buffer REFp) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_ANALOG, + AD77681_ANALOG_REF_BUF_POS_MSK, + AD77681_ANALOG_REF_BUF_POS(REFp)); + + if (ret == SUCCESS) + dev->REFp = REFp; + else + return FAILURE; + + return ret; +} + +/** + * Set filter type and decimation ratio + * @param dev - The device structure. + * @param decimate - Decimation ratio of filter + * Accepted values: AD77681_SINC5_FIR_DECx32 + * AD77681_SINC5_FIR_DECx64 + * AD77681_SINC5_FIR_DECx128 + * AD77681_SINC5_FIR_DECx256 + * AD77681_SINC5_FIR_DECx512 + * AD77681_SINC5_FIR_DECx1024 + * @param filter - Select filter type + * Accepted values: AD77681_SINC5 + * AD77681_SINC5_DECx8 + * AD77681_SINC5_DECx16 + * AD77681_SINC3 + * AD77681_FIR + * @param sinc3_osr - Select decimation ratio for SINC3 filter separately as + * integer from 0 to 8192. + * See the AD7768-1 datasheet for more info + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_filter_type(struct ad77681_dev *dev, + enum ad77681_sinc5_fir_decimate decimate, + enum ad77681_filter_type filter, + uint16_t sinc3_osr) +{ + int32_t ret; + + ret = ad77681_spi_reg_write(dev, AD77681_REG_DIGITAL_FILTER, 0x00); + + /* SINC5 for OSR 8x and 16x*/ + if ((filter == AD77681_SINC5_DECx8) || (filter == AD77681_SINC5_DECx16)) { + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_DIGITAL_FILTER, + AD77681_DIGI_FILTER_FILTER_MSK, + AD77681_DIGI_FILTER_FILTER(filter)); + /* SINC5 and FIR for osr 32x to 1024x */ + } else if ((filter == AD77681_SINC5) || (filter == AD77681_FIR)) { + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_DIGITAL_FILTER, + AD77681_DIGI_FILTER_FILTER_MSK, + AD77681_DIGI_FILTER_FILTER(filter)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_DIGITAL_FILTER, + AD77681_DIGI_FILTER_DEC_RATE_MSK, + AD77681_DIGI_FILTER_DEC_RATE(decimate)); + /* SINC3*/ + } else { + uint8_t sinc3_LSB = 0, sinc3_MSB = 0; + + sinc3_MSB = sinc3_osr >> 8; + sinc3_LSB = sinc3_osr & 0x00FF; + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_DIGITAL_FILTER, + AD77681_DIGI_FILTER_FILTER_MSK, + AD77681_DIGI_FILTER_FILTER(filter)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SINC3_DEC_RATE_MSB, + AD77681_SINC3_DEC_RATE_MSB_MSK, + AD77681_SINC3_DEC_RATE_MSB(sinc3_MSB)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SINC3_DEC_RATE_LSB, + AD77681_SINC3_DEC_RATE_LSB_MSK, + AD77681_SINC3_DEC_RATE_LSB(sinc3_LSB)); + } + + if ( ret == SUCCESS) { + dev->decimate = decimate; + dev->filter = filter; + /* Sync pulse after each filter change */ + ret |= ad77681_initiate_sync(dev); + } + + return ret; +} + +/** + * Enable 50/60 Hz rejection + * @param dev - The device structure. + * @param enable - The positive reference buffer selector + * Accepted values: true + * false + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_50HZ_rejection(struct ad77681_dev *dev, + uint8_t enable) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_DIGITAL_FILTER, + AD77681_DIGI_FILTER_60HZ_REJ_EN_MSK, + AD77681_DIGI_FILTER_60HZ_REJ_EN(enable)); + + return ret; +} + +/** + * Set the REF- reference buffer + * @param dev - The device structure. + * @param continuous_enable - Continous read enable + * Accepted values: AD77681_CONTINUOUS_READ_ENABLE + * AD77681_CONTINUOUS_READ_DISABLE + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_continuos_read(struct ad77681_dev *dev, + enum ad77681_continuous_read continuous_enable) +{ + int32_t ret; + + if (continuous_enable) { + ret = ad77681_spi_write_mask(dev, + AD77681_REG_INTERFACE_FORMAT, + AD77681_INTERFACE_CONT_READ_MSK, + AD77681_INTERFACE_CONT_READ_EN(continuous_enable)); + } else { + /* To exit the continuous read mode, a key 0x6C must be + written into the device over the SPI*/ + uint8_t end_key = EXIT_CONT_READ; + ret = spi_write_and_read(dev->spi_desc, &end_key, 1); + } + + return ret; +} + +/** + * Power down / power up the device + * @param dev - The device structure. + * @param sleep_wake - Power down, or power up the ADC + * Accepted values: AD77681_SLEEP + * AD77681_WAKE + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_power_down(struct ad77681_dev *dev, + enum ad77681_sleep_wake sleep_wake) +{ + int32_t ret; + + if (sleep_wake == AD77681_SLEEP) { + ret = ad77681_spi_reg_write(dev, AD77681_REG_POWER_CLOCK, + AD77681_POWER_CLK_POWER_DOWN); + } else { + /* Wake up the ADC over SPI, by sending a wake-up sequence: + 1 followed by 63 zeroes and CS hold low*/ + uint8_t wake_sequence[8] = { 0 }; + /* Insert '1' to the beginning of the wake_sequence*/ + wake_sequence[0] = 0x80; + ret = spi_write_and_read(dev->spi_desc, wake_sequence, + ARRAY_SIZE(wake_sequence)); + } + + return ret; +} + +/** + * Conversion mode and source select + * @param dev - The device structure. + * @param conv_mode - Sets the conversion mode of the ADC + * Accepted values: AD77681_CONV_CONTINUOUS + * AD77681_CONV_ONE_SHOT + * AD77681_CONV_SINGLE + * AD77681_CONV_PERIODIC + * @param diag_mux_sel - Selects which signal to route through diagnostic mux + * Accepted values: AD77681_TEMP_SENSOR + * AD77681_AIN_SHORT + * AD77681_POSITIVE_FS + * AD77681_NEGATIVE_FS + * @param conv_diag_sel - Select the input for conversion as AIN or diagnostic mux + * Accepted values: true + * false + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_conv_mode(struct ad77681_dev *dev, + enum ad77681_conv_mode conv_mode, + enum ad77681_conv_diag_mux diag_mux_sel, + bool conv_diag_sel) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_CONVERSION, + AD77681_CONVERSION_MODE_MSK, + AD77681_CONVERSION_MODE(conv_mode)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_CONVERSION, + AD77681_CONVERSION_DIAG_MUX_MSK, + AD77681_CONVERSION_DIAG_MUX_SEL(diag_mux_sel)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_CONVERSION, + AD77681_CONVERSION_DIAG_SEL_MSK, + AD77681_CONVERSION_DIAG_SEL(conv_diag_sel)); + + if (ret == SUCCESS) { + dev->conv_mode = conv_mode; + dev->diag_mux_sel = diag_mux_sel; + dev->conv_diag_sel = conv_diag_sel; + } + + return ret; +} + +/** + * Set the Conversion Result Output Length. + * @param dev - The device structure. + * @param conv_len - The MCLK divider. + * Accepted values: AD77681_CONV_24BIT + * AD77681_CONV_16BIT + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_convlen(struct ad77681_dev *dev, + enum ad77681_conv_len conv_len) +{ + int32_t ret; + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_INTERFACE_FORMAT, + AD77681_INTERFACE_CONVLEN_MSK, + AD77681_INTERFACE_CONVLEN(conv_len)); + + if (ret == SUCCESS) { + dev->conv_len = conv_len; + ad77681_get_frame_byte(dev); + } + + return ret; +} + +/** + * Activates CRC on all SPI transactions and + * Selects CRC method as XOR or 8-bit polynomial + * @param dev - The device structure. + * @param crc_sel - The CRC type. + * Accepted values: AD77681_CRC + * AD77681_XOR + * AD77681_NO_CRC + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_crc_sel(struct ad77681_dev *dev, + enum ad77681_crc_sel crc_sel) +{ + int32_t ret; + + if (crc_sel == AD77681_NO_CRC) { + ret = ad77681_spi_write_mask(dev, + AD77681_REG_INTERFACE_FORMAT, + AD77681_INTERFACE_CRC_EN_MSK, + AD77681_INTERFACE_CRC_EN(0)); + } else { + ret = ad77681_spi_write_mask(dev, + AD77681_REG_INTERFACE_FORMAT, + AD77681_INTERFACE_CRC_EN_MSK, + AD77681_INTERFACE_CRC_EN(1)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_INTERFACE_FORMAT, + AD77681_INTERFACE_CRC_TYPE_MSK, + AD77681_INTERFACE_CRC_TYPE(crc_sel)); + } + + if (ret == SUCCESS) { + dev->crc_sel = crc_sel; + ad77681_get_frame_byte(dev); + } + + return ret; +} + +/** + * Enables Status bits output + * @param dev - The device structure. + * @param status_bit - enable or disable status bit + * Accepted values: true + * false + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_set_status_bit(struct ad77681_dev *dev, + bool status_bit) +{ + int32_t ret; + + // Set status bit + ret = ad77681_spi_write_mask(dev, + AD77681_REG_INTERFACE_FORMAT, + AD77681_INTERFACE_STATUS_EN_MSK, + AD77681_INTERFACE_STATUS_EN(status_bit)); + + if (ret == SUCCESS) { + dev->status_bit = status_bit; + ad77681_get_frame_byte(dev); + } + + return ret; +} + +/** + * Device reset over SPI. + * @param dev - The device structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_soft_reset(struct ad77681_dev *dev) +{ + int32_t ret = 0; + + // Two writes are required to initialize the reset + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SYNC_RESET, + AD77681_SYNC_RST_SPI_RESET_MSK, + AD77681_SYNC_RST_SPI_RESET(0x3)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SYNC_RESET, + AD77681_SYNC_RST_SPI_RESET_MSK, + AD77681_SYNC_RST_SPI_RESET(0x2)); + + return ret; +} + +/** + * Initiate a SYNC_OUT pulse over spi + * @param dev - The device structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_initiate_sync(struct ad77681_dev *dev) +{ + return ad77681_spi_write_mask(dev, + AD77681_REG_SYNC_RESET, + AD77681_SYNC_RST_SPI_STARTB_MSK, + AD77681_SYNC_RST_SPI_STARTB(0)); +} + +/** + * Write to offset registers + * @param dev The device structure. + * @param value The desired value of the whole 24-bit offset register + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_apply_offset(struct ad77681_dev *dev, + uint32_t value) +{ + int32_t ret; + uint8_t offset_HI = 0, offset_MID = 0, offset_LO = 0; + + offset_HI = (value & 0x00FF0000) >> 16; + offset_MID = (value & 0x0000FF00) >> 8; + offset_LO = (value & 0x000000FF); + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_OFFSET_HI, + AD77681_OFFSET_HI_MSK, + AD77681_OFFSET_HI(offset_HI)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_OFFSET_MID, + AD77681_OFFSET_MID_MSK, + AD77681_OFFSET_MID(offset_MID)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_OFFSET_LO, + AD77681_OFFSET_LO_MSK, + AD77681_OFFSET_LO(offset_LO)); + + return ret; +} + +/** + * Write to gain registers + * @param dev - The device structure. + * @param value - The desired value of the whole 24-bit gain register + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_apply_gain(struct ad77681_dev *dev, + uint32_t value) +{ + int32_t ret; + uint8_t gain_HI = 0, gain_MID = 0, gain_LO = 0; + + gain_HI = (value & 0x00FF0000) >> 16; + gain_MID = (value & 0x0000FF00) >> 8; + gain_LO = (value & 0x000000FF); + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GAIN_HI, + AD77681_GAIN_HI_MSK, + AD77681_GAIN_HI(gain_HI)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_GAIN_MID, + AD77681_GAIN_MID_MSK, + AD77681_GAIN_MID(gain_MID)); + + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_GAIN_LO, + AD77681_GAIN_LOW_MSK, + AD77681_GAIN_LOW(gain_LO)); + + return ret; +} + +/** + * Upload sequence for Programmamble FIR filter + * @param dev - The device structure. + * @param coeffs - Pointer to the desired filter coefficients array to be written + * @param num_coeffs - Count of active filter coeffs + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_programmable_filter(struct ad77681_dev *dev, + const float *coeffs, + uint8_t num_coeffs) +{ + uint8_t coeffs_buf[4], coeffs_index, check_back = 0, i, address; + uint32_t twait; + int32_t twos_complement, ret; + const uint8_t coeff_reg_length = 56; + + /* Specific keys in the upload sequence */ + const uint8_t key1 = 0xAC, key2 = 0x45, key3 = 0x55; + /* Scaling factor for all coefficients 2^22 */ + const float coeff_scale_factor = (1 << 22); + /* Wait time in uS necessary to access the COEFF_CONTROL and */ + /* COEFF_DATA registers. Twait = 512/MCLK */ + twait = (uint32_t)(((512.0) / ((float)(dev->mclk))) * 1000.0) + 1; + + /* Set Filter to FIR */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_DIGITAL_FILTER, + AD77681_DIGI_FILTER_FILTER_MSK, + AD77681_DIGI_FILTER_FILTER(AD77681_FIR)); + + /* Check return value before proceeding */ + if (ret < 0) + return ret; + + /* Write the first access key to the ACCESS_KEY register */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_ACCESS_KEY, + AD77681_ACCESS_KEY_MSK, + AD77681_ACCESS_KEY(key1)); + + /* Check return value before proceeding */ + if (ret < 0) + return ret; + + /* Write the second access key to the ACCESS_KEY register */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_ACCESS_KEY, + AD77681_ACCESS_KEY_MSK, + AD77681_ACCESS_KEY(key2)); + + /* Check return value before proceeding */ + if (ret < 0) + return ret; + + /* Read the the ACCESS_KEY register bit 0, the key bit */ + ret = ad77681_spi_read_mask(dev, + AD77681_REG_ACCESS_KEY, + AD77681_ACCESS_KEY_CHECK_MSK, + &check_back); + + /* Checks ret and key bit, return FAILURE in case key bit not equal to 1 */ + if ((ret < 0) || (check_back != 1)) + return FAILURE; + + /* Set the initial adress to 0 and enable the write and coefficient access bits */ + address = AD77681_COEF_CONTROL_COEFFACCESSEN_MSK + | AD77681_COEF_CONTROL_COEFFWRITEEN_MSK; + + /* The COEFF_DATA register has to be filled with 56 coeffs.*/ + /* In case the number of active filter coefficient is less */ + /* than 56, zeros will be padded before the desired coeff. */ + for (i = 0; i < coeff_reg_length; i++) { + /* Set the coeff address */ + ret = ad77681_spi_reg_write(dev, + AD77681_REG_COEFF_CONTROL, + address); + + /* Check return value before proceeding */ + if (ret < 0) + return ret; + + /* Wait for Twait uSeconds*/ + udelay(twait); + + /* Padding of zeros before the desired coef in case the coef count in less than 56 */ + if((num_coeffs + i) < coeff_reg_length) { + /* wirte zeroes to COEFF_DATA, in case of less coeffs than 56*/ + coeffs_buf[0] = AD77681_REG_WRITE(AD77681_REG_COEFF_DATA); + coeffs_buf[1] = 0; + coeffs_buf[2] = 0; + coeffs_buf[3] = 0; + } else {/* Writting of desired filter coefficients */ + /* Computes the index of coefficients to be uploaded */ + coeffs_index = (num_coeffs + i) - coeff_reg_length; + /* Scaling the coefficient value and converting it to 2's complement */ + twos_complement = (int32_t)(coeffs[coeffs_index] * coeff_scale_factor); + + /* Write coefficients to COEFF_DATA */ + coeffs_buf[0] = AD77681_REG_WRITE(AD77681_REG_COEFF_DATA); + coeffs_buf[1] = (twos_complement & 0xFF0000) >> 16; + coeffs_buf[2] = (twos_complement & 0x00FF00) >> 8; + coeffs_buf[3] = (twos_complement & 0x0000FF); + } + + ret = spi_write_and_read(dev->spi_desc, coeffs_buf, 4); + + /* Check return value before proceeding */ + if (ret < 0) + return ret; + + /* Increment the address*/ + address++; + /* Wait for Twait uSeconds*/ + udelay(twait); + } + + /* Disable coefficient write */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_COEFF_CONTROL, + AD77681_COEF_CONTROL_COEFFWRITEEN_MSK, + AD77681_COEF_CONTROL_COEFFWRITEEN(0x00)); + + /* Check return value before proceeding */ + if (ret < 0) + return ret; + + udelay(twait); + + /* Disable coefficient access */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_COEFF_CONTROL, + AD77681_COEF_CONTROL_COEFFACCESSEN_MSK, + AD77681_COEF_CONTROL_COEFFACCESSEN(0x00)); + + /* Check return value before proceeding */ + if (ret < 0) + return ret; + + /* Toggle the synchronization pulse and to begin reading data */ + /* Write 0x800000 to COEFF_DATA */ + coeffs_buf[0] = AD77681_REG_WRITE(AD77681_REG_COEFF_DATA); + coeffs_buf[1] = 0x80; + coeffs_buf[2] = 0x00; + coeffs_buf[3] = 0x00; + + ret = spi_write_and_read(dev->spi_desc, coeffs_buf, 4); + + /* Check return value before proceeding */ + if (ret < 0) + return ret; + + /* Exit filter upload by wirting specific access key 0x55*/ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_ACCESS_KEY, + AD77681_ACCESS_KEY_MSK, + AD77681_ACCESS_KEY(key3)); + + /* Check return value before proceeding */ + if (ret < 0) + return ret; + + /* Send synchronization pulse */ + ad77681_initiate_sync(dev); + + return ret; +} + +/** + * Read value from GPIOs present in AD7768-1 separately, or all GPIOS at once. + * @param dev - The device structure. + * @param value - Readed value. + * @param gpio_number - Number of GPIO, the value will be written into + * Accepted values: AD77681_GPIO0 + * AD77681_GPIO1 + * AD77681_GPIO2 + * AD77681_GPIO3 + * AD77681_ALL_GPIOS + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_gpio_read(struct ad77681_dev *dev, + uint8_t *value, + enum ad77681_gpios gpio_number) +{ + int32_t ret; + + switch (gpio_number) { + case AD77681_GPIO0: /* Read to GPIO0 */ + ret = ad77681_spi_read_mask(dev, + AD77681_REG_GPIO_READ, + AD77681_GPIO_READ_0_MSK, + value); + break; + case AD77681_GPIO1: /* Read to GPIO1 */ + ret = ad77681_spi_read_mask(dev, + AD77681_REG_GPIO_READ, + AD77681_GPIO_READ_1_MSK, + value); + break; + case AD77681_GPIO2: /* Read to GPIO2 */ + ret = ad77681_spi_read_mask(dev, + AD77681_REG_GPIO_READ, + AD77681_GPIO_READ_2_MSK, + value); + break; + case AD77681_GPIO3: /* Read to GPIO3 */ + ret = ad77681_spi_read_mask(dev, + AD77681_REG_GPIO_READ, + AD77681_GPIO_READ_3_MSK, + value); + break; + case AD77681_ALL_GPIOS: /* Read to all GPIOs */ + ret = ad77681_spi_read_mask(dev, + AD77681_REG_GPIO_READ, + AD77681_GPIO_READ_ALL_MSK, + value); + break; + default: + return FAILURE; + break; + } + + return ret; +} + +/** + * Write value to GPIOs present in AD7768-1 separately, or all GPIOS at once. + * @param dev - The device structure. + * @param value - Value to be written into GPIO + * Accepted values: GPIO_HIGH + * GPIO_LOW + * 4-bit value for all gpios + * @param gpio_number - Number of GPIO, the value will be written into + * Accepted values: AD77681_GPIO0 + * AD77681_GPIO1 + * AD77681_GPIO2 + * AD77681_GPIO3 + * AD77681_ALL_GPIOS + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_gpio_write(struct ad77681_dev *dev, + uint8_t value, + enum ad77681_gpios gpio_number) +{ + int32_t ret; + + switch (gpio_number) { + case AD77681_GPIO0: /* Write to GPIO0 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_WRITE, + AD77681_GPIO_WRITE_0_MSK, + AD77681_GPIO_WRITE_0(value)); + break; + case AD77681_GPIO1: /* Write to GPIO1 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_WRITE, + AD77681_GPIO_WRITE_1_MSK, + AD77681_GPIO_WRITE_1(value)); + break; + case AD77681_GPIO2: /* Write to GPIO2 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_WRITE, + AD77681_GPIO_WRITE_2_MSK, + AD77681_GPIO_WRITE_2(value)); + break; + case AD77681_GPIO3: /* Write to GPIO3 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_WRITE, + AD77681_GPIO_WRITE_3_MSK, + AD77681_GPIO_WRITE_3(value)); + break; + case AD77681_ALL_GPIOS: /* Write to all GPIOs */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_WRITE, + AD77681_GPIO_WRITE_ALL_MSK, + AD77681_GPIO_WRITE_ALL(value)); + break; + default: + return FAILURE; + break; + } + + return ret; +} + +/** + * Set AD7768-1s GPIO as input or output. + * @param dev - The device structure. + * @param direction - Direction of the GPIO + * Accepted values: GPIO_INPUT + * GPIO_OUTPUT + * 4-bit value for all gpios + * @param gpio_number - Number of GPIO, which will be affected + * Accepted values: AD77681_GPIO0 + * AD77681_GPIO1 + * AD77681_GPIO2 + * AD77681_GPIO3 + * AD77681_ALL_GPIOS + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_gpio_inout(struct ad77681_dev *dev, + uint8_t direction, + enum ad77681_gpios gpio_number) +{ + int32_t ret; + + switch (gpio_number) { + case AD77681_GPIO0: /* Set direction of GPIO0 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_GPIO0_OP_EN_MSK, + AD77681_GPIO_CNTRL_GPIO0_OP_EN(direction)); + break; + case AD77681_GPIO1: /* Set direction of GPIO1 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_GPIO1_OP_EN_MSK, + AD77681_GPIO_CNTRL_GPIO1_OP_EN(direction)); + break; + case AD77681_GPIO2: /* Set direction of GPIO2 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_GPIO2_OP_EN_MSK, + AD77681_GPIO_CNTRL_GPIO2_OP_EN(direction)); + break; + case AD77681_GPIO3: /* Set direction of GPIO3 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_GPIO3_OP_EN_MSK, + AD77681_GPIO_CNTRL_GPIO3_OP_EN(direction)); + break; + case AD77681_ALL_GPIOS: /* Set direction of all GPIOs */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_ALL_GPIOS_OP_EN_MSK, + AD77681_GPIO_CNTRL_ALL_GPIOS_OP_EN(direction)); + break; + default: + return FAILURE; + break; + } + + return ret; +} + +/** + * Enable global GPIO bit. + * This bit must be set high to change GPIO settings. + * @param dev - The device structure. + * @param gpio_enable - Enable or diable the global GPIO pin + * Accepted values: AD77681_GLOBAL_GPIO_ENABLE + * AD77681_GLOBAL_GPIO_DISABLE + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_global_gpio(struct ad77681_dev *dev, + enum ad77681_gobal_gpio_enable gpio_enable) +{ + return ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_UGPIO_EN_MSK, + AD77681_GPIO_CNTRL_UGPIO_EN(gpio_enable)); +} + +/** + * Read and write from ADC scratchpad register to check SPI Communication in + * the very beginning, during inicialization. + * @param dev - The device structure. + * @param sequence - The sequence which will be written into scratchpad and the + * readed sequence will be returned + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_scratchpad(struct ad77681_dev *dev, + uint8_t *sequence) +{ + int32_t ret; + const uint8_t check = *sequence;/* Save the original sequence */ + uint8_t ret_sequence = 0;/* Return sequence */ + + ret = ad77681_spi_write_mask(dev, + AD77681_REG_SCRATCH_PAD, + AD77681_SCRATCHPAD_MSK, + AD77681_SCRATCHPAD(check)); + + ret |= ad77681_spi_read_mask(dev, + AD77681_REG_SCRATCH_PAD, + AD77681_SCRATCHPAD_MSK, + &ret_sequence); + + if (check != ret_sequence)/* Compare original an returned sequence */ + return FAILURE; + + return ret; +} + +/** + * Set AD7768-1s GPIO output type between strong driver and open drain. + * GPIO3 can not be accessed! + * @param dev - The device structure. + * @param gpio_number - AD7768-1s GPIO to be affected (Only GPIO0, GPIO1 and GPIO2) + * Accepted values: AD77681_GPIO0 + * AD77681_GPIO1 + * AD77681_GPIO2 + * AD77681_ALL_GPIOS + * + * @param output_type - Output type of the GPIO + * Accepted values: AD77681_GPIO_STRONG_DRIVER + * AD77681_GPIO_OPEN_DRAIN + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_gpio_open_drain(struct ad77681_dev *dev, + enum ad77681_gpios gpio_number, + enum ad77681_gpio_output_type output_type) +{ + int32_t ret; + + switch (gpio_number) { + case AD77681_GPIO0: /* Set ouptut type of GPIO0 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_GPIO0_OD_EN_MSK, + AD77681_GPIO_CNTRL_GPIO0_OD_EN(output_type)); + break; + case AD77681_GPIO1: /* Set ouptut type of GPIO1 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_GPIO1_OD_EN_MSK, + AD77681_GPIO_CNTRL_GPIO1_OD_EN(output_type)); + break; + case AD77681_GPIO2: /* Set ouptut type of GPIO2 */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_GPIO2_OD_EN_MSK, + AD77681_GPIO_CNTRL_GPIO2_OD_EN(output_type)); + break; + case AD77681_ALL_GPIOS: /* Set ouptut type of all GPIOs */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_GPIO_CONTROL, + AD77681_GPIO_CNTRL_ALL_GPIOS_OD_EN_MSK, + AD77681_GPIO_CNTRL_ALL_GPIOS_OD_EN(output_type)); + break; + default: + return FAILURE; + break; + } + + return ret; +} + +/** + * Clear all error flags at once + * @param dev - The device structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_clear_error_flags(struct ad77681_dev *dev) +{ + int32_t ret; + + /* SPI ignore error CLEAR */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_SPI_DIAG_STATUS, + AD77681_SPI_IGNORE_ERROR_MSK, + AD77681_SPI_IGNORE_ERROR_CLR(ENABLE)); + /* SPI read error CLEAR */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SPI_DIAG_STATUS, + AD77681_SPI_READ_ERROR_MSK, + AD77681_SPI_READ_ERROR_CLR(ENABLE)); + /* SPI write error CLEAR */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SPI_DIAG_STATUS, + AD77681_SPI_WRITE_ERROR_MSK, + AD77681_SPI_WRITE_ERROR_CLR(ENABLE)); + /* SPI CRC error CLEAR */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SPI_DIAG_STATUS, + AD77681_SPI_CRC_ERROR_MSK, + AD77681_SPI_CRC_ERROR_CLR(ENABLE)); + + return ret; +} + +/** + * Enabling error flags. All error flags enabled by default + * @param dev - The device structure. + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_error_flags_enabe(struct ad77681_dev *dev) +{ + int32_t ret; + + /* SPI ERRORS ENABLE */ + /* SPI ignore error enable */ + ret = ad77681_spi_write_mask(dev, + AD77681_REG_SPI_DIAG_ENABLE, + AD77681_SPI_DIAG_ERR_SPI_IGNORE_MSK, + AD77681_SPI_DIAG_ERR_SPI_IGNORE(ENABLE)); + /* SPI Clock count error enable */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SPI_DIAG_ENABLE, + AD77681_SPI_DIAG_ERR_SPI_CLK_CNT_MSK, + AD77681_SPI_DIAG_ERR_SPI_CLK_CNT(ENABLE)); + /* SPI Read error enable */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SPI_DIAG_ENABLE, + AD77681_SPI_DIAG_ERR_SPI_RD_MSK, + AD77681_SPI_DIAG_ERR_SPI_RD(ENABLE)); + /* SPI Write error enable */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_SPI_DIAG_ENABLE, + AD77681_SPI_DIAG_ERR_SPI_WR_MSK, + AD77681_SPI_DIAG_ERR_SPI_WR(ENABLE)); + + /* ADC DIAG ERRORS ENABLE */ + /* DLDO PSM error enable */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_ADC_DIAG_ENABLE, + AD77681_ADC_DIAG_ERR_DLDO_PSM_MSK, + AD77681_ADC_DIAG_ERR_DLDO_PSM(ENABLE)); + /* ALDO PSM error enable */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_ADC_DIAG_ENABLE, + AD77681_ADC_DIAG_ERR_ALDO_PSM_MSK, + AD77681_ADC_DIAG_ERR_ALDO_PSM(ENABLE)); + /* Filter saturated error enable */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_ADC_DIAG_ENABLE, + AD77681_ADC_DIAG_ERR_FILT_SAT_MSK, + AD77681_ADC_DIAG_ERR_FILT_SAT(ENABLE)); + /* Filter not settled error enable */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_ADC_DIAG_ENABLE, + AD77681_ADC_DIAG_ERR_FILT_NOT_SET_MSK, + AD77681_ADC_DIAG_ERR_FILT_NOT_SET(ENABLE)); + /* External clock check error enable */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_ADC_DIAG_ENABLE, + AD77681_ADC_DIAG_ERR_EXT_CLK_QUAL_MSK, + AD77681_ADC_DIAG_ERR_EXT_CLK_QUAL(ENABLE)); + + /* DIG DIAG ENABLE */ + /* Memory map CRC error enabled */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_DIG_DIAG_ENABLE, + AD77681_DIG_DIAG_ERR_MEMMAP_CRC_MSK, + AD77681_DIG_DIAG_ERR_MEMMAP_CRC(ENABLE)); + /* RAM CRC error enabled */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_DIG_DIAG_ENABLE, + AD77681_DIG_DIAG_ERR_RAM_CRC_MSK, + AD77681_DIG_DIAG_ERR_RAM_CRC(ENABLE)); + /* FUSE CRC error enabled */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_DIG_DIAG_ENABLE, + AD77681_DIG_DIAG_ERR_FUSE_CRC_MSK, + AD77681_DIG_DIAG_ERR_FUSE_CRC(ENABLE)); + /* Enable MCLK Counter */ + ret |= ad77681_spi_write_mask(dev, + AD77681_REG_DIG_DIAG_ENABLE, + AD77681_DIG_DIAG_FREQ_COUNT_EN_MSK, + AD77681_DIG_DIAG_FREQ_COUNT_EN(ENABLE)); + + return ret; +} + +/** + * Read from all ADC status registers + * @param dev - The device structure. + * @param status - Structure with all satuts bits + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_status(struct ad77681_dev *dev, + struct ad77681_status_registers *status) +{ + int32_t ret; + uint8_t buf[3]; + + /* Master status register */ + ret = ad77681_spi_reg_read(dev, AD77681_REG_MASTER_STATUS,buf); + status->master_error = buf[1] & AD77681_MASTER_ERROR_MSK; + status->adc_error = buf[1] & AD77681_MASTER_ADC_ERROR_MSK; + status->dig_error = buf[1] & AD77681_MASTER_DIG_ERROR_MSK; + status->adc_err_ext_clk_qual = buf[1] & AD77681_MASTER_DIG_ERR_EXT_CLK_MSK; + status->adc_filt_saturated = buf[1] & AD77681_MASTER_FILT_SAT_MSK; + status->adc_filt_not_settled = buf[1] & AD77681_MASTER_FILT_NOT_SET_MSK; + status->spi_error = buf[1] & AD77681_MASTER_SPI_ERROR_MSK; + status->por_flag = buf[1] & AD77681_MASTER_POR_FLAG_MSK; + /* SPI diag status register */ + ret |= ad77681_spi_reg_read(dev, AD77681_REG_SPI_DIAG_STATUS, buf); + status->spi_ignore = buf[1] & AD77681_SPI_IGNORE_ERROR_MSK; + status->spi_clock_count = buf[1] & AD77681_SPI_CLK_CNT_ERROR_MSK; + status->spi_read_error = buf[1] & AD77681_SPI_READ_ERROR_MSK; + status->spi_write_error = buf[1] & AD77681_SPI_WRITE_ERROR_MSK; + status->spi_crc_error = buf[1] & AD77681_SPI_CRC_ERROR_MSK; + /* ADC diag status register */ + ret |= ad77681_spi_reg_read(dev, AD77681_REG_ADC_DIAG_STATUS,buf); + status->dldo_psm_error = buf[1] & AD77681_ADC_DLDO_PSM_ERROR_MSK; + status->aldo_psm_error = buf[1] & AD77681_ADC_ALDO_PSM_ERROR_MSK; + status->ref_det_error = buf[1] & AD77681_ADC_REF_DET_ERROR_MSK; + status->filt_sat_error = buf[1] & AD77681_ADC_FILT_SAT_MSK; + status->filt_not_set_error = buf[1] & AD77681_ADC_FILT_NOT_SET_MSK; + status->ext_clk_qual_error = buf[1] & AD77681_ADC_DIG_ERR_EXT_CLK_MSK; + /* DIG diag status register */ + ret |= ad77681_spi_reg_read(dev, AD77681_REG_DIG_DIAG_STATUS,buf); + status->memoy_map_crc_error = buf[1] & AD77681_DIG_MEMMAP_CRC_ERROR_MSK; + status->ram_crc_error = buf[1] & AD77681_DIG_RAM_CRC_ERROR_MSK; + status->fuse_crc_error = buf[1] & AD77681_DIG_FUS_CRC_ERROR_MSK; + + return ret; +} + +/** + * Initialize the device. + * @param device - The device structure. + * @param init_param - The structure that contains the device initial + * parameters. + * @param status - The structure that will contains the ADC status + * @return 0 in case of success, negative error code otherwise. + */ +int32_t ad77681_setup(struct ad77681_dev **device, + struct ad77681_init_param init_param, + struct ad77681_status_registers **status) +{ + struct ad77681_dev *dev; + struct ad77681_status_registers *stat; + int32_t ret; + uint8_t scratchpad_check = 0xAD; + + dev = (struct ad77681_dev *)malloc(sizeof(*dev)); + if (!dev) { + return -1; + } + + stat = (struct ad77681_status_registers *)malloc(sizeof(*stat)); + if (!stat) { + free(dev); + return -1; + } + + dev->power_mode = init_param.power_mode; + dev->mclk_div = init_param.mclk_div; + dev->conv_diag_sel = init_param.conv_diag_sel; + dev->conv_mode = init_param.conv_mode; + dev->diag_mux_sel = init_param.diag_mux_sel; + dev->conv_len = init_param.conv_len; + dev->crc_sel = AD77681_NO_CRC; + dev->status_bit = init_param.status_bit; + dev->VCM_out = init_param.VCM_out; + dev->AINn = init_param.AINn; + dev->AINp = init_param.AINp; + dev->REFn = init_param.REFn; + dev->REFp = init_param.REFp; + dev->filter = init_param.filter; + dev->decimate = init_param.decimate; + dev->sinc3_osr = init_param.sinc3_osr; + dev->vref = init_param.vref; + dev->mclk = init_param.mclk; + dev->sample_rate = init_param.sample_rate; + dev->data_frame_byte = init_param.data_frame_byte; + + ret = spi_init(&dev->spi_desc, &init_param.spi_eng_dev_init); + if (ret < 0) { + free(dev); + free(stat); + return ret; + } + + ret |= ad77681_soft_reset(dev); + + udelay(200); + + /* Check physical connection using scratchpad*/ + if (ad77681_scratchpad(dev, &scratchpad_check) == FAILURE) { + scratchpad_check = 0xAD;/* If failure, second try */ + ret |= (ad77681_scratchpad(dev, &scratchpad_check)); + if(ret == FAILURE) { + free(dev); + free(stat); + return ret; + } + } + ret |= ad77681_set_power_mode(dev, dev->power_mode); + ret |= ad77681_set_mclk_div(dev, dev->mclk_div); + ret |= ad77681_set_conv_mode(dev, + dev->conv_mode, + dev->diag_mux_sel, + dev->conv_diag_sel); + ret |= ad77681_set_convlen(dev, dev->conv_len); + ret |= ad77681_set_status_bit(dev, dev->status_bit); + ret |= ad77681_set_crc_sel(dev, init_param.crc_sel); + ret |= ad77681_set_VCM_output(dev, dev->VCM_out); + ret |= ad77681_set_AINn_buffer(dev, dev->AINn); + ret |= ad77681_set_AINp_buffer(dev, dev->AINp); + ret |= ad77681_set_REFn_buffer(dev, dev->REFn); + ret |= ad77681_set_REFp_buffer(dev, dev->REFp); + ret |= ad77681_set_filter_type(dev, dev->decimate, dev->filter, dev->sinc3_osr); + ret |= ad77681_error_flags_enabe(dev); + ret |= ad77681_clear_error_flags(dev); + ret |= ad77681_status(dev, stat); + ad77681_get_frame_byte(dev); + ad77681_update_sample_rate(dev); + *status = stat; + *device = dev; + + if (!ret) + printf("ad77681 successfully initialized\n"); + + return ret; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681.h Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,686 @@ +/***************************************************************************//** + * @file ad77681.h + * @brief Header file of the AD7768-1 Driver. + * @author SPopa (stefan.popa@analog.com) +******************************************************************************** + * Copyright 2017(c) Analog Devices, Inc. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - 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. + * - Neither the name of Analog Devices, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * - The use of this software may or may not infringe the patent rights + * of one or more patent holders. This license does not release you + * from the requirement that you obtain separate licenses from these + * patent holders to use this software. + * - Use of the software either in source or binary form, must be run + * on or directly connected to an Analog Devices Inc. component. + * + * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, 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 SRC_AD77681_H_ +#define SRC_AD77681_H_ + +//#include "spi_engine.h" + +#include "spi.h" +#include <stdbool.h> + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +#define AD77681_REG_CHIP_TYPE 0x3 +#define AD77681_REG_PROD_ID_L 0x4 +#define AD77681_REG_PROD_ID_H 0x5 +#define AD77681_REG_CHIP_GRADE 0x6 +#define AD77681_REG_SCRATCH_PAD 0x0A +#define AD77681_REG_VENDOR_L 0x0C +#define AD77681_REG_VENDOR_H 0x0D +#define AD77681_REG_INTERFACE_FORMAT 0x14 +#define AD77681_REG_POWER_CLOCK 0x15 +#define AD77681_REG_ANALOG 0x16 +#define AD77681_REG_ANALOG2 0x17 +#define AD77681_REG_CONVERSION 0x18 +#define AD77681_REG_DIGITAL_FILTER 0x19 +#define AD77681_REG_SINC3_DEC_RATE_MSB 0x1A +#define AD77681_REG_SINC3_DEC_RATE_LSB 0x1B +#define AD77681_REG_DUTY_CYCLE_RATIO 0x1C +#define AD77681_REG_SYNC_RESET 0x1D +#define AD77681_REG_GPIO_CONTROL 0x1E +#define AD77681_REG_GPIO_WRITE 0x1F +#define AD77681_REG_GPIO_READ 0x20 +#define AD77681_REG_OFFSET_HI 0x21 +#define AD77681_REG_OFFSET_MID 0x22 +#define AD77681_REG_OFFSET_LO 0x23 +#define AD77681_REG_GAIN_HI 0x24 +#define AD77681_REG_GAIN_MID 0x25 +#define AD77681_REG_GAIN_LO 0x26 +#define AD77681_REG_SPI_DIAG_ENABLE 0x28 +#define AD77681_REG_ADC_DIAG_ENABLE 0x29 +#define AD77681_REG_DIG_DIAG_ENABLE 0x2A +#define AD77681_REG_ADC_DATA 0x2C +#define AD77681_REG_MASTER_STATUS 0x2D +#define AD77681_REG_SPI_DIAG_STATUS 0x2E +#define AD77681_REG_ADC_DIAG_STATUS 0x2F +#define AD77681_REG_DIG_DIAG_STATUS 0x30 +#define AD77681_REG_MCLK_COUNTER 0x31 + +/* AD77681_REG_INTERFACE_FORMAT */ +#define AD77681_INTERFACE_CRC_EN_MSK (0x1 << 6) +#define AD77681_INTERFACE_CRC_EN(x) (((x) & 0x1) << 6) +#define AD77681_INTERFACE_CRC_TYPE_MSK (0x1 << 5) +#define AD77681_INTERFACE_CRC_TYPE(x) (((x) & 0x1) << 5) +#define AD77681_INTERFACE_STATUS_EN_MSK (0x1 << 4) +#define AD77681_INTERFACE_STATUS_EN(x) (((x) & 0x1) << 4) +#define AD77681_INTERFACE_CONVLEN_MSK (0x1 << 3) +#define AD77681_INTERFACE_CONVLEN(x) (((x) & 0x1) << 3) +#define AD77681_INTERFACE_RDY_EN_MSK (0x1 << 2) +#define AD77681_INTERFACE_RDY_EN(x) (((x) & 0x1) << 3) +#define AD77681_INTERFACE_CONT_READ_MSK (0x1 << 0) +#define AD77681_INTERFACE_CONT_READ_EN(x) (((x) & 0x1) << 0) +#define AD77681_REG_COEFF_CONTROL 0x32 +#define AD77681_REG_COEFF_DATA 0x33 +#define AD77681_REG_ACCESS_KEY 0x34 + +/* AD77681_REG_SCRATCH_PAD*/ +#define AD77681_SCRATCHPAD_MSK (0xFF << 0) +#define AD77681_SCRATCHPAD(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_POWER_CLOCK */ +#define AD77681_POWER_CLK_PWRMODE_MSK 0x3 +#define AD77681_POWER_CLK_PWRMODE(x) (((x) & 0x3) << 0) +#define AD77681_POWER_CLK_MOD_OUT_MSK (0x1 << 2) +#define AD77681_POWER_CLK_MOD_OUT(x) (((x) & 0x1) << 2) +#define AD77681_POWER_CLK_POWER_DOWN 0x08 +#define AD77681_POWER_CLK_MCLK_DIV_MSK (0x3 << 4) +#define AD77681_POWER_CLK_MCLK_DIV(x) (((x) & 0x3) << 4) +#define AD77681_POWER_CLK_CLOCK_SEL_MSK (0x3 << 6) +#define AD77681_POWER_CLK_CLOCK_SEL(x) (((x) & 0x3) << 6) + +/* AD77681_CONVERSION_REG */ +#define AD77681_CONVERSION_DIAG_MUX_MSK (0xF << 4) +#define AD77681_CONVERSION_DIAG_MUX_SEL(x) (((x) & 0xF) << 4) +#define AD77681_CONVERSION_DIAG_SEL_MSK (0x1 << 3) +#define AD77681_CONVERSION_DIAG_SEL(x) (((x) & 0x1) << 3) +#define AD77681_CONVERSION_MODE_MSK (0x7 << 0) +#define AD77681_CONVERSION_MODE(x) (((x) & 0x7) << 0) + +/* AD77681_REG_ANALOG */ +#define AD77681_ANALOG_REF_BUF_POS_MSK (0x3 << 6) +#define AD77681_ANALOG_REF_BUF_POS(x) (((x) & 0x3) << 6) +#define AD77681_ANALOG_REF_BUF_NEG_MSK (0x3 << 4) +#define AD77681_ANALOG_REF_BUF_NEG(x) (((x) & 0x3) << 4) +#define AD77681_ANALOG_AIN_BUF_POS_OFF_MSK (0x1 << 1) +#define AD77681_ANALOG_AIN_BUF_POS_OFF(x) (((x) & 0x1) << 1) +#define AD77681_ANALOG_AIN_BUF_NEG_OFF_MSK (0x1 << 0) +#define AD77681_ANALOG_AIN_BUF_NEG_OFF(x) (((x) & 0x1) << 0) + +/* AD77681_REG_ANALOG2 */ +#define AD77681_ANALOG2_VCM_MSK (0x7 << 0) +#define AD77681_ANALOG2_VCM(x) (((x) & 0x7) << 0) + +/* AD77681_REG_DIGITAL_FILTER */ +#define AD77681_DIGI_FILTER_60HZ_REJ_EN_MSK (0x1 << 7) +#define AD77681_DIGI_FILTER_60HZ_REJ_EN(x) (((x) & 0x1) << 7) +#define AD77681_DIGI_FILTER_FILTER_MSK (0x7 << 4) +#define AD77681_DIGI_FILTER_FILTER(x) (((x) & 0x7) << 4) +#define AD77681_DIGI_FILTER_DEC_RATE_MSK (0x7 << 0) +#define AD77681_DIGI_FILTER_DEC_RATE(x) (((x) & 0x7) << 0) + +/* AD77681_REG_SINC3_DEC_RATE_MSB */ +#define AD77681_SINC3_DEC_RATE_MSB_MSK (0x0F << 0) +#define AD77681_SINC3_DEC_RATE_MSB(x) (((x) & 0x0F) << 0) + +/* AD77681_REG_SINC3_DEC_RATE_LSB */ +#define AD77681_SINC3_DEC_RATE_LSB_MSK (0xFF << 0) +#define AD77681_SINC3_DEC_RATE_LSB(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_DUTY_CYCLE_RATIO */ +#define AD77681_DC_RATIO_IDLE_TIME_MSK (0xFF << 0) +#define AD77681_DC_RATIO_IDLE_TIME(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_SYNC_RESET */ +#define AD77681_SYNC_RST_SPI_STARTB_MSK (0x1 << 7) +#define AD77681_SYNC_RST_SPI_STARTB(x) (((x) & 0x1) << 7) +#define AD77681_SYNC_RST_SYNCOUT_EDGE_MSK (0x1 << 6) +#define AD77681_SYNC_RST_SYNCOUT_EDGE(x) (((x) & 0x1) << 6) +#define AD77681_SYNC_RST_GPIO_START_EN_MSK (0x1 << 3) +#define AD77681_SYNC_RST_GPIO_START_EN(x) (((x) & 0x1) << 3) +#define AD77681_SYNC_RST_SPI_RESET_MSK (0x3 << 0) +#define AD77681_SYNC_RST_SPI_RESET(x) (((x) & 0x3) << 0) + +/* AD77681_REG_GPIO_CONTROL */ +#define AD77681_GPIO_CNTRL_UGPIO_EN_MSK (0x1 << 7) +#define AD77681_GPIO_CNTRL_UGPIO_EN(x) (((x) & 0x1) << 7) +#define AD77681_GPIO_CNTRL_GPIO2_OD_EN_MSK (0x1 << 6) +#define AD77681_GPIO_CNTRL_GPIO2_OD_EN(x) (((x) & 0x1) << 6) +#define AD77681_GPIO_CNTRL_GPIO1_OD_EN_MSK (0x1 << 5) +#define AD77681_GPIO_CNTRL_GPIO1_OD_EN(x) (((x) & 0x1) << 5) +#define AD77681_GPIO_CNTRL_GPIO0_OD_EN_MSK (0x1 << 4) +#define AD77681_GPIO_CNTRL_GPIO0_OD_EN(x) (((x) & 0x1) << 4) +#define AD77681_GPIO_CNTRL_ALL_GPIOS_OD_EN_MSK (0x7 << 4) +#define AD77681_GPIO_CNTRL_ALL_GPIOS_OD_EN(x) (((x) & 0x7) << 4) +#define AD77681_GPIO_CNTRL_GPIO3_OP_EN_MSK (0x1 << 3) +#define AD77681_GPIO_CNTRL_GPIO3_OP_EN(x) (((x) & 0x1) << 3) +#define AD77681_GPIO_CNTRL_GPIO2_OP_EN_MSK (0x1 << 2) +#define AD77681_GPIO_CNTRL_GPIO2_OP_EN(x) (((x) & 0x1) << 2) +#define AD77681_GPIO_CNTRL_GPIO1_OP_EN_MSK (0x1 << 1) +#define AD77681_GPIO_CNTRL_GPIO1_OP_EN(x) (((x) & 0x1) << 1) +#define AD77681_GPIO_CNTRL_GPIO0_OP_EN_MSK (0x1 << 0) +#define AD77681_GPIO_CNTRL_GPIO0_OP_EN(x) (((x) & 0x1) << 0) +#define AD77681_GPIO_CNTRL_ALL_GPIOS_OP_EN_MSK (0xF << 0) +#define AD77681_GPIO_CNTRL_ALL_GPIOS_OP_EN(x) (((x) & 0xF) << 0) + +/* AD77681_REG_GPIO_WRITE */ +#define AD77681_GPIO_WRITE_3_MSK (0x1 << 3) +#define AD77681_GPIO_WRITE_3(x) (((x) & 0x1) << 3) +#define AD77681_GPIO_WRITE_2_MSK (0x1 << 2) +#define AD77681_GPIO_WRITE_2(x) (((x) & 0x1) << 2) +#define AD77681_GPIO_WRITE_1_MSK (0x1 << 1) +#define AD77681_GPIO_WRITE_1(x) (((x) & 0x1) << 1) +#define AD77681_GPIO_WRITE_0_MSK (0x1 << 0) +#define AD77681_GPIO_WRITE_0(x) (((x) & 0x1) << 0) +#define AD77681_GPIO_WRITE_ALL_MSK (0xF << 0) +#define AD77681_GPIO_WRITE_ALL(x) (((x) & 0xF)) + +/* AD77681_REG_GPIO_READ */ +#define AD77681_GPIO_READ_3_MSK (0x1 << 3) +#define AD77681_GPIO_READ_2_MSK (0x1 << 2) +#define AD77681_GPIO_READ_1_MSK (0x1 << 1) +#define AD77681_GPIO_READ_0_MSK (0x1 << 0) +#define AD77681_GPIO_READ_ALL_MSK (0xF << 0) + +/* AD77681_REG_OFFSET_HI */ +#define AD77681_OFFSET_HI_MSK (0xFF << 0) +#define AD77681_OFFSET_HI(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_OFFSET_MID */ +#define AD77681_OFFSET_MID_MSK (0xFF << 0) +#define AD77681_OFFSET_MID(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_OFFSET_LO */ +#define AD77681_OFFSET_LO_MSK (0xFF << 0) +#define AD77681_OFFSET_LO(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_GAIN_HI */ +#define AD77681_GAIN_HI_MSK (0xFF << 0) +#define AD77681_GAIN_HI(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_GAIN_MID */ +#define AD77681_GAIN_MID_MSK (0xFF << 0) +#define AD77681_GAIN_MID(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_GAIN_HI */ +#define AD77681_GAIN_LOW_MSK (0xFF << 0) +#define AD77681_GAIN_LOW(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_SPI_DIAG_ENABLE */ +#define AD77681_SPI_DIAG_ERR_SPI_IGNORE_MSK (0x1 << 4) +#define AD77681_SPI_DIAG_ERR_SPI_IGNORE(x) (((x) & 0x1) << 4) +#define AD77681_SPI_DIAG_ERR_SPI_CLK_CNT_MSK (0x1 << 3) +#define AD77681_SPI_DIAG_ERR_SPI_CLK_CNT(x) (((x) & 0x1) << 3) +#define AD77681_SPI_DIAG_ERR_SPI_RD_MSK (0x1 << 2) +#define AD77681_SPI_DIAG_ERR_SPI_RD(x) (((x) & 0x1) << 2) +#define AD77681_SPI_DIAG_ERR_SPI_WR_MSK (0x1 << 1) +#define AD77681_SPI_DIAG_ERR_SPI_WR(x) (((x) & 0x1) << 1) + +/* AD77681_REG_ADC_DIAG_ENABLE */ +#define AD77681_ADC_DIAG_ERR_DLDO_PSM_MSK (0x1 << 5) +#define AD77681_ADC_DIAG_ERR_DLDO_PSM(x) (((x) & 0x1) << 5) +#define AD77681_ADC_DIAG_ERR_ALDO_PSM_MSK (0x1 << 4) +#define AD77681_ADC_DIAG_ERR_ALDO_PSM(x) (((x) & 0x1) << 4) +#define AD77681_ADC_DIAG_ERR_FILT_SAT_MSK (0x1 << 2) +#define AD77681_ADC_DIAG_ERR_FILT_SAT(x) (((x) & 0x1) << 2) +#define AD77681_ADC_DIAG_ERR_FILT_NOT_SET_MSK (0x1 << 1) +#define AD77681_ADC_DIAG_ERR_FILT_NOT_SET(x) (((x) & 0x1) << 1) +#define AD77681_ADC_DIAG_ERR_EXT_CLK_QUAL_MSK (0x1 << 0) +#define AD77681_ADC_DIAG_ERR_EXT_CLK_QUAL(x) (((x) & 0x1) << 0) + +/* AD77681_REG_DIG_DIAG_ENABLE */ +#define AD77681_DIG_DIAG_ERR_MEMMAP_CRC_MSK (0x1 << 4) +#define AD77681_DIG_DIAG_ERR_MEMMAP_CRC(x) (((x) & 0x1) << 4) +#define AD77681_DIG_DIAG_ERR_RAM_CRC_MSK (0x1 << 3) +#define AD77681_DIG_DIAG_ERR_RAM_CRC(x) (((x) & 0x1) << 3) +#define AD77681_DIG_DIAG_ERR_FUSE_CRC_MSK (0x1 << 2) +#define AD77681_DIG_DIAG_ERR_FUSE_CRC(x) (((x) & 0x1) << 2) +#define AD77681_DIG_DIAG_FREQ_COUNT_EN_MSK (0x1 << 0) +#define AD77681_DIG_DIAG_FREQ_COUNT_EN(x) (((x) & 0x1) << 0) + +/* AD77681_REG_MASTER_STATUS */ +#define AD77681_MASTER_ERROR_MSK (0x1 << 7) +#define AD77681_MASTER_ADC_ERROR_MSK (0x1 << 6) +#define AD77681_MASTER_DIG_ERROR_MSK (0x1 << 5) +#define AD77681_MASTER_DIG_ERR_EXT_CLK_MSK (0x1 << 4) +#define AD77681_MASTER_FILT_SAT_MSK (0x1 << 3) +#define AD77681_MASTER_FILT_NOT_SET_MSK (0x1 << 2) +#define AD77681_MASTER_SPI_ERROR_MSK (0x1 << 1) +#define AD77681_MASTER_POR_FLAG_MSK (0x1 << 0) + +/* AD77681_REG_SPI_DIAG_STATUS */ +#define AD77681_SPI_IGNORE_ERROR_MSK (0x1 << 4) +#define AD77681_SPI_IGNORE_ERROR_CLR(x) (((x) & 0x1) << 4) +#define AD77681_SPI_CLK_CNT_ERROR_MSK (0x1 << 3) +#define AD77681_SPI_READ_ERROR_MSK (0x1 << 2) +#define AD77681_SPI_READ_ERROR_CLR(x) (((x) & 0x1) << 2) +#define AD77681_SPI_WRITE_ERROR_MSK (0x1 << 1) +#define AD77681_SPI_WRITE_ERROR_CLR(x) (((x) & 0x1) << 1) +#define AD77681_SPI_CRC_ERROR_MSK (0x1 << 0) +#define AD77681_SPI_CRC_ERROR_CLR(x) (((x) & 0x1) << 0) + +/* AD77681_REG_ADC_DIAG_STATUS */ +#define AD77681_ADC_DLDO_PSM_ERROR_MSK (0x1 << 5) +#define AD77681_ADC_ALDO_PSM_ERROR_MSK (0x1 << 4) +#define AD77681_ADC_REF_DET_ERROR_MSK (0x1 << 3) +#define AD77681_ADC_FILT_SAT_MSK (0x1 << 2) +#define AD77681_ADC_FILT_NOT_SET_MSK (0x1 << 1) +#define AD77681_ADC_DIG_ERR_EXT_CLK_MSK (0x1 << 0) + +/* AD77681_REG_DIG_DIAG_STATUS */ +#define AD77681_DIG_MEMMAP_CRC_ERROR_MSK (0x1 << 4) +#define AD77681_DIG_RAM_CRC_ERROR_MSK (0x1 << 3) +#define AD77681_DIG_FUS_CRC_ERROR_MSK (0x1 << 2) + +/* AD77681_REG_MCLK_COUNTER */ +#define AD77681_MCLK_COUNTER_MSK (0xFF << 0) +#define AD77681_MCLK_COUNTER(x) (((x) & 0xFF) << 0) + +/* AD77681_REG_COEFF_CONTROL */ +#define AD77681_COEF_CONTROL_COEFFACCESSEN_MSK (0x1 << 7) +#define AD77681_COEF_CONTROL_COEFFACCESSEN(x) (((x) & 0x1) << 7) +#define AD77681_COEF_CONTROL_COEFFWRITEEN_MSK (0x1 << 6) +#define AD77681_COEF_CONTROL_COEFFWRITEEN(x) (((x) & 0x1) << 6) +#define AD77681_COEF_CONTROL_COEFFADDR_MSK (0x3F << 5) +#define AD77681_COEF_CONTROL_COEFFADDR(x) (((x) & 0x3F) << 5) + +/* AD77681_REG_COEFF_DATA */ +#define AD77681_COEFF_DATA_USERCOEFFEN_MSK (0x1 << 23) +#define AD77681_COEFF_DATA_USERCOEFFEN(x) (((x) & 0x1) << 23) +#define AD77681_COEFF_DATA_COEFFDATA_MSK (0x7FFFFF << 22) +#define AD77681_COEFF_DATA_COEFFDATA(x) (((x) & 0x7FFFFF) << 22) + +/* AD77681_REG_ACCESS_KEY */ +#define AD77681_ACCESS_KEY_MSK (0xFF << 0) +#define AD77681_ACCESS_KEY(x) (((x) & 0xFF) << 0) +#define AD77681_ACCESS_KEY_CHECK_MSK (0x1 << 0) + +#define AD77681_REG_READ(x) ( (1 << 6) | (x & 0xFF) ) // Read from register x +#define AD77681_REG_WRITE(x) ( (~(1 << 6)) & (x & 0xFF) ) // Write to register x + +/* 8-bits wide checksum generated using the polynomial */ +#define AD77681_CRC8_POLY 0x07 // x^8 + x^2 + x^1 + x^0 + +/* Initial CRC for continuous read mode */ +#define INITIAL_CRC_CRC8 0x03 +#define INITIAL_CRC_XOR 0x6C +#define INITIAL_CRC 0x00 + +#define CRC_DEBUG + +/* AD7768-1 */ +/* A special key for exit the contiuous read mode, taken from the AD7768-1 datasheet */ +#define EXIT_CONT_READ 0x6C +/* Bit resolution of the AD7768-1 */ +#define AD7768_N_BITS 24 +/* Full scale of the AD7768-1 = 2^24 = 16777216 */ +#define AD7768_FULL_SCALE (1 << AD7768_N_BITS) +/* Half scale of the AD7768-1 = 2^23 = 8388608 */ +#define AD7768_HALF_SCALE (1 << (AD7768_N_BITS - 1)) + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define ENABLE 1 +#define DISABLE 0 + +/*****************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ +enum ad77681_power_mode { + AD77681_ECO = 0, + AD77681_MEDIAN = 2, + AD77681_FAST = 3, +}; + +enum ad77681_mclk_div { + AD77681_MCLK_DIV_16 = 0, + AD77681_MCLK_DIV_8 = 1, + AD77681_MCLK_DIV_4 = 2, + AD77681_MCLK_DIV_2 = 3 +}; + +enum ad77681_conv_mode { + AD77681_CONV_CONTINUOUS = 0, + AD77681_CONV_ONE_SHOT = 1, + AD77681_CONV_SINGLE = 2, + AD77681_CONV_PERIODIC = 3, + AD77681_CONV_STANDBY = 4 +}; + +enum ad77681_conv_len { + AD77681_CONV_24BIT = 0, + AD77681_CONV_16BIT = 1 +}; + +enum ad77681_rdy_dout { + AD77681_RDY_DOUT_EN, + AD77681_RDY_DOUT_DIS +}; + +enum ad77681_conv_diag_mux { + AD77681_TEMP_SENSOR = 0x0, + AD77681_AIN_SHORT= 0x8, + AD77681_POSITIVE_FS = 0x9, + AD77681_NEGATIVE_FS = 0xA +}; + +enum ad77681_crc_sel { + AD77681_CRC, + AD77681_XOR, + AD77681_NO_CRC +}; + +/* Filter tye FIR, SINC3, SINC5 */ +enum ad77681_filter_type { + AD77681_SINC5 = 0, + AD77681_SINC5_DECx8 = 1, + AD77681_SINC5_DECx16 = 2, + AD77681_SINC3 = 3, + AD77681_FIR = 4 +}; + +/* Dectimation ratios for SINC5 and FIR */ +enum ad77681_sinc5_fir_decimate { + AD77681_SINC5_FIR_DECx32 = 0, + AD77681_SINC5_FIR_DECx64 = 1, + AD77681_SINC5_FIR_DECx128 = 2, + AD77681_SINC5_FIR_DECx256 = 3, + AD77681_SINC5_FIR_DECx512 = 4, + AD77681_SINC5_FIR_DECx1024 = 5 +}; + +/* Sleep / Power up */ +enum ad77681_sleep_wake { + AD77681_SLEEP = 1, + AD77681_WAKE = 0 +}; + +/* Reset option */ +enum ad7761_reset_option { + AD77681_SOFT_RESET, + AD77681_HARD_RESET +}; +/* AIN- precharge */ +enum ad77681_AINn_precharge { + AD77681_AINn_ENABLED = 0, + AD77681_AINn_DISABLED = 1 +}; + +/* AIN+ precharge */ +enum ad77681_AINp_precharge { + AD77681_AINp_ENABLED = 0, + AD77681_AINp_DISABLED = 1 +}; + +/* REF- buffer */ +enum ad77681_REFn_buffer { + AD77681_BUFn_ENABLED = 0, + AD77681_BUFn_DISABLED = 1, + AD77681_BUFn_FULL_BUFFER_ON = 2 +}; + +/* REF+ buffer */ +enum ad77681_REFp_buffer { + AD77681_BUFp_ENABLED = 0, + AD77681_BUFp_DISABLED = 1, + AD77681_BUFp_FULL_BUFFER_ON = 2 +}; + +/* VCM output voltage */ +enum ad77681_VCM_out { + AD77681_VCM_HALF_VCC = 0, + AD77681_VCM_2_5V = 1, + AD77681_VCM_2_05V = 2, + AD77681_VCM_1_9V = 3, + AD77681_VCM_1_65V = 4, + AD77681_VCM_1_1V = 5, + AD77681_VCM_0_9V = 6, + AD77681_VCM_OFF = 7 +}; + +/* Global GPIO enable/disable */ +enum ad77681_gobal_gpio_enable { + AD77681_GLOBAL_GPIO_ENABLE = 1, + AD77681_GLOBAL_GPIO_DISABLE = 0 +}; + +/* ADCs GPIO numbering */ +enum ad77681_gpios { + AD77681_GPIO0 = 0, + AD77681_GPIO1 = 1, + AD77681_GPIO2 = 2, + AD77681_GPIO3 = 3, + AD77681_ALL_GPIOS = 4 +}; + +enum ad77681_gpio_output_type { + AD77681_GPIO_STRONG_DRIVER = 0, + AD77681_GPIO_OPEN_DRAIN = 1 +}; + +/* Continuous ADC read */ +enum ad77681_continuous_read { + AD77681_CONTINUOUS_READ_ENABLE = 1, + AD77681_CONTINUOUS_READ_DISABLE = 0, +}; + +/* ADC data read mode */ +enum ad77681_data_read_mode { + AD77681_REGISTER_DATA_READ = 0, + AD77681_CONTINUOUS_DATA_READ = 1, +}; + +/* ADC data structure */ +struct adc_data { + bool finish; + uint16_t count; + uint16_t samples; + uint32_t raw_data[4096]; +}; +/* ADC status registers structure */ +struct ad77681_status_registers { + bool master_error; + bool adc_error; + bool dig_error; + bool adc_err_ext_clk_qual; + bool adc_filt_saturated; + bool adc_filt_not_settled; + bool spi_error; + bool por_flag; + bool spi_ignore; + bool spi_clock_count; + bool spi_read_error; + bool spi_write_error; + bool spi_crc_error; + bool dldo_psm_error; + bool aldo_psm_error; + bool ref_det_error; + bool filt_sat_error; + bool filt_not_set_error; + bool ext_clk_qual_error; + bool memoy_map_crc_error; + bool ram_crc_error; + bool fuse_crc_error; +}; + +struct ad77681_dev { + /* SPI */ + spi_desc *spi_desc; + /* Configuration */ + enum ad77681_power_mode power_mode; + enum ad77681_mclk_div mclk_div; + enum ad77681_conv_mode conv_mode; + enum ad77681_conv_diag_mux diag_mux_sel; + bool conv_diag_sel; + enum ad77681_conv_len conv_len; + enum ad77681_crc_sel crc_sel; + uint8_t status_bit; + enum ad77681_VCM_out VCM_out; + enum ad77681_AINn_precharge AINn; + enum ad77681_AINp_precharge AINp; + enum ad77681_REFn_buffer REFn; + enum ad77681_REFp_buffer REFp; + enum ad77681_filter_type filter; + enum ad77681_sinc5_fir_decimate decimate; + uint16_t sinc3_osr; + uint16_t vref; /* Reference voltage*/ + uint16_t mclk; /* Mater clock*/ + uint32_t sample_rate; /* Sample rate*/ + uint8_t data_frame_byte; /* SPI 8bit frames*/ +}; + +struct ad77681_init_param { + /* SPI */ + spi_init_param spi_eng_dev_init; + /* Configuration */ + enum ad77681_power_mode power_mode; + enum ad77681_mclk_div mclk_div; + enum ad77681_conv_mode conv_mode; + enum ad77681_conv_diag_mux diag_mux_sel; + bool conv_diag_sel; + enum ad77681_conv_len conv_len; + enum ad77681_crc_sel crc_sel; + uint8_t status_bit; + enum ad77681_VCM_out VCM_out; + enum ad77681_AINn_precharge AINn; + enum ad77681_AINp_precharge AINp; + enum ad77681_REFn_buffer REFn; + enum ad77681_REFp_buffer REFp; + enum ad77681_filter_type filter; + enum ad77681_sinc5_fir_decimate decimate; + uint16_t sinc3_osr; + uint16_t vref; + uint16_t mclk; + uint32_t sample_rate; + uint8_t data_frame_byte; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ +uint8_t ad77681_compute_crc8(uint8_t *data, + uint8_t data_size, + uint8_t init_val); +uint8_t ad77681_compute_xor(uint8_t *data, + uint8_t data_size, + uint8_t init_val); +int32_t ad77681_setup(struct ad77681_dev **device, + struct ad77681_init_param init_param, + struct ad77681_status_registers **status); +int32_t ad77681_spi_reg_read(struct ad77681_dev *dev, + uint8_t reg_addr, + uint8_t *reg_data); +int32_t ad77681_spi_read_mask(struct ad77681_dev *dev, + uint8_t reg_addr, + uint8_t mask, + uint8_t *data); +int32_t ad77681_spi_reg_write(struct ad77681_dev *dev, + uint8_t reg_addr, + uint8_t reg_data); +int32_t ad77681_spi_write_mask(struct ad77681_dev *dev, + uint8_t reg_addr, + uint8_t mask, + uint8_t data); +int32_t ad77681_set_power_mode(struct ad77681_dev *dev, + enum ad77681_power_mode mode); +int32_t ad77681_set_mclk_div(struct ad77681_dev *dev, + enum ad77681_mclk_div clk_div); +int32_t ad77681_spi_read_adc_data(struct ad77681_dev *dev, + uint8_t *adc_data, + enum ad77681_data_read_mode mode); +int32_t ad77681_set_conv_mode(struct ad77681_dev *dev, + enum ad77681_conv_mode conv_mode, + enum ad77681_conv_diag_mux diag_mux_sel, + bool conv_diag_sel); +int32_t ad77681_set_convlen(struct ad77681_dev *dev, + enum ad77681_conv_len conv_len); +int32_t ad77681_soft_reset(struct ad77681_dev *dev); +int32_t ad77681_initiate_sync(struct ad77681_dev *dev); +int32_t ad77681_programmable_filter(struct ad77681_dev *dev, + const float *coeffs, + uint8_t num_coeffs); +int32_t ad77681_gpio_read(struct ad77681_dev *dev, + uint8_t *value, + enum ad77681_gpios gpio_number); +int32_t ad77681_apply_offset(struct ad77681_dev *dev, + uint32_t value); +int32_t ad77681_apply_gain(struct ad77681_dev *dev, + uint32_t value); +int32_t ad77681_set_crc_sel(struct ad77681_dev *dev, + enum ad77681_crc_sel crc_sel); +int32_t ad77681_gpio_open_drain(struct ad77681_dev *dev, + enum ad77681_gpios gpio_number, + enum ad77681_gpio_output_type output_type); +int32_t ad77681_set_continuos_read(struct ad77681_dev *dev, + enum ad77681_continuous_read continuous_enable); +int32_t ad77681_clear_error_flags(struct ad77681_dev *dev); +int32_t ad77681_data_to_voltage(struct ad77681_dev *dev, + uint32_t *raw_code, + double *voltage); +int32_t ad77681_CRC_status_handling(struct ad77681_dev *dev, + uint16_t *data_buffer); +int32_t ad77681_set_AINn_buffer(struct ad77681_dev *dev, + enum ad77681_AINn_precharge AINn); +int32_t ad77681_set_AINp_buffer(struct ad77681_dev *dev, + enum ad77681_AINp_precharge AINp); +int32_t ad77681_set_REFn_buffer(struct ad77681_dev *dev, + enum ad77681_REFn_buffer REFn); +int32_t ad77681_set_REFp_buffer(struct ad77681_dev *dev, + enum ad77681_REFp_buffer REFp); +int32_t ad77681_set_filter_type(struct ad77681_dev *dev, + enum ad77681_sinc5_fir_decimate decimate, + enum ad77681_filter_type filter, + uint16_t sinc3_osr); +int32_t ad77681_set_50HZ_rejection(struct ad77681_dev *dev, + uint8_t enable); +int32_t ad77681_power_down(struct ad77681_dev *dev, + enum ad77681_sleep_wake sleep_wake); +int32_t ad77681_set_status_bit(struct ad77681_dev *dev, + bool status_bit); +int32_t ad77681_set_VCM_output(struct ad77681_dev *dev, + enum ad77681_VCM_out VCM_out); +int32_t ad77681_gpio_write(struct ad77681_dev *dev, + uint8_t value, + enum ad77681_gpios gpio_number); +int32_t ad77681_gpio_inout(struct ad77681_dev *dev, + uint8_t direction, + enum ad77681_gpios gpio_number); +int32_t ad77681_global_gpio(struct ad77681_dev *devices, + enum ad77681_gobal_gpio_enable gpio_enable); +int32_t ad77681_scratchpad(struct ad77681_dev *dev, + uint8_t *sequence); +int32_t ad77681_error_flags_enabe(struct ad77681_dev *dev); +int32_t ad77681_update_sample_rate(struct ad77681_dev *dev); +int32_t ad77681_SINC3_ODR(struct ad77681_dev *dev, + uint16_t *sinc3_dec_reg, + float sinc3_odr); +int32_t ad77681_status(struct ad77681_dev *dev, + struct ad77681_status_registers *status); +#endif /* SRC_AD77681_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681_data_capture.c Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,171 @@ +/***************************************************************************//** + * @file ad77681_data_capture.c + * @brief Data capture interface for AD7768-1 IIO application + * @details This module handles the AD7768-1 data capturing +******************************************************************************** + * Copyright (c) 2021 Analog Devices, Inc. + * + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <string.h> +#include <stdlib.h> + +#include "app_config.h" +#include "ad77681_iio.h" +#include "ad77681_data_capture.h" +#include "adc_data_capture.h" +#include "error.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/* AD77681 ADC Resolution */ +#define AD77681_ADC_RESOLUTION 24 +/* AD77681 Buffer Length */ +#define AD77681_SAMPLE_DATA_BUFF_LEN 6 +/* AD77681 24 Bits Sign Extension Value */ +#define AD77681_24_BITS_SIGN_EXTENSION 0xFFFFFF +/* AD77681 2 Bytes Shift Value */ +#define AD77681_2_BYTES_SHIFT 16 +/* AD77681 1 Byte Shift Value */ +#define AD77681_1_BYTE_SHIFT 8 + +/******************************************************************************/ +/********************** Variables and User Defined Data Types *****************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* Perform single sample read pre-operations */ +static int32_t ad77681_single_sample_read_start_ops(uint8_t input_chn); +/* Perform continuous sample read pre-operations */ +static int32_t ad77681_continuous_sample_read_start_ops(uint32_t chn_mask); +/* Perform conversion on input channel and read single conversion sample */ +static int32_t ad77681_perform_conv_and_read_sample(uint32_t *read_adc_data, + uint8_t chn); +/* Read ADC sampled/conversion data */ +static int32_t ad77681_read_converted_sample(uint32_t *adc_raw, uint8_t chn_indx); + +/* Define the variable for data_capture_ops structure */ +struct data_capture_ops data_capture_ops = { + /* Point AD77681 data capture functions to generic ADC data capture functions */ + .single_sample_read_start_ops = ad77681_single_sample_read_start_ops, + .perform_conv_and_read_sample = ad77681_perform_conv_and_read_sample, + .single_sample_read_stop_ops = NULL, + .continuous_sample_read_start_ops = ad77681_continuous_sample_read_start_ops, + .read_converted_sample = ad77681_read_converted_sample, + .continuous_sample_read_stop_ops = NULL, + .trigger_next_conversion = NULL, +}; + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/*! + * @brief Perform the operations required before starting continuous sample read + * @param input_chn[out] - ADC input channel + * @return SUCCESS in case of success, FAILURE otherwise + */ +int32_t ad77681_single_sample_read_start_ops(uint8_t input_chn) +{ + + int32_t single_read_sts = FAILURE; + + single_read_sts = ad77681_set_conv_mode + ( + p_ad77681_dev_inst, + AD77681_CONV_SINGLE, + AD77681_AIN_SHORT, + false + ); + + return single_read_sts; +} + +/*! + * @brief Perform the operations required before starting continuous sample read + * @param chn_mask[in] - holds the list of all active channels set from IIO client for data capturing + * @return SUCCESS in case of success, FAILURE otherwise + */ +int32_t ad77681_continuous_sample_read_start_ops(uint32_t chn_mask) +{ + int32_t cont_read_sts = FAILURE; + + cont_read_sts = ad77681_set_conv_mode + ( + p_ad77681_dev_inst, + AD77681_CONV_CONTINUOUS, + AD77681_AIN_SHORT, + false + ); + + return cont_read_sts; +} + +/*! + * @brief Read ADC raw data for recently sampled channel + * @param adc_raw[out] - Pointer to adc data read variable + * @param chn_indx[in] - Channel for which data is to read + * @return SUCCESS in case of success, FAILURE otherwise + * @note This function is intended to call from the conversion end trigger + * event. Therefore, this function should just read raw ADC data + * without further monitoring conversion end event + */ +int32_t ad77681_read_converted_sample(uint32_t *adc_raw, uint8_t chn_indx) +{ + uint32_t ad77681_sample_data = 0; + uint8_t ad77681_sample_data_buff[AD77681_SAMPLE_DATA_BUFF_LEN] = { 0, 0, 0, 0, 0, 0 }; + + if (!adc_raw) { + return FAILURE; + } + + if (ad77681_spi_read_adc_data(p_ad77681_dev_inst, ad77681_sample_data_buff, + AD77681_REGISTER_DATA_READ) != SUCCESS) { + return FAILURE; + } + + ad77681_sample_data = (uint32_t) + ( + (ad77681_sample_data_buff[1] << AD77681_2_BYTES_SHIFT) | + (ad77681_sample_data_buff[2] << AD77681_1_BYTE_SHIFT ) | + (ad77681_sample_data_buff[3]) + ); + *adc_raw = ad77681_sample_data & AD77681_24_BITS_SIGN_EXTENSION; + + return SUCCESS; +} + +/*! + * @brief Read ADC single sample data + * @param read_adc_data[out] - Pointer to adc data read variable + * @param chn[in] - Channel for which data is to read + * @return SUCCESS in case of success, FAILURE otherwise + * @details This function performs the sampling on previously active channel + * and then read conversion result + */ +int32_t ad77681_perform_conv_and_read_sample(uint32_t *read_adc_data, + uint8_t chn) +{ + uint32_t ad77681_sample_data = 0; + + if (ad77681_read_converted_sample(&ad77681_sample_data, 0) != SUCCESS) { + return FAILURE; + } + *read_adc_data = ad77681_sample_data; + + return SUCCESS; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681_data_capture.h Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,37 @@ +/***************************************************************************//** + * @file ad77681_data_capture.h + * @brief Header for AD7768-1 data capture interfaces +******************************************************************************** + * Copyright (c) 2021 Analog Devices, Inc. + * + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +#ifndef _AD77681_DATA_CAPTURE_H_ +#define _AD77681_DATA_CAPTURE_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include "app_config.h" +#include "ad77681.h" +#include "adc_data_capture.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/******************************************************************************/ +/********************** Variables and User Defined Data Types *****************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************ Public Declarations *********************************/ +/******************************************************************************/ + +#endif /* _AD77681_DATA_CAPTURE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681_iio.c Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,872 @@ +/***************************************************************************//** + * @file ad77681_iio.c + * @brief Implementation of AD7768-1 IIO application interfaces + * @details This module acts as an interface for AD7768-1 IIO application +******************************************************************************** + * Copyright (c) 2021 Analog Devices, Inc. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> + +#include "app_config.h" +#include "tinyiiod.h" +#include "ad77681_iio.h" +#include "ad77681_user_config.h" +#include "ad77681_regs.h" +#include "ad77681_data_capture.h" +#include "adc_data_capture.h" +#include "error.h" + +/******************************************************************************/ +/************************ Macros/Constants ************************************/ +/******************************************************************************/ + +/* AD77681 Channel Number */ +#define AD77681_NUM_CHANNELS 1 +/* Bytes per sample (for ADC resolution of 24-bits) */ +#define AD77681_BYTES_PER_SAMPLE sizeof(uint32_t) +/* Number of data storage bits (needed for IIO client) */ +#define AD77681_CHN_STORAGE_BITS (AD77681_BYTES_PER_SAMPLE * 8) +/* AD77681 24 bits scale factor */ +#define AD77681_SCALE_FACTOR (1 << ADC_RESOLUTION) +/* AD77681 ADC data to Voltage conversion default scale factor for IIO client */ +#define AD77681_DEFAULT_SCALE ((((float)(AD77681_VOLTAGE_REF / 1000.00) * 2) / AD77681_SCALE_FACTOR) * 1000) +/* Register Max Address */ +#define AD77681_REG_MAX_ADDR AD77681_REG_MCLK_COUNTER + 1 +/* Conv Mode Value after setting a single conversion mode */ +#define SINGLE_MODE_CONV_STANDBY 6 +/* Conv Mode Value after setting a periodic conversion mode */ +#define PERIODIC_MODE_CONV_STANDBY 7 + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/* IIO interface descriptor */ +static struct iio_desc *p_ad77681_iio_desc; + +/* Device name */ +static const char dev_name[] = ACTIVE_DEVICE_NAME; + +/* Pointer to the struct representing the AD77681 IIO device */ +struct ad77681_dev *p_ad77681_dev_inst = NULL; + +/* Pointer to the struct AD77681 status register */ +struct ad77681_status_registers *p_ad77681_stat_reg = NULL; + +/* Flag to trigger new data capture */ +static bool adc_data_capture_started = false; + +/* Scale value per channel */ +static float attr_scale_val[AD77681_NUM_CHANNELS] = { + AD77681_DEFAULT_SCALE +}; + +/* Power mode values string representation */ +static const char* power_mode_str[] = { + "Eco-Mode", + "Value-Not-Assigned", + "Median-Mode", + "Fast-Mode" +}; + +/* Conversion mode values string representation */ +static const char* conv_mode_str[] = { + "Continuous-Mode", + "Continious-One-Shot-Mode", + "Single-Mode", + "Periodic-Mode", + "Standby-Mode" +}; + +/* MCLK division values string representation */ +static const char* mclk_division_str[] = { + "AD77681_MCLK_DIV_16", + "AD77681_MCLK_DIV_8", + "AD77681_MCLK_DIV_4", + "AD77681_MCLK_DIV_2" +}; + +/******************************************************************************/ +/************************ Functions Prototypes ********************************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/*! + * @brief Getter/Setter for the sampling frequency attribute value + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @param id- Attribute ID (optional) + * @return Number of characters read/written + * @Note This attribute is used to define the timeout period in IIO + * client during data capture. + * Timeout = (number of requested samples * (1/sampling frequency)) + 1sec + * e.g. if sampling frequency = 64KSPS and requested samples = 400 + * Timeout = (400 * (1/64000)) + 1 = 1.00625sec = ~1sec + */ +static ssize_t get_sampling_frequency(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + return (ssize_t) sprintf(buf, "%d", (int32_t)AD77681_DEFAULT_SAMPLING_FREQ); +} + +static ssize_t set_sampling_frequency(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + /* NA- Can't set sampling frequency value */ + return len; +} + +/*! + * @brief Getter/Setter for the raw attribute value + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @return Number of characters read/written + */ +ssize_t get_raw(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + uint32_t adc_data_raw = 0; + + /* Capture the raw adc data */ + if (read_single_sample((uint32_t)channel->ch_num, &adc_data_raw) != FAILURE) { + return (ssize_t) sprintf(buf, "%d", (int32_t)adc_data_raw); + } + + return - EINVAL; +} + +ssize_t set_raw(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + /* NA- Can't set raw value */ + return len; +} + +/*! + * @brief Getter/Setter for the scale attribute value + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @return Number of characters read/written + */ +ssize_t get_scale(void* device, + char* buf, + size_t len, + const struct iio_ch_info* channel, + intptr_t id) +{ + return (ssize_t)sprintf(buf, "%f", attr_scale_val[channel->ch_num]); +} + +ssize_t set_scale(void* device, + char* buf, + size_t len, + const struct iio_ch_info* channel, + intptr_t id) +{ + float scale; + + (void)sscanf(buf, "%f", &scale); + + if (scale > 0.0) { + attr_scale_val[channel->ch_num] = scale; + return len; + } + + return -EINVAL; +} + +/*! + * @brief Getter for the power mode available values + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @param id- Attribute ID (optional) + * @return Number of characters read/written + */ +static ssize_t get_power_mode_available(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + return sprintf(buf, "%s", "Eco-Mode Value-Not-Assigned Median-Mode Fast-Mode"); +} + +/*! + * @brief Setter for the power mode available values + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @param id- Attribute ID (optional) + * @return Number of characters read/written + */ +static ssize_t set_power_mode_available(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + /* NA- Can't set error value */ + return len; +} + +/*! + * @brief Getter/Setter for the power mode attribute value + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @return Number of characters read/written + */ +ssize_t get_power_mode(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + uint8_t power_mode_value = 0; + + if (ad77681_spi_read_mask(device, + AD77681_REG_POWER_CLOCK, + AD77681_POWER_CLK_PWRMODE_MSK, + &power_mode_value) == SUCCESS) { + return (ssize_t)sprintf(buf, "%s", power_mode_str[power_mode_value]); + } + + return -EINVAL; +} + +ssize_t set_power_mode(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + uint8_t power_mode_value; + + for (power_mode_value = 0; + power_mode_value < (uint8_t)ARRAY_SIZE(power_mode_str); power_mode_value++) { + if (!strncmp(buf, power_mode_str[power_mode_value], + strlen(power_mode_str[power_mode_value]))) { + break; + } + } + + if (power_mode_value < (uint8_t)ARRAY_SIZE(power_mode_str)) { + if (ad77681_set_power_mode(device, power_mode_value) == SUCCESS) { + return len; + } + } + + return -EINVAL; +} + +/*! + * @brief Getter for the conv mode available values + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @param id- Attribute ID (optional) + * @return Number of characters read/written + */ +static ssize_t get_conv_mode_available(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + return sprintf(buf, "%s", + "Continuous-Mode Continious-One-Shot-Mode Single-Mode Periodic-Mode Standby-Mode"); +} + +/*! + * @brief Setter for the conv mode available values + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @param id- Attribute ID (optional) + * @return Number of characters read/written + */ +static ssize_t set_conv_mode_available(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + /* NA- Can't set error value */ + return len; +} + +/*! + * @brief Getter/Setter for the conversion mode attribute value + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @return Number of characters read/written + */ +ssize_t get_conv_mode(void* device, + char* buf, + size_t len, + const struct iio_ch_info* channel, + intptr_t id) +{ + uint8_t conv_mode_value = 0; + + if (ad77681_spi_read_mask(device, + AD77681_REG_CONVERSION, + AD77681_CONVERSION_MODE_MSK, + &conv_mode_value) == SUCCESS) { + if (conv_mode_value <= (uint8_t)ARRAY_SIZE(conv_mode_str)) { + return (ssize_t)sprintf(buf, "%s", conv_mode_str[conv_mode_value]); + } else if (conv_mode_value == SINGLE_MODE_CONV_STANDBY) { + return (ssize_t)sprintf(buf, "%s", conv_mode_str[2]); + } else if (conv_mode_value == PERIODIC_MODE_CONV_STANDBY) { + return (ssize_t)sprintf(buf, "%s", conv_mode_str[3]); + } + } + + return -EINVAL; +} + +ssize_t set_conv_mode(void* device, + char* buf, + size_t len, + const struct iio_ch_info* channel, + intptr_t id) +{ + uint8_t conv_mode_value; + + for (conv_mode_value = 0; conv_mode_value < (uint8_t)ARRAY_SIZE(conv_mode_str); + conv_mode_value++) { + if (!strncmp(buf, conv_mode_str[conv_mode_value], + strlen(conv_mode_str[conv_mode_value]))) { + break; + } + } + + if (conv_mode_value < (uint8_t)ARRAY_SIZE(conv_mode_str)) { + if (ad77681_set_conv_mode(device, conv_mode_value, AD77681_AIN_SHORT, + false) == SUCCESS) { + return len; + } + } + + return -EINVAL; +} + +/*! + * @brief Getter for the mclk division available values + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @param id- Attribute ID (optional) + * @return Number of characters read/written + */ + +static ssize_t get_mclk_division_available(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + return sprintf(buf, "%s", + "AD77681_MCLK_DIV_16 AD77681_MCLK_DIV_8 AD77681_MCLK_DIV_4 AD77681_MCLK_DIV_2"); +} + +/*! + * @brief Setter for the mclk division available values + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @param id- Attribute ID (optional) + * @return Number of characters read/written + */ +static ssize_t set_mclk_division_available(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) +{ + /* NA- Can't set error value */ + return len; +} + +/*! + * @brief Getter/Setter for the MCLK division attribute value + * @param device- pointer to IIO device structure + * @param buf- pointer to buffer holding attribute value + * @param len- length of buffer string data + * @param channel- pointer to IIO channel structure + * @param channel- pointer to IIO channel structure + * @return Number of characters read/written + */ +ssize_t get_mclk_division(void* device, + char* buf, + size_t len, + const struct iio_ch_info* channel, + intptr_t id) +{ + uint8_t mclk_division_value = 0; + + if (ad77681_spi_read_mask(device, + AD77681_REG_POWER_CLOCK, + AD77681_POWER_CLK_MCLK_DIV_MSK, + &mclk_division_value) == SUCCESS) { + return (ssize_t)sprintf(buf, "%s", mclk_division_str[mclk_division_value >> 4]); + } + + return -EINVAL; +} + +ssize_t set_mclk_division(void* device, + char* buf, + size_t len, + const struct iio_ch_info* channel, + intptr_t id) +{ + uint8_t mclk_division_value = 0; + uint8_t mclk_division_str_len = 0; + + mclk_division_str_len = (uint8_t)ARRAY_SIZE(mclk_division_str); + + for (uint8_t mclk_division_cntr = 0; mclk_division_cntr < mclk_division_str_len; + mclk_division_cntr++) { + if (!strncmp(buf, mclk_division_str[mclk_division_cntr], + strlen(mclk_division_str[mclk_division_cntr]))) { + mclk_division_value = mclk_division_cntr; + break; + } + } + + if (mclk_division_value < mclk_division_str_len) { + if (ad77681_set_mclk_div(device, mclk_division_value) == SUCCESS) { + return len; + } + } + + return -EINVAL; +} + +/*! + * @brief Get the actual register address value from the list + * @param reg- Register address to read from + * @param Reg_add - actual value of Register address + * @return true in case of success, false value otherwise + */ +bool debug_get_reg_value(uint8_t reg, uint8_t* Reg_add) +{ + bool ad77681_regs_debug_flg = false; + uint8_t ad77681_regs_arr_cntr; + + for (ad77681_regs_arr_cntr = 0; + ad77681_regs_arr_cntr < (uint8_t)AD77681_REG_MAX_ADDR; + ad77681_regs_arr_cntr++) { + if (reg == ad77681_regs[ad77681_regs_arr_cntr]) { + ad77681_regs_debug_flg = true; + *Reg_add = reg; + break; + } + } + + return ad77681_regs_debug_flg; +} + +/*! + * @brief Read the debug register value + * @param dev- Pointer to IIO device instance + * @param reg- Register address to read from + * @param readval- Pointer to variable to read data into + * @return SUCCESS in case of success, negative value otherwise + */ +int32_t debug_reg_read(void *dev, uint32_t reg, uint32_t *readval) +{ + + bool ad77681_dev_debug_read_flg = false; + uint8_t ad77681_dev_actual_reg_add = 0; + + ad77681_dev_debug_read_flg = debug_get_reg_value((uint8_t)reg, + &ad77681_dev_actual_reg_add); + + /* Read the data from device */ + if (ad77681_dev_debug_read_flg == true) { + if ((ad77681_spi_reg_read(dev, (uint8_t)ad77681_dev_actual_reg_add, + (uint8_t *)readval) == SUCCESS)) { + // Shift 8 bits to get the uint8 value from uint32 + *readval = *readval >> 8; + return SUCCESS; + } + } + + return FAILURE; +} + +/*! + * @brief Write into the debug register + * @param dev- Pointer to IIO device instance + * @param reg- Register address to write into + * @param writeval- Register value to write + * @return SUCCESS in case of success, negative value otherwise + */ +int32_t debug_reg_write(void *dev, uint32_t reg, uint32_t writeval) +{ + bool ad77681_dev_debug_write_flg = false; + uint8_t ad77681_dev_actual_reg_add = 0; + + ad77681_dev_debug_write_flg = debug_get_reg_value((uint8_t)reg, + &ad77681_dev_actual_reg_add); + + if (ad77681_dev_debug_write_flg == true) { + if (ad77681_spi_reg_write(dev, ad77681_dev_actual_reg_add, + (uint8_t) writeval) == SUCCESS) { + return SUCCESS; + } + } + + return FAILURE; +} + + +/** + * @brief Read buffer data corresponding to AD4170 IIO device + * @param dev_instance[in] - IIO device instance + * @param pbuf[out] - Pointer to output data buffer + * @param offset[in] - Data buffer offset + * @param bytes_count[in] - Number of bytes to read + * @param ch_mask[in] - Channels select mask + * @return SUCCESS in case of success or negative value otherwise + */ +static ssize_t iio_ad77681_read_data(void *dev_instance, + char *pbuf, + size_t offset, + size_t bytes_count, + uint32_t ch_mask) +{ + if (adc_data_capture_started == false) { + start_data_capture(ch_mask, AD77681_NUM_CHANNELS); + adc_data_capture_started = true; + } + + /* Read the data stored into acquisition buffers */ + return (ssize_t)read_buffered_data(pbuf, + bytes_count, + offset, + ch_mask, + AD77681_BYTES_PER_SAMPLE); +} + +/** + * @brief Transfer the device data into memory (optional) + * @param dev_instance[in] - IIO device instance + * @param bytes_count[in] - Number of bytes to read + * @param ch_mask[in] - Channels select mask + * @return SUCCESS in case of success or negative value otherwise + */ +static ssize_t iio_ad77681_transfer_dev_data(void *dev_instance, + size_t bytes_count, + uint32_t ch_mask) +{ + /* The function insures that data is first read into memory from the device. + * This function doesn't do any sort of data transfer but it make sure data + * read and it's transfer to memory from device is happening in application through + * iio_ad4130_read_data() function */ + + /* Store the requested samples count value for data capture */ + store_requested_samples_count(bytes_count, AD77681_BYTES_PER_SAMPLE); + + return SUCCESS; +} + +/** + * @brief Perform tasks before new data transfer + * @param dev_instance[in] - IIO device instance + * @param ch_mask[in] - Channels select mask + * @return SUCCESS in case of success or negative value otherwise + */ +static int32_t iio_ad77681_start_transfer(void *dev_instance, uint32_t ch_mask) +{ + return SUCCESS; +} + + +/** + * @brief Perform tasks before end of current data transfer + * @param dev_instance[in] - IIO device instance + * @return SUCCESS in case of success or negative value otherwise + */ +static int32_t iio_ad77681_stop_transfer(void *dev) +{ + adc_data_capture_started = false; + stop_data_capture(); + + return SUCCESS; +} + +/********************************************************* + * IIO Attributes and Structures + ********************************************************/ + +/* IIOD channels attributes list */ +struct iio_attribute channel_input_attributes[] = { + { + .name = "raw", + .show = get_raw, + .store = set_raw, + }, + { + .name = "scale", + .show = get_scale, + .store = set_scale, + }, + + END_ATTRIBUTES_ARRAY +}; + +/* IIOD device (global) attributes list */ +static struct iio_attribute global_attributes[] = { + { + .name = "sampling_frequency", + .show = get_sampling_frequency, + .store = set_sampling_frequency, + }, + { + .name = "conv_mode_available", + .show = get_conv_mode_available, + .store = set_conv_mode_available, + }, + { + .name = "conv_mode", + .show = get_conv_mode, + .store = set_conv_mode, + }, + { + .name = "power_mode_available", + .show = get_power_mode_available, + .store = set_power_mode_available, + }, + { + .name = "power_mode", + .show = get_power_mode, + .store = set_power_mode, + }, + { + .name = "mclk_division_available", + .show = get_mclk_division_available, + .store = set_mclk_division_available, + }, + { + .name = "mclk_division", + .show = get_mclk_division, + .store = set_mclk_division, + }, + + END_ATTRIBUTES_ARRAY + +}; + +/* IIOD debug attributes list */ +static struct iio_attribute debug_attributes[] = { + { + .name = "direct_reg_access", + .show = NULL, + .store = NULL, + }, + + END_ATTRIBUTES_ARRAY +}; + +/* IIOD channels configurations */ +struct scan_type chn_scan = { + .sign = 's', + .realbits = AD77681_CHN_STORAGE_BITS, + .storagebits = AD77681_CHN_STORAGE_BITS, + .shift = 0, + .is_big_endian = false +}; + +/* IIOD Channel list */ +static struct iio_channel iio_ad77681_channels[] = { + { + .name = "voltage0", + .ch_type = IIO_VOLTAGE, + .channel = 0, + .scan_index = 0, + .scan_type = &chn_scan, + .attributes = channel_input_attributes, + .ch_out = false, + .indexed = true, + }, +}; + +/** + * @brief Init for reading/writing and parameterization of a + * ad77681 IIO device + * @param desc[in,out] - IIO device descriptor + * @return SUCCESS in case of success, FAILURE otherwise + */ +static int32_t iio_ad77681_init(struct iio_device **desc) +{ + struct iio_device *iio_ad77861_inst; + + iio_ad77861_inst = calloc(1, sizeof(struct iio_device)); + if (!iio_ad77861_inst) { + return FAILURE; + } + + iio_ad77861_inst->num_ch = sizeof(iio_ad77681_channels) / sizeof( + iio_ad77681_channels[0]); + iio_ad77861_inst->channels = iio_ad77681_channels; + iio_ad77861_inst->attributes = global_attributes; + iio_ad77861_inst->debug_attributes = debug_attributes; + iio_ad77861_inst->transfer_dev_to_mem = iio_ad77681_transfer_dev_data; + iio_ad77861_inst->transfer_mem_to_dev = NULL; + iio_ad77861_inst->read_data = iio_ad77681_read_data; + iio_ad77861_inst->write_data = NULL; + iio_ad77861_inst->prepare_transfer = iio_ad77681_start_transfer; + iio_ad77861_inst->end_transfer = iio_ad77681_stop_transfer; + iio_ad77861_inst->debug_reg_read = debug_reg_read; + iio_ad77861_inst->debug_reg_write = debug_reg_write; + + *desc = iio_ad77861_inst; + + return SUCCESS; +} + + +/** + * @brief Release resources allocated for AD77681 IIO device + * @param desc[in] - IIO device descriptor + * @return SUCCESS in case of success, FAILURE otherwise + */ +static int32_t iio_ad77681_remove(struct iio_desc *desc) +{ + int32_t status; + + if (!desc) { + return FAILURE; + } + + status = iio_unregister(desc, (char *)dev_name); + if (status != SUCCESS) { + return FAILURE; + } + + return SUCCESS; +} + +/** + * @brief Initialize the IIO interface for AD77681 IIO device + * @return none + * @return SUCCESS in case of success, FAILURE otherwise + */ +int32_t ad77681_iio_initialize(void) +{ + int32_t init_status = FAILURE; + + /* IIO device descriptor */ + struct iio_device *p_iio_ad77681_dev; + + /** + * IIO interface init parameters + */ + struct iio_init_param iio_init_params = { + .phy_type = USE_UART, + { + &uart_init_params + } + }; + + /* Initialize AD77681 device and peripheral interface */ + init_status = ad77681_setup(&p_ad77681_dev_inst, sad77681_init, + &p_ad77681_stat_reg); + if (init_status != SUCCESS) { + return init_status; + } + + /* Initialize the IIO interface */ + init_status = iio_init(&p_ad77681_iio_desc, &iio_init_params); + if (init_status != SUCCESS) { + return init_status; + } + + /* Initialize the AD77681 IIO application interface */ + init_status = iio_ad77681_init(&p_iio_ad77681_dev); + if (init_status != SUCCESS) { + return init_status; + } + + /* Register AD77681 IIO interface */ + init_status = iio_register(p_ad77681_iio_desc, + p_iio_ad77681_dev, + (char *)dev_name, + p_ad77681_dev_inst, + NULL, + NULL); + + if (init_status != SUCCESS) { + return init_status; + } + + /* Init the system peripherals */ + init_status = init_system(); + if (init_status != SUCCESS) { + return init_status; + } + + return init_status; +} + +/** + * @brief Run the AD77681 IIO event handler + * @return none + * @details This function monitors the new IIO client event + */ +void ad77681_iio_event_handler(void) +{ + while (1) { + (void)iio_step(p_ad77681_iio_desc); + } +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681_iio.h Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,42 @@ +/***************************************************************************//** +* @file ad77681_iio.h +* @brief Header file of ad77681_iio +******************************************************************************** +* Copyright (c) 2021 Analog Devices, Inc. +* All rights reserved. +* +* This software is proprietary to Analog Devices, Inc. and its licensors. +* By using this software you agree to the terms of the associated +* Analog Devices Software License Agreement. +*******************************************************************************/ +#ifndef _AD77681_IIO_H_ +#define _AD77681_IIO_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdio.h> +#include <stdbool.h> + +#include "iio.h" +#include "iio_types.h" + +/******************************************************************************/ +/************************ Macros/Constants ************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************ Public Declarations *********************************/ +/******************************************************************************/ + +/* AD77681 global device instance for accessing device specific APIs */ +extern struct ad77681_dev *p_ad77681_dev_inst; + +/* Init the IIO interface */ +int32_t ad77681_iio_initialize(void); + +/* Run the IIO event handler */ +void ad77681_iio_event_handler(void); + +#endif /* _AD77681_IIO_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681_regs.c Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,62 @@ +/***************************************************************************//** + * @file ad77681_regs.c + * @brief AD77681 registers map + * @details +******************************************************************************** + * Copyright (c) 2021 Analog Devices, Inc. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdint.h> +#include "ad77681.h" + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +const uint32_t ad77681_regs[] = { + AD77681_REG_CHIP_TYPE, + AD77681_REG_PROD_ID_L, + AD77681_REG_PROD_ID_H, + AD77681_REG_CHIP_GRADE, + AD77681_REG_SCRATCH_PAD, + AD77681_REG_VENDOR_L, + AD77681_REG_VENDOR_H, + AD77681_REG_INTERFACE_FORMAT, + AD77681_REG_POWER_CLOCK, + AD77681_REG_ANALOG, + AD77681_REG_ANALOG2, + AD77681_REG_CONVERSION, + AD77681_REG_DIGITAL_FILTER, + AD77681_REG_SINC3_DEC_RATE_MSB, + AD77681_REG_SINC3_DEC_RATE_LSB, + AD77681_REG_DUTY_CYCLE_RATIO, + AD77681_REG_SYNC_RESET, + AD77681_REG_GPIO_CONTROL, + AD77681_REG_GPIO_WRITE, + AD77681_REG_GPIO_READ, + AD77681_REG_OFFSET_HI, + AD77681_REG_OFFSET_MID, + AD77681_REG_OFFSET_LO, + AD77681_REG_GAIN_HI, + AD77681_REG_GAIN_MID, + AD77681_REG_GAIN_LO, + AD77681_REG_SPI_DIAG_ENABLE, + AD77681_REG_ADC_DIAG_ENABLE, + AD77681_REG_DIG_DIAG_ENABLE, + AD77681_REG_ADC_DATA, + AD77681_REG_MASTER_STATUS, + AD77681_REG_SPI_DIAG_STATUS, + AD77681_REG_ADC_DIAG_STATUS, + AD77681_REG_DIG_DIAG_STATUS, + AD77681_REG_MCLK_COUNTER +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681_regs.h Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,27 @@ +/***************************************************************************//** +* @file ad77681_regs.h +* @brief Global declarations for ad77681_regs module +******************************************************************************** +* Copyright (c) 2021 Analog Devices, Inc. +* All rights reserved. +* +* This software is proprietary to Analog Devices, Inc. and its licensors. +* By using this software you agree to the terms of the associated +* Analog Devices Software License Agreement. +*******************************************************************************/ +#ifndef _AD77681_REGS_H_ +#define _AD77681_REGS_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdint.h> + +/******************************************************************************/ +/************************ Public Declarations *********************************/ +/******************************************************************************/ + +extern const uint32_t ad77681_regs[]; + +#endif /* _AD77681_REGS_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681_user_config.c Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,58 @@ +/***************************************************************************** + * @file ad77681_user_config.h + * + * @brief User configuration settings for AD77681 on start-up + * + * @details +****************************************************************************** +Copyright (c) 2021 Analog Devices, Inc. All Rights Reserved. + +This software is proprietary to Analog Devices, Inc. and its licensors. +By using this software you agree to the terms of the associated +Analog Devices Software License Agreement. +******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include <stdint.h> + +#include "app_config.h" +#include "app_config_mbed.h" +#include "ad77681_user_config.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +// Initialize the ad77681 device structure +struct ad77681_init_param sad77681_init = { + // Define SPI init parameters structure + .spi_eng_dev_init = + { + .max_speed_hz = 22500000, // Max SPI Speed + .chip_select = SPI_SS, // Chip Select + .mode = SPI_MODE_3, // CPOL = 1, CPHA = 1 + .extra = &spi_init_extra_params // SPI extra configurations + }, + .power_mode = AD77681_FAST, + .mclk_div = AD77681_MCLK_DIV_8, + .conv_mode = AD77681_CONV_CONTINUOUS, + .diag_mux_sel = AD77681_TEMP_SENSOR, + .conv_diag_sel = false, + .conv_len = AD77681_CONV_24BIT, + .crc_sel = AD77681_NO_CRC, + .status_bit = 0, + .VCM_out = AD77681_VCM_0_9V, + .AINn = AD77681_AINn_DISABLED, + .AINp = AD77681_AINp_DISABLED, + .REFn = AD77681_BUFn_ENABLED, + .REFp = AD77681_BUFp_ENABLED, + .filter = AD77681_SINC5, + .decimate = AD77681_SINC5_FIR_DECx32, + .sinc3_osr = 0, + .vref = AD77681_VOLTAGE_REF, + .mclk = AD77681_MCLK, + .sample_rate = AD77681_DEFAULT_SAMPLING_FREQ, + .data_frame_byte = AD77681_DECIMATION_RATE +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad77681_user_config.h Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,37 @@ +/*************************************************************************//** + * @file ad77861_user_config.h + * @brief Header for AD7768-1 user configuration file +****************************************************************************** +* Copyright (c) 2021 Analog Devices, Inc. +* +* All rights reserved. +* +* This software is proprietary to Analog Devices, Inc. and its licensors. +* By using this software you agree to the terms of the associated +* Analog Devices Software License Agreement. +*****************************************************************************/ + +#ifndef _AD77681_USER_CONFIG_H_ +#define _AD77681_USER_CONFIG_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdint.h> +#include "ad77681.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/* AD77681 Voltage reference */ +#define AD77681_VOLTAGE_REF (4096) + +/******************************************************************************/ +/********************** Variables and User Defined Data Types *****************/ +/******************************************************************************/ + +extern struct ad77681_init_param sad77681_init; + +#endif //_AD77681_USER_CONFIG_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/app_config.c Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,136 @@ +/***************************************************************************//** + * @file app_config.c + * @brief Application configurations module + * @details This module contains the configurations needed for IIO application +******************************************************************************** + * Copyright (c) 2021 Analog Devices, Inc. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdbool.h> + +#include "app_config.h" +#include "adc_data_capture.h" +#include "ad77681_iio.h" +#include "error.h" +#include "uart.h" +#include "irq.h" +#include "gpio.h" + +/******************************************************************************/ +/************************ Macros/Constants ************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/* + * UART init parameters structure + */ +struct uart_init_param uart_init_params = { + .device_id = NULL, + .baud_rate = IIO_UART_BAUD_RATE, + .extra = &uart_init_extra_params +}; + +/* LED GPIO descriptor */ +struct gpio_init_param gpio_init_led_green = { + .number = LED_GREEN, + .extra = NULL +}; + +/* External interrupt init parameters */ +struct irq_init_param external_int_init_param = { + .irq_ctrl_id = EXTERNAL_INT_ID1, + .extra = &mbed_ext_int_init_param +}; + +/* External interrupt callback descriptor */ +struct callback_desc external_int_callback_desc = { + data_capture_callback, + NULL, + NULL +}; + +/* LED GPIO descriptor */ +gpio_desc *led_green_gpio_desc = NULL; + +/* External interrupt descriptor */ +struct irq_ctrl_desc *external_int_desc; + +/******************************************************************************/ +/************************ Functions Prototypes ********************************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/** + * @brief Initialize the GPIOs + * @return SUCCESS in case of success, FAILURE otherwise + * @details This function initialize the GPIOs used by application + */ +static int32_t init_gpio(void) +{ + /* Initialize the LED GREEN GPIO */ + if (gpio_get_optional(&led_green_gpio_desc, &gpio_init_led_green) != SUCCESS) { + return FAILURE; + } + + if (led_green_gpio_desc) { + if (gpio_direction_output(led_green_gpio_desc, GPIO_HIGH) != SUCCESS) { + return FAILURE; + } + } + + return SUCCESS; +} + +/** + * @brief Initialize the IRQ contoller + * @return SUCCESS in case of success, FAILURE otherwise + * @details This function initialize the interrupts for system peripherals + */ +static int32_t init_interrupt(void) +{ + /* Init interrupt controller for external interrupt */ + if (irq_ctrl_init(&external_int_desc, &external_int_init_param) == FAILURE) { + return FAILURE; + } + + /* Register a callback function for external interrupt */ + if (irq_register_callback(external_int_desc, + EXTERNAL_INT_ID1, + &external_int_callback_desc) == FAILURE) { + return FAILURE; + } + + return SUCCESS; +} + +/** + * @brief Initialize the system peripherals + * @return SUCCESS in case of success, FAILURE otherwise + */ +int32_t init_system(void) +{ + if (init_gpio() != SUCCESS) { + return FAILURE; + } + + if (init_interrupt() != SUCCESS) { + return FAILURE; + } + + return SUCCESS; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/app_config.h Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,89 @@ +/***************************************************************************//* + * @file app_config.h + * @brief Configuration file for AD77681 IIO firmware application + * @details +****************************************************************************** + * Copyright (c) 2021 Analog Devices, Inc. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +******************************************************************************/ + +#ifndef _APP_CONFIG_H_ +#define _APP_CONFIG_H_ + +/* List of supported platforms*/ +#define MBED_PLATFORM 1 + +/* Select the active platform */ +#define ACTIVE_PLATFORM MBED_PLATFORM + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdint.h> + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/* Name of active device */ +#define ACTIVE_DEVICE_NAME "ad7768-1" + +#if (ACTIVE_PLATFORM == MBED_PLATFORM) +#include "app_config_mbed.h" + +/* Used to form a VCOM serial number */ +#define FIRMWARE_NAME "ad77681_mbed_iio_application" + +/* Redefine the init params structure mapping w.r.t. platform */ +#define uart_init_extra_params mbed_uart_extra_init_param +#define spi_init_extra_params mbed_spi_init_extra_params +#else +#error "No/Invalid active platform selected" +#endif + +/* ADC resolution for active device */ +#define ADC_RESOLUTION 24 + +/* Baud rate for IIO application UART interface */ +#define IIO_UART_BAUD_RATE (230400) + +/****** Macros used to form a VCOM serial number ******/ +#if !defined(DEVICE_NAME) +#define DEVICE_NAME "DEV_AD77681" +#endif + +#if !defined(PLATFORM_NAME) +#define PLATFORM_NAME "SDP_K1" +#endif +/******/ + +/* Enable the VirtualCOM port connection/interface. By default serial communication + * is physical UART */ +//#define USE_VIRTUAL_COM_PORT + +#if defined(USE_VIRTUAL_COM_PORT) +/* Below USB configurations (VID and PID) are owned and assigned by ADI. + * If intended to distribute software further, use the VID and PID owned by your + * organization */ +#define VIRTUAL_COM_PORT_VID 0x0456 +#define VIRTUAL_COM_PORT_PID 0xb66c +/* Serial number string is formed as: application name + device (target) name + platform (host) name */ +#define VIRTUAL_COM_SERIAL_NUM (FIRMWARE_NAME "_" DEVICE_NAME "_" PLATFORM_NAME) +#endif + +/******************************************************************************/ +/************************ Public Declarations *********************************/ +/******************************************************************************/ + +int32_t init_system(void); + +extern struct uart_init_param uart_init_params; +extern struct gpio_desc *led_green_gpio_desc; + + +#endif /* _APP_CONFIG_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/app_config_mbed.c Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,64 @@ +/***************************************************************************//** + * @file app_config_mbed.c + * @brief Application configurations module for Mbed platform + * @details This module contains the configurations needed for IIO application +******************************************************************************** + * Copyright (c) 2021 Analog Devices, Inc. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdbool.h> +#include "app_config.h" +#include "app_config_mbed.h" + +/******************************************************************************/ +/************************ Macros/Constants ************************************/ +/******************************************************************************/ + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/* UART Mbed platform parameters structure */ +mbed_uart_init_param mbed_uart_extra_init_param = { +#if defined(USE_VIRTUAL_COM_PORT) + .virtual_com_enable = true, + .vendor_id = VIRTUAL_COM_PORT_VID, + .product_id = VIRTUAL_COM_PORT_PID, + .serial_number = VIRTUAL_COM_SERIAL_NUM +#else + .uart_tx_pin = UART_TX, + .uart_rx_pin = UART_RX, + .virtual_com_enable = false +#endif +}; + +/* Define external interrupt platform specific parameters structure */ +mbed_irq_init_param mbed_ext_int_init_param = { + .int_mode = EXT_IRQ_FALL, + .ext_int_pin = DRDY, +}; + +/* SPI Mbed platform parameters structure */ +mbed_spi_init_param mbed_spi_init_extra_params = { + .spi_clk_pin = SPI_SCK, + .spi_miso_pin = SPI_MISO, + .spi_mosi_pin = SPI_MOSI +}; + + +/******************************************************************************/ +/************************ Functions Prototypes ********************************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/app_config_mbed.h Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,72 @@ +/***************************************************************************//* + * @file app_config_mbed.h + * @brief Header file for Mbed platform configurations +****************************************************************************** + * Copyright (c) 2021 Analog Devices, Inc. + * All rights reserved. + * + * This software is proprietary to Analog Devices, Inc. and its licensors. + * By using this software you agree to the terms of the associated + * Analog Devices Software License Agreement. +******************************************************************************/ + +#ifndef _APP_CONFIG_MBED_H_ +#define _APP_CONFIG_MBED_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdint.h> +#include <PinNames.h> + +#include "uart_extra.h" +#include "irq_extra.h" +#include "spi_extra.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +// Pin mapping of AD7768-1 with arduino +#define SPI_SS D10 // SPI_CS +#define SPI_MOSI D11 // SPI_MOSI +#define SPI_MISO D12 // SPI_MISO +#define SPI_SCK D13 // SPI_SCK +#define DRDY D2 // Conversion ready interrupt + +/* Common pin mapping */ +#define UART_TX USBTX +#define UART_RX USBRX +#define LED_GREEN LED3 + +/* Define the max possible sampling frequency (or output data) rate for AD77681 (in SPS). + * This is also used to find the time period to trigger a periodic conversion event. + * Note: Max possible ODR is 64KSPS for continuous data capture on IIO Client. + * This is derived by capturing data from the firmware using the SDP-K1 controller board + * @22.5Mhz SPI clock. The max possible ODR can vary from board to board and + * data continuity is not guaranteed above this ODR on IIO oscilloscope */ + +/* AD77681 default internal clock frequency (MCLK = 16.384 Mhz) */ +#define AD77681_MCLK (16384) + +/* AD77681 decimation rate */ +#define AD77681_DECIMATION_RATE (32U) + +/* AD77681 default mclk_div value */ +#define AD77681_DEFAULT_MCLK_DIV (8) + +/* AD77681 ODR conversion */ +#define AD77681_ODR_CONV_SCALER (AD77681_DECIMATION_RATE * AD77681_DEFAULT_MCLK_DIV) + +/* AD77681 default sampling frequency */ +#define AD77681_DEFAULT_SAMPLING_FREQ ((AD77681_MCLK * 1000) / AD77681_ODR_CONV_SCALER) + +/******************************************************************************/ +/********************* Public/Extern Declarations *****************************/ +/******************************************************************************/ +extern mbed_irq_init_param mbed_ext_int_init_param; +extern mbed_uart_init_param mbed_uart_extra_init_param; +extern mbed_spi_init_param mbed_spi_init_extra_params; + +#endif /* _APP_CONFIG_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/libtinyiiod.lib Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,1 @@ +https://github.com/analogdevicesinc/libtinyiiod.git/#217b19a7e5719757ed90b48fdb57140f73d445fd \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/main.c Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,54 @@ +/***************************************************************************//** + * @file main.c + * @brief Main interface for AD7768-1 IIO firmware application + * @details +******************************************************************************** +* Copyright (c) 2021 Analog Devices, Inc. +* All rights reserved. +* +* This software is proprietary to Analog Devices, Inc. and its licensors. +* By using this software you agree to the terms of the associated +* Analog Devices Software License Agreement. +*******************************************************************************/ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include <assert.h> + +#include "ad77681_iio.h" +#include "error.h" + +/******************************************************************************/ +/********************* Macros and Constants Definition ************************/ +/******************************************************************************/ + +/******************************************************************************/ +/******************** Variables and User Defined Data Types *******************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************** Functions Declaration *****************************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************** Functions Definition ******************************/ +/******************************************************************************/ + +/* @brief Main function + * @details This is a main entry function for firmware application + */ +int main(void) +{ + if (ad77681_iio_initialize() == FAILURE) { + assert(false); + } + + while (true) { + // Execute forever loop + ad77681_iio_event_handler(); + } + + // this line should never be reached + return (FAILURE); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/mbed_platform_drivers.lib Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/AnalogDevices/code/platform_drivers/#5ae03a197e59/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/no-OS.lib Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,1 @@ +https://github.com/analogdevicesinc/no-OS/#d04b1a13621a09ed33f1ad3f83e4215433d9d60e \ No newline at end of file
--- a/main.cpp Thu Sep 02 14:02:38 2021 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* Copyright (c) 2019 Analog Devices, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 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. - - Modified versions of the software must be conspicuously marked as such. - - This software is licensed solely and exclusively for use with processors/products - manufactured by or for Analog Devices, Inc. - - This software may not be combined or merged with other code in any manner - that would cause the software to become subject to terms and conditions which - differ from those listed here. - - Neither the name of Analog Devices, Inc. nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - - The use of this software may or may not infringe the patent rights of one or - more patent holders. This license does not release you from the requirement - that you obtain separate licenses from these patent holders to use this software. - -THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, -TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL -PROPERTY RIGHTS INFRINGEMENT; 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. - -2019-01-10-7CBSD SLA -*/ - -#include "mbed.h" - -// LED Blinking rate in milliseconds (Note: need to define the unit of a time duration i.e. seconds(s) or milliseconds(ms)) -#define SLEEP_TIME 500ms - -// Initialise the digital pin that controls LED1 -DigitalOut led(LED1); -// Initialise the serial object with TX and RX pins -static BufferedSerial serial_port(USBTX, USBRX); - -// The File handler is needed to allow printf commands to write to the terminal -FileHandle *mbed::mbed_override_console(int fd) -{ - return &serial_port; -} - -// main() runs in its own thread in the OS -int main() -{ - // printing the Mbed OS version this example was written to the console - printf("This Application has been developed on Mbed OS version 6.4\r\n"); - - // printing the actual Mbed OS version that this application is using to the console. - printf( - "Mbed OS version %d.%d.%d is what this applicaiton is currently using\r\n", - MBED_MAJOR_VERSION, - MBED_MINOR_VERSION, - MBED_PATCH_VERSION - ); - - // The loop will toggle the LED every 500ms(SLEEP_TIME = 500ms) and print LED1s current state to the terminal - while (1) { - led = !led; // toggle LED1 state - printf("LED1 state: %d \r\n", (uint8_t)led); - ThisThread::sleep_for(SLEEP_TIME); - } -} -
--- a/mbed-os.lib Thu Sep 02 14:02:38 2021 +0000 +++ b/mbed-os.lib Fri Sep 24 15:14:06 2021 +0100 @@ -1,1 +1,1 @@ -https://github.com/ARMmbed/mbed-os/#8ef0a435b2356f8159dea8e427b2935d177309f8 +https://github.com/ARMmbed/mbed-os/#26606218ad9d1ee1c8781aa73774fd7ea3a7658e \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed_app.json Fri Sep 24 15:14:06 2021 +0100 @@ -0,0 +1,22 @@ +{ + "config": { + "usb_speed": { + "help": "USE_USB_OTG_FS or USE_USB_OTG_HS or USE_USB_HS_IN_FS", + "value": "USE_USB_OTG_HS" + } + }, + "requires": ["bare-metal", "drivers-usb", "events"], + "macros": [ + "TINYIIOD_VERSION_MAJOR=0", + "TINYIIOD_VERSION_MINOR=1", + "TINYIIOD_VERSION_GIT=\"0.1\"", + "IIOD_BUFFER_SIZE=0x1000", + "_USE_STD_INT_TYPES" + ], + "target_overrides": { + "*": { + "platform.default-serial-baud-rate": 230400, + "target.printf_lib": "std" + } + } +} \ No newline at end of file