精华内容
下载资源
问答
  • imx6ul之按键驱动添加

    千次阅读 2019-05-22 17:10:42
    一、给imx6ul添加按键驱动 在linux4.1.15中给imx6ul添加按键驱动涉及到设备树文件和驱动源码如下 linux-4.1.15/arch/arm/boot/dts/tq-imx6ul.dts linux-4.1.15/drivers/input/keyboard/gpio_keys.c 在板子 首先...

    一、给imx6ul添加按键驱动

    在linux4.1.15中给imx6ul添加按键驱动涉及到设备树文件和驱动源码如下

    linux-4.1.15/arch/arm/boot/dts/tq-imx6ul.dts

    linux-4.1.15/drivers/input/keyboard/gpio_keys.c

    在板子

    首先需要修改设备树文件,在tq-imx6ul.dts中添加如下代码:

    gpio-keys {
    		compatible = "gpio-keys";
    		pinctrl-names = "default";
    		pinctrl-0 = <&pinctrl_gpio_keys>;
    		1 {
    			label = "1";				//按键标签				
    			gpios = <&gpio4 23 GPIO_ACTIVE_LOW>; //使用gpio4_23,低电平有效	
    			gpio-key,wakeup; 			//该按键可以唤醒系统			
    			linux,code = <KEY_1>; 		//键值
    		};
    	
    };
    
    pinctrl_gpio_keys: gpio_keys{
    			fsl,pins = <
    				MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x17059
    			>;
    };

    其中KEY_1定义在linux-4.1.15/include/dt-bindings/input/input.h

    make menuconfig将gpio button选上即可。

     

    展开全文
  • imx6 项目的按键驱动程序

    千次阅读 2016-09-17 16:57:38
     * filename:imx6_key_drv.c  * description: matrix key driver for imx6.  * author:shell.albert@gmail.com  * date: September 1,2015.  *  * three gpio keys are connected to imx6 through ...
    /**
    
     * filename:imx6_key_drv.c
     * description: matrix key driver for imx6.
     * author:shell.albert@gmail.com
     * date: September 1,2015.
     *
     * three gpio keys are connected to imx6 through different GPIO.
     * up/down key: GPIO04/SLEEP_WAKE
     * led key:EIM_BCLK/VOL+
     * left/right key:CSI0_DATA_EN/VOL-
     * ok key:NANDF_CS0
     * return key:NANDF_CS1
     *
     * attention here.
     * the mdev rules must be enabled before use this driver.
     * do the following work to make it works.
     *     /etc/init.d/rcS
     *     #mount partitions
     *     mkdir /dev/pts -p
     *     mount -t devpts devpts /dev/pts
     *     mount -a
     *     echo /sbin/mdev > /proc/sys/kernel/hotplug
     *     mdev -s
     *
     *     /etc/mdev.conf
     *     # system all-writable devices
     *      full            0:0     0666
     *      null            0:0     0666
     *          ptmx            0:0     0666
     *      random          0:0     0666
     *        tty             0:0     0666
     *        zero            0:0     0666


     *        # i2c devices
     *        i2c-0           0:0     0666    =i2c/0
     *        i2c-1           0:0     0666    =i2c/1

     *        # frame buffer devices
     *        fb[0-9]         0:0     0666

     *        # input devices
     *        mice            0:0     0660    =input/
     *        mouse.*         0:0     0660    =input/
     *        event.*         0:0     0660    =input/
     *        ts.*            0:0     0660    =input/
     */

    /**
    Event: time 1441159728.919925, -------------- Report Sync ------------
    Event: time 1441159733.423896, type 4 (Misc), code 4 (ScanCode), value 70052
    Event: time 1441159733.423896, type 1 (Key), code 103 (Up), value 1
    Event: time 1441159733.423896, -------------- Report Sync ------------
    Event: time 1441159733.511935, type 4 (Misc), code 4 (ScanCode), value 70052
    Event: time 1441159733.511935, type 1 (Key), code 103 (Up), value 0
    Event: time 1441159733.511935, -------------- Report Sync ------------
    Event: time 1441159735.431922, type 4 (Misc), code 4 (ScanCode), value 70050
    Event: time 1441159735.431922, type 1 (Key), code 105 (Left), value 1
    Event: time 1441159735.431922, -------------- Report Sync ------------
    Event: time 1441159735.503919, type 4 (Misc), code 4 (ScanCode), value 70050
    Event: time 1441159735.503919, type 1 (Key), code 105 (Left), value 0
    Event: time 1441159735.503919, -------------- Report Sync ------------
    Event: time 1441159739.127894, type 4 (Misc), code 4 (ScanCode), value 700e4
    Event: time 1441159739.127894, type 1 (Key), code 97 (RightCtrl), value 1
    Event: time 1441159739.127894, -------------- Report Sync ------------
    Event: time 1441159739.263894, type 4 (Misc), code 4 (ScanCode), value 700e4
    Event: time 1441159739.263894, type 1 (Key), code 97 (RightCtrl), value 0
    Event: time 1441159739.263894, -------------- Report Sync ------------
    Event: time 1441159742.103834, type 4 (Misc), code 4 (ScanCode), value 700e0
    Event: time 1441159742.103834, type 1 (Key), code 29 (LeftControl), value 1
    Event: time 1441159742.103834, -------------- Report Sync ------------
    Event: time 1441159742.207873, type 4 (Misc), code 4 (ScanCode), value 700e0
    Event: time 1441159742.207873, type 1 (Key), code 29 (LeftControl), value 0
    Event: time 1441159742.207873, -------------- Report Sync ------------
     */

    /**
     * PAD Mux registers.
     * related register define here.
     * I/O are multiplex,so we choose the right mode.
     */
    #define IOMUXC_SW_MUX_CTL_PAD_GPIO04                0x20E0238 //GPIO1_IO04
    #define IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK                0x20E0158 //GPIO6_IO31
    #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA_EN            0x20E0260 //GPIO5_IO20
    #define IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B            0x20E02E4 //GPIO6_IO11
    #define IOMUXC_SW_MUX_CTL_PAD_NAND_CS1_B            0x20E02E8 //GPIO6_IO14
    /**
     * PAD Control registers.
     * used to control the pad physical features.
     */
    #define IOMUXC_SW_PAD_CTL_PAD_GPIO04                    0x20E0608
    #define IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK                    0x20E046C
    #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA_EN                0x20E0630
    #define IOMUXC_SW_PAD_CTL_PAD_NAND_CS0_B                0x20E06CC
    #define IOMUXC_SW_PAD_CTL_PAD_NAND_CS1_B                0x20E06D0

    //register size,it's always 32-bit,4 bytes in 32-bit CPU.
    #define REG_SIZE        0x4

    #define MODULE_NAME        "imx6_key_drv"

    #define print_debug(fmt,arg...)     printk(KERN_DEBUG fmt,##arg)
    #define print_error(fmt,arg...)        printk(KERN_ERR fmt,##arg)

    //GPIO related register define here.
    //up/down key,GPIO1[4].
    #define GPIO1_GDIR        0x209C004
    #define GPIO1_PSR        0x209C008
    #define GPIO1_IMR        0x209C014
    //left/right key,GPIO5[20].
    #define GPIO5_GDIR        0x20AC004
    #define GPIO5_PSR        0x20AC008
    #define GPIO5_IMR        0x20AC014
    //led key:GPIO6[31].
    //ok key: GPIO6[11].
    //return key: GPIO6[14].
    #define GPIO6_GDIR        0x20B0004
    #define GPIO6_PSR        0x20B0008
    #define GPIO6_IMR        0x20B0014

    //for module.
    #include <linux/module.h>
    #include <linux/init.h>
    //for IRQ.
    #include <linux/irq.h>
    #include <linux/interrupt.h>
    //for timer.
    #include <linux/timer.h>
    #include <linux/jiffies.h>

    //for input framework.
    #include <linux/input.h>

    //for ioremap.
    #include <linux/io.h>
    //for kzalloc.
    #include <linux/slab.h>
    //for ulong.
    #include <linux/types.h>

    struct imx6_keys_dev {
        //virtual address after mapping.
        volatile ulong *up_down_vir_addr; //GPIO1[4].
        volatile ulong up_down_status;

        volatile ulong *left_right_vir_addr; //GPIO5[20].
        volatile ulong left_right_status;

        volatile ulong *led_ok_return_vir_addr;//GPIO6[11/14/31].
        volatile ulong led_ok_return_status;
        //scan timer.
        struct timer_list scan_timer;

        //input core.
        struct input_dev *input_device;
    };
    struct imx6_keys_dev *key_dev;
    /**
     * configure the register at initial stage.
     * these registers should only be configured once.
     */
    int imx6_config_reg(ulong phy_addr, int bits_mask, int bits_value) {
        volatile ulong *pbase = NULL;
        volatile int ret;
        int i;
        int reg_bits_num = sizeof(ret);
        pbase = (ulong*) ioremap(phy_addr, REG_SIZE);
        if (!pbase) {
            print_error("error accord when ioremap()!\n");
            return -1;
        }
        ret = ioread32(pbase);
        for (i = 0; i < reg_bits_num; i++) {
            if (bits_mask & (0x1 << i)) {
                ret &= (~(0x1 << i));
            }
        }
        ret |= bits_value;
        iowrite32(ret, pbase);
        iounmap(pbase);
        pbase = NULL;
        return 0;
    }
    /**
     * configure the IOMUX registers to choose the right pin mode.
     */
    int imx6_config_all_iomuxcs(void) {
        //IOMUXC_SW_MUX_CTL_PAD_GPIO04.[2:0]=101=0x5,GPIO1[4].
        //bits_mask=111=0x7,
        if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_GPIO04, 0x7, 0x5) < 0) {
            return -1;
        }
        
        //IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK,[2:0]=101=0x5,GPIO6[31].
        //bits_mask=111=0x7.
        if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK, 0x7, 0x5) < 0) {
            return -1;
        }
        
        //IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA_EN,[2:0]=101=0x5,ALT5,GPIO5[20].
        //bits_mask=111=0x7.
        if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA_EN, 0x7, 0x5) < 0) {
            return -1;
        }

        //IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B,[2:0]=101=0x5,ALT5,GPIO6[11].
        //bits_mask=111=0x7.
        if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B, 0x7, 0x5) < 0) {
            return -1;
        }
        
        //IOMUXC_SW_MUX_CTL_PAD_NAND_CS1_B,[2:0]=101=0x5,ALT5,GPIO6[14].
        //bits_mask=111=0x7.
        if (imx6_config_reg(IOMUXC_SW_MUX_CTL_PAD_NAND_CS1_B, 0x7, 0x5) < 0) {
            return -1;
        }
        return 0;
    }

    //configure pad's physical feature.
    int imx6_config_all_pads(void) {
        //[16]=1,Schmitt trigger input.
        //[15:14]=10,100Kohm pull up.
        //[13]=1,pull enabled.
        //[12]=1,pull/keeper enabled.
        //bits_mask= 1,1111,0000,0000,0000=0x1F000.
        //bits_value=1,1011,0000,0000,0000=0x1B000.

        //IOMUXC_SW_PAD_CTL_PAD_GPIO04.
        if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_GPIO04, 0x1F000, 0x1B000) < 0) {
            return -1;
        }
        //IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK.
        if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK, 0x1F000, 0x1B000) < 0) {
            return -1;
        }
        //IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA_EN.
        if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA_EN, 0x1F000, 0x1B000) < 0) {
            return -1;
        }
        
        //IOMUXC_SW_PAD_CTL_PAD_NAND_CS0_B.
        if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_NAND_CS0_B, 0x1F000, 0x1B000) < 0) {
            return -1;
        }
        
        //IOMUXC_SW_PAD_CTL_PAD_NAND_CS1_B.
        if (imx6_config_reg(IOMUXC_SW_PAD_CTL_PAD_NAND_CS1_B, 0x1F000, 0x1B000) < 0) {
            return -1;
        }
        return 0;
    }

    //configure GPIO registers.
    int imx6_config_all_gpios(void) {
        //up/down key,GPIO1[4].
        //[4]=0,direction:input.
        //bits_mask=0001,0000=0x10.
        //bits_value=0000,0000=0x0.
        if (imx6_config_reg(GPIO1_GDIR, 0x10, 0x0) < 0) {
            return -1;
        }
        //[4]=0,disable interrupt.
        if (imx6_config_reg(GPIO1_IMR, 0x10, 0x0) < 0) {
            return -1;
        }

        //left/right key,GPIO5[20].
        //[20]=0,direction,input.
        //bits_mask=1,0000,0000,0000,0000,0000=0x100000.
        //bits_value=0,0000,0000,0000,0000,0000=0x0.
        if (imx6_config_reg(GPIO5_GDIR, 0x100000, 0x0) < 0) {
            return -1;
        }
        //[4]=0,disable interrupt.
        if (imx6_config_reg(GPIO5_IMR, 0x100000, 0x0) < 0) {
            return -1;
        }

        //led key:GPIO6[31].
        //ok key: GPIO6[11].
        //return key: GPIO6[14].
        //[31]=0,direction input.
        //[11]=0,direction input.
        //[14]=0,direction input.
        //bits_mask=1000,0000,0000,0000,0100,1000,0000,0000=0x80004800.
        //bits_value=0000,0000,0000,0000,0000,0000,0000,0000=0x0.
        if (imx6_config_reg(GPIO6_GDIR, 0x80004800, 0x0) < 0) {
            return -1;
        }
        //[31]=0,disable interrupt.
        //[14]=0,disable interrupt.
        //[11]=0,disable interrupt.
        if (imx6_config_reg(GPIO6_IMR, 0x80004800, 0x0) < 0) {
            return -1;
        }

        //do ioremap for virtual address.
        if (!(key_dev->up_down_vir_addr = (ulong*) ioremap(GPIO1_PSR, REG_SIZE))) {
            return -1;
        }
        if (!(key_dev->left_right_vir_addr = (ulong*) ioremap(GPIO5_PSR, REG_SIZE))) {
            return -1;
        }
        if (!(key_dev->led_ok_return_vir_addr = (ulong*) ioremap(GPIO6_PSR, REG_SIZE))) {
            return -1;
        }
        key_dev->up_down_status=1;
        key_dev->left_right_status=1;
        key_dev->led_ok_return_status=1;
        return 0;
    }

    //timer function.
    //used to poll key status.
    void key_status_scan_function(unsigned long arg) {

        struct imx6_keys_dev *pkey_dev = (struct imx6_keys_dev*) (arg);
        volatile int ret;

        //the up/down key,GPIO1[4].
        ret = ioread32(pkey_dev->up_down_vir_addr);
        if(!(ret & (0x1 << 4)) && pkey_dev->up_down_status)
        {
            //key was pressed.
            pkey_dev->up_down_status=0;
            input_report_key(pkey_dev->input_device, KEY_UP, 1);
            input_sync(pkey_dev->input_device);
        }else if((ret&(0x1 << 4)) && !pkey_dev->up_down_status)
        {
            //key was released.
            pkey_dev->up_down_status=1;
            input_report_key(pkey_dev->input_device, KEY_UP, 0);
            input_sync(pkey_dev->input_device);
        }

        //the left/right key,GPIO5[20].
        ret = ioread32(pkey_dev->left_right_vir_addr);
        if(!(ret & (0x1 << 20)) && pkey_dev->left_right_status)
        {
            //key was pressed.
            pkey_dev->left_right_status=0;
            input_report_key(pkey_dev->input_device, KEY_LEFT, 1);
            input_sync(pkey_dev->input_device);
        }else if((ret&(0x1<<20)) && !pkey_dev->left_right_status)
        {
            //key was released.
            pkey_dev->left_right_status=1;
            input_report_key(pkey_dev->input_device, KEY_LEFT, 0);
            input_sync(pkey_dev->input_device);
        }

        //led key:GPIO6[31],open or close led.
        //ok key: GPIO6[11],left ctrl.
        //return key: GPIO6[14],left shift.
        ret = ioread32(pkey_dev->led_ok_return_vir_addr);
        if(!(ret & (0x1 << 11)) && (pkey_dev->led_ok_return_status&(0x1<<11)))
        {
            //key was pressed.
            pkey_dev->led_ok_return_status&=~(0x1<<11);
            input_report_key(pkey_dev->input_device, KEY_LEFTCTRL, 1);
            input_sync(pkey_dev->input_device);
        }else if( (ret&(0x1<<11)) && !(pkey_dev->led_ok_return_status&(0x1<<11)))
        {
            //key was released.
            pkey_dev->led_ok_return_status|=(0x1<<11);
            input_report_key(pkey_dev->input_device, KEY_LEFTCTRL, 0);
            input_sync(pkey_dev->input_device);
        }
        /
        ret = ioread32(pkey_dev->led_ok_return_vir_addr);
        if(!(ret & (0x1 << 14)) && (pkey_dev->led_ok_return_status&(0x1<<14)))
        {
            //key was pressed.
            pkey_dev->led_ok_return_status&=~(0x1<<14);
            input_report_key(pkey_dev->input_device, KEY_LEFTSHIFT, 1);
            input_sync(pkey_dev->input_device);
        }else if( (ret&(0x1<<14)) && !(pkey_dev->led_ok_return_status&(0x1<<14)))
        {
            //key was released.
            pkey_dev->led_ok_return_status|=(0x1<<14);
            input_report_key(pkey_dev->input_device, KEY_LEFTSHIFT, 0);
            input_sync(pkey_dev->input_device);
        }
        //
        ret = ioread32(pkey_dev->led_ok_return_vir_addr);
        if(!(ret & (0x1 << 31)) && (pkey_dev->led_ok_return_status&(0x1<<31)))
        {
            //key was pressed to open led.
            pkey_dev->led_ok_return_status&=~(0x1<<31);
        }else if( (ret&(0x1<<31)) && !(pkey_dev->led_ok_return_status&(0x1<<31)))
        {
            //key was released to close led.
            pkey_dev->led_ok_return_status|=(0x1<<31);
        }

    #if 1
        //restart the scan routine.
        pkey_dev->scan_timer.expires = jiffies + HZ / 4;    //500ms.
        add_timer(&pkey_dev->scan_timer);
    #endif

    }

    static int __init imx6_key_drv_init(void)
    {
        key_dev=(struct imx6_keys_dev *)kzalloc(sizeof(struct imx6_keys_dev),GFP_KERNEL);
        if(!key_dev)
        {
            print_error("kzalloc() failed!\n");goto error_exit_1;
        }
        key_dev->input_device=input_allocate_device();
        if(!key_dev->input_device)
        {
            print_error(
            "allocate input device failed!\n");goto error_exit_2;
        }

    #if 1
        if(imx6_config_all_iomuxcs()<0)
        {
            goto  error_exit_3;
            return -1;
        }
        if(imx6_config_all_pads()<0)
        {
            goto  error_exit_3;
            return -1;
        }
        if(imx6_config_all_gpios()<0)
        {
            goto  error_exit_3;
            return -1;
        }
    #endif

        //input device name.
        key_dev->input_device->name=MODULE_NAME;

        //key event.
        set_bit(EV_KEY,key_dev->input_device->evbit);
        //key value.
        set_bit(KEY_UP,key_dev->input_device->keybit);
        set_bit(KEY_LEFT,key_dev->input_device->keybit);
        set_bit(KEY_LEFTCTRL,key_dev->input_device->keybit);
        set_bit(KEY_LEFTSHIFT,key_dev->input_device->keybit);
        if(input_register_device(key_dev->input_device))
        {
            print_error("input register device failed!\n");goto error_exit_3;
        }

        //start timer.
        init_timer(&key_dev->scan_timer);key_dev->scan_timer.data=(ulong)key_dev;
        key_dev->scan_timer.function=key_status_scan_function;
        key_dev->scan_timer.expires=jiffies+HZ/2;//500ms.
        add_timer(&key_dev->scan_timer);

        print_debug("imx6_key_drv load successfully!\n");
    return 0;
    /**
     * exit flow when errors occured.
     */
    error_exit_3:
    input_free_device(key_dev->input_device);
    error_exit_2:
    kfree(key_dev);
    error_exit_1:
    return -1;
    }

    static void __exit imx6_key_drv_exit(void)
    {
        del_timer_sync(&key_dev->scan_timer);input_unregister_device(key_dev->input_device);
        input_free_device(key_dev->input_device);
        kfree(key_dev);
    }

    module_init(imx6_key_drv_init);
    module_exit(imx6_key_drv_exit);

    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("zhangshaoyan <shell.albert@gmail.com>");
    MODULE_DESCRIPTION("Keyboard driver for Freescale iMX6 GPIOs");
    MODULE_ALIAS("platform:imx6 key driver");
    展开全文
  • 我在看资料的基础上加以整改,把程序记录下来以便于...GPIO2_6 对应 /* Bank2 */ 中 #define PINID_SSP0_DATA6 MXS_PIN_ENCODE(2, 6) 以此类推 GPIO2_5 对应 /* Bank2 */ 中 #define PINID_SSP0_DATA5 MXS_PIN_...

    我在看资料的基础上加以整改,把程序记录下来以便于日后查看。

    DEMO板上的按键原理图
    这里写图片描述

    按键对应的芯片引脚为:
    GPIO2_6 对应 /* Bank2 */ 中 #define PINID_SSP0_DATA6 MXS_PIN_ENCODE(2, 6)
    以此类推
    GPIO2_5 对应 /* Bank2 */ 中 #define PINID_SSP0_DATA5 MXS_PIN_ENCODE(2, 5)
    GPIO2_4 对应 /* Bank2 */ 中 #define PINID_SSP0_DATA4 MXS_PIN_ENCODE(2, 4)
    GPIO1_18对应 /* Bank1 */ 中 #define PINID_LCD_D18 MXS_PIN_ENCODE(1, 18)
    GPIO1_17对应 /* Bank1 */ 中#define PINID_LCD_D17 MXS_PIN_ENCODE(1, 17)
    具体可以查看内核中芯片引脚:

    linux-2.6.35.3/arch/arm/mach-mx28/mx28_pins.h
    /* Bank 1 */

    define PINID_LCD_D00 MXS_PIN_ENCODE(1, 0)

    define PINID_LCD_D01 MXS_PIN_ENCODE(1, 1)

    define PINID_LCD_D02 MXS_PIN_ENCODE(1, 2)

    define PINID_LCD_D03 MXS_PIN_ENCODE(1, 3)

    define PINID_LCD_D04 MXS_PIN_ENCODE(1, 4)

    define PINID_LCD_D05 MXS_PIN_ENCODE(1, 5)

    define PINID_LCD_D06 MXS_PIN_ENCODE(1, 6)

    define PINID_LCD_D07 MXS_PIN_ENCODE(1, 7)

    define PINID_LCD_D08 MXS_PIN_ENCODE(1, 8)

    define PINID_LCD_D09 MXS_PIN_ENCODE(1, 9)

    define PINID_LCD_D10 MXS_PIN_ENCODE(1, 10)

    define PINID_LCD_D11 MXS_PIN_ENCODE(1, 11)

    define PINID_LCD_D12 MXS_PIN_ENCODE(1, 12)

    define PINID_LCD_D13 MXS_PIN_ENCODE(1, 13)

    define PINID_LCD_D14 MXS_PIN_ENCODE(1, 14)

    define PINID_LCD_D15 MXS_PIN_ENCODE(1, 15)

    define PINID_LCD_D16 MXS_PIN_ENCODE(1, 16)

    define PINID_LCD_D17 MXS_PIN_ENCODE(1, 17)

    define PINID_LCD_D18 MXS_PIN_ENCODE(1, 18)

    define PINID_LCD_D19 MXS_PIN_ENCODE(1, 19)

    define PINID_LCD_D20 MXS_PIN_ENCODE(1, 20)

    define PINID_LCD_D21 MXS_PIN_ENCODE(1, 21)

    define PINID_LCD_D22 MXS_PIN_ENCODE(1, 22)

    define PINID_LCD_D23 MXS_PIN_ENCODE(1, 23)

    define PINID_LCD_RD_E MXS_PIN_ENCODE(1, 24)

    define PINID_LCD_WR_RWN MXS_PIN_ENCODE(1, 25)

    define PINID_LCD_RS MXS_PIN_ENCODE(1, 26)

    define PINID_LCD_CS MXS_PIN_ENCODE(1, 27)

    define PINID_LCD_VSYNC MXS_PIN_ENCODE(1, 28)

    define PINID_LCD_HSYNC MXS_PIN_ENCODE(1, 29)

    define PINID_LCD_DOTCK MXS_PIN_ENCODE(1, 30)

    define PINID_LCD_ENABLE MXS_PIN_ENCODE(1, 31)

    /* Bank 2 */

    define PINID_SSP0_DATA0 MXS_PIN_ENCODE(2, 0)

    define PINID_SSP0_DATA1 MXS_PIN_ENCODE(2, 1)

    define PINID_SSP0_DATA2 MXS_PIN_ENCODE(2, 2)

    define PINID_SSP0_DATA3 MXS_PIN_ENCODE(2, 3)

    define PINID_SSP0_DATA4 MXS_PIN_ENCODE(2, 4)

    define PINID_SSP0_DATA5 MXS_PIN_ENCODE(2, 5)

    define PINID_SSP0_DATA6 MXS_PIN_ENCODE(2, 6)

    define PINID_SSP0_DATA7 MXS_PIN_ENCODE(2, 7)

    define PINID_SSP0_CMD MXS_PIN_ENCODE(2, 8)

    define PINID_SSP0_DETECT MXS_PIN_ENCODE(2, 9)

    define PINID_SSP0_SCK MXS_PIN_ENCODE(2, 10)

    define PINID_SSP1_SCK MXS_PIN_ENCODE(2, 12)

    define PINID_SSP1_CMD MXS_PIN_ENCODE(2, 13)

    define PINID_SSP1_DATA0 MXS_PIN_ENCODE(2, 14)

    define PINID_SSP1_DATA3 MXS_PIN_ENCODE(2, 15)

    define PINID_SSP2_SCK MXS_PIN_ENCODE(2, 16)

    define PINID_SSP2_MOSI MXS_PIN_ENCODE(2, 17)

    define PINID_SSP2_MISO MXS_PIN_ENCODE(2, 18)

    define PINID_SSP2_SS0 MXS_PIN_ENCODE(2, 19)

    define PINID_SSP2_SS1 MXS_PIN_ENCODE(2, 20)

    define PINID_SSP2_SS2 MXS_PIN_ENCODE(2, 21)

    define PINID_SSP3_SCK MXS_PIN_ENCODE(2, 24)

    define PINID_SSP3_MOSI MXS_PIN_ENCODE(2, 25)

    define PINID_SSP3_MISO MXS_PIN_ENCODE(2, 26)

    define PINID_SSP3_SS0 MXS_PIN_ENCODE(2, 27)

    下面直接上代码:

    imx_key.c

    /*
    
       GPIO Driver driver for EasyARM-iMX283
    
    */
    
    #include <linux/module.h>
    
    #include <linux/kernel.h>
    
    #include <linux/types.h>
    
    #include <linux/sched.h>
    
    #include <linux/init.h>
    
    #include <linux/fs.h>
    
    #include <linux/ioctl.h>
    
    #include <linux/delay.h>
    
    #include <linux/bcd.h>
    
    #include <linux/capability.h>
    
    #include <linux/rtc.h>
    
    #include <linux/cdev.h>
    
    #include <linux/miscdevice.h>
    
    #include <linux/gpio.h>
    
    #include <linux/slab.h>
    
    #include </usr/src/linux-2.6.35.3/arch/arm/mach-mx28/mx28_pins.h>
    
    #include <linux/list.h>
    
    #include<linux/init.h>
    
    #include<linux/module.h>
    
    #include<mach/gpio.h>                                                  
    
    #include<asm/io.h>                                                 
    
    #include"/usr/src/linux-2.6.35.3/arch/arm/mach-mx28/mx28_pins.h"
    
    #include "/usr/src/linux-2.6.35.3/arch/arm/plat-mxs/include/mach/pinctrl.h"
    
    #include "/usr/src/linux-2.6.35.3/arch/arm/mach-mx28/include/mach/mx28.h"
    
    #include<linux/fs.h>
    
    #include <linux/io.h>
    
    #include<asm/uaccess.h>                                     
    
    #include<linux/miscdevice.h>                          
    
    #include<linux/irq.h>                          
    
    #include<linux/sched.h>                   
    
    #include<linux/interrupt.h>              
    
    #include<linux/timer.h>
    
    #include <linux/input.h>
    
    #include <linux/time.h>
    
    #include <linux/list.h>
    
    #include <linux/irqreturn.h>
    
    #include <linux/errno.h>
    
    
    #define GPIO_1      MXS_PIN_TO_GPIO(PINID_LCD_D17)
    
    #define GPIO_2      MXS_PIN_TO_GPIO(PINID_LCD_D18)
    
    #define GPIO_3      MXS_PIN_TO_GPIO(PINID_SSP0_DATA4)
    
    #define GPIO_4      MXS_PIN_TO_GPIO(PINID_SSP0_DATA5)
    
    #define GPIO_5      MXS_PIN_TO_GPIO(PINID_SSP0_DATA6)
    
    struct input_dev  *inputdev;
    
    struct imx28x_key_struct 
    {
    
        int key_code;                      /* 按键能产生的键值*/
    
        int gpio;                          /* 按键连接的GPIO*/
    
        struct work_struct work;                       /* 按键的工作队列*/
    
    };
    
    struct imx28x_key_struct keys_list[] ={
    
        {.key_code = KEY_A, .gpio = GPIO_1},
    
        {.key_code = KEY_B, .gpio = GPIO_2},
    
        {.key_code = KEY_C, .gpio = GPIO_3},
    
        {.key_code = KEY_D, .gpio = GPIO_4},
    
        {.key_code = KEY_E, .gpio = GPIO_5}
    };
    
    
    static void imx28x_scankeypad(struct work_struct *_work){
    
            struct imx28x_key_struct *key_tmp = container_of(_work, struct imx28x_key_struct, work);
    
            int gpio = key_tmp->gpio;
    
        int code= key_tmp->key_code; 
    
        while(!gpio_get_value(gpio)){
    
            mdelay(10);
    
        }
    
        input_report_key(inputdev, code, 0); 
    
        input_sync(inputdev);
    
    }
    
    
    static irqreturn_t imx28x_key_intnerrupt(int irq, void *dev_id){
    
        int i  = (int)dev_id;
    
        int gpio = keys_list[i].gpio;/* 获取按键的GPIO*/
    
        int code = keys_list[i].key_code;
    
        udelay(5);
    
        if (gpio_get_value(gpio)) {
    
            return IRQ_HANDLED;
    
        }
    
        input_report_key(inputdev, code, 1);/* 先报告键按下事件*/
    
        input_sync(inputdev);
    
        schedule_work(&(keys_list[i].work));/* 提交工作队列,实现中断的下半部处理*/
    
        printk("key down \n");  
    
    
    
        //return IRQ_RETVAL(IRQ_HANDLED);
    
           return IRQ_HANDLED;
    
    }
    
    static void __exit iMX28x_key_exit(void){
    
        int i = 0;
    
        int irq_no;
    
        for (i = 0; i < sizeof(keys_list)/sizeof(keys_list[0]); i++) {
    
        irq_no = gpio_to_irq(keys_list[i].gpio);/* 为每个按键释放GPIO*/
    
        free_irq(irq_no, (void *)i);    
    
        input_unregister_device(inputdev);  
    
        printk("EasyARM-i.MX28x key driver remove \n");
    
           }
    
    }
    
    static int __devinit iMX28x_key_init(void)
    
    {
    
        int i = 0, ret = 0;
    
        int irq_no = 0; 
    
        int code, gpio;
    
        inputdev = input_allocate_device(); /* 为输入设备驱动对象申请内存空间*/
    
        if (!inputdev) {
    
            return -ENOMEM;
    
             }
    
        inputdev->name  = "EasyARM-i.MX28x_key";
    
        set_bit(EV_KEY, inputdev->evbit);   /* 设置输入设备支持按键事件*/
    
        for (i = 0; i < sizeof(keys_list)/sizeof(keys_list[0]); i++) {
    
            code = keys_list[i].key_code;
    
            gpio = keys_list[i].gpio; 
    
            INIT_WORK(&(keys_list[i].work), imx28x_scankeypad);
    
            set_bit(code, inputdev->keybit); 
    
            gpio_free(gpio);
    
            ret = gpio_request(gpio, "key_gpio");
    
            if (ret) {
    
                printk("request gpio failed %d \n", gpio);
    
                return -EBUSY;
    
            } 
    
            gpio_direction_input(gpio); 
    
            irq_no  = gpio_to_irq(gpio);
    
            set_irq_type(gpio, IRQF_TRIGGER_FALLING);    
    
            ret = request_irq(irq_no, imx28x_key_intnerrupt, IRQF_DISABLED, "imx28x_key", (void *)i);
    
            if(ret){
    
                printk("request irq faile  %d!\n", irq_no);
    
                return -EBUSY;
    
            }
    
        }
    
        input_register_device(inputdev);/* 注册设备驱动*/
    
        printk("EasyARM-i.MX28x key driver up \n");
    
        return 0;
    
    }
    
    module_init(iMX28x_key_init);
    
    module_exit(iMX28x_key_exit);
    
    MODULE_AUTHOR("EasyARM28xx By jiaochengliang");
    
    MODULE_LICENSE("Dual BSD/GPL");
    
    MODULE_DESCRIPTION("gpio button interrupt module");
    
    
    
    

    编写Makefile

    PWD:=$(shell pwd)
    obj-m:=imx_key.o
    module-objs := imx_key.o
    KERNEL_SRC = /usr/src/linux-2.6.35.3/
    KDIR:=$(KERNEL_SRC)
    all:
        $(MAKE) -C $(KDIR) M=$(PWD) modules
    clean:
        rm -rf *.ko *.order *.symvers *.cmd *.o *.mod.c *.tmp_versions .*.cmd .tmp_versions

    make一下,生成的 .ko文件挂载到板子上

    insmod imx_key.ko

    测试下,输出
    这里写图片描述

    这里的问题:1、按键去抖用延时
    2、处理事件在中断中
    3、就是在卸载模块后,个别按键还在作用中

    展开全文
  • 本文记录在IMX6开发板上移植鼎芯Linux3.0.35内核时,需要配置的矩阵按键的信息。本设备使用的矩阵按键是一个5*5的矩阵按键。 本人其他开发板内核的移植与分析请点击链接查看: jz2440开发板相关与IMX6开发板相关 1、...

    学习交流加

    • 个人qq:
      1126137994
    • 个人微信:
      liu1126137994
    • 学习交流资源分享qq群:
      962535112

    本文记录在IMX6开发板上移植鼎芯Linux3.0.35内核时,需要配置的矩阵按键的信息。本设备使用的矩阵按键是一个5*5的矩阵按键。

    本人其他开发板内核的移植与分析请点击链接查看: jz2440开发板相关IMX6开发板相关

    1、IMX6移植3.0.35内核时需要配置的按键的信息

    首先我们要知道我们的按键接的核心板的引脚都有哪些:

    在这里插入图片描述

    3.0.35内核中使用的矩阵按键驱动源码在”drivers/input/keyboard/matrix_keypad.c”中。

    里面是一个平台驱动,我们只要写平台设备,描述硬件的资源与此驱动匹配即可。

    驱动中有代码如下:

    488 static struct platform_driver matrix_keypad_driver = {
    489     .probe      = matrix_keypad_probe,
    490     .remove     = __devexit_p(matrix_keypad_remove),
    491     .driver     = {
    492         .name   = "matrix-keypad",
    493         .owner  = THIS_MODULE,
    494 #ifdef CONFIG_PM
    495         .pm = &matrix_keypad_pm_ops,
    496 #endif
    497     },
    498 };
    499 module_platform_driver(matrix_keypad_driver);
    

    通过阅读平台驱动的probe函数,可得知我们写的平台设备应提供具本哪些硬件信息.

    378 static int __devinit matrix_keypad_probe(struct platform_device *pdev)
    379 {
    380     const struct matrix_keypad_platform_data *pdata; //平台设备提供的platform_data
    381     const struct matrix_keymap_data *keymap_data;
    382     struct matrix_keypad *keypad;
    383     struct input_dev *input_dev;
    384     unsigned short *keycodes;
    385     unsigned int row_shift;
    386     int err;
    
    388     pdata = pdev->dev.platform_data;
        ... .....
    394     keymap_data = pdata->keymap_data;
    
        ... .....
    433     matrix_keypad_build_keymap(keymap_data, row_shift,
    434                    input_dev->keycode, input_dev->keybit); //从keymap_data里分解出行列键对应的键码
        ... .....
    439     err = init_matrix_gpio(pdev, keypad); //注册行线的中断号
        ... .....
    443     err = input_register_device(keypad->input_dev); //输入设备对象注册
        ... .....
    456     return err;
    457 }
    

    通过probe函数,可以确定我们写平台设备时只需通过platform_data成员提供平台驱动所需的信息,无需再提供resource.

    再确定结构体matrix_keypad_platform_data的每个成员的作用即可,如不清楚具体用途,可以在驱动代码里通过查看对成员值的访问反推出用途.

    在"include/linux/input/matrix_keypad.h"中有

    #define KEY(row, col, val)  ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\
                     (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\
                     ((val) & 0xffff))
    .....
    #define KEY_ROW(k)      (((k) >> 24) & 0xff)
    #define KEY_COL(k)      (((k) >> 16) & 0xff)
    #define KEY_VAL(k)      ((k) & 0xffff)
    .....
    .....
    #define MATRIX_SCAN_CODE(row, col, row_shift)   (((row) << (row_shift)) + (col))
    
    
    ......
    ......
    struct matrix_keymap_data {
        const uint32_t *keymap; //装载按键对应的键码数组, 注意每个键码需要使用宏KEY来写。也就是一个32位数据里,行,列,键码各占用8, 8, 16位.
        unsigned int    keymap_size; //键码数组的元素个数
    };
    ......
    ......
    struct matrix_keypad_platform_data {
        const struct matrix_keymap_data *keymap_data; //键码数据对象的首地址
    
        const unsigned int *row_gpios; //行线用的IO口
        const unsigned int *col_gpios; //列线用的IO口
    
        unsigned int    num_row_gpios; //多少个行线
        unsigned int    num_col_gpios; //多少个列线
    
        unsigned int    col_scan_delay_us; //扫描列线时间隔时间
    
        unsigned int    debounce_ms; //防抖动的间隔时间
    
        unsigned int    clustered_irq; //行线是否共用一个中断, 设0则每个行线的中断是独立的
        unsigned int    clustered_irq_flags;
    
        bool        active_low; //键按下时,行线是否为低电平
        bool        wakeup;
        bool        no_autorepeat; //按键按下时是否重复提交按键, 设1就是不重复,设0重复
    };
    
    

    根据我们的原理图:

    行线接: KEY_ROW0, KEY_ROW1, KEY_ROW2, KEY_ROW4,KEY_ROW5
    列线接: KEY_ROW0, KEY_ROW1, KEY_ROW2, KEY_ROW4,KEY_ROW5

    2、添加设备信息的具体步骤

    Imx_keypad平台层函数的添加

    1. 在board-mx6q_sabresd.c中添加
    //注意键值,可以根据自己项目的需求自己更改
    static int mx6_sabresd_keymap[] = {
    		   KEY(0, 0, KEY_UP),
    		   KEY(0, 1, KEY_F9),
    		   KEY(0, 2, KEY_F3),
    		   KEY(0, 4, KEY_DOWN),
    		   KEY(0, 5, KEY_PRINT),
    	
    	
    		   KEY(1, 0, KEY_RIGHT),
    		   KEY(1, 1, KEY_F8),
    		   KEY(1, 2, KEY_F4),
    		   KEY(1, 4, KEY_HOME),
    		   KEY(1, 5, KEY_PAGEDOWN),
    	
    	
    		   KEY(2, 0, KEY_F12),
    		   KEY(2, 1, KEY_F7),
    		   KEY(2, 2, KEY_F5),
    		   KEY(2, 4, KEY_END),
    		   KEY(2, 5, KEY_PAGEUP),
    	
    	
    		   KEY(4, 0, KEY_F11),
    		   KEY(4, 1, KEY_F1),
    		   KEY(4, 2, KEY_F6),
    		   KEY(4, 4, KEY_NUMLOCK),
    		   KEY(4, 5, KEY_ESC),
    	
    	
    		   KEY(5, 0, KEY_F10),
    		   KEY(5, 1, KEY_F2),
    		   KEY(5, 2, KEY_LEFT),
    		   KEY(5, 4, KEY_SCROLLLOCK),
    		   KEY(5, 5, KEY_PAUSE),
    	
    };
    
    static const struct matrix_keymap_data mx6_sabresd_map_data __initconst= {
    	.keymap		= mx6_sabresd_keymap,
    	.keymap_size	= ARRAY_SIZE(mx6_sabresd_keymap),
    };
    
    
    1. 在mx6_sabresd_board_init函数中添加:
    imx6q_add_imx_keypad(&mx6_sabresd_map_data);   //KEYBOARD 
    

    这个函数是在Platfprm-imx-keypad.c定义的,需要在Devices-imx6q.h中添加宏定义:

    extern const struct imx_imx_keypad_data imx6q_imx_keypad_data ;  //lyy 
    #define imx6q_add_imx_keypad(pdata)   \
    	imx_add_imx_keypad(&imx6q_imx_keypad_data,pdata);
    
    1. 在Platfprm-imx-keypad.c中添加:
    //lyy
    #ifdef CONFIG_SOC_IMX6Q
    const struct imx_imx_keypad_data imx6q_imx_keypad_data __initconst =
    	imx_imx_keypad_data_entry_single(MX6SL, SZ_16);
    #endif /* ifdef CONFIG_SOC_IMX6Q */
    
    1. 在Board-mx6_sabresd.h中添加并将所有复用引脚注释掉

    有可能有其它设备复用了下面这些引脚,一定要先将他们注释掉

    /* keyboaed lyy */
    	MX6Q_PAD_KEY_COL0__KPP_COL_0,
       	MX6Q_PAD_KEY_ROW0__KPP_ROW_0,
       	MX6Q_PAD_KEY_COL1__KPP_COL_1,
       	MX6Q_PAD_KEY_ROW1__KPP_ROW_1,
       	MX6Q_PAD_KEY_COL2__KPP_COL_2,
       	MX6Q_PAD_KEY_ROW2__KPP_ROW_2,
        MX6Q_PAD_KEY_COL4__KPP_COL_4,
        MX6Q_PAD_KEY_ROW4__KPP_ROW_4,
        MX6Q_PAD_CSI0_DAT4__KPP_COL_5,
        MX6Q_PAD_CSI0_DAT5__KPP_ROW_5,
    
    1. 在arch\arm\mach-mx6\Clock.c中的lookups[]中加入:
    static struct clk_lookup lookups[] = {
    。。。。。。。
    。。。。。。。
    _REGISTER_CLOCK(NULL, "kpp", dummy_clk),  //这是加入的
    }

    3、测试

    重新编译内核后,烧写到开发板,然后测试按键是否可以正常使用:

    首先在板子启动后,在板子的终端输入;

    $ cat /proc/bus/input/devices
    

    查看当前的设备,找到我们的按键设备,假设为evet0。

    则在终端中输入

    $ hexdump /dev/input/event0
    

    所有按键都按一遍,会发现终端中打印了按键的值(显示的内容好像是某一种编码,不知道怎么转换为按键的值)

    4、总结

    已经转行做互联网了,现在把实验室相关的事做一下,之前没补完的博客补一下,以后可能就不写嵌入式相关的内容了。当然,还会写关于Linux内核的相关知识。

    做嵌入式,如果做的不深,如果不是去深度定制Linux内核,或者深度开发驱动,其实就没什么可做的了。希望看到这里的朋友,加油,不管在做什么,不要放弃,下一步就会成功!!!

    学习探讨加:
    qq:1126137994
    微信:liu1126137994

    展开全文
  • 这里整理一下按键的通用版本,也就大家都用的按键处理版本,结构比较清晰: 直接上代码: five_buttons.c /* GPIO Driver driver for EasyARM-iMX283 AUTHOR:JIAOCHENGLIANG */ #include &amp;lt;linux...
  • 本篇文章记录在IMX6开发板移植4.1.15内核时,添加矩阵按键的设备树信息。 1、具体添加的设备树信息 下面是我们的开发板中按键与核心板的引脚链接情况: 具体的驱动程序的分析可以查看之前移植3.0.35内核时的相关...
  • 说明:本来想尝试做一个红外按键控制QT界面控件选中的,因为windows中pushbutton有三种状态,一种是常态,一种是光标停靠态还有一种是停靠态,想的是通过移动光标使pushbutton处于光标停靠状态来表示pushbutton被...
  • imx6ul 7之按键输入

    2020-09-08 02:19:21
    按键key0接到了UART1_CTS , 默认情况下KEY0为高,当按下KEY0之后,UART1_CTS 为低 二、sw 1、设置UART1_CTS复用为GPIO1_IO18 2、设置UART1_CTS的电气属性 3、配置GPIO1_IO18为输入模式 4、读取按键值也就是GPIO1_IO...
  • android系统移植之iMX53按键驱动篇 .

    千次阅读 2014-06-18 07:00:35
    MX53_QSB开发板上一起有四个按键,分别为RESET,POWER,USER1,USER2。其中RESET为纯硬件复位按键,无须软件控制。POWER,USER1,USER2三个按键均需要程序控制。默认BSP包中将三个按钮全设置为上升和下
  • android系统移植之iMX53按键驱动篇

    千次阅读 2014-05-23 22:17:33
    前者用于多按键的情况,如果按键比较少,后者就可以了,一般情况下,android系统只需几个按键就可以了,所以大多数情况下,都是使用的gpio_keys.c。下面我们将详细分析该驱动的工作流程。 在module_init函数中,...
  • IMX6UL上添加支持矩阵按键

    热门讨论 2019-11-28 15:42:43
    一般按键驱动有两种,一种是矩阵键盘驱动,一个是GPIO接口键盘驱动 矩阵键盘路径:drivers/input/keyboard/matrix_keypad.c(一般用于多...这里使用的平台和内核版本是TQIMX6UL+Linux-4.1.4 1、使用内核自带矩阵键盘...
  • 需要注意的是一定要设置input_set_capability(imx6uirq.inputdev, EV_KEY, key_value[4]);这个代表输入子系统会上报的按键事件, 如果没有设置这个. 那么上报的按键是无效的 #include <linux/t..
  • 按键控制程序代码(主要学会看数据手册): 裸机程序控制外设 include “common.h” //包含SDK的两个头文件 /按键初始化函数/ void button_init(void) { /(1)按键初始化 使能时钟/ CCM->CCGR1 = 0xffffffff; ...
  • 项目上需要多个按键输入, 因此记录一下多个按键的中断如何做 2 修改设备树 pinctrl_gpio_keys: gpio-keys { fsl,pins = < MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x80000000 /* KEY1 */ MX6ULL...
  • PAD_SD3_DAT1__SD3_DATA1 0x2c4 0x6ac 0x000 0x5 0x0 2、打开文件 linux-4.1.15/arch/arm/boot/dts/imx6qdl-sabresd.dtsi 搜索 gpio-keys 添加 key-zero、key-one gpio-keys { compatible = "gpio-keys";...
  • 通过按键控制灯的亮灭,并通过网络编程把按键的状态传到外界,驱动代码运用到了中断,还有唤醒与休眠机制,当没有数据产生时,app会进入到休眠状态,直到按键产生了数据,这个时候就会唤醒app。可减少cpu的工作效率 ...
  • IMX6Q核心板 IMX6DL核心板 Freescale Cortex-A9 四核 i.MX6Q, Freescale Cortex-A9 双核精简版 i.MX6DL, 主频 1.2 GHz 主频 1.2 GHz 内存:2G 内存:1G ...
  • IMX6UL开发板

    千次阅读 2018-06-08 15:43:26
    迅为iMX6UL开发板采用核心板加底板形式,核心板使用邮票孔方式连接,牢固耐用。处理器ARM®Cortex®-A7内核,运行速度高达528 MHz。512MDDR内存,8G EMMC存储,板截双网口,双路CAN总线,4路USB HOST,8路串口。可在...
  • iMX6ULL上手体验

    万次阅读 2019-05-07 08:50:49
    CSDN仅用于增加百度收录权重,排版未优化,日常不维护。... 本博文对应地址: https://hceng.cn/2018/03/28/iMX6ULL上手体验/#more ...iMX6ULL感觉还是很有优势的,除了之前接触的NanoPi(全志H3),就没见过几个运行Li...
  • 本人最近在学习正点原子的imx6ull板子的教程视频,在学习到用EPIT1定时器来对按键消抖的实验的时候,代码什么的和例程完全一样,操作什么的也是一样,但是按下按键之后,蜂鸣器应该发出声音,再按一次停止鸣叫,但是...
  • 自己总结的imx6q驱动代码,基于platform框架,驱动GPIO按键,使用飞凌的板子
  • 基于IMX6的GPIO驱动程序

    万次阅读 2016-12-28 13:46:16
    Linux内核版本:linux-3.0.35 开发板: IMX6S MY-IMX6-EK200 编译环境:Ubuntu12 主要内容:IMX6S的IO驱动程序编写(ioctl) 实现功能:通过应用层程序控制底层IO的读写操作。一、驱动层

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,298
精华内容 519
关键字:

imx6按键