30-PS2_Mouse-Library (STM32F4)

Mit dieser Library kann eine PS2-Maus an die STM32F4-CPU angeschlossen werden.

Zum Betrieb wird eine externe Interrupt-Leitung und ein normaler GPIO-Pin benötigt. Ich habe PB7 und PA8 am Discovery-Board benutzt.

Die Maus muss nach dem Init gepollt werden und liefert in einer Struktur die Koordinaten Werte für die X- und Y-Achse, den Status von zwei Maustasten und falls es eine Intelli-Maus ist noch den Wert der Z-Achse, was dem Mausrad entspricht.
Hinweis : Die Maus braucht nach PowerOn ca 500ms bevor sie bereit ist.

Mann kann (bzw. muss) für alle 3 Achsen einen Maximumwert im H-File einstellen, damit kein Überlauf entstehen kann. Ich hab im Moment die Auflösung vom Display (320×240) eingestellt…die Zahlen sind aber beliebig.

Die Maus die ich hier habe läuft nur mit 5V. Ich hab sie direkt an die GPIOs angeschlossen (ohne Pegelwandler) das scheint zu funktionieren.

Wegen der Interrupt-Leitung wird auch die Library “STM32_UB_EXT_INT5TO9″ benötigt.

PS2-Steckerbelegung :

ps2

Benutzte Pins :

1
2
Clock an PB7 (per externem Interrupt-7)
Data an PA8

Voraussetzungen :

1
2
Benutzte Module der CooCox-IDE : GPIO
Benutzte Librarys : STM32_UB_EXT_INT5TO9

Enumerationen :

1
2
3
4
5
typedef enum {
  MOUSE_INAKTIV = 0,    // Mouse abgeschaltet
  MOUSE_AKTIV,          // Mouse eingeschaltet
  MOUSE_NEW_DATA        // Neue Daten vorhanden
}PS2_MOUSE_STATUS_t;

.

1
2
3
4
5
6
7
typedef enum {
  MOUSE_SPEED_10 =0,    // 10 Messungen pro sek (100ms)
  MOUSE_SPEED_20,       // 20 Messungen pro sek (50ms)
  MOUSE_SPEED_40,       // 40 Messungen pro sek (25ms)
  MOUSE_SPEED_60,       // 60 Messungen pro sek (16,6ms)
  MOUSE_SPEED_80        // 80 Messungen pro sek (12,5ms)
}PS2_MOUSE_SPEED_t;

.

1
2
3
4
typedef enum {
  BTN_RELEASED =0,      // Taste losgelassen
  BTN_PRESSED           // Taste betätigt
}PS2_MOUSE_BTN;

Struktur der Mausdaten :

1
2
3
4
5
6
7
8
typedef struct {
  PS2_MOUSE_BTN btn_left;     // Status der linken Maustaste
  PS2_MOUSE_BTN btn_right;    // Status der rechten Maustaste
  uint16_t xpos;              // aktuelle X-Pos
  uint16_t ypos;              // aktuelle Y-Pos
  uint16_t zpos;              // aktuelle Z-Pos (Mausrad)
}PS2_MOUSE_DATA_t;
PS2_MOUSE_DATA_t PS2_MOUSE_DATA;

Funktionen :

1
2
3
void UB_PS2_Mouse_Init(void);                            // zum initialisieren der Maus
ErrorStatus UB_PS2_Mouse_Start(PS2_MOUSE_SPEED_t mode);  // zum aktivieren der maus
PS2_MOUSE_STATUS_t UB_PS2_Mouse_GetData(void);           // zum Abfragen der Mausdaten

Beispiel :

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
//--------------------------------------------------------------
// File     : main.c
// Datum    : 03.04.2013
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F4
// IDE      : CooCox CoIDE 1.7.0
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der PS2-Mouse-Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_ps2_mouse.h"
#include "stm32_ub_led.h"
 
void Delay(volatile uint32_t nCount)
{
  while(nCount--)
  {
  }
}
 
int main(void)
{
  PS2_MOUSE_STATUS_t check;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // Init der LEDs
  UB_Led_Init();
 
  // Init der PS2-Maus
  UB_PS2_Mouse_Init();
 
  // kleine Pause
  Delay(50000000);
 
  // PS2-Maus aktivieren (10 samples/sec)
  UB_PS2_Mouse_Start(MOUSE_SPEED_10);
 
  while(1)
  {
    // Maus-Daten abfragen
    check=UB_PS2_Mouse_GetData();
    if(check==MOUSE_INAKTIV) {
      UB_Led_On(LED_RED); // keine Maus vorhanden
    }
    else if(check==MOUSE_NEW_DATA){
      UB_Led_Toggle(LED_GREEN); // neue Daten vorhanden
 
      // Blaue LED mit linker Maustaste ein/ausschalten
      if(PS2_MOUSE_DATA.btn_left==BTN_PRESSED) UB_Led_On(LED_BLUE); else UB_Led_Off(LED_BLUE);
    }
  }
}

