【Hi3559V200 BSP 开发】使用 UART1 与外设通信

关键字 :HisiliconAuto

一、 前言

       Hi3559V200 的 UART0 是调试串口,所以当我们想要用串口跟外设通信的时候就要用到其他的 UART,接下来为大家介绍 Hi3559V200 UART1 的启用步骤。

使用的硬件平台是 Hi3559V200DMEB VER.A,使用的 SDK 版本是 Hi3559V200_MobileCam_SDK_V1.0.1.5。

 

 

二、 硬件原理图

2.1 Hi3559V200 平台 UART 介绍

      Hi3559V200 平台一共有 5 个 UART,如果要使用 UART1,首先在设备树中使能 UART1,然后需要把具有 UART1 TXD 和 RXD 功能的管脚复用为 UART1 功能,

然后编写一个验证 UART1 收发数据功能的应用程序即可实现 UART1 通信。

2.2 查看原理图确认 UART1 的位置

      查看原理图可以发现 CPU 的 UART1_TXD 和 UART1_RXD 管脚连接到 J21 上,所以 J21 就是 UART1 在板端的位置。

图 2.1 UART1 的原理图

 

图 2.2 UART1 在板端的位置

 

 

三、 硬件资源申请及分配

3.1 配置 DTS 文件

        海思平台可以通过 DTS 设备树文件对硬件设备资源进行申请及分配,DTS 文件所在目录为 osdrv\opensource\kernel\linux-4.9.y\arch\arm\boot\dts,

文件名是 hi3559v200.dtsi  和 hi3559v200-demb.dts。在 hi3559v200.dtsi 中 UART1 是默认分配给 LiteOS 系统的,这里需要修改为分配到 Linux 系统中,

并且在 aliases 中添加 “serial1 = &uart1;”:

 

图 3.1 修改 hi3559v200.dtsi 文件

       在 hi3559v200-demb.dts 文件中只需要把 uart1 的状态设置为 “okay”即可:


图3.2 修改 hi3559v200-demb.dts 文件

 

3.2 配置时钟和中断

      这一步骤是为了填 SDK 里的一个坑,如果配置好 DTS 文件启用 UART1 后直接调试的话,会出现 UART1 的波特率一直为 0,从而无法通信的情况。

造成这个问题的原因是 UART1 的时钟没有开启!需要手动在 osdrv/opensource/kernel/linux-4.9.y/drivers/clk/hisilicon/clk-hi3559v200.c 文件里开启 UART1 的时钟,

并且 UART1 在 HI3559V200 平台上默认用作 LiteOS 系统的调试串口,所以也需要在 osdrv/platform/liteos/platform/bsp/board/hi3559v200/include/hisoc/uart.h

文件把 LiteOS 的默认调试串口修改为其他串口,在osdrv/platform/liteos/platform/bsp/board/hi3559v200/include/irq_map.h 文件把 UART1 的中断从 CPU1 所属

设置为 CPU0 所属,CPU1 是 LiteOS 系统,CPU0 是 Linux 系统。

 

图 3.3 去掉注释开启 UART1 时钟



图 3.4 修改 LiteOS 调试串口为 UART2



图 3.5 修改 UART1 中断所属为 CPU0

注:完成此步骤后需要重新编译 kernel 并更新到板端。

 

四、 管脚复用

4.1 查询管脚复用寄存器

        在 《Hi3559V200_PINOUT_CN.xlsx》 中查询 UART1_TXD 和 UART1_RXD 管脚的控制寄存器地址:

图 4.1 UART1 管脚复用寄存器

 

4.2 配置管脚复用

        接下来需要把以上的两个引脚复用成 UART1 功能,海思提供了一个表格工具对引脚复用进行初始化配置,表格工具位于 osdrv\tools\pc\uboot_tools,

对于 Hi3559V200DMEB 板,适用 Hi3559V200-DMEB_6L_T-DDR3_1800M_512MB_16bitx2-A7_900M-SYSBUS_300M.xlsm 表格,只需按照上面的例子

把刚才查到的寄存器名称、地址、要写入的数据填进去即可:

图 4.2 配置管脚复用表格


注:添加复用后要重新编译 u-boot 并更新到板端。

 

五、 编写 UART1 通信应用程序

配置好 SDK 后,接下来需要一个应用程序来验证 UART1 是否能正常收发数据,以下是我在 Samplecam 中编写的一个用于调试的 uart_app 应用程序,

存放的位置为 reference/samplecam/app/uart1/uart1_main.c,完整代码请看附件,以下代码仅供参考:


/* 发送数据函数 */

int HI_Serial_Send(int fd, char *send_buf,int data_len)

{

int len = 0;



len = write(fd,send_buf,data_len);

if (len == data_len )

{

printf("send data is %s\n",send_buf);

return len;

}

else

{

tcflush(fd,TCOFLUSH);

return HI_FALSE;

}



}



/* 接收数据函数 */


int HI_Serial_Recv(int fd, char *rcv_buf,int data_len)

{

int len,fs_sel;

fd_set fs_read;



struct timeval time;



FD_ZERO(&fs_read);

FD_SET(fd,&fs_read);



time.tv_sec = 30;

time.tv_usec = 0;



//select fdset

fs_sel = select(fd+1,&fs_read,NULL,NULL,&time);

if(fs_sel)

{

len = read(fd,rcv_buf,data_len);

//printf("HiSeral Receive Data = %s len = %d fs_sel = %d\n",rcv_buf,len,fs_sel);

return len;

}

else

{

printf("Hiserial haven't data receive!");

return HI_FALSE;

}

}

/* 提示运行程序时需要输入的参数 */

void HI_Serial_Usage(void)

{

printf("Usage:\n");

printf("\tmyhicom [-d] [-s] get netdeviece info [-rw] read or write select\n");

printf("\tExample:\n\tmyhicom -d /dev/ttyAMA1 -s 115200 -w HiSerial:HelloWorld\n");

}



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

{

int cmd;

int len;

HI_S32 HiSerfd;

HI_S32 *fd = &HiSerfd;

extern char *optarg;

const HI_CHAR *uartDev = "/dev/ttyAMA1";

char sendbuf[1024]={0};

char recvbuf[1024]={0};

//extern int optind, opterr, optopt;



//Hi_init_signals();



if(argc == 1)

{

HI_Serial_Usage();

exit(0);

}

else

{

while ((cmd = getopt(argc, argv, ":rw:")) != -1)

{

switch (cmd)

{

case 'r':

printf("myHicom read\n");

HAL_UART_Init(uartDev, fd);

//HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');

while(1)

{

len = HI_Serial_Recv(HiSerfd, recvbuf,sizeof(recvbuf));

if(len > 0)

{

recvbuf[len] = '\0';

printf("Hiserial receive data: %s\n",recvbuf);

memset(recvbuf,0,sizeof(recvbuf));

//break;

}

else

{

printf("Hiserial haven't data receive \n");

}

sleep(2);

};

break;

case 'w':

printf("myHicom write %s\n",optarg);

HAL_UART_Init(uartDev, fd);

//HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');

sprintf(sendbuf,"%s\n",optarg);

HI_Serial_Send(HiSerfd, sendbuf, strlen(sendbuf)+1);

if(HiSerfd > 0)

HAL_UART_DeInit(HiSerfd);

break;

default:

exit(0);

}

}

}

return 0;

}

 

 

 六、验证过程

为了方便验证,使用 UART1 串口与 PC 端进行通信,将 UART0 调试串口和 UART1 同时连接到 PC 端,具体验证步骤如下:

① 在板端输入 “stty -F /dev/ttyAMA1 ispeed 115200 ospeed 115200” 命令设置 UART1 的波特率为 115200,其中的 “/dev/ttyAMA1”指的是 UART1 的设备文件。

② 运行 uart_app 使用 UART1 发送一串数据,查看 PC 端是否能成功接收。

③ 运行 uart_app 进入读取 UART1 数据的状态,在此状态会一直读取 UART1 接收的数据,然后在 PC 端发送一串数据到 UART1,查看板端是否能准确读取。


图 6.1 UART0 调试终端



图 6.2 UART1 终端

 

从上两图可以看出,UART1 发送 “12345” 这个字符串成功在 PC 端接收,PC 端发送 “hello world!” 字符串在板端也成功接收,

至此,UART1 已经成功与外部设备进行通信。



参考资料:

【1】《外围设备驱动操作指南.doc》

【2】《Hi3559V200_PINOUT_CN.xlsx》

【3】《HI3559V200DMEB_VER_A_SCH.pdf》

技术文档

类型标题档案
软件C文件

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论