OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 5:54 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 12 posts ] 
Author Message
 Post subject: Mouse driver not working
PostPosted: Sat Feb 23, 2019 6:52 pm 
Offline
Member
Member

Joined: Wed Dec 12, 2018 12:16 pm
Posts: 119
I'm trying to do an mouse driver, but I can't detect the mouse. I'm following the "8042" PS/2 Controller and Mouse input.
Here is the code:
Code:
#include "kernel.h"
#include "terminal.h"
#include "irq.h"
#include "bool.h"

typedef enum MouseCommands
{
    MOUSE_ACK = 0xFA,
    MOUSE_IDENTITY = 0xF2,
    MOUSE_DISABLE_DATA = 0xF5,
} MouseCommands;

bool __mouse_self_test;
bool __mouse_has_2channels;
bool __mouse_interface1_test = false, __mouse_interface2_test = false;

void mouse_write(uint8_t val)
{
    outb(0x64, val);
}

uint8_t mouse_read(void)
{
    return inb(0x60);
}

/*
None    Ancient AT keyboard with translation enabled in the PS/Controller (not possible for the second PS/2 port)
0x00    Standard PS/2 mouse
0x03    Mouse with scroll wheel
0x04    5-button mouse
0xAB, 0x41 or 0xAB, 0xC1    MF2 keyboard with translation enabled in the PS/Controller (not possible for the second PS/2 port)
0xAB, 0x83    MF2 keyboard
*/
uint8_t mouse_type(void)
{
    mouse_write(MOUSE_DISABLE_DATA);
    if (mouse_read() == MOUSE_ACK)
    {
        mouse_write(MOUSE_IDENTITY);
        if (mouse_read() == MOUSE_ACK)
            return mouse_read();
    }
}

void mouse_handler(struct regs *r)
{
    /* Nothing to do yet... */
}

int mouse_installer(void)
{
    /* Disabling any other device that can mess up */
    mouse_write(0xAD);
    mouse_write(0xA7);
    /*
    Mouse self test. 0x55 test passed, 0xFC failed
    In some systems, it resets the computer.
    */
    mouse_write(0xAA);
    if (mouse_read() == 0x55)
        __mouse_self_test = true;
    else
        __mouse_self_test = false;

    /* Check if we have 2 channels */
    mouse_write(0xA8);
    if (inb(0x20) & (5 << 0))
    {
        __mouse_has_2channels = false;
    }
    else
    {
        __mouse_has_2channels = true;
        /* Disable second PS/2 port again */
        mouse_write(0xA7);
    }
    /* Interface tests */
    if (__mouse_has_2channels)
    {
        mouse_write(0xAB);
        if (inb(0x60) == 0x00)
        {
            __mouse_interface1_test = true;
            /* Enable port 1! */
            mouse_write(0xA8);
            outb(0x60, 1);
        }
    }
    else
    {
        mouse_write(0xA9);
        if (inb(0x60) == 0x00)
        {
            __mouse_interface2_test = true;
            /* Enable port 2! */
            mouse_write(0xAE);
            outb(0x60, 0);
        }
    }
   

    /* Enable packet streaming */
    mouse_write(0xF4);

    if (inb(0x64) == MOUSE_ACK)
    {
        kputs("mouse detected, received ACK response");
        irq_install_handler(12, mouse_handler);
    }
    else
    {
        kputs("no mouse detected");
        return -1;
    }
}

Also, when I use the mouse_type function, the keyboard driver stop working.


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Sat Feb 23, 2019 9:58 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
Have you sent an End of Interrupt (EOI) to the appropriate PIC(s) when your IRQ handlers are finished? You also seem to be reading port 0x20? That is the master PIC.


Last edited by MichaelPetch on Sun Feb 24, 2019 1:51 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Sat Feb 23, 2019 10:58 pm 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
Code:
void mouse_write(uint8_t val)
{
    outb(0x64, val);
}

uint8_t mouse_read(void)
{
    return inb(0x60);
}

These two need to test to see if the buffer is ready to receive a byte and if there is a byte in the buffer to read. Reading from an empty buffer will return undefined results.

