Toon posts:

[C, Linux] Muis driver krijgt 4x dezelfde beweging door

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik moet voor school een muisdrivertje voor linux gaan schrijven. Nou, het is niet echt een driver voor XFree86, het zet in een log alle bewegingen en gespankte knoppen. Echter als je de muis een pixel beweegt, geeft ie aan dat het 4x die pixel verschoven is. Mijn muis is een Logitech Wheel mouse ps/2.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/system.h>

#define NO_BUTTONS 0x08
#define MOUSE_BASE 0x60
#define L_DOWN     0x01
#define R_DOWN     0x02
#define M_DOWN     0x04

static int cnt = 0;
static int xpos = 0, ypos = 0;
static int wheel = 0;
void start_tasklet(unsigned long);
DECLARE_TASKLET(dev_tasklet, start_tasklet, 0);


struct mds {
    unsigned char buttons[4];
};

static struct mds mousedata;

void irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
    mousedata.buttons[cnt++] = inb(MOUSE_BASE);
    if (cnt == 4)
    {
        cnt = 0;
        tasklet_schedule(&dev_tasklet);
    }
    tasklet_schedule(&dev_tasklet);
}

void start_tasklet(unsigned long foobar)
{
    if (mousedata.buttons[0] == NO_BUTTONS)
    {
        /* printk(KERN_INFO "Geen knoppies ingedrukt\n"); */
    }
    else
    {
        if ((mousedata.buttons[0] & L_DOWN) == L_DOWN)
            printk(KERN_INFO "L_DOWN\n");
        if ((mousedata.buttons[0] & R_DOWN) == R_DOWN)
            printk(KERN_INFO "R_DOWN, %x, %x\n", xpos, ypos);
        if ((mousedata.buttons[0] & M_DOWN) == M_DOWN)
            printk(KERN_INFO "M_DOWN\n");
    }
    if (mousedata.buttons[1] < 127)
        xpos = xpos + mousedata.buttons[1];
    else
        xpos = xpos + (mousedata.buttons[1] - 0x100);
    if (mousedata.buttons[2] < 127)
        ypos = ypos - mousedata.buttons[2];
    else
        ypos = ypos - (mousedata.buttons[2] - 0x100);
    if (mousedata.buttons[3] < 127)
        wheel = mousedata.buttons[3];
    else
        wheel = (mousedata.buttons[3] - 0x100);
    printk(KERN_INFO "xpos = %d, ypos = %d, wheel = %d\n", xpos, ypos, wheel);
}

int init_module(void)
{
    if (request_irq(12, irq_handler, SA_SHIRQ, "test_mouse", &mousedata))
    {
        printk(KERN_INFO "Interrupt aanvragen nie goed gegaan\n");
        return -EBUSY;
    }
    return 0;
}

void cleanup_module(void)
{
    free_irq(12, &mousedata);
}


Ook zie je
code:
1
2
3
4
if (mousedata.buttons[2] < 127)
    ypos = ypos - mousedata.buttons[2];
else
    ypos = ypos - (mousedata.buttons[2] - 0x100);

dit is om een unsigned char te converteren naar een signed integer, maar is hier geen mooiere methode voor?

Verwijderd

Hé dit klinkt als een opdracht die ik vorig jaar moest maken voor comp3. :7
Jij zit toch ook niet toevallig op de HRO? :*)

Verwijderd

Topicstarter
ja, jij ook :P!

heb je je uiteindelijke resultaat nog toevallig>?

Verwijderd

Topicstarter
Ik ben er zelf al achter gekomen waarom alles 4x doorkwam. Iedereen vriendelijk bedankt voor de hulp (!). Maar goed, voor degenen die het toch nog willen weten wat eraan mankeerde:

void irq_handler(int irq, void *dev_id, struct pt_regs *regs)
{
mousedata.buttons[cnt++] = inb(MOUSE_BASE);
if (cnt == 4)
{
cnt = 0;
tasklet_schedule(&dev_tasklet);
}
tasklet_schedule(&dev_tasklet);
}

haal die onderste tasklet_schedule(&dev_tasklet); weg