⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 led_sw.c

📁 对富士通frv400架构
💻 C
字号:
/* joy_wudan  2007/12/ */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/irq.h>
#include <asm/frvirq.h>
#include <asm/uaccess.h>
#include <asm/smplock.h>
#include "LED_SW.h"
/*functions*/
void delay(void);
int init_module(void);
void cleanup_module(void);
static void sw_handler(int irq, void *dev_id, struct pt_regs *regs);
static int device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
static inline void write_tarboio_register(volatile unsigned char *x, unsigned char v);
static inline u8 read_tarboio_register(volatile unsigned char *x);
static inline u16 read_tarboio_register_sw(volatile unsigned short *x);
static int device_release(struct inode *inode, struct file *file);
static int device_open(struct inode *inode, struct file *file);
static void sw_task(unsigned long data);
DECLARE_TASKLET(sw_tasklet,sw_task, 0);
static int Device_Open = 0,led_i=0,led_j=0,led_k=0,led_l=0,led_m=0; 
static struct file_operations fops = {
	  ioctl :	device_ioctl,
	  open:	 device_open,
	  release:	 device_release,
      
};
int init_module(void)
{
      register_chrdev(Major, DEVICE_NAME, &fops);
      request_irq(IRQ_SW2_6,sw_handler,SA_INTERRUPT, "fr400_sw", NULL);
      request_irq(IRQ_SW9 ,sw_handler,SA_INTERRUPT, "fr400_sw", NULL);
      request_irq(IRQ_SW8 ,sw_handler,SA_INTERRUPT, "fr400_sw", NULL);
      disable_irq(IRQ_SW2_6);
      disable_irq(IRQ_SW9);
      disable_irq(IRQ_SW8);
	  return 0;
}
void cleanup_module(void)
{
       unregister_chrdev(Major, DEVICE_NAME);
       free_irq(IRQ_SW2_6,NULL);
       free_irq(IRQ_SW9,NULL);
       free_irq(IRQ_SW8,NULL);
}
 
static int device_open(struct inode *inode, struct file *file)
{
	  return 0;
}
static int device_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
        unsigned char temp;
        unsigned short sw;
		switch(cmd)
            {
  /* cmd for write :*/  
                 case LED8_SET:
                        temp=read_tarboio_register(LED_ADDR);
                        write_tarboio_register(LED_ADDR,temp);
                        break;
                 case LED7_SET:
                        temp=read_tarboio_register(LED_ADDR);
                         write_tarboio_register(LED_ADDR,(temp|0x02));
                         break;
                 case LED6_SET:
                        temp=read_tarboio_register(LED_ADDR);
                         write_tarboio_register(LED_ADDR,(temp|0x04));
                        break;
                        temp=read_tarboio_register(LED_ADDR);
                         write_tarboio_register(LED_ADDR,(temp|0x08));
                        break;
                 case LED4_SET:
                        temp=read_tarboio_register(LED_ADDR);
                         write_tarboio_register(LED_ADDR,(temp|0x10));
                        break;
                 case LED3_SET:
                        temp=read_tarboio_register(LED_ADDR);
                         write_tarboio_register(LED_ADDR,(temp|0x20));
                        break;
                 case LED2_SET:
                        temp=read_tarboio_register(LED_ADDR);
                         write_tarboio_register(LED_ADDR,(temp|0x40));
                 case LED_CLR:
                      write_tarboio_register(LED_ADDR,0x00);
                        break;
                 case LED_SET:
                      write_tarboio_register(LED_ADDR,0x7F);
                        break;
                 case SW_READ:
                        sw=read_tarboio_register_sw(SW_ADDR);
                        *(unsigned short *)arg=((~sw)& 0x7FFF);
                        break;
                 case DISABLE_IRQ:
                         disable_irq(IRQ_SW2_6);
                         disable_irq(IRQ_SW9);
                         disable_irq(IRQ_SW8);
                         break;
                case ENABLE_IRQ:
                         enable_irq(IRQ_SW2_6);
                         enable_irq(IRQ_SW9);
                         enable_irq(IRQ_SW8);   
                         break;         
                default:printk(" LED: invalid command.\n");
                return -EINVAL;
                break;
		}
}
static int device_release(struct inode *inode, struct file *file)
{
	  Device_Open --;     /* We're now ready for our next caller */
	   return 0;
}
static void sw_handler(int irq, void *dev_id, struct pt_regs *regs)
{
    disable_irq(IRQ_SW2_6);
    disable_irq(IRQ_SW9);
    disable_irq(IRQ_SW8);
    tasklet_schedule(&sw_tasklet);
}
static void sw_task(unsigned long data)
{
    static int led_i=0,led_j=0,led_k=0,led_l=0,led_m=0;
    unsigned short sw;
    unsigned char temp;
    sw=read_tarboio_register_sw(SW_ADDR);
    sw=((~sw)& 0x7FFF) ;
    switch (sw)
    {
        case 0x4000 :
		    if((led_i%2)==0)
		    {
		
                    temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp|0x01));
		    }

                    else
                    {
                     temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp&0xFE));
                   
                    }
		    led_i++;
                    break;
        case 0x2000:
		    if((led_j%2)==0)
		    {
		
                    temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp|0x02));
		    }

                    else
                    {
                     temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp&0xFD));
                   
                    }
		    led_j++;   
                    break;     
        case 0x1000:
		    if((led_k%2)==0)
		    {
		
                    temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp|0x04));
		    }

                    else
                    {
                     temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp&0xFB));
                   
                    }
		    led_k++;   
		   break;
        case 0x0800:
		    if((led_l%2)==0)
		    {
		
                    temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp|0x08));
		    }

                    else
                    {
                     temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp&0xF7));
                   
                    }
		    led_l++; 
		   break;  
         case 0x0400:
		    if((led_m%2)==0)
		    {
		
                    temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp|0x10));
		    }

                    else
                    {
                     temp=read_tarboio_register(LED_ADDR);
                    write_tarboio_register(LED_ADDR,(temp&0xEF));
                   
                    }
		    led_m++;
		    break;                
         default:
                    printk("unsupported sw\n");
   	 }
       delay();
       enable_irq(IRQ_SW2_6);      
       enable_irq(IRQ_SW9);
       enable_irq(IRQ_SW8);   
}
static inline u8 read_tarboio_register(volatile unsigned char *x)
{
	unsigned char v;
	v = *((volatile unsigned char *)(x));
	__asm__ __volatile__("membar");
	return v;
}
static inline u16 read_tarboio_register_sw(volatile unsigned short *x)
{
	unsigned short v;
	v = *((volatile unsigned short *)(x));
	__asm__ __volatile__("membar");
	return v;
}
static inline void write_tarboio_register(volatile unsigned char*x, unsigned char v)
{
	*((volatile unsigned char*)(x)) = (v);
	__asm__ __volatile__("membar");
}

void delay(void)
{
	int i=0,j=0,a;
	for(i=0;i<3000;i++)
		{
			for(j=0;j<1000;j++)
				{
					a=10/10;
				}
		}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -