【飞凌RZ/G2L开发板试用体验】5. 迪文串口屏事件分析

描述

本文来源电子发烧友社区,作者:voidpbq, 帖子地址:https://bbs.elecfans.com/jishu_2303725_1_1.html


一、前言

本章介绍下OKG2L的uart引脚、测试方法以及如何处理迪文串口的uart信息。

二、硬件

2.1 电路图

OKG2L支持三个uart口,其中

开发板试用

GPIO33、35分别为rx,tx

开发板试用

开发板试用

在底板的P23,从下往上数左侧第9个为uart的rx(接收端),可以查看uart图标找到对应位置。

35是开发板的TX,33是开发板的RX。

使用电脑的串口工具时,连接usb ttl小板,开发板TX接小板RX。

2.2 连接图

连接迪文串口屏,开发板tx连接串口屏rx

连接如下图

开发板试用

三、代码

3.1 fltest_uarttest——官方实现uart基础测试

串口代码路径:drivers/tty/serial/sh-sci.c

开发板中路径:/dev/ttySX

外接的uart时ttySC1

官方提供的cmd:fltest_uarttest

开发板试用

fltest_uarttest工具代码路径:OKG2L-linux-sdk10appsrcforlinx-cmduarttest

我的代码也是基于这个增加了串口件通信。
PS:注意,这里是一位一位获取数据的,经我测试,一次读取最多8位,所以需要增加新的机制判断一组数据是否获取完毕。
详见如下问题一节。

3.2 实现迪文串口间通信

此代码为我基于官方实现添加了迪文串口屏的事件判定,开源,禁止商用,谢谢。

uart_example.c



#include "dwin.h"

#include           /*��׼�����������*/
#include          /*��׼�����ⶨ��*/
#include          /*Unix��׼��������*/
#include       /**/
#include        /**/
#include           /*�ļ����ƶ���*/
#include         /*PPSIX�ն˿��ƶ���*/
#include           /*����Ŷ���*/
#include	 
#include     
#include     
#include    "stdbool.h"

#define uint8_t u_int8_t
#define bool _Bool

extern void u8_to_char(uint8_t * , char ** );
extern int judge_dwin_cmd(uint8_t ** );
extern int get_len(uint8_t *cmd_u8);
extern dwin_event_flag uart_judge_dwin_event(i_dwin_cmd * cmd);
extern i_dwin_cmd temp_cmd_recv;
extern dwin_event_key event_key_list[EVENT_KEY_NUM_MAX];
extern dwin_event_key_spec event_key_spec[EVENT_KEY_SPEC_NUM_MAX];

extern c_dwin_cmd cmd_recv_char; // from dwin
extern c_dwin_cmd cmd_send_char; // send to dwin
extern dwin_event_flag c_judge_dwin_event(c_dwin_cmd * cmd);
extern void c_dwin_cmd_analysis(char * in,c_dwin_cmd *cmd);
extern void c_print_cmd(c_dwin_cmd *cmd);

#define UART_ID                 0

#define UART_RECV_LEN           1024
#define BUF_RX_MAX 512
#define LEN_CHAR_TEMP 17

c_dwin_cmd cmd_char;

int search_str_end(uint8_t *str_z, int count)
{
int temp_zero = 1;
int temp_count = count -1;  // 有效字符11个,12个是0x00
printf("init count = %d, temp_count = %dn",count,temp_count);
uint8_t *str_temp1 = str_z;

while(1)
{
printf("str = [%02X], temp_zero = [%d], temp_count = [%d]n",*str_temp1,temp_zero,temp_count);
// if find 10 zero, will return count
if(*str_temp1 != 0x00)
{
printf("value = %02X, %ldn",*str_temp1,str_temp1-str_z);
temp_count += temp_zero;
str_temp1++;
temp_zero = 1;
}
else
{
temp_zero++;
printf("value = %02X, %ldn",*str_temp1,str_temp1-str_z);
}

if(temp_zero > 10)
break;

}
printf("init count = %d, temp_count = %dn",count,temp_count);
return temp_count;

}

int my_strlen(uint8_t *str)
{
printf("enter my_strlen");
uint8_t *str_temp = str;
// assert(str);
int count = 0;

// while (*str != '') // this will ignore 0x00
while (*str_temp != '')
{
printf("value = %02X, %ldn",*str_temp,str_temp-str);
count++;
str_temp++;
}
// has found 0x00, str end. but uart data may contents 0x00 .. 0x00
// so, need to judge next value
count = search_str_end(str_temp-1,count);

return count;

}

