Overoで動作するデータ収録プログラム
サブCPUからGPS時刻付きADデータを取得してSDに記録する。
Revisão | 5d4820757c9692d0c0a5125adc558336f741ad58 (tree) |
---|---|
Hora | 2011-12-15 23:48:36 |
Autor | Naoya Takamura <ntaka206@user...> |
Commiter | Naoya Takamura |
SDへの書き込み間隔を長くする
SPI CMD send add
@@ -30,9 +30,9 @@ INCDIR = ${STAGEDIR}/include | ||
30 | 30 | |
31 | 31 | TARGET = scilog |
32 | 32 | |
33 | -OBJS = scilog.o spi.o thread_rcv.o ring.o ad_ring.o thread_rec.o sts.o ad_file.o conf.o | |
33 | +OBJS = scilog.o spi.o thread_rcv.o ring.o ad_ring.o thread_rec.o sts.o ad_file.o conf.o lcd.o | |
34 | 34 | |
35 | -HDRS = mes_print.h debug_print.h spi.h my_thread.h ring.h ad_ring.h thread_rec.h sts.h ad_file.h conf.h | |
35 | +HDRS = mes_print.h debug_print.h spi.h my_thread.h ring.h ad_ring.h thread_rec.h sts.h ad_file.h conf.h lcd.h | |
36 | 36 | |
37 | 37 | ${TARGET} : $(OBJS) $(HDRS) |
38 | 38 | ${CC} ${CFLAGS} ${OBJS} -L ${LIBDIR} -o ${TARGET} |
@@ -2,6 +2,7 @@ | ||
2 | 2 | #define __AVG_RING_H__ |
3 | 3 | |
4 | 4 | #include <time.h> |
5 | +#include "spi.h" | |
5 | 6 | |
6 | 7 | // リングバッファサイズ 個数 |
7 | 8 | #define AD_RING_NUM (60 * 5) |
@@ -29,12 +30,15 @@ typedef struct { | ||
29 | 30 | |
30 | 31 | // リングバッファのデータタイプ |
31 | 32 | typedef struct { |
33 | + char rescode; // コマンドに対する返答 ACK/NAK/NUL | |
34 | + char resdata[SPI_RESDATA_LEN]; // コマンドに対する返答データ | |
32 | 35 | UbloxNavTimeUtc gps; // GPSタイムスタンプ SPIで受信 |
33 | 36 | struct tm t; // タイムスタンプ struct tmの月は(0〜11)なので注意 年は1900からのオフセット |
34 | 37 | int freq; // 平均周波数 Hz |
35 | 38 | long data1sec[AD_CHNUM]; // 1sec平均値 SPIで受信 |
36 | 39 | long data[AD_CHNUM][AD_SAMPLE]; // AD_SAMPLE[Hz]の生データ SPIで受信 |
37 | 40 | long avg[AD_CHNUM][AD_SAMPLE]; // 平均後データ |
41 | + unsigned int checksum; // SPI受信データのchecksumフィールド | |
38 | 42 | } AdData; |
39 | 43 | |
40 | 44 |
@@ -0,0 +1,146 @@ | ||
1 | +#include <stdio.h> | |
2 | +#include <unistd.h> | |
3 | +#include <string.h> | |
4 | +#include <sys/ioctl.h> | |
5 | +#include <sys/types.h> | |
6 | +#include <sys/stat.h> | |
7 | +#include <fcntl.h> | |
8 | +#include <linux/i2c-dev.h> /* for I2C_SLAVE */ | |
9 | + | |
10 | +#include "mes_print.h" | |
11 | +#include "lcd.h" | |
12 | + | |
13 | +#define DEV_LCD "/dev/i2c-3" | |
14 | + | |
15 | + | |
16 | +static int fh = -1; | |
17 | + | |
18 | +static int lcd_open(void) | |
19 | +{ | |
20 | + fh = open(DEV_LCD, O_RDWR); | |
21 | + return fh; | |
22 | +} | |
23 | +static void lcd_close(void) | |
24 | +{ | |
25 | + close(fh); | |
26 | + fh = -1; | |
27 | +} | |
28 | +// 1byte out | |
29 | +static void lcd_out(unsigned char dat, char rs) | |
30 | +{ | |
31 | + unsigned char data[2]; | |
32 | + | |
33 | + if (lcd_open() < 0) { | |
34 | + PERRF("ERROR lcd_open()\n"); | |
35 | + return; | |
36 | + } | |
37 | + ioctl(fh, I2C_SLAVE, I2CLCD_ADDRESS >> 1); | |
38 | + | |
39 | + data[0] = rs ? 0x40 : 0x00; // RS | |
40 | + data[1] = dat; | |
41 | + write(fh, data, 2); | |
42 | + | |
43 | + lcd_close(); | |
44 | +} | |
45 | +/* | |
46 | + 複数バイトout | |
47 | + RS=1 | |
48 | +*/ | |
49 | +static void lcd_out_mul(unsigned char *out, int len) | |
50 | +{ | |
51 | + unsigned char data[256]; | |
52 | + | |
53 | + if (lcd_open() < 0) { | |
54 | + PERRF("ERROR lcd_open()\n"); | |
55 | + return; | |
56 | + } | |
57 | + ioctl(fh, I2C_SLAVE, I2CLCD_ADDRESS >> 1); | |
58 | + | |
59 | + data[0] = 0x40; // RS = 1 | |
60 | + if (len >= sizeof(data)) len = sizeof(data)-1; | |
61 | + memcpy(data+1, out, len); | |
62 | + write(fh, data, len+1); | |
63 | + | |
64 | + lcd_close(); | |
65 | +} | |
66 | +/* | |
67 | + i2c LCDモジュールの設定 | |
68 | +*/ | |
69 | +static void i2clcd_init(void) | |
70 | +{ | |
71 | + unsigned char data[16]; | |
72 | + unsigned char cfg; | |
73 | + | |
74 | + fh = -1; | |
75 | + if (lcd_open() < 0) { | |
76 | + PERRF("ERROR lcd_open()\n"); | |
77 | + return; | |
78 | + } | |
79 | + ioctl(fh, I2C_SLAVE, I2CLCD_ADDRESS >> 1); | |
80 | + | |
81 | + cfg = 0; | |
82 | + data[0] = I2CLCD_CFG_ENABLE | (cfg & 0x1f); | |
83 | + data[1] = 0; | |
84 | + write(fh, data, 2); | |
85 | + | |
86 | + lcd_close(); | |
87 | +} | |
88 | +/* | |
89 | + LCD初期化 | |
90 | +*/ | |
91 | +void lcd_init(void) | |
92 | +{ | |
93 | + unsigned char func, display, entry; | |
94 | + | |
95 | + i2clcd_init(); | |
96 | + usleep(10*1000); | |
97 | + | |
98 | + lcd_out(0x30, 0); | |
99 | + usleep(5*1000); | |
100 | + lcd_out(0x30, 0); | |
101 | + usleep(2*1000); | |
102 | + lcd_out(0x30, 0); | |
103 | + | |
104 | + func = I2CLCD_8BITMODE | I2CLCD_2LINE | I2CLCD_5x8DOTS; | |
105 | +// shift = | |
106 | + display = I2CLCD_DISPLAYON | I2CLCD_CURSOROFF | I2CLCD_BLINKOFF; | |
107 | + entry = I2CLCD_ENTRYLEFT; | |
108 | + | |
109 | + lcd_out(0x20 | (func & 0x1f), 0); // func | |
110 | +// lcd_out(0x10 | (shift & 0x0f), 0); // shift | |
111 | + lcd_out(0x08 | (display & 0x07), 0); // display | |
112 | + lcd_out(0x04 | (entry & 0x03), 0); // entry mode | |
113 | + | |
114 | + lcd_clear(); | |
115 | + lcd_home(); | |
116 | +} | |
117 | +/* | |
118 | + int x,y: 0始まり | |
119 | +*/ | |
120 | +void lcd_pos(int x, int y) | |
121 | +{ | |
122 | + unsigned char adr; | |
123 | + unsigned char ofs[] = {0, 0x40, 0x14, 0x54 }; | |
124 | + | |
125 | + if (y >= LCD_YMAX) y = LCD_YMAX - 1; | |
126 | + if (x >= LCD_XMAX) x = LCD_XMAX - 1; | |
127 | + adr = ofs[y] + x; | |
128 | + lcd_out(I2CLCD_SETDDRAMADDR | (adr & 0x7F), 0); | |
129 | +} | |
130 | + | |
131 | +void lcd_print(char *str) | |
132 | +{ | |
133 | + lcd_out_mul((unsigned char*)str, strlen(str)); | |
134 | +} | |
135 | +void lcd_clear(void) | |
136 | +{ | |
137 | + lcd_out(I2CLCD_CLEARDISPLAY, 0); | |
138 | +usleep(2*1000); | |
139 | +} | |
140 | +void lcd_home(void) | |
141 | +{ | |
142 | + lcd_out(I2CLCD_RETURNHOME, 0); | |
143 | +usleep(2*1000); | |
144 | +} | |
145 | + | |
146 | + |
@@ -0,0 +1,59 @@ | ||
1 | +#if !defined(__I2CLCD_H__) | |
2 | +#define __I2CLCD_H__ | |
3 | + | |
4 | +#define I2CLCD_ADDRESS 0x7c | |
5 | +// i2c LCDモジュール設定用 | |
6 | +#define I2CLCD_CFG_ENABLE 0x20 | |
7 | +#define I2CLCD_CFG_LED 0x08 | |
8 | +#define I2CLCD_CFG_3V 0x04 | |
9 | +#define I2CLCD_CFG_ADDR 0x02 | |
10 | +#define I2CLCD_CFG_INIT 0x01 | |
11 | + | |
12 | +// commands | |
13 | +#define I2CLCD_CLEARDISPLAY 0x01 | |
14 | +#define I2CLCD_RETURNHOME 0x02 | |
15 | +#define I2CLCD_ENTRYMODESET 0x04 | |
16 | +#define I2CLCD_DISPLAYCONTROL 0x08 | |
17 | +#define I2CLCD_CURSORSHIFT 0x10 | |
18 | +#define I2CLCD_FUNCTIONSET 0x20 | |
19 | +#define I2CLCD_SETCGRAMADDR 0x40 | |
20 | +#define I2CLCD_SETDDRAMADDR 0x80 | |
21 | + | |
22 | +// flags for display entry mode | |
23 | +#define I2CLCD_ENTRYRIGHT 0x00 | |
24 | +#define I2CLCD_ENTRYLEFT 0x02 | |
25 | +#define I2CLCD_ENTRYSHIFTINCREMENT 0x01 | |
26 | +#define I2CLCD_ENTRYSHIFTDECREMENT 0x00 | |
27 | + | |
28 | +// flags for display on/off control | |
29 | +#define I2CLCD_DISPLAYON 0x04 | |
30 | +#define I2CLCD_DISPLAYOFF 0x00 | |
31 | +#define I2CLCD_CURSORON 0x02 | |
32 | +#define I2CLCD_CURSOROFF 0x00 | |
33 | +#define I2CLCD_BLINKON 0x01 | |
34 | +#define I2CLCD_BLINKOFF 0x00 | |
35 | + | |
36 | +// flags for display/cursor shift | |
37 | +#define I2CLCD_DISPLAYMOVE 0x08 | |
38 | +#define I2CLCD_CURSORMOVE 0x00 | |
39 | +#define I2CLCD_MOVERIGHT 0x04 | |
40 | +#define I2CLCD_MOVELEFT 0x00 | |
41 | + | |
42 | +// flags for function set | |
43 | +#define I2CLCD_8BITMODE 0x10 | |
44 | +#define I2CLCD_4BITMODE 0x00 | |
45 | +#define I2CLCD_2LINE 0x08 | |
46 | +#define I2CLCD_1LINE 0x00 | |
47 | +#define I2CLCD_5x10DOTS 0x04 | |
48 | +#define I2CLCD_5x8DOTS 0x00 | |
49 | + | |
50 | +#define LCD_YMAX 4 | |
51 | +#define LCD_XMAX 20 | |
52 | + | |
53 | +void lcd_init(void); | |
54 | +void lcd_pos(int x, int y); | |
55 | +void lcd_print(char *str); | |
56 | +void lcd_clear(void); | |
57 | +void lcd_home(void); | |
58 | + | |
59 | +#endif |
@@ -27,6 +27,7 @@ | ||
27 | 27 | #include "thread_rec.h" |
28 | 28 | #include "conf.h" |
29 | 29 | #include "ad_file.h" |
30 | +#include "lcd.h" | |
30 | 31 | |
31 | 32 | // debug_print.h内で#define DEBUG_PRINTしているので |
32 | 33 | // リリース時は、debug_print.hでコメントする |
@@ -83,10 +84,10 @@ int main (int argc, char *argv[]) | ||
83 | 84 | signal(SIGKILL, sig_handler); |
84 | 85 | signal(SIGTERM, sig_handler); |
85 | 86 | |
86 | -// lcd_init(); | |
87 | -// lcd_pos(6, 1); | |
88 | -// lcd_print("sciLogger"); | |
89 | -// lcd_pos(0, 3); | |
87 | + lcd_init(); | |
88 | + lcd_pos(6, 1); | |
89 | + lcd_print("sciLogger"); | |
90 | + lcd_pos(0, 3); | |
90 | 91 | |
91 | 92 | ad_ring_init(); |
92 | 93 | sts_init(); |
@@ -100,7 +101,7 @@ int main (int argc, char *argv[]) | ||
100 | 101 | // 設定ファイル読み込み |
101 | 102 | conf_read(); |
102 | 103 | PDEBUG("freq=%d\n", conf_freq_get()); |
103 | -// lcd_print("*"); | |
104 | + lcd_print("*"); | |
104 | 105 | |
105 | 106 | PDEBUG("sciLogger %s START\n", VERSION); |
106 | 107 | sleep(1); |
@@ -111,7 +112,7 @@ int main (int argc, char *argv[]) | ||
111 | 112 | perror("spi_open() ERROR!"); |
112 | 113 | goto END; |
113 | 114 | } |
114 | -// lcd_print(fd_lcd0, "*"); | |
115 | + lcd_print("*"); | |
115 | 116 | |
116 | 117 | // |
117 | 118 | /**** スレッド生成 |
@@ -123,7 +124,7 @@ int main (int argc, char *argv[]) | ||
123 | 124 | } else { |
124 | 125 | PDEBUG("SPI RCV thread create\n"); |
125 | 126 | } |
126 | -// lcd_print("*"); | |
127 | + lcd_print("*"); | |
127 | 128 | |
128 | 129 | // |
129 | 130 | /**** メインループ 記録 ************************ |
@@ -6,27 +6,34 @@ | ||
6 | 6 | |
7 | 7 | // SPI送信データ長セット |
8 | 8 | #define CMD_TX_LEN 12 |
9 | -// SPI送信データセット | |
9 | +// SPI送信データセット PICへのコマンド | |
10 | 10 | #define CMD_TX_SET 13 |
11 | - | |
12 | 11 | // リングバッファにあるデータ数を返す |
13 | 12 | #define CMD_DNUM_GET 14 |
14 | - | |
15 | 13 | // リングバッファクリア |
16 | 14 | #define CMD_BUF_CLEAR 15 |
17 | - | |
18 | 15 | // SPIで実際に受信したデータ長を取得 |
19 | 16 | #define CMD_RECEIVED_LEN_GET 20 |
20 | 17 | |
21 | 18 | // SPIで受信するデータ長 固定長 $含む |
22 | -#define SPI_DATA_LEN 945 | |
23 | -// SPI受信データの先頭文字 | |
19 | +#define SPI_DATA_LEN 965 | |
20 | +// SPI受信データの先頭文字 送信コマンドでも使用 | |
24 | 21 | #define SPI_HEAD_CHAR '$' |
25 | 22 | |
23 | +// SPI受信データ 応答データ 長さ | |
24 | +#define SPI_RESDATA_LEN 17 | |
25 | + | |
26 | +// SPI受信データ Checksum 長さ | |
27 | +#define SPI_CHECKSUM_LEN 2 | |
28 | + | |
29 | +// SPI送信するコマンド長 固定長 $含む | |
30 | +#define SPI_CMD_LEN 20 | |
31 | + | |
32 | + | |
26 | 33 | // SPI受信データの先頭からのオフセット |
27 | -#define SPI_OFS_GPS (18-17) | |
28 | -#define SPI_OFS_1SEC (38-17) | |
29 | -#define SPI_OFS_DATA (62-17) | |
34 | +#define SPI_OFS_GPS (19) | |
35 | +#define SPI_OFS_1SEC (39) | |
36 | +#define SPI_OFS_DATA (63) | |
30 | 37 | |
31 | 38 | |
32 | 39 |
@@ -7,6 +7,7 @@ | ||
7 | 7 | #include <sys/types.h> |
8 | 8 | #include <string.h> |
9 | 9 | |
10 | +#include "debug_print.h" | |
10 | 11 | #include "spi.h" |
11 | 12 | #include "ad_ring.h" |
12 | 13 | #include "conf.h" |
@@ -40,6 +41,11 @@ static int decode(char *buf, AdData *ad) | ||
40 | 41 | gps = &(ad->gps); |
41 | 42 | |
42 | 43 | if (*ptr++ != SPI_HEAD_CHAR) return -1; |
44 | + // Response Code | |
45 | + ad->rescode = *ptr++; | |
46 | + // Response Data | |
47 | + memcpy(ad->resdata, ptr, SPI_RESDATA_LEN); | |
48 | + ptr += SPI_RESDATA_LEN; | |
43 | 49 | // GPS |
44 | 50 | gps->tow = *((int32_t*)ptr); ptr += 4; |
45 | 51 | gps->tacc = *((int32_t*)ptr); ptr += 4; |
@@ -64,6 +70,7 @@ static int decode(char *buf, AdData *ad) | ||
64 | 70 | } |
65 | 71 | } |
66 | 72 | // Checksum |
73 | + memcpy(&(ad->checksum), ptr, SPI_CHECKSUM_LEN); | |
67 | 74 | |
68 | 75 | // gps->struct tm |
69 | 76 | ad->t.tm_year = gps->year - 1900; |
@@ -100,14 +107,23 @@ static void do_avg(int freq, AdData *ad) | ||
100 | 107 | } |
101 | 108 | void* thread_rcv(void* pParam) |
102 | 109 | { |
103 | - while(1) { | |
104 | - fd_set fds; | |
105 | - char buf[SPI_DATA_LEN+256]; | |
106 | - int i; | |
107 | -// int ch; | |
108 | - int fd_spi; | |
109 | - AdData ad, *ad_ptr; | |
110 | 110 | |
111 | + fd_set fds; | |
112 | + char buf[SPI_DATA_LEN+256]; | |
113 | + int i; | |
114 | + int fd_spi; | |
115 | + AdData ad, *ad_ptr; | |
116 | +#if 0 | |
117 | +char cmd[SPI_CMD_LEN]; | |
118 | +char c; | |
119 | +c=0; | |
120 | +#endif | |
121 | + // spiドライバのリングバッファクリア | |
122 | + spi_buf_clear(); | |
123 | + // spi送信コマンド長セット | |
124 | + spi_tx_len_set(SPI_CMD_LEN); | |
125 | + | |
126 | + while(1) { | |
111 | 127 | fd_spi = spi_get_fd(); |
112 | 128 | // select の準備 |
113 | 129 | FD_ZERO(&fds); |
@@ -117,9 +133,18 @@ void* thread_rcv(void* pParam) | ||
117 | 133 | i = select(fd_spi + 1, &fds, NULL, NULL, NULL); // 読みselect |
118 | 134 | if(i <= 0) syslog(LOG_ERR, "%s: select returned with signal or error. ret=%d\n", __FUNCTION__, i); |
119 | 135 | if(FD_ISSET(fd_spi, &fds)) { |
136 | +#if 0 | |
137 | +// SPI送信データセット | |
138 | +memset(cmd, 0, SPI_CMD_LEN); | |
139 | +cmd[0] = SPI_HEAD_CHAR; | |
140 | +cmd[1] = 1; | |
141 | +cmd[2] = 2; | |
142 | +cmd[3] = c++; | |
143 | +spi_tx_set(cmd); | |
144 | +#endif | |
120 | 145 | // 受信した |
121 | 146 | i = spi_dnum_get(); |
122 | -//printf("thread_rcv(): wakeup dnum=%d rcv_len=%d\n", i, spi_rcvd_len_get()); | |
147 | +//PDEBUG("thread_rcv(): wakeup dnum=%d rcv_len=%d\n", i, spi_rcvd_len_get()); | |
123 | 148 | while(i-- > 0) { |
124 | 149 | memset(&ad, 0, sizeof(ad)); |
125 | 150 | // データ取得 |
@@ -129,22 +154,25 @@ void* thread_rcv(void* pParam) | ||
129 | 154 | ad.freq = conf_freq_get(); |
130 | 155 | // 平均 仮コード 要変更 |
131 | 156 | do_avg(AD_SAMPLE, &ad); |
132 | -#if 0 | |
133 | -printf("%04d/%02d/%02d %02d:%02d:%02d.%09ld,%6lums,%6luns,%02X", | |
134 | - ad.t.year, ad.t.month, ad.t.day, ad.t.hour, ad.t.min, ad.t.sec, ad.t.nano, | |
135 | - ad.t.tow, ad.t.tacc, ad.t.valid); | |
157 | +#if 1 | |
158 | +int ch; | |
159 | +PDEBUG("%04d/%02d/%02d %02d:%02d:%02d.%09ld,%6lums,%6luns,%02X", | |
160 | + ad.gps.year, ad.gps.month, ad.gps.day, ad.gps.hour, ad.gps.min, ad.gps.sec, ad.gps.nano, | |
161 | + ad.gps.tow, ad.gps.tacc, ad.gps.valid); | |
136 | 162 | for(ch = 0; ch < AD_CHNUM; ch++) { |
137 | - printf(",%+7ld", ad.data1sec[ch]); | |
163 | + PDEBUG(",%+7ld", ad.data1sec[ch]); | |
138 | 164 | } |
139 | -printf("\r\n"); | |
165 | +PDEBUG("\r\n"); | |
166 | +#endif | |
167 | +#if 0 | |
140 | 168 | for(ch = 0; ch < AD_CHNUM; ch++) { |
141 | - printf(",%+7ld", ad.data[ch][0]); | |
169 | + PDEBUG(",%+7ld", ad.data[ch][0]); | |
142 | 170 | } |
143 | -printf("\r\n"); | |
171 | +PDEBUG("\r\n"); | |
144 | 172 | for(ch = 0; ch < AD_CHNUM; ch++) { |
145 | - printf(",%+7ld", ad.data[ch][49]); | |
173 | + PDEBUG(",%+7ld", ad.data[ch][49]); | |
146 | 174 | } |
147 | -printf("\r\n"); | |
175 | +PDEBUG("\r\n"); | |
148 | 176 | #endif |
149 | 177 | // ADリングバッファに書き込み |
150 | 178 | ad_ptr = ad_ring_get(ad_ring_write_get()); |
@@ -10,11 +10,12 @@ | ||
10 | 10 | #include "ad_file.h" |
11 | 11 | |
12 | 12 | // 1secファイル書き込み間隔 sec |
13 | -#define SEC_FLUSH_NUM 1 | |
14 | -//#define SEC_FLUSH_NUM 60 | |
13 | +//#define SEC_FLUSH_NUM 1 | |
14 | +#define SEC_FLUSH_NUM 60 | |
15 | 15 | |
16 | 16 | // 高速サンプルファイル書き込み間隔 sec |
17 | -#define HIGH_FLUSH_NUM 1 | |
17 | +//#define HIGH_FLUSH_NUM 1 | |
18 | +#define HIGH_FLUSH_NUM 10 | |
18 | 19 | |
19 | 20 | // 日付変化検出用 |
20 | 21 | static struct tm high_tm; |
@@ -103,6 +104,7 @@ int ProcRec(void) | ||
103 | 104 | while(ad_ring_num_get_sec() > 0) { |
104 | 105 | // データ取り出し |
105 | 106 | d = ad_ring_get(ad_ring_read_get_sec()); |
107 | +#if 0 | |
106 | 108 | PDEBUG("%04d/%02d/%02d %02d:%02d:%02d.%09ld,%6lums,%6luns,%02X", |
107 | 109 | d->gps.year, d->gps.month, d->gps.day, d->gps.hour, d->gps.min, d->gps.sec, d->gps.nano, |
108 | 110 | d->gps.tow, d->gps.tacc, d->gps.valid); |
@@ -111,6 +113,7 @@ for(ch = 0; ch < AD_CHNUM; ch++) { | ||
111 | 113 | PDEBUG(",%+7ld", d->data1sec[ch]); |
112 | 114 | } |
113 | 115 | PDEBUG("\r\n"); |
116 | +#endif | |
114 | 117 | |
115 | 118 | // 日にち変わった ファイル切換する |
116 | 119 | #ifdef DEBUG_FILE_MIN |