1      Scope of Document

This document describes UART hardware design, uart driver porting

2      Requiremen

2.1     Function Requirement

Uboot enable uart0 for debug, Kernel enable uart0 uart1 uart2 uart3.

2.2     Performance Requirement

Support common uart rx tx function.

3      Hardware Overview

uart interface,pin map:

// uart 0

AM335X_UART0_RXD

AM335X_UART0_TXD

// uart 1

AM335X_UART1_RXD

AM335X_UART1_TXD

// uart 2

AM335X_UART2_RXD

AM335X_UART2_TXD

// uart 3

AM335X_UART3_RXD

AM335X_UART3_TXD

 

Figure 1 uart interface block diagram

4      Functional Description

4.1     UART DRIVER Overview

The UART Driver enables the UART’s available on the device. The driver configures the UART hardware and interfaces with a number of standard linux tools (ex. stty, minicom, etc.) to enable the configuration and usage of the hardware. The H/W UARTs available will vary by SoC and system configuration.

4.2     UART

4.2.1 Overview

The UART driver can be used to send/receive raw ASCII characters from the User Interface as shown by the below diagram..

4.2.1 User Layer

The UART driver leverages the TTY framework within Linux. This framework uses typical file I/O operations to interact with the UART. This interface allows userspace modules to easily be developed to read/write the /dev/ttyxx to exchange data over the UART. Since this is a very common Linux framework, there are many standard tools that can be used to interact with it. These tools, like stty, minicom, picocom, and many others, can easily be used to exercise a UART for data exchange.

Features

  • Exposes UART to User Space via /dev/tty*
  • Supports multiple baud rates and UART capabilities
  • Hardware Flow Control

5      Porting

5.1     Uboot porting

In uboot default enable debug uart, so do not need to modify.

5.2     Kernel porting

Index: am335x-evm.dts

uart1_pins: pinmux_uart1_pins {

pinctrl-single,pins = <

AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE1)      /* uart1_rxd.uart1_rxd */

AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE1)  /* uart1_txd.uart1_txd */

>;

};

uart2_pins: pinmux_uart2_pins {

pinctrl-single,pins = <

AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE1)      /* mii1_txclk.uart2_rxd */

AM33XX_IOPAD(0x930, PIN_OUTPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxclk.uart2_txd */

>;

};

uart3_pins: pinmux_uart3_pins {

pinctrl-single,pins = <

AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE1)      /* mii1_rxd3.uart3_rxd */

AM33XX_IOPAD(0x938, PIN_OUTPUT_PULLDOWN | MUX_MODE1)  /* mii1_rxd2.uart3_txd */

>;

};

&uart1 {

pinctrl-names = "default";

pinctrl-0 = <&uart1_pins>;

status = "okay";

};

&uart2 {

pinctrl-names = "default";

pinctrl-0 = <&uart2_pins>;

status = "okay";

};

&uart3 {

pinctrl-names = "default";

pinctrl-0 = <&uart3_pins>;

status = "okay";

};

6      Follow-up

Uart loop test code:

#include     <stdio.h>

#include     <stdlib.h>

#include     <string.h>

#include     <unistd.h>

#include     <sys/types.h>

#include     <sys/stat.h>

#include     <fcntl.h>

#include     <termios.h>

#include     <errno.h>

#include     <pthread.h>

#include     <sys/ioctl.h>

#define FALSE 1

#define TRUE 0

int fd=-1;

char buff[512];

int speed_arr[] = {  B115200, B57600, B38400, B19200, B9600, B4800,

B2400, B1200};

int name_arr[] = {115200, 57600, 38400,  19200,  9600,  4800,  2400, 1200};

#define debugnum(data,len,prefix)  \

{ \

unsigned int i;   \

for (i = 0;i < len;i++) { \

if(prefix)  \

printf("0x%02x ",data[i]); \

else  \

printf("%02x ",data[i]); \

} \

}

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)

{

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;

break;

case 'o':

case 'O':

options.c_cflag |= (PARODD | PARENB);

options.c_iflag |= INPCK;

break;

case 'e':

case 'E':

options.c_cflag |= PARENB;

options.c_cflag &= ~PARODD;

options.c_iflag |= INPCK;

break;

case 'S':

case 's':

options.c_cflag &= ~PARENB;

options.c_cflag &= ~CSTOPB;

break;

default:

fprintf(stderr,"Unsupported parity\n");

return (FALSE);

}

switch (stopbits)

{

case 1:

options.c_cflag &= ~CSTOPB;

break;

case 2:

options.c_cflag |= CSTOPB;

break;

default:

fprintf(stderr,"Unsupported stop bits\n");

return (FALSE);

}

options.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);

options.c_oflag &= ~OPOST;

options.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);

/* 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)

{

perror("SetupSerial 3");

return (FALSE);

}

return (TRUE);

}

void receivethread(void)

{

int nread;

while(1)

{

if((nread = read(fd,buff,100))>0) //接收数据

{

printf("[RECEIVE] Len is %d,content is :\n",nread);

buff[nread]='\0';

printf("%s\n",buff);

}

usleep(100/**1000*/);

}

