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 :
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 :
Hier der komplette CooCox-Projektordner zum Download :
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?
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.
Thanks.
If I got new results of my researches, I shall write this.