OSDN Git Service

IDE MPLABXで使えるようにする
[scilog/cpu2010.git] / main.c
diff --git a/main.c b/main.c
index 7dd2fe1..b86961c 100644 (file)
--- a/main.c
+++ b/main.c
@@ -3,6 +3,12 @@
  * sciLogger サブCPU
  * PIC24Fj64GA004
  * 8MHz
+
+ **** Ver1.1
+ * 2016/2
+ * IDE MPLABXで使えるようにするため
+ * xc16-gccのオプション, Option Categories: Optimization, Do not override 'inline' チェックを入れる
+ * _CONFIG2変更 定数定義が変わっているので
  *
  * Created on February 9, 2010, 10:53 AM
  */
@@ -11,7 +17,6 @@
 #include <stdlib.h>
 #include <p24FJ64GA004.h>
 #include <libpic30.h>
-//#include <uart.h>
 #include <string.h>
 #include "myuart.h"
 #include "myspi.h"
 #include "byte2var.h"
 #include "myint.h"
 #include "mysts.h"
+#include "util.h"
 
 _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2 )
 //_CONFIG2( FCKSM_CSDCMD & OSCIOFNC_ON & POSCMOD_OFF & FNOSC_FRC)
-#pragma config FCKSM = CSDCMD, OSCIOFNC = ON, POSCMOD = OFF, FNOSC = FRC, FPBDIV = DIV_8
+//#pragma config FCKSM = CSDCMD, OSCIOFNC = ON, POSCMOD = OFF, FNOSC = FRC, FPBDIV = DIV_8
+_CONFIG2(POSCMOD_NONE & IOL1WAY_OFF & OSCIOFNC_ON & FCKSM_CSDCMD & FCKSM_CSECMD & FNOSC_FRC)  // RC 8MHz
+
 
 //#define CPU_CLOCK        10000000                         // クロック[ Hz ]
 //#define CPU_PLL          8                                // PLL
 //#define CLOCK_FREQUENCY  ( ( CPU_CLOCK * CPU_PLL ) / 4 )  // 動作周波数[ Hz ]
 //#define FOSC 4000000L
 // UART2 Debug Port
-#define BAUDRATE2         9600L
+#define BAUDRATE2         19200L
 // UART1 GPS
 #define BAUDRATE1         9600L
 
+// SPI受信データの先頭文字 送信コマンドでも使用
+#define        SPI_HEAD_CHAR   '$'
+
 /*** ADバッファ *************************************************
  * 50Hzデータ
  * 1秒平均データ
  * タイムスタンプ
  */
 #define ADBUF_BYTE  3   // AD 1CH 1sample dataのbyte数
+#define ADBUF_LEN   (sizeof(ADbufType)+1)   // SPI送信1packetの長さ byte $含まず DMA問題のために+1byteしている
 
+#define RESDATA_LEN 17  // コマンドに対する返答データ 最大長さ
+
+// 送信データの先頭からのオフセット adbuf内のオフセット $含まない
+#define        ADBUF_OFS_SUM           962 // checksum
+
+// SPI送信にそのまま使われるので注意!
+// 全体のサイズが2byteの整数倍になるようにすること word align
 typedef struct {
+    unsigned char   rescode;    // コマンドに対する返答 ACK/NAK/NUL
+    unsigned char   resdata[RESDATA_LEN];   // コマンドに対する返答データ
     UbloxNavTimeUtc t;  // タイムスタンプ
     long data1sec[AD_CHNUM];  // 1sec平均値
     unsigned char data[AD_CHNUM][ADBUF_BYTE*AD_SAMPLE];  // AD_SAMPLE[Hz]のデータ
+    unsigned char suma;
+    unsigned char sumb;
 } ADbufType;
+//} __attribute__((__packed__)) ADbufType;
 static ADbufType   adbuf[RING_NUM];
 
