mandag den 11. oktober 2010

Opgave 7
- Find ud af hvordan DAC7612 er forbundet til OMAP’en
Forbundet Bus 1, chipsselect 3

- Find ud af DAC7612’s SPI karakteristika.
CPOL = 1;
CPHA = 1;

- Indsæt værdier i board struct’en, ret number of bit_per_word i spi_probe
i ads7870-core.c ændres structen således:
.bus_num = 1,
.chip_select = 3,
i ads7870-core.c ændres metoden __devinit ads7870_spi_probe
så bit_pr_word = 14;

- Indsæt nogle debug printk’er

Implementer write
Da vi skal implimentere write før vi kan sætte en default værdi, gør vi dette først. Efter vi har sat defaultværdien implementerer i wiritefunktionen (ads7870_cdrv_write i filen dac7612.c)

ssize_t ads7870_cdrv_write(struct file *filep, const char __user *ubuf,
size_t count, loff_t *f_pos)
{
int minor, len, value;
char kbuf[MAXLEN];

minor = MINOR(filep->f_dentry->d_inode->i_rdev);

len = count < (MAXLEN - 1) ? count : MAXLEN;

copy_from_user(kbuf, ubuf, len);

sscanf(kbuf, "%i", &value);

dac7612_write(minor, value);
return count;
}


Hvorefter vi kan måle på Devkittet at udgangen ændrede spænding når vi skrev til devicet.
echo 1000 >/dev/dac0
giver en spænding på 1000mV
.

mandag den 4. oktober 2010

Øvelse 6 - Interrputs

Implementer Interrupt request/free
Requester interrupt i interrupt.c (modificeret øvelse 5)
indsættes i init lige før return:

unsigned int IRQ = gpio_to_irq(130);


request_irq(IRQ, myISR, IRQF_TRIGGER_RISING, "Joe", NULL);
printk("IRQ-line: %d", IRQ);
//der ses med dmesg hvilket IRQ-linie vi får tildelt.

implimenter pseudo myISR, som kører printk(KERN_ALERT "IRQ event!!!\n");.

Implementer ISR
Der er et eksempel på wait() på side 160 i LDD3.
Tilføj følgende kode i toppen af filen, som global variabel.

static DECLARE_WAIT_QUEUE_HEAD(wq);
static int flag = 0;

I mygpio_read( ) på linie 278 og 279 tilføjes følgende kode.
flag = 0;
wait_event_interruptible(wq, flag!=0);

I mypgio_isr( ) implimenteres således:

vi forbinder interruptbenet til GROUND
indsætter modul:
insmod interrupts.ko

VI skifter benet over til VCC, og bagefter til GND igen.

vi kigger i dmesg, og ser at der sket nogle interrupts.


Øvelse 5 - GPIO Linux Device Driver

Implementer ”init” og ”exit”
/*
* ID: mygpio.c
*/
#include
#include
#include
#include
#include

#define MYGPIO_MAJOR 62
#define MYGPIO_MINOR 0
#define MYGPIO_CHS 8
#define MAXLEN 512

static struct cdev MyGpioDev;
struct file_operations mygpio_Fops;

static int devno;

const unsigned int gpio_len = 8;
struct gpioPort{
unsigned int num;
enum direnu { in, out } dir;
const char label[10]; // Very important to specify a size. Just [] causes havoc to gpio indexing
} gpio[] = {
{130, in, "gpio0_0"},
{131, in, "gpio0_1"},
{132, in, "gpio0_2"},
{133, in, "gpio0_3"},
{134, out, "gpio0_4"},
{135, out, "gpio0_5"},
{136, out, "gpio0_6"},
{137, out, "gpio0_7"},
{139, out, "gpio0_9"}
};


static int mygpio_init(void)
{
int err, i;

printk(KERN_ALERT "Mygpio Module Inserted\n");


/*
* Allocate Major/Minor Numbers
*/
devno = MKDEV(MYGPIO_MAJOR, MYGPIO_MINOR);
if((err=register_chrdev_region(devno, gpio_len, "myGpio"))<0){
printk(KERN_ALERT "Can't Register Major no: %i\n", MYGPIO_MAJOR);
return err;
}

/*
* Create cdev
*/
cdev_init(&MyGpioDev, &mygpio_Fops);
MyGpioDev.owner = THIS_MODULE;
MyGpioDev.ops = &mygpio_Fops;
err = cdev_add(&MyGpioDev, devno, gpio_len);
if (err) {
printk (KERN_ALERT "Error %d adding MyGpio device\n", err);
return -1;
}

/*
* Request GPIO Ressources
*/

/*** YOUR CODE HERE ****/

//gpio_request(139, gpio);
gpio_request(130, "GPIO0_0");

/*
* Set GPIO Direction
*/

/*** YOUR CODE HERE ****/
//gpio_direction_output(139, 1);
gpio_direction_input(130);


return 0;
}

