LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Hardware
User Name
Password
Linux - Hardware This forum is for Hardware issues.
Having trouble installing a piece of hardware? Want to know if that peripheral is compatible with Linux?

Notices

Reply
 
Search this Thread
Old 12-26-2008, 05:38 AM   #1
devajyotibarman
LQ Newbie
 
Registered: May 2008
Posts: 4

Rep: Reputation: 0
UART Interrupt Handler


Hello. I didn't know where to put this. So please consider.

I ams trying to make a simple Uart Driver which can receive some data from an external source. Here's my code:

Code:
#include <linux/init.h>
#include <asm/signal.h>
#include <linux/module.h>
#include <linux/cdev.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#define BASE_PORT 0x3F8

MODULE_AUTHOR ( "Devajyoti Barman" );
MODULE_DESCRIPTION ( "Character Driver" );
MODULE_LICENSE ( "GPL" );

dev_t myUart;
char *memoryBuffer = NULL;

struct cdev myUartX;
void *memoryPtr;
unsigned int myIrq = 4;
int irqstatus = 1;
struct resource *myPort = NULL;

irqreturn_t myIrqReturn ( int myInt, void *xPtr )
{
	printk ( KERN_ALERT "Hello Interrupt\n" );
	return IRQ_HANDLED;
}

ssize_t myUartX_read ( struct file *myFile, char *buff, size_t count, loff_t *offp )
{
	int status;
	status = inb ( BASE_PORT );

	if ( status &= 0x01 )
	{
		*memoryBuffer = ( char ) inb ( BASE_PORT );
		copy_to_user ( buff, memoryBuffer, 1 );
	}

	return 0;
}

ssize_t myUartX_write ( struct file *myFile, const char *buff, size_t count, loff_t *offp )
{
	copy_from_user ( memoryBuffer, buff, 1 );
	iowrite8 ( *memoryBuffer, memoryPtr );
	return 0;
}

int myUartX_open ( struct inode *mynode, struct file *myFile )
{
	printk ( KERN_ALERT "You have called a OPEN Operation!\n" );
	return 0;
}

int myUartX_close ( struct inode *mynode, struct file *myFile )
{
	printk ( KERN_ALERT "You have called a CLOSE Operation!\n" );
	return 0;
}

struct file_operations fops =
{
	.owner = THIS_MODULE,
	.read = myUartX_read,
	.open = myUartX_open,
	.write = myUartX_write,
	.release = myUartX_close
};

static int init_dev ( void )
{
	int status;
	status = alloc_chrdev_region ( &myUart, 0, 1, "myUartDriver" );
	if ( status )
	{
		printk ( KERN_ALERT "Driver Initialization Failed!\n" );
		return -1;
	}
	else
	{
		printk ( KERN_ALERT "Driver created Successfully!\n" );
		printk ( KERN_ALERT "Major Number: %d\n", MAJOR ( myUart ) );
	}
	cdev_init ( &myUartX, &fops );
	status = cdev_add ( &myUartX, myUart,  1 );
	if ( status )
	{
		printk ( KERN_ALERT "Driver initialization Failed!\n" );
		return -1;
	}
	else
	{
		printk ( KERN_ALERT "Driver added Successfully for device number %d!\n", MAJOR ( myUart ) );
	}
	memoryBuffer  = kmalloc ( 1, GFP_KERNEL );
	memset ( memoryBuffer, '\0', 1 );
	if ( memoryBuffer == NULL )
	{
		printk ( KERN_ALERT "Memory initializialization Failed\n" );
	}
	else
	{
		printk ( KERN_ALERT "Memory initialized Successfully\n" );
	}
	myPort = request_region ( BASE_PORT, 8, "myUartPort" );
	if (myPort == NULL )
	{
		printk ( KERN_ALERT "Port allocation failed!\n");
		return -1;
	}
	else
	{
		printk ( KERN_ALERT "Port allocation Successful!\n");
	}
	enable_irq ( myIrq );
	irqstatus = request_irq ( myIrq, &myIrqReturn, IRQF_DISABLED, "myInterrupt", NULL );
	if ( irqstatus < 0 )
	{
		printk ( KERN_ALERT "Interrupt Capture failed!" );
		return -1;
	}
	else
	{
		printk ( KERN_ALERT "Interrupt Capture Assigned to %d\n", myIrq );
		outb ( 0x00, BASE_PORT + 1 );
		outb ( 0X01, BASE_PORT + 2 );
		outb ( 0x80, BASE_PORT + 3 );
		outb ( 0x0C, BASE_PORT + 0 );
		outb ( 0x03, BASE_PORT + 3 );
		outb ( 0x0B, BASE_PORT + 4 );
		outb ( 0x05, BASE_PORT + 1 );
		printk ( KERN_ALERT "Port Configuration OK!\n" );
	}
	return 0;
}

static void exit_dev ( void )
{
	if ( memoryBuffer )
	{
		kfree ( memoryBuffer );
	}
	if( myPort != NULL )
	{
		release_region ( BASE_PORT, 8 );
		printk ( KERN_ALERT "Port deallocation Successful!\n" );
	}

	if ( irqstatus == 0 )
	{
		free_irq ( myIrq, NULL );
		printk ( KERN_ALERT "IRQ %d freed successfully!\n", myIrq );
	}

	cdev_del ( &myUartX );

	unregister_chrdev_region ( myUart, 1 );
	printk ( KERN_ALERT "Driver Unregistered Successfully!\n" );
}

module_init ( init_dev );
module_exit ( exit_dev );



I ams using Ubuntu 8.10 with kernel 2.6.27.9. I have disabled the default? serial driver using setserial command. All device, memory and Port allocation comes out OK. Interrupts are also assigned. But the problem is that the ISR is never invoked. Either there is a problem with the UART configuration or I am missing something.

On a similar note how do I use the parallel port interrupt without using the User Space default? driver. I tried unloading modules like lp, parport, parport_pc etc but somehow after that my own driver would not work!!
 
Old 01-02-2009, 03:09 PM   #2
greenstone
LQ Newbie
 
Registered: May 2006
Posts: 1

Rep: Reputation: Disabled
Looks like "transmitter-holding-register empty" interrupt is disabled.
And if the high byte of rate divisor is not zero when your driver is loaded (it does not high byte), baud rate will be incorrect and nothing will be received at all. Clearing DLAB before Interrupt Enable Register access would be reasonable.
 
Old 01-02-2009, 11:12 PM   #3
devajyotibarman
LQ Newbie
 
Registered: May 2008
Posts: 4

Original Poster
Rep: Reputation: 0
Re: Uart

I have already considered all. THing is it receives data without fail using polling method. But interrupt is never generated.

Should I fool around the PIR register at 0x21?
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
UART Polling/Interrupt jdhar Linux - Software 1 06-10-2010 02:55 PM
Problem in interrupt handler for uart 16550 mrinal mishra Linux - Kernel 3 05-05-2006 12:00 AM
control is not going to interrupt handler when interrupt comes in serial driver sateeshalla Linux - Kernel 1 05-04-2006 09:43 AM
Linux Interrupt Handler lucky6969b Linux - Software 1 12-01-2005 11:55 AM
<0>Kernel panic: Aiee, killing interrupt handler! In interrupt handler - not syncing mrb Linux - Newbie 2 01-09-2005 09:47 AM


All times are GMT -5. The time now is 03:14 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration