本文來源電子發(fā)燒友社區(qū),作者:voidpbq, 帖子地址:https://bbs.elecfans.com/jishu_2303725_1_1.html
一、前言
本章介紹下OKG2L的uart引腳、測試方法以及如何處理迪文串口的uart信息。
二、硬件
2.1 電路圖
OKG2L支持三個uart口,其中
GPIO33、35分別為rx,tx
在底板的P23,從下往上數(shù)左側(cè)第9個為uart的rx(接收端),可以查看uart圖標(biāo)找到對應(yīng)位置。
35是開發(fā)板的TX,33是開發(fā)板的RX。
使用電腦的串口工具時,連接usb ttl小板,開發(fā)板TX接小板RX。
2.2 連接圖
連接迪文串口屏,開發(fā)板tx連接串口屏rx
連接如下圖
三、代碼
3.1 fltest_uarttest——官方實現(xiàn)uart基礎(chǔ)測試
串口代碼路徑:drivers/tty/serial/sh-sci.c
開發(fā)板中路徑:/dev/ttySX
外接的uart時ttySC1
官方提供的cmd:fltest_uarttest
fltest_uarttest工具代碼路徑:OKG2L-linux-sdk10appsrcforlinx-cmduarttest
我的代碼也是基于這個增加了串口件通信。
PS:注意,這里是一位一位獲取數(shù)據(jù)的,經(jīng)我測試,一次讀取最多8位,所以需要增加新的機(jī)制判斷一組數(shù)據(jù)是否獲取完畢。
詳見如下問題一節(jié)。
3.2 實現(xiàn)迪文串口間通信
此代碼為我基于官方實現(xiàn)添加了迪文串口屏的事件判定,開源,禁止商用,謝謝。
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;
四、測試結(jié)果
這是檢索事件
錄音及停止事件
掃碼及停止
nfc檢索及停止
PS:電子發(fā)燒友的代碼顯示有異常,有興趣的話去我的csdn查看,后續(xù)會更新出來。
https://blog.csdn.net/qq_38091632
六、編譯
命令:$CC uart_example.c dwin.c -o dwin_test
五、問題
5.1 字符串地址傳遞
void u8_to_char(uint8_t * , char ** );
子函數(shù)內(nèi)如果使用malloc分配空間,建議使用char **進(jìn)行地址傳遞。
也可以在main函數(shù)中先分配,再傳指針進(jìn)子函數(shù)。
5.2 uart數(shù)據(jù)
串口傳輸可以選擇hex還是字符串,我們在使用串口工具測試時選擇hex,模擬實際迪文屏數(shù)據(jù)傳輸。
此外注意傳入的數(shù)據(jù)為uint_8,需要轉(zhuǎn)換為字符串進(jìn)行分析。
原數(shù)據(jù):0x5AA5
字符串:"5AA5"
傳出時再進(jìn)行字符串轉(zhuǎn)為uint_8
5.3 一次接收8位
使用read函數(shù)對ttySC1進(jìn)行讀取,一次只能讀8位。
由于迪文屏的串口數(shù)據(jù)結(jié)構(gòu),其中的第三個字節(jié)傳輸?shù)氖呛罄m(xù)數(shù)據(jù)的長度。
比如0x5AA5 06 82 1000 01 1234
其中的06就是后續(xù)的82 1000 01 1234長度,所以先計算出一組數(shù)據(jù)長度為06+3,3是前面的5AA5加上len。
代碼中先判斷head為5AA5,然后存入len,當(dāng)接收到的字符串長度為len*2,一組接收完畢。
乘以2是因為uint_8轉(zhuǎn)換為兩位char。
六、小結(jié)
串口通信較為簡單,實現(xiàn)了基礎(chǔ)的讀寫功能后再結(jié)合串口屏的傳輸協(xié)議進(jìn)行數(shù)據(jù)處理。
此功能應(yīng)該適用于其他linux開發(fā)板,后續(xù)可以在其他平臺上試試。
目前上述代碼只是實現(xiàn)了基本的事件判斷架構(gòu),后續(xù)各種判斷條件可以自行添加,只需要定義匹配的字符串以及執(zhí)行的函數(shù)即可。
最后,感謝飛凌提供的試用機(jī)會。
-
飛凌
+關(guān)注
關(guān)注
0文章
135瀏覽量
16403 -
開發(fā)板試用
+關(guān)注
關(guān)注
3文章
301瀏覽量
2340
發(fā)布評論請先 登錄
具有3D圖形和視頻編解碼器的通用 MPU RZ/G2L 數(shù)據(jù)手冊

瑞薩電子RZ MPU家族精品RZ/N2L產(chǎn)品介紹

飛凌嵌入式受邀亮相瑞薩2024工業(yè)技術(shù)研討會

瑞薩RZ/G2L微處理器的SD卡GPIO控制功能介紹

【飛凌嵌入式OK3588J-C開發(fā)板體驗】OK3588J-C開發(fā)板開箱評測
RZ/G2L高速虛擬串口方案 基于瑞薩RZ/G2L SMARC開發(fā)板的虛擬(Virtual UART)實現(xiàn)方案

【飛凌嵌入式OK3576-C開發(fā)板體驗】開箱報告
迪文串口屏如何與電腦連接
【飛凌嵌入式OK527N-C開發(fā)板體驗】- 1. 開箱
迪文串口屏基礎(chǔ)GUI開發(fā)流程

評論