调试MT7688的GPIO:输出、输入(中断)

您所在的位置:网站首页 mt7688 调试MT7688的GPIO:输出、输入(中断)

调试MT7688的GPIO:输出、输入(中断)

#调试MT7688的GPIO:输出、输入(中断)| 来源: 网络整理| 查看: 265

用到的GPIO如下:

GPIO#11,名称为GPIO0,连接beep用于输出。

GPIO#36,名称为PERST_N,连接到开发板的reset button,用于输入(irq模式)

1、BEEP控制(GPIO#11)

参考手册可知应该进行如下操作:

a.首先要把GPIO_CTRL_0(0x600)寄存器的bit11设置为1,即代表把GPIO#11设置为GPIO output mode.

b.然后通过GPIO_DSET_0(0x630)和GPIO_DCLR_0(0x640)来控制输出高电平或低电平:

  对GPIO_DSET_0的bit11写1,数据输出寄存器置高,输出高电平,beep off

  对GPIO_DCLR_0的bit11写1,数据输出寄存器清零,输出低电平,beep on

2、通过按键触发外部中断(GPIO#36)

a.首先把GPIO#36设置为输入模式:GPIO_CTRL_1(0x604)的bit4设置为0,GPIO input mode;

b.使能falling edge interrupt:GINT_FEDGE_1(0x664)的bit4设置为1,Enable falling edge triggered;

c.注意:在中断服务器程序中,应当清除中断标志位,并需要重新使能下降沿中断,具体操作如下:

  i.清除中断标志位:GINT_STAT_1(0x694)的bit4写入1(手册中写了W1C,即write 1 to clear)

  ii.重新使能下降沿中断:GINT_FEDGE_1(0x664)的bit4设置为1

部分代码如下:

头文件包含:

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* for gpio_to_irq */ 设置GPIO#11的方向寄存器:

// gpio#11 static void my_gpio_set_direction(u32 dir) { u32 mode; u32 reg; if(dir) { reg = 0x600; mode = rt_sysc_r32(reg); mode = mode & 0xFFFFF7FF; mode = mode | 0x00000800; // 1:output rt_sysc_w32(mode, reg); } else { reg = 0x600; mode = rt_sysc_r32(reg); mode = mode & 0xFFFFF7FF; // 0:input rt_sysc_w32(mode, reg); } } 设置GPIO#11的数据寄存器:

static void my_gpio_set_value(u32 val) { u32 mode; u32 reg; if(val) { reg = 0x630; //DSET mode = rt_sysc_r32(reg); mode = mode & 0xFFFFF7FF; mode = mode | 0x00000800; // 1 --> set rt_sysc_w32(mode, reg); } else { reg = 0x640; //DCLR mode = rt_sysc_r32(reg); mode = mode & 0xFFFFF7FF; mode = mode | 0x00000800; // 1 --> clear rt_sysc_w32(mode, reg); } } GPIO#36中断初始化:

static void my_irq_init(void) { int irq_no; int iRet; irq_no = gpio_to_irq(GPIO_PIN_RST);//GPIO_PIN_RST=36 //申请中断并设置中断处理函数 iRet = request_irq(irq_no, buttons_irq, IRQF_DISABLED, "gpio_int", NULL); if (iRet != 0) { printk("request irq failed!! ret: %d irq:%d gpio:%d \n", iRet, irq_no, GPIO_PIN_RST); return -EBUSY; } else { //input my_gpio_set_direction_RST(0); //set pin to high my_gpio_set_value_RST(1); //enable interrupt my_enable_rst_button_interrupt(); } }

GPIO#36,中断使能,中断关闭,清除中断标志位等操作:

static void my_enable_rst_button_interrupt(void) { u32 mode; //Falling Edge Interrupt mode = rt_sysc_r32(0x664); mode = mode | 0x00000010; // 1 --> enabled rt_sysc_w32(mode, 0x664); } static void my_disable_rst_button_interrupt(void) { u32 mode; //Falling Edge Interrupt mode = rt_sysc_r32(0x664); mode = mode & 0xFFFFFFF7; // 0 --> disable rt_sysc_w32(mode, 0x664); } static void my_clear_rst_button_interrupt(void) { u32 mode; mode = rt_sysc_r32(0x694); //interrupt status reg mode = mode | 0x00000010; // write 1 to clear; rt_sysc_w32(mode, 0x694); } GPIO#36中断服务程序:

//中断处理函数 static irqreturn_t buttons_irq(int irq, void *dev_id) { my_clear_rst_button_interrupt(); printk("rst button irq triggered, irq=%d\n",irq); //must re-enable interrupt. my_enable_rst_button_interrupt(); return IRQ_RETVAL(IRQ_HANDLED); } 最后,Makefile:

KERNELDIR=/work/openwrt/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7688/linux-3.18.45 PWD:=$(shell pwd) INSTALLDIR=/work/dev/drivers TOOLCHAIN="/work/openwrt/staging_dir/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mipsel-openwrt-linux-" obj-m:=hello.o .PHONY:modules modules_install clean modules: #$(MAKE) -C $(KERNELDIR) M=$(PWD) modules make -C $(KERNELDIR) ARCH=mips CROSS_COMPILE=$(TOOLCHAIN) M=$(PWD) modules modules_install: cp hello.ko $(INSTALLDIR) clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

备注,dts文件位于:

/work/openwrt/target/linux/ramips/dts



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3