int judge_char(uint8_t * str)
{
if (str != NULL){
// not empty
printf("enter judge_char");
if (my_strlen(str) != 0) {
// not ''
return 1;
}
else
return 0;
}
else
return -1;
}

void func_uart_write(uint8_t * str, int fd)
{
printf("enter func_uart_write");
unsigned int ret;

// plus 3 due to dwin has head1/2/len
ret = write(fd, str, *(str+2));
if (ret <0)
{
printf("%s, %d: LzUartInit(%d) failed!n", __FILE__, __LINE__, ret);
return;
}

}

void uint8_2_char(uint8_t * in,char * out, int cp_len)
{
printf("raw uint8_t data[");
int cmd_len=*(in+2)+3;
char tmp[3];
memset(tmp,0x00,3);
for(int i =0;i< cp_len;i++)
{
printf("%02X",*(in+i));
sprintf(tmp,"%02X",*(in+i));
strcat(out,tmp);

memset(tmp,0x00,3);
}
printf("]n");

}

void main(void)
{
int fd;
int nread;
char buf_rx[BUF_RX_MAX+1];
int n=0,i=0;
char dev[]  = "/dev/ttySC1";
struct termios oldtio,newtio;
speed_t speed = B115200;
int next_option,havearg = 0,flow = 0;


/*  打开串口 */
fd = open(dev, O_RDWR | O_NONBLOCK| O_NOCTTY | O_NDELAY);
if (fd < 0)	{
printf("Can't Open Serial Port!n");
exit(0);	
}

printf("Welcome to uart buf_txn");

//save to oldtio
tcgetattr(fd,&oldtio);
bzero(&newtio,sizeof(newtio));
newtio.c_cflag = speed|CS8|CLOCAL|CREAD;
newtio.c_cflag &= ~CSTOPB;
newtio.c_cflag &= ~PARENB;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
// newtio.c_cc[VTIME]=10;
tcflush(fd,TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
tcgetattr(fd,&oldtio);

memset(buf_rx,0,BUF_RX_MAX+1);

char buf_tx[100]="forlinx_uart_test.1234567890...";

printf("Send buf_tx data:n[%s] [%ld]n",buf_tx,strlen(buf_tx));
write(fd, buf_tx, strlen(buf_tx));
fd_set rd;

int flag_rx=0;
bool flag_rx1= false;
bool flag_rx2 = false;

bool flag_print=true;
int cmd_len=0;

uint8_t str_send[UART_RECV_LEN] = "HelloWorld!n";
char str_send_char[513] = "";
uint8_t recv_int8[UART_RECV_LEN];
char recv_char[UART_RECV_LEN];
uint8_t recv_int8_t[9];
char recv_char_t[LEN_CHAR_TEMP];

char *recv_char_p=NULL;

bool status_uart_send = false;

init_dwin_status();

// ------------------- test uint8 to char -------------------
uint8_t xxx[]={0X5A,0XA5,0X05,0X82,0X10,0X00,0X00,0X01};
// u8_2_char(xxx);
char *yyy=(char *)malloc(get_len(recv_int8));
u8_to_char(xxx,&yyy);
// yyy = (char *)u8_to_char(xxx);
printf("yyy = %sn",yyy);
// ------------------- test uint8 to char -------------------

printf("enter whilen");

while (1)
{
// ----------------- uart read -----------------
memset(recv_int8_t,0x00,UART_RECV_LEN);
int nread = read(fd, recv_int8_t, UART_RECV_LEN);
if (nread >  0)
{
if(*recv_int8_t==0x5a && *(recv_int8_t+1)==0xa5)
{
cmd_len=*(recv_int8_t+2)+3;
cmd_len=2*cmd_len ;
printf("ncmd len = %dn",cmd_len);

}

memset(recv_char_t,0x00,LEN_CHAR_TEMP);
uint8_2_char(recv_int8_t,recv_char_t, nread);

strcat(recv_char,recv_char_t);

flag_rx1=true;
flag_rx2=true;


}
else if(nread < 0 )
{
printf("%s, %d: LzUartInit(%d) failed!n", __FILE__, __LINE__, nread);
return;
}
if(nread == 0)
{
// 判断传输停止
if(flag_rx1==true&&flag_rx2==true)
{
flag_rx2=false;
}
else if(flag_rx1==true&&flag_rx2==false)
{
flag_rx1=false;

if(strlen(recv_int8)>0)
{
if(strlen(recv_char)==cmd_len)
{
printf(">>>recv_cmd_char = [%s]n",recv_char);
c_dwin_cmd_analysis(recv_char,&cmd_recv_char);
memset(recv_char,0x00,UART_RECV_LEN);
tcflush(fd, TCIOFLUSH);
}

}


}


}

}
close(fd);

return;
}

dwin.h



#include "stddef.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
#include "stdint.h"

#define TRUE 1
#define FALSE 0
#define uint8_t u_int8_t
#define bool _Bool

typedef enum{
EVENT_FLAG_OK = 0X0,
EVENT_FLAG_AUDIO_RECORD = 0x3,
EVENT_FLAG_AUDIO_PLAY = 0x4,
EVENT_FLAG_CAM_SCAN = 0x5,
EVENT_FLAG_NFC_SCAN = 0x6,
EVENT_FLAG_BOOK_SEARCH = 0x10,
EVENT_FLAG_BOOK_INPUT = 0x11,
EVENT_FLAG_UNKOWN = -1,
}dwin_event_flag;

typedef enum{
// EVENT_FLAG_STATUS_START = 0x0,
EVENT_FLAG_STATUS_ING = TRUE,
EVENT_FLAG_STATUS_STOP = FALSE,
EVENT_FLAG_STATUS_ERROR = -1,
}dwin_event_flag_status;

typedef enum{
EVENT_TYPE_DWIN_SEND = 0x0,  // uart read
EVENT_FLAG_DWIN_RECV = 0x1,  // uart write
}dwin_event_type;

#define DWIN_CMD_LEN_U8_MAX 259

typedef struct
{
uint8_t head[2];
uint8_t len;
uint8_t wr;
uint8_t addr[2];
uint8_t * value;
// uint8_t cmd_u8[DWIN_CMD_LEN_U8_MAX];
uint8_t * cmd_u8;
char * cmd_char;
}i_dwin_cmd;

void uart_recv_value_cut(uint8_t * recv_all);
// dwin_event_flag uart_judge_dwin_event(char *str);
dwin_event_flag uart_judge_dwin_event(i_dwin_cmd * cmd);

void print_dwin_cmd(i_dwin_cmd cmd);

char * dwin_cmd_uint8_t2char(i_dwin_cmd cmd);

char * uint8_t2char(uint8_t value);

char * uint8_t2char_list(uint8_t * p_dwin_u8_value,int len);

void change_dwin_status(dwin_event_flag event_flag);

// UART recv/send judge dwin_event
#define EVENT_KEY_NUM_MAX 10
// #define EVENT_KEY_MAX -1

// function
void func_open_record();
void func_close_record();
void func_open_cam();
void func_close_cam();
void func_open_nfc();
void func_close_nfc();

#define EVENT_NAME_MAX 11
#define EVENT_FLAG_NAME_MAX 30
#define EVENT_KEY_VALUE_MAX 11   //"3000 0001"  is 8

typedef struct
{
dwin_event_flag flag;
char event_name[EVENT_NAME_MAX];
dwin_event_flag_status status;
char key[EVENT_KEY_VALUE_MAX];   // key[0,3] addr key[4,7] value
char flag_name[EVENT_FLAG_NAME_MAX];
void (*open)();
void (*close)();
}dwin_event_key;

dwin_event_key event_key_list[EVENT_KEY_NUM_MAX];
// {
//     // {
//     //     event_flag, event_name,
//     //     event_status,
//     //     event_addr, event_flag_name,
//     //     event_ops1, enent_ops1
//     // },

//     {
//         EVENT_FLAG_AUDIO_RECORD, "record",
//         EVENT_FLAG_STATUS_STOP,
//         "1503", "EVENT_FLAG_AUDIO_RECORD",
//         func_open_record,   func_close_record
//     },

//     {
//         EVENT_FLAG_CAM_SCAN,    "cam",
//         EVENT_FLAG_STATUS_STOP,
//         "1504", "EVENT_FLAG_CAM_SCAN",
//         func_open_cam,      func_close_cam
//     },

//     {
//         EVENT_FLAG_NFC_SCAN,    "nfc",
//         EVENT_FLAG_STATUS_STOP,
//         "1505", "EVENT_FLAG_NFC_SCAN",
//         func_open_nfc,      func_close_nfc
//     },

//     {
//         EVENT_FLAG_UNKOWN,  "unknow",
//         EVENT_FLAG_STATUS_STOP,
//         "0000" , "EVENT_FLAG_UNKOWN"
//     }
// };

typedef struct
{
char key[EVENT_KEY_VALUE_MAX];   // key[0,3] addr key[4,7] value
char event_name[EVENT_FLAG_NAME_MAX];
void (*func)();
}dwin_event_key_spec;

void func_search();
void func_spec_end();

void searc_spec_event();

#define EVENT_KEY_SPEC_VALUE "over"
#define EVENT_KEY_SPEC_NUM_MAX 20
dwin_event_key_spec event_key_spec[EVENT_KEY_SPEC_NUM_MAX];
// {
//     // special event, just one ops
//     // {
//     //     event_key, event_name,
//     //     event_ops
//     // },

//     {
//         "1502010012",  "search",
//         func_search
//     },
//     // ...

//     {EVENT_KEY_SPEC_VALUE,  "end",
//         func_spec_end
//     }
// };

void change_dwin_status_key(dwin_event_key *in_key);

void change_cmd_send_status(dwin_event_flag temp_event_flag);

// -------------------- basic func  --------------------

void copy_u8_2_u8(uint8_t * u8_raw);

void u8_to_char(uint8_t * in_u8, char ** out);

uint8_t * u8_to_u8(uint8_t * in_u8);

// -------------------- dwin func --------------------
void dwin_cmd_init_send();
void init_dwin_status();
void i_dwin_cmd_clear(i_dwin_cmd * cmd);

// get u8 from example
void uart_dwin_cmd_analysis(uint8_t *str);

void copy_u8_to_cmdu8(i_dwin_cmd *cmd, uint8_t * u8);

//int my_strlen(uint8_t *str);

// int search_str_end(uint8_t *str_z, int count);
// int my_strlen(uint8_t *str);
// int judge_char(uint8_t * str);

#define DWIN_CMD_CHAR_ADDR_VALUE 8
#define DWIN_CMD_CHAR_VALUE_VALUE 12
#define DWIN_CMD_CHAR_MAX 513
#define DWIN_CMD_U8_MAX 256

// add for char
#define C_CMD_POINT_HEAD 0
#define C_CMD_POINT_LEN 4
#define C_CMD_POINT_WR 6
#define C_CMD_POINT_ADDR 8
#define C_CMD_POINT_VALUE 12

typedef struct
{
char head[5];
char len[3];
char wr[3];
char addr[5];
char * value;
char * cmd_char;
}c_dwin_cmd;


四、测试结果

开发板试用

这是检索事件

开发板试用

录音及停止事件

开发板试用

扫码及停止

开发板试用

nfc检索及停止

PS:电子发烧友的代码显示有异常,有兴趣的话去我的csdn查看,后续会更新出来。
https://blog.csdn.net/qq_38091632

六、编译

命令:$CC uart_example.c dwin.c -o dwin_test

五、问题

5.1 字符串地址传递

void u8_to_char(uint8_t * , char ** );

子函数内如果使用malloc分配空间,建议使用char **进行地址传递。

也可以在main函数中先分配,再传指针进子函数。

5.2 uart数据

串口传输可以选择hex还是字符串,我们在使用串口工具测试时选择hex,模拟实际迪文屏数据传输。

此外注意传入的数据为uint_8,需要转换为字符串进行分析。

原数据:0x5AA5
字符串:"5AA5"

传出时再进行字符串转为uint_8

5.3 一次接收8位

使用read函数对ttySC1进行读取,一次只能读8位。

由于迪文屏的串口数据结构,其中的第三个字节传输的是后续数据的长度。

比如0x5AA5 06 82 1000 01 1234

其中的06就是后续的82 1000 01 1234长度,所以先计算出一组数据长度为06+3,3是前面的5AA5加上len。

代码中先判断head为5AA5,然后存入len,当接收到的字符串长度为len*2,一组接收完毕。

乘以2是因为uint_8转换为两位char。

六、小结

串口通信较为简单,实现了基础的读写功能后再结合串口屏的传输协议进行数据处理。

此功能应该适用于其他linux开发板,后续可以在其他平台上试试。

目前上述代码只是实现了基本的事件判断架构,后续各种判断条件可以自行添加,只需要定义匹配的字符串以及执行的函数即可。

最后,感谢飞凌提供的试用机会。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分