OSDN Git Service

11/11/30 12H serial csv out.
[scilog/cpu2010.git] / main.c
1 /*
2  * File:   main.c
3  * sciLogger サブCPU
4  * PIC24Fj64GA004
5  * 8MHz
6  *
7  * Created on February 9, 2010, 10:53 AM
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <p24FJ64GA004.h>
13 #include <libpic30.h>
14 //#include <uart.h>
15 #include <string.h>
16 #include "myuart.h"
17 #include "myspi.h"
18 #include "debug_print.h"
19 #include "ublox.h"
20 #include "myad.h"
21 #include "delay.h"
22 #include "ring.h"
23 #include "byte2var.h"
24 #include "myint.h"
25 #include "mysts.h"
26
27 _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2 )
28 //_CONFIG2( FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_OFF & FNOSC_FRC)
29 #pragma config FCKSM = CSDCMD, OSCIOFNC = ON, POSCMOD = OFF, FNOSC = FRC, FPBDIV = DIV_8
30
31 //#define CPU_CLOCK        10000000                         // クロック[ Hz ]
32 //#define CPU_PLL          8                                // PLL
33 //#define CLOCK_FREQUENCY  ( ( CPU_CLOCK * CPU_PLL ) / 4 )  // 動作周波数[ Hz ]
34 //#define FOSC 4000000L
35 // UART2 Debug Port
36 #define BAUDRATE2         9600L
37 // UART1 GPS
38 #define BAUDRATE1         9600L
39
40 /*** ADバッファ *************************************************
41  * 50Hzデータ
42  * 1秒平均データ
43  * タイムスタンプ
44  */
45 #define ADBUF_BYTE  3   // AD 1CH 1sample dataのbyte数
46
47 typedef struct {
48     UbloxNavTimeUtc t;  // タイムスタンプ
49     long data1sec[AD_CHNUM];  // 1sec平均値
50     unsigned char data[AD_CHNUM][ADBUF_BYTE*AD_SAMPLE];  // AD_SAMPLE[Hz]のデータ
51 } ADbufType;
52 static ADbufType   adbuf[RING_NUM];
53
54 // SPI外部送信用バッファ AD_SAMPLE[Hz]
55 //static char adbuf[RING_NUM][AD_CHNUM][ADBUF_BYTE*AD_SAMPLE];
56 // 1sec平均値
57 //static long adbuf_1sec[RING_NUM][AD_CHNUM];
58 // timestamp
59 //static UbloxNavTimeUtc adbuf_t[RING_NUM];
60
61 #define adbuf_get(buf_no)   (&adbuf[buf_no])
62 #define adbuf_data_get(buf_no)   (adbuf[buf_no].data)
63 #define adbuf_1sec_get(buf_no)   (adbuf[buf_no].data1sec)
64 #define adbuf_time_get(buf_no)   (&(adbuf[buf_no].t))
65
66 inline void my_memcpy(void *dest0, void *src0, int len)
67 {
68     int i;
69     char *dest, *src;
70
71     dest = (char*)dest0;
72     src = (char*)src0;
73     for(i = 0; i < len; i++) {
74         *dest++ = *src++;
75     }
76 }
77 inline void my_memset(void *dest0, unsigned char data, int len)
78 {
79     int i;
80     char *dest;
81
82     dest = (char*)dest0;
83     for(i = 0; i < len; i++) {
84         *dest++ = data;
85     }
86 }
87 inline void adbuf_write(unsigned char buf_no, unsigned char ch, int cnt, long *data)
88 {
89     unsigned char    *ptr = (unsigned char*)data;
90     unsigned char   i;
91
92     for(i = 0; i < ADBUF_BYTE; i++) {
93         adbuf->data[ch][ADBUF_BYTE*cnt + i] = *(ptr++);
94     }
95 }
96 // 1
97 inline void adbuf_1sec_write(char buf_no, long *data)
98 {
99     my_memcpy(adbuf_1sec_get(buf_no), data, sizeof(long) * AD_CHNUM);
100 /*    char ch;
101     for(ch = 0; ch < AD_CHNUM; ch++)
102         adbuf_1sec[buf_no][ch] = data[ch];
103 */
104 }
105 inline void adbuf_time_write(char buf_no, UbloxNavTimeUtc *t)
106 {
107 //    my_memcpy(&adbuf_t[buf_no], t, sizeof(UbloxNavTimeUtc));
108     my_memcpy(adbuf_time_get(buf_no), t, sizeof(UbloxNavTimeUtc));
109 }
110
111 /**** ublox *************************************************/
112
113 void test_ublox_rcv_mon(void)
114 {
115     unsigned char class, id;
116     unsigned int    len;
117     unsigned char   payload[128];
118     char    sz[128];
119     UbloxNavTimeUtc *gps, gps1;
120
121     gps = &gps1;
122     
123     while(1) {
124         ublox_rcv_pkt(&class, &id, &len, payload);
125         sprintf(sz, "CLASS=%02X ID=%02X LEN=%d\r\n", class, id, len);
126         PDEBUG(sz);
127         ublox_debug_pkt_out(payload, len);
128         ublox_decode_nav_timeutc(payload, gps);
129         sprintf(sz, "%04u/%02d/%02d %02d:%02d:%02d.%09ld %6lums %6luns %02X\r\n",
130             gps->year, gps->month, gps->day, gps->hour, gps->min, gps->sec, gps->nano,
131             gps->tow, gps->tacc, gps->valid
132         );
133         PDEBUG(sz);
134
135     }
136 }
137 static UbloxNavTimeUtc gpsNow;
138 static void ublox_rcv(void)
139 {
140     unsigned char class, id;
141     unsigned int    len;
142     unsigned char   payload[128];
143 //    char    sz[128];
144     UbloxNavTimeUtc *gps = &gpsNow;
145
146     ublox_rcv_pkt(&class, &id, &len, payload);
147 //    sprintf(sz, "CLASS=%02X ID=%02X LEN=%d\r\n", class, id, len);
148 //    PDEBUG(sz);
149 //    ublox_debug_pkt_out(payload, len);
150     if (class == UBX_CLS_NAV && id == UBX_ID_NAV_TIMEUTC && len == UBX_LEN_NAV_TIMEUTC) {
151         ublox_decode_nav_timeutc(payload, gps);
152 /*        sprintf(sz, "%04u/%02d/%02d %02d:%02d:%02d.%09ld %6lums %6luns %02X\r\n",
153             gps->year, gps->month, gps->day, gps->hour, gps->min, gps->sec, gps->nano,
154             gps->tow, gps->tacc, gps->valid
155         );
156         PDEBUG(sz);
157 */
158     }
159 }
160
161 /**** INT1/SPI1 ***********************************************/
162 /*
163  * INT1 Int及びSPI1 IntでADのデータを取得する
164  */
165 #define ADSTS_IDLE  0
166 #define ADSTS_H 1
167 #define ADSTS_M 2
168 #define ADSTS_L 3
169
170
171 static char adint_ch;   // 取得中のCH
172 static char adint_cnt = 0;  // 0〜AD_SAMPLE-1
173 static char adint_sts = ADSTS_IDLE;
174 static long adint_add[AD_CHNUM];    // 1秒平均用加算
175
176 /**** 1PPS ********************************************/
177 static char pps_intf;
178
179 #define pps_intf_clear()  pps_intf = 0
180 #define pps_intf_set()  pps_intf = 1
181 #define pps_is_intf_enable()    (pps_intf != 0)
182
183 /*
184  * main()
185  */
186 int main(int argc, char** argv) {
187     unsigned int i;
188     // UART2 DebugPort
189     const double Baudrate2 = ( double )FCY / ( 16 * BAUDRATE2 ) - 1;
190     // ボーレートの小数点以下を四捨五入する
191     unsigned int baudrate2 = ( unsigned int )( Baudrate2 + 0.5 );
192     // UART1 GPS
193     const double Baudrate1 = ( double )FCY / ( 16 * BAUDRATE1 ) - 1;
194     // ボーレートの小数点以下を四捨五入する
195     unsigned int baudrate1 = ( unsigned int )( Baudrate1 + 0.5 );
196     char    sz[128];
197     UbloxNavTimeUtc *gps = &gpsNow;
198
199     /**** 割り込み禁止 ****/
200     SET_CPU_IPL( 7 );
201     __builtin_write_OSCCONL(OSCCON & 0xbf); //clear the bit 6 of OSCCONL to unlock Pin Re-map
202
203     // UART1ピン割り当て
204     RPINR18bits.U1RXR = 6;      // UART1 RX to RP6
205     RPOR2bits.RP5R =  3;        // UART1 TX(3) to RP5
206     // UART2ピン割り当て
207     RPINR19bits.U2RXR = 21;     // UART2 RX to RP21
208     RPOR10bits.RP20R = 5;       // UART2 TX(5) to RP20
209     // PIC-RDYピン割り当て
210     RPOR12bits.RP25R = 0;       // RC9
211
212     // DataOut SPI2 pin config
213     RPINR22bits.SDI2R = 13;     // SPI2 RX to RP13
214     RPINR22bits.SCK2R = 23;     // SPI2 CLK to RP23
215     RPINR23bits.SS2R = 24;      // SPI2 SS to RP24
216     RPOR11bits.RP22R = 10;      // SPI1 SDO2(10) to RP22
217     // AD SPI1 pin config
218     RPINR20bits.SDI1R = 18;     // SPI1 RX to RP18
219     RPOR8bits.RP16R = 8;        // SPI1 SCK1(8) to RP16
220     RPOR8bits.RP17R = 7;        // SPI1 SDO1(7) to RP17
221     // TRISx 1=input 0=output
222     TRISA = 0x0000;             // PortA RA7,8,9 output
223     //        5432109876543210
224     TRISB = 0b0011000011000000; // PortB RB13(RP13),RB12,RB7,RB6(RP6) input
225     TRISC = 0x01A4;             // ポートC RC8(RP24),RC7(RP23),RC5(RP21),RC2(RP18) input
226     CLKDIV = 0;                 // CPU Peripheral Clock Ratio=1:1
227     AD1PCFG = 0xFFFF;           // AN1-12input pin = Digital mode
228
229     // INT1(RP12 RB12) AD -DRDY0 Int enable
230     RPINR0bits.INT1R = 12;  // RP12(RB12)
231     int1_level_set(4);    // Int priority
232     int1_edge_neg(); // Negative Edge
233     // INT0(RB7) GPS +PPS Int enable
234     int0_level_set(4);    // INT Priority
235     int0_edge_pos(); // Positive Edge
236
237     adint_cnt = 0;
238     ad_cs_dis();
239     sts_set(STS_NOSYNC);
240     pps_intf_clear();
241     
242     // GPS UART1初期設定 BRGH=Standard mode
243     // 9600bps 8bit nonparity 1stop nonflowcnt.
244     //                           5432109876543210
245     unsigned int U1MODEvalue = 0b1000100000000000;
246     unsigned int U1STAvalue =  0b0000010000000000;
247 //    OpenUART1( U1MODEvalue, U1STAvalue, baudrate1);
248     uart1_init( U1MODEvalue, U1STAvalue, baudrate1);
249     // DEBUG UART2初期設定 BRGH=Standard mode
250     // 9600bps 8bit nonparity 1stop nonflowcnt.
251     //                           5432109876543210
252     unsigned int U2MODEvalue = 0b1000100000000000;
253     unsigned int U2STAvalue =  0b0000010000000000;
254     uart2_init( U2MODEvalue, U2STAvalue, baudrate2);
255
256
257     spi1_init();
258     spi2_init();
259
260     PDEBUG("START\r\n");
261     puts("START debug\r\n");
262     sprintf(sz, "RPINR20=%04X\r\n", RPINR20);
263     PDEBUG(sz);
264     sprintf(sz, "SPI1CON1=%04X\r\n", SPI1CON1);
265     PDEBUG(sz);
266     sprintf(sz, "SPI1CON2=%04X\r\n", SPI1CON2);
267     PDEBUG(sz);
268     sprintf(sz, "SPI1STAT=%04X\r\n", SPI1STAT);
269     PDEBUG(sz);
270
271     // GPS UART1 受信割り込み許可
272     uart1_rx_int_enable();
273     uart1_set_int_level(4);  // 割り込みレベル デフォルト4
274     // DataOut SPI2 割り込み許可
275 //    spi2_int_enable();
276 //    spi2_set_int_level(4);
277
278     //**** 割り込み許可 **************************************************
279     // CPU割り込み優先レベル デフォルト0 ペリフェラルはデフォルト4
280 //    SRbits.IPL = 2;
281     SET_CPU_IPL( 2 );
282
283     // UBXプロトコルのみにする
284     ublox_rcvbuf_clear();
285     ublox_send_cfg_prt(BAUDRATE1);
286     ublox_rcv_ack();
287     // TimePulse2にAD用クロック出力する
288     ublox_rcvbuf_clear();
289     ublox_send_cfg_tp5_timepulse2();
290     ublox_rcv_ack();
291     // NAV-TIMEUTC出力させる
292     ublox_send_cfg_msg();
293     ublox_rcv_ack();
294
295     // AD初期化
296     ad_reset_dis();
297     ad_start_dis();
298     ad_cs_dis();
299     //
300     ad_reset(); // -AD RESET
301     // WAIT 2^16 AD system clocks
302     delay_ms(100);
303     //
304     ad_cs_init();
305     ad_init();
306     pga_init();
307     
308     ring_init();
309     // AD SPI1 割り込み設定のみ 許可しない
310     // INT1ハンドラ内で有効にされる
311     spi1_intf_clear();
312     spi1_set_int_level(4);
313
314     // INT1割り込み許可
315     int1_intf_clear();
316     int1_int_enable();    // Int enable
317     // INT0割り込み許可
318     int0_intf_clear();
319     int0_int_enable();    // Int enable
320
321     while(1) {
322         // GPSから受信してデコード
323         ublox_rcv();
324         if (gpsNow.valid == 0x07 && sts_get() == STS_NOSYNC) {
325             // 時刻有効
326             sts_set(STS_SYNCNOW0);
327         }
328         if (ring_read_get() != ring_write_get()) {
329             // タイムスタンプget
330             gps = adbuf_time_get(ring_read_get());
331             sprintf(sz, "%04u/%02d/%02d %02d:%02d:%02d.%09ld,%6lums,%6luns,%02X",
332                 gps->year, gps->month, gps->day, gps->hour, gps->min, gps->sec, gps->nano,
333                 gps->tow, gps->tacc, gps->valid
334             );
335             PDEBUG(sz);
336
337 #if 1
338             // AD data get
339             char ch;
340             long    *lp;
341             lp = adbuf_1sec_get(ring_read_get());
342             for(ch=0; ch<AD_CHNUM; ch++) {
343                 sprintf(sz, ",%+7ld", lp[ch]);
344                 PDEBUG(sz);
345             }
346             PDEBUG("\r\n");
347 #endif
348             ring_read_plus();
349         }
350     }
351 /*
352         if (pps_is_intf_enable()) {
353             pps_intf_clear();
354             PDEBUG("pps\r\n");
355         }
356     i = 0;
357     while(1) {
358         if (ring_read_get() != ring_write_get()) {
359             char ch;
360             for(ch=0; ch<AD_CHNUM; ch++) {
361                 sprintf(sz, "%+7ld,", adbuf_1sec[ring_read_get()][ch]);
362                 PDEBUG(sz);
363             }
364             PDEBUG("\r\n");
365
366             ring_read_plus();
367         }
368     }
369 */
370     
371     return (EXIT_SUCCESS);
372 }
373 /*
374  * INT0 GPS 1PPS割り込みハンドラ
375  * 
376  *
377  */
378 void __attribute__((interrupt, no_auto_psv)) _INT0Interrupt(void)
379 {
380     // AD STARTピン=H
381     ad_start_ena();
382
383     int0_intf_clear();
384     pps_intf_set();
385     /****AD同期!!!!!!!!!!!!!!!*/
386     // AD個数カウンタ=SAMP_FREQ-1
387     adint_cnt = AD_SAMPLE - 1;
388
389     // ADバッファにタイムスタンプ付ける
390     adbuf_time_write(ring_read_get(), &gpsNow);
391
392     // AD START信号による同期
393     if (sts_get() == STS_SYNCNOW0) {
394         // AD STARTピン=L
395         ad_start_dis();
396         sts_set(STS_SYNCNOW1);
397     } else if (sts_get() == STS_SYNCNOW1) {
398         // AD STARTピン=H
399 //        ad_start_ena();
400         sts_set(STS_SYNCWAIT);
401     } else if (sts_get() == STS_SYNCWAIT) {
402         sts_set(STS_SYNCED);
403     }
404 }
405
406 /*
407  * INT1(RP12) AD DRDY0割り込みハンドラ
408  * Negativ Edge
409  * SPI1受信開始してSPI1割り込み有効にする
410  *
411  */
412 void __attribute__((interrupt, no_auto_psv)) _INT1Interrupt(void)
413 //void _ISR _INT1Interrupt(void)
414 {
415     int1_intf_clear();
416     if (!ad_is_drdy0_enable()) {
417         return;
418     }
419
420     adint_ch = 0;
421     adint_sts = ADSTS_H;
422     if (adint_cnt == 0) {
423         my_memset(adint_add, 0, sizeof(adint_add));
424     }
425
426     ad_cs(adint_ch);    // CSx=L
427     spi1_rx_overrun_clear();
428     // 前に受信したデータをクリア
429     spi1_getc();
430     // SPI割り込みON
431     spi1_intf_clear();
432     spi1_int_enable();
433     // 送信
434     spi1_putc(0);
435 }
436 /*
437  * AD SPI1 Interrupt Handler
438  * ADから受信したデータをADバッファに格納する
439  * 6CHぶん受信したらSPI1割り込みをOFF
440  * 
441  */
442 //void _ISR _SPI1Interrupt(void)
443 void __attribute__((interrupt, auto_psv)) _SPI1Interrupt(void)
444 {
445     static unsigned char in[3];
446     unsigned char c;
447     long    l;
448
449     c = spi1_getc();
450 //    spi1_intf_clear();
451     spi1_rx_overrun_clear();
452 //spi1_int_disable();
453 //ad_cs_dis();
454 //return;
455 //c=1;
456     switch(adint_sts) {
457         case ADSTS_H:
458             in[2] = c;
459             adint_sts = ADSTS_M;
460             spi1_putc(0);
461             break;
462         case ADSTS_M:
463             in[1] = c;
464             adint_sts = ADSTS_L;
465             spi1_putc(0);
466             break;
467         case ADSTS_L:
468             // CSx=H
469             ad_cs_dis();
470             in[0] = c;
471             l = byte3_to_long(in);
472             // バッファに書きこみ
473             adbuf_write(ring_write_get(), adint_ch, adint_cnt, &l);
474             // 1秒平均用加算
475             adint_add[adint_ch] += l;
476             // CH進める
477             adint_ch++;
478             if (adint_ch >= AD_CHNUM) {
479                 // 全CHデータgetした
480                 adint_cnt++;
481                 if (adint_cnt >= AD_SAMPLE) {
482                     // 1secぶんのデータgetした
483                     // 平均してバッファに書きこみ
484                     char ch;
485                     for(ch = 0; ch < AD_CHNUM; ch++) {
486                         adint_add[ch] /= adint_cnt;
487                     }
488                     // バッファに書きこみ
489                     adbuf_1sec_write(ring_write_get(), adint_add);
490                     // バッファ書き込み位置+1
491                     ring_write_plus();
492                     adint_cnt = 0;
493                 }
494                 spi1_int_disable(); // SPI割り込みOFF
495                 adint_sts = ADSTS_IDLE;
496             } else {
497                 // 次のCHへ
498                 ad_cs(adint_ch);    // CSx=L
499                 // 送信
500                 spi1_putc(0);
501                 adint_sts = ADSTS_H;
502             }
503
504             break;
505         default:
506             spi1_int_disable(); // SPI割り込みOFF
507             adint_sts = ADSTS_IDLE;
508             break;
509     }
510
511 }
512
513 /*
514  * DataOut SPI2 Interrupt Handler
515  * TX FIFOに1byteの空きが出来ると発生
516  */
517 void __attribute__((interrupt, no_auto_psv)) _SPI2Interrupt(void)
518 {
519 static unsigned char   spi2c;
520     unsigned char   rx;
521     static unsigned int txlen = 512;
522 /*
523     while(!spi2_tx_fifo_is_full())
524         spi2_putc(c++);
525     while(!spi2_rx_fifo_is_empty()) {
526         rx = spi2_getc();
527         if (rx == '$') c = 0;
528     }
529 */
530 //spi2c = 123;
531 // RX FIFOから読み出し
532 //    while(!spi2_rx_fifo_is_empty() || (!spi2_tx_fifo_is_full() && txlen > 0)) {
533     while(!spi2_rx_fifo_is_empty()) {
534         if (!spi2_rx_fifo_is_empty()) {
535             rx = spi2_getc();
536             if (rx == '$') {
537                 spi2c = 0;
538                 txlen = 3;
539             }
540         }
541         // TX FIFOに書き込み
542         if (!spi2_tx_fifo_is_full()) {
543             if (txlen > 0) {
544                 spi2_putc(spi2c++);
545                 txlen--;
546             }
547         }
548     }
549     // オーバーランエラーならばクリアする
550     // spi2_rx_is_overrun()
551     if (SPI2STATbits.SPIROV == 1) SPI2STATbits.SPIROV = 0;
552
553     // TODO:Interrupt Flag@IEC Clear
554 }
555 /*
556 void test_ad1()
557 {
558         unsigned char in[3];
559         long l[6];
560         char cs;
561         while(!ad_is_drdy0_enable());
562 //        PDEBUG("AD\r\n");
563         for(cs=0; cs<6; cs++) {
564             ad_cs(cs);
565                 in[2] = ad_spi_rcv();
566                 in[1] = ad_spi_rcv();
567                 in[0] = ad_spi_rcv();
568             ad_cs_dis();
569             l[cs] = byte3_to_long(in);
570 //            sprintf(sz, "%02X %02X %02X", in[2], in[1], in[0]);
571 //            PDEBUG(sz);
572         }
573         for(cs=0; cs<6; cs++) {
574             sprintf(sz, "%+7ld,", l[cs]);
575             PDEBUG(sz);
576         }
577         PDEBUG("\r\n");
578
579 }
580  */
581 /*
582  * CS0〜15順番にenable
583  */
584 void test_ad_cs()
585 {
586     int i;
587     
588     while(1) {
589         delay_ms(1000);
590         ad_cs(i);
591         i++;
592         if (i >= 16) i = 0;
593     }
594 }
595
596 /*
597  Dataout SPI2 test
598  */
599 void test_spi2()
600 {
601     unsigned int    c = 0x12;
602     unsigned int    rx;
603     unsigned int    sts = 0;
604     int i;
605     
606     i = SPI2BUF;
607     while(1) {
608         PORTCbits.RC9 = 1;
609         delay_ms(100);
610         PORTCbits.RC9 = 0;
611         delay_ms(900);
612
613 //        while(spi2_tx_fifo_is_full());
614 //        spi2_putc(c++);
615 //        while(spi2_rx_fifo_is_empty());
616 //        rx = spi2_getc();
617 #if 0
618         while(spi2STATbits.SPIRBF == 0);
619         sts = spi2STAT;
620         if (spi2STATbits.SPITBF == 0) {
621             spi2BUF = c++;
622         }
623 //        while(spi2STATbits.SPIRBF == 1) {
624             i = spi2BUF;
625 //        }
626         if (i == '$') {
627             c = 0;
628         }
629         if (spi2STATbits.SPIROV == 1) spi2STATbits.SPIROV = 0;
630         sprintf(sz, "%d %04X\r\n", i, sts);
631         PDEBUG(sz);
632 #endif
633 //        while(spi2STATbits.SPITBF == 1);
634 //        while(spi2STATbits.SPITBF);
635 /*
636          while(!spi2_tx_fifo_is_full())
637             spi2_putc(c++);
638         while(!spi2_rx_fifo_is_empty()) {
639             rx = spi2_getc();
640             if (rx == '$') c = 0;
641         }
642 */
643         //        i = ReadUART1();
644 //        WriteUART2(i);
645
646 //        PDEBUG(mes);
647 //        delay();
648     }
649 }