OSDN Git Service

Ring Buffer for SPI RCV実装
authorNaoya Takamura <ntaka206@users.sourceforge.jp>
Thu, 15 Dec 2011 14:49:38 +0000 (23:49 +0900)
committerNaoya Takamura <ntaka206@users.sourceforge.jp>
Thu, 15 Dec 2011 14:49:38 +0000 (23:49 +0900)
SPI CMD send add

spike-ad.c

index 5e32129..fb8fca1 100644 (file)
 
 #include "spike-ad.h"
 
-#define SPI_BUFF_SIZE  2048
+#define SPI_BUFF_SIZE  2048    // for spike_ctl
 #define USER_BUFF_SIZE 128
 
 #define SPI_BUS 1
 #define SPI_BUS_CS0 0
 #define SPI_BUS_SPEED 500000   // Hz
 
-#define        SPI_DATA_SIZE   945     // $含む
+#define        SPI_DATA_SIZE   965     // $含む PICから受信するデータ長
 
 #define GPIO_DRDY_IN 144       // DRDY Input = GPIO144
 
-#define        DEBUG_TOGGLE_OUT        // デバッグ時定義する
+//#define      DEBUG_TOGGLE_OUT        // デバッグ時定義する
 #ifdef DEBUG_TOGGLE_OUT
        #define GPIO_TOGGLE_OUT 145     // Debug用toggle出力 = GPIO145
 #endif
@@ -117,33 +117,118 @@ static FileInfo finfo;
 void spike_tasklet_func(unsigned long data);
 DECLARE_TASKLET(spike_tasklet, spike_tasklet_func, 0);
 
-//
-static char    ring_buf[SPI_DATA_SIZE];
-
-// 送信データ
+//
+/**** SPI送信データ バッファ ******************************************
+*/
+// 送信データ(CMD for PIC)
 #define        SPI_TX_MAX      (64)
 static unsigned char   spitxbuf[SPI_TX_MAX];
