I am testing the board at 921600 board rate. It sends junk characters. Would any body please try this. I have the source code below B460800 works correctly. Does the board support 921600. Please help -- #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <fcntl.h> #include <signal.h> #include <termios.h> #include <sys/types.h> #include <sys/mman.h> #include "/home/saju/target_fs/home/include/s3c2410-regs.h" # include <time.h> # include <errno.h> # include <string.h> #define COMPORT "/dev/ttySAC1" #define FATAL do { fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \ __LINE__, __FILE__, errno, strerror(errno)); exit(1); } while(0) int running = 1; void done (int sig) /* Signal handler to stop the program gracefully */ { running = 0; } static void Error(const char *Msg) { fprintf (stderr, "%s\n", Msg); fprintf (stderr, "strerror() is %s\n", strerror(errno)); exit(1); } static void Warning(const char *Msg) { fprintf (stderr, "Warning: %s\n", Msg); } int main(int argc, void *argv[]) { int fd; struct termios COMAttr; char SerKeyOut[5] = "12345"; char SerKeyIn[10000]; int CntSerKeyIn; printf ("Serial port test program\n"); printf ("Settings: %s B921600 8 N N\n", COMPORT); signal (SIGINT, done); // set up signal handler fd = open (COMPORT, O_RDWR | O_NOCTTY | O_NONBLOCK);//Read is non blocking //fd = open (COMPORT, O_RDWR | O_NOCTTY);//Read is blocking if (fd == -1) FATAL; memset(&COMAttr, 0, sizeof(struct termios)); COMAttr.c_iflag = IGNPAR; //COMAttr.c_cflag = B115200 | HUPCL | CS8 | CREAD | CLOCAL; //COMAttr.c_cflag = B460800 | HUPCL | CS8 | CREAD | CLOCAL; //CS8=>8n1 COMAttr.c_cflag = B921600 | HUPCL | CS8 | CREAD | CLOCAL; //CS8=>8n1 COMAttr.c_cc[VMIN] = 1; if (tcsetattr(fd, TCSANOW, &COMAttr) < 0) Warning("Unable to set COM port\n"); write(fd, &SerKeyOut, sizeof(SerKeyOut)); while (running) { CntSerKeyIn = read(fd, &SerKeyIn, sizeof(SerKeyIn)); if (CntSerKeyIn > 0) { SerKeyIn[CntSerKeyIn] = 0; //SerKeyIn[0] = 'b'; //SerKeyIn[1] = 0; printf("Cnt: %d: %s\n", CntSerKeyIn, SerKeyIn); } } return 0; }
Serial port at 921600 bad
I don't know how the linux driver handles UART frequency calculation, but it might be that you can't use 921600 baud on the port. The default clock source (for the mini2440 at least) seems to be PCLK. 109 #define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 110 S3C2410_UCON_RXILEVEL | \ 111 S3C2410_UCON_TXIRQMODE | \ 112 S3C2410_UCON_RXIRQMODE | \ 113 S3C2410_UCON_RXFIFO_TOI) If we calculate using the recommended PCLK freq for 405Mhz FCLK (usually 50.625 Mhz), we get UBRDIVn = (int)(50625000 / (921600 x 16) ) -1 ~= (int)3.433 - 1 0.433 will be "chopped off" the 3.433 original divisor, so that's an error rate of 12.6%. The S3C2440 manual says that "UART Frame error should be less than 1.87%(3/160)." With 460800, UBRDIVn = (int)(50625000 / (460800 x 16) ) -1 ~= (int)6.8664 - 1 Since we should round it to the nearest integer (to reduce error rate), it'll be 7, and the error part is 7 - 6.8664 = 0.1336. Error rate 0.1336 / 7 = 1.908%, that's very close to the margin, i think that's why it works.
Attempt with cfsetispeed and cfsetospeed.how below int open_port(char *port,int speed) { int fd; struct termios options,oldtio; if ((fd = open(port,O_RDWR |O_NDELAY| O_NOCTTY )) < 0) { fprintf(stderr,"Error al abrir puerto: %s\n",port); exit(0); } else { fcntl(fd,F_SETFL,FNDELAY); tcgetattr(fd, &oldtio); // Set the baud rates ... cfsetispeed(&options, speed); cfsetospeed(&options, speed); options.c_cflag |= (CLOCAL | CREAD); // Enable the receiver and set local mode... options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; options.c_cflag &= ~CSTOPB; //un bit de stop options.c_cflag |= CRTSCTS; options.c_cflag &= ~PARENB; // Clear parity enable //options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //options.c_oflag &= ~OPOST; options.c_lflag = 0; options.c_oflag = 0; options.c_iflag = 0; options.c_cc[VTIME]= 0; //temporizador entre caracter, no usado options.c_cc[VMIN]= 0; // bloquea lectura hasta recibir x chars // Set the new options for the port... tcflush(fd, TCIOFLUSH); tcsetattr(fd,TCSANOW, &options);// } return(fd); }