/***************************************************************************//**
* @file ad7689.c
* @brief Source file for the ad7689 driver
* @author Darius Berghe (darius.berghe@analog.com)
********************************************************************************
* Copyright 2021(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 <stdlib.h>
#include "ad7689.h"
#include "no_os_util.h"
#include "no_os_error.h"
#include "no_os_print_log.h"
#include "no_os_delay.h"
#include "no_os_alloc.h"
const char *ad7689_device_name[] = {
"AD7689",
"AD7682",
"AD7949",
"AD7699",
};
static void _ad7689_config_put(struct ad7689_dev *dev,
struct ad7689_config *config)
{
dev->configs[1] = dev->configs[0];
if (config)
dev->configs[0] = *config;
else
dev->configs[0] = dev->configs[1];
}
static struct ad7689_config *_ad7689_config_get(struct ad7689_dev *dev)
{
// dev->configs[1] is the config currently in use. If the current
// SPI transaction is numbered N, this config was written at N-2
// and applied at the EOC of N-1.
return &dev->configs[1];
}
static int32_t _ad7689_rac(struct ad7689_dev *dev,
struct ad7689_config *config_in, struct ad7689_config *config_out,
uint16_t *data)
{
int32_t ret;
uint16_t cfg = 0;
uint8_t buf[4] = {0, 0, 0, 0};
uint16_t sz;
struct ad7689_config *c;
if (!dev)
return -EINVAL;
c = _ad7689_config_get(dev);
if (config_in) {
cfg |= no_os_field_prep(AD7689_CFG_CFG_MSK, 1);
cfg |= no_os_field_prep(AD7689_CFG_INCC_MSK, config_in->incc);
cfg |= no_os_field_prep(AD7689_CFG_INX_MSK, config_in->inx);
cfg |= no_os_field_prep(AD7689_CFG_BW_MSK, config_in->bw);
cfg |= no_os_field_prep(AD7689_CFG_REF_MSK, config_in->ref);
cfg |= no_os_field_prep(AD7689_CFG_SEQ_MSK, config_in->seq);
cfg |= no_os_field_prep(AD7689_CFG_RB_MSK, !config_in->rb);
cfg <<= 2;
buf[0] = cfg >> 8;
buf[1] = cfg;
}
sz = c->rb && config_out ? 4 : 2;
ret = no_os_spi_write_and_read(dev->spi_desc, buf, sz);
if (ret < 0)
return ret;
_ad7689_config_put(dev, config_in);
if (data) {
// by default, data width is 16-bits
*data = ((uint16_t)buf[0] << 8) | buf[1];
// handle 14-bit data width:
if (dev->id == ID_AD7949) {
// Bipolar samples are in two's complement, scale down to 14-bit
// by keeping the sign bit using division instead of implementation
// specific right shift. This works for unipolar samples too.
*data = (int16_t)*data / 4;
}
}
if (c->rb && config_out) {
if (dev->id == ID_AD7949)
cfg = (((uint32_t)buf[1] << 16) | ((uint32_t)buf[2] << 8) | buf[3]) >> 2;
else
cfg = ((uint16_t)buf[2] << 8) | buf[3];
cfg >>= 2;
config_out->incc = no_os_field_get(AD7689_CFG_INCC_MSK, cfg);
config_out->inx = no_os_field_get(AD7689_CFG_INX_MSK, cfg);
config_out->bw = no_os_field_get(AD7689_CFG_BW_MSK, cfg);
config_out->ref = no_os_field_get(AD7689_CFG_REF_MSK, cfg);
config_out->seq = no_os_field_get(AD7689_CFG_SEQ_MSK, cfg);
config_out->rb = !(bool)no_os_field_get(AD7689_CFG_RB_MSK, cfg);
}
return 0;
}
/***************************************************************************//**
* @brief Initialize the ad7689 driver and create a descriptor.
*
* @param dev - Device descriptor to create.
* @param init_param - Initialization parameters.
*
* @return Returns negative error code or 0 in case of success.
* Example: -EINVAL - Bad input parameters.
* -ENOMEM - Failed to allocate memory.
* 0 - No errors encountered.
*******************************************************************************/
int32_t ad7689_init(struct ad7689_dev **dev,
struct ad7689_init_param *init_param)
{
struct ad7689_dev *d;
int32_t ret;
if (init_param->id > ID_AD7699)
return -EINVAL;
d = (struct ad7689_dev *)no_os_calloc(1, sizeof(*d));
if (!d)
return -ENOMEM;
d->id = init_param->id;
d->name = ad7689_device_name[d->id];
ret = no_os_spi_init(&d->spi_desc, &init_param->spi_init);
if (ret < 0)
goto error_spi;
ret = ad7689_write_config(d, &init_param->config);
if (ret < 0)
goto error_init;
// perform one extra dummy conversion (2 are needed after power-up)
ret = _ad7689_rac(d, NULL, NULL, NULL);
if (ret < 0)
goto error_init;
*dev = d;
return 0;
error_init:
no_os_spi_remove(d->spi_desc);
error_spi:
no_os_free(d);
pr_err("%s initialization failed with status %d\n", d->name,
ret);
return ret;
}
/***************************************************************************//**
* @brief Write the device's CFG register.
*
* @param dev - Device descriptor.
* @param config - Configuration to write.
*
* @return Returns negative error code or 0 in case of success.
* Example: -EINVAL - Bad input parameters.
* 0 - No errors encountered.
*******************************************************************************/
int32_t ad7689_write_config(struct ad7689_dev *dev,
struct ad7689_config *config)
{
return _ad7689_rac(dev, config, NULL, NULL);
}
/***************************************************************************//**
* @brief Read the device's CFG register.
*
* If the readback is enabled when making this call, one SPI transaction
* is enough to retrieve the CFG register.
*
* If the readback is disabled when making this call, it is temporarily
* enabled, then disabled back. 3 SPI transactions are needed to retrieve
* the CFG register.
*
* @param dev - Device descriptor.
* @param config - pointer to location where the read configuration gets stored.
*
* @return Returns negative error code or 0 in case of success.
* Example: -EINVAL - Bad input parameters.
* 0 - No errors encountered.
*******************************************************************************/
int32_t ad7689_read_config(struct ad7689_dev *dev, struct ad7689_config *config)
{
int32_t ret = 0;
struct ad7689_config *c = _ad7689_config_get(dev);
if (c->rb == true)
return _ad7689_rac(dev, NULL, config, NU
没有合适的资源?快使用搜索试试~ 我知道了~
AD7689通用驱动C语言代码
共2个文件
h:1个
c:1个
需积分: 0 27 下载量 75 浏览量
2024-02-25
23:56:33
上传
评论 1
收藏 4KB 7Z 举报
温馨提示
#define AD7689_CFG_CFG_MSK NO_OS_BIT(13) #define AD7689_CFG_INCC_MSK NO_OS_GENMASK(12,10) #define AD7689_CFG_INX_MSK NO_OS_GENMASK(9,7) #define AD7689_CFG_BW_MSK NO_OS_BIT(6) #define AD7689_CFG_REF_MSK NO_OS_GENMASK(5,3) #define AD7689_CFG_SEQ_MSK NO_OS_GENMASK(2,1) #define AD7689_CFG_RB_MSK NO_OS_BIT(0) /** * @enum ad7689_device_id * @brief Device ID definitions */ enum ad7689_device_id { /** 16-Bit, 8-Channel, 250 kSPS PulSAR ADC */ ID_AD7689, /** 16
资源推荐
资源详情
资源评论
收起资源包目录
AD7689_Driver.7z (2个子文件)
AD7689_Driver
ad7689.h 6KB
ad7689.c 10KB
共 2 条
- 1
资源评论
逆水东流
- 粉丝: 34
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功