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

📄 xup_spartan3e_led.c

📁 Xilinx ISE&EDK 8.2平台的嵌入式MiNiVOS服务器
💻 C
字号:
#include <linux/module.h>
#include <asm/io.h>
#include <linux/poll.h>  
#include <linux/init.h> 
#include <linux/ioctl.h> 
#include <asm/semaphore.h>//struct semaphore
#include <linux/timer.h>//timer_list
//#include <linux/wait.h>//wait_event_interruptible_timeout
//#include <linux/sched.h>//schedule_timeout

#define XUP_SPARTAN3E_LED_MAJOR			222#define XUP_SPARTAN3E_PLAY_MAJOR             223
#define DATA_REG_ADDR			0x40000000
#define DIRC_REG_ADDR			0x40000004
#define OutMem(OutAddr, Value)		(*(volatile u32 *)((OutAddr)) = (Value))
#define InMem(InputAddr)		(*(volatile u32 *)(InputAddr))
#define DELAY				(HZ>>3)#define INITIAL_COUNT                   40
#define XUP_SPARTAN3E_LED_IOC_MAGIC			'x'
#define XUP_SPARTAN3E_LED_MAX_NUM			4
#define XUP_SPARTAN3E_LED_SET_DIR			_IOWR(XUP_SPARTAN3E_LED_IOC_MAGIC, 0, u32) //ioctl
#define XUP_SPARTAN3E_LED_SET_REV			_IOWR(XUP_SPARTAN3E_LED_IOC_MAGIC, 1, u32) //ioctl

static int initial_count;
static unsigned char led_state;
static struct semaphore sem;     /* mutual exclusion semaphore     */
static struct timer_list refresh_timer;

static void refresh(unsigned long ptr)
{		if (refresh_timer.data == 1) 
	{
		if (initial_count < INITIAL_COUNT)		{			if (led_state|0x0)
				led_state <<= 1;
			else
				led_state = 1;			initial_count = initial_count + 1;		}		else if (initial_count < INITIAL_COUNT*2 && initial_count >= INITIAL_COUNT)		{			if (led_state != 0x01)
				led_state >>= 1;
			else
				led_state = 0x80;			initial_count = initial_count + 1;		}		else		{			if (led_state == 0x0)
				led_state = 0xff;
			else if (led_state == 0xff)
				led_state = 0x0;			else				led_state=0x0;		}		OutMem(DATA_REG_ADDR, led_state);
		refresh_timer.expires = jiffies + DELAY;
		add_timer(&refresh_timer);
	}	else if (refresh_timer.data == 2)	{		OutMem(DATA_REG_ADDR, led_state);
		refresh_timer.expires = jiffies + DELAY>>2;
		add_timer(&refresh_timer);			}	else {}
}static int xled_open(struct inode * inode, struct file * file)
{
	MOD_INC_USE_COUNT;
	//printk("XUP_SPARTAN3E_LED open: Usage = %d\n", MOD_IN_USE);
	return 0;
}

static int xled_release(struct inode * inode, struct file * file)
{
	MOD_DEC_USE_COUNT;
	//printk("XUP_SPARTAN3E_LED release: Usage = %d\n", MOD_IN_USE);
	return 0;
}

static ssize_t xled_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
{
	down(&sem);
	//led_state = inb(INPORT);
	//OutMem(DIRC_REG_ADDR, 0xFFFFFFFF);//set direction
	//barrier();
	//led_state = InMem(DATA_REG_ADDR);
	//printk("data = %x hex\n", led_state);    // for debugging only
	if(copy_to_user( buffer, &led_state, 1))
	{
		printk("Read Data to user error\n");
		up(&sem);
		return -EFAULT;
	}
	up(&sem);
	return 1;
}

static ssize_t xled_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{	down(&sem);	refresh_timer.data = 0;
	if (copy_from_user(&led_state, __user (u8 *)buf, 1))
	//int ret = get_user(led_state,buf);
	//if (ret != 0)
	{
		printk("Write Data from user error\n");
		up(&sem);
		return -EFAULT;
	}
	printk("Write Data from user %x\n", led_state);	up(&sem);
	//outb(data, OUTPORT);	if (led_state == 0xAA)	{			refresh_timer.data = 1;		refresh(0);		}	else
	{			refresh_timer.data = 2;		refresh(0);			}	
	return 1;
}

