mcp2515驱动移植于新唐的N32926

           控制器局域网总线(CANController Area Network)是一种用于实时应用的串行通讯协议总线,它可以使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。CAN协议用于汽车中各种不同元件之间的通信,以此取代昂贵而笨重的配电线束。该协议的健壮性使其用途延伸到其他自动化和工业应用。CAN协议的特性包括完整性的串行数据通讯、提供实时支持、传输速率高达1Mb/s、同时具有11位的寻址以及检错能力。

         本驱动用到的是MicrochipMCP2515是一款独立控制器局域网络(Controller Area Network CAN)协议控制器,完全支持CAN V2.0B技术规范。该器件能发送和接收标准和扩展数据帧以及远程帧。MCP2515自带的两个验收屏蔽寄存器和六个验收滤波寄存器可以过滤掉不想要的报文,因此减少了主单片机MCU)的开销。MCP2515MCU的连接是通过业界标准串行外设接口SearialPeripheral Interface SPI)来实现的。

         mcp2515驱动移植于新唐的N32926,内核版本是linux-2.6.35.4。开始移植时途中也碰到了很多问题。下面我徒手解答我碰到的一一问题。

原理图先附上:



 

一,首先我们配置内核选项(Linux-2.6以上的内核都有自带的mcp251x驱动)

cd linux-2.6.35.4/

make menuconfig

1,选择如下配置:

[*]Networkingsupport->

      <*>CAN bus subsystemsupport->

          <*>RawCAN Protocal

          <*>BroadcastManage CAN Protocal

          CANDevice Drivers->

            <*>Platform CAN driver withNetlink support

               [*]CANbit-timing calculation

            <*>Microchip MCP251x SPI CANcontrollers

2,配置spi驱动 

因为mcp2515是依通过spi通信协议进行数据交流的配置如下

[*] SPIsupport --->               

 -*-  Utilitiesfor Bitbanging SPImasters               

 <>  GPIO-based bitbanging SPI Master(NEW)             

 <>  Xilinx SPI controller common module(NEW)          

 <*>  NuvotonW55FA92 seriesSPI                         

 <*>    SPI transfer with PDMA(NEW)                     

        SPI CS0 pin select (enable CS0pin) --->        

        SPI CS1 pin select (disable CS1pin) --->       

      SPI CS0 device select (device for MTDflash)  ---> 

 <>  DesignWare SPI controller core support(NEW)       

      *** SPI Protocol Masters***                       

 <>  User mode SPI device driver support(NEW)          

 <>   Infineon TLE62X0 (for power switching)(NEW)   

 以上就是驱动方面的配置。

,在内核代码增加一个spi的设备

1,根据硬件我们的mcp2515是挂在在spi0的接口中,不同的板子对应的内核实现都不一样

 N32926  增加一个spi的是设备是在linux-2.6.35.4/arch/arm/mach-w55fa92/dev.c

可以其他板子是在 mach-xxx.c中注册一个spi的设备具体可以搜索

spi_register_board_info(structspi_board_info const *info, unsigned n)

函数说明

structspi_board_info 结构体

structspi_board_info {

         char           modalias[SPI_NAME_SIZE];//定义的spi设备名字

         const void          *platform_data; //平台数据

         void           *controller_data;

         int              irq;  //中断号

         u32            max_speed_hz; 

 

         u16            bus_num;//spi

         u16            chip_select;

         u8              mode;// 模式选择

};

dev.c定义了

staticstruct spi_board_info w55fa92_spi_board_info[] __initdata{  

         ……….

};

 

 

因此我们把mcp2515所需的数据定义到这个数组中

staticstruct mcp251x_platform_data mcp251x_info = {

         .oscillator_frequency = 8000000,

 };

staticstruct spi_board_info w55fa92_spi_board_info[] __initdata = {

        {

                .modalias ="mcp2515",

                .bus_num = 0,

                .chip_select = 0,

                .platform_data =&mcp251x_info,

                .irq = W55FA92_IRQ(2),

                .max_speed_hz = 2*1000*1000,

                .mode = SPI_MODE_0,

        },

 

};

最终spi注册

void__init w55fa92_dev_init()

{

       platform_add_devices(w55fa92_public_dev,ARRAY_SIZE(w55fa92_public_dev));//注册平台设备

       spi_register_board_info(w55fa92_spi_board_info,ARRAY_SIZE(w55fa92_spi_board_info));//注册spi设备

}

貌似驱动方面搞定了?看上去好像很简单。那我们编译一下吧!