-int    spi_tx_len;
+static int     spi_tx_len;
+
+//
+/**** SPI受信データ リングバッファ ******************************************
+*/
+#define        RING_NUM        (30)    // リングバッファ個数
+#define        SPI_MAX (SPI_DATA_SIZE+256)     // 1回のデータバイト数max
+static unsigned char   spibuf[RING_NUM][SPI_MAX];
+
+/*
+       受信データのデコード結果と
+       ソケット送信・記録パケット
+*/
+
+// 読み出し位置
+static int     ring_read;
+// 書き込み位置 データ受信で使用
+static int     ring_write;
+
+void ring_init(void)
+{
+       ring_read = 0;
+       ring_write = ring_read;
+       memset(spibuf, 0, sizeof(spibuf));
+}
+#define        ring_clear()    ring_read_set(ring_write_get())
+
+// 読み出し位置
+int ring_read_get(void)
+{
+       return ring_read;
+}
+void ring_read_set(int i)
+{
+       ring_read = i;
+}
+void ring_read_plus(void)
+{
+       ring_read++;
+       if (ring_read >= RING_NUM) ring_read = 0;
+}
+
+// 書き込み位置 受信で使用
+int ring_write_get(void)
+{
+       return ring_write;
+}
+void ring_write_plus(void)
+{
+       ring_write++;
+       if (ring_write >= RING_NUM) ring_write = 0;
+}
+// 読み込んでいないデータ数
+int ring_num_get(void)
+{
+       int     i;
+       
+       i = ring_write - ring_read;
+       if (i < 0) i += RING_NUM;
+       return i;
+}
+
+// 位置指定してデータ取得
+unsigned char* ring_get(int ptr)
+{
+       return spibuf[ptr];
+}
+/*
+       書き込み位置のパケットをゼロクリア
+*/
+void ring_zero(void)
+{
+       memset(spibuf[ring_write], 0, SPI_MAX);
+}
+/*
+       パケットバッファフル?
+       1=Full
+       0=not Full
+*/
+int ring_full(void)
+{
+       if (ring_num_get() >= RING_NUM-1) return 1;
+       return 0;
+}
 
 
 /*
        spike_queue_spi_write()で開始した
        spi_async()終了後に呼ばれる
+       つまりSPIでデータを受信完了した状態
 */
 static void spike_spi_completion_handler(void *arg)
 {
-       // Streaming mapping DMA unmap
-//     unmap_dma_buf();
+       unsigned char   *p;
 
        spike_ctl.spi_callbacks++;
        spike_ctl.busy = 0;
-// 受信したデータを保存 仮
-memcpy(ring_buf, spike_ctl.rx_buff, SPI_DATA_SIZE);
+
+       // 受信したデータをリングバッファに保存
+       p = ring_get(ring_write_get());
+       memcpy(p, spike_ctl.rx_buff, SPI_DATA_SIZE);
        // 実際に受信できたデータ長
        spike_ctl.received_len = spike_ctl.msg.actual_length;
 
        // 書き込み位置進める
-//     ring_write_plus();
+       ring_write_plus();
 
        // 寝ているものを起こす
        if (finfo.sleep_mode) {
@@ -155,7 +240,8 @@ memcpy(ring_buf, spike_ctl.rx_buff, SPI_DATA_SIZE);
        }
 }
 /*
-       spi_async()で送信
+       spi_async()で送信開始
+       受信データはcallback funcで受ける
 */
 static int spike_queue_spi_write(void)
 {
@@ -174,6 +260,11 @@ static int spike_queue_spi_write(void)
        spike_ctl.tx_buff[0] = '$';
        memset(spike_ctl.rx_buff, 0, SPI_BUFF_SIZE);
 
+       // TXコマンドセット
+       memcpy(spike_ctl.tx_buff, spitxbuf, spi_tx_len);
+       // TXコマンドクリア
+       memset(spitxbuf, 0, SPI_TX_MAX);
+
        spike_ctl.transfer.tx_buf = spike_ctl.tx_buff;
        spike_ctl.transfer.rx_buf = spike_ctl.rx_buff;
        spike_ctl.transfer.len = SPI_DATA_SIZE;
@@ -197,6 +288,7 @@ static int spike_queue_spi_write(void)
 /*
   Tasklet
   IRQ Handlerで呼び出される
+  SPI送受信を開始する
 */
 void spike_tasklet_func(unsigned long data)
 {
@@ -226,7 +318,7 @@ static irqreturn_t irq_handler(int irq, void *dev_id)
 
        return IRQ_HANDLED;
 }
-
+#if 0
 static ssize_t spike_file_read(struct file *filp, char __user *buff, size_t count,
                        loff_t *offp)
 {
@@ -300,6 +392,7 @@ status = spike_queue_spi_write();
 
        return status;  
 }
+#endif
 
 static int spike_file_open(struct inode *inode, struct file *filp)
 {      
@@ -327,7 +420,7 @@ static int spike_file_open(struct inode *inode, struct file *filp)
        init_waitqueue_head(&(finfo.wait));
        filp->private_data = (void*)&finfo;      // プライベートデータに構造体ポインタ設定
 
-//     ring_clear();
+       ring_clear();
 
        up(&spike_dev.fop_sem);
 
@@ -377,6 +470,7 @@ static long spike_file_ioctl(struct file *file, unsigned int cmd, unsigned long
                        printk(KERN_ALERT "spike_file_ioctl(): copy_from_user() failed\n");
                        return -EFAULT;
                }
+printk(KERN_INFO "spike_file_ioctl: CMD_TX_LEN %d\n", spi_tx_len);
                if (spi_tx_len > SPI_TX_MAX) spi_tx_len = SPI_TX_MAX;
                return 0;
        // SPI送信データセット
@@ -385,14 +479,14 @@ static long spike_file_ioctl(struct file *file, unsigned int cmd, unsigned long
                        printk(KERN_ALERT "spike_file_ioctl(): copy_from_user() failed\n");
                        return -EFAULT;
                }
+printk(KERN_INFO "spike_file_ioctl: CMD_TX_SET %02X %02X %02X %02X\n", spitxbuf[0], spitxbuf[1], spitxbuf[2], spitxbuf[3]);
                return 0;
        // SPI受信データ返す
        case CMD_RX_GET:
                // リングバッファからデータ取得
-//             p = ring_get(ring_read_get());
-p = ring_buf;
+               p = ring_get(ring_read_get());
                // 読み込み位置進める
-//             ring_read_plus();
+               ring_read_plus();
                if (copy_to_user((void *)arg, p, SPI_DATA_SIZE)) {
                        printk(KERN_ALERT "spike_file_ioctl(): copy_to_user() failed\n");
                        return -EFAULT;
@@ -408,8 +502,7 @@ p = ring_buf;
                return 0;
        // リングバッファにあるデータ数を返す
        case CMD_DNUM_GET:
-//             i = ring_num_get();
-i = 1;
+               i = ring_num_get();
                if (copy_to_user((void *)arg, &i, sizeof(int))) {
                        printk(KERN_ALERT "spike_file_ioctl(): copy_to_user() failed\n");
                        return -EFAULT;
@@ -417,7 +510,7 @@ i = 1;
                return 0;
        // リングバッファクリア
        case CMD_BUF_CLEAR:
-//             ring_clear();
+               ring_clear();
                return 0;
        default:
                printk(KERN_INFO "spike_file_ioctl: unknown cmd=%d\n", cmd);
@@ -730,10 +823,13 @@ static int __init spike_init(void)
        memset(&irq_dev, 0, sizeof(irq_dev));
        sema_init(&irq_dev.sem, 1);
 
+       // TXコマンドクリア
+       memset(spitxbuf, 0, SPI_TX_MAX);
+
        finfo.f_version = 0;            // 未使用マーク
        spi_tx_len = 0;
        // リングバッファ初期化
-//     ring_init();
+       ring_init();
 
        if (spike_init_cdev() < 0) 
                goto fail_1;