Part Number:TDA4VM
eg.
由于在UART来模拟Lin信号过程中,Lin信号需要 >=13bit的信号,UART无法一次性发送个13bit的数据,我尝试通过降低波特率的方式来实现。
但是,在实现过程中在切换波特率过程比较耗时,导致发送的信号无法连续,从而导致失败。使用的linux的接口代码
static speed_t speed_arr[] = {B230400, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B600, B300}; static intname_arr[] = { 230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 600, 300}; static uint32_t uart_fd; struct serial_t {intfd;char*device;/*/dev/ttyS0,...*/intbaud;intdatabit;/*5,6,7,8*/charparity;/*O,E,N*/intstopbit;/*1,2*/intstartbit;/*1*/struct termiosoptions; }; #define FILE"/dev/ttyS6" static struct serial_t __seri_conf[] = {[0] = {//connect with b board, ttyS6.device = FILE,.baud =9600,.databit = 8,.parity = 'N',.stopbit = 1,},[1] = {//connect with b board, ttyS6.device = FILE,.baud =19200,.databit = 8,.parity = 'N',.stopbit = 1,}, }; /** *@brief 设置串口通信速率 *@param fd类型 int 打开串口的文件句柄 *@param speed 类型 int 串口速度 *@return void */ void set_speed(int fd, int speed) {inti;intstatus;struct termiosOpt;tcgetattr(fd, &Opt);for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++){if (speed == name_arr[i]){tcflush(fd, TCIOFLUSH);cfsetispeed(&Opt, speed_arr[i]);cfsetospeed(&Opt, speed_arr[i]);status = tcsetattr(fd, TCSANOW, &Opt);if (status != 0)perror("tcsetattr fd1");return;}tcflush(fd,TCIOFLUSH);} } //设置非标准波特率,比如13292 int serial_set_speci_baud(struct serial_t *tty,int baud) {struct serial_struct ss,ss_set;tcgetattr(tty->fd,&tty->options);cfsetispeed(&tty->options,B38400);cfsetospeed(&tty->options,B38400);tcflush(tty->fd,TCIFLUSH);/*handle unrecevie char*/tcsetattr(tty->fd,TCSANOW,&tty->options);if((ioctl(tty->fd,TIOCGSERIAL,&ss))<0){printf("BAUD: error to get the serial_struct info:%s\n",strerror(errno));return -1;}ss.flags = ASYNC_SPD_CUST;ss.custom_divisor = ss.baud_base / baud;printf("ss.custom_divisor = %d \r\n",ss.custom_divisor);if((ioctl(tty->fd,TIOCSSERIAL,&ss))<0){printf("BAUD: error to set serial_struct:%s\n",strerror(errno));//return -2;}ioctl(tty->fd,TIOCGSERIAL,&ss_set);printf("BAUD: success set baud to %d,custom_divisor=%d,baud_base=%d\n",baud,ss_set.custom_divisor,ss_set.baud_base);return 0; } /*get serial's current attribute*/ static int serial_get_attr(struct serial_t *tty) {if(tcgetattr(tty->fd,&tty->options) != 0){printf("SERIAL: can't get serial's attribute\n");return -1; }return 0; } /*update serial's attrbute*/ static int serial_attr_update(struct serial_t *tty) {tcflush(tty->fd,TCIFLUSH);/*handle unrecevie char*/if((tcsetattr(tty->fd,TCSANOW,&tty->options)) < 0){return -1; }return 0; } static int serial_init_databit(struct serial_t *tty) {if(serial_get_attr(tty)<0)return -1;tty->options.c_cflag &= ~CSIZE;switch(tty->databit){case 5: tty->options.c_cflag |= CS5;break;case 6: tty->options.c_cflag |= CS6;break;case 7: tty->options.c_cflag |= CS7;break;case 8: tty->options.c_cflag |= CS8;break;default:printf("SERIAL: unsupported databit %d\n",tty->databit);return -2; }if(serial_attr_update(tty) < 0)return -3;printf("SERIAL: set databit to %d\n",tty->databit);return 0; } static int serial_init_parity(struct serial_t *tty) {if(serial_get_attr(tty)<0)return -1;/*ignore framing and parity error*/tty->options.c_iflag = IGNPAR;switch (tty->parity){case 'n':case 'N':/* Clear parity enable */tty->options.c_cflag &= ~PARENB;/* Enable parity checking */tty->options.c_iflag &= ~INPCK;break;case 'o':case 'O':/* 设置为奇校检*/tty->options.c_cflag |= (PARODD|PARENB);/* Disnable parity checking */tty->options.c_iflag |= (INPCK|ISTRIP);break;case 'e':case 'E':/* Enable parity */tty->options.c_cflag |= PARENB;/* 转换为偶效验*/tty->options.c_cflag &= ~PARODD;/* Disnable parity checking */tty->options.c_iflag |= (INPCK|ISTRIP);break;default:printf("SERIAL: unsupported parity %c\n",tty->parity);return -2; }if(serial_attr_update(tty) < 0)return -3;printf("SERIAL: set parity to %c\n",tty->parity);return 0; } static int serial_init_stopbit(struct serial_t *tty) {if(serial_get_attr(tty)<0)return -1;switch(tty->stopbit){case 1:tty->options.c_cflag &= ~CSTOPB;break;case 2:tty->options.c_cflag |= CSTOPB;break;default:printf("SERIAL: unsupported stopbit %d\n",tty->stopbit);return -2; }if(serial_attr_update(tty) < 0)return -3;printf("SERIAL: set stopbit to %d\n",tty->stopbit);return 0; } static void uart_init(struct serial_t* seri_conf) {uart_fd = open(FILE, O_RDWR | O_NOCTTY | O_NONBLOCK);seri_conf->fd = uart_fd;set_speed(seri_conf->fd,seri_conf->baud);if(serial_init_databit(seri_conf)<0)printf("serial_init_databit error\n");if(serial_init_parity(seri_conf)<0)printf("serial_init_parity error\n");if(serial_init_stopbit(seri_conf)<0)printf("serial_init_stopbit error\n");//struct termios opt;tcgetattr(seri_conf->fd,&seri_conf->options);seri_conf->options.c_iflag &=~(BRKINT|ICRNL|INPCK|ISTRIP|IXON);seri_conf->options.c_lflag &=~(ICANON|ECHO|ECHOE|ECHONL|ISIG|IEXTEN);seri_conf->options.c_oflag &=~(OPOST);if(tcsetattr(seri_conf->fd,TCSANOW,&seri_conf->options)!=0)printf("error"); } static int8_t BoardDiag_linSend(uint32_t fd, uint8_t *writeBuf,uint32_t byteCount) {int8_t ret = 0;ret = write(fd, (uint8_t *)&writeBuf[0], byteCount);if(!ret){close(fd);return -1;}return 0; } static int8_t BoardDiag_linReceive(uint32_t fd, uint8_t *readBuf,uint8_t byteCount) {int8_t ret = 0;ret = read(fd, (uint8_t *)&readBuf[0], byteCount);if(!ret){close(fd);return -1;}return 0; } typedef struct {uint8_t sync;uint8_t pid;uint8_t data[7];uint8_t checksum; }linData_t; void Lin_SendBreak(void) {uint8_tbreakfield1;int8_tstatus= 0;linData_tlinMasterData;//breakuart_init(&__seri_conf[0]);breakfield1 = 0x00;//usigned char breakfieldBoardDiag_linSend(uart_fd, (uint8_t *)(&breakfield1),sizeof(breakfield1));close(uart_fd);//重置波特率 uart_init(&__seri_conf[1]);set_speed(uart_fd,19200);linMasterData.sync= 0x55;linMasterData.pid= 0xC1;//PID:0xC1 1100 0001ID: 0x01linMasterData.data[0]= 0x07;// 0000 0111protectId = 0x01;linMasterData.checksum = LIN_MakeChecksum(protectId,sizeof(linMasterData.data),(uint8_t *)(&linMasterData.data));status = BoardDiag_linSend(uart_fd, (uint8_t *)(&linMasterData),sizeof(linMasterData)); } int main(void) {Lin_SendBreak();close(uart_fd); return 0; }
请问:
问题1.在TDA4上通过UART来模拟Lin信号是否是可行的?
如果可行,有什么比较好的方法来降低波特率的切换耗时的问题吗?
如果不行,有什么别的好的方法可以实现呢?
问题2.我用devmem2工具来读取UART4 地址0x02840000寄存器的数据正常,但是我用devmem2工具向寄存器地址0x02840000写值时,提示写入成功,但是重新读取时值未发生改变。
请问这个寄存器是不让修改的吗?
Annie Liu:
感谢您对TI产品的关注!为更加有效地解决您的问题,我们将问题发布在E2E英文技术论坛上,将由资深的英文论坛工程师为您提供帮助。您也可以查看下帖了解进展:
https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1136636/tda4vm-since-tda4-does-not-have-a-driver-for-lin-i-now-want-to-use-uart-to-simulate-the-lin-signal-and-thus-execute-the-communication
,
Annie Liu:
zhu he 说:问题1.在TDA4上通过UART来模拟Lin信号是否是可行的?
是的,这应该是可能的,但这尚未得到验证。
zhu he 说:由于在UART来模拟Lin信号过程中,Lin信号需要 >=13bit的信号,UART无法一次性发送个13bit的数据,我尝试通过降低波特率的方式来实现。
为什么要切换波特率?切换波特率如何帮助您接收连续的 13 位数据?
zhu he 说:问题2.我用devmem2工具来读取UART4 地址0x02840000寄存器的数据正常,但是我用devmem2工具向寄存器地址0x02840000写值时,提示写入成功,但是重新读取时值未发生改变。
您使用的是哪个 SDK 版本,我们需要检查 UART4 是由 Linux 拥有还是为 RTOS 保留。
,
zhu he:
1.为什么要切换波特率?切换波特率如何帮助您接收连续的 13 位数据?
由于需要满足13个bit,uart无法一次性发13个bit,由于接受方是19200波特率,发送方需要拉低波特率来满足13个bit。
2.您使用的是哪个 SDK 版本?
a.使用的是ti-processor-sdk-rtos-j721e-evm-08_01_00_13这个SDK版本,
b.同时UART5 UART_DLL地址0x02850000 和UART_DLH 0x02850004 寄存器也是无法写入的。帮忙查看一下为什么不能写。
3.如何通过寄存器来修改UART5的波特率,麻烦告知我UART_DLH 和UART_DLL 的寄存器地址。