zoukankan      html  css  js  c++  java
  • Learn ZYNQ Programming(1)

    GPIO LED AND KEY:

    part1:gpio leds and gpio btns combination. (include 1~4)

    part2:use gpio btns interrupt to trigger led on and off. (include 5, 6, 7)

    part3:some useful tips. (include 8)

    my vivado & sdk projects ( ready to download):

    1.custom_ip ( only led exists)

    2.custom_ip ( led with key)

    3.custom_ip (led key and interrupts)

    my driver package ( ready to download):

    gpio_driver.tar.bz2

    (1)Block Design:

    Screenshot from 2014-05-15 14_56_47

    (2)Constraints:

    set_property PACKAGE_PIN T22 [get_ports {leds_8bits_tri_o[0]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[0]}]
    
    set_property PACKAGE_PIN T21 [get_ports {leds_8bits_tri_o[1]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[1]}]
    
    set_property PACKAGE_PIN U22 [get_ports {leds_8bits_tri_o[2]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[2]}]
    
    set_property PACKAGE_PIN U21 [get_ports {leds_8bits_tri_o[3]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[3]}]
    
    set_property PACKAGE_PIN V22 [get_ports {leds_8bits_tri_o[4]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[4]}]
    
    set_property PACKAGE_PIN W22 [get_ports {leds_8bits_tri_o[5]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[5]}]
    
    set_property PACKAGE_PIN U19 [get_ports {leds_8bits_tri_o[6]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[6]}]
    
    set_property PACKAGE_PIN U14 [get_ports {leds_8bits_tri_o[7]}]
    set_property IOSTANDARD LVCMOS33 [get_ports {leds_8bits_tri_o[7]}]
    
    
    
    set_property PACKAGE_PIN P16 [get_ports {btns_5bits_tri_i[0]}]
    set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[0]}]
    
    set_property PACKAGE_PIN N15 [get_ports {btns_5bits_tri_i[2]}]
    set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[2]}]
    
    set_property PACKAGE_PIN T18 [get_ports {btns_5bits_tri_i[4]}]
    set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[4]}]
    
    set_property PACKAGE_PIN R18 [get_ports {btns_5bits_tri_i[3]}]
    set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[3]}]
    
    set_property PACKAGE_PIN R16 [get_ports {btns_5bits_tri_i[1]}]
    set_property IOSTANDARD LVCMOS25 [get_ports {btns_5bits_tri_i[1]}]

    (3) Standalone Program

    #include <stdio.h>
    #include "platform.h"
    #include "xil_io.h"
    #include "xgpio.h"
    #include "xparameters.h"
    
    
    //void print(char *str);
    
    int main()
    {
        init_platform();
    
        print("Hello World
    
    ");
    
        u32 btn_data;
        //XGpio
        //btn_data = Xil_In32(0x41200000);
          //      printf("data is xxx %d
    ",btn_data);
        Xil_Out32(0x41200000 , 0x08);
        sleep(1);
        //Xil_Out32(0x41200000 , 0x00);
        while(1){
            //Xil_Out32(0x41210000 , 0x00000000);
            btn_data = Xil_In32(0x41210000);
            //if(btn_data & 0x01){
                //Xil_Out32(0x41210000 , 0x01);
            sleep(1);
            printf("data is %ld
    ",btn_data);
            //}
            /*if(btn_data & 0x00000001)
                Xil_Out32(0x41200000 , 0x01);
            if(btn_data & 0x00000002)
                Xil_Out32(0x41200000 , 0x02);
            if(btn_data & 0x00000004)
                Xil_Out32(0x41200000 , 0x04);
            if(btn_data & 0x00000008)
                Xil_Out32(0x41200000 , 0x08);
                */
        }
        //sleep(1);
    
        return 0;
    }

    (4) Linux Driver:

    #include <linux/module.h>
    #include <linux/version.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/fs.h>
    #include <linux/cdev.h>
    #include <linux/delay.h>
    #include <linux/spinlock.h>
    #include <linux/device.h>
    #include <linux/types.h>
    #include <linux/ioctl.h>
    
    #include <asm/io.h>
    #include <asm/uaccess.h>
    #include <asm/atomic.h>
    #include <linux/wait.h>
    #include <linux/cdev.h>
    
    #define DEVICE_NAME "gpio_dev"
    #define LED_PHY_ADDR 0x41200000
    #define KEY_PHY_ADDR 0X41210000
    
    /*
    #define ULTRASONIC_IOC_MAGIC 'Z'
    
    #define LED_SHUTDOWN _IOR(ULTRASONIC_IOC_MAGIC, 0, int)
    #define LED_OPEN _IOR(ULTRASONIC_IOC_MAGIC, 1, int)
    #define GET_KEY_STATUS _IOR(ULTRASONIC_IOC_MAGIC, 2, int)
    */
    
    
    static unsigned long led_addr = 0;
    static unsigned long key_addr = 0;
    
    static struct class* gpio_class = NULL;
    static struct device* gpio_device = NULL;
    
    static int gpio_major = 0;
    
    //arg means the led number, cmd controls it on or off
    static ssize_t gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    {
            //printk("fun(gpio_ioctl):");
            u32 status = 0xff;
            int ret;
            switch(cmd){
                    case 0:
                    case 1:
                            //if(arg > 8)
                            //      return -EINVAL;
                            status = ioread32(led_addr);
                            if(0 == cmd)
                                    status &=  ~(0x1 << arg);
                            else if(1 == cmd)
                                    status |= (0x1 << arg);
                            iowrite32(status,led_addr);
                            //printk("debug1 cmd= %d
    ",cmd);
                            return 0;
                    case 3:
                            //printk("debug3 cmd=%d
    ",cmd);
                            status = ioread32(key_addr);
                            ret = __put_user(status, (u32 *)arg);
                            printk("key print = 0x%x
    ",status);
                            return 0;
                    default:
                            printk("default cmd=%d
    ",cmd);
                            return -EINVAL;
            }
    }
    
    /*
    static ssize_t key_read(struct file *file,u32  __user *buf, size_t count, loff_t *ppos)
    {
            u32 data;
            int ret = 0;
            data = ioread32(key_addr);
            ret = __put_user(data, (u32 *)buf);
            printk("key print = 0x%x
    ",data);
            return (sizeof(u32));
    }
    */
    static struct file_operations gpio_fops = {
            .owner = THIS_MODULE,
            .unlocked_ioctl = gpio_ioctl,
    //      .read = key_read,
    };
    
    static int __init gpio_init(void)
    {
            int ret;
    
            printk("debug0");
            ret = register_chrdev(0,DEVICE_NAME, &gpio_fops);
            if(ret < 0)
            {
                    printk("gpio: can't get major number
    ");
                    return ret;
            }
    
            printk("debug1");
            gpio_major = ret;
            gpio_class = class_create(THIS_MODULE, "gpio_class");
            if(IS_ERR(gpio_class))
            {
                    printk("gpio: failed in creating class
    ");
                    unregister_chrdev(gpio_major, DEVICE_NAME);
                    return -1;
            }
    
            printk("debug2");
    
            gpio_device = device_create(gpio_class,NULL,MKDEV(gpio_major,0),NULL,DEVICE_NAME);
            if(IS_ERR(gpio_device))
            {
                    printk("gpio: failed in creating device!
    ");
                    unregister_chrdev(gpio_major, DEVICE_NAME);
                    class_unregister(gpio_class);
                    class_destroy(gpio_class);
                    return -1;
            }
    
            led_addr = (unsigned long) ioremap(LED_PHY_ADDR, sizeof(u32));
            key_addr = (unsigned long) ioremap(KEY_PHY_ADDR, sizeof(u32));
    /*     
            iowrite32(0x00,led_addr);
            mdelay(100);
            iowrite32(0xff,led_addr);
    */
            printk("gpio installed successfully!");
            return 0;
    }
    
    
    static void __exit gpio_exit(void)
    {
    /*
            iowrite32(0x00,led_addr);
            mdelay(100);           
            iowrite32(0xff,led_addr);
    */
            device_destroy(gpio_class,MKDEV(gpio_major, 0));
            class_unregister(gpio_class);
            class_destroy(gpio_class);
            unregister_chrdev(gpio_major,DEVICE_NAME);
            printk("gpio module exit!");
    }
    
    module_init(gpio_init);
    module_exit(gpio_exit);
    
    
    MODULE_AUTHOR("seg");
    MODULE_LICENSE("GPL");
                                                                                                                                                                    

    (5) Linux App:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/ioctl.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/select.h>
    #include <sys/time.h>
    
    static int led_fd;
    
    int main(void)
    {
            int i;
            // open device
            led_fd = open("/dev/gpio_dev", 0);
            if (led_fd < 0) {
                    perror("open device gpio_dev error!
    ");
                    exit(1);
            }
    
            printf("Please look at the leds
    ");
    
            // led all off
            ioctl(led_fd, 1, 0);
            ioctl(led_fd, 1, 1);
            ioctl(led_fd, 1, 2);
            ioctl(led_fd, 1, 3);
    
            ioctl(led_fd, 1, 4);
            ioctl(led_fd, 1, 5);
            ioctl(led_fd, 1, 6);
            ioctl(led_fd, 1, 7);
            for(i=0;i<2;i++)
            {
                    ioctl(led_fd, 0, 0);
                    usleep(50000);
                    ioctl(led_fd, 0, 1);
                    usleep(50000);
                    ioctl(led_fd, 0, 2);
                    usleep(50000);
                    ioctl(led_fd, 0, 3);
                    usleep(50000);
    
                    ioctl(led_fd, 0, 4);
                    usleep(50000);
                    ioctl(led_fd, 0, 5);
                    usleep(50000);
                    ioctl(led_fd, 0, 6);
                    usleep(50000);
                    ioctl(led_fd, 0, 7);
                    usleep(50000);
                    // led off one by one
                    ioctl(led_fd, 1, 0);
                    usleep(50000);
                    ioctl(led_fd, 1, 1);
                    usleep(50000);
                    ioctl(led_fd, 1, 2);
                    usleep(50000);
                    ioctl(led_fd, 1, 3);
                    usleep(50000);
                    ioctl(led_fd, 1, 4);
                    usleep(50000);
                    ioctl(led_fd, 1, 5);
                    usleep(50000);
                    ioctl(led_fd, 1, 6);
                    usleep(50000);
                    ioctl(led_fd, 1, 7);
                    usleep(50000);
            }
    
            while(1)
            {
                    unsigned int key = 0;
                    //printf("original = %d , %x",key,key);
                    ioctl(led_fd, 3, &key);
                    printf("key = %d
    ",key);
                    for(i=0;i<8;i++)
                            ioctl(led_fd,0,i);
                    if(key & (0x01<<0))
                            ioctl(led_fd, 1, 0);
                    else if(key & (0x01<<1))
                            ioctl(led_fd, 1, 1);
                    else if(key & (0x01<<2))
                            ioctl(led_fd, 1, 2);
                    else if(key & (0x01<<3))
                            ioctl(led_fd, 1, 3);
                    else if(key & (0x01<<4))
                            ioctl(led_fd, 1, 4);
                    else{}
    
    
                    usleep(1000000);
            }
    
            close(led_fd);
            return 0;
    }

    (5)Hardware Interrupt Vivado Project

     Screenshot Screenshot from3Screenshot from2  Screenshot from4

    (6)Hardware Interrupt SDK Project

    #include "xparameters.h"
    #include "xgpio.h"
    #include "xil_exception.h"
    
    #include "xscugic.h"
    
    
    /************************** Constant Definitions *****************************/
    
    #define LED_ADDR 0x41200000
    #define KEY_ADDR 0X41210000
    
    
    #define GPIO_DEVICE_ID        XPAR_AXI_GPIO_1_DEVICE_ID
    #define INTC_GPIO_INTERRUPT_ID    XPAR_FABRIC_GPIO_1_VEC_ID
    
    
     #define INTC_DEVICE_ID    XPAR_SCUGIC_0_DEVICE_ID
     #define INTC        XScuGic
     #define INTC_HANDLER    XScuGic_InterruptHandler
    
    
    
    #define GPIO_ALL_LEDS        0xFFFF
    #define GPIO_ALL_BUTTONS    0xFFFF
    
    /*
     * The following constants define the GPIO channel that is used for the buttons
     * and the LEDs. They allow the channels to be reversed easily.
     */
    #define BUTTON_CHANNEL     1    /* Channel 1 of the GPIO Device */
    #define LED_CHANNEL     2    /* Channel 2 of the GPIO Device */
    #define BUTTON_INTERRUPT XGPIO_IR_CH1_MASK  /* Channel 1 Interrupt Mask */
    
    
    /*
     * The following constant is used to wait after an LED is turned on to make
     * sure that it is visible to the human eye.  This constant might need to be
     * tuned for faster or slower processor speeds.
     */
    #define LED_DELAY     1000000
    
    /**************************** Type Definitions *******************************/
    
    typedef struct
    {
        u32 ButtonMask;     /* The bit corresponding to the button */
        u32 LedMask;     /* The bit corresponding to the LED */
    } MapButtonTable;
    
    
    /************************** Function Prototypes ******************************/
    
    int MapButton2Led(u32 Buttons, u32 *ButtonFoundPtr);
    
    void SequenceLeds();
    
    void GpioIsr(void *InstancePtr);
    
    int SetupInterruptSystem();
    
    /************************** Variable Definitions *****************************/
    
    static XGpio Gpio; /* The Instance of the GPIO Driver */
    
    static INTC Intc; /* The Instance of the Interrupt Controller Driver */
    
    volatile int InterruptCount; /* Count of interrupts that have occured */
    
    int main(void)
    {
        int Status;
    
    
    
        SequenceLeds();
    
    
    
        /* Initialize the GPIO driver. If an error occurs then exit */
    
        Status = XGpio_Initialize(&Gpio, GPIO_DEVICE_ID);
        if (Status != XST_SUCCESS) {
            return XST_FAILURE;
        }
    
        /*
         * Perform a self-test on the GPIO.  This is a minimal test and only
         * verifies that there is not any bus error when reading the data
         * register
         */
        XGpio_SelfTest(&Gpio);
    
    
    
        /*
         * Setup the interrupts such that interrupt processing can occur. If
         * an error occurs then exit
         */
        Status = SetupInterruptSystem();
        if (Status != XST_SUCCESS) {
            return XST_FAILURE;
        }
    
        printf("in the loop:
    ");
        while (1) {
        }
    
        return XST_SUCCESS;
    }
    
    
    void SequenceLeds()
    {
        u32 led = 0x01;
        u32 out = 0x0;
        int i;
    
        for (i = 0; i < 8; i++) {
    
            out = led << i;
    
            Xil_Out32(LED_ADDR, out);
    
            sleep(1);
        }
    
        Xil_Out32(LED_ADDR, 0x00);
    }
    
    
    /********************************************************************************************************************************************************/
    void GpioIsr(void *InstancePtr)
    {
        XGpio *GpioPtr = (XGpio *)InstancePtr;
        u32 Led;
        u32 LedState;
        u32 Buttons;
        u32 ButtonFound;
        u32 ButtonsChanged = 0;
        static u32 PreviousButtons;
    
        printf("Enter GpioIsr!
    ");
    
        /*
         * Disable the interrupt
         */
        XGpio_InterruptDisable(GpioPtr, BUTTON_INTERRUPT);
    
        /* Keep track of the number of interrupts that occur */
    
        InterruptCount++;
    
        Xil_Out32(LED_ADDR,0x00);
    
        ButtonsChanged = Xil_In32(KEY_ADDR);
        printf("BUTTON:%d;",ButtonsChanged);
    
        //while (ButtonsChanged != 0) {
            /*
             * Determine which button changed state and then get
             * the current state of the associated LED
             */
    
             printf("SET_LED=%d",ButtonsChanged);
             Xil_Out32(LED_ADDR,ButtonsChanged);
    //         LedState = Xil_In32(LED_ADDR) & Led;
    
             /*
              * Clear the button that is being processed so that it is
              * done and others can be handled also
              */
    //         ButtonsChanged &= ~ButtonFound;
    
             /* Toggle the state of the LED */
    //         if (LedState) {
    //             Xil_Out32(LED_ADDR,LedState & ~Led);
    //         } else {
    //             Xil_Out32(LED_ADDR,Led);
    //         }
    //     }
    
         /* Clear the interrupt such that it is no longer pending in the GPIO */
    
         (void)XGpio_InterruptClear(GpioPtr, BUTTON_INTERRUPT);
    
         /*
          * Enable the interrupt
          */
         XGpio_InterruptEnable(GpioPtr, BUTTON_INTERRUPT);
    
    }
    
    
    int SetupInterruptSystem()
    {
        int Result;
        INTC *IntcInstancePtr = &Intc;
    
        XScuGic_Config *IntcConfig;
    
        /*
         * Initialize the interrupt controller driver so that it is ready to
         * use.
         */
        IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
        if (NULL == IntcConfig) {
            return XST_FAILURE;
        }
    
        Result = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
                        IntcConfig->CpuBaseAddress);
        if (Result != XST_SUCCESS) {
            return XST_FAILURE;
        }
    
        XScuGic_SetPriorityTriggerType(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID,
                        0xA0, 0x3);
    
        /*
         * Connect the interrupt handler that will be called when an
         * interrupt occurs for the device.
         */
    
    
        Result = XScuGic_Connect(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID,
                     (Xil_ExceptionHandler)GpioIsr, &Gpio);
        if (Result != XST_SUCCESS) {
            return Result;
        }
        printf("XST_SUCCESS");
        /*
         * Enable the interrupt for the GPIO device.
         */
        XScuGic_Enable(IntcInstancePtr, INTC_GPIO_INTERRUPT_ID);
    
    
        /*
         * Enable the GPIO channel interrupts so that push button can be
         * detected and enable interrupts for the GPIO device
         */
        XGpio_InterruptEnable(&Gpio, BUTTON_INTERRUPT);
        XGpio_InterruptGlobalEnable(&Gpio);
    
        /*
         * Initialize the exception table and register the interrupt
         * controller handler with the exception table
         */
        Xil_ExceptionInit();
    
        Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
                 (Xil_ExceptionHandler)INTC_HANDLER, IntcInstancePtr);
    
        /* Enable non-critical exceptions */
        Xil_ExceptionEnable();
    
        return XST_SUCCESS;
    }

    (7) Interrupt driver edition

    #include <linux/module.h>
    #include <linux/version.h>
    #include <linux/kernel.h>
    #include <linux/init.h>
    #include <linux/fs.h>
    #include <linux/cdev.h>
    #include <linux/delay.h>
    #include <linux/spinlock.h>
    #include <linux/device.h>
    #include <linux/types.h>
    #include <linux/ioctl.h>
    
    #include <asm/io.h>
    #include <asm/uaccess.h>
    #include <asm/atomic.h>
    #include <linux/wait.h>
    #include <linux/cdev.h>
    
    #include <linux/interrupt.h>
    #include <asm/signal.h>
    #include <linux/gpio.h>
    #include <linux/irq.h>
    
    #define DEVICE_NAME "gpio_dev"
    #define GPIO_BASEADDR 0x41200000
    #define LED_PHY_ADDR 0x41200000
    #define KEY_PHY_ADDR 0X41210000
    #define INTERRUPT_ID 91
    
    #define IRQ_MASK 0x1
    
    #define IRQ_DEVICE_ID 0
    
    #define XGPIO_GIE_OFFSET	0x11C /**< Glogal interrupt enable register */
    #define XGPIO_ISR_OFFSET	0x120 /**< Interrupt status register */
    #define XGPIO_IER_OFFSET	0x128 /**< Interrupt enable register */
    #define XGPIO_GIE_GINTR_ENABLE_MASK 0x80000000
    
    //#define is_keypad_irq() (!(inb(IRQ_STAT_ADDR) & IRQ_MASK))
    //#define disable_irq()    (iowrite32(IRQ_DIST_BASEADDR+XGPIO_IER_OFFSET,ioread32(IRQ_DIST_BASEADDR+XGPIO_IER_OFFSET) & ~IRQ_MASK))
    
    //#define enable_irq()      (iowrite32(IRQ_DIST_BASEADDR+XGPIO_IER_OFFSET,ioread32(IRQ_DIST_BASEADDR+XGPIO_IER_OFFSET) | IRQ_MASK))
    
    //#define clear_irq()      (iowrite32(KEY_PHY_ADDR+XGPIO_IER_OFFSET,ioread32(KEY_PHY_ADDR+XGPIO_IER_OFFSET) & IRQ_MASK))
     
    
    static unsigned long led_addr = 0;
    static unsigned long key_addr = 0;
    
    static struct class* gpio_class = NULL;
    static struct device* gpio_device = NULL;
    
    static int gpio_major = 0;
    
    typedef struct {
            dev_t dev_no;
    
    	u32 IsReady;
    	int InterruptPresent;
    	u32 BaseAddress;
    //      spinlock_t lock;
            atomic_t lock;
    } KEY_DEV;
    
    static KEY_DEV keydev;
    
    //arg means the led number, cmd controls it on or off
    static ssize_t gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    {
    	//printk("fun(gpio_ioctl):");
    	u32 status = 0xff;
    	int ret;
    	switch(cmd){
    		case 0:
    		case 1:
    			//if(arg > 8)
    			//	return -EINVAL;
    			status = ioread32(led_addr);
    			if(0 == cmd)
    				status &=  ~(0x1 << arg);
    			else if(1 == cmd)
    				status |= (0x1 << arg);
    			iowrite32(status,led_addr);
    			return 0;
    		case 3:
    			status = ioread32(key_addr);
    			ret = __put_user(status, (u32 *)arg);
    			printk("key print = 0x%x
    ",status);
    			return 0;
    		default:
    			printk("default cmd=%d
    ",cmd);
    			return -EINVAL;
    	}
    }
    static void InterruptClear()
    {
            u32 val;
            val = ioread32(key_addr + XGPIO_ISR_OFFSET);
            iowrite32(val & IRQ_MASK,key_addr + XGPIO_ISR_OFFSET);
            printk("int cleared");
    }
    
    static irqreturn_t key_interrupt(int irq, void *dev_id, struct pt_regs *regs)
    {
    	u32 status = 0xff;
    	//disable_irq(INTERRUPT_ID);
    //	disable_irq();
    	status = ioread32(key_addr);
    	iowrite32(status,led_addr);
    	printk("key print = 0x%x
    ",status);	
    //	clear_irq();
    	//enable_irq(INTERRUPT_ID);
    //	enable_irq();
    
    	InterruptClear();
    	return 0;
    }
    static void InterruptEnable()
    {
    	//from stand alone program
    	//XGpio_InterruptEnable(&Gpio, BUTTON_INTERRUPT);
    	//XGpio_InterruptGlobalEnable(&Gpio);
    	u32 val;
    	printk("debug1 read addr = %lx
    ",key_addr+XGPIO_IER_OFFSET);
    	//			  0x128
    	val = ioread32(key_addr + XGPIO_IER_OFFSET);
    	printk("debug2 val=%lx
    ",val);
    	//                   0x128                  0x1
    	iowrite32(val | IRQ_MASK,key_addr + XGPIO_IER_OFFSET);
    	printk("debug3 ");
    	//		     0x11c            0x80000000
    	iowrite32(XGPIO_GIE_GINTR_ENABLE_MASK,key_addr + XGPIO_GIE_OFFSET);
    }
    
    static int key_open(struct inode *inode, struct file *filp)
    {
            int ret;
    	printk("open!
    ");
    	InterruptEnable();
    	printk("interrupt Enabled!
    ");
    	ret = request_irq(INTERRUPT_ID, key_interrupt,IRQF_TRIGGER_RISING, DEVICE_NAME, &keydev);
    	if(ret)
    	{
    		printk("could not register interrupt!");
    		return ret;
    	}
    	//disable_irq(INTERRUPT_ID);
    	//enable_irq(INTERRUPT_ID);
    //	enable_irq();
    	printk("register interrupt success!
    ");
    	return 0;
    }
    
    static struct file_operations gpio_fops = {
    	.owner = THIS_MODULE,
    	.unlocked_ioctl = gpio_ioctl,
    	.open = key_open,
    //	.read = key_read,
    };
    
    static int __init gpio_init(void)
    {
    	int ret;
    	
    	ret = register_chrdev(0,DEVICE_NAME, &gpio_fops);
    	if(ret < 0)
    	{
    		printk("gpio: can't get major number
    ");
    		return ret;
    	}
    
    	gpio_major = ret;
    	gpio_class = class_create(THIS_MODULE, "gpio_class");
    	if(IS_ERR(gpio_class))
    	{
    		printk("gpio: failed in creating class
    ");
    		unregister_chrdev(gpio_major, DEVICE_NAME);
    		return -1;
    	}
    
    	gpio_device = device_create(gpio_class,NULL,MKDEV(gpio_major,0),NULL,DEVICE_NAME);
    	if(IS_ERR(gpio_device))
    	{
    		printk("gpio: failed in creating device!
    ");
    		unregister_chrdev(gpio_major, DEVICE_NAME);
    		class_unregister(gpio_class);
    		class_destroy(gpio_class);
    		return -1;
    	}
    	
    	led_addr = (unsigned long) ioremap(LED_PHY_ADDR, sizeof(u32));
    	key_addr = (unsigned long) ioremap(KEY_PHY_ADDR, sizeof(u32));
    /*	
    	iowrite32(0x00,led_addr);
    	mdelay(100);
    	iowrite32(0xff,led_addr);
    */
    
    	printk("gpio installed successfully!
    ");
    	return 0;
    }
    
    static void __exit gpio_exit(void)
    {
    /*
    	iowrite32(0x00,led_addr);
    	mdelay(100);		
    	iowrite32(0xff,led_addr);
    */
    	device_destroy(gpio_class,MKDEV(gpio_major, 0));
    	class_unregister(gpio_class);
    	class_destroy(gpio_class);
    	unregister_chrdev(gpio_major,DEVICE_NAME);
    	printk("gpio module exit!");
    }
    
    module_init(gpio_init);
    module_exit(gpio_exit);
    
    
    MODULE_AUTHOR("seg");
    MODULE_LICENSE("GPL");

    (8) Useful Tips for write linux driver

    Part1: we can use commands below to test gpio led.

    cd /sys/class/gpio/
    echo 248 > ./export
    cd gpio248/
    echo "out" > ./direction
    echo 1 > ./value

    Screenshot from 2014-05-17 10_03_07

    Part2: we can use commands below to see interrupts status.

    cat /proc/interrupts
    cat /proc/stat

    Screenshot from 2014-05-19 14_41_27

  • 相关阅读:
    通过图像识别技术监控屏幕画面卡死问题
    人生四问
    bring to front 必须在右边的form上才生效。
    ADO 右键问题,当dbgrideh非只读的时候,会遇到这个问题
    K-Means聚类算法
    BIRCH算法---使用聚类特征树的多阶段算法
    BIRCH算法---使用聚类特征树的多阶段算法
    分布式系统阅读笔记(二十二)-----时钟和时钟同步
    分布式系统阅读笔记(二十二)-----时钟和时钟同步
    分布式系统阅读笔记(二十二)-----时钟和时钟同步
  • 原文地址:https://www.cnblogs.com/shenerguang/p/3730047.html
Copyright © 2011-2022 走看看