Hier die Library zum Download :

ub_stm32f4_ps2_mouse_v100

Hier der komplette CooCox-Projektordner zum Download :

Demo_30_PS2_MOUSE

3 Antworten auf 30-PS2_Mouse-Library (STM32F4)

  1. Pavel Negrobov sagt:

    Hi. I don’t know German, so I will write English. Sorry, it’s some bad, I am russian.

    I tried your PS/2 mouse with my STM32F4Discovery. And I got very different results with my 5 different PS/2 mouses.
    1. Old Genius Netscroll+Eye optical mouse, approximately 2002 year release. Driver works very fine.
    2. Old ball mouse without wheel from end 199x years. Don’t works, because it is not Intellimouse, it is standard mouse, and don’t understand F2h command. Your driver retuns error during initialization in this case. Why? Although all decoding algorithm fine understands both types of mouses and works correctly. I fixed it:

    // warte auf ID
    P_PS2_Mouse_Timeout_RX ( 50000 );
    // if(P_PS2_Mouse_Timeout_RX(50000)==ERROR)
    // return(ERROR);
    3. Two modern Logitech RX250 USB/PS2 mouses. One of them works, other - not. I still do not understand why.
    4. Modern PS/2 mouse, marked as "Trust". Does not work. I researched this mouse a little. On your driver it does not generate interrupt. I some rewrite P_PS2_Mouse_Send procedure:
    static ErrorStatus P_PS2_Mouse_Send ( uint8_t dataByte )
    {
    GPIO_InitTypeDef GPIO_InitStruct;

    PS2_MOUSE_VAR.receive_code = 0;

    // Режим передачи
    // PA3 (данные) – выход
    P_PS2_Mouse_SetGPIO_TX ( );

    // PA4 (CLK) – выход
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init ( GPIOA, &GPIO_InitStruct );

    // PA3, PA4 := 1
    GPIO_SetBits ( GPIOA, GPIO_Pin_3 );// Data := 1
    GPIO_SetBits ( GPIOA, GPIO_Pin_4 );// Clk := 1

    delay ( 300 );// 300 mks
    GPIO_ResetBits ( GPIOA, GPIO_Pin_4 );// Clk := 0
    delay ( 300 );// 300 mks
    GPIO_ResetBits ( GPIOA, GPIO_Pin_3 );// Data := 0
    delay ( 10 );// 10 mks
    GPIO_SetBits ( GPIOA, GPIO_Pin_4 );// CLK := 1

    PS2_MOUSE_VAR.mode = TX_MODE;// Transmit mode
    PS2_MOUSE_VAR.send_code = dataByte;
    PS2_MOUSE_VAR.receive_code = 0;

    // PA4 – Clk := 1
    GPIO_SetBits ( GPIOA, GPIO_Pin_4 );

    UB_Ext_INT4_Init ( );

    if ( P_PS2_Mouse_Timeout_TX ( 50000 ) == ERROR )
    return ERROR;

    if ( P_PS2_Mouse_Timeout_RX ( 50000 ) == ERROR )
    return ERROR;

    if ( PS2_MOUSE_VAR.receive_code != PS2_MOUSE_CMD_ACK )
    return ERROR;

    return SUCCESS;
    } // P_PS2_Mouse_Send

    This algorithm taken from some Arduino code.
    After this I received all interrupts, but most mouse commands returns undocumented code F8h or FCh – error.

    What are you think about this?

    • admin_ub sagt:

      hi,
      2.) the Command F2h “Get Device ID” is a standard PS/2 Command. see http://www.computer-engineering.org/ps2mouse/ . the mouse MUST send a answer. The only unknown is the delay time between the request and the answer from the mouse. To spare a timer i used only a for-n loop…so try to increment the delay and check if the mouse send an ID-Code. Without receiving a valid ID-Code my driver set an error. “MOUSE_TYP_UNKNOWN”

      4.) a return code FCh is a “error” or “NACK” command from the mouse.

      sorry, but i didn’t spent a lot of time in this library, so you must fix this at your own. I think the delay times are a point to start. and read the doku i linked maybe my software is not 100% implemented the right protocol.

  2. Pavel Negrobov sagt:

    Thanks.
    If I got new results of my researches, I shall write this.


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Noch keine Bewertungen)
Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert