kernel 3.18,mcp2515 implemented in AT91SAM9G25

2019-07-13 04:04发布

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!! "); } ... ... };