return;

}

int main(int argc, char *argv[])

{

char str[500];

pthread_t receiveid;

int  c, ctrlbits;

/*

参数个数小于1则返回,按如下方式执行:

./uart_test /dev/ttyAT1

*/

if (argc < 2) {

printf("Useage: %s dev\n", argv[0]);

exit(0);

}

printf("test\n");

fd = open(argv[1], O_RDWR);

if (fd < 0){

printf("open device %s faild\n", argv[1]);

exit(0);

}

set_speed(fd,115200); //设置串口波特率

set_Parity(fd,8,1,'N'); //设置8位数据位,1位停止位,无校验等其他设置。

pthread_create(&receiveid,NULL,(void*)receivethread,NULL);//创建接收线程

while(1)

{

printf("Please Input string to send to %s\n:",argv[1]);

scanf("%s", str);

if(strlen(str)>0){

//发送数据

write(fd, str, strlen(str));

write(fd, "\n", strlen("\n"));

usleep(200*1000);

}

}

close(fd);

exit(0);

}

am335x system upgrade kernel uart(七)的更多相关文章

  1. am335x system upgrade kernel tf(五)

    1      Scope of Document This document describes TF hardware design 2      Requiremen 2.1     Functi ...

  2. am335x system upgrade kernel ethernet(四)

    1      Scope of Document This document describes ethernet hardware design and porting KZS8081 to ubo ...

  3. am335x system upgrade kernel gpio(九)

    1      Hardware Overview gpio interface,pin map: AM335X_I2C0_W_C----------------------MCASP0_AXR1 /* ...

  4. am335x system upgrade kernel can(八)

    1      Scope of Document This document describes can bus hardware design and can bus driver developm ...

  5. am335x system upgrade kernel i2c rtc eeprom(六)

    1      Scope of Document This document describes i2c bus hardware design and support i2c-devices: ee ...

  6. am335x system upgrade kernel ec20 simcom7600ce(十一)

    1      Scope of Document This document describes 4G hardware design, support quectel ec20 4G module/ ...

  7. am335x system upgrade kernel usb stroage(十)

    1      Scope of Document This document describes USB hardware design, support stardard usb2.0 port o ...

  8. am335x system upgrade kernel f-ram fm25l16b(十六)

    1      Scope of Document This document describes SPI F-RAM hardware design 2      Requiremen 2.1     ...

  9. am335x system upgrade kernel emmc(十八)

    1      Scope of Document This document describes EMMC hardware design 2      Requiremen 2.1     Func ...

随机推荐

  1. opencv学习笔记D01

    目录 opencv学习笔记D01 一.图片读取 二.图片保存 三.图片展示 四.图片缩放 五.四种常用插值方式的比较 1.最近邻插值 2.双线性插值 3.区域插值 4.三次样条插值 我是尾巴: ope ...

  2. Modelsim——do脚本、bat命令

    一.do脚本实现自动化仿真 Modelsim是支持命令的,我们可以用 .do 文件将这些命令先写好然后在Modelsim上调用.因为我的编辑器不支持.do的语法,所以这里改用 .tcl文件,它和 .d ...

  3. Linux守护进程编写指南

    Linux守护进程编写指南 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程是一种很有用的进 程.Linux的大多数服务器 ...

  4. kubernetes第五章--创建资源的两种方式

  5. 【转载】使用Winrar对压缩文件进行加密,并且给定解压密码

    有时候我们从网上下载的压缩包文件,如.rar文件.zip文件等,解压的时候需要输入解压密码才可顺利解压,否则解压失败.其实像这种情况,是压缩包制作者在压缩文件的时候对压缩文件进行了加密,输入了压缩包解 ...

  6. python day6 装饰器补充,正则表达式

    目录 python day 6 1. 装饰器decorator 2. 正则表达式re 2.1 正则表达式概述 2.2 re模块常用方法 python day 6 2019/10/09 学习资料来自老男 ...

  7. Vue中v-model解析、sync修饰符解析

    上善若水,水善利萬物而不爭.——<道德經> 简介 在平时开发是经常用到一些父子组件通信,经常用到props.vuex等等,这里面记录另外的三种方式v-model.sync是怎么使用,再说是 ...

  8. 微信小程序自定义toast的实现

    今天写微信小程序突然发现一个尴尬的问题,请求报错需要提示,就去小程序API里找,可悲的小程序的toast并不能满足我的需求,原生提供的方法调用如下 wx.showToast({ title: '成功' ...

  9. 【转】TI DSP C6657学习之——编译静态库.lib

    熟悉C++开发的的小伙伴都知道,我们一般代码中往往要引入许多第三方编译好的库,有些是静态链接库static library, 有些是动态链接库dll.引入库的目的一是减少代码的编译时间,二是只提供函数 ...

  10. Python爬虫的三种数据解析方式

    数据解析方式 - 正则 - xpath - bs4 数据解析的原理: 标签的定位 提取标签中存储的文本数据或者标签属性中存储的数据 正则 # 正则表达式 单字符: . : 除换行以外所有字符 [] : ...