如何使用全志H3 驱动mcp2515进行can总线通信

短文介绍如何使用全志H3和MCP2515进行can通信

软件资源:

1、全志H3 SDK,linux3.49

2、交叉编译器:arm-linux-gnueabi-gcc

硬件资源:

1、PC ubuntu14.04

2、MCP2515

3、H3 demo板

 

开发步骤:

1、首先确保能够使用交叉编译器编译出H3可运行的最小linux系统(可看小民之前写的另外一篇博客);

2、menuconfig如下,在网络设备文件支持里面选中RAW CAN Protocol ;

选中CAN Device Drivers;选中Microchip MCP251x SPI CAN controllers

3、配置SPI,MCP2515芯片使用SPI和主机通信

4、修改平台文件:/home/fanxiangqiang/src/lichee/linux-3.4/arch/arm/mach-sunxi/sun8i.c,对mcp2515_pdata的定义在文件/home/fanxiangqiang/src/lichee/linux-3.4/include/linux/can/platform/mcp251x.h

添加如下代码:

///
/* spi device controller state, alloc */ 
struct sunxi_spi_config { 
int bits_per_word; //8bit 
int max_speed_hz; //80MHz
 int mode; // pha,pol,LSB,etc.. 
}; 

struct mcp251x_platform_data mcp2515_pdata = { 
   8000000, 0, NULL, NULL, NULL, 
};

struct sunxi_spi_config sunxi_data = { 
   8, 2000000, SPI_MODE_0 
};

 struct spi_board_info spi_infos[] = { 
 {
   .modalias = "mcp2515", 
   .platform_data = &mcp2515_pdata,
   .controller_data = &sunxi_data,//需查控制器的驱动代码,可得知需要提供struct sunxi_spi_config类型数据. 注意不同的同台,需要数据类型也会不同 //      
   //.irq = gpio_to_irq(GPIOA(10)),
 .max_speed_hz = 2000000, //2MHz 
   .bus_num = 1, // 接着编号为0的控制器
   .mode = SPI_MODE_0,
 }, 

};
/

init sunxi_dev_init(void)这个函数中需要添加对MCP2515的注册,它会将MCP2515注册到 /sys/bus目录下

printk("ina219 devi--------------------------------------------ce registered\n");
///

    spi_infos[0].irq = gpio_to_irq(GPIOA(3));
    spi_register_board_info(spi_infos, ARRAY_SIZE(spi_infos));

5、改sys_config.fex,这里的这个文件相当于设备数文件,全志好像没给dts文件,还是我没找到。。。。,把所有的关于spi 设备相关的描述注释掉,不然不会生成can0 设备。

;----------------------------------------------------------------------------------
;SPI device configuration
;----------------------------------------------------------------------------------
;[spi_devices]
;spi_dev_num = 1

;[spi_board0]
;modalias      = spidev
;max_speed_hz  = 33000000
;bus_num       = 1
;chip_select   = 0
;mode          = 0

5、编译,下载,CAN总线作为网络设备,使用ifconfig -a ,可以在网络接口设备中看见can0

启动log如下:

[    1.360579] sunxi_spi_chan_cfg()1376 - [spi-0] has no spi_regulator.
[    1.367637] sunxi_spi_chan_cfg()1376 - [spi-1] has no spi_regulator.
[    1.374721] sunxi_spi_register_spidev()1987 - Get spi devices number failed
[    1.382469] sunxi_spi_init()2073 - register spi devices board info failed 
[    1.390118] sunxi_spi_init()2082 - Sunxi SPI init channel 1 
[    1.396577] sunxi_spi_probe()1665 - [spi-1]: cs bitmap from cfg = 0x1 
[    1.403985] sunxi_spi_request_gpio()1416 - Pinctrl init 1 ... [spi1]
[    1.411193] sunxi_spi_clk_init()1484 - [spi-1] mclk 100000000
[    1.417580] spi_set_clk()219 - set spi clock 10000000, mclk 100000000
[    1.424751] spi_set_clk()229 - CDR2 - n = 4 
[    1.429593] spi spi1: registered master spi1
[    1.434355] spi spi1: master is unqueued, this is deprecated
[    1.440674] spi spi1.0: setup mode 0, 8 bits/w, 2000000 Hz max --> 0
[    1.447807] spi spi1: registered child spi1.0
[    1.452666] sunxi_spi_probe()1719 - allwinners SoC SPI Driver loaded for Bus SPI-1 with 1 Slaves at most
[    1.463212] sunxi_spi_probe()1720 - [spi-1]: driver probe succeed, base f1c69000, irq 98!
[    1.472351] tun: Universal TUN/TAP device driver, 1.6
[    1.477957] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[    1.485047] CAN device driver interface
[    1.489389] mcp251x spi1.0: setup mode 0, 8 bits/w, 2000000 Hz max --> 0
[    1.496973] sunxi_spi_xfer()956 - [spi-1]: begin transfer, txbuf c4ee3fc0, rxbuf   (null), len 1, mode 5
[    1.507534] sunxi_spi_mode_check()873 - dual_mode_cfg = c0919b80 
[    1.514314] sunxi_spi_mode_check()917 - in single SPI mode
[    1.520419] spi_set_bc_tc_stc()382 - tx: 1, rx: 0, stc: 1, dummy: 0
[    1.527376] spi_set_bc_tc_stc()387 - REG BC = 0x1 --
[    1.530404] spi_set_bc_tc_stc()393 - REG TC = 0x1 --
[    1.530404] spi_set_bc_tc_stc()400 - REG BCC = 0x1 --
[    1.544019] sunxi_spi_xfer()1085 -  tx -> by ahb
[    1.549152] sunxi_spi_handler()1256 - [spi-1]: irq status = 1032 
[    1.554003] sunxi_spi_handler()1261 - [spi-1]: SPI TC comes
[    1.562142] spi_set_clk()219 - set spi clock 2000000, mclk 100000000
[    1.569196] spi_set_clk()229 - CDR2 - n = 24 
[    1.574050] sunxi_spi_xfer()956 - [spi-1]: begin transfer, txbuf c4ee3fc0, rxbuf c4ee3f80, len 3, mode 5
[    1.584595] sunxi_spi_mode_check()873 - dual_mode_cfg = c0919b80 
[    1.591375] sunxi_spi_mode_check()917 - in single SPI mode
[    1.597465] spi_set_bc_tc_stc()382 - tx: 3, rx: 0, stc: 3, dummy: 0
[    1.601363] spi_set_bc_tc_stc()387 - REG BC = 0x3 --
[    1.601363] spi_set_bc_tc_stc()393 - REG TC = 0x3 --
[    1.601363] spi_set_bc_tc_stc()400 - REG BCC = 0x3 --
[    1.621061] sunxi_spi_xfer()1105 -  rx and tx -> by ahb
[    1.626880] sunxi_spi_handler()1256 - [spi-1]: irq status = 1033 
[    1.631048] sunxi_spi_handler()1261 - [spi-1]: SPI TC comes
[    1.639863] spi_set_clk()219 - set spi clock 2000000, mclk 100000000
[    1.646934] spi_set_clk()229 - CDR2 - n = 24 
[    1.651790] sunxi_spi_xfer()956 - [spi-1]: begin transfer, txbuf c4ee3fc0, rxbuf c4ee3f80, len 3, mode 5
[    1.662335] sunxi_spi_mode_check()873 - dual_mode_cfg = c0919b80 
[    1.669098] sunxi_spi_mode_check()917 - in single SPI mode
[    1.675204] spi_set_bc_tc_stc()382 - tx: 3, rx: 0, stc: 3, dummy: 0
[    1.682161] spi_set_bc_tc_stc()387 - REG BC = 0x3 --
[    1.685190] spi_set_bc_tc_stc()393 - REG TC = 0x3 --
[    1.685190] spi_set_bc_tc_stc()400 - REG BCC = 0x3 --
[    1.698800] sunxi_spi_xfer()1105 -  rx and tx -> by ahb
[    1.704635] sunxi_spi_handler()1256 - [spi-1]: irq status = 1033 
[    1.711398] sunxi_spi_handler()1261 - [spi-1]: SPI TC comes
[    1.717618] spi_set_clk()219 - set spi clock 2000000, mclk 100000000
[    1.724689] spi_set_clk()229 - CDR2 - n = 24 
[    1.729529] sunxi_spi_xfer()956 - [spi-1]: begin transfer, txbuf c4ee3fc0, rxbuf c4ee3f80, len 3, mode 5
[    1.740073] sunxi_spi_mode_check()873 - dual_mode_cfg = c0919b80 
[    1.746837] sunxi_spi_mode_check()917 - in single SPI mode
[    1.752952] spi_set_bc_tc_stc()382 - tx: 3, rx: 0, stc: 3, dummy: 0
[    1.759908] spi_set_bc_tc_stc()387 - REG BC = 0x3 --
[    1.762929] spi_set_bc_tc_stc()393 - REG TC = 0x3 --
[    1.762929] spi_set_bc_tc_stc()400 - REG BCC = 0x3 --
[    1.776549] sunxi_spi_xfer()1105 -  rx and tx -> by ahb
[    1.782384] sunxi_spi_handler()1256 - [spi-1]: irq status = 1033 
[    1.789147] sunxi_spi_handler()1261 - [spi-1]: SPI TC comes
[    1.795367] spi_set_clk()219 - set spi clock 2000000, mclk 100000000
[    1.795380] mcp251x spi1.0: CANSTAT 0x80 CANCTRL 0x07
[    1.808046] spi_set_clk()229 - CDR2 - n = 24 
[    1.812902] sunxi_spi_xfer()956 - [spi-1]: begin transfer, txbuf c4ee3fc0, rxbuf c4ee3f80, len 3, mode 5
[    1.823446] sunxi_spi_mode_check()873 - dual_mode_cfg = c0919b80 
[    1.830226] sunxi_spi_mode_check()917 - in single SPI mode
[    1.836316] spi_set_bc_tc_stc()382 - tx: 3, rx: 0, stc: 3, dummy: 0
[    1.840214] spi_set_bc_tc_stc()387 - REG BC = 0x3 --
[    1.840214] spi_set_bc_tc_stc()393 - REG TC = 0x3 --
[    1.840214] spi_set_bc_tc_stc()400 - REG BCC = 0x3 --
[    1.859911] sunxi_spi_xfer()1105 -  rx and tx -> by ahb
[    1.865745] sunxi_spi_handler()1256 - [spi-1]: irq status = 1033 
[    1.872509] sunxi_spi_handler()1261 - [spi-1]: SPI TC comes
[    1.878728] spi_set_clk()219 - set spi clock 2000000, mclk 100000000
[    1.879241] mcp251x spi1.0: probed

