OpenMoCo / SpaceBall

Dependents:   SpaceBall_Example

Committer:
jocis
Date:
Wed Sep 03 07:36:43 2014 +0000
Revision:
4:f953792e45cb
Parent:
2:a7c0fcd157f7
Added documentation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jocis 1:e6282b645d9b 1 #include "SpaceBall.h"
jocis 1:e6282b645d9b 2
jocis 2:a7c0fcd157f7 3 #define Sleep(x) wait_ms(x)
jocis 1:e6282b645d9b 4
jocis 2:a7c0fcd157f7 5 //extern Serial pc;
jocis 1:e6282b645d9b 6
jocis 1:e6282b645d9b 7 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 8
jocis 1:e6282b645d9b 9 /*
jocis 1:e6282b645d9b 10 Convert characters to nibbles
jocis 1:e6282b645d9b 11 */
jocis 1:e6282b645d9b 12 int DecodeSM(char c)
jocis 1:e6282b645d9b 13 {
jocis 1:e6282b645d9b 14 int n;
jocis 1:e6282b645d9b 15
jocis 1:e6282b645d9b 16 switch (c) {
jocis 1:e6282b645d9b 17 case '0': n = 0; break;
jocis 1:e6282b645d9b 18 case 'A': n = 1; break;
jocis 1:e6282b645d9b 19 case 'B': n = 2; break;
jocis 1:e6282b645d9b 20 case '3': n = 3; break;
jocis 1:e6282b645d9b 21 case 'D': n = 4; break;
jocis 1:e6282b645d9b 22 case '5': n = 5; break;
jocis 1:e6282b645d9b 23 case '6': n = 6; break;
jocis 1:e6282b645d9b 24 case 'G': n = 7; break;
jocis 1:e6282b645d9b 25 case 'H': n = 8; break;
jocis 1:e6282b645d9b 26 case '9': n = 9; break;
jocis 1:e6282b645d9b 27 case ':': n = 10; break;
jocis 1:e6282b645d9b 28 case 'K': n = 11; break;
jocis 1:e6282b645d9b 29 case '<': n = 12; break;
jocis 1:e6282b645d9b 30 case 'M': n = 13; break;
jocis 1:e6282b645d9b 31 case 'N': n = 14; break;
jocis 1:e6282b645d9b 32 case '?': n = 15; break;
jocis 1:e6282b645d9b 33 default: n = 0; break;
jocis 1:e6282b645d9b 34 }
jocis 1:e6282b645d9b 35
jocis 1:e6282b645d9b 36 return(n);
jocis 1:e6282b645d9b 37 }
jocis 1:e6282b645d9b 38
jocis 1:e6282b645d9b 39 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 40
jocis 1:e6282b645d9b 41 void SpaceBall::InitSB()
jocis 1:e6282b645d9b 42 {
jocis 1:e6282b645d9b 43 m_resetoccured=0;
jocis 1:e6282b645d9b 44
jocis 2:a7c0fcd157f7 45 m_spaceball4000 = 0; /* re-determine which type it is */
jocis 1:e6282b645d9b 46 m_leftymode4000 = 0; /* re-determine if its in lefty mode */
jocis 1:e6282b645d9b 47
jocis 2:a7c0fcd157f7 48 _fScaleT = 1.0 / 5000.0;
jocis 2:a7c0fcd157f7 49 _fScaleR = 1.0 / 2000.0;
jocis 2:a7c0fcd157f7 50
jocis 1:e6282b645d9b 51 if (!m_resetoccured) {
jocis 1:e6282b645d9b 52 m_resetoccured=1;
jocis 1:e6282b645d9b 53 _serial.printf ( "@\r" ); /* force reset */
jocis 1:e6282b645d9b 54 }
jocis 1:e6282b645d9b 55
jocis 1:e6282b645d9b 56 Sleep(10);
jocis 1:e6282b645d9b 57
jocis 1:e6282b645d9b 58 // pc.printf("Sending initialization sequence to spaceball...\n");
jocis 1:e6282b645d9b 59
jocis 1:e6282b645d9b 60 _serial.printf ( "CB\r" );
jocis 1:e6282b645d9b 61 Sleep(10);
jocis 1:e6282b645d9b 62 _serial.printf ( "NT\r" );
jocis 1:e6282b645d9b 63 Sleep(10);
jocis 1:e6282b645d9b 64 _serial.printf ( "FTp\r" );
jocis 1:e6282b645d9b 65 Sleep(10);
jocis 1:e6282b645d9b 66 _serial.printf ( "FRp\r" );
jocis 1:e6282b645d9b 67 Sleep(10);
jocis 1:e6282b645d9b 68 _serial.printf ( "P@r@r\r" );
jocis 1:e6282b645d9b 69 Sleep(10);
jocis 1:e6282b645d9b 70 _serial.printf ( "MSSV\r" );
jocis 1:e6282b645d9b 71 Sleep(10);
jocis 1:e6282b645d9b 72 _serial.printf ( "Z\r" );
jocis 1:e6282b645d9b 73 Sleep(10);
jocis 1:e6282b645d9b 74 _serial.printf ( "BcCcC\r" );
jocis 1:e6282b645d9b 75
jocis 1:e6282b645d9b 76 Sleep(10);
jocis 1:e6282b645d9b 77 _serial.printf ( "\rvz\r" );
jocis 1:e6282b645d9b 78 Sleep(10);
jocis 1:e6282b645d9b 79 _serial.printf ( "vQ\r" );
jocis 1:e6282b645d9b 80 Sleep(10);
jocis 1:e6282b645d9b 81 _serial.printf ( "kQ\r" );
jocis 1:e6282b645d9b 82 Sleep(10);
jocis 1:e6282b645d9b 83 _serial.printf ( "m3\r" );
jocis 1:e6282b645d9b 84 }
jocis 1:e6282b645d9b 85
jocis 1:e6282b645d9b 86 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 87
jocis 1:e6282b645d9b 88 void SpaceBall::ProcessSB ( char data )
jocis 1:e6282b645d9b 89 {
jocis 1:e6282b645d9b 90 switch (data) {
jocis 1:e6282b645d9b 91 case '\r': //0xd:
jocis 1:e6282b645d9b 92 _data[_idx] = 0;
jocis 1:e6282b645d9b 93 ProcessPacketSB();
jocis 1:e6282b645d9b 94 _idx = 0;
jocis 1:e6282b645d9b 95 _escape = 0;
jocis 1:e6282b645d9b 96 break;
jocis 1:e6282b645d9b 97 case '^':
jocis 1:e6282b645d9b 98 if (!_escape) {
jocis 1:e6282b645d9b 99 _escape = 1;
jocis 1:e6282b645d9b 100 break;
jocis 1:e6282b645d9b 101 }
jocis 1:e6282b645d9b 102 _escape = 0;
jocis 1:e6282b645d9b 103 case 'M':
jocis 1:e6282b645d9b 104 case 'Q':
jocis 1:e6282b645d9b 105 case 'S':
jocis 1:e6282b645d9b 106 if (_escape) {
jocis 1:e6282b645d9b 107 _escape = 0;
jocis 1:e6282b645d9b 108 data &= 0x1f;
jocis 1:e6282b645d9b 109 }
jocis 1:e6282b645d9b 110 default:
jocis 1:e6282b645d9b 111 if (_escape)
jocis 1:e6282b645d9b 112 _escape = 0;
jocis 1:e6282b645d9b 113 if (_idx < SPACEBALL_MAX_LENGTH)
jocis 1:e6282b645d9b 114 _data[_idx++] = data;
jocis 1:e6282b645d9b 115 break;
jocis 1:e6282b645d9b 116 }
jocis 1:e6282b645d9b 117 }
jocis 1:e6282b645d9b 118
jocis 1:e6282b645d9b 119 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 120
jocis 1:e6282b645d9b 121 void SpaceBall::ProcessPacketSB ( void )
jocis 1:e6282b645d9b 122 {
jocis 1:e6282b645d9b 123 int i;
jocis 1:e6282b645d9b 124
jocis 1:e6282b645d9b 125 if (_idx < 2) return;
jocis 1:e6282b645d9b 126
jocis 1:e6282b645d9b 127 switch (_data[0]) {
jocis 1:e6282b645d9b 128
jocis 1:e6282b645d9b 129 case 'D': /* Ball data */
jocis 1:e6282b645d9b 130 if (_idx != 15) return;
jocis 1:e6282b645d9b 131 for (i = 0; i < 6; i++) {
jocis 2:a7c0fcd157f7 132 _axis[i] = (short)( (_data[2*i + 3] << 8) | _data[2*i + 2] );
jocis 1:e6282b645d9b 133 }
jocis 1:e6282b645d9b 134 DoChangedAxis();
jocis 1:e6282b645d9b 135 break;
jocis 1:e6282b645d9b 136
jocis 1:e6282b645d9b 137 case 'd': /* Ball data */
jocis 1:e6282b645d9b 138 //pc.printf("d%d",_idx);
jocis 1:e6282b645d9b 139 if (_idx != 25) return;
jocis 1:e6282b645d9b 140 for (i = 0; i < 6; i++) {
jocis 2:a7c0fcd157f7 141 _axis[i] = (short)( (
jocis 1:e6282b645d9b 142 DecodeSM(_data[4*i+4]) | (DecodeSM(_data[4*i+3])<<4) | (DecodeSM(_data[4*i+2])<<8) | (DecodeSM(_data[4*i+1])<<12) )
jocis 1:e6282b645d9b 143 ^ 0x8000 );
jocis 1:e6282b645d9b 144 }
jocis 1:e6282b645d9b 145 DoChangedAxis();
jocis 1:e6282b645d9b 146 break;
jocis 1:e6282b645d9b 147
jocis 1:e6282b645d9b 148 case 'K': /* Button data */
jocis 1:e6282b645d9b 149 if (_idx != 3) return;
jocis 1:e6282b645d9b 150 /* Spaceball 2003A, 2003B, 2003 FLX, 3003 FLX, 4000 FLX */
jocis 1:e6282b645d9b 151 /* button packet. (4000 only for backwards compatibility) */
jocis 1:e6282b645d9b 152 /* The lowest 5 bits of the first byte are buttons 5-9 */
jocis 1:e6282b645d9b 153 /* Button '8' on a Spaceball 2003 is the rezero button */
jocis 1:e6282b645d9b 154 /* The lowest 4 bits of the second byte are buttons 1-4 */
jocis 1:e6282b645d9b 155 /* For Spaceball 2003, we'll map the buttons 1-7 normally */
jocis 1:e6282b645d9b 156 /* skip 8, as its a hardware "rezero button" on that device */
jocis 1:e6282b645d9b 157 /* and call the "pick" button "8". */
jocis 1:e6282b645d9b 158 /* On the Spaceball 3003, the "right" button also triggers */
jocis 1:e6282b645d9b 159 /* the "pick" bit. We OR the 2003/3003 rezero bits together */
jocis 1:e6282b645d9b 160
jocis 1:e6282b645d9b 161 /* if we have found a Spaceball 4000, then we ignore the 'K' */
jocis 1:e6282b645d9b 162 /* packets entirely, and only use the '.' packets. */
jocis 1:e6282b645d9b 163 if (m_spaceball4000)
jocis 1:e6282b645d9b 164 break;
jocis 1:e6282b645d9b 165
jocis 2:a7c0fcd157f7 166 _buttons =
jocis 1:e6282b645d9b 167 ((_data[1] & 0x10) << 8) | /* 2003 pick button is ??? */
jocis 1:e6282b645d9b 168 ((_data[1] & 0x20) << 9) | /* 3003 rezero button */
jocis 1:e6282b645d9b 169 ((_data[1] & 0x08) << 11) | /* 2003 rezero button */
jocis 1:e6282b645d9b 170 ((_data[1] & 0x07) << 4) | /* 5,6,7 (2003/4000) */
jocis 1:e6282b645d9b 171 ((_data[2] & 0x30) << 8) | /* 3003 Left/Right buttons */
jocis 1:e6282b645d9b 172 ((_data[2] & 0x0F)); /* 1,2,3,4 (2003/4000) */
jocis 1:e6282b645d9b 173
jocis 1:e6282b645d9b 174 DoChangedButtons();
jocis 1:e6282b645d9b 175 break;
jocis 1:e6282b645d9b 176
jocis 1:e6282b645d9b 177 case 'k': /* Button data */
jocis 1:e6282b645d9b 178 //pc.printf("k%d",_idx);
jocis 2:a7c0fcd157f7 179 //pc.printf("<%s>\r\n",_data);
jocis 1:e6282b645d9b 180 if (_idx != 4) return;
jocis 2:a7c0fcd157f7 181 _buttons = DecodeSM(_data[1]) | (DecodeSM(_data[2])<<4) | (DecodeSM(_data[3])<<8);
jocis 1:e6282b645d9b 182
jocis 1:e6282b645d9b 183 DoChangedButtons();
jocis 1:e6282b645d9b 184 break;
jocis 1:e6282b645d9b 185
jocis 1:e6282b645d9b 186 case '.': /* Advanced button data */
jocis 1:e6282b645d9b 187 if (_idx != 3) return;
jocis 1:e6282b645d9b 188 /* Spaceball 4000 FLX "expanded" button packet, with 12 buttons */
jocis 1:e6282b645d9b 189
jocis 1:e6282b645d9b 190 /* extra packet validity check, since we use this packet type */
jocis 1:e6282b645d9b 191 /* to override the 'K' button packets, and determine if its a */
jocis 1:e6282b645d9b 192 /* Spaceball 4000 or not... */
jocis 1:e6282b645d9b 193
jocis 1:e6282b645d9b 194 /* if we got a valid '.' packet, this must be a Spaceball 4000 */
jocis 1:e6282b645d9b 195 m_spaceball4000 = 1; /* Must be talking to a Spaceball 4000 */
jocis 1:e6282b645d9b 196
jocis 1:e6282b645d9b 197 /* Spaceball 4000 series "expanded" button press event */
jocis 1:e6282b645d9b 198 /* includes data for 12 buttons, and left/right orientation */
jocis 2:a7c0fcd157f7 199 _buttons =
jocis 1:e6282b645d9b 200 (((~_data[1]) & 0x20) << 10) | /* "left handed" mode */
jocis 1:e6282b645d9b 201 ((_data[1] & 0x1F) << 7) | /* 8,9,10,11,12 */
jocis 1:e6282b645d9b 202 ((_data[2] & 0x3F) ) | /* 1,2,3,4,5,6 (4000) */
jocis 1:e6282b645d9b 203 ((_data[2] & 0x80) >> 1); /* 7 (4000) */
jocis 1:e6282b645d9b 204
jocis 1:e6282b645d9b 205 /* set "lefty" orientation mode if "lefty bit" is _clear_ */
jocis 1:e6282b645d9b 206 if ((_data[1] & 0x20) == 0)
jocis 1:e6282b645d9b 207 m_leftymode4000 = 1; /* left handed mode */
jocis 1:e6282b645d9b 208 else
jocis 1:e6282b645d9b 209 m_leftymode4000 = 0; /* right handed mode */
jocis 1:e6282b645d9b 210
jocis 1:e6282b645d9b 211 DoChangedButtons();
jocis 1:e6282b645d9b 212 break;
jocis 1:e6282b645d9b 213
jocis 1:e6282b645d9b 214 case 'E': /* Device error */
jocis 1:e6282b645d9b 215 case 'e': /* Device error */
jocis 1:e6282b645d9b 216 //printk(KERN_ERR "spaceball: Device error. [%s]\n", spaceball->data + 1);
jocis 1:e6282b645d9b 217 break;
jocis 1:e6282b645d9b 218
jocis 1:e6282b645d9b 219 case '?': /* Bad command packet */
jocis 1:e6282b645d9b 220 //printk(KERN_ERR "spaceball: Bad command. [%s]\n", spaceball->data + 1);
jocis 1:e6282b645d9b 221 break;
jocis 1:e6282b645d9b 222
jocis 1:e6282b645d9b 223 case 'C': /* Communications mode packet */
jocis 1:e6282b645d9b 224 case 'F': /* Spaceball sensitization packet */
jocis 1:e6282b645d9b 225 case 'P': /* Spaceball update rate packet */
jocis 1:e6282b645d9b 226 case 'M': /* Spaceball movement mode packet */
jocis 1:e6282b645d9b 227 case 'N': /* Null region packet */
jocis 1:e6282b645d9b 228 case '\r': /* carriage return at poweron */
jocis 1:e6282b645d9b 229 case '\v': /* XON at poweron */
jocis 1:e6282b645d9b 230 /* eat and ignore these packets */
jocis 1:e6282b645d9b 231 break;
jocis 1:e6282b645d9b 232
jocis 1:e6282b645d9b 233 case '@': /* Reset packet */
jocis 1:e6282b645d9b 234 case 'z': /* Reset packet */
jocis 1:e6282b645d9b 235 /* if we get a reset packet, we have to re-initialize */
jocis 1:e6282b645d9b 236 /* the device, and assume that its completely schizophrenic */
jocis 1:e6282b645d9b 237 /* at this moment, we must reset it again at this point */
jocis 1:e6282b645d9b 238 m_resetoccured=1;
jocis 1:e6282b645d9b 239 //Init();
jocis 1:e6282b645d9b 240 break;
jocis 1:e6282b645d9b 241
jocis 1:e6282b645d9b 242 case 'b': /* Beep */
jocis 1:e6282b645d9b 243 case 'c': /* */
jocis 1:e6282b645d9b 244 case 'p': /* */
jocis 1:e6282b645d9b 245 case 'm': /* mode changed */
jocis 1:e6282b645d9b 246 case 'n': /* Zero radius */
jocis 1:e6282b645d9b 247 case 'q': /* Sensitivity */
jocis 1:e6282b645d9b 248 case 'v': /* Version number follows */
jocis 1:e6282b645d9b 249 /* eat and ignore these packets */
jocis 1:e6282b645d9b 250 break;
jocis 1:e6282b645d9b 251
jocis 1:e6282b645d9b 252 default:
jocis 2:a7c0fcd157f7 253 //pc.printf("<%s>\r\n",_data);
jocis 1:e6282b645d9b 254 break;
jocis 1:e6282b645d9b 255 }
jocis 1:e6282b645d9b 256 }
jocis 1:e6282b645d9b 257
jocis 1:e6282b645d9b 258 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 259 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 260 ///////////////////////////////////////////////////////////////////////////////