static int xled_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	if (MINOR(inode->i_rdev) >= XUP_SPARTAN3E_LED_MAX_NUM)
		return -ENODEV;
	if (_IOC_TYPE(cmd) != XUP_SPARTAN3E_LED_IOC_MAGIC)
		return -ENOTTY;
	switch (cmd)
	{
		case XUP_SPARTAN3E_LED_SET_DIR:
			OutMem(DIRC_REG_ADDR, arg);
			printk("Set XUP_SPARTAN3E_LED direct %ld\n", arg);
			break;
		case XUP_SPARTAN3E_LED_SET_REV:
			;
			break;
		default:
			return -ENOTTY;
	}
	return 0;
}static ssize_t play_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
{
	down(&sem);
	//led_state = inb(INPORT);
	//OutMem(DIRC_REG_ADDR, 0xFFFFFFFF);//set direction
	//barrier();
	//led_state = InMem(DATA_REG_ADDR);
	//printk("data = %x hex\n", led_state);    // for debugging only
	if(copy_to_user( buffer, &led_state, 1))
	{
		printk("Read Data to user error\n");
		up(&sem);
		return -EFAULT;
	}
	up(&sem);
	return 1;
}

static ssize_t play_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
	down(&sem);
	refresh_timer.data = 0;	if (copy_from_user(&led_state, __user (u8 *)buf, 1))
	//int ret = get_user(led_state,buf);
	//if (ret != 0)	//if (copy_from_user(&led_state, __user (u8 *)buf, count))
	{
		printk("Write Data from user error\n");
		up(&sem);
		return -EFAULT;
	}
	printk("Write Data from user %x\n", led_state);
	//outb(data, OUTPORT);
	OutMem(DATA_REG_ADDR, led_state);	up(&sem);
	return 1;
}

struct file_operations play_fops = {
 	owner:   THIS_MODULE,
	open:    xled_open,
	release: xled_release,
	read:    play_read,
	write:   play_write,
	ioctl:   xled_ioctl,
      };struct file_operations xled_fops = {
 	owner:   THIS_MODULE,
	open:    xled_open,
	release: xled_release,
	read:    xled_read,
	write:   xled_write,
	ioctl:   xled_ioctl,
      };


int __init xled_init (void)
{
	if (register_chrdev(XUP_SPARTAN3E_LED_MAJOR,"XUP_SPARTAN3E_LED",&xled_fops)) 
	{
		printk("XUP_SPARTAN3E_LED: Failed to get major %d\n", XUP_SPARTAN3E_LED_MAJOR);
		return -EIO;
	}	
	if (register_chrdev(XUP_SPARTAN3E_PLAY_MAJOR,"XUP_SPARTAN3E_PLAY",&play_fops)) 
	{
		printk("XUP_SPARTAN3E_PLAY: Failed to get major %d\n", XUP_SPARTAN3E_PLAY_MAJOR);
		return -EIO;
	}	initial_count = 0;
	init_MUTEX(&sem);
	init_timer(&refresh_timer); 
	refresh_timer.function = refresh;
	refresh_timer.data = 1;
	refresh_timer.expires = jiffies + DELAY;
	add_timer(&refresh_timer);
	printk("Registered device XUP_SPARTAN3E_LED: major %d\n",XUP_SPARTAN3E_LED_MAJOR);	printk("Registered device XUP_SPARTAN3E_PLAY: major %d\n",XUP_SPARTAN3E_PLAY_MAJOR);
	return 0;
}

static void __exit xled_cleanup (void)
{
	printk("Freed resources: MOD_IN_USE = %d\n", MOD_IN_USE); 	
	unregister_chrdev(XUP_SPARTAN3E_LED_MAJOR,"XUP_SPARTAN3E_LED");	unregister_chrdev(XUP_SPARTAN3E_PLAY_MAJOR,"XUP_SPARTAN3E_PLAY");
	del_timer(&refresh_timer);
	printk("Unregistered device XUP_SPARTAN3E_LED: major %d\n",XUP_SPARTAN3E_LED_MAJOR);	printk("Unregistered device XUP_SPARTAN3E_PLAY: major %d\n",XUP_SPARTAN3E_PLAY_MAJOR);
}

module_init(xled_init);
module_exit(xled_cleanup);
MODULE_LICENSE("GPL");
EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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