hi Dave
below is my code i have changed it a bit to make it more readable
--the SSCR* are defined in the pxa-regs.h and also in the sample
driver in the gumstix build root file ssp.c
-- this code is tested and is hanging the gumstix
-- in another driver if the various interrrupt situation(like txd\rxd
service request, interrupt test reg or fifo over/under run are not
enabled)are not enabled then the data can be transported and received
form the FIFO
--regs are initialised as follows
SSCR0-- for 32 bit data transfer ,using TI ssp protocol
SSCR1-- rxd/txd interrupt enabled,Loop backmode,transmission /receive
fifo threshold,timeout interrupt, etc
this code test for the interrupt when it is initialised.
the gumstix system is not handling the interrupt it just hangup
thanks in advance
the code
/*
*nsspdrv.h
*/
#include <linux/fs.h>
#include <asm/uaccess.h>=09/* for put_user */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/arch/pxa-regs.h>
#define TRFS (1 << 6)
#define SUCCESS 0
#define DEVICE_NAME "nsspdev"=09/* Dev name as it appears in /proc/devices =
*/
#define BUF_LEN 80=09=09/* Max length of the message from the device */
struct ssp_state {
u32 cr0;
u32 cr1;
u32 to;
u32 psp;
u32 itr;
};
static struct ssp_state regs;
struct nssp_irq{
int a;
int b;
};
static struct nssp_irq nssp_int;
static int Major;=09=09/* Major number assigned to our device driver */
static int Device_Open =3D 0;=09/* Is device open?
=09=09=09=09 * Used to prevent multiple access to device */
static char msg[BUF_LEN];=09/* The msg the device will give when asked */
static char *msg_Ptr;
int nssp_init(void);
void nssp_exit(void);
static int nssp_open(struct inode *, struct file *);
static int nssp_release(struct inode *, struct file *);
static ssize_t nssp_read(struct file *, char *, size_t, loff_t *);
static ssize_t nssp_write(struct file *, const char *, size_t, loff_t *);
void nssp_disable(void);
void nssp_enable(void);
int nssp_write_word(u32 );
int nssp_read_word(void);
irqreturn_t nssp_interrupt(int , void *, struct pt_regs *);
module_init(nssp_init);
module_exit(nssp_exit);
MODULE_DESCRIPTION("PXA NSSP driver");
MODULE_AUTHOR("ashutosh");
MODULE_LICENSE("GPL");
/*
* nsspdrv.c
*/
#include"nsspdrv.h"
//File_ops structture initialisation
static struct file_operations fops =3D {
=09.read =3D nssp_read,
=09.write =3D nssp_write,
=09.open =3D nssp_open,
=09.release =3D nssp_release,
=09
};
int nssp_write_word(u32 data)
{
while (!(SSSR_P2 & SSSR_TNF));
// cpu_relax();
SSDR_P2 =3D data;
return 0;
}
int nssp_read_word()
{
while (!(SSSR_P2 & SSSR_RNE));
// cpu_relax();
return SSDR_P2;
}
void nssp_enable()
{
SSCR0_P2 |=3D SSCR0_SSE;
}
void nssp_disable()
{
SSCR0_P2 &=3D ~SSCR0_SSE;
}
int nssp_init(void)
{
int i,ret,irq;
printk(KERN_INFO "inside nssp_init()\n");
irq =3D IRQ_NSSP;
memset(®s,0,sizeof(struct ssp_state));
regs.cr0=3D SSCR0_DataSize(16) | SSCR0_TI | (7<<8) | SSCR0_EDSS;
regs.cr1=3DSSCR1_RIE | SSCR1_TIE | SSCR1_LBM | SSCR1_TxTresh(11) |
SSCR1_RxTresh(11)
| SSCR1_TINTE | SSCR1_TTE ;
regs.to=3D46000;//not used
regs.itr=3D0;//not used
SSCR0_P2 =3D regs.cr0;
SSCR1_P2 =3D regs.cr1;
ret =3D request_irq(irq, &nssp_interrupt, 0, "NSSP",&nssp_int);
if (ret)
return -3;
Major =3D register_chrdev(0, DEVICE_NAME, &fops);
=09if (Major < 0) {
=09=09printk("Registering the character device(nsspdev) failed with %d\n", =
Major);
=09=09return -2;
=09}
=09printk("<1>I was assigned major number %d. To talk to\n", Major);
=09printk("<1>the driver, create a dev file with\n");
=09printk("'mknod /dev/nssp c %d 0'.\n", Major);
=09
nssp_enable();
//Testing the system for the interrupt
SSITR_P2 |=3D TRFS;
for(i=3D0;i<1000;i++);//just for testing the interrupt
SSITR_P2 &=3D ~TRFS;
nssp_disable();
=09return 0;
}
void nssp_exit(void)
{
int ret,irq;
SSCR0_P2 &=3D ~SSCR0_SSE;
irq =3D IRQ_NSSP;
=09free_irq(irq, &nssp_int);
=09ret =3D unregister_chrdev(Major, DEVICE_NAME);
=09if (ret < 0)
=09=09printk("Error in unregister_chrdev: %d\n", ret);
=09printk("nssp_exit \n");=09
}
static int nssp_open(struct inode *inode, struct file *file)
{
=09static int counter =3D 0;
=09Device_Open++;
=09printk("I already told you %d times Hello world!\n", Device_Open);
=09msg_Ptr =3D msg;
=09try_module_get(THIS_MODULE);
return SUCCESS;
}
static int nssp_release(struct inode *inode, struct file *file)
{
=09Device_Open--;
=09printk("the device no released : %i\n",Device_Open+1);
=09module_put(THIS_MODULE);
=09return 0;
}
irqreturn_t nssp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
// struct ssp_dev *dev =3D (struct ssp_dev*) dev_id;
unsigned int status =3D SSSR_P2;
SSSR_P2 =3D status; /* clear status bits */
if (status & SSSR_BCE)
{ printk(KERN_WARNING "NSSP: bit count error\n");}
=09if (status & SSSR_TUR)
{ printk(KERN_WARNING "NSSP: transmitter underrun\n");}
=09
=09if(status & SSSR_TINT)
=09{ printk(KERN_INFO "NSSP: timeout interrupt\n");}
=09
if (status & SSSR_ROR)
{ printk(KERN_WARNING "NSSP: receiver overrun\n");}
if(status & SSSR_RFS)
{ printk(KERN_INFO " NSSP: Rsv FIFO service request\n");}
=09
if(status & SSSR_TFS)
{ printk(KERN_INFO " NSSP: Trns FIFO service request \n");}
=09return IRQ_HANDLED;
}
// the function accessed by read() system call
static ssize_t nssp_read(struct file *filp, char *buffer,size_t
length,loff_t * offset)
{
=09int ret, bytes_read =3D 1;
int i=3D0;
=09nssp_enable();
=09for(i=3D0;i<8;i++)
{ ret=3D1000+i;
printk(" the word written is : %x \n",ret);
nssp_write_word(ret);
=09 printk(" reading : %x \n",nssp_read_word());
}=09
=09nssp_disable();
=09return bytes_read;
}
static ssize_t
nssp_write(struct file *filp, const char *buff, size_t len, loff_t * off)
{
=09printk("<1>Sorry, this operation isn't supported.\n");
=09return -EINVAL;
}
bye
ashutosh
|