-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpetitPanCake.c
137 lines (129 loc) · 5.03 KB
/
petitPanCake.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/**************************************************************************************
petitPanCake for Raspberry Pi
Copyright (c) 2015 Wataru KUNINO
***************************************************************************************/
#include <stdio.h> // 標準入出力用
#include <fcntl.h> // シリアル通信用(Fd制御)
#include <termios.h> // シリアル通信用(端末IF)
#include <unistd.h> // read,usleep用
#include <string.h> // strncmp,bzero用
#include <sys/time.h> // fd_set,select用
#include <ctype.h> // isprint,isdigit用
static int ComFd; // シリアル用ファイルディスクリプタ
static struct termios ComTio_Bk; // 現シリアル端末設定保持用の構造体
static int TXL_WAIT = 2500;
static int MOVIE = 0;
int open_serial_port(){
struct termios ComTio; // シリアル端末設定用の構造体変数
speed_t speed = B115200; // 通信速度の設定
char modem_dev[15]="/dev/ttyUSBx"; // シリアルポートの初期値
int i;
for(i=12;i>=-1;i--){
if(i>=10) snprintf(&modem_dev[5],8,"rfcomm%1d",i-10); // ポート探索(rfcomm0-2)
else if(i>=0) snprintf(&modem_dev[5],8,"ttyUSB%1d",i); // ポート探索(USB0~9)
else snprintf(&modem_dev[5],8,"ttyAMA0"); // 拡張IOのUART端子に設定
ComFd=open(modem_dev, O_RDWR|O_NONBLOCK); // シリアルポートのオープン
if(ComFd >= 0){ // オープン成功時
printf("com=%s\n",modem_dev); // 成功したシリアルポートを表示
tcgetattr(ComFd, &ComTio_Bk); // 現在のシリアル端末設定状態を保存
ComTio.c_iflag = 0; // シリアル入力設定の初期化
ComTio.c_oflag = 0; // シリアル出力設定の初期化
ComTio.c_cflag = CLOCAL|CREAD|CS8; // シリアル制御設定の初期化
ComTio.c_lflag = 0; // シリアルローカル設定の初期化
bzero(ComTio.c_cc,sizeof(ComTio.c_cc)); // シリアル特殊文字設定の初期化
cfsetispeed(&ComTio, speed); // シリアル入力の通信速度の設定
cfsetospeed(&ComTio, speed); // シリアル出力の通信速度の設定
ComTio.c_cc[VMIN] = 0; // リード待ち容量0バイト(待たない)
ComTio.c_cc[VTIME] = 0; // リード待ち時間0.0秒(待たない)
tcflush(ComFd,TCIFLUSH); // バッファのクリア
tcsetattr(ComFd, TCSANOW, &ComTio); // シリアル端末に設定
break; // forループを抜ける
}
}
return ComFd;
}
char read_serial_port(void){
char c='\0'; // シリアル受信した文字の代入用
fd_set ComReadFds; // select命令用構造体ComReadFdを定義
struct timeval tv; // タイムアウト値の保持用
FD_ZERO(&ComReadFds); // ComReadFdの初期化
FD_SET(ComFd, &ComReadFds); // ファイルディスクリプタを設定
tv.tv_sec=0; tv.tv_usec=TXL_WAIT;
if(select(ComFd+1, &ComReadFds, 0, 0, &tv)) read(ComFd, &c, 1); // データを受信
// usleep(5000); // 5msの(IchigoJam処理)待ち時間
return c; // 戻り値=受信データ(文字変数c)
}
int close_serial_port(void){
tcsetattr(ComFd, TCSANOW, &ComTio_Bk);
return close(ComFd);
}
int ahex2i(char c){
if(c>='0' && c<='9') return c-'0';
if(c>='a' && c<='f') return c-'a'+10;
if(c>='A' && c<='F') return c-'F'+10;
return -1;
}
int main(int argc,char **argv){
char s[256]; // 文字データ用
char PC_LINE[]={0x80,0x08,0x01};
int i,j,k,loop;
char c; // 文字入力用の文字変数
FILE *fp;
printf("petitPanCake for Raspberry Pi\n");
if( argc < 2){
fprintf(stderr,"Usage : %s input_files\n",argv[0]);
fprintf(stderr," %s fuji.txt\n",argv[0]);
fprintf(stderr," %s pc_movie/pc*.txt\n",argv[0]);
fprintf(stderr,"PanCake用コマンドのファイルを入力してください。\n");
return -1;
}
if( argc > 2){
MOVIE=1; TXL_WAIT=1800;
printf("MOVIE mode\n");
}
if(open_serial_port() <= 0){
fprintf(stderr,"UART OPEN ERROR\n");
return -1;
}
for(loop=0;loop < (argc-1);loop++){
fp=fopen(argv[loop+1],"r");
if(fp==0){
fprintf(stderr,"FILE OPEN ERROR\n");
return -1;
}
while(feof(fp)==0){
fgets(s,256,fp);
// printf("%s",s);
if(strncmp(s,"?\"",2)==0) j=2;
else if(strncmp(s,"? \"",3)==0) j=3;
else j=0;
if(strncmp(&s[j],"PC LINE",7)==0){
if(!MOVIE) printf("(BIN)%s",s);
write(ComFd, PC_LINE, 3);
for(i=j+8;i<j+23;i+=3){
k=ahex2i(s[i]); if( k<0 ) break;
c=(char)ahex2i(s[i+1]); if( c<0 ) break;
c+=(char)(k<<4);
write(ComFd, &c, 1);
// usleep(TX_WAIT);
}
j=0;
}else for(i=j;i<255;i++){
if(s[i]=='\"' || s[i]=='\0' ) break;
write(ComFd, &s[i], 1);
// usleep(TX_WAIT);
}
write(ComFd, "\r\n", 2);
c=read_serial_port();
while(c){
if( isprint(c) ) printf("%c",c); // 表示可能な文字の時に表示する
if( c=='\n' ) printf("\n");
c=read_serial_port(); // シリアルからデータを受信
}
}
fclose(fp);
}
printf("DONE\n");
close_serial_port();
return 0;
}