-// SPI外部送信用バッファ AD_SAMPLE[Hz]
-//static char adbuf[RING_NUM][AD_CHNUM][ADBUF_BYTE*AD_SAMPLE];
-// 1sec平均値
-//static long adbuf_1sec[RING_NUM][AD_CHNUM];
-// timestamp
-//static UbloxNavTimeUtc adbuf_t[RING_NUM];
-
 #define adbuf_get(buf_no)   (&adbuf[buf_no])
 #define adbuf_data_get(buf_no)   (adbuf[buf_no].data)
 #define adbuf_1sec_get(buf_no)   (adbuf[buf_no].data1sec)
 #define adbuf_time_get(buf_no)   (&(adbuf[buf_no].t))
 
-inline void my_memcpy(void *dest0, void *src0, int len)
-{
-    int i;
-    char *dest, *src;
-
-    dest = (char*)dest0;
-    src = (char*)src0;
-    for(i = 0; i < len; i++) {
-        *dest++ = *src++;
-    }
-}
-inline void my_memset(void *dest0, unsigned char data, int len)
-{
-    int i;
-    char *dest;
-
-    dest = (char*)dest0;
-    for(i = 0; i < len; i++) {
-        *dest++ = data;
-    }
-}
 inline void adbuf_write(unsigned char buf_no, unsigned char ch, int cnt, long *data)
 {
     unsigned char    *ptr = (unsigned char*)data;
     unsigned char   i;
 
     for(i = 0; i < ADBUF_BYTE; i++) {
-        adbuf->data[ch][ADBUF_BYTE*cnt + i] = *(ptr++);
+        adbuf[buf_no].data[ch][ADBUF_BYTE*cnt + i] = *(ptr++);
     }
 }
 // 1
@@ -107,33 +103,81 @@ inline void adbuf_time_write(char buf_no, UbloxNavTimeUtc *t)
 //    my_memcpy(&adbuf_t[buf_no], t, sizeof(UbloxNavTimeUtc));
     my_memcpy(adbuf_time_get(buf_no), t, sizeof(UbloxNavTimeUtc));
 }
+inline void adbuf_sum_write(char buf_no, unsigned char *suma, unsigned char *sumb)
+{
+    adbuf[buf_no].suma = *suma;
+    adbuf[buf_no].sumb = *sumb;
+}
+
+/**** SPI CMD受信バッファ ********************************************
+ */
+#define SPI_RX_LEN   20  // Overoから受信するコマンド長 $含む
+static char spi_rx_buf[SPI_RX_LEN];
+static char spi_rx_cnt; // 受信文字数カウント 0〜SPI_RX_LEN
+
+// 受信コマンド内のオフセット位置
+#define CMD_OFS_CMDCODE 1
+#define CMD_OFS_CMDDATA 2
 
-/**** ublox *************************************************/
+// コマンドコード
+#define CMD_CODE_GAIN   1
 
-void test_ublox_rcv_mon(void)
+// 返答コード
+#define RES_CODE_ACK    1
+#define RES_CODE_NAK    2
+#define RES_CODE_NUL    0
+
+// 状態
+#define CMD_STS_NONE    0   // 有効なコマンド無し
+#define CMD_STS_RCVD    1   // 有効なコマンド受け取った
+static char spi_cmd_sts;    // コマンド受信状態
+
+#define spi_cmd_sts_set(i)  INTERRUPT_PROTECT(spi_cmd_sts = i)
+#define spi_cmd_sts_get()   spi_cmd_sts
+
+
+// ACK送信
+void spi_res_send(unsigned char res_code, unsigned char *res_data, int data_len)
 {
-    unsigned char class, id;
-    unsigned int    len;
-    unsigned char   payload[128];
-    char    sz[128];
-    UbloxNavTimeUtc *gps, gps1;
+    ADbufType *ad;
+
+    INTERRUPT_PROTECT(
+        ad = adbuf_get(ring_read1_get());
+        ad->rescode = res_code;
+        if (res_data == NULL || data_len <= 0) {
+            my_memset(ad->resdata, 0, RESDATA_LEN);
+        } else {
+            my_memcpy(ad->resdata, res_data, data_len);
+        }
+    );
+}
+#define spi_res_send_ack()  spi_res_send(RES_CODE_ACK, NULL, 0)
+#define spi_res_send_nak()  spi_res_send(RES_CODE_NAK, NULL, 0)
 
