调试MT7688的GPIO:输出、输入(中断) |
您所在的位置:网站首页 › mt7688 › 调试MT7688的GPIO:输出、输入(中断) |
用到的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 |