am335x 配置uart1-5驱动

GPIO可配置的选项:

AM33XX_SLEWCTRL_FAST: 高速管脚 AM33XX_SLEWCTRL_SLOW: 低速管脚 AM33XX_PULL_DISA: 关闭内部上下拉 AM33XX_PIN_OUTPUT: 输出下拉 AM33XX_PIN_OUTPUT_PULLUP: 输出上拉 AM33XX_PIN_INPUT: 关闭内部上下拉,并配置成输入 AM33XX_PIN_INPUT_PULLUP: 开启内部上拉,并配置成输入 AM33XX_PIN_INPUT_PULLDOWN: 开启内部下拉,并配置成输入


_AM33XX_MUXENTRY(UART1_TXD, 0,
	"uart1_txd", "mmc2_sdwp", "d_can1_rx", "i2c1_scl",
	NULL, "pr1_uart0_txd_mux1", NULL, "gpio0_15"),
其中:
“uart1_txd”		    对应步骤3的OMAP_MUX_MODE0
“mmc2_sdwp”	          对应步骤3的OMAP_MUX_MODE1
“d_can1_rx”	          对应步骤3的OMAP_MUX_MODE2
“i2c1_scl”		   对应步骤3的OMAP_MUX_MODE3
“pr1_uart0_txd_mux1”	  对应步骤3的OMAP_MUX_MODE5
“gpio0_15”		   对应步骤3的OMAP_MUX_MODE7


按照原理图增加uart1-uart5驱动需要修改两个文件:mux33xx.c board-am335xevm.c
mux33xx.c中:
uart1 uart2原来定义的里面就有无需修改

_AM33XX_MUXENTRY(MII1_RXD3, 0,
"mii1_rxd3", "uart3_rxd", "rgmii1_rd3", "mmc0_dat5",
"mmc1_dat2", NULL, "mcasp0_axr0", "gpio2_18"),


_AM33XX_MUXENTRY(MII1_RXD2, 0,
"mii1_rxd2", "uart3_txd", "rgmii1_rd2", "mmc0_dat4",
"mmc1_dat3", NULL, "mcasp0_axr1", "gpio2_19"),

 

_AM33XX_MUXENTRY(MII1_TXD3, 0,
"mii1_txd3", NULL, "rgmii1_td3", "uart4_rxd",
"mcasp1_fsx", "mmc2_dat1", "mcasp0_fsr", "gpio0_16"),


_AM33XX_MUXENTRY(MII1_TXD2, 0,
"mii1_txd2", NULL, "rgmii1_td2", "uart4_txd",
"mcasp1_axr0", "mmc2_dat2", "mcasp0_ahclkx", "gpio0_17"),

_AM33XX_MUXENTRY(MII1_RXDV, 0,
"mii1_rxdv", NULL, "rgmii1_rctl", "uart5_txd",
"mcasp1_aclx", "mmc2_dat0", "mcasp0_aclkr", "gpio3_4"),

_AM33XX_MUXENTRY(MII1_RXDV, 0,
"mii1_rxdv", NULL, "rgmii1_rctl", "uart5_txd",
"mcasp1_aclx", "mmc2_dat0", "mcasp0_aclkr", "gpio3_4"),

 

board-am335xevm.c里面需要配置管脚模式及初始化:

/* Module pin mux for uart2 */
static struct pinmux_config uart2_pin_mux[] = {
{"spi0_sclk.uart2_rxd", OMAP_MUX_MODE1 | AM33XX_SLEWCTRL_SLOW |
AM33XX_PIN_INPUT_PULLUP},
{"spi0_d0.uart2_txd", OMAP_MUX_MODE1 | AM33XX_PULL_UP |
AM33XX_PULL_DISA |
AM33XX_SLEWCTRL_SLOW},
{NULL, 0},
};

/* Module pin mux for uart1 */
static struct pinmux_config uart1_pin_mux[] = {
{"uart1_rxd.uart1_rxd", OMAP_MUX_MODE0 | AM33XX_SLEWCTRL_SLOW | AM33XX_PIN_INPUT_PULLUP},
{"uart1_txd.uart1_txd", OMAP_MUX_MODE0 | AM33XX_PULL_UP |
AM33XX_PULL_DISA |
AM33XX_SLEWCTRL_SLOW},
{NULL, 0},
};

