Dear support-team,
I need to set a custom baudrate to the serial port. I try this with the following code:
- /* open the device to be non-blocking (read will return immediatly) */
- fd=open("/dev/ttySAC1", O_RDWR | O_NOCTTY | O_NONBLOCK);
- if (fd<0) return;
- /* allow the process to receive SIGIO */
- fcntl(fd, F_SETOWN, getpid());
- /* Make the file descriptor asynchronous (the manual page says only O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
- fcntl(fd, F_SETFL, FASYNC);
- tcgetattr(fd,&oldtio); /* save current port settings */
- /* set new port settings for canonical input processing */
- newtio.c_cflag = B38400 | CS8 | CLOCAL | CREAD;
- newtio.c_iflag = IXANY;
- newtio.c_oflag = 0;
- newtio.c_lflag = 0;
- newtio.c_cc[VMIN]=0;
- newtio.c_cc[VTIME]=0;
- cfsetispeed(&newtio,B38400);
- cfsetospeed(&newtio,B38400);
- tcsetattr(fd,TCSANOW,&newtio);
- ioctl(fd, TIOCGSERIAL, &new_serdrvinfo); // read driver settings
- new_serdrvinfo.flags = (new_serdrvinfo.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST; // activate custom baudrate
- printf("BaudBase: %i - Divisor: %i\n",new_serdrvinfo.baud_base,new_serdrvinfo.custom_divisor);
- new_serdrvinfo.baud_base=3000000;
- new_serdrvinfo.custom_divisor = 6; // set custom divisor
- ioctl(fd, TIOCSSERIAL, &new_serdrvinfo); // write new driver settings
When I run the program the first time it's killed in the
command with the message "... sets custom speed on ttySAC1. This is deprecated".
The BaudBase and the Divisor will be printed with value 0. When I run the program a second time this seems to work. Baudbase and Divisor will be printed as 300000 and 6. The program will not be killed.
Why does'nt this work when running the first time? Is this the right way to set a custom baud rate?
On PicoMod7 with kernel 2.6.39 it was not possible to set a custom speed this way. I had to run a module where I could access a special register in "PHKMEM":
- unsigned int fda = open("/dev/fs-phkmem", O_RDWR);
- if (fda==-1) {
- printf("error unable to open /dev/fs-phkmem \n");
- return;
- }
- #define FS_PHKMEM_GETREG 0x10
- #define FS_PHKMEM_SETREG 0x20
- s5p_register.addr = 0xEC000428;
- s5p_register.value = 11;
- if (ioctl(fda,FS_PHKMEM_SETREG, &s5p_register) < 0) {
- printf("error writing register \n");
- return;
- }
- close(fda);
But that was not very comfortable.
Thanks for any hints.