编译成功后。

重新启动板子

发现can驱动报错:

mcp251xspi0.0: MCP251x didn't enter in conf mode after reset

mcp251xspi0.0: Probe failed

mcp251xspi0.0: probe failed

这是什么情况?于是我跟了一下代码

/* Here is OK to not lock the MCP, no oneknows about it yet */

         if(!mcp251x_hw_probe(spi)) {

                   dev_info(&spi->dev,"Probe failed\n");

                   gotoerror_probe;

         }

static int mcp251x_hw_probe(structspi_device *spi)

{

         intst1, st2;

 

         mcp251x_hw_reset(spi);

 

         st1= mcp251x_read_reg(spi, CANSTAT) & 0xEE;

         st2= mcp251x_read_reg(spi, CANCTRL) & 0x17;

 

         dev_dbg(&spi->dev,"CANSTAT 0x%02x CANCTRL 0x%02x\n", st1, st2);

 

         /*Check for power up default values */

         return(st1 == 0x80 && st2 == 0x07) ? 1 : 0;

}

static int mcp251x_hw_reset(structspi_device *spi)

{

         structmcp251x_priv *priv = dev_get_drvdata(&spi->dev);

         intret;

         unsignedlong timeout;

 

         priv->spi_tx_buf[0]= INSTRUCTION_RESET;//¸´Î»Ö¸Áî

         ret= spi_write(spi, priv->spi_tx_buf, 1);

         if(ret) {

                   dev_err(&spi->dev,"reset failed: ret = %d\n", ret);

                   return-EIO;

         }

 

         /*Wait for reset to finish */

         timeout= jiffies + HZ;

         mdelay(10);

         while((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK)

                != CANCTRL_REQOP_CONF) { 

                   schedule();

                   if(time_after(jiffies, timeout)) {

                            dev_err(&spi->dev,"MCP251x didn't"

                                     "enter in conf mode after reset\n");

                            return-EBUSY;

                   }

         }

         return0;

}

原来祸根是这里,mcp251x_read_reg读寄存器出错 ,这里读的目的是判断是不是mcp2515属于配置模式因为probe函数会初始化mcp2515 寄存器。即写寄存器。怎么办继续跟咯

static u8 mcp251x_read_reg(structspi_device *spi, uint8_t reg)

{

         structmcp251x_priv *priv = dev_get_drvdata(&spi->dev);

         u8val = 0;

 

         priv->spi_tx_buf[0]= INSTRUCTION_READ;

         priv->spi_tx_buf[1]= reg;

 

         mcp251x_spi_trans(spi,3);

         val= priv->spi_rx_buf[2];

 

         returnval;

}

 

static int mcp251x_spi_trans(structspi_device *spi, int len)

{

         structmcp251x_priv *priv = dev_get_drvdata(&spi->dev);

         structspi_transfer t = {

                   .tx_buf= priv->spi_tx_buf,

                   .rx_buf= priv->spi_rx_buf,

                   .len= len,

                   .cs_change= 0,

         };

         structspi_message m;

         intret;

 

         spi_message_init(&m);

         spi_message_add_tail(&t,&m);

 

         ret= spi_sync(spi, &m);

         if(ret)

                   dev_err(&spi->dev,"spi transfer failed: ret = %d\n", ret);

        

         returnret;

}

 

这下明白了mcp2515  的读写都是调用了mcp251x_spi_trans()函数。而这个函数里实现的是spi协议的 读写。不懂可以参考下面的博文,看了就明白了。

http://blog.csdn.net/eastmoon502136/article/details/7921846

问题发现了是板子的spi有问题?一切的一切又回到开始了。

怎么办?于是我去找了个spi的应用把板子的SPI0_SO with SPI0_SI 进行短接。测试了一下。

待续…………….. 碰到什么问题可以给我留言,或者 发送问题到邮箱 917768817@qq.com


 出现这个错误的情况,排除法:

1,保证spi 通信正常(自行下载一个通用spi 应用 进行测试)

2,和can 芯片连接 接收和发送要交叉接



 

 

 

