文档章节

RT5350 GPIO中断

ansonc
 ansonc
发布于 2015/07/31 00:15
字数 552
阅读 83
收藏 0

一、依赖

sdk版本:MTK_Ralink_ApSoC_SDK_4200_20131106

kernel版本:linux-2.6.21.x

参考:RT5350_datasheet.pdf

二、PIO寄存器

RT5350_datasheet:P56~P61

RT5350总共28路PIO,28路PIO按0~21,22~27分两组寄存器分别控制。

三、ralink_gpio模块主要函数

  1. ralink_gpio_led_do_timer:周期轮询pio,对设定的pio进行on/off/blink操作

  2. ralink_gpio_led_init_timer:初始化pio轮询定时器

  3. ralink_gpio_init:注册ralink_gpio模块,使能pio中断,调用初始化pio轮询定时器

  4. ralink_gpio_exit:注销ralink_gpio模块

  5. ralink_gpio_notify_user:中断通知

  6. ralink_gpio_save_clear_intp:保存清穿中断标识

  7. ralink_gpio_irq_handler:中断处理函数,记录pio触发中断后维持时间,通知用户

  8. ralink_gpio_init_irq:注册中断处理函数

四、添加自定义中断处理函数

  1. 添加自定义中断处理函数数组

typedef void(*pio_irq_hdlr)(void*);
typedef struct __cstm_pio_hdlr{
    pio_irq_hdlr irq_hdlr;
    unsigned char rising;
}cstm_pio_hdlr_t,*cstm_pio_hdlr_p;
cstm_pio_hdlr_t cstm_pio_irq_hdlr[RALINK_GPIO_NUMBER] = {0};

    2. 添加自定义中断处理函数绑定

    unsigned long tmp;
    unsigned long reg_pio_dir = (irq_num<22)? RALINK_REG_PIODIR:RALINK_REG_PIO2722DIR;
    unsigned char bitoffset = (irq_num<22)? irq_num:(irq_num-22);
    unsigned long reg_irq_ena = 0;
      unsigned long gpiomode = irq_num==0 ? 0 : \
        (irq_num<=2 ? RALINK_GPIOMODE_I2C : \
        (irq_num<=6 ? RALINK_GPIOMODE_SPI : \
        (irq_num<=14 ? RALINK_GPIOMODE_UARTF : \
        (irq_num<=16 ? RALINK_GPIOMODE_UARTL : \
        (irq_num<=21 ? RALINK_GPIOMODE_JTAG : \
        (irq_num<=26 ? RALINK_GPIOMODE_EPHY : \
        (irq_num<=27 ? RALINK_GPIOMODE_SPI_CS1 : 0)))))));


    /*set pio as gpio*/
    *(volatile u32 *)(RALINK_REG_GPIOMODE) = cpu_to_le32(gpiomode);
    
    /* set pio direction as input */
    tmp = le32_to_cpu(*(volatile u32 *)(reg_pio_dir));
    tmp &= ~cpu_to_le32(1<<bitoffset);
    *(volatile u32 *)(RALINK_REG_PIODIR) = tmp;    

    /* enable gpio interrupt*/
    *(volatile u32 *)(RALINK_REG_INTENA) = cpu_to_le32(RALINK_INTCTL_PIO);
    
    /* set irq edge trigger*/
    if(rising)
    {
        reg_irq_ena = (irq_num<22)? RALINK_REG_PIORENA:RALINK_REG_PIO2722RENA;
    }
    else
    {
        reg_irq_ena = (irq_num<22)? RALINK_REG_PIOFENA:RALINK_REG_PIO2722FENA;
    }
    *(volatile u32 *)(reg_irq_ena) = bitoffset;

EXPORT_SYMBOL(ralink_gpio_cstm_irq_bind);

    3. 添加中断跳转捕获

修改ralink_gpio_irq_handler,

