How to Use UART

www.azdisplays.com
How to Use UART
Abstract
Here is the guide to teach that how to enable the uart port on AZD-A7N-1GB and how to test the uart
port is available.
The process are running under the terminal of Linux system.
Dev board pin
Pins info http://www.azdisplays.com/download/devboard/docs/AZDA20-KIT.pdf
Fex Guide http://linux-sunxi.org/Fex_Guide
Open the port
#mount /dev/nanda /mnt
#cd /mnt
#bin2fex
script.bin script.fex
#vi script.fex
Modify the script.fex to open the uart3, uart4 as below:
[uart_para3]
uart_used = 1
uart_port = 3
uart_type = 4
uart_tx = port:PG06<4><1><default><default>
uart_rx = port:PG07<4><1><default><default>
uart_rts = port:PG08<4><1><default><default>
uart_cts = port:PG09<4><1><default><default>
[uart_para4]
uart_used = 1
uart_port = 4
uart_type = 2
uart_tx = port:PG10<4><1><default><default>
www.azdisplays.com
uart_rx = port:PG11<4><1><default><default>
Save the modification.
#fex2bin script.fex
script.bin
#reboot
After the reboot ,the uart3 and uart4 are available.
remember save as script.bin and reboot
Test the uart
Write an internal loopback program to test the uart.
#vi uart_test.c
Edit the program
/********************************************************************
**************************uart_test*********************************
********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/time.h>
#include <string.h>
#define TRUE 1
#define FALSE -1
int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
www.azdisplays.com
int name_arr[] = {115200, 38400,
38400,
19200,
19200,
9600,
9600, 4800, 2400, 1200,
4800,
2400,
300, };
void set_speed(int fd, int speed)
{
int i;
int status;
struct termios Opt;
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);
}
}
int set_Parity(int fd,int databits,int stopbits,int parity)
1200,
300,
www.azdisplays.com
{
struct termios options;
if( tcgetattr( fd,&options)!= 0)
{
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;
switch(databits)
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (FALSE);
}
switch(parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
/* Clear parity enable */
/* Enable parity checking */
options.c_iflag &= ~(ICRNL|IGNCR);
www.azdisplays.com
options.c_lflag &= ~(ICANON );
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB);
options.c_iflag |= INPCK;
/* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB;
/* Enable parity */
options.c_cflag &= ~PARODD;
options.c_iflag |= INPCK;
/* Disnable parity checking */
break;
case 'S':
case 's':
/*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (FALSE);
}
switch(stopbits)
www.azdisplays.com
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if(parity != 'n')
options.c_iflag |= INPCK;
options.c_cc[VTIME] = 150; // 15 seconds
options.c_cc[VMIN] = 0;
tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
if(tcsetattr(fd,TCSANOW,&options) != 0)
{
www.azdisplays.com
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
int main(int argc, char **argv)
{
int fd;
int nread;
int nwrite;
int n=0;
int i=0;
char buffer[15];
char devname_head[10] = "/dev/";
char dev_name[20];
if(argc < 2)
{
printf("Please input './test_uart ttySx'\n");
exit(1);
}
else
{
strcpy(dev_name, devname_head);
strcat(dev_name, argv[1]);
}
fd = open(dev_name, O_RDWR);
if(fd < 0)
{
perror("error to open /dev/ttySx\n");
exit(1);
www.azdisplays.com
}
if (fd > 0)
{
set_speed(fd,115200);
}
else
{
printf("Can't Open Serial Port!\n");
exit(0);
}
if (set_Parity(fd,8,1,'N') == FALSE)
{
printf("Set Parity Error\n");
exit(1);
}
printf("\nWelcome to uart_test\n\n");
memset(buffer,0,sizeof(buffer));
char test[15] = "hello world";
nwrite = write(fd,test,strlen(test));
if(nwrite < 0)
{
printf("write error\n");
}
printf("Send test data------>%s\n",test);
www.azdisplays.com
while(1)
{
nread = read(fd,&buffer[n],1);
if(nread < 0)
{
printf("read error\n");
}
printf("read char is -> %c \n",buffer[n]);
if (strlen(buffer) == strlen(test))
{
printf("Read Test Data finished,Read Test Data is------>%s\n",buffer);
memset(buffer,0,sizeof(buffer));
printf("Send test data again------>%s\n",test);
write(fd,test,strlen(test));
n=0;
sleep(1);
continue;
}
n++;
}
}
Install software build the compiled enviroment.
#apt-get install gcc build-essential
#gcc uart_test.c -o uart_test
The uart0 3 4 5 6 are available in our dev board, but uart0 is debug serial.
To test uart3(or uart4) should make sure the PG06 and PG07 (or PG10 and PG11)internal loopback,
use Dupont Wire Cable to connect them.
www.azdisplays.com
If you only open the uart0 4, uart4 is mapping the device ttyS1.
While open the uart0 3 4, uart3 is mapping the device ttyS1. uart4 is mapping the device ttyS2.
#./uart_test ttyS1 // or ttyS2
The terminal will printf as below, it proves that the uart3 is working.