平台at91sam9g45 linux版本 3.6.9
1 board-sam9m10g45ek.c 文件添加如下结构体
static struct mcp251x_platform_data mcp251x_info = {
.oscillator_frequency = 8000000,
.board_specific_setup = NULL,//&mcp251x_setup,
.power_enable = NULL, //mcp251x_power_enable,
.transceiver_enable = NULL,
};
static struct spi_board_info can_spi_devices[] = {
{
.modalias = "mcp2515",
.platform_data = &mcp251x_info,
.irq = AT91_PIN_PD18,
.max_speed_hz = 2*1000*1000,
.chip_select = 0,
.bus_num = 0,
.mode = SPI_MODE_0,
},
};
在 ek_board_init函数中添加spi设备注册接口
at91_add_device_spi(can_spi_devices, ARRAY_SIZE(can_spi_devices));
2 spi-atmel.c文件中修改atmel_spi_devtypes结构体,这样spi控制器才能找到对应的驱动
这是这个内核版本的问题,高版本就不需要更改这个地方
static const struct platform_device_id atmel_spi_devtypes[] = {
{
.name = "spi-at91rm9200",
.driver_data = (unsigned long) &at91rm9200_config,
}, {
.name = "spi-at91sam9260",
.driver_data = (unsigned long) &at91sam9260_config,
}, {
.name = "atmel_spi", //"spi-at91sam9x5",//modify by cs 20180305 for spi
.driver_data = (unsigned long) &at91sam9x5_config,
}, {
/* sentinel */
}
};
3 在mcp251x.c文件中添加
#include <linux/gpio.h>
在函数mcp251x_open中添加flags变量和赋值语句,将spi->irq通过gpio_to_irq转为系统认识的中断号,并更改request_threaded_irq入参
unsigned long flags;
int ret, irq;
flags = IRQF_ONESHOT;
if (pdata->irq_flags)
flags |= pdata->irq_flags;
else
flags |= IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;//at91系列芯片必须同时定义上升沿和下降沿中断
irq = gpio_to_irq(spi->irq);
ret = request_threaded_irq(irq, NULL, mcp251x_can_ist,
flags,DEVICE_NAME, priv);
在函数mcp251x_stop中,添加irq变量,同样将spi->irq通过gpio_to_irq转为系统认识的中断号,并更改free_irq的入参
int irq;
irq = gpio_to_irq(spi->irq);
free_irq(irq, priv);
在mcp251x_can_ist函数开始位置添加如下代码,屏蔽上升沿中断
int val=gpio_get_value(spi->irq);
if (val==1) return IRQ_NONE;
4 编译
1 关闭dts
Boot options --->
[ ] Flattened Device Tree support
2 选择支持can芯片mcp251x
[*] Networking support --->
<*> CAN bus subsystem support --->
--- CAN bus subsystem support
<*> Raw CAN Protocol (raw access with CAN-ID filtering)
<*> Broadcast Manager CAN Protocol (with content filtering)
< > CAN Gateway/Router (with netlink configuration)
CAN Device Drivers --->
< > Virtual Local CAN Interface (vcan)
< > Serial / USB serial CAN Adaptors (slcan)
<*> Platform CAN drivers with Netlink support
[*] CAN bit-timing calculation
< > Atmel AT91 onchip CAN controller
<*> Microchip MCP251x SPI CAN controllers
< > Philips/NXP SJA1000 devices --->
< > Bosch C_CAN/D_CAN devices --->
< > Bosch CC770 and Intel AN82527 devices --->
CAN USB interfaces --->
< > Softing Gmbh CAN generic support
[*] CAN devices debugging messages
3 选择支持spi
[*] SPI support --->
--- SPI support
[*] Debug support for SPI drivers
*** SPI Master Controller Drivers ***
< > Altera SPI Controller
<*> Atmel SPI Controller
<*> Utilities for Bitbanging SPI masters
< > GPIO-based bitbanging SPI Master
< > OpenCores tiny SPI
< > Analog Devices AD-FMCOMMS1-EBZ SPI-I2C-bridge driver
< > Xilinx SPI controller common module
< > DesignWare SPI controller core support
*** SPI Protocol Masters ***
<*> User mode SPI device driver support
< > Infineon TLE62X0 (for power switching)
4测试can
编译 iproute和canutils并拷贝到设备文件系统中
./ip link set can0 down
./ip link set can0 type can bitrate 125000
./ip link set can0 up
./cansend can0 -i 0x800 -e 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 //-e为扩展帧
./cansend can0 -i 0x00 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88
./cansend can0 -i 0x02 0x11 0x12 --loop=20
./candump can0