#include <linux/poll.h>
#include <linux/wait.h>
#include <linux/sched.h>
+#include <asm/atomic.h>
#include "spike-ad.h"
#define SPI_BUS_CS0 0
#define SPI_BUS_SPEED 500000 // Hz
-#define SPI_DATA_SIZE 965 // $含む PICから受信するデータ長
+#define SPI_DATA_SIZE (965+1) // $含む PICから受信するデータ長 DMA問題のために+1byteしている
#define GPIO_DRDY_IN 144 // DRDY Input = GPIO144
const char this_driver_name[] = MODULE_NAME;
+#define SPI_CMD_MAX (64) // SPI送信データの最大長
+
+// 送信データバッファ(CMD for PIC)
+typedef struct {
+} SpiTxBuf;
+
struct spike_control {
struct spi_message msg;
struct spi_transfer transfer;
u32 busy; // 1=spi_async()終了待ち
u32 spi_callbacks;
-// u32 busy_counter;
u8 *tx_buff;
u8 *rx_buff;
int received_len;
-};
-static struct spike_control spike_ctl;
+ int irq; // DRDY信号割り込み
-struct irq_device {
- struct semaphore sem;
- int irq;
+ struct semaphore cmd_sem;
+ u8 cmd_buf[SPI_CMD_MAX]; // 送信するコマンド
+ int cmd_len; // SPIで送信するコマンド長
};
-static struct irq_device irq_dev;
-
+static struct spike_control spike_ctl;
struct spike_dev {
spinlock_t spi_lock;
DECLARE_TASKLET(spike_tasklet, spike_tasklet_func, 0);
//
-/**** SPI送信データ バッファ ******************************************
-*/
-#define SPI_TX_MAX (64) // SPI送信データの最大長
-
-// 送信データバッファ(CMD for PIC)
-typedef struct {
- unsigned char txbuf[SPI_TX_MAX];
- int tx_len; // SPIで送信するデータ長
- struct semaphore txbuf_sem;
-} SpiTxBuf;
-
-static SpiTxBuf spi_txbuf;
-
-
-
-//
/**** SPI受信データ リングバッファ ******************************************
*/
#define RING_NUM (30) // リングバッファ個数
*/
// 読み出し位置
-static int ring_read;
+static atomic_t ring_read;
// 書き込み位置 データ受信で使用
-static int ring_write;
+static atomic_t ring_write;
void ring_init(void)
{
- ring_read = 0;
- ring_write = ring_read;
+ atomic_set(&ring_read, 0);
+ atomic_set(&ring_write, 0);
memset(spibuf, 0, sizeof(spibuf));
}
#define ring_clear() ring_read_set(ring_write_get())
// 読み出し位置
int ring_read_get(void)
{
- return ring_read;
+ return atomic_read(&ring_read);
}
void ring_read_set(int i)
{
- ring_read = i;
+ atomic_set(&ring_read, i);
}
void ring_read_plus(void)
{
- ring_read++;
- if (ring_read >= RING_NUM) ring_read = 0;
+ atomic_inc(&ring_read);
+ if (atomic_read(&ring_read) >= RING_NUM) atomic_set(&ring_read, 0);
}
// 書き込み位置 受信で使用
int ring_write_get(void)
{
- return ring_write;
+ return atomic_read(&ring_write);
}
void ring_write_plus(void)
{
- ring_write++;
- if (ring_write >= RING_NUM) ring_write = 0;
+ atomic_inc(&ring_write);
+ if (atomic_read(&ring_write) >= RING_NUM) atomic_set(&ring_write, 0);
}
// 読み込んでいないデータ数
int ring_num_get(void)
{
int i;
- i = ring_write - ring_read;
+ i = atomic_read(&ring_write) - atomic_read(&ring_read);
if (i < 0) i += RING_NUM;
return i;
}
*/
void ring_zero(void)
{
- memset(spibuf[ring_write], 0, SPI_MAX);
+ memset(spibuf[atomic_read(&ring_write)], 0, SPI_MAX);
}
/*
パケットバッファフル?
spike_ctl.msg.context = NULL;
memset(spike_ctl.tx_buff, 0, SPI_BUFF_SIZE);
-// spike_ctl.tx_buff[0] = '$';
memset(spike_ctl.rx_buff, 0, SPI_BUFF_SIZE);
- if (down_interruptible(&spi_txbuf.txbuf_sem))
+ if (down_interruptible(&spike_ctl.cmd_sem))
return -ERESTARTSYS;
// TXコマンドセット
- memcpy(spike_ctl.tx_buff, spi_txbuf.txbuf, spi_txbuf.tx_len);
+ memcpy(spike_ctl.tx_buff, spike_ctl.cmd_buf, spike_ctl.cmd_len);
// TXコマンドクリア
- memset(spi_txbuf.txbuf, 0, SPI_TX_MAX);
- up(&spi_txbuf.txbuf_sem);
+ memset(spike_ctl.cmd_buf, 0, SPI_CMD_MAX);
+ up(&spike_ctl.cmd_sem);
spike_ctl.transfer.tx_buf = spike_ctl.tx_buff;
spike_ctl.transfer.rx_buf = spike_ctl.rx_buff;
switch(cmd) {
// SPI送信データ長セット
case CMD_TX_LEN:
- if (down_interruptible(&spi_txbuf.txbuf_sem))
+ if (down_interruptible(&spike_ctl.cmd_sem))
return -ERESTARTSYS;
- if (copy_from_user(&spi_txbuf.tx_len, (void *)arg, sizeof(int))) {
+ if (copy_from_user(&spike_ctl.cmd_len, (void *)arg, sizeof(int))) {
printk(KERN_ALERT "spike_file_ioctl(): copy_from_user() failed\n");
- up(&spi_txbuf.txbuf_sem);
+ up(&spike_ctl.cmd_sem);
return -EFAULT;
}
-printk(KERN_INFO "spike_file_ioctl: CMD_TX_LEN %d\n", spi_txbuf.tx_len);
- if (spi_txbuf.tx_len > SPI_TX_MAX) spi_txbuf.tx_len = SPI_TX_MAX;
- up(&spi_txbuf.txbuf_sem);
+printk(KERN_INFO "spike_file_ioctl: CMD_TX_LEN %d\n", spike_ctl.cmd_len);
+ if (spike_ctl.cmd_len > SPI_CMD_MAX) spike_ctl.cmd_len = SPI_CMD_MAX;
+ up(&spike_ctl.cmd_sem);
return 0;
// SPI送信データセット
case CMD_TX_SET:
- if (down_interruptible(&spi_txbuf.txbuf_sem))
+ if (down_interruptible(&spike_ctl.cmd_sem))
return -ERESTARTSYS;
- if (copy_from_user(&spi_txbuf.txbuf, (void *)arg, spi_txbuf.tx_len)) {
+ if (copy_from_user(&spike_ctl.cmd_buf, (void *)arg, spike_ctl.cmd_len)) {
printk(KERN_ALERT "spike_file_ioctl(): copy_from_user() failed\n");
- up(&spi_txbuf.txbuf_sem);
+ up(&spike_ctl.cmd_sem);
return -EFAULT;
}
-printk(KERN_INFO "spike_file_ioctl: CMD_TX_SET %02X %02X %02X %02X\n", spi_txbuf.txbuf[0], spi_txbuf.txbuf[1], spi_txbuf.txbuf[2], spi_txbuf.txbuf[3]);
- up(&spi_txbuf.txbuf_sem);
+printk(KERN_INFO "spike_file_ioctl: CMD_TX_SET %02X %02X %02X %02X\n", spike_ctl.cmd_buf[0], spike_ctl.cmd_buf[1], spike_ctl.cmd_buf[2], spike_ctl.cmd_buf[3]);
+ up(&spike_ctl.cmd_sem);
return 0;
// SPI受信データ返す
case CMD_RX_GET:
{
int result;
- irq_dev.irq = OMAP_GPIO_IRQ(GPIO_DRDY_IN);
- result = request_irq(irq_dev.irq,
+ spike_ctl.irq = OMAP_GPIO_IRQ(GPIO_DRDY_IN);
+ result = request_irq(spike_ctl.irq,
irq_handler,
IRQF_TRIGGER_FALLING,
"spike",
- &irq_dev);
+ &spike_ctl);
if (result < 0) {
printk(KERN_ALERT "request_irq failed: %d\n", result);
}
void spike_free_irq(void)
{
- free_irq(irq_dev.irq, &irq_dev);
+ free_irq(spike_ctl.irq, &spike_ctl);
}
static int __init spike_init(void)
sema_init(&spike_dev.fop_sem, 1);
spin_lock_init(&spike_dev.spi_lock);
- memset(&irq_dev, 0, sizeof(irq_dev));
- sema_init(&irq_dev.sem, 1);
-
- // TXコマンドクリア
- memset(&spi_txbuf, 0, sizeof(spi_txbuf));
- sema_init(&spi_txbuf.txbuf_sem, 1);
+ sema_init(&spike_ctl.cmd_sem, 1);
finfo.f_version = 0; // 未使用マーク
// リングバッファ初期化