/* Module pin mux for uart3 */
static struct pinmux_config uart3_pin_mux[] = {
{"mii1_rxd3.uart3_rxd", OMAP_MUX_MODE1 | AM33XX_SLEWCTRL_SLOW | AM33XX_PIN_INPUT_PULLUP},
{"mii1_rxd2.uart3_txd", OMAP_MUX_MODE1 | AM33XX_PULL_UP |
AM33XX_PULL_DISA |
AM33XX_SLEWCTRL_SLOW},
{NULL, 0},
};

/* Module pin mux for uart4 */
static struct pinmux_config uart4_pin_mux[] = {
{"mii1_txd3.uart4_rxd", OMAP_MUX_MODE3 | AM33XX_SLEWCTRL_SLOW | AM33XX_PIN_INPUT_PULLUP},
{"mii1_txd2.uart4_txd", OMAP_MUX_MODE3 | AM33XX_PULL_UP |
AM33XX_PULL_DISA |
AM33XX_SLEWCTRL_SLOW},
{NULL, 0},
};

/* Module pin mux for uart5 */
static struct pinmux_config uart5_pin_mux[] = {
{"mii1_col.uart5_rxd", OMAP_MUX_MODE3 | AM33XX_SLEWCTRL_SLOW | AM33XX_PIN_INPUT_PULLUP},
{"mii1_rxdv.uart5_txd", OMAP_MUX_MODE3 | AM33XX_PULL_UP |
AM33XX_PULL_DISA |
AM33XX_SLEWCTRL_SLOW},
{NULL, 0},
};

初始化:

/* setup uart5 */
static void uart5_init(int evm_id, int profile)
{
setup_pin_mux(uart5_pin_mux);
return;
}
/* setup uart4 */
static void uart4_init(int evm_id, int profile)
{
setup_pin_mux(uart4_pin_mux);
return;
}

/* setup uart3 */
static void uart3_init(int evm_id, int profile)
{
setup_pin_mux(uart3_pin_mux);
return;
}

/* setup uart2 */
static void uart2_init(int evm_id, int profile)
{
setup_pin_mux(uart2_pin_mux);
return;
}

/* setup uart1 */
static void uart1_init(int evm_id, int profile)
{
setup_pin_mux(uart1_pin_mux);
return;
}

{uart1_init, DEV_ON_BASEBOARD, PROFILE_ALL},
{uart2_init, DEV_ON_BASEBOARD, PROFILE_ALL},
{uart3_init, DEV_ON_BASEBOARD, PROFILE_ALL},
{uart4_init, DEV_ON_BASEBOARD, PROFILE_ALL},
{uart5_init, DEV_ON_BASEBOARD, PROFILE_ALL},

编译后进行测试,驱动增加完成。

 

串口测试程序源码:

串口接收到什么数据然后发出什么数据

 

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <termios.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <string.h>
#include <getopt.h>
#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <termios.h>
#include <stdlib.h>

struct termios gsTio[5];

pthread_t gsThreadId;

struct stru_run_param
{
fd_set rfds; //文件描述符集
int ptid[5]; //打开的通讯口句柄。
signed char cid[5]; //通讯口状态标示
signed char cnt; //打开通讯口个数
signed char brun; //监视线程运行控制标识
} Serial_RunPar;

