USB to quadrature encoder so you use modern USB mice on the Amiga.

Dependencies:   USBHOST

Introduction

This project is devised so you can attach a mouse (and/or steam controller) to a classic computer such as an Amiga. Computers of that era use bus mice which just send the pulses from the quadrature encoder wheels on the mouse directly to the computer with out interpretation.

Use

Program a build base on this repository to a STM32 nucleo board (I tested this on a NUCLEO STM32F411 board). You will then need connect the Nucleo board to your computers joystick and mouse ports as follows (if you only use a mouse you won't need a joystick lead :) ). If you use a steam controller the thumb stick and left pad are mapped to the Amiga's joystick port and the right pad and front trigger buttons are mapped to the mouse.

mouse_port_forward(D10) - Amiga Joystick pin 1
mouse_port_back(D11) - Amiga Joystick pin 2
mouse_port_left(D12) - Amiga Joystick pin 3
mouse_port_right(D13) - Amiga Joystick pin 4
mouse_port_left_button(D9) - Amiga Joystick pin 6
GND - Amiga joystick pin 8
mouse_port_right_button(D8) - Amiga Joystick pin 9

game_port_forward(PC_8) - Amiga Joystick pin 1
game_port_back(PC_12) - Amiga Joystick pin 2
game_port_left(PC_10) - Amiga Joystick pin 3
game_port_right(PC_11) - Amiga Joystick pin 4
game_port_left_button(PC_6) - Amiga Joystick pin 6
GND - Amiga joystick pin 8
game_port_right_button(PC_5) - Amiga Joystick pin 9

It is best NOT to use the 5V pin from the Amiga's joystick port to power the nucleo board as the power suppled by the Amiga is limited!

You will also need to attach a USB socket to the nuclea board so you can use the Nucleo's usb OTG support.

(1) 5V     - 5v
(2) PA11 - Data-
(3) PA12 - Data+
(4) GND - GND

According to the usb spec it is required to attach a 15k ohm resistor between D-/+ and ground but it appears the USB host works fine without this.

NOTES:

  • The right touch pad can take a little while before it generates mouse events.
  • I found that the STM USBHost library needed some modifications to correctly work with boot protocol (it needs to call set protocol) and hubs (getSize doesn't report the correct size). This project uses a modified USB host library with fixes for this (they will need a little more work before I can create a pull request).
Committer:
geekylou
Date:
Thu Aug 17 22:13:12 2017 +0000
Revision:
0:d0c521cb6c90
Child:
1:ab916b5c1a4d
First working version.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
geekylou 0:d0c521cb6c90 1 #include "mbed.h"
geekylou 0:d0c521cb6c90 2 #include "USBHostMSD.h"
geekylou 0:d0c521cb6c90 3 #include "USBHostMouse.h"
geekylou 0:d0c521cb6c90 4 #include "USBHostKeyboard.h"
geekylou 0:d0c521cb6c90 5 #include "FATFileSystem.h"
geekylou 0:d0c521cb6c90 6 #include <stdlib.h>
geekylou 0:d0c521cb6c90 7
geekylou 0:d0c521cb6c90 8 int x_cur;
geekylou 0:d0c521cb6c90 9 int y_cur;
geekylou 0:d0c521cb6c90 10
geekylou 0:d0c521cb6c90 11 DigitalOut led(LED1);
geekylou 0:d0c521cb6c90 12 DigitalOut led2(LED2);
geekylou 0:d0c521cb6c90 13 DigitalOut led3(LED3);
geekylou 0:d0c521cb6c90 14 DigitalOut led4(A0);
geekylou 0:d0c521cb6c90 15
geekylou 0:d0c521cb6c90 16
geekylou 0:d0c521cb6c90 17 void onMouseEvent(uint8_t buttons, int8_t x, int8_t y, int8_t z) {
geekylou 0:d0c521cb6c90 18 //printf("buttons: %d, x: %d, y: %d, z: %d\r\n", buttons, x, y, z);
geekylou 0:d0c521cb6c90 19
geekylou 0:d0c521cb6c90 20 led = buttons & 1;
geekylou 0:d0c521cb6c90 21 led4 = buttons & 0x2;
geekylou 0:d0c521cb6c90 22
geekylou 0:d0c521cb6c90 23 while (x != 0 || y != 0)
geekylou 0:d0c521cb6c90 24 {
geekylou 0:d0c521cb6c90 25 if (x >0)
geekylou 0:d0c521cb6c90 26 {
geekylou 0:d0c521cb6c90 27 x--;
geekylou 0:d0c521cb6c90 28 x_cur = (x_cur+1) & 3;
geekylou 0:d0c521cb6c90 29 }
geekylou 0:d0c521cb6c90 30 else if (x < 0)
geekylou 0:d0c521cb6c90 31 {
geekylou 0:d0c521cb6c90 32 x++;
geekylou 0:d0c521cb6c90 33 x_cur = (x_cur-1) & 3;
geekylou 0:d0c521cb6c90 34 }
geekylou 0:d0c521cb6c90 35
geekylou 0:d0c521cb6c90 36 if (y >0)
geekylou 0:d0c521cb6c90 37 {
geekylou 0:d0c521cb6c90 38 y--;
geekylou 0:d0c521cb6c90 39 y_cur = (y_cur+1) & 3;
geekylou 0:d0c521cb6c90 40 }
geekylou 0:d0c521cb6c90 41 else if (y < 0)
geekylou 0:d0c521cb6c90 42 {
geekylou 0:d0c521cb6c90 43 y++;
geekylou 0:d0c521cb6c90 44 y_cur = (y_cur-1) & 3;
geekylou 0:d0c521cb6c90 45 }
geekylou 0:d0c521cb6c90 46
geekylou 0:d0c521cb6c90 47 //printf("x %d y %d\r\n", x, y);
geekylou 0:d0c521cb6c90 48
geekylou 0:d0c521cb6c90 49
geekylou 0:d0c521cb6c90 50 led2 = ((x_cur + 1)/2) & 1;
geekylou 0:d0c521cb6c90 51 led3 = (x_cur/2) & 0x1;
geekylou 0:d0c521cb6c90 52
geekylou 0:d0c521cb6c90 53 //led = ((y_cur + 1)/2) & 1;
geekylou 0:d0c521cb6c90 54 //led4 = (y_cur/2) & 0x1;
geekylou 0:d0c521cb6c90 55
geekylou 0:d0c521cb6c90 56 Thread::wait(1);
geekylou 0:d0c521cb6c90 57 }
geekylou 0:d0c521cb6c90 58 }
geekylou 0:d0c521cb6c90 59
geekylou 0:d0c521cb6c90 60 void mouse_task(void const *) {
geekylou 0:d0c521cb6c90 61
geekylou 0:d0c521cb6c90 62 USBHostMouse mouse;
geekylou 0:d0c521cb6c90 63 printf("mouse started\n");
geekylou 0:d0c521cb6c90 64 while(1) {
geekylou 0:d0c521cb6c90 65
geekylou 0:d0c521cb6c90 66 // try to connect a USB mouse
geekylou 0:d0c521cb6c90 67 while(!mouse.connect())
geekylou 0:d0c521cb6c90 68 Thread::wait(500);
geekylou 0:d0c521cb6c90 69
geekylou 0:d0c521cb6c90 70 // when connected, attach handler called on mouse event
geekylou 0:d0c521cb6c90 71 mouse.attachEvent(onMouseEvent);
geekylou 0:d0c521cb6c90 72
geekylou 0:d0c521cb6c90 73 // wait until the mouse is disconnected
geekylou 0:d0c521cb6c90 74 while(mouse.connected())
geekylou 0:d0c521cb6c90 75 Thread::wait(500);
geekylou 0:d0c521cb6c90 76 printf("mouse seen disconnected\n");
geekylou 0:d0c521cb6c90 77 }
geekylou 0:d0c521cb6c90 78 }
geekylou 0:d0c521cb6c90 79 void onKey(uint8_t key) {
geekylou 0:d0c521cb6c90 80 printf("Key: %c\r\n", key);
geekylou 0:d0c521cb6c90 81 }
geekylou 0:d0c521cb6c90 82 void keyboard_task(void const *) {
geekylou 0:d0c521cb6c90 83
geekylou 0:d0c521cb6c90 84 USBHostKeyboard keyboard;
geekylou 0:d0c521cb6c90 85
geekylou 0:d0c521cb6c90 86 while(1) {
geekylou 0:d0c521cb6c90 87 // try to connect a USB keyboard
geekylou 0:d0c521cb6c90 88 while(!keyboard.connect())
geekylou 0:d0c521cb6c90 89 Thread::wait(500);
geekylou 0:d0c521cb6c90 90
geekylou 0:d0c521cb6c90 91 // when connected, attach handler called on keyboard event
geekylou 0:d0c521cb6c90 92 keyboard.attach(onKey);
geekylou 0:d0c521cb6c90 93
geekylou 0:d0c521cb6c90 94 // wait until the keyboard is disconnected
geekylou 0:d0c521cb6c90 95 while(keyboard.connected())
geekylou 0:d0c521cb6c90 96 Thread::wait(500);
geekylou 0:d0c521cb6c90 97 }
geekylou 0:d0c521cb6c90 98 }
geekylou 0:d0c521cb6c90 99
geekylou 0:d0c521cb6c90 100
geekylou 0:d0c521cb6c90 101
geekylou 0:d0c521cb6c90 102 void msd_task(void const *) {
geekylou 0:d0c521cb6c90 103
geekylou 0:d0c521cb6c90 104 USBHostMSD msd;
geekylou 0:d0c521cb6c90 105 int i = 0;
geekylou 0:d0c521cb6c90 106 FATFileSystem fs("usb");
geekylou 0:d0c521cb6c90 107 int err;
geekylou 0:d0c521cb6c90 108 printf("wait for usb memory stick insertion\n");
geekylou 0:d0c521cb6c90 109 while(1) {
geekylou 0:d0c521cb6c90 110
geekylou 0:d0c521cb6c90 111 // try to connect a MSD device
geekylou 0:d0c521cb6c90 112 while(!msd.connect()) {
geekylou 0:d0c521cb6c90 113 Thread::wait(500);
geekylou 0:d0c521cb6c90 114 }
geekylou 0:d0c521cb6c90 115 if (fs.mount(&msd) != 0) continue;
geekylou 0:d0c521cb6c90 116 else
geekylou 0:d0c521cb6c90 117 printf("file system mounted\n");
geekylou 0:d0c521cb6c90 118
geekylou 0:d0c521cb6c90 119 if (!msd.connect()) {
geekylou 0:d0c521cb6c90 120 continue;
geekylou 0:d0c521cb6c90 121 }
geekylou 0:d0c521cb6c90 122
geekylou 0:d0c521cb6c90 123 // in a loop, append a file
geekylou 0:d0c521cb6c90 124 // if the device is disconnected, we try to connect it again
geekylou 0:d0c521cb6c90 125
geekylou 0:d0c521cb6c90 126 // append a file
geekylou 0:d0c521cb6c90 127 File file;
geekylou 0:d0c521cb6c90 128 err = file.open(&fs, "test1.txt", O_WRONLY | O_CREAT |O_APPEND);
geekylou 0:d0c521cb6c90 129
geekylou 0:d0c521cb6c90 130 if (err == 0) {
geekylou 0:d0c521cb6c90 131 char tmp[100];
geekylou 0:d0c521cb6c90 132 sprintf(tmp,"Hello fun USB stick World: %d!\r\n", i++);
geekylou 0:d0c521cb6c90 133 file.write(tmp,strlen(tmp));
geekylou 0:d0c521cb6c90 134 sprintf(tmp,"Goodbye World!\r\n");
geekylou 0:d0c521cb6c90 135 file.write(tmp,strlen(tmp));
geekylou 0:d0c521cb6c90 136 file.close();
geekylou 0:d0c521cb6c90 137 } else {
geekylou 0:d0c521cb6c90 138 printf("FILE == NULL\r\n");
geekylou 0:d0c521cb6c90 139 }
geekylou 0:d0c521cb6c90 140 Thread::wait(500);
geekylou 0:d0c521cb6c90 141 printf("again\n");
geekylou 0:d0c521cb6c90 142 // if device disconnected, try to connect again
geekylou 0:d0c521cb6c90 143 while (msd.connected()) {
geekylou 0:d0c521cb6c90 144 Thread::wait(500);
geekylou 0:d0c521cb6c90 145 }
geekylou 0:d0c521cb6c90 146 while (fs.unmount() < 0) {
geekylou 0:d0c521cb6c90 147 Thread::wait(500);
geekylou 0:d0c521cb6c90 148 printf("unmount\n");
geekylou 0:d0c521cb6c90 149 }
geekylou 0:d0c521cb6c90 150 }
geekylou 0:d0c521cb6c90 151 }
geekylou 0:d0c521cb6c90 152
geekylou 0:d0c521cb6c90 153 int main() {
geekylou 0:d0c521cb6c90 154 Thread msdTask(msd_task, NULL, osPriorityNormal, 1024 * 4);
geekylou 0:d0c521cb6c90 155 Thread mouseTask(mouse_task, NULL, osPriorityNormal, 1024* 4);
geekylou 0:d0c521cb6c90 156 Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 1024 * 4);
geekylou 0:d0c521cb6c90 157
geekylou 0:d0c521cb6c90 158 int x,y = 0;
geekylou 0:d0c521cb6c90 159 for(y=-10; y<10; y++)
geekylou 0:d0c521cb6c90 160 {
geekylou 0:d0c521cb6c90 161 x = y & 3;
geekylou 0:d0c521cb6c90 162 printf("phase %d[%d] %d\r\n",((x + 1)/2) & 1, x, (x/2) & 0x1 );
geekylou 0:d0c521cb6c90 163 }
geekylou 0:d0c521cb6c90 164 while(1) {
geekylou 0:d0c521cb6c90 165 //led=!led;
geekylou 0:d0c521cb6c90 166 Thread::wait(500);
geekylou 0:d0c521cb6c90 167 }
geekylou 0:d0c521cb6c90 168 }