static void mygpio_exit(void)
{
int i;

printk(KERN_NOTICE "Removing Mygpio Module\n");

/*
* Set GPIOs to Inputs
* (leave things as when we entered)
*/

/*** YOUR CODE HERE ****/
gpio_direction_input(139);


/*
* Free GPIO Ressources
*/

/*** YOUR CODE HERE ****/
//gpio_free(139);
gpio_free(130);


/*
* Delete cdev
*/
unregister_chrdev_region(devno, gpio_len);
cdev_del(&MyGpioDev);
}


Implementer ”open” og ”release”
int mygpio_open(struct inode *inode, struct file *filep)
{
int major, minor;

major = MAJOR(inode->i_rdev);
minor = MINOR(inode->i_rdev);

printk("Opening MyGpio Device [major], [minor]: %i, %i\n", major, minor);


/*
* Check if major/minor is valid
*/

/*** YOUR CODE HERE ****/


/*
* Try to get the module sem
*/
if (!try_module_get(mygpio_Fops.owner)) // Get Module
return -ENODEV;

return 0;
}

int mygpio_release(struct inode *inode, struct file *filep)
{
int minor, major;

major = MAJOR(inode->i_rdev);
minor = MINOR(inode->i_rdev);

printk("Closing MyGpio Device [major], [minor]: %i, %i\n", major, minor);


/*
* Check if major/minor is valid
*/

/*** YOUR CODE HERE ****/


/*
* Put the module semaphore
* to release it
*/
module_put(mygpio_Fops.owner);

return 0;
}


Implementer ”write”
ssize_t mygpio_write(struct file *filep, const char __user *ubuf,
size_t count, loff_t *f_pos)
{
int minor, len, value;
char kbuf[MAXLEN];

/*
* retrieve minor from file ptr
*/
minor = MINOR(filep->f_dentry->d_inode->i_rdev);
printk(KERN_ALERT "Writing to MyGpio [Minor] %i \n", minor);

/*
* Check if minor is valid
*/

/*** YOUR CODE HERE ****/

/*
* Copy data from user space
* to kernel space
*/
len = count < MAXLEN ? count : MAXLEN; // set len < MAXLEN

/**** Use copy_from_user to get data ****/
/*** YOUR CODE HERE ****/
copy_from_user(kbuf, ubuf, count);

kbuf[len] = '\0'; // Pad null termination to string
printk("string from user: %s\n", kbuf);

/*
* Convert string to int
*/

/**** Use sscanf to convert string to int ****/
/*** YOUR CODE HERE ****/
sscanf(kbuf,"%i", &value);
printk("value %i\n", value);

value = value > 0 ? 1 : 0;

/*
* Set GPIO port
* (if an output port)
*/

/**** Use gpio_set_value on appropriate port ****/
/*** YOUR CODE HERE ****/
gpio_set_value(139, value);

*f_pos += count;
return count;
}

Implementer ”read”
ssize_t mygpio_read(struct file *filep, char __user *buf,
size_t count, loff_t *f_pos)
{
char readBuf[MAXLEN];
int len, result=-1, minor;

/*
* retrieve minor from file ptr
*/
minor = MINOR(filep->f_dentry->d_inode->i_rdev);
printk(KERN_ALERT "Reading from MyGpio [Minor] %i \n", minor);

/*
* Check if minor is valid
*/

/*** YOUR CODE HERE ****/

/*
* Read GPIO port
* (if an input port)
*/

/*** YOUR CODE HERE ****/
result = gpio_get_value(130);

/*
* Convert int to string
* using sprintf
*/
len=sprintf(readBuf,"%i", result);
len++; // To include null-termination

/*
* Copy string result
* to User Space
*/

/*** YOUR CODE HERE ****/
copy_to_user(buf, readBuf, len);

*f_pos += len;
return len;
}


struct file_operations mygpio_Fops =
{
.owner = THIS_MODULE,
.open = mygpio_open,
.release = mygpio_release,
.write = mygpio_write,
.read = mygpio_read,
};

module_init(mygpio_init);
module_exit(mygpio_exit);

MODULE_DESCRIPTION("My GPIO Module");
MODULE_AUTHOR("IHA ");
MODULE_LICENSE("GPL");


Indsæt modul, node, kørsel af læsningsprogram
insmod mygpio.ko
mknod /dev/wepee c 62
./rd /dev/wepee