#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
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) {
}
}
/*
- spi_async()で送信
+ spi_async()で送信開始
+ 受信データはcallback funcで受ける
*/
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;
/*
Tasklet
IRQ Handlerで呼び出される
+ SPI送受信を開始する
*/
void spike_tasklet_func(unsigned long data)
{
return IRQ_HANDLED;
}
-
+#if 0
static ssize_t spike_file_read(struct file *filp, char __user *buff, size_t count,
loff_t *offp)
{
return status;
}
+#endif
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);
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送信データセット
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;
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;
return 0;
// リングバッファクリア
case CMD_BUF_CLEAR:
-// ring_clear();
+ ring_clear();
return 0;
default:
printk(KERN_INFO "spike_file_ioctl: unknown cmd=%d\n", cmd);
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;