总结:

1、spi设备驱动框架
 

#include <linux/module.h>
#include <linux/spi/spi.h>

#define DEVICE_NAME   "sensor"
#define SENSOR_SPI_BUS 0
struct spi_device *sensor_spi=NULL;


int sensor_spi_write(void)
{
    return 0;
}

int sensor_spi_read(void)
{
    return 0;
}

static const struct spi_device_id sensor_spi_id[] = {
    { DEVICE_NAME, 0 },
    { }
};

MODULE_DEVICE_TABLE(spi, sensor_spi_id);

static int  sensor_probe(struct spi_device *spi)
{
    sensor_spi=spi;
    return 0;
}

static int  sensor_remove(struct spi_device *spi)
{
    return 0;
}

static struct spi_driver sensor_driver = {
    .driver = {
        .name  = DEVICE_NAME,
        .owner = THIS_MODULE,
    },
    .probe    =  sensor_probe,
    .remove   =  sensor_remove,
    .id_table =  sensor_spi_id,
};

static __init int sensor_spi_init(void)
{
    int status=-1;
    struct spi_master *master;
    struct spi_device *spi;
    struct spi_board_info chip =
    {
        .modalias     = DEVICE_NAME,
        .mode         = 0x00,
        .bus_num      = 0,
        .chip_select  = 0,
        .max_speed_hz = 2000000,
    };
    spi_register_driver(&sensor_driver);
    if (status<0)
    {
        pr_err("%s: spi_register_driver spi_driver failure. status = %d\n", __func__, status);
    }
    pr_err("%s: spi_register_driver spi_driver success. status = %d\n", __func__, status);
    master = spi_busnum_to_master(SENSOR_SPI_BUS);
    if (!master)
    {
        status = -ENODEV;
        goto error_busnum;
    }
    spi = spi_new_device(master, &chip);
    if (!spi)
    {
        status = -EBUSY;
        goto error_mem;
    }
    return status;

error_mem:
error_busnum:
    spi_unregister_driver(&sensor_driver);
    return status;
}

static __exit void sensor_spi_exit(void)
{
    spi_unregister_driver(&sensor_driver);
    if(sensor_spi!=NULL)
    spi_unregister_device(sensor_spi);
}

module_init(sensor_spi_init);
module_exit(sensor_spi_exit);
MODULE_LICENSE("GPL v2");

参考:

https://blog.csdn.net/dearsq/article/details/51953610

https://blog.csdn.net/jklinux/article/details/74347820

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值