//串口线程
void thread_serial(void* arg)
{
struct stru_run_param *prp;
unsigned char buff[5][1024];
struct timeval tmv;
int bRecCnt[5],retval,i,maxid,wCount;
int aaa=0,k;
char bbb[10];

memset(buff,0,1024);
bbb[9]='\n';
prp = (struct stru_run_param*)arg;


if(prp->cnt == 0)
{
printf("There is no serial port needing for watching!\n");
pthread_exit(0);
}
maxid = prp->ptid[0];
for(i=1; i<prp->cnt; i++) //取出最大的文件描述符
{
if(maxid < prp->ptid[i])
maxid = prp->ptid[i];
}
prp->brun = 1;

while(prp->brun){
tmv.tv_sec = 0;
tmv.tv_usec = 50000; //线程周期50毫秒
sleep(1);
for(i=0; i<prp->cnt; i++){
retval = select(maxid + 1, &prp->rfds, NULL, NULL, &tmv);

if(retval != 0 && retval != -1){ //检测到有数据接收
printf("get data from serial\n");

if((bRecCnt[i] = read(prp->ptid[i], buff[i], 1024)) == -1){
perror("serial port read");
FD_CLR(prp->ptid[i], &prp->rfds);
}else{
wCount = write(prp->ptid[i],buff[i],bRecCnt[i]);
printf("receive data OK!count=%d\n",wCount);
wCount=0;
for(k=0;k<bRecCnt[i];k++){
printf("%02x ",buff[i][k]);
}
printf("\n");
memset(buff[i],0,1024);
}
}else{
FD_ZERO(&prp->rfds); //超时或出错后清除文件描述符集
for(i=0; i<prp->cnt; i++)
FD_SET(prp->ptid[i], &prp->rfds); //重新添加一下
}
}
}
printf("serial port thread exit\n");
pthread_exit(0);
}
//开启串口线程
signed char CreateSerialWatchThread()
{
int ret;
ret = pthread_create(&gsThreadId, NULL, (void *(*)(void*))thread_serial, (void*)&Serial_RunPar);
if(ret != 0)
{
printf("Create serial port thread error!\n");
return -1;
}
return 1;
}
//打开串口函数
signed char OpenSerial(signed char COM, signed int baud, signed char data,
signed char stop, signed char check, signed char typ)
{
signed char path[16];
struct termios newtio;

sprintf(path, "/dev/ttyO%d", COM); //ttyO*
Serial_RunPar.ptid[Serial_RunPar.cnt] = open(path, O_RDWR | O_NOCTTY | O_NDELAY);

if (Serial_RunPar.ptid[Serial_RunPar.cnt] < 0)
{
printf("Can not open serial port %s!\n", path);
return -1;
}else{
printf("open serial port %s\n",path);
}

//读取旧设置
if(tcgetattr(Serial_RunPar.ptid[Serial_RunPar.cnt], &gsTio[Serial_RunPar.cnt]) != 0)
{
printf("Can not get serial port %s attributes!\n", path);
return -1;
}
bzero(&newtio, sizeof(newtio));
//字符大小
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
newtio.c_lflag = 0;
newtio.c_oflag = 0;
newtio.c_iflag = IXOFF | IXON;
//波特率
switch(baud)
{
case 2400:
cfsetispeed(&newtio, B2400);
cfsetospeed(&newtio, B2400);
break;
case 4800:
cfsetispeed(&newtio, B4800);
cfsetospeed(&newtio, B4800);
break;
case 9600:
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
break;
case 19200:
cfsetispeed(&newtio, B19200);
cfsetospeed(&newtio, B19200);
break;
case 38400:
cfsetispeed(&newtio, B38400);
cfsetospeed(&newtio, B38400);
break;
case 57600:
cfsetispeed(&newtio, B57600);
cfsetospeed(&newtio, B57600);
break;
case 115200:
cfsetispeed(&newtio, B115200);
cfsetospeed(&newtio, B115200);
break;
}
//数据位
if(data == 8)
newtio.c_cflag |= CS8;
else if(data == 7)
newtio.c_cflag |= CS7;
//停止位
if(stop == 1)
newtio.c_cflag &= ~CSTOPB;
else if(stop == 2)
newtio.c_cflag |= ~CSTOPB;
//奇偶校验位
switch(check)
{
case 0:
newtio.c_cflag &= ~PARENB;
break;
case 1:
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
break;
case 2:
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
newtio.c_iflag |= (INPCK);
break;
}
//最小字符和等待时间
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 0;
//处理未接收字符
tcflush(Serial_RunPar.ptid[Serial_RunPar.cnt], TCIFLUSH);
//激活新设置
if(tcsetattr(Serial_RunPar.ptid[Serial_RunPar.cnt], TCSANOW, &newtio) != 0)
{
printf("Can not set serial port %s attributes!\n", path);
return -1;
}
//将文件描述符加入描述符集
FD_SET(Serial_RunPar.ptid[Serial_RunPar.cnt], &Serial_RunPar.rfds);
Serial_RunPar.cid[Serial_RunPar.cnt] = COM;
Serial_RunPar.cnt += 1;
return 1;
}
void main()
{
FD_ZERO(&Serial_RunPar.rfds);
//OpenSerial(4, 2400, 8, 1, 2, 1);
OpenSerial(4, 115200, 8, 1, 2, 1);
CreateSerialWatchThread();
while(1);
}

 






转载于:https://www.cnblogs.com/lazybeee/p/10460135.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值