AT91 linux开发板的驱动\CAN总线驱动

编写心得;

can总线的芯片是mcp2515,利用spi进行数据的读写,spi是写在底层的驱动,对于mcp的数据读写操作放在应用层里面完成的

1:spi的底层驱动代码是

#include <linux/mm.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/rtc.h> /* get the user-level API */
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/kdev_t.h>
#include <linux/types.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
#include <linux/version.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/moduleparam.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/pci.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/pci.h>
#include <linux/input.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/kdev_t.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
#include <asm/mach/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <mach/at91_pio.h>
#include <mach/gpio.h>
#include <mach/hardware.h>
#include <linux/version.h>

//boy
/* Read / Write of SPI mode (SPI_MODE_0..SPI_MODE_3) */
#define SPI_READ_MODE          _IOR('D', 1, long)
#define SPI_WRITE_MODE          _IOW('D', 1, long)
#define CS_SPI_H          _IOW('D', 2, int)
#define CS_SPI_L          _IOW('D', 3, int)
#define SPI_READ_DATA          _IOR('D', 4, long)
#define SPI_WRITE_DATA          _IOW('D', 4, long)
/*
     通过测试成功 AT91 的开发板 内核是2.6.27
*/
#define DEVICE_NAME     "spi"  /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */ 
#define SPI_MAJOR       231    /*  */
///
#define SPI_CLK_H      (at91_set_gpio_value(AT91_PIN_PA2, 1))
#define SPI_CLK_L      (at91_set_gpio_value(AT91_PIN_PA2, 0))
#define SPI_MOSI_H      (at91_set_gpio_value(AT91_PIN_PA1, 1))
#define SPI_MOSI_L      (at91_set_gpio_value(AT91_PIN_PA1, 0))
#define MCP2515_CS_H    (at91_set_gpio_value(AT91_PIN_PA3, 1))
#define MCP2515_CS_L    (at91_set_gpio_value(AT91_PIN_PA3, 0))
///PA3作为片选
struct button_irq_desc
 {   
  int irq;    /*中断号*/
  unsigned long flags;    /*中断标志,用来定义中断触发方式*/
  char *name;    /* 中断名称*/
 }; 
static struct button_irq_desc button_irqs [] = {   
 {AT91_PIN_PA26,AT91_AIC_SRCTYPE_RISING, "cancle"},    
 //{AT91_PIN_PA28,AT91_AIC_SRCTYPE_RISING, "right"},
 //{AT91_PIN_PA29,AT91_AIC_SRCTYPE_RISING, "enter"},
 };
wait_queue_head_t button_waitq; /**/  
static void __iomem *pio_base;
static volatile int ev_press = 0;/* 中断事件标志, 中断服务程序将它置1,buttons_read将它清0 */
//
/***************************************************
*函数名:static irqreturn_t buttons_interrupt(int irq, void *dev_id)
*描述:中断服务函数
*输入参数:
*返回:
***************************************************/
static irqreturn_t buttons_interrupt(
    int irq,
    void *dev_id)
{    
 ev_press = 1;                   // 表示中断发生了 
 wake_up_interruptible(&button_waitq);    // 唤醒休眠的进程    
 printk(KERN_DEBUG"SPI_CAN_INTERRUPTER\n");
 return IRQ_RETVAL(IRQ_HANDLED);
}
delay()
void spi_delay(int num)
{
  int i;
  while(num--)
  {
     for(i = 0;i<100;i++);
  }
}
int SpiWrite(unsigned char data)
{
 int i;
 unsigned char datat;
 datat = data;
 unsigned char mask[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
        for(i=7; i >= 0; i--)
 {
  SPI_CLK_L;                  //把clock线拉低,模拟一个时钟
  if((data & mask[i]) >> i)   //把数据送上DATA线
   SPI_MOSI_H; 
  else
   SPI_MOSI_L;
  测试把MOSI于MISO连接在一起可以进行测试,要注意因为写的东西没有保存所以读和写要在一个函数里面就可以了//
  //if((readl(pio_base + PIO_PDSR) & mask[i]) >> i)//把数据送上DATA线 ?读寄存器是不行的,不知道原因
  /*
  if(at91_get_gpio_value(AT91_PIN_PA0)==1)
  {
    printk(DEVICE_NAME " PA0=1\n");
  }
  else
  {
    printk(DEVICE_NAME " PA0=0\n");
                }
                */ 
                 测试读数据
  spi_delay(10);              //等待适当的时间,以等待数据稳定
  SPI_CLK_H;                 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值