Ben
- http://www.fysnet.net/input_and_output_devices.htm


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Sun Feb 24, 2019 9:11 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
Your code has a variety of issues. Perhaps the biggest is the name: you're trying to write a mouse driver, but most of the code you've written is for the PS/2 controller. Those are separate components, and you should name your functions appropriately to avoid confusion. I recommend also separating it into three drivers: one for the PS/2 controller, one for the mouse, and one for the keyboard.

Yes, the keyboard is also connected to the PS/2 controller. That's why your attempt at identifying the mouse causes the keyboard to stop responding.

Once you have clear separation between code that configures the PS/2 controller and code that configures the keyboard/mouse, I can help you more.


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Sun Feb 24, 2019 9:45 am 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
Octocontrabass wrote:
Your code has a variety of issues. Perhaps the biggest is the name: you're trying to write a mouse driver, but most of the code you've written is for the PS/2 controller. Those are separate components, and you should name your functions appropriately to avoid confusion. I recommend also separating it into three drivers: one for the PS/2 controller, one for the mouse, and one for the keyboard.

Yes, the keyboard is also connected to the PS/2 controller. That's why your attempt at identifying the mouse causes the keyboard to stop responding.

Once you have clear separation between code that configures the PS/2 controller and code that configures the keyboard/mouse, I can help you more.

I have to second this. Octocontrabass' point is exactly what I was thinking but didn't comment at the time. I will add just a little to emphasize his point. On some PS/2 controllers, in fact more than not, you might have the mouse and the keyboard swapped and still work. I haven't tried it myself, but have read numerous sources that say it is available. With this in mind, dividing the drivers into three different sources is a very good point. (I had done this myself long ago)

Ben
- http://www.fysnet.net/input_and_output_devices.htm


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Sun Feb 24, 2019 11:38 am 
Offline
Member
Member

Joined: Wed Dec 12, 2018 12:16 pm
Posts: 119
Here is my code so far:
Code:
#include "kernel.h"
#include "terminal.h"
#include "irq.h"
#include "bool.h"

typedef enum MouseCommands
{
    MOUSE_ACK = 0xFA,
    MOUSE_IDENTITY = 0xF2,
    MOUSE_DISABLE_DATA = 0xF5,
} MouseCommands;

uint8_t offset = 0;
uint8_t buffer[3];
uint8_t mouse_key = 0;
int16_t mouse_x = 0, mouse_y = 0;

void mouse_wait(unsigned char type)
{
    unsigned int time_o = 100000;
    if (type == 0)
    {   
        while (--time_o)
        {
            if ((inb(0x64) & 1) == 1)
            {
                break;
            }
        }
        return;
    }
    else
    {
        while (--time_o)
        {
            if ((inb(0x64) & 2) == 0)
            {
                break;
            }
        }
        return;
    }
}

uint8_t mouse_ctrl_status(void)
{
    mouse_wait(0);
    return inb(0x64);
}

void mouse_send_cmd(uint8_t cmd)
{
    while (1)
   {
       if ((mouse_ctrl_status() & 2) == 0)
      {
           break;
      }
   }
    outb(0x64, cmd);
}

void mouse_send_data(uint8_t data)
{
    while (1)
   {
       if ((mouse_ctrl_status() & 2) == 0)
      {
           break;
      }
   }
    outb(0x60, data);
}



uint8_t mouse_read_data(void)
{
    mouse_wait(0);
    return inb(0x60);
}

/*
None    Ancient AT keyboard with translation enabled in the PS/Controller (not possible for the second PS/2 port)
0x00    Standard PS/2 mouse
0x03    Mouse with scroll wheel
0x04    5-button mouse
0xAB, 0x41 or 0xAB, 0xC1    MF2 keyboard with translation enabled in the PS/Controller (not possible for the second PS/2 port)
0xAB, 0x83    MF2 keyboard
*/
uint8_t mouse_type(void)
{
    mouse_send_cmd(MOUSE_DISABLE_DATA);
    if (mouse_read_data() == MOUSE_ACK)
    {
        mouse_send_cmd(MOUSE_IDENTITY);
        if (mouse_read_data() == MOUSE_ACK)
            return mouse_read_data();
    }
}