-    gps = &gps1;
-    
-    while(1) {
-        ublox_rcv_pkt(&class, &id, &len, payload);
-        sprintf(sz, "CLASS=%02X ID=%02X LEN=%d\r\n", class, id, len);
-        PDEBUG(sz);
-        ublox_debug_pkt_out(payload, len);
-        ublox_decode_nav_timeutc(payload, gps);
-        sprintf(sz, "%04u/%02d/%02d %02d:%02d:%02d.%09ld %6lums %6luns %02X\r\n",
-            gps->year, gps->month, gps->day, gps->hour, gps->min, gps->sec, gps->nano,
-            gps->tow, gps->tacc, gps->valid
-        );
-        PDEBUG(sz);
 
+// コマンドに対応する処理
+void spi_cmd_proc(void)
+{
+    int i;
+
+    switch(spi_rx_buf[CMD_OFS_CMDCODE]) {
+        case CMD_CODE_GAIN:
+            for(i = 0; i < AD_CHNUM; i++) {
+                pga_gain_set(i, spi_rx_buf[CMD_OFS_CMDDATA + i]);
+            }
+            // ACK送信
+            spi_res_send_ack();
+            break;
+        default:
+            PDEBUG("spi_cmd_porc(): unknown CMD CODE\r\n");
+            // NACK送信
+            spi_res_send_nak();
+            break;
     }
 }
+
+/**** ublox ************************************************
+ */
 static UbloxNavTimeUtc gpsNow;
 static void ublox_rcv(void)
 {
@@ -157,7 +201,6 @@ static void ublox_rcv(void)
 */
     }
 }
-
 /**** INT1/SPI1 ***********************************************/
 /*
  * INT1 Int及びSPI1 IntでADのデータを取得する
@@ -180,99 +223,23 @@ static char pps_intf;
 #define pps_intf_set()  pps_intf = 1
 #define pps_is_intf_enable()    (pps_intf != 0)
 
-/*
- * SPI FLAG test
- */
-void test_spi_flag(void)
-{
-    char    sz[128];
-    int in;
-    unsigned char txc = 0;
-    unsigned char rxc;
+/**** DataOut SPI2 *********************************************/
+#define SPI2CSpin  (PORTCbits.RC8)
 
-    spi2_int_disable();
-    cnint_int_disable();
-    while(1) {
-        delay_ms(1000);
-        sprintf(sz, "SPI2STAT=%04X "
-                "SPIBEC=%d SRMPT=%d SPIROV=%d SRXMPT=%d TBF=%d RBF=%d\r\n"
-                , SPI2STAT
-                , SPI2STATbits.SPIBEC
-                , SPI2STATbits.SRMPT
-                , SPI2STATbits.SPIROV
-                , SPI2STATbits.SRXMPT
-                , SPI2STATbits.SPITBF
-                , SPI2STATbits.SPIRBF
-                );
-        PDEBUG(sz);
-        if ((in = uart2_rcvbuf_getc()) >= 0) {
-            uart2_myputc(in);
-            uart2_puts("\r\n");
-
-            switch(in) {
-                case 'r':
-                    rxc = spi2_getc();
-                    sprintf(sz, "RX=%02X\r\n", rxc);
-                    uart2_puts(sz);
-                    break;
-                case 't':
-                    spi2_putc(txc++);
-                    sprintf(sz, "TX=%02X\r\n", txc);
-                    uart2_puts(sz);
-                    break;
-                case 'v':
-                    spi2_rx_overrun_clear();
-                    break;
-                case 'x':
-                    SPI2STATbits.SRXMPT = 0;
-                    break;
-                case 'y':
-                    SPI2STATbits.SRXMPT = 1;
-                    break;
-            }
-        }
-    }
-}
-/*
- * polling send/rcv
- */
-void test_spi_send(void)
-{
-    unsigned char txc = 1;
-    unsigned char rxc;
-    char    sz[128];
+// SPI2 未送信データバイト数
+static int  dataout_cnt;
+#define dataout_cnt_set(i)  dataout_cnt = (i)
+#define dataout_cnt_get()  dataout_cnt
+#define dataout_cnt_minus()  (dataout_cnt--)
+
+// 送信位置ポインタ
+static char    *dout_ptr;
+
+
+/**** DRDY OUT ****************************************/
+#define DRDY_OUT    PORTCbits.RC9
 
-    spi2_int_disable();
-    cnint_int_disable();
-//    SPI2BUF = txc++;
-//    rxc = SPI2BUF;
-    while(1) {
-        while(SPI2STATbits.SPITBF == 0) {
-            // TX
-            SPI2BUF = txc++;
-        }
-        if (SPI2STATbits.SRXMPT == 0) {
-            while(SPI2STATbits.SRXMPT == 0) {
-                // RX FIFO読み出し
-                rxc = SPI2BUF;
-            }
-#if 0
-            sprintf(sz, "SPI2STAT=%04X "
-                    "SPIBEC=%d SRMPT=%d SPIROV=%d SRXMPT=%d TBF=%d RBF=%d\r\n"
-                    , SPI2STAT
-                    , SPI2STATbits.SPIBEC
-                    , SPI2STATbits.SRMPT
-                    , SPI2STATbits.SPIROV
-                    , SPI2STATbits.SRXMPT
-                    , SPI2STATbits.SPITBF
-                    , SPI2STATbits.SPIRBF
-                    );
-            PDEBUG(sz);
-#endif
-        }
-    }
 
-}
 /*
  * main()
  */
