7 * Created on February 9, 2010, 10:53 AM
12 #include <p24FJ64GA004.h>
18 #include "debug_print.h"
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
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
36 #define BAUDRATE2 9600L
38 #define BAUDRATE1 9600L
40 /*** ADバッファ *************************************************
45 #define ADBUF_BYTE 3 // AD 1CH 1sample dataのbyte数
46 #define ADBUF_LEN sizeof(ADbufType) // 1dataの長さ byte
49 UbloxNavTimeUtc t; // タイムスタンプ
50 long data1sec[AD_CHNUM]; // 1sec平均値
51 unsigned char data[AD_CHNUM][ADBUF_BYTE*AD_SAMPLE]; // AD_SAMPLE[Hz]のデータ
53 static ADbufType adbuf[RING_NUM];
55 // SPI外部送信用バッファ AD_SAMPLE[Hz]
56 //static char adbuf[RING_NUM][AD_CHNUM][ADBUF_BYTE*AD_SAMPLE];
58 //static long adbuf_1sec[RING_NUM][AD_CHNUM];
60 //static UbloxNavTimeUtc adbuf_t[RING_NUM];
62 #define adbuf_get(buf_no) (&adbuf[buf_no])
63 #define adbuf_data_get(buf_no) (adbuf[buf_no].data)
64 #define adbuf_1sec_get(buf_no) (adbuf[buf_no].data1sec)
65 #define adbuf_time_get(buf_no) (&(adbuf[buf_no].t))
67 inline void my_memcpy(void *dest0, void *src0, int len)
74 for(i = 0; i < len; i++) {
78 inline void my_memset(void *dest0, unsigned char data, int len)
84 for(i = 0; i < len; i++) {
88 inline void adbuf_write(unsigned char buf_no, unsigned char ch, int cnt, long *data)
90 unsigned char *ptr = (unsigned char*)data;
93 for(i = 0; i < ADBUF_BYTE; i++) {
94 adbuf->data[ch][ADBUF_BYTE*cnt + i] = *(ptr++);
98 inline void adbuf_1sec_write(char buf_no, long *data)
100 my_memcpy(adbuf_1sec_get(buf_no), data, sizeof(long) * AD_CHNUM);
102 for(ch = 0; ch < AD_CHNUM; ch++)
103 adbuf_1sec[buf_no][ch] = data[ch];
106 inline void adbuf_time_write(char buf_no, UbloxNavTimeUtc *t)
108 // my_memcpy(&adbuf_t[buf_no], t, sizeof(UbloxNavTimeUtc));
109 my_memcpy(adbuf_time_get(buf_no), t, sizeof(UbloxNavTimeUtc));
112 /**** ublox *************************************************/
114 void test_ublox_rcv_mon(void)
116 unsigned char class, id;
118 unsigned char payload[128];
120 UbloxNavTimeUtc *gps, gps1;
125 ublox_rcv_pkt(&class, &id, &len, payload);
126 sprintf(sz, "CLASS=%02X ID=%02X LEN=%d\r\n", class, id, len);
128 ublox_debug_pkt_out(payload, len);
129 ublox_decode_nav_timeutc(payload, gps);
130 sprintf(sz, "%04u/%02d/%02d %02d:%02d:%02d.%09ld %6lums %6luns %02X\r\n",
131 gps->year, gps->month, gps->day, gps->hour, gps->min, gps->sec, gps->nano,
132 gps->tow, gps->tacc, gps->valid
138 static UbloxNavTimeUtc gpsNow;
139 static void ublox_rcv(void)
141 unsigned char class, id;
143 unsigned char payload[128];
145 UbloxNavTimeUtc *gps = &gpsNow;
147 ublox_rcv_pkt(&class, &id, &len, payload);
148 // sprintf(sz, "CLASS=%02X ID=%02X LEN=%d\r\n", class, id, len);
150 // ublox_debug_pkt_out(payload, len);
151 if (class == UBX_CLS_NAV && id == UBX_ID_NAV_TIMEUTC && len == UBX_LEN_NAV_TIMEUTC) {
152 ublox_decode_nav_timeutc(payload, gps);
153 /* sprintf(sz, "%04u/%02d/%02d %02d:%02d:%02d.%09ld %6lums %6luns %02X\r\n",
154 gps->year, gps->month, gps->day, gps->hour, gps->min, gps->sec, gps->nano,
155 gps->tow, gps->tacc, gps->valid
162 /**** INT1/SPI1 ***********************************************/
164 * INT1 Int及びSPI1 IntでADのデータを取得する
172 static char adint_ch; // 取得中のCH
173 static char adint_cnt = 0; // 0〜AD_SAMPLE-1
174 static char adint_sts = ADSTS_IDLE;
175 static long adint_add[AD_CHNUM]; // 1秒平均用加算
177 /**** 1PPS ********************************************/
178 static char pps_intf;
180 #define pps_intf_clear() pps_intf = 0
181 #define pps_intf_set() pps_intf = 1
182 #define pps_is_intf_enable() (pps_intf != 0)
184 /**** SPI2 *********************************************/
185 #define SPI2CSpin (PORTCbits.RC8)
187 static int dataout_cnt;
188 #define dataout_cnt_set(i) dataout_cnt = (i)
189 #define dataout_cnt_get() dataout_cnt
190 #define dataout_cnt_minus() (dataout_cnt--)
191 /**** DRDY OUT ****************************************/
192 #define DRDY_OUT PORTCbits.RC9
193 /**** TEST *******************************************/
197 void test_spi_flag(void)
201 unsigned char txc = 0;
204 // spi2_int_disable();
205 // cnint_int_disable();
208 sprintf(sz, "SPI2STAT=%04X "
209 "SPIBEC=%d SRMPT=%d SPIROV=%d SRXMPT=%d TBF=%d RBF=%d\r\n"
211 , SPI2STATbits.SPIBEC
213 , SPI2STATbits.SPIROV
214 , SPI2STATbits.SRXMPT
215 , SPI2STATbits.SPITBF
216 , SPI2STATbits.SPIRBF
219 if ((in = uart2_rcvbuf_getc()) >= 0) {
226 sprintf(sz, "RX=%02X\r\n", rxc);
231 sprintf(sz, "TX=%02X\r\n", txc);
235 spi2_rx_overrun_clear();
238 SPI2STATbits.SPIEN = 0;
240 SPI2STATbits.SPIEN = 1;
244 SPI2STATbits.SRXMPT = 1;
253 void test_spi_send(void)
255 unsigned char txc = 1;
264 while(SPI2STATbits.SPITBF == 0) {
268 if (SPI2STATbits.SRXMPT == 0) {
269 while(SPI2STATbits.SRXMPT == 0) {
274 sprintf(sz, "SPI2STAT=%04X "
275 "SPIBEC=%d SRMPT=%d SPIROV=%d SRXMPT=%d TBF=%d RBF=%d\r\n"
277 , SPI2STATbits.SPIBEC
279 , SPI2STATbits.SPIROV
280 , SPI2STATbits.SRXMPT
281 , SPI2STATbits.SPITBF
282 , SPI2STATbits.SPIRBF
293 int main(int argc, char** argv) {
296 const double Baudrate2 = ( double )FCY / ( 16 * BAUDRATE2 ) - 1;
297 // ボーレートの小数点以下を四捨五入する
298 unsigned int baudrate2 = ( unsigned int )( Baudrate2 + 0.5 );
300 const double Baudrate1 = ( double )FCY / ( 16 * BAUDRATE1 ) - 1;
301 // ボーレートの小数点以下を四捨五入する
302 unsigned int baudrate1 = ( unsigned int )( Baudrate1 + 0.5 );
304 UbloxNavTimeUtc *gps = &gpsNow;
308 __builtin_write_OSCCONL(OSCCON & 0xbf); //clear the bit 6 of OSCCONL to unlock Pin Re-map
313 RPINR18bits.U1RXR = 6; // UART1 RX to RP6
314 RPOR2bits.RP5R = 3; // UART1 TX(3) to RP5
316 RPINR19bits.U2RXR = 21; // UART2 RX to RP21
317 RPOR10bits.RP20R = 5; // UART2 TX(5) to RP20
319 RPOR12bits.RP25R = 0; // RC9
321 // DataOut SPI2 pin config
322 RPINR22bits.SDI2R = 13; // SPI2 RX to RP13
323 RPINR22bits.SCK2R = 23; // SPI2 CLK to RP23
324 RPINR23bits.SS2R = 24; // SPI2 SS to RP24
325 RPOR11bits.RP22R = 10; // SPI1 SDO2(10) to RP22
326 // AD SPI1 pin config
327 RPINR20bits.SDI1R = 18; // SPI1 RX to RP18
328 RPOR8bits.RP16R = 8; // SPI1 SCK1(8) to RP16
329 RPOR8bits.RP17R = 7; // SPI1 SDO1(7) to RP17
330 // TRISx 1=input 0=output
331 TRISA = 0x0000; // PortA RA7,8,9 output
333 TRISB = 0b0011000011000000; // PortB RB13(RP13),RB12,RB7,RB6(RP6) input
334 TRISC = 0x01A4; // ポートC RC8(RP24),RC7(RP23),RC5(RP21),RC2(RP18) input
335 CLKDIV = 0; // CPU Peripheral Clock Ratio=1:1
336 AD1PCFG = 0xFFFF; // AN1-12input pin = Digital mode
338 // INT1(RP12 RB12) AD -DRDY0 setup
339 RPINR0bits.INT1R = 12; // RP12(RB12)
341 int1_level_set(4); // Int priority
342 int1_edge_neg(); // Negative Edge
343 // INT0(RB7) GPS +PPS setup
345 int0_level_set(4); // INT Priority
346 int0_edge_pos(); // Positive Edge
347 // ChangeNotification INT, CN20(RC8), SPI2(Overo) CS0
349 CNEN2bits.CN20IE = 1;
350 CNPU2bits.CN20PUE = 1; // Pullup ON
360 // GPS UART1初期設定 BRGH=Standard mode
361 // 9600bps 8bit nonparity 1stop nonflowcnt.
363 unsigned int U1MODEvalue = 0b1000100000000000;
364 unsigned int U1STAvalue = 0b0000010000000000;
365 // OpenUART1( U1MODEvalue, U1STAvalue, baudrate1);
366 uart1_init( U1MODEvalue, U1STAvalue, baudrate1);
367 // DEBUG UART2初期設定 BRGH=Standard mode
368 // 9600bps 8bit nonparity 1stop nonflowcnt.
370 unsigned int U2MODEvalue = 0b1000100000000000;
371 unsigned int U2STAvalue = 0b0000010000000000;
372 uart2_init( U2MODEvalue, U2STAvalue, baudrate2);
382 puts("START debug\r\n");
383 sprintf(sz, "RPINR20=%04X\r\n", RPINR20);
385 sprintf(sz, "SPI1CON1=%04X\r\n", SPI1CON1);
387 sprintf(sz, "SPI1CON2=%04X\r\n", SPI1CON2);
389 sprintf(sz, "sizeof(ADBUF)=%d\r\n", ADBUF_LEN);
392 // GPS UART1 受信割り込み許可
393 uart1_rx_int_enable();
394 uart1_set_int_level(4); // 割り込みレベル デフォルト4
395 // DebugOut UART2 受信割り込み許可
396 uart2_rx_int_enable();
397 uart2_set_int_level(4); // 割り込みレベル デフォルト4
399 //**** 割り込み許可 **************************************************
400 // CPU割り込み優先レベル デフォルト0 ペリフェラルはデフォルト4
405 ublox_rcvbuf_clear();
406 ublox_send_cfg_prt(BAUDRATE1);
408 // TimePulse2にAD用クロック出力する
409 ublox_rcvbuf_clear();
410 ublox_send_cfg_tp5_timepulse2();
413 ublox_send_cfg_msg();
421 ad_reset(); // -AD RESET
422 // WAIT 2^16 AD system clocks
430 // AD SPI1 割り込み設定のみ 許可しない
433 spi1_set_int_level(4);
437 int1_int_enable(); // Int enable
440 int0_int_enable(); // Int enable
441 // DataOut SPI2 割り込み許可しない CSのCN INTで許可するので
443 spi2_set_int_level(4);
444 // ChangeNotification INT許可 SPI2(Overo) CS
447 /****!!!!!!!!!!!!!!!!!!!!!!!!*/
454 if (gpsNow.valid == 0x07 && sts_get() == STS_NOSYNC) {
456 sts_set(STS_SYNCNOW0);
458 // DebugOutに1secデータ出力
459 if (ring_read2_get() != ring_write_get()) {
461 gps = adbuf_time_get(ring_read2_get());
462 sprintf(sz, "%04u/%02d/%02d %02d:%02d:%02d.%09ld,%6lums,%6luns,%02X",
463 gps->year, gps->month, gps->day, gps->hour, gps->min, gps->sec, gps->nano,
464 gps->tow, gps->tacc, gps->valid
472 lp = adbuf_1sec_get(ring_read2_get());
473 for(ch=0; ch<AD_CHNUM; ch++) {
474 sprintf(sz, ",%+7ld", lp[ch]);
483 if (pps_is_intf_enable()) {
489 if (ring_read_get() != ring_write_get()) {
491 for(ch=0; ch<AD_CHNUM; ch++) {
492 sprintf(sz, "%+7ld,", adbuf_1sec[ring_read_get()][ch]);
502 return (EXIT_SUCCESS);
505 * INT0 GPS 1PPS割り込みハンドラ
509 void __attribute__((interrupt, no_auto_psv)) _INT0Interrupt(void)
516 /****AD同期!!!!!!!!!!!!!!!*/
517 // AD個数カウンタ=SAMP_FREQ-1
518 adint_cnt = AD_SAMPLE - 1;
521 adbuf_time_write(ring_write_get(), &gpsNow);
524 if (sts_get() == STS_SYNCNOW0) {
527 sts_set(STS_SYNCNOW1);
528 } else if (sts_get() == STS_SYNCNOW1) {
531 sts_set(STS_SYNCWAIT);
532 } else if (sts_get() == STS_SYNCWAIT) {
538 * INT1(RP12) AD DRDY0割り込みハンドラ
540 * SPI1受信開始してSPI1割り込み有効にする
543 void __attribute__((interrupt, no_auto_psv)) _INT1Interrupt(void)
544 //void _ISR _INT1Interrupt(void)
547 if (!ad_is_drdy0_enable()) {
553 if (adint_cnt == 0) {
554 my_memset(adint_add, 0, sizeof(adint_add));
557 ad_cs(adint_ch); // CSx=L
558 spi1_rx_overrun_clear();
568 * AD SPI1 Interrupt Handler
569 * ADから受信したデータをADバッファに格納する
570 * 6CHぶん受信したらSPI1割り込みをOFF
573 //void _ISR _SPI1Interrupt(void)
574 void __attribute__((interrupt, auto_psv)) _SPI1Interrupt(void)
576 static unsigned char in[3];
582 spi1_rx_overrun_clear();
583 //spi1_int_disable();
602 l = byte3_to_long(in);
604 adbuf_write(ring_write_get(), adint_ch, adint_cnt, &l);
606 adint_add[adint_ch] += l;
609 if (adint_ch >= AD_CHNUM) {
612 if (adint_cnt >= AD_SAMPLE) {
618 for(ch = 0; ch < AD_CHNUM; ch++) {
619 adint_add[ch] /= adint_cnt;
622 adbuf_1sec_write(ring_write_get(), adint_add);
629 spi1_int_disable(); // SPI割り込みOFF
630 adint_sts = ADSTS_IDLE;
633 ad_cs(adint_ch); // CSx=L
641 spi1_int_disable(); // SPI割り込みOFF
642 adint_sts = ADSTS_IDLE;
649 * DataOut SPI2 Interrupt Handler
650 * TX FIFOに1byteの空きが出来ると発生
652 static unsigned char spi2c;
653 void __attribute__((interrupt, no_auto_psv)) _SPI2Interrupt(void)
656 static unsigned int txlen = 512;
660 // static unsigned char c=0;
661 while(!spi2_tx_fifo_is_full())
663 while(!spi2_rx_fifo_is_empty()) {
665 // if (rx == '$') c = 0;
669 while(SPI2_TBF == 0) {
670 if (dataout_cnt_get() <= 0) break;
675 while(SPI2_SRXMPT == 0) {
682 // while(!spi2_rx_fifo_is_empty() || (!spi2_tx_fifo_is_full() && txlen > 0)) {
683 while(!spi2_rx_fifo_is_empty()) {
684 if (!spi2_rx_fifo_is_empty()) {
692 if (!spi2_tx_fifo_is_full()) {
701 // spi2_rx_is_overrun()
702 if (SPI2STATbits.SPIROV == 1) SPI2STATbits.SPIROV = 0;
704 // TODO:Interrupt Flag@IEC Clear
707 * Overo SPI2 CS Input Change Notification
711 void __attribute__((interrupt, no_auto_psv)) _CNInterrupt(void)
714 if (SPI2CSpin == 1) {
718 // SPI2をリセットしてTX/RX FIFOクリア
719 SPI2STATbits.SPIEN = 0;
721 SPI2STATbits.SPIEN = 1;
734 dataout_cnt_set(ADBUF_LEN);
735 // SPI2 TX FIFOに送信データ書き込み
736 while(SPI2_TBF == 0) {
737 if (dataout_cnt_get() <= 0) break;
765 unsigned int c = 0x12;
767 unsigned int sts = 0;
777 // while(spi2_tx_fifo_is_full());
779 // while(spi2_rx_fifo_is_empty());
782 while(spi2STATbits.SPIRBF == 0);
784 if (spi2STATbits.SPITBF == 0) {
787 // while(spi2STATbits.SPIRBF == 1) {
793 if (spi2STATbits.SPIROV == 1) spi2STATbits.SPIROV = 0;
794 sprintf(sz, "%d %04X\r\n", i, sts);
797 // while(spi2STATbits.SPITBF == 1);
798 // while(spi2STATbits.SPITBF);
800 while(!spi2_tx_fifo_is_full())
802 while(!spi2_rx_fifo_is_empty()) {
804 if (rx == '$') c = 0;
820 while(!ad_is_drdy0_enable());
822 for(cs=0; cs<6; cs++) {
824 in[2] = ad_spi_rcv();
825 in[1] = ad_spi_rcv();
826 in[0] = ad_spi_rcv();
828 l[cs] = byte3_to_long(in);
829 // sprintf(sz, "%02X %02X %02X", in[2], in[1], in[0]);
832 for(cs=0; cs<6; cs++) {
833 sprintf(sz, "%+7ld,", l[cs]);