mcp2515的嵌入式linux的用例,网上的资料基本都是应用到比较老的内核。步骤基本无异。
本文的内容,是基于dts配置的设备支持;需要做的工作主要有两部分;dts的构建和代码的少量修改。
1.硬件连接:
外设------iso1050-----mcp2515----cpu
cpu与mcp2515之间采用spi通信方式,利用的cpu的spi0接口,片上的spi0。
2.dts的编写
1)、
spi0: spi@f0000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "atmel,at91rm9200-spi";
reg = <0xf0000000 0x100>;
interrupts = <13 IRQ_TYPE_LEVEL_HIGH 3>;
dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(1)>,
<&dma0 1 AT91_DMA_CFG_PER_ID(2)>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi0>;
clocks = <&spi0_clk>;
clock-names = "spi_clk";
cs-gpios = <&pioA 14 GPIO_ACTIVE_LOW>;
status = "okay";
};
spi这个大同小异,每个片子的配置差不多。注意的就是cs-gpios,片选的gpio。
2)、
mcp2515的dnode编写
clocks {
mcp251x: mcp251x_xtal {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <8000000>;//8Mhz,这个时钟的大小和原理图mcp2515外挂的晶振大小有关 8MHZ or 16MHZ
};
};
ahb{
apb{
spi0: spi@f0000000 {
can0: can@0 {
compatible = "microchip,mcp2515";
reg = <0>;//cs 0
clocks = <&mcp251x>;
clock-names = "mcp251x_clk";
spi-max-frequency = <25000000>;//25Mhz
interrupt-parent = <&pioC>;//pc
interrupts = <30 IRQ_TYPE_EDGE_FALLING>;//falling edge trigger 中断依据原理图的mcp2515的INT接到cpu的位置
rst-gpios = <&pioC 5 0>;//依赖于mcp2515的reset接到cpu的哪个pin
int-gpios = <&pioC 30 0>;//依赖于mcp2515的INT接到cpu的哪个pin
//vdd-supply = <®_can>;
//xceiver-supply = <®5v0>;
};
};
};
};
dts的修改具体可参考 microchip,mcp251x.txt
3.代码修改
mcp251x.c
struct mcp251x_priv {
....
//mcp reset pin and interrupt pin desc
struct gpio_desc *rst_gpio;
struct gpio_desc *int_gpio;
....
}
static int mcp251x_can_probe(struct spi_device *spi)
{
... ...
priv->rst_gpio = devm_gpiod_get_index(&spi->dev,"rst",0x00);
if (IS_ERR_OR_NULL(priv->rst_gpio))
{
priv->rst_gpio = NULL;
//printk("get rst gpio error!!
");
}
else
{
err = gpiod_direction_output(priv->rst_gpio, 1);
if (err) {
dev_dbg(&spi->dev, "Unable to set input direction for mcp2515 INT GPIO");
}
//printk("set rst gpio output!!
");
}
priv->int_gpio = devm_gpiod_get_index(&spi->dev,"int",0x00);
if (IS_ERR_OR_NULL(priv->int_gpio))
{
priv->int_gpio = NULL;
//printk("get int gpio error!!
");
}
else
{
err = gpiod_direction_input(priv->int_gpio);
if (err) {
dev_dbg(&spi->dev, "Unable to set input direction for mcp2515 INT GPIO");
}
//printk("set int gpio input!!
");
}
... ...
};