@@ -288,7 +255,8 @@ int main(int argc, char** argv) {
     unsigned int baudrate1 = ( unsigned int )( Baudrate1 + 0.5 );
     char    sz[128];
     UbloxNavTimeUtc *gps = &gpsNow;
-
+    ADbufType   *ad;
+    
     /**** 割り込み禁止 ****/
     SET_CPU_IPL( 7 );
     __builtin_write_OSCCONL(OSCCON & 0xbf); //clear the bit 6 of OSCCONL to unlock Pin Re-map
@@ -336,11 +304,12 @@ int main(int argc, char** argv) {
     CNPU2bits.CN20PUE = 1;  // Pullup ON
     cnint_level_set(4);
 
-
     adint_cnt = 0;
     ad_cs_dis();
     sts_set(STS_NOSYNC);
     pps_intf_clear();
+    DRDY_OUT = 1;
+    spi_cmd_sts = CMD_STS_NONE;
     
     // GPS UART1初期設定 BRGH=Standard mode
     // 9600bps 8bit nonparity 1stop nonflowcnt.
@@ -361,17 +330,11 @@ int main(int argc, char** argv) {
     spi2_init();
     spi1_int_disable();
     spi2_int_disable();
+    spi2_putc(SPI_HEAD_CHAR); // 一番最初のデータ送信のためにセットしておく
 
     PDEBUG("START\r\n");
-    puts("START debug\r\n");
-    sprintf(sz, "RPINR20=%04X\r\n", RPINR20);
-    PDEBUG(sz);
-    sprintf(sz, "SPI1CON1=%04X\r\n", SPI1CON1);
-    PDEBUG(sz);
-    sprintf(sz, "SPI1CON2=%04X\r\n", SPI1CON2);
-    PDEBUG(sz);
-    sprintf(sz, "SPI1STAT=%04X\r\n", SPI1STAT);
-    PDEBUG(sz);
+//    sprintf(sz, "sizeof(ADBUF)=%d\r\n", ADBUF_LEN);
+//    PDEBUG(sz);
 
     // GPS UART1 受信割り込み許可
     uart1_rx_int_enable();
@@ -379,12 +342,16 @@ int main(int argc, char** argv) {
     // DebugOut UART2 受信割り込み許可
     uart2_rx_int_enable();
     uart2_set_int_level(4);  // 割り込みレベル デフォルト4
+PDEBUG("*");
 
     //**** 割り込み許可 **************************************************
     // CPU割り込み優先レベル デフォルト0 ペリフェラルはデフォルト4
 //    SRbits.IPL = 2;
     SET_CPU_IPL( 2 );
+PDEBUG("*");
 
+    // ublox起動待ち
+    delay_ms(100);
     // UBXプロトコルのみにする
     ublox_rcvbuf_clear();
     ublox_send_cfg_prt(BAUDRATE1);
@@ -393,9 +360,17 @@ int main(int argc, char** argv) {
     ublox_rcvbuf_clear();
     ublox_send_cfg_tp5_timepulse2();
     ublox_rcv_ack();
+PDEBUG("*");
+    // TimePulse1をGPS時刻fixしなくても出力する
+    // pulse幅 unlocked=500msec locked=100msec
+    ublox_rcvbuf_clear();
+    ublox_send_cfg_tp5_timepulse1();
+    ublox_rcv_ack();
+PDEBUG("*");
     // NAV-TIMEUTC出力させる
     ublox_send_cfg_msg();
     ublox_rcv_ack();
+PDEBUG("*");
 
     // AD初期化
     ad_reset_dis();
@@ -405,33 +380,36 @@ int main(int argc, char** argv) {
     ad_reset(); // -AD RESET
     // WAIT 2^16 AD system clocks
     delay_ms(100);
+PDEBUG("*");
     //
     ad_cs_init();
     ad_init();
     pga_init();
     
     ring_init();
+PDEBUG("*");
     // AD SPI1 割り込み設定のみ 許可しない
     // INT1ハンドラ内で有効にされる
     spi1_intf_clear();
     spi1_set_int_level(4);
+    // DataOut SPI2 割り込み許可しない CSのCN INTで許可するので
+    spi2_intf_clear();
+    spi2_set_int_level(4);
+PDEBUG("*");
 
+    /**** ペリフェラル割り込み許可 INT1/INT0/CN ************************/
     // INT1割り込み許可
     int1_intf_clear();
     int1_int_enable();    // Int enable
+PDEBUG("*");
     // INT0割り込み許可
     int0_intf_clear();
     int0_int_enable();    // Int enable
-    // DataOut SPI2 割り込み許可しない CSのCN INTで許可するので
-    spi2_intf_clear();
-    spi2_set_int_level(4);
-//    spi2_int_enable();
+PDEBUG("*");
     // ChangeNotification INT許可 SPI2(Overo) CS
     cnint_intf_clear();
     cnint_int_enable();
-/****!!!!!!!!!!!!!!!!!!!!!!!!*/
-//    test_spi_flag();
-test_spi_send();
+PDEBUG("*\r\n");
 
     while(1) {
         // GPSから受信してデコード
@@ -440,9 +418,10 @@ test_spi_send();
             // 時刻有効
             sts_set(STS_SYNCNOW0);
         }
-        if (ring_read_get() != ring_write_get()) {
+        // DebugOutに1secデータ出力
+        if (ring_read2_get() != ring_write_get()) {
             // タイムスタンプget
-            gps = adbuf_time_get(ring_read_get());
+            gps = adbuf_time_get(ring_read2_get());
             sprintf(sz, "%04u/%02d/%02d %02d:%02d:%02d.%09ld,%6lums,%6luns,%02X",
                 gps->year, gps->month, gps->day, gps->hour, gps->min, gps->sec, gps->nano,
                 gps->tow, gps->tacc, gps->valid
@@ -453,35 +432,37 @@ test_spi_send();
             // AD data get
             char ch;
             long    *lp;
-            lp = adbuf_1sec_get(ring_read_get());
+            lp = adbuf_1sec_get(ring_read2_get());
             for(ch=0; ch<AD_CHNUM; ch++) {
                 sprintf(sz, ",%+7ld", lp[ch]);
                 PDEBUG(sz);
             }
             PDEBUG("\r\n");
 #endif
-            ring_read_plus();
-        }
-    }
-/*
-        if (pps_is_intf_enable()) {
-            pps_intf_clear();
-            PDEBUG("pps\r\n");
+#if 0
+            ad = adbuf_get(ring_read2_get());
+            sprintf(sz, "%02X %02X\r\n", ad->sumb, ad->suma);
+            PDEBUG(sz);
+#endif
+            ring_read2_plus();
         }
-    i = 0;
-    while(1) {
-        if (ring_read_get() != ring_write_get()) {
-            char ch;
-            for(ch=0; ch<AD_CHNUM; ch++) {
-                sprintf(sz, "%+7ld,", adbuf_1sec[ring_read_get()][ch]);
+        // SPIからコマンド受信
+        if (spi_cmd_sts_get() == CMD_STS_RCVD) {
+#ifdef DEBUG_PRINT
+            PDEBUG("CMD RCV:");
+            for(i = 0; i < SPI_RX_LEN; i++) {
+                sprintf(sz, " %02X", spi_rx_buf[i]);
                 PDEBUG(sz);
             }
             PDEBUG("\r\n");
-
-            ring_read_plus();
+#endif
+            // コマンドに対応する処理
+            spi_cmd_proc();
+            // コマンド受信再開
+            spi_cmd_sts_set(CMD_STS_NONE);
         }
+
     }
-*/
     
     return (EXIT_SUCCESS);
 }
@@ -490,7 +471,7 @@ test_spi_send();
  * 
  *
  */
-void __attribute__((interrupt, no_auto_psv)) _INT0Interrupt(void)
+void __attribute__((interrupt, no_auto_psv, shadow)) _INT0Interrupt(void)
 {
     // AD STARTピン=H
     ad_start_ena();
@@ -501,17 +482,13 @@ void __attribute__((interrupt, no_auto_psv)) _INT0Interrupt(void)
     // AD個数カウンタ=SAMP_FREQ-1
     adint_cnt = AD_SAMPLE - 1;
 
-    // ADバッファにタイムスタンプ付ける
-    adbuf_time_write(ring_read_get(), &gpsNow);
-
     // AD START信号による同期
     if (sts_get() == STS_SYNCNOW0) {
         // AD STARTピン=L
         ad_start_dis();
         sts_set(STS_SYNCNOW1);
     } else if (sts_get() == STS_SYNCNOW1) {
-        // AD STARTピン=H
-//        ad_start_ena();
+        // AD STARTピン=H 関数先頭で行っているのでここではやらない
         sts_set(STS_SYNCWAIT);
     } else if (sts_get() == STS_SYNCWAIT) {
         sts_set(STS_SYNCED);
@@ -547,6 +524,7 @@ void __attribute__((interrupt, no_auto_psv)) _INT1Interrupt(void)
     spi1_int_enable();
     // 送信
     spi1_putc(0);
+
 }
 /*
  * AD SPI1 Interrupt Handler
@@ -560,14 +538,13 @@ void __attribute__((interrupt, auto_psv)) _SPI1Interrupt(void)
     static unsigned char in[3];
     unsigned char c;
     long    l;
+//int i;
+//unsigned char   *ptr;
 
     spi1_intf_clear();
     c = spi1_getc();
     spi1_rx_overrun_clear();
-//spi1_int_disable();
-//ad_cs_dis();
-//return;
-//c=1;
+
     switch(adint_sts) {
         case ADSTS_H:
             in[2] = c;
@@ -593,18 +570,36 @@ void __attribute__((interrupt, auto_psv)) _SPI1Interrupt(void)
             if (adint_ch >= AD_CHNUM) {
                 // 全CHデータgetした
                 adint_cnt++;
-                if (adint_cnt >= AD_SAMPLE) {
+                if (adint_cnt == AD_SAMPLE-1) {
+                    // ADバッファにタイムスタンプ付ける
+                    adbuf_time_write(ring_write_get(), &gpsNow);
+                } else if (adint_cnt >= AD_SAMPLE) {
                     // 1secぶんのデータgetした
-                    // 平均してバッファに書きこみ
+                    // DRDY->H DRDY=Lの時でもDRDYのエッジを作るため
+                    DRDY_OUT = 1;
+                    // 1sec平均する
                     char ch;
                     for(ch = 0; ch < AD_CHNUM; ch++) {
                         adint_add[ch] /= adint_cnt;
                     }
-                    // バッファに書きこみ
+                    // 1secバッファに書きこみ
                     adbuf_1sec_write(ring_write_get(), adint_add);
+#if 0
+ptr = (unsigned char*)adbuf_get(ring_write_get());
+ptr += 62;
+            for(i = 0; i < 900; i++) {
+                suma += *ptr++;
+                sumb += suma;
+            }
+#endif
                     // バッファ書き込み位置+1
                     ring_write_plus();
+                    // 次のADバッファをゼロクリア
+                    my_memset(adbuf_get(ring_write_get()), 0, ADBUF_LEN);
                     adint_cnt = 0;
+                    // DRDY->L
+// TODO: waitカウンタで制限
+                    DRDY_OUT = 0;
                 }
                 spi1_int_disable(); // SPI割り込みOFF
                 adint_sts = ADSTS_IDLE;
@@ -624,172 +619,100 @@ void __attribute__((interrupt, auto_psv)) _SPI1Interrupt(void)
     }
 
 }
+static unsigned char    suma;
+static unsigned char    sumb;
 
 /*
  * DataOut SPI2 Interrupt Handler
  * TX FIFOに1byteの空きが出来ると発生
  */
-static unsigned char   spi2c;
-void __attribute__((interrupt, auto_psv)) _SPI2Interrupt(void)
+void __attribute__((interrupt, no_auto_psv)) _SPI2Interrupt(void)
 {
     unsigned char   rx;
-    static unsigned int txlen = 512;
+
     spi2_intf_clear();
-#if 1
-//    static unsigned char   c=0;
-    while(!spi2_tx_fifo_is_full())
-        spi2_putc(spi2c++);
-    while(!spi2_rx_fifo_is_empty()) {
-        rx = spi2_getc();
-//        if (rx == '$') c = 0;
-    }
-#endif
-#if 0
-    //spi2c = 123;
-// RX FIFOから読み出し
-//    while(!spi2_rx_fifo_is_empty() || (!spi2_tx_fifo_is_full() && txlen > 0)) {
-    while(!spi2_rx_fifo_is_empty()) {
-        if (!spi2_rx_fifo_is_empty()) {
-            rx = spi2_getc();
-            if (rx == '$') {
-                spi2c = 0;
-                txlen = 3;
-            }
+    // 送信 AD DATA
+    while(SPI2_TBF == 0) {
+        // checksum
+        if ((ADBUF_LEN - dataout_cnt_get()) == ADBUF_OFS_SUM) {
+            // checksum書き込み
+            adbuf_sum_write(ring_read1_get(), &suma, &sumb);
         }
-        // TX FIFOに書き込み
-        if (!spi2_tx_fifo_is_full()) {
-            if (txlen > 0) {
-                spi2_putc(spi2c++);
-                txlen--;
+        suma += (unsigned char)*dout_ptr;
+        sumb += suma;
+
+        if (dataout_cnt_get() <= 0) break;
+        spi2_putc(*dout_ptr++);
+        dataout_cnt_minus();
+    }
+    // 受信 CMD
+    while(SPI2_SRXMPT == 0) {
+        rx = spi2_getc();
+        if (spi_cmd_sts == CMD_STS_NONE && spi_rx_cnt < SPI_RX_LEN) {
+            spi_rx_buf[spi_rx_cnt] = rx;
+            spi_rx_cnt++;
+            if (spi_rx_cnt >= SPI_RX_LEN) {
+                if (spi_rx_buf[CMD_OFS_CMDCODE] != 0) {
+                    spi_cmd_sts = CMD_STS_RCVD;
+                }
             }
         }
     }
-#endif
+
     // オーバーランエラーならばクリアする
-    // spi2_rx_is_overrun()
     if (SPI2STATbits.SPIROV == 1) SPI2STATbits.SPIROV = 0;
 
-    // TODO:Interrupt Flag@IEC Clear
 }
 /*
  * Overo SPI2 CS Input Change Notification
  * Interrupt Handler
  *
  */
-#define SPI2CSpin  (PORTCbits.RC8)
-void __attribute__((interrupt, auto_psv)) _CNInterrupt(void)
+void __attribute__((interrupt, no_auto_psv)) _CNInterrupt(void)
 {
     cnint_intf_clear();
     if (SPI2CSpin == 1) {
         // CS=H
         // SPI2割り込みOFF
         spi2_int_disable();
-
+        // SPI2をリセットしてTX/RX FIFOクリア
+        SPI2STATbits.SPIEN = 0;
+        asm("nop");
+        SPI2STATbits.SPIEN = 1;
+        asm("nop");
+        SPI2BUF;    // RBF->0
+        // $->TX FIFO
+        spi2_putc(SPI_HEAD_CHAR);
+        // リングバッファ読み込み位置+1
+        ring_read1_plus();
+        // 送信データがリングバッファにあるとき
+        if (ring_num1_get() > 0) {
+            // DRDY->L
+            DRDY_OUT = 0;
+        }
     } else {
         // CS=L
-    // SPI送信の一番最初なので
-    spi2c = 0;
-
-// SPI2 RX FIFOクリア
-// SPI2 TX FIFOクリア
-// リングバッファ読み込み位置get?
-// SPI2 TX FIFOに送信データ書き込み?
-        // SPI2割り込みON
-        spi2_int_enable();
-    }
-}
-/*
- * CS0〜15順番にenable
- */
-void test_ad_cs()
-{
-    int i;
-    
-    while(1) {
-        delay_ms(1000);
-        ad_cs(i);
-        i++;
-        if (i >= 16) i = 0;
-    }
-}
-
-/*
- Dataout SPI2 test
- */
-void test_spi2()
-{
-    unsigned int    c = 0x12;
-    unsigned int    rx;
-    unsigned int    sts = 0;
-    int i;
-    
-    i = SPI2BUF;
-    while(1) {
-        PORTCbits.RC9 = 1;
-        delay_ms(100);
-        PORTCbits.RC9 = 0;
-        delay_ms(900);
-
-//        while(spi2_tx_fifo_is_full());
-//        spi2_putc(c++);
-//        while(spi2_rx_fifo_is_empty());
-//        rx = spi2_getc();
-#if 0
-        while(spi2STATbits.SPIRBF == 0);
-        sts = spi2STAT;
-        if (spi2STATbits.SPITBF == 0) {
-            spi2BUF = c++;
+        // リングバッファ読み込み位置get
+        dout_ptr = (char*)adbuf_get(ring_read1_get());
+        // SPI送信の一番最初
+        dataout_cnt_set(ADBUF_LEN);
+        suma = 0;
+        sumb = 0;
+        // SPI2 TX FIFOに送信データ書き込み
+        while(SPI2_TBF == 0) {
+            suma += (unsigned char)*dout_ptr;
+            sumb += suma;
+            if (dataout_cnt_get() <= 0) break;
+            spi2_putc(*dout_ptr++);
+            dataout_cnt_minus();
         }
-//        while(spi2STATbits.SPIRBF == 1) {
-            i = spi2BUF;
-//        }
-        if (i == '$') {
-            c = 0;
-        }
-        if (spi2STATbits.SPIROV == 1) spi2STATbits.SPIROV = 0;
-        sprintf(sz, "%d %04X\r\n", i, sts);
-        PDEBUG(sz);
-#endif
-//        while(spi2STATbits.SPITBF == 1);
-//        while(spi2STATbits.SPITBF);
-/*
-         while(!spi2_tx_fifo_is_full())
-            spi2_putc(c++);
-        while(!spi2_rx_fifo_is_empty()) {
-            rx = spi2_getc();
-            if (rx == '$') c = 0;
+        if (spi_cmd_sts == CMD_STS_NONE) {
+            // SPI受信文字数カウンタクリア
+            spi_rx_cnt = 0;
         }
-*/
-        //        i = ReadUART1();
-//        WriteUART2(i);
-
-//        PDEBUG(mes);
-//        delay();
+        // SPI2割り込みON
+        spi2_int_enable();
+        // DRDY=H
+        DRDY_OUT = 1;
     }
 }
-/*
-void test_ad1()
-{
-        unsigned char in[3];
-        long l[6];
-        char cs;
-        while(!ad_is_drdy0_enable());
-//        PDEBUG("AD\r\n");
-        for(cs=0; cs<6; cs++) {
-            ad_cs(cs);
-                in[2] = ad_spi_rcv();
-                in[1] = ad_spi_rcv();
-                in[0] = ad_spi_rcv();
-            ad_cs_dis();
-            l[cs] = byte3_to_long(in);
-//            sprintf(sz, "%02X %02X %02X", in[2], in[1], in[0]);
-//            PDEBUG(sz);
-        }
-        for(cs=0; cs<6; cs++) {
-            sprintf(sz, "%+7ld,", l[cs]);
-            PDEBUG(sz);
-        }
-        PDEBUG("\r\n");
-
-}
- */