对于mcp2515的移植相关知识课先参考这里http://blog.csdn.net/sno_guo/article/details/17029295
下面是针对s5p4418官方提供的内核为基础做的相关修改。
对于2515的驱动我们不用关心,直接使用内核自带的即可。首先我们需要对内核的配置做添加,具体如下面的图所示:
务必确保内核的配置中上面图片的选择是被打开的,免得做其他工作时造成未知的问题。
下面是修改板级目录下device.c的文件,找到下面的代码,并修改成如下所示:
/*------------------------------------------------------------------------------
* SSP/SPI
*/
#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
#include
#include
static void spi0_cs(u32 chipselect)
{
//printk("ERTER:%s ......
",__func__);
#if (CFG_SPI0_CS_GPIO_MODE)
if(nxp_soc_gpio_get_io_func( CFG_SPI0_CS )!= nxp_soc_gpio_get_altnum( CFG_SPI0_CS))
nxp_soc_gpio_set_io_func( CFG_SPI0_CS, nxp_soc_gpio_get_altnum( CFG_SPI0_CS));
nxp_soc_gpio_set_io_dir( CFG_SPI0_CS,1);
nxp_soc_gpio_set_out_value( CFG_SPI0_CS , chipselect);
#else
;
#endif
}
struct pl022_config_chip spi0_info = {
/* available POLLING_TRANSFER, INTERRUPT_TRANSFER, DMA_TRANSFER */
.com_mode = CFG_SPI0_COM_MODE,
.iface = SSP_INTERFACE_MOTOROLA_SPI,
/* We can only act as master but SSP_SLAVE is possible in theory */
.hierarchy = SSP_MASTER,
/* 0 = drive TX even as slave, 1 = do not drive TX as slave */
.slave_tx_disable = 1,
.rx_lev_trig = SSP_RX_4_OR_MORE_ELEM,
.tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC,
.ctrl_len = SSP_BITS_8,
.wait_state = SSP_MWIRE_WAIT_ZERO,
.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
/*
* This is where you insert a call to a function to enable CS
* (usually GPIO) for a certain chip.
*/
#if (CFG_SPI0_CS_GPIO_MODE)
.cs_control = spi0_cs,
#endif
.clkdelay = SSP_FEEDBACK_CLK_DELAY_1T,
};
void s5p4418_mcp2515_init(void)
{
printk("ERTER:%s ......
",__func__);
nxp_soc_gpio_set_io_func(PAD_GPIO_C+ 30, 0);
nxp_soc_gpio_set_io_func(PAD_GPIO_C+ 29, 1);
nxp_soc_gpio_set_io_func(PAD_GPIO_D+ 0, 1);
nxp_soc_gpio_set_io_func(PAD_GPIO_C+ 31, 1);
nxp_soc_gpio_set_io_func(PAD_GPIO_B+ 6, 0);
}
static struct mcp251x_platform_data mcp251x_info = {
.oscillator_frequency = 20 * 1000 * 1000,
.board_specific_setup = &s5p4418_mcp2515_init,
.power_enable = NULL,
.transceiver_enable = NULL,
};
static struct spi_board_info spi_plat_board[] __initdata = {
#ifdef CONFIG_CAN_MCP251X
[0] = {
.modalias = "mcp2515", /* fixup */
.max_speed_hz = 1 * 1000 * 1000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0, /* Note> set bus num, must be smaller than ARRAY_SIZE(spi_plat_device) */
.chip_select = 0, /* Note> set chip select num, must be smaller than spi cs_num */
.controller_data = &spi0_info,
.mode = SPI_MODE_0,
.platform_data = &mcp251x_info,
.irq = PB_PIO_IRQ(CFG_IO_CAN_DETECT),
},
#else
[0] = {
.modalias = "spidev", /* fixup */
.max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */
.bus_num = 0, /* Note> set bus num, must be smaller than ARRAY_SIZE(spi_plat_device) */
.chip_select = 0, /* Note> set chip select num, must be smaller than spi cs_num */
.controller_data = &spi0_info,
.mode = SPI_MODE_3 | SPI_CPOL | SPI_CPHA,
},
#endif
};
#endif
相对于源码主要做的修改是:
1.spi_plat_board结构体增加了对mcp2515的定义
2.添加mcp251x_info结构定义
3.添加void s5p4418_mcp2515_init(void)函数
这里说明一下void s5p4418_mcp2515_init(void)函数的意义,该函数是对SPI0的GPIO做了配置,在默认的情况下SPI0的GPIO不一定为SPI的功能,所以这里务必需要重新配置一下(由于开始没注意,导致了无法初始化的问题),当然这个配置工作也可以在其他的地方做。
CFG_IO_CAN_DETECT这个定义是在板级目录的include目录下cfg_main.h文件中,这里定义的是GPIOB6引脚。
做了上面的配置之后初始化就应该没有问题了。
使用ifconfig can0 up进行检测,如果不报错那么与mcp2515的通信是没有问题了。
剩下的就可以使用ip、candump等命令进行 can操作了。
希望对移植can遇到问题的朋友有所帮助。