void mouse_handler(struct regs *r)
{
    uint8_t __status = mouse_ctrl_status();
    if (!(__status & 0x20))
        return;
    buffer[offset] = mouse_read_data();
    offset = (offset + 1) % 3;

    if (offset == 0)
    {
        mouse_x += buffer[1] - (0x100 & (buffer[0] << (8-4)));
        mouse_y -= buffer[2] - (0x100 & (buffer[0] << (8-5)));
    }
}

void mouse_printpos(void)
{
    char buf[255];
    kputs(itoa(mouse_x, buf, 10)); 
    kputs(itoa(mouse_y, buf, 10));
}

int mouse_installer(void)
{
    uint8_t __status;
    mouse_send_cmd(0xA8);
    mouse_send_cmd(0x20);
    __status = mouse_read_data() | 2;
    mouse_send_data(__status);
    mouse_send_cmd(0xD4);
    mouse_send_data(0xF4);
    mouse_read_data();
    irq_install_handler(12, mouse_handler);
}

In kmain.c I have the mouse_printpos is in a infinite loop, but just prints zeros. And how I saided before, the keyboard does not work. #-o


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Mon Feb 25, 2019 8:23 am 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 296
hextakatt wrote:
Code:
void mouse_handler(struct regs *r)
{
    uint8_t __status = mouse_ctrl_status();
    if (!(__status & 0x20))
        return;
    buffer[offset] = mouse_read_data();
    offset = (offset + 1) % 3;

    if (offset == 0)
    {
        mouse_x += buffer[1] - (0x100 & (buffer[0] << (8-4)));
        mouse_y -= buffer[2] - (0x100 & (buffer[0] << (8-5)));
    }
}

In kmain.c I have the mouse_printpos is in a infinite loop, but just prints zeros. And how I saided before, the keyboard does not work. #-o


