你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 1283|回复: 0

[STM32F429] uclinux stm32f429i discovery 移植enc28j60网卡

[复制链接]

1

主题

0

回帖

0

蝴蝶豆

新手上路

最后登录
2016-4-21
发表于 2016-3-28 02:09:25 | 显示全部楼层 |阅读模式
移植enc28j60笔记
这个是面向过程的方法,还有一种是把中断弄进iomux里初始化,不过那样IO口就固定为中断了,而且不好理解,所以用了这个。
enc28j60移植第一步初始化接口
1,spi接口(5个SPI随便,lcd和陀螺仪那个别用)
2,外部中断接口 (这里举例用了pe1,其实可以随便设置)

平台设备注册

arch/arm/mach-stm32/spi.c
注册平台设备
#if defined(CONFIG_STM32_SPI4)
        platform_set_drvdata(&spi_stm32_dev4,
                (void *) stm32_clock_get(CLOCK_PCLK2));//设置时钟
        platform_device_register(&spi_stm32_dev4);
#endif

io初始化

arch/arm/mach-stm32/iomux.c

struct stm32f2_gpio_dsc                gpio_dsc;//gpio指向结构体

struct stm32f2_gpio_dsc {
        u32                port;                /* GPIO port ap接口
                              */
        u32                pin;                /* GPIO pin  ap接口下的pin              */
};
case STM32F2_GPIO_ROLE_SPI4
                otype  = STM32F2_GPIO_OTYPE_PP;//输出
                ospeed = STM32F2_GPIO_SPEED_50M;//io频率
                pupd   = STM32F2_GPIO_PUPD_UP;//上下拉
                break;


#if defined(CONFIG_STM32_SPI4)
                gpio_dsc.port = 4;        /* CLCK */
                gpio_dsc.pin  = 2;


                stm32f2_gpio_config(&gpio_dsc, STM32F2_GPIO_ROLE_SPI4);//初始化完成

                gpio_dsc.port = 4;        /* DI */
                gpio_dsc.pin  = 5;
                stm32f2_gpio_config(&gpio_dsc, STM32F2_GPIO_ROLE_SPI4);

                gpio_dsc.port = 4;        /* DO */
                gpio_dsc.pin  = 6;
                stm32f2_gpio_config(&gpio_dsc, STM32F2_GPIO_ROLE_SPI4);

                gpio_dsc.port = 4;        /* CS */
                gpio_dsc.pin  = 4;
                stm32f2_gpio_config(&gpio_dsc, STM32F2_GPIO_ROLE_OUT);
#endif


gpio操作函数

kernel config 设置CONFIG_GPIOLIB =y
1获取gpio地址
#define STM32_GPIO_PORTPIN2NUM(port, pin)        \
        (STM32_GPIO_OFF + ((port) * STM32_GPIO_PORT_PINS + (pin)))

2设值函数
#define gpio_get_value                                __gpio_get_value//获取设置值
#define gpio_set_value                                __gpio_set_value//设置值
#define gpio_to_irq                                __gpio_to_irq//获取gpio中断
#define gpio_cansleep                                __gpio_cansleep//使能休眠
linux中断申请函数
int request_irq(unsigned int irq, irq_handler_t handler,
                         unsigned long irqflags, const char *devname, void *dev_id)
irq是要申请的硬件中断号。
handler是向系统注册的中断处理函数,是一个回调函数,中断发生时,系统调用这个函数,dev_id参数将被传递给它。
irqflags是中断处理的属性,若设置了IRQF_DISABLED (老版本中的SA_INTERRUPT,本版zhon已经不支持了),则表示中断处理程序是快速处理程序,快速处理程序被调用时屏蔽所有中断,慢速处理程序不屏蔽;若设置了IRQF_SHARED (老版本中的SA_SHIRQ),则表示多个设备共享中断,若设置了IRQF_SAMPLE_RANDOM(老版本中的SA_SAMPLE_RANDOM),表示对系统熵有贡献,对系统获取随机数有好处。(这几个flag是可以通过或的方式同时使用的)
devname设置中断名称,通常是设备驱动程序的名称  在cat /proc/interrupts中可以看到此名称。
dev_id在中断共享时会用到,一般设置为这个设备的设备结构体或者NULL。
request_irq()返回0表示成功,返回-INVAL表示中断号无效或处理函数指针为NULL,返回-EBUSY表示中断已经被占用且不能共享。

以下进入驱动文件修改。enc28j60.c enc28j60.h
模块中断函数

static irqreturn_t enc28j60_irq(int irq, void *dev_id)
{
        struct enc28j60_net *priv = dev_id;

        /*
         * Can't do anything in interrupt context because we need to
         * block (spi_sync() is blocking) so fire of the interrupt
         * handling workqueue.
         * Remember that we access enc28j60 registers through SPI bus
         * via spi_sync() call.
         */
                *
在中断的情况下,不能做任何事情,因为block (spi_sync() is blocking)被阻塞。
                *进入中断服务函数

                *ENC28J60通过SPI总线开始数据通讯.
               
*通过spi_sync()调用。
*
        schedule_work(&priv->irq_work);

        stm32irq_clear();//释放中断
        gpio_set_value(gpio_to_irq(STM32_GPIO_PORTPIN2NUM(4, 1)),0);//清理寄存器

        return IRQ_HANDLED;
}
注册外部中断函数
static stm32irq_reg(void){
gpio_request(gpio_to_irq(STM32_GPIO_PORTPIN2NUM(4, 1)),ethirq);
}
释放中断函数
static stm32irq_clear(void){
free_irq(gpio_to_irq(STM32_GPIO_PORTPIN2NUM(4, 1)),ethirq);
}
获取pe1的gpio值
STM32_GPIO_PORTPIN2NUM(4, 1)
取gpio的中断号
gpio_to_irq(STM32_GPIO_PORTPIN2NUM(4, 1))
用这个替换probe里的中断服务函数
ret = request_irq(gpio_to_irq(STM32_GPIO_PORTPIN2NUM(4, 1)), enc28j60_irq, 0, ethirq, priv);

enc28j60中断函数,我们这里要修改为外部中断
ret = request_irq(spi->irq, enc28j60_irq, 0, DRV_NAME, priv);
修改
dev->irq = spi->irq;
为如下
dev->irq = gpio_to_irq(STM32_GPIO_PORTPIN2NUM(4, 1));


kernel编译设置
device drivers--->
    spi_support --->

          stm32 spi controller

device drivers--->

    network device support --->

         ethernet (10 or 100mbit) --->

                 enc28j60 support
networking support --->

      netowrking options---->

           packet socket

           unix domain sockets

          tcp/ip networking



回复

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版