This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] ADS8668:未将写入值获取到寄存器

Guru**** 1693050 points
Other Parts Discussed in Thread: ADS8668
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/1082997/ads8668-not-get-written-value-to-a-register

部件号:ADS8668
“线程:测试”中讨论的其它部件,

代码:

#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <Linux/SPI/spedev.h>

#define 卫生组织_am_I_REG 0x75
#define 卫生组织_am_I_Expected VAL 0x91
#define ACCEL_CONFIG_REG 0x28
#define gyro_config_REG 0x27
#define using _write_FUNC 0

静态 const char *设备="/dev/spidev0.0";
静态 uint8_t 模式= SPI_MODE_1;
静态 uint8_t 位=8;
静态 UINT32_t SPI_speed_Hz = 1000;
静态 int transfer_len =4;
静态 int fd;

/********************************************* //**
 *初始化 SPI 功能
 (小一 /
Int payload_board_SPI_INIT (空)

 内部支架=0;
 
 FD =开路(设备,O_RDWR);
 如果(FD < 0){
 错误(“无法打开设备”);
 返回-1;
 }

 //SPI 模式
 //模式= SPI_MODE_1;
 RET = ioctl (FD,SPI_IOC_WR_MODE,&MODE);
 如果(转台< 0){
 perror (“无法设置 SPI 模式”);
 返回支架;
 }

 //每字位数
 RET = ioctl (FD,SPI_IOC_WR_Bits_Per 字,&Bits);
 如果 (转台< 0)为{
 错误("SPI_IOC_MESSAGE");
 返回支架;
 }

 //最大速度 Hz
 RET = ioctl (FD,SPI_IOC_WR_MAX_SPEED _Hz,&SPI_SPEED _Hz);
 如果(转台< 0){
 错误(“无法设置最大速度 Hz”);
 返回支架;
 }

 返回0;

 //还有其他 IOCTL 与此无关  
 //特定从属设备。
}

/********************************************* //**
 *从 SPI 从属设备寄存器读取一个字节。
 *
 *@param reg_addr 是要读取的寄存器的地址。
 *@param read_buffer 是指向读取数据字节所在变量的指针
 *将被存储。
 *
 *@成功返回0。否则-1。
 (小一 /
静态整数 ICG_20660_REG_READ (uint8_t REG_addr,uint8_t* read_buffer)

 结构 SPI_IOC_TRANSFER tr;
 内部支架;
 UINT8_t wr_data[2]={0};
 UINT8_t rd_data[2]={0};

 memset(&tr, 0, sizeof(tr ));//清除任何无效数据。 这是必需的。
 TR.TX_Buf =(无符号长) wr_data;
 TR.Rx_buf =(无符号长) rd_data;
 tr.len = transfer_len,//一个完整的读/写周期由16位数据传输组成。

 //set Bit7 (位7)以告知从属设备我们正在读取数据。
 WR_DATA[0]=(REG_ADDR|0x80);

 RET = ioctl (FD,SPI_IOC_MESSAGE (1),&tr);
 如果(转台< 1){
 Perror("[payload IMU] can't send SPI message");
 返回-1;
 }否则
 //我们已经读取了2个字节的数据。 但第一个字节是垃圾。
 read_buffer[0]= rd_data[1];
 返回0;
 }
}

/********************************************* //**
 *将一个字节写入 SPI 从属设备寄存器。
 *
 *@param reg_addr 是要写入的寄存器的地址。
 *@param write_data 是要写入的8位数据。
 *
 *@成功返回0。否则-1。
 (小一 /
内部 ICG_20660_REG_WRITE (uint8_t REG_addr,uint8_t write_data)

 结构 SPI_IOC_TRANSFER tr;
 内部支架;
 UINT8_t wr_data[4]={0};
 UINT8_t rd_data[4]={0};

 memset(&tr, 0, sizeof(tr ));//清除任何无效数据。 这是必需的。
 TR.TX_Buf =(无符号长) wr_data;
 TR.Rx_buf =(无符号长) rd_data;
 tr.len = transfer_len,//一个完整周期由16位数据传输组成。

 //重置 Bit7以告诉从属设备我们正在写入。
 WR 数据[0]= REG_ADDR;
 WR_DATA[1]=写入数据;

 RET = ioctl (FD,SPI_IOC_MESSAGE (1),&tr);
printf("\n 写入缓冲:%X %X %X \n",wr_data[0],wr_data[1],wr_data[2],wr_data[3]);
 
printf("读取缓冲区:%X %X %X \n",rd_data[0],rd_data[1],rd_data[2],rd_data[3]);
如果(转台< 1){
 perror ("[error][payload IMU]无法发送 SPI 消息");
 返回-1;
 }否则
 返回0;
 }
}

/********************************************* //**
 *启动有效载荷板 SPI 接口测试。
 *
 *@param Response_buffer 是指向 TLV 所在缓冲区的指针  
 *将存储来自测试功能的响应。
 *
 *@返回接收到的 TLV 字符串的长度
 (小一 /
int cmd_pld_imU_SPI_test (char* response 缓冲区)

 UINT8_t val_read = 0;
 内部支架;
 char* pass_string =“04000300140000010004PASS \r\n”;
 char* ffail_string =“04000300320000010004FIL0000020008buserror\r\n”;

 RET = ICG_20660_REG_READ (WH_AM_I_REG,&VAL_READ);
 如果(ret<0){
 strcpy (Response_buffer,fail_string);
 printf("[错误][payload IMU]读取错误\n");
 返回 strlen (response 缓冲区);
 }
 
 如果(val_read = Wher_am_I_Expected _VAL){
 strcpy (Response_buffer,pass_string);
 返回 strlen (response 缓冲区);
 }否则
 strcpy (Response_buffer,fail_string);
 printf("[错误][payload IMU]意外的 WAT_AM_I 值:0x%x\n",val_read;
 返回 strlen (response 缓冲区);
 }

}

Int main (无效)

printf("\nStart\n");
内部支架;
RET = payload_board_SPI_INIT();
printf("\nret =%d",ret);

内部 I =10;
当时(i>0)

RET = ICG_20660_REG_WRITE (0b11,0xff);
printf("\nret =%d",ret);
睡眠(1);
RET = ICG_20660_REG_WRITE (0b11,0xa5);
printf("\nret =%d",ret);
一;
}
关闭(FD);
}

 

计时图  

问题:

在使用上述代码测试 ADS8668时, 我遇到了一个意外的行为,即写入到0x2寄存器的值在16时钟后没有得到。在这里,我使用的是 SPI 模式1,但数据在16时钟的下缘偏移,而不是前缘17时钟。我想是 出现问题。请帮助我避免意外结果

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,BIBIN,

    只是想确认一下,您尝试对0x02通道断电寄存器进行编程,同时您也尝试重新读取寄存器数据,但在16时后您未在 SDI 上找到数据,如果我的理解不正确,请纠正我的错误。

    在主循环中,您将向 ADC 发送以下命令:

    命令1: 0000 0011 1111      -->此命令将0xFF 数据写入0x01程序寄存器,而不是对0x02寄存器进行编程的命令。

    命令2:  0000  0011 1010 0101     --> 此命令将0xA5数据写入0x01程序寄存器 ,而不是0x02寄存器,这也不是寄存器读取命令

    此外,应使用 SPI 配置(CPOL =0和 CPHA =1)。 请参阅 E2E 文章 :ADS8688 SPI 时钟中的更多详细信息

    您的图像模糊,难以看清。 请为这两个命令提供清晰,更近的计时屏幕截图吗?

    此致,

    戴尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,戴利,

    我的错误是,它是0x01寄存器(AUTO_SEQ_EN)。

    根据该数据表,写入值将在16时钟后缘后的 SDI 行中可用。

    但数据采样工作不正常,因为如果  CPHA =1,则数据将在前导边移出,数据将在 时钟的后缘采样。 

    原始图像为:

    drive.google.com/.../view

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,BIBIN,

    ADS8668的计时不是标准 SPI 计时:

    • 对于从主机控制器到 ADC 的 SDI,SDI 线路上的数据由 ADC 在 SCLK 的每个下降边缘读取/锁定。
    • 对于从 ADC 到主机控制器的 SDO,转换数据的 MSB 将输出到 SCLK 第16个下降边缘的 SDO 线路上,您的主机控制器可以在 SCLK 信号的随后(第17个)下降边缘读取数据。 对于16位输出数据,LSB 可以在 SCLK 信号的第32个下降边缘读取。  请参阅下面的 ADS8668的 SPI 时序。

    需要 SPI 配置(CPOL =0和 CPHA =1),因为主机控制器可以在 SCLK 的每个下降边缘采样数据,以便获得正确的转换结果。

    我无法访问 Google Drive,但我已经了解了您的担忧,并向您解释了时间安排。 如果您对 ADS8668有任何其他疑问,请告诉我。

    谢谢(&W),

    戴尔

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢戴尔