### 回答1: MCP2515是一种控制器区域网络(CAN)控制器片,而FPGA(可编程逻辑门阵列)是一种可编程的数字电路设备。MCP2515驱动程序是一种软件,用于控制FPGA来与MCP2515通信和操作。 通过MCP2515驱动程序,FPGA可以实现对CAN总线的控制和操作。MCP2515提供了CAN总线控制器所需的所有功能,包括消息传输、帧过滤和错误检测等。FPGA作为一个可编程的硬件设备,可以通过MCP2515驱动程序来配置和控制MCP2515的功能,实现CAN总线通信。 MCP2515驱动程序通过FPGA与MCP2515之间的SPI(串行外设接口)进行通信。SPI是一种串行数据交换协议,允许FPGA与外部设备进行通信。MCP2515驱动程序会定义SPI通信协议,包括数据传输速率、字节顺序和信号控制等。FPGA根据这些定义来与MCP2515进行通信,发送控制命令和接收数据。 通过MCP2515驱动程序,FPGA可以实现CAN总线的各种功能,如发送消息、接收消息和帧过滤等。FPGA可以根据MCP2515提供的控制寄存器来配置CAN总线的参数,如波特率和工作模式等。FPGA还可以根据MCP2515提供的接收缓冲区来接收CAN总线上的消息,并根据定义的过滤器进行帧过滤。 总之,通过MCP2515驱动程序,FPGA可以实现对MCP2515片的控制和操作。这样,FPGA可以作为一个功能强大且灵活可编程的平台,与MCP2515一起实现CAN总线的控制与通信。 ### 回答2: MCP2515是一款CAN总线控制器片,它具有高性能的SPI接口以及完整的CAN通信协议支持。FPGA是可编程逻辑片,可以通过配置内部逻辑电路来实现特定功能。因此,MCP2515驱动程序可以用于驱动FPGA模块与CAN总线之间的通信。 MCP2515驱动程序首先需要在FPGA中配置SPI接口,并将其与MCP2515进行连接。SPI接口是一种串行通信协议,通过发送和接收数据帧来实现FPGA与MCP2515之间的数据传输。驱动程序需要实现SPI接口的初始化、数据发送和接收等功能。通过配置SPI接口,驱动程序可以控制MCP2515的工作模式、寄存器读写以及CAN消息的发送和接收。 另外,MCP2515驱动程序还需要实现CAN通信协议的支持。CAN(Controller Area Network)是一种广泛应用于汽车、工业控制和嵌入式系统的串行通信协议,它具有高可靠性和实时性能。驱动程序需要解析CAN消息的标识符、数据和控制位,以实现CAN消息的发送和接收。同时,驱动程序还可以实现CAN消息的过滤、屏蔽和ACK等功能,以满足不同应用场景的需求。 在FPGA中使用MCP2515驱动程序,可以实现FPGA与CAN总线之间的高速数据传输和实时通信。这对于需要与CAN设备进行数据交换的应用非常重要,例如汽车电子、工业自动化和机器人控制等领域。同时,由于FPGA具有可编程性,驱动程序可以根据实际应用需求进行灵活配置和优化,以提高系统性能和可扩展性。 总结来说,MCP2515驱动程序可以用于驱动FPGA模块与CAN总线之间的通信。驱动程序需要实现SPI接口的配置和数据传输,以及CAN通信协议的解析和支持。这样的驱动程序可以实现高速实时数据传输和与CAN设备的可靠通信,为各种应用领域提供了强大的功能和灵活性。 ### 回答3: MCP2515是一款常用于CAN总线通信的控制器,而FPGA则是一种可编程逻辑器件。在使用MCP2515驱动程序时,FPGA可以作为控制器的主要载体,负责将MCP2515的功能集成进系统中。 首先,FPGA可以通过对MCP2515进行逻辑控制来完成CAN总线通信的主要功能。它可以配置和控制MCP2515的寄存器,设置CAN总线的通信速率、数据格式等参数。通过FPGA的逻辑控制,可以将MCP2515与其他外设进行连接,实现MCP2515与其他模块的数据交互。 其次,FPGA可以提供更多的灵活性和可编程性。通过使用Verilog或VHDL等硬件描述语言,可以在FPGA中实现更复杂的控制逻辑和算法。相比传统的固定功能片,FPGA可以根据具体应用的需求进行定制,从而提供更高的性能和定制化的功能。 此外,FPGA还可以与其他外设和传感器进行连接。例如,可以通过SPI接口将FPGA与MCP2515进行通信,并通过CAN总线与其他设备进行数据交换。FPGA还可以与处理器或微控制器等设备进行串口通信,实现更多的功能集成。 综上所述,将MCP2515驱动程序集成到FPGA中可以实现更高的灵活性和可编程性,同时可以与其他外设和处理器进行集成,提供更高级、更复杂的功能。这种集成方式为CAN总线通信提供了更多的应用场景和灵活性,适用于各种不同的工业控制和汽车电子等领域。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值