Here is problem. You don`t send EOI. After send irq, other interrupts is stop and PIC is waiting for EOI. Change your code:
Code:
void mouse_handler(struct regs *r)
{
    //EOI - End Of Interrupt
    outb(0xA0, 0x20);
    outb(0x20, 0x20);

    ...
}


And I think than http://os-development.000webhostapp.com/mys.html maybe help you.

_________________
https://github.com/VendelinSlezak/BleskOS


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Mon Feb 25, 2019 9:43 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
hextakatt wrote:
In kmain.c I have the mouse_printpos is in a infinite loop, but just prints zeros. And how I saided before, the keyboard does not work. #-o

You're still mixing up the PS/2 controller and the mouse. Your "mouse_send_cmd" and "mouse_send_data" functions are sending commands and data to the PS/2 controller, not the mouse. You must separate the PS/2 controller functions from the mouse functions in your code.

The keyboard doesn't work because you're sending nonsense to the PS/2 controller, and the keyboard is connected to the PS/2 controller the same way the mouse is.

Klakap wrote:
And I think than http://os-development.000webhostapp.com/mys.html maybe help you.

This is a very bad example. It mixes up the PS/2 controller and the mouse, and interferes with the keyboard.


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Mon Feb 25, 2019 10:24 am 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 296
Octocontrabass wrote:
Klakap wrote:
And I think than http://os-development.000webhostapp.com/mys.html maybe help you.

This is a very bad example. It mixes up the PS/2 controller and the mouse, and interferes with the keyboard.


Hm. My driver for mouse is based on it and I have not any mistakes. But I am agree, that it mixes PS/2 and mouse.

_________________
https://github.com/VendelinSlezak/BleskOS


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Mon Feb 25, 2019 12:47 pm 
Offline
Member
Member

Joined: Wed Dec 12, 2018 12:16 pm
Posts: 119
I managed to make the mouse driver work(¿?), but it is very sensitive, with moving the mouse a little the cursor is already in the corner of the screen. How can I change the sensitivity? Also it says that I pressed a mouse key when I not.
Edit:
mouse.c
Code:
#include "kernel.h"
#include "terminal.h"
#include "irq.h"
#include "bool.h"
#include "mouse.h"

typedef enum MouseCommands
{
    MOUSE_ACK = 0xFA,
    MOUSE_IDENTITY = 0xF2,
    MOUSE_ENABLE_PACKETS = 0xF4,
    MOUSE_DISABLE_DATA = 0xF5,
    MOUSE_READ_PORT = 0x60,
    MOUSE_WRITE_PORT = 0x64,
} MouseCommands;


uint8_t offset;
uint8_t buffer[3];
uint8_t mouse_key;
int8_t mouse_x = 40, mouse_y = 12;

void mouse_wait(unsigned char type)
{
    unsigned int time_o = 100000;
    if (type == 0)
    {   
        while (--time_o)
        {
            if ((inb(0x64) & 1) == 1)
            {
                break;
            }
        }
        return;
    }
    else
    {
        while (--time_o)
        {
            if ((inb(0x64) & 2) == 0)
            {
                break;
            }
        }
        return;
    }
}

uint8_t mouse_ctrl_status(void)
{
    mouse_wait(0);
    return inb(0x64);
}

void mouse_send_cmd(uint8_t cmd)
{
    while (1)
   {
       if ((mouse_ctrl_status() & 2) == 0)
      {
           break;
      }
   }
    outb(0x64, cmd);
}

void mouse_send_data(uint8_t data)
{
    mouse_wait(1);
    outb(0x64, 0xD4);
    mouse_wait(1);
    outb(0x60, data);
}



uint8_t mouse_read_data(void)
{
    mouse_wait(0);
    return inb(0x60);
}

/*
None    Ancient AT keyboard with translation enabled in the PS/Controller (not possible for the second PS/2 port)
0x00    Standard PS/2 mouse
0x03    Mouse with scroll wheel
0x04    5-button mouse
0xAB, 0x41 or 0xAB, 0xC1    MF2 keyboard with translation enabled in the PS/Controller (not possible for the second PS/2 port)
0xAB, 0x83    MF2 keyboard
*/
uint8_t mouse_type(void)
{
    mouse_send_cmd(MOUSE_DISABLE_DATA);
    if (mouse_read_data() == MOUSE_ACK)
    {
        mouse_send_cmd(MOUSE_IDENTITY);
        if (mouse_read_data() == MOUSE_ACK)
            return mouse_read_data();
    }
}

void mouse_handler(struct regs *r)
{
    uint8_t __status = mouse_ctrl_status();
    if (!(__status & 0x20))
        return;
    buffer[offset] = mouse_read_data();
    offset = (offset + 1) % 3;

    if (offset == 0)
    {
        mouse_key = buffer[0];
        mouse_x += buffer[1] - (0x100 & (buffer[0] << (8-4)));
        if (mouse_x < 0) mouse_x = 0;
        if (mouse_x >= 80) mouse_x = 79;

        mouse_y -= buffer[2] - (0x100 & (buffer[0] << (8-5)));
        if (mouse_y < 0) mouse_y = 0;
        if (mouse_y >= 25) mouse_y = 24;
    }
    outb(0xA0, 0x20);
    outb(0x20, 0x20);
}

void mouse_get_pos(int8_t x, int8_t y)
{
    x = mouse_x;
    y = mouse_y;
}

MOUSE_DATA mouse_get_key(void)
{
    for (uint8_t cout = 0; cout < 3; ++cout)
    {
        if ((buffer[0] & (0x01 << cout)) != (mouse_key & (0x01 << cout)))
        {
            kputs("rgh");//return MOUSE_RIGHT_KEY;
        }
    }
}

void mouse_printpos(void)
{
    char buf[255];
    kputs("X: ");
    kputs(itoa(mouse_x, buf, 10)); 
    kputs(" Y: ");
    kputs(itoa(mouse_y, buf, 10));
    if (mouse_get_key() == MOUSE_RIGHT_KEY)
    {
        kputs("  Right key!");
    }
    else if (mouse_get_key() == MOUSE_LEFT_KEY)
    {
        kputs("  Left key!");
    }
   
    kputs("\r");
}

void mouse_installer(void)
{
   uint8_t status = 0;
   
    mouse_wait(1);
    outb(MOUSE_WRITE_PORT,0xA8);

    mouse_wait(1);
    outb(MOUSE_WRITE_PORT,0x20);

    mouse_wait(0);
    status = (inb(MOUSE_READ_PORT) | 2);

    mouse_wait(1);
    outb(MOUSE_WRITE_PORT, 0x60);

    mouse_wait(1);
    outb(MOUSE_READ_PORT, status);

    //set sample rate
    mouse_send_data(0xF3);
    mouse_read_data();

    mouse_send_data(200);
    mouse_read_data();

    //set sample rate
    mouse_send_data(0xF3);
    mouse_read_data();

    mouse_send_data(200);
    mouse_read_data();

    //set sample rate
    mouse_send_data(0xF3);
    mouse_read_data();

    mouse_send_data(80);
    mouse_read_data();

    //start sending packets
    mouse_send_data(MOUSE_ENABLE_PACKETS);
    mouse_read_data();

    irq_install_handler(12, mouse_handler);
}

and mouse.h
Code:
#ifndef _MOUSE_H_
#define _MOUSE_H_

typedef enum
{
   MOUSE_LEFT_KEY = 0x10,
   MOUSE_RIGHT_KEY = 0x11,
}MOUSE_DATA;

void mouse_handler(struct regs *r);
void mouse_printpos(void);
void mouse_installer(void);

#endif


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Tue Feb 26, 2019 7:08 am 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 296
hextakatt wrote:
I managed to make the mouse driver work(¿?), but it is very sensitive, with moving the mouse a little the cursor is already in the corner of the screen. How can I change the sensitivity?


You mustn`t change sensitivity. You must write good driver for moving cursor. In LightningOS kernel 0.1.1 is moving cursor quite well with:

