From 11c4a2d9ed05cc91f5862f0071179fce77d761a5 Mon Sep 17 00:00:00 2001 From: Naoya Takamura Date: Thu, 15 Dec 2011 23:49:38 +0900 Subject: [PATCH] =?utf8?q?Ring=20Buffer=20for=20SPI=20RCV=E5=AE=9F?= =?utf8?q?=E8=A3=85=20SPI=20CMD=20send=20add?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- spike-ad.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 119 insertions(+), 23 deletions(-) diff --git a/spike-ad.c b/spike-ad.c index 5e32129..fb8fca1 100644 --- a/spike-ad.c +++ b/spike-ad.c @@ -47,18 +47,18 @@ #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; -- 2.11.0