Part Number:TDA4VM-Q1Other Parts Discussed in Thread: ADS8684
HI:
我的项目上使用TDA4VM-Q1,然后通过SPI1连接到ADS8684,SPI1的设备树配置如下:
&main_spi1 {
pinctrl-names = "default"; pinctrl-0 = <&spi1_pins_default>;
status="okay";
spidev@0 {
spi-max-frequency = <24000000>;
reg = <0>;
compatible = "linux,spidev";
};
};
spi1_pins_default: spi1_pins_default {
pinctrl-single,pins = <
J721E_IOPAD(0x1dc, PIN_INPUT, 0) /* (Y1) SPI1_CLK */
J721E_IOPAD(0x1d4, PIN_INPUT, 0) /* (Y3) SPI1_CS0 */
J721E_IOPAD(0x1e0, PIN_INPUT, 0) /* (Y5) SPI1_D0 */
J721E_IOPAD(0x1e4, PIN_INPUT, 0) /* (Y2) SPI1_D1 */
>;
};
目前跑到LInux下已经可以识别到SPIDEV1.0,可以通过spidev_test读写
然后,我写了ADS8684的驱动,代码如下:
typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; typedef signed char s8; typedef short s16; typedef int s32; typedef long long s64; u16 My_Ad[8]={0,0,}; float ad_real[2]={0.0,0.0}; #define NO_OP 0X0000 #define STDBY 0X8200 #define PWR_DN 0X8300 #define SPIRST 0X8500 #define AUTO_RST 0XA000 #define MAN_Ch_1 0XC000 #define MAN_Ch_2 0XC400 #define MAN_Ch_3 0XC800 #define MAN_Ch_4 0XCC00 #define MAN_Ch_5 0XD000 #define MAN_Ch_6 0XD400 #define MAN_Ch_7 0XD800 #define MAN_Ch_8 0XDC00 #define MAN_AUX 0XE000 #define CH1 0x05 #define CH2 0x06 #define CH3 0x07 #define CH4 0x08 #define CH5 0x09 #define CH6 0x0a #define CH7 0x0b #define CH8 0x0c static int spidev_fd = 0; static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) { int ret; int out_fd; struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = len, .delay_usecs = delay, .speed_hz = speed, .bits_per_word = bits, }; if (mode & SPI_TX_OCTAL) tr.tx_nbits = 8; else if (mode & SPI_TX_QUAD) tr.tx_nbits = 4; else if (mode & SPI_TX_DUAL) tr.tx_nbits = 2; if (mode & SPI_RX_OCTAL) tr.rx_nbits = 8; else if (mode & SPI_RX_QUAD) tr.rx_nbits = 4; else if (mode & SPI_RX_DUAL) tr.rx_nbits = 2; if (!(mode & SPI_LOOP)) { if (mode & (SPI_TX_OCTAL | SPI_TX_QUAD | SPI_TX_DUAL)) tr.rx_buf = 0; else if (mode & (SPI_RX_OCTAL | SPI_RX_QUAD | SPI_RX_DUAL)) tr.tx_buf = 0; } ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) pabort("can't send spi message"); if (verbose) hex_dump(tx, len, 32, "TX"); if (output_file) { out_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (out_fd < 0) pabort("could not open output file"); ret = write(out_fd, rx, len); if (ret != len) pabort("not all bytes written to output file"); close(out_fd); } if (verbose) hex_dump(rx, len, 32, "RX"); } void ADS8688_SPI_WB(uint8_t com) { int ret = 0; transfer(spidev_fd,&com,0,1); return; ret = ioctl(spidev_fd, SPI_IOC_WR_BITS_PER_WORD, &com); if (ret == -1) printf("can't set bits per word\n"); else printf("set bits per word \n"); } uint8_t ADS8688_SPI_RB(void) { int ret = 0; uint8_t bits=0; transfer(spidev_fd,0,&bits,1); return bits; ret = ioctl(spidev_fd, SPI_IOC_RD_BITS_PER_WORD, &bits); if (ret == -1) printf("can't get bits per word"); else printf(" bits per word"); return bits; } void ADS8688_WriteCommandReg(uint16_t command)//写ADS8688命令寄存器 { ADS8688_SPI_WB(command>>8 & 0XFF); ADS8688_SPI_WB(command & 0XFF); } void ADS8688_Write_Program_Register(uint8_t Addr,uint8_t data) { ADS8688_SPI_WB(Addr<<1| 0X01); ADS8688_SPI_WB(data); } u8 ADS8688_READ_Program_Register(uint8_t Addr) { u8 data = 0; ADS8688_SPI_WB(Addr<<1); data = ADS8688_SPI_RB(); data = ADS8688_SPI_RB(); return data; }void Enter_RESET_MODE(void)//软件复位模式,复位 program registers {ADS8688_WriteCommandReg(SPIRST); } void AUTO_RST_Mode(void)//进入自动扫描模式 { ADS8688_WriteCommandReg(AUTO_RST); } void MAN_Ch_n_Mode(uint16_t ch)//自动模式 { ADS8688_WriteCommandReg(ch); } void Set_CH_Range_Select(uint8_t ch,uint8_t range) //设置各个通道的范围 { ADS8688_Write_Program_Register(ch,range); } void Get_AUTO_RST_Mode_Data(uint16_t* outputdata, uint8_t chnum) { //读取扫描通道序列的AD转换数据code到变量数组中 u8 i=0,datal=0,datah=0; u16 data=0; for (i=0; i<chnum; i++) { ADS8688_SPI_WB(0X00); ADS8688_SPI_WB(0X00); datah = ADS8688_SPI_RB(); datal = ADS8688_SPI_RB(); data = datah<<8 | datal; //低位在前,低位在后 *(outputdata+i) = data; } } //初始化通道1,默认正负10V范围 void ADS8688_Init_Single() { //ADS_8688_RST_PD_L; //delay_us(2); //ADS_8688_RST_PD_H; //ADS_8688_DAISY_IN_L; Enter_RESET_MODE(); ADS8688_Write_Program_Register(0X01,0Xff); ADS8688_READ_Program_Register(0X01); usleep(2); ADS8688_Write_Program_Register(0x02,0x00);//所有通道退出低功耗状态 ADS8688_Write_Program_Register(0x01,0xff);//使能所有通道 Set_CH_Range_Select(CH1,0x00);//设置通道1的输?范围:+-2.5*Vref // //0x00 -> +-2.5*ref // //0x01 -> +-1.25*ref // //0x02 -> +-0.625*ref // //0x03 -> +2.5*ref // //0x04 -> +1.25*ref MAN_Ch_n_Mode(MAN_Ch_1); //HAL_Delay(300); }void ADS8688_Init_Mult(void) { //ADS_8688_RST_PD_H; //ADS_8688_DAISY_IN_L; //delay_us(10); Enter_RESET_MODE(); //进入配置 ADS8688_Write_Program_Register(0X00,0X00); usleep(10); //开启通道 ADS8688_Write_Program_Register(0X01,0X07); usleep(10); //下拉 ADS8688_Write_Program_Register(0x02,0xf8);//所有通道退出低功耗状态 usleep(10); //设置功能 ADS8688_Write_Program_Register(0x03,0x03); usleep(10); //ADS8688_Write_Program_Register(0x01,0xff);//使能所有通道 Set_CH_Range_Select(CH1,0x00);//设置通道1的输入范围:+-2.5*Vref usleep(10); Set_CH_Range_Select(CH2,0x00); usleep(10); Set_CH_Range_Select(CH3,0x00); usleep(10); Set_CH_Range_Select(CH4,0x00); usleep(10); /* Set_CH_Range_Select(CH2,0x00); Set_CH_Range_Select(CH3,0x00); Set_CH_Range_Select(CH4,0x00); Set_CH_Range_Select(CH5,0x00); Set_CH_Range_Select(CH6,0x00); Set_CH_Range_Select(CH7,0x00); */ // //0x00 -> +-2. 5*ref // //0x01 -> +-1.25*ref // //0x02 -> +-0.625*ref // //0x03 -> +2.5*ref // //0x04 -> +1.25*ref //AUTO_RST_Mode();//进入自动扫描模式 ADS8688_Write_Program_Register(0xa0,0x03); usleep(10);AUTO_RST_Mode(); } uint16_t Get_MAN_Ch_n_Mode_Data(void) { u8 datah=0,datal=0; //ADS_8688_nCS_L; ADS8688_SPI_WB(0X00); ADS8688_SPI_WB(0X00); datah = ADS8688_SPI_RB(); datal = ADS8688_SPI_RB(); //ADS_8688_nCS_H; return (datah<<8 | datal); } u16 get_ADS_ch1(void) { return Get_MAN_Ch_n_Mode_Data();//读取通道1数据,具体通道数由函数 MAN_Ch_n_Mode()所决定的 } static u16 ADS_Results[4]={0,}; void get_ADS_allch(float*result) { Get_AUTO_RST_Mode_Data(ADS_Results,4);//?动扫描模式,?动扫描并转换8通 道。转换数据存与Results数组中 } double get_realdata(u16 x,u8 t)//mv { double y; if(!t) { y = (s16)(((double)(x-32762) *20.48/(double)65535)*1000); }else { y = (s16)(((double)(x-32725) *20.48/(double)65535)*1000); } return y; } //初始化多通道,默认全开、正负10V范围 void gat_real_ad(float *real_ad) { real_ad[0]= (float)get_realdata(My_Ad[0],0); real_ad[1]= (float)get_realdata(My_Ad[1],1); } void get_ADS_1and2(u16 *My_Ad,float *real_ad) { Get_AUTO_RST_Mode_Data(My_Ad,2); gat_real_ad(real_ad); } double get_realdata1(u16 x) { double y; y=x-32768; if(y<0) y = y * 0.0001907+0.02; else y = y * 0.0001907+0.02; return y; } int main(int argc, char *argv[]) { int ret = 0; int fd; parse_opts(argc, argv); if (input_tx && input_file) pabort("only one of -p and --input may be selected"); spidev_fd = open(device, O_RDWR); if (fd < 0) pabort("can't open device"); printf("open device %s ok...",device); /** spi mode*/ ret = ioctl(spidev_fd, SPI_IOC_WR_MODE32, &mode); if (ret == -1) pabort("can't set spi mode"); ret = ioctl(spidev_fd, SPI_IOC_RD_MODE32, &mode); if (ret == -1) pabort("can't get spi mode"); /** bits per word*/ ret = ioctl(spidev_fd, SPI_IOC_WR_BITS_PER_WORD, &bits); if (ret == -1) pabort("can't set bits per word"); ret = ioctl(spidev_fd, SPI_IOC_RD_BITS_PER_WORD, &bits); if (ret == -1) pabort("can't get bits per word"); /** max speed hz*/ ret = ioctl(spidev_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); if (ret == -1) pabort("can't set max speed hz"); ret = ioctl(spidev_fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); if (ret == -1) pabort("can't get max speed hz"); printf("spi mode: 0x%x\n", mode); printf("bits per word: %u\n", bits); printf("max speed: %u Hz (%u kHz)\n", speed, speed/1000); ADS8688_Init_Mult(); while(1) { Get_AUTO_RST_Mode_Data(ADS_Results,4);//?动扫描模式,?动扫描并转换8通 道。转换数据存与Results数组中 printf("get data:{%d,%d,%d,%d}---%f,%f,%f,%f\n",ADS_Results[0],ADS_Results[1],ADS_Results[2],ADS_Results[3], get_realdata1(ADS_Results[0]),get_realdata1(ADS_Results[1]),get_realdata1(ADS_Results[2]),get_realdata1(ADS_Results[3])); usleep(500*1000); } }
但是我给通道输入数据后,通过spi读出来的数据却一直是65535,没有获取到实际的ADC通道数据,请帮忙看看这个过程中哪里有问题?
Cherry Zhou:
您好,
我先和您确认下,以下帖子和这个问题是有关联的吗?之前的这个问题是否已解决?
https://e2echina.ti.com/support/processors/f/processors-forum/756152/tda4vm-kernel-adc
,
wei dong:
没有关联,这是另外一个问题了跟上个帖子里的问题不是同一个问题,之前的问题也没有解决,上个帖子问题是连续读取的问题,这个是读取数据异常或者说可能是读取不到的问题。
,
Cherry Zhou:
了解了,升级到英文论坛了,请查看以下链接:
e2e.ti.com/…/tda4vm-q1-using-spi-to-connect-the-ads8684-to-capture-data
,
wei dong:
还没有看到回复,帮忙看看是否端午前能回复到?
,
Cherry Zhou:
您可以关注下工程师的答复。非常抱歉,这条线人手比较短缺,回复会相对较慢,给您带来的不便敬请谅解。
,
Cherry Zhou:
您好,
您的两个问题我们的工程师在跟进中,但还需要您提供更多信息来帮助debug。
https://e2e.ti.com/support/processors-group/processors/f/791/t/1235583