主题中讨论的其他部件:ADS124S08
您好,
我将ASD124S08 EVM https://www.ti.com/tool/ADS124S08EVM上的JP1短接 ,以便可以使用另一个微控制器来控制它以开发Linux驱动程序,并且我无法读取或写入寄存器。
请参阅以下设置:
微控制器: nrf5340-dk
RTOS:Zephyr.
SDK:nrf SDK 1.8 .........0
SPI时钟:5MHz
尝试读回所有寄存器时。 我得到全零。
为了测试SPI读取寄存器操作,我有一个无限的while循环来读取数据速率寄存器。

下面是生成的波形:

如上所示,在发出RREAD命令后,似乎根本没有读取寄存器。

请参阅下面的驱动程序源代码,请参阅ads124s08.c底部的宏和ads124s08_SPI.c中的SPI实现:
ads124s08.c
#define DT_DRV_COMPAT ti_ads124s08
#include <init.h>
#include <sys/byteorder.h>
#include <sys/__assert.h>
#include <logging/log.h>
LOG_MODULE_REGISTER(ads124s08, CONFIG_SENSOR_LOG_LEVEL);
#include "ads124s08.h"
#include <devicetree.h>
#include <drivers/gpio.h>
#include <nrf.h>
#include <hal/nrf_gpio.h>
static const struct device *dev_start;
static const struct device *dev_reset;
// configure GPIO Pins for CS, Start and reset
static void init_gpio(void) {
int status;
dev_reset = device_get_binding(ADS124S08_RESET_LABEL);
if (dev_reset == NULL){
LOG_ERR("dev_reset device_get_binding() failure.");
return;
}
status = gpio_pin_configure(dev_reset, ADS124S08_RESET_PIN, GPIO_OUTPUT_ACTIVE);
if (status < 0){
LOG_ERR("dev_reset gpio_pin_configure() failure.");
return;
}
dev_start= device_get_binding(ADS124S08_START_LABEL);
if (dev_start == NULL){
LOG_ERR("dev_start device_get_binding() failure.");
return;
}
status = gpio_pin_configure(dev_start, ADS124S08_START_PIN, GPIO_OUTPUT_ACTIVE);
if (status < 0){
LOG_ERR("dev_start gpio_pin_configure() failure.");
return;
}
#ifndef CONFIG_ADS124S08_TRIGGER
nrf_gpio_cfg_input(DRDY_PIN, NRF_GPIO_PIN_PULLUP);
#endif
}
static void ads124s08_set_start_pin(int STATE){
gpio_pin_set(dev_start, ADS124S08_START_PIN, STATE);
}
static void ads124s08_set_reset_pin(int STATE){
gpio_pin_set(dev_reset, ADS124S08_RESET_PIN, STATE);
}
static const struct sensor_driver_api ads124s08_driver_api = {
// .attr_set = ads124s08_attr_set,
#if CONFIG_ADS124S08_TRIGGER
.trigger_set = ads124s08_trigger_set,
#endif
// .sample_fetch = ads124s08_sample_fetch,
// .channel_get = ads124s08_channel_get,
};
static int ads124s08_reset(const struct device *dev){
#if ENABLE_SOFT_CONFIGS // software reset
struct ads124s08_data *ads124s08 = dev->data;
ctrl = ADS124S08_CMD_RESET;
ads124s08_spi_cmd_send(dev, ctrl);
#else // hardware reset
ads124s08_set_reset_pin(HIGH);
k_sleep(K_MSEC(100));
ads124s08_set_reset_pin(LOW);
k_sleep(K_MSEC(100));
ads124s08_set_reset_pin(HIGH);
k_sleep(K_MSEC(100));
#endif
return 0;
}
static int ads124s08_init(const struct device *dev)
{
struct ads124s08_data *ads124s08 = dev->data;
const struct ads124s08_config *cfg = dev->config;
int status;
ads124s08->bus = device_get_binding(cfg->bus_name);
if (!ads124s08->bus) {
LOG_ERR("master not found: %s", cfg->bus_name);
return -EINVAL;
}
cfg->bus_init(dev);
init_gpio();
//Reset Device
status = ads124s08_reset(dev);
uint8_t reg;
while (1){
status = ads124s08->hw_tf->read_reg(dev,ADS124S08_REG_DATARATE, ® );
LOG_INF("ADS124S08_REG_DATARATE: %x", reg);
k_sleep(K_MSEC(1000));
}
if (status < 0){
LOG_ERR("ads124s08_init(). Unable to read status register");
}
return 0;
}
#if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
#warning "ADS124S08 driver enabled without any devices"
#endif
/*
* Device creation macro, shared by ADS124S08_DEFINE_SPI() and
*/
#define ADS124S08_DEVICE_INIT(inst) \
DEVICE_DT_INST_DEFINE(inst, \
ads124s08_init, \
NULL, \
&ads124s08_data_##inst, \
&ads124s08_config_##inst, \
POST_KERNEL, \
CONFIG_SENSOR_INIT_PRIORITY, \
&ads124s08_driver_api);
#define IS_LSM303AGR_DEV(inst) \
DT_NODE_HAS_COMPAT(DT_DRV_INST(inst), st_lsm303agr_accel)
#define DISC_PULL_UP(inst) \
DT_INST_PROP(inst, disconnect_sdo_sa0_pull_up)
/*
* Instantiation macros used when a device is on a SPI bus.
*/
#define ADS124S08_HAS_CS(inst) DT_INST_SPI_DEV_HAS_CS_GPIOS(inst)
#define ADS124S08_DATA_SPI_CS(inst) \
{ .cs_ctrl = { \
.gpio_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(inst), \
.gpio_dt_flags = DT_INST_SPI_DEV_CS_GPIOS_FLAGS(inst), \
}, \
}
#define ADS124S08_DATA_SPI(inst) \
COND_CODE_1(ADS124S08_HAS_CS(inst), \
(ADS124S08_DATA_SPI_CS(inst)), \
({}))
#define ADS124S08_SPI_CS_PTR(inst) \
COND_CODE_1(ADS124S08_HAS_CS(inst), \
(&(ads124s08_data_##inst.cs_ctrl)), \
(NULL))
#define ADS124S08_SPI_CS_LABEL(inst) \
COND_CODE_1(ADS124S08_HAS_CS(inst), \
(DT_INST_SPI_DEV_CS_GPIOS_LABEL(inst)), (NULL))
#define ADS124S08_SPI_CFG(inst) \
(&(struct ads124s08_spi_cfg) { \
.spi_conf = { \
.frequency = \
DT_INST_PROP(inst, spi_max_frequency), \
.operation = (SPI_WORD_SET(8) | \
SPI_OP_MODE_MASTER | \
SPI_MODE_CPOL | \
SPI_MODE_CPHA), \
.slave = DT_INST_REG_ADDR(inst), \
.cs = ADS124S08_SPI_CS_PTR(inst), \
}, \
.cs_gpios_label = ADS124S08_SPI_CS_LABEL(inst), \
})
#ifdef CONFIG_ADS124S08_TRIGGER
#define GPIO_DT_SPEC_INST_GET_BY_IDX_COND(id, prop, idx) \
COND_CODE_1(DT_INST_PROP_HAS_IDX(id, prop, idx), \
(GPIO_DT_SPEC_INST_GET_BY_IDX(id, prop, idx)), \
({.port = NULL, .pin = 0, .dt_flags = 0}))
#else
#define ADS124S08_CFG_INT(inst)
#endif /* CONFIG_ADS124S08_TRIGGER */
#define ADS124S08_CONFIG_SPI(inst) \
{ \
.bus_name = DT_INST_BUS_LABEL(inst), \
.bus_init = ads124s08_spi_init, \
.bus_cfg = { .spi_cfg = ADS124S08_SPI_CFG(inst) }, \
ADS124S08_CFG_INT(inst) \
}
#define ADS124S08_DEFINE_SPI(inst) \
static struct ads124s08_data ads124s08_data_##inst = \
ADS124S08_DATA_SPI(inst); \
static const struct ads124s08_config ads124s08_config_##inst = \
ADS124S08_CONFIG_SPI(inst); \
ADS124S08_DEVICE_INIT(inst)
/*
* Main instantiation macro. Use of COND_CODE_1() selects the right
* bus-specific macro at preprocessor time.
*/
#define ADS124S08_DEFINE(inst) \
COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
(ADS124S08_DEFINE_SPI(inst)), \
)
DT_INST_FOREACH_STATUS_OKAY(ADS124S08_DEFINE)
ADS124s08_SPI.c
/* * * Datasheet: * www.ti.com/.../ADS124S08 */ #define DT_DRV_COMPAT ti_ads124s08 #include <string.h> #include "ads124s08.h" #include <logging/log.h> #include <hal\nrf_gpio.h> #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) LOG_MODULE_DECLARE(ads124s08, CONFIG_SENSOR_LOG_LEVEL); /* ADS124S08 supports only SPI mode 0, word size 8 bits, MSB first */ #define ADS124S08_SPI_CFG SPI_WORD_SET(8) static int ads124s08_spi_write(const struct device *dev,uint8_t value, uint8_t len) { struct ads124s08_data *data = dev->data; const struct ads124s08_config *cfg = dev->config; const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; const struct spi_buf tx_buf = { .buf = &value, .len = 1, }; const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 }; if (len > 64) { return -EIO; } nrf_gpio_pin_clear(data->cs_ctrl.gpio_pin); if (spi_write(data->bus, spi_cfg, &tx)) { return -EIO; } nrf_gpio_pin_set(data->cs_ctrl.gpio_pin); return 0; } static int ads124s08_spi_read(const struct device *dev,uint8_t *value, uint8_t len) { struct ads124s08_data *data = dev->data; const struct ads124s08_config *cfg = dev->config; const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; uint8_t buffer_tx[1] = {ADS124S08_CMD_NOP}; const struct spi_buf tx_buf = { .buf = buffer_tx, .len = 1, }; const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 }; const struct spi_buf rx_buf[2] = { { .buf = NULL, .len = 2, }, { .buf = value, .len = len, } }; const struct spi_buf_set rx = { .buffers = rx_buf, .count = 2 }; if (len > 64) { return -EIO; } if (len > 1) { buffer_tx[0] |= 0x0; } nrf_gpio_pin_clear(data->cs_ctrl.gpio_pin); if (spi_transceive(data->bus, spi_cfg, &tx, &rx)) { return -EIO; } nrf_gpio_pin_set(data->cs_ctrl.gpio_pin); return 0; } static int ads124s08_reg_read(const struct device *dev, uint8_t reg_addr, uint8_t *pRxData) { struct ads124s08_data *data = dev->data; const struct ads124s08_config *cfg = dev->config; const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; const uint8_t len = 2; // read back 4 bytes from reg uint8_t buffer_tx[3]; buffer_tx[0] = ((ADS124S08_START_REG_MASK & reg_addr ) | ADS124S08_CMD_RREG); buffer_tx[1] = 0x00; //number of registers to read minus 1 buffer_tx[2] = 0x00 ; // no op const struct spi_buf tx_buf = { .buf = buffer_tx, .len = 3, }; const struct spi_buf_set tx = { .buffers = &tx_buf, .count = 1 }; const struct spi_buf rx_buf[2] = { { .buf = NULL, .len = 1, }, { .buf = pRxData, .len = len, } }; const struct spi_buf_set rx = { .buffers = rx_buf, .count = 2 }; if (len > 64) { return -EIO; } if (len > 1) { buffer_tx[0] |= 0x0; } nrf_gpio_pin_clear(data->cs_ctrl.gpio_pin); if (spi_transceive(data->bus, spi_cfg, &tx, &rx)) { return -EIO; } nrf_gpio_pin_set(data->cs_ctrl.gpio_pin); return 0; } static int ads124s08_reg_write(const struct device *dev, uint8_t reg_addr, uint8_t *value, uint8_t len) { struct ads124s08_data *data = dev->data; const struct ads124s08_config *cfg = dev->config; const struct spi_config *spi_cfg = &cfg->bus_cfg.spi_cfg->spi_conf; uint8_t buffer_tx[2] = { ( reg_addr & ADS124S08_START_REG_MASK) | ADS124S08_CMD_WREG , 0}; const struct spi_buf tx_buf[2] = { { .buf = buffer_tx, .len = 2, }, { .buf = value, .len = len, } }; const struct spi_buf_set tx = { .buffers = tx_buf, .count = 1 }; if (len > 64) { return -EIO; } // if (len > 1) { // buffer_tx[0] |= ADS124S08_SPI_AUTOINC; // } if (spi_write(data->bus, spi_cfg, &tx)) { return -EIO; } return 0; } static int adsd124s08_read_sample(const struct device *dev, uint8_t *value, uint8_t len){ return ads124s08_spi_read(dev,value,len); } static int adsd124s08_write_command(const struct device *dev, uint8_t value){ return ads124s08_spi_write(dev,value,1); } static int ads124s08_spi_read_reg(const struct device *dev, uint8_t reg_addr, uint8_t *value) { return ads124s08_reg_read(dev, reg_addr, value); } static int ads124s08_spi_write_reg(const struct device *dev, uint8_t reg_addr, uint8_t value) { uint8_t tmp_val = value; return ads124s08_reg_write(dev, reg_addr, &tmp_val, 1); } static const struct ads124s08_transfer_function ads124s08_spi_transfer_fn = { .read_reg = ads124s08_spi_read_reg, .write_reg = ads124s08_spi_write_reg, .read_samp = adsd124s08_read_sample, .write_command = adsd124s08_write_command, }; int ads124s08_spi_init(const struct device *dev) { struct ads124s08_data *data = dev->data; const struct ads124s08_config *cfg = dev->config; const struct ads124s08_spi_cfg *spi_cfg = cfg->bus_cfg.spi_cfg; data->hw_tf = &ads124s08_spi_transfer_fn; if (spi_cfg->cs_gpios_label != NULL) { /* handle SPI CS thru GPIO if it is the case */ data->cs_ctrl.gpio_dev = device_get_binding(spi_cfg->cs_gpios_label); if (!data->cs_ctrl.gpio_dev) { LOG_ERR("Unable to get GPIO SPI CS device"); return -ENODEV; } LOG_ERR("SPI GPIO CS configured on %s:%u", spi_cfg->cs_gpios_label, data->cs_ctrl.gpio_pin); } return 0; } #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
ads124s08.h
#ifndef ZEPHYR_DRIVERS_SENSOR_ADS124S08_ADS124S08_H_
#define ZEPHYR_DRIVERS_SENSOR_ADS124S08_ADS124S08_H_
#include <kernel.h>
#include <device.h>
#include <sys/util.h>
#include <stdint.h>
#include <drivers/gpio.h>
#include <drivers/sensor.h>
#include <string.h>
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
#include <drivers/spi.h>
#endif
#define DEBUG_MODE (1)
#if(DEBUG_MODE)
#define DEBUG_PRINT printk
#else
#define DEBUG_PRINT(...)
#endif
#define HIGH (0xFF)
#define LOW (0x00)
#define MULTI_CHANNEL_READ (0) // read through every channel
#define ENABLE_SOFT_CONFIGS (0)
// #define SINGLE_SHOT_MODE
#if defined(SINGLE_SHOT_MODE)
#define SINGLE_SHOT_MODE_BIT (0x20)
#else
#define SINGLE_SHOT_MODE_BIT (0x00)
#endif
// GPIO Pins
// #define ADS124S08_CS_LABEL DT_GPIO_LABEL(DT_ALIAS(gpiocus0), gpios)
// #define ADS124S08_CS_PIN DT_GPIO_PIN(DT_ALIAS(gpiocus0), gpios)
#define ADS124S08_RESET_LABEL DT_GPIO_LABEL(DT_ALIAS(gpiocus1), gpios)
#define ADS124S08_RESET_PIN DT_GPIO_PIN(DT_ALIAS(gpiocus1), gpios)
#define ADS124S08_START_LABEL DT_GPIO_LABEL(DT_ALIAS(gpiocus2), gpios)
#define ADS124S08_START_PIN DT_GPIO_PIN(DT_ALIAS(gpiocus2), gpios)
// Interrupt Pins
#if DT_INST_PROP_HAS_IDX(0, irq_gpios, 1)
/* INT1 is configured */
#define ADS124S08_INT1_GPIOS_PIN DT_INST_GPIO_PIN_BY_IDX(0, irq_gpios, 0)
#define ADS124S08_INT1_GPIOS_FLAGS DT_INST_GPIO_FLAGS_BY_IDX(0, irq_gpios, 0)
#define ADS124S08_INT1_GPIO_DEV_NAME DT_INST_GPIO_LABEL_BY_IDX(0, irq_gpios, 0)
#else
#define ADS124S08_INT1_GPIOS_PIN DT_INST_GPIO_PIN(0, irq_gpios)
#define ADS124S08_INT1_GPIOS_FLAGS DT_INST_GPIO_FLAGS(0, irq_gpios)
#define ADS124S08_INT1_GPIO_DEV_NAME DT_INST_GPIO_LABEL(0, irq_gpios)
#endif
#define DRDY_PIN (43)
#define RES (double)((double)VREF/pow(2,23))
// Commands
#define ADS124S08_CMD_NOP 0x00
#define ADS124S08_CMD_WAKEUP 0x02
#define ADS124S08_CMD_PWRDWN 0x04
#define ADS124S08_CMD_RESET 0x06
#define ADS124S08_CMD_START 0x08
#define ADS124S08_CMD_STOP 0x0A
#define ADS124S08_CMD_SYOCAL 0x16
#define ADS124S08_CMD_SYGCAL 0x17
#define ADS124S08_CMD_SFOCAL 0x19
#define ADS124S08_CMD_RDATA 0x12
#define ADS124S08_CMD_RREG 0x20
#define ADS124S08_CMD_WREG 0x40
// Registers
#define ADS124S08_REG_ID 0x00
#define ADS124S08_REG_STATUS 0x01
#define ADS124S08_REG_INPMUX 0x02
#define ADS124S08_REG_PGA 0x03
#define ADS124S08_REG_DATARATE 0x04
#define ADS124S08_REG_REF 0x05
#define ADS124S08_REG_IDACMAG 0x06
#define ADS124S08_REG_IDACMUX 0x07
#define ADS124S08_REG_VBIAS 0x08
#define ADS124S08_REG_SYS 0x09
#define ADS124S08_REG_OFCAL0 0x0A
#define ADS124S08_REG_OFCAL1 0x0B
#define ADS124S08_REG_OFCAL2 0x0C
#define ADS124S08_REG_FSCAL0 0x0D
#define ADS124S08_REG_FSCAL1 0x0E
#define ADS124S08_REG_FSCAL2 0x0F
#define ADS124S08_REG_GPIODAT 0x10
#define ADS124S08_REG_GPIOCON 0x11
/* ADS124S0x common channels */
#define ADS124S08_AIN0 0x00
#define ADS124S08_AIN1 0x01
#define ADS124S08_AIN2 0x02
#define ADS124S08_AIN3 0x03
#define ADS124S08_AIN4 0x04
#define ADS124S08_AIN5 0x05
#define ADS124S08_AINCOM 0x0c
#define ADS124S08_AIN6 0x06
#define ADS124S08_AIN7 0x07
#define ADS124S08_AIN8 0x08
#define ADS124S08_AIN9 0x09
#define ADS124S08_AIN10 0x0a
#define ADS124S08_AIN11 0x0b
#define ADS124S08_MAX_CHANNELS 12
#define ADS124S08_POS_MUX_SHIFT 0x04
#define ADS124S08_INT_REF 0x09
#define ADS124S08_START_REG_MASK 0x1f
#define ADS124S08_NUM_BYTES_MASK 0x1f
#define ADS124S08_START_CONV 0x01
#define ADS124S08_STOP_CONV 0x00
#define ADS124S08_CHIP_ID 0x00
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
struct ads124s08_spi_cfg {
struct spi_config spi_conf;
const char *cs_gpios_label;
};
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
union ads124s08_bus_cfg {
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
const struct ads124s08_spi_cfg *spi_cfg;
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
};
struct ads124s08_config {
const char *bus_name;
int (*bus_init)(const struct device *dev);
const union ads124s08_bus_cfg bus_cfg;
};
struct ads124s08_transfer_function {
int (*read_reg)(const struct device *dev, uint8_t reg_addr,
uint8_t *value);
int (*write_reg)(const struct device *dev, uint8_t reg_addr,
uint8_t value);
int (*read_samp)(const struct device *dev, uint8_t *value, uint8_t len);
int (*write_command)(const struct device *dev, uint8_t value);
};
union asd124s08_sample{
uint8_t bytes[3];
uint32_t raw[1];
};
struct ads124s08_data {
const struct device *bus;
const struct ads124s08_transfer_function *hw_tf;
union asd124s08_sample sample;
uint8_t tempRecordings[18]; // 3 bytes per sample * 6 channels = 18 bytes
#ifdef CONFIG_ADS124S08_TRIGGER
const struct device *dev;
const struct device *gpio_int1;
struct gpio_callback gpio_int1_cb;
sensor_trigger_handler_t handler_drdy;
atomic_t trig_flags;
enum sensor_channel chan_drdy;
#if defined(CONFIG_ADS124S08_TRIGGER_OWN_THREAD)
K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ADS124S08_THREAD_STACK_SIZE);
struct k_thread thread;
struct k_sem gpio_sem;
#elif defined(CONFIG_ADS124S08_TRIGGER_GLOBAL_THREAD)
struct k_work work;
#endif
#endif /* CONFIG_ADS124S08_TRIGGER */
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
struct spi_cs_control cs_ctrl;
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(spi) */
};
#ifdef CONFIG_ADS124S08_TRIGGER
int ads124s08_trigger_set(const struct device *dev,
const struct sensor_trigger *trig,
sensor_trigger_handler_t handler);
int ads124s08_init_interrupt(const struct device *dev);
#endif
int ads124s08_spi_init(const struct device *dev);
#endif
覆盖文件:
/*
* Copyright (c) 2019 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
&spi2 {
compatible = "nordic,nrf-spim";
status = "okay";
sck-pin = <47>;
mosi-pin = <45>;
miso-pin = <46>;
cs-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
ads124s08@0 {
compatible = "ti,ads124s08";
label = "ADS124S08";
spi-max-frequency = <5000000>;
reg = <0>;
irq-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
};
};
&uart0 {
status = "okay";
current-speed = <115200>;
tx-pin = <20>;
rx-pin = <22>;
rts-pin = <19>;
cts-pin = <21>;
};
/ {
gpiocustom {
compatible = "gpio-keys";
// gpiocus0: gpiocus_0 {
// gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
// label = "CS";
// };
gpiocus1: gpiocus_1 {
gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
label = "RESET";
};
gpiocus2: gpiocus_2 {
gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>;
label = "START";
};
};
aliases {
// gpiocus0 = &gpiocus0;
gpiocus1 = &gpiocus1;
gpiocus2 = &gpiocus2;
};
};
如有任何帮助,我们将不胜感激。
谢谢!
马特