Code:
     //move right//
     if(mouse_move_x==0x01 || mouse_move_x==0x04 || mouse_move_x==0x05 || mouse_move_x==0x07 || mouse_move_x==0x09 || mouse_move_x==0x0A) {
         if(mouse_x<79) {
             //move cursor
         }
     }

     //move left//
     if(mouse_move_x==0xFE || mouse_move_x==0xFB || mouse_move_x==0xFA || mouse_move_x==0xF8 || mouse_move_x==0xF6 || mouse_move_x==0xF5) {
        if(mouse_x>0) {
             //move cursor
         }           
     }

     //move up//
     if(mouse_move_y==0x01 || mouse_move_y==0x04 || mouse_move_y==0x05 || mouse_move_y==0x07 || mouse_move_y==0x09 || mouse_move_y==0x0A) {
         if(mouse_y>0) {
             //move cursor
         }         
     }

     //move down//
     if(mouse_move_y==0xFE || mouse_move_y==0xFB || mouse_move_y==0xFA || mouse_move_x==0xF8 || mouse_move_x==0xF6 || mouse_move_x==0xF5) {
         if(mouse_y<24) {
             //move cursor
         }
     }


Did you see the idea?

hextakatt wrote:
Code:
MOUSE_DATA mouse_get_key(void)
{
    for (uint8_t cout = 0; cout < 3; ++cout)
    {
        if ((buffer[0] & (0x01 << cout)) != (mouse_key & (0x01 << cout)))
        {
            kputs("rgh");//return MOUSE_RIGHT_KEY;
        }
    }
}

typedef enum
{
   MOUSE_LEFT_KEY = 0x10,
   MOUSE_RIGHT_KEY = 0x11,
}MOUSE_DATA;



What are you doing here? Read part Receiving data from mouse of http://os-development.000webhostapp.com/mys.html carefully. The most important sentence for you is(translate):
Quote:
In fourth byte mouse send information about pressed keys. If in it is 0x10, left key is pressed. If in it is 0x20, right key is pressed. If in it is 0x40, middle key is pressed.


You can detect it in mouse handler:
Code:
    if (mouse_buffer[3] & 0x4) {
        //middle key is pressed
    }

    if (mouse_buffer[3] & 0x2) {           
        //right key is pressed
    }

    if (mouse_bytes[3] & 0x1) {
        //left key is pressed
    }


I test it and it work in Bochs, Qemu and Virtualbox. Good luck!

_________________
https://github.com/VendelinSlezak/BleskOS


Top
 Profile  
 
 Post subject: Re: Mouse driver not working
PostPosted: Thu Feb 28, 2019 4:45 pm 
Offline
Member
Member

Joined: Wed Dec 12, 2018 12:16 pm
Posts: 119
Oh, sorry I didn't answer, I was busy.
Anyway, I don't know what made me think I would need a mouse driver, if I don't even have a GUI, or even a functional OS. :lol:
Thanks anyway, maybe it will help me someday! :)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], DotBot [Bot], SemrushBot [Bot] and 60 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group