#if defined (RALINK_GPIO_HAS_2722)
    for (i = 0; i < 22; i++) {
        if (! (ralink_gpio_intp & (1 << i)))
            continue;
        ralink_gpio_irqnum = i;
        if (ralink_gpio_edge & (1 << i)) { //rising edge
            if( NULL != cstm_pio_irq_hdlr[i].cstm_pio_irq_hdlr && cstm_pio_irq_hdlr[i].rising)
            {
                cstm_pio_irq_hdlr[i].irq_hdlr(NULL);
                continue;
            }  
     
            if (record[i].rising != 0 && time_before_eq(now,
                        record[i].rising + 40L)) {
                /*
                 * If the interrupt comes in a short period,
                 * it might be floating. We ignore it.
                 */
            }
            else {
                record[i].rising = now;
                if (time_before(now, record[i].falling + 200L)) {
                    //one click
                    ralink_gpio_notify_user(1);
                }
                else {
                    //press for several seconds
                    ralink_gpio_notify_user(2);
                }
            }
        }
        else { //falling edge
            if( NULL != cstm_pio_irq_hdlr[i].cstm_pio_irq_hdlr && !cstm_pio_irq_hdlr[i].rising)
            {
                cstm_pio_irq_hdlr[i].irq_hdlr(NULL);
                continue;
            }          
     
            record[i].falling = now;
        }
        break;
    }
    for (i = 22; i < 28; i++) {
        if (! (ralink_gpio2722_intp & (1 << (i - 22))))
            continue;
        ralink_gpio_irqnum = i;
        if (ralink_gpio2722_edge & (1 << (i - 22))) {
            if( NULL != cstm_pio_irq_hdlr[i].cstm_pio_irq_hdlr && cstm_pio_irq_hdlr[i].rising)
            {
                cstm_pio_irq_hdlr[i].irq_hdlr(NULL);
                continue;
            }                    
            if (record[i].rising != 0 && time_before_eq(now,
                        record[i].rising + 40L)) {
            }
            else {
                record[i].rising = now;
                if (time_before(now, record[i].falling + 200L)) {
                    ralink_gpio_notify_user(1);
                }
                else {
                    ralink_gpio_notify_user(2);
                }
            }
        }
        else {
            if( NULL != cstm_pio_irq_hdlr[i].cstm_pio_irq_hdlr && !cstm_pio_irq_hdlr[i].rising)
            {
                cstm_pio_irq_hdlr[i].irq_hdlr(NULL);
                continue;
            }                    
            record[i].falling = now;
        }
        break;
    }





© 著作权归作者所有

ansonc
粉丝 3
博文 46
码字总数 16716
作品 0
南京
私信 提问
设备树之GPIO和中断实例

概述 设备树不仅仅描述常规硬件信息,还可以描述中断,GPIO,DMA,PINCTRL,时钟,电源管理等内核基础设施信息及其使用情况,下面重点介绍中断,GPIO等结点属性 中断控制器 对于中断控制器结...

lusimquan
2018/02/02
0
0
[求救大神]4412开发板设置外部中断为下降沿触发,但是在上升沿的时候也触发中断

[求救大神]4412开发板设置外部中断为下降沿触发,但是在上升沿的时候也触发中断 设置和问题如下: 中断信号经过硬件消斗处理; 调试迅为4412的外部中断时,设置中断为下降沿触发,但是在上升...

歌之王子殿下
2017/02/20
320
1
STM32F103CBT6外部中断应用笔记

测试方式: 主芯片:STM32F103CBT6 PA1/PB2接键盘按键 PA6/PA4接LCD PA1—PA4 PB2---PA6 按键被按下后LCD灯亮 实现步骤: - 设置相应时钟 - 设置相应中断 - IO口初始化 - 把相应的IO口设置成...

fcsong000833
2012/07/07
352
0
stm32串口中断注意中断使能

本文以USART1为例,叙述串口中断的编程过程。 1、先来讲述一下在应用串口中断时涉及到的一些库文件。 首先对于STM32外设库文件的应用编程,misc.c和stm32f10xrcc.c是肯定要添加到。 接下来就...

青春无极限
2015/06/11
3.5K
1
STM32GPIO外部中断总结

1 STM32中断分组 STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处。STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB0,PC0,PD0,P...

dp29sym41zygndvf
2017/12/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Guava 3: 集合Collections

正文 一、引子 Guava 对JDK集合的拓展,是最成熟且最受欢迎的部分。本文属于Guava的核心,需要仔细看。 二、Guava 集合 2.1 Immutable Collections不可变集合 1.作用 用不变的集合进行防御性...

孟飞阳
12分钟前
2
0
源码分析 RocketMQ DLedger 多副本存储实现

RocketMQ DLedger 的存储实现思路与 RocketMQ 的存储实现思路相似,本文就不再从源码角度详细剖析其实现,只是点出其实现关键点。我们不妨简单回顾一下 CommitLog 文件、ConsumeQueue 文件设...

中间件兴趣圈
16分钟前
2
0
vue入门--简单路由配置

本文转载于:专业的前端网站➜vue入门--简单路由配置   在初始化vue init webpack <工程名>时,有一步是询问是否安装vue-router,选择yes,如果没有安装的话,后面需要自己安装。然后在目录...

前端老手
47分钟前
5
0
怎么给视频配音

很多刚开始尝试视频制作的小伙伴,帮助到怎么给制作完成的视频配音,其实给视频配音的方法非常简单,在手机上可以进行制作,下面一起来看看给视频配音的方法吧! 具体步骤如下: 1、首先在手...

白米稀饭2019
56分钟前
4
0
windows批处理bat脚本编写

什么是bat脚本 .bat结尾的文件其实就是windows上的批处理脚本,Windows中的bat文件相当于 Linux中shell编程的.sh脚本,批量执行DOS命令。 其最简单的例子,是逐行书写在命令行中会用到的各种...

孙幼凌
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部