Luke Cartwright / Mbed 2 deprecated ELEC2645_Project_el18loc_nearlythere

Dependencies:   mbed

Committer:
lukeocarwright
Date:
Mon Mar 30 15:03:36 2020 +0000
Revision:
2:07cef563acdf
Parent:
1:766a293c9b07
Child:
3:b7df72682b81
Sin generated to onboard speaker and secondary sin modulation signal generated but not implemented. Square wve function also there but not implemented.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lukeocarwright 1:766a293c9b07 1 #include "Gamepad.h"
lukeocarwright 1:766a293c9b07 2
lukeocarwright 1:766a293c9b07 3 #include "mbed.h"
lukeocarwright 1:766a293c9b07 4
lukeocarwright 1:766a293c9b07 5 //////////// constructor/destructor ////////////
lukeocarwright 1:766a293c9b07 6 Gamepad::Gamepad()
lukeocarwright 1:766a293c9b07 7 :
lukeocarwright 1:766a293c9b07 8 _led1(new PwmOut(PTA2)),
lukeocarwright 1:766a293c9b07 9 _led2(new PwmOut(PTC2)),
lukeocarwright 1:766a293c9b07 10 _led3(new PwmOut(PTC3)),
lukeocarwright 1:766a293c9b07 11 _led4(new PwmOut(PTA1)),
lukeocarwright 1:766a293c9b07 12 _led5(new PwmOut(PTC10)),
lukeocarwright 1:766a293c9b07 13 _led6(new PwmOut(PTC11)),
lukeocarwright 1:766a293c9b07 14
lukeocarwright 1:766a293c9b07 15 _button_A(new InterruptIn(PTC7)),
lukeocarwright 1:766a293c9b07 16 _button_B(new InterruptIn(PTC9)),
lukeocarwright 1:766a293c9b07 17 _button_X(new InterruptIn(PTC5)),
lukeocarwright 1:766a293c9b07 18 _button_Y(new InterruptIn(PTC0)),
lukeocarwright 1:766a293c9b07 19 _button_start(new InterruptIn(PTC8)),
lukeocarwright 1:766a293c9b07 20
lukeocarwright 1:766a293c9b07 21 _vert(new AnalogIn(PTB11)),
lukeocarwright 1:766a293c9b07 22 _horiz(new AnalogIn(PTB10)),
lukeocarwright 1:766a293c9b07 23
lukeocarwright 1:766a293c9b07 24 _pot1(new AnalogIn(PTB2)),
lukeocarwright 1:766a293c9b07 25 _pot2(new AnalogIn(PTB3)),
lukeocarwright 1:766a293c9b07 26
lukeocarwright 1:766a293c9b07 27 dac(new AnalogOut(DAC0_OUT)),
lukeocarwright 1:766a293c9b07 28 ticker(new Ticker),
lukeocarwright 1:766a293c9b07 29 timeout(new Timeout),
lukeocarwright 1:766a293c9b07 30 note_timeout(new Timeout),
lukeocarwright 1:766a293c9b07 31
lukeocarwright 1:766a293c9b07 32 _x0(0),
lukeocarwright 1:766a293c9b07 33 _y0(0)
lukeocarwright 1:766a293c9b07 34 {}
lukeocarwright 1:766a293c9b07 35
lukeocarwright 1:766a293c9b07 36
lukeocarwright 1:766a293c9b07 37 ///////////////// public methods /////////////////
lukeocarwright 1:766a293c9b07 38
lukeocarwright 1:766a293c9b07 39 void Gamepad::init()
lukeocarwright 1:766a293c9b07 40 {
lukeocarwright 1:766a293c9b07 41 leds_off();
lukeocarwright 1:766a293c9b07 42
lukeocarwright 1:766a293c9b07 43 // read centred values of joystick
lukeocarwright 1:766a293c9b07 44 _x0 = _horiz->read();
lukeocarwright 1:766a293c9b07 45 _y0 = _vert->read();
lukeocarwright 1:766a293c9b07 46
lukeocarwright 1:766a293c9b07 47 // Set all buttons to PullUp
lukeocarwright 1:766a293c9b07 48 _button_A->mode(PullUp);
lukeocarwright 1:766a293c9b07 49 _button_B->mode(PullUp);
lukeocarwright 1:766a293c9b07 50 _button_X->mode(PullUp);
lukeocarwright 1:766a293c9b07 51 _button_Y->mode(PullUp);
lukeocarwright 1:766a293c9b07 52 _button_start->mode(PullUp);
lukeocarwright 1:766a293c9b07 53
lukeocarwright 1:766a293c9b07 54 // Set up interrupts for the fall of buttons
lukeocarwright 1:766a293c9b07 55 _button_A->fall(callback(this,&Gamepad::A_fall_interrupt));
lukeocarwright 1:766a293c9b07 56 _button_B->fall(callback(this,&Gamepad::B_fall_interrupt));
lukeocarwright 1:766a293c9b07 57 _button_X->fall(callback(this,&Gamepad::X_fall_interrupt));
lukeocarwright 1:766a293c9b07 58 _button_Y->fall(callback(this,&Gamepad::Y_fall_interrupt));
lukeocarwright 1:766a293c9b07 59 _button_start->fall(callback(this,&Gamepad::start_fall_interrupt));
lukeocarwright 1:766a293c9b07 60
lukeocarwright 1:766a293c9b07 61 // initalise button flags
lukeocarwright 1:766a293c9b07 62 reset_buttons();
lukeocarwright 1:766a293c9b07 63
lukeocarwright 1:766a293c9b07 64 // number of samples
lukeocarwright 1:766a293c9b07 65 _n = 16;
lukeocarwright 1:766a293c9b07 66 _sample_array = new float[_n];
lukeocarwright 1:766a293c9b07 67
lukeocarwright 1:766a293c9b07 68 // create sample array for one period between 0.0 and 1.0
lukeocarwright 1:766a293c9b07 69 for (int i = 0; i < _n ; i++) {
lukeocarwright 1:766a293c9b07 70 _sample_array[i] = 0.5f + 0.5f*sin(i*2*PI/_n);
lukeocarwright 1:766a293c9b07 71 //printf("y[%i] = %f\n",i,_sample_array[i]);
lukeocarwright 1:766a293c9b07 72 }
lukeocarwright 1:766a293c9b07 73
lukeocarwright 1:766a293c9b07 74 }
lukeocarwright 1:766a293c9b07 75
lukeocarwright 1:766a293c9b07 76 void Gamepad::leds_off()
lukeocarwright 1:766a293c9b07 77 {
lukeocarwright 1:766a293c9b07 78 leds(0.0);
lukeocarwright 1:766a293c9b07 79 }
lukeocarwright 1:766a293c9b07 80
lukeocarwright 1:766a293c9b07 81 void Gamepad::leds_on()
lukeocarwright 1:766a293c9b07 82 {
lukeocarwright 1:766a293c9b07 83 leds(1.0);
lukeocarwright 1:766a293c9b07 84 }
lukeocarwright 1:766a293c9b07 85
lukeocarwright 1:766a293c9b07 86 void Gamepad::leds(float val) const
lukeocarwright 1:766a293c9b07 87 {
lukeocarwright 1:766a293c9b07 88 if (val < 0.0f) {
lukeocarwright 1:766a293c9b07 89 val = 0.0f;
lukeocarwright 1:766a293c9b07 90 }
lukeocarwright 1:766a293c9b07 91 if (val > 1.0f) {
lukeocarwright 1:766a293c9b07 92 val = 1.0f;
lukeocarwright 1:766a293c9b07 93 }
lukeocarwright 1:766a293c9b07 94
lukeocarwright 1:766a293c9b07 95 // leds are active-low, so subtract from 1.0
lukeocarwright 1:766a293c9b07 96 // 0.0 corresponds to fully-off, 1.0 to fully-on
lukeocarwright 1:766a293c9b07 97 val = 1.0f - val;
lukeocarwright 1:766a293c9b07 98
lukeocarwright 1:766a293c9b07 99 _led1->write(val);
lukeocarwright 1:766a293c9b07 100 _led2->write(val);
lukeocarwright 1:766a293c9b07 101 _led3->write(val);
lukeocarwright 1:766a293c9b07 102 _led4->write(val);
lukeocarwright 1:766a293c9b07 103 _led5->write(val);
lukeocarwright 1:766a293c9b07 104 _led6->write(val);
lukeocarwright 1:766a293c9b07 105 }
lukeocarwright 1:766a293c9b07 106
lukeocarwright 1:766a293c9b07 107 void Gamepad::led(int n,float val) const
lukeocarwright 1:766a293c9b07 108 {
lukeocarwright 1:766a293c9b07 109 // ensure they are within valid range
lukeocarwright 1:766a293c9b07 110 if (val < 0.0f) {
lukeocarwright 1:766a293c9b07 111 val = 0.0f;
lukeocarwright 1:766a293c9b07 112 }
lukeocarwright 1:766a293c9b07 113 if (val > 1.0f) {
lukeocarwright 1:766a293c9b07 114 val = 1.0f;
lukeocarwright 1:766a293c9b07 115 }
lukeocarwright 1:766a293c9b07 116
lukeocarwright 1:766a293c9b07 117 switch (n) {
lukeocarwright 1:766a293c9b07 118
lukeocarwright 1:766a293c9b07 119 // check for valid LED number and set value
lukeocarwright 1:766a293c9b07 120
lukeocarwright 1:766a293c9b07 121 case 1:
lukeocarwright 1:766a293c9b07 122 _led1->write(1.0f-val); // active-low so subtract from 1
lukeocarwright 1:766a293c9b07 123 break;
lukeocarwright 1:766a293c9b07 124 case 2:
lukeocarwright 1:766a293c9b07 125 _led2->write(1.0f-val); // active-low so subtract from 1
lukeocarwright 1:766a293c9b07 126 break;
lukeocarwright 1:766a293c9b07 127 case 3:
lukeocarwright 1:766a293c9b07 128 _led3->write(1.0f-val); // active-low so subtract from 1
lukeocarwright 1:766a293c9b07 129 break;
lukeocarwright 1:766a293c9b07 130 case 4:
lukeocarwright 1:766a293c9b07 131 _led4->write(1.0f-val); // active-low so subtract from 1
lukeocarwright 1:766a293c9b07 132 break;
lukeocarwright 1:766a293c9b07 133 case 5:
lukeocarwright 1:766a293c9b07 134 _led5->write(1.0f-val); // active-low so subtract from 1
lukeocarwright 1:766a293c9b07 135 break;
lukeocarwright 1:766a293c9b07 136 case 6:
lukeocarwright 1:766a293c9b07 137 _led6->write(1.0f-val); // active-low so subtract from 1
lukeocarwright 1:766a293c9b07 138 break;
lukeocarwright 1:766a293c9b07 139
lukeocarwright 1:766a293c9b07 140 }
lukeocarwright 1:766a293c9b07 141 }
lukeocarwright 1:766a293c9b07 142
lukeocarwright 1:766a293c9b07 143 float Gamepad::read_pot1() const
lukeocarwright 1:766a293c9b07 144 {
lukeocarwright 1:766a293c9b07 145 return _pot1->read();
lukeocarwright 1:766a293c9b07 146 }
lukeocarwright 1:766a293c9b07 147
lukeocarwright 1:766a293c9b07 148 float Gamepad::read_pot2() const
lukeocarwright 1:766a293c9b07 149 {
lukeocarwright 1:766a293c9b07 150 return _pot2->read();
lukeocarwright 1:766a293c9b07 151 }
lukeocarwright 1:766a293c9b07 152
lukeocarwright 1:766a293c9b07 153
lukeocarwright 1:766a293c9b07 154 // this method gets the magnitude of the joystick movement
lukeocarwright 1:766a293c9b07 155 float Gamepad::get_mag()
lukeocarwright 1:766a293c9b07 156 {
lukeocarwright 1:766a293c9b07 157 Polar p = get_polar();
lukeocarwright 1:766a293c9b07 158 return p.mag;
lukeocarwright 1:766a293c9b07 159 }
lukeocarwright 1:766a293c9b07 160
lukeocarwright 1:766a293c9b07 161 // this method gets the angle of joystick movement (0 to 360, 0 North)
lukeocarwright 1:766a293c9b07 162 float Gamepad::get_angle()
lukeocarwright 1:766a293c9b07 163 {
lukeocarwright 1:766a293c9b07 164 Polar p = get_polar();
lukeocarwright 1:766a293c9b07 165 return p.angle;
lukeocarwright 1:766a293c9b07 166 }
lukeocarwright 1:766a293c9b07 167
lukeocarwright 1:766a293c9b07 168 Direction Gamepad::get_direction()
lukeocarwright 1:766a293c9b07 169 {
lukeocarwright 1:766a293c9b07 170 float angle = get_angle(); // 0 to 360, -1 for centred
lukeocarwright 1:766a293c9b07 171
lukeocarwright 1:766a293c9b07 172 Direction d;
lukeocarwright 1:766a293c9b07 173 // partition 360 into segments and check which segment the angle is in
lukeocarwright 1:766a293c9b07 174 if (angle < 0.0f) {
lukeocarwright 1:766a293c9b07 175 d = CENTRE; // check for -1.0 angle
lukeocarwright 1:766a293c9b07 176 } else if (angle < 22.5f) { // then keep going in 45 degree increments
lukeocarwright 1:766a293c9b07 177 d = N;
lukeocarwright 1:766a293c9b07 178 } else if (angle < 67.5f) {
lukeocarwright 1:766a293c9b07 179 d = NE;
lukeocarwright 1:766a293c9b07 180 } else if (angle < 112.5f) {
lukeocarwright 1:766a293c9b07 181 d = E;
lukeocarwright 1:766a293c9b07 182 } else if (angle < 157.5f) {
lukeocarwright 1:766a293c9b07 183 d = SE;
lukeocarwright 1:766a293c9b07 184 } else if (angle < 202.5f) {
lukeocarwright 1:766a293c9b07 185 d = S;
lukeocarwright 1:766a293c9b07 186 } else if (angle < 247.5f) {
lukeocarwright 1:766a293c9b07 187 d = SW;
lukeocarwright 1:766a293c9b07 188 } else if (angle < 292.5f) {
lukeocarwright 1:766a293c9b07 189 d = W;
lukeocarwright 1:766a293c9b07 190 } else if (angle < 337.5f) {
lukeocarwright 1:766a293c9b07 191 d = NW;
lukeocarwright 1:766a293c9b07 192 } else {
lukeocarwright 1:766a293c9b07 193 d = N;
lukeocarwright 1:766a293c9b07 194 }
lukeocarwright 1:766a293c9b07 195
lukeocarwright 1:766a293c9b07 196 return d;
lukeocarwright 1:766a293c9b07 197 }
lukeocarwright 1:766a293c9b07 198
lukeocarwright 1:766a293c9b07 199 void Gamepad::reset_buttons()
lukeocarwright 1:766a293c9b07 200 {
lukeocarwright 1:766a293c9b07 201 A_fall = B_fall = X_fall = Y_fall = start_fall = false;
lukeocarwright 1:766a293c9b07 202 }
lukeocarwright 1:766a293c9b07 203
lukeocarwright 1:766a293c9b07 204 bool Gamepad::A_pressed()
lukeocarwright 1:766a293c9b07 205 {
lukeocarwright 1:766a293c9b07 206 if (A_fall) {
lukeocarwright 1:766a293c9b07 207 A_fall = false;
lukeocarwright 1:766a293c9b07 208 return true;
lukeocarwright 1:766a293c9b07 209 } else {
lukeocarwright 1:766a293c9b07 210 return false;
lukeocarwright 1:766a293c9b07 211 }
lukeocarwright 1:766a293c9b07 212 }
lukeocarwright 1:766a293c9b07 213
lukeocarwright 1:766a293c9b07 214 bool Gamepad::B_pressed()
lukeocarwright 1:766a293c9b07 215 {
lukeocarwright 1:766a293c9b07 216 if (B_fall) {
lukeocarwright 1:766a293c9b07 217 B_fall = false;
lukeocarwright 1:766a293c9b07 218 return true;
lukeocarwright 1:766a293c9b07 219 } else {
lukeocarwright 1:766a293c9b07 220 return false;
lukeocarwright 1:766a293c9b07 221 }
lukeocarwright 1:766a293c9b07 222 }
lukeocarwright 1:766a293c9b07 223
lukeocarwright 1:766a293c9b07 224 bool Gamepad::X_pressed()
lukeocarwright 1:766a293c9b07 225 {
lukeocarwright 1:766a293c9b07 226 if (X_fall) {
lukeocarwright 1:766a293c9b07 227 X_fall = false;
lukeocarwright 1:766a293c9b07 228 return true;
lukeocarwright 1:766a293c9b07 229 } else {
lukeocarwright 1:766a293c9b07 230 return false;
lukeocarwright 1:766a293c9b07 231 }
lukeocarwright 1:766a293c9b07 232 }
lukeocarwright 1:766a293c9b07 233
lukeocarwright 1:766a293c9b07 234 bool Gamepad::Y_pressed()
lukeocarwright 1:766a293c9b07 235 {
lukeocarwright 1:766a293c9b07 236 if (Y_fall) {
lukeocarwright 1:766a293c9b07 237 Y_fall = false;
lukeocarwright 1:766a293c9b07 238 return true;
lukeocarwright 1:766a293c9b07 239 } else {
lukeocarwright 1:766a293c9b07 240 return false;
lukeocarwright 1:766a293c9b07 241 }
lukeocarwright 1:766a293c9b07 242 }
lukeocarwright 1:766a293c9b07 243
lukeocarwright 1:766a293c9b07 244 bool Gamepad::start_pressed()
lukeocarwright 1:766a293c9b07 245 {
lukeocarwright 1:766a293c9b07 246 if (start_fall) {
lukeocarwright 1:766a293c9b07 247 start_fall = false;
lukeocarwright 1:766a293c9b07 248 return true;
lukeocarwright 1:766a293c9b07 249 } else {
lukeocarwright 1:766a293c9b07 250 return false;
lukeocarwright 1:766a293c9b07 251 }
lukeocarwright 1:766a293c9b07 252 }
lukeocarwright 1:766a293c9b07 253
lukeocarwright 1:766a293c9b07 254 bool Gamepad::A_held()
lukeocarwright 1:766a293c9b07 255 {
lukeocarwright 1:766a293c9b07 256 // Buttons are configured as PullUp hence the not
lukeocarwright 1:766a293c9b07 257 return !_button_A->read();
lukeocarwright 1:766a293c9b07 258 }
lukeocarwright 1:766a293c9b07 259
lukeocarwright 1:766a293c9b07 260 bool Gamepad::B_held()
lukeocarwright 1:766a293c9b07 261 {
lukeocarwright 1:766a293c9b07 262 return !_button_B->read();
lukeocarwright 1:766a293c9b07 263 }
lukeocarwright 1:766a293c9b07 264
lukeocarwright 1:766a293c9b07 265 bool Gamepad::X_held()
lukeocarwright 1:766a293c9b07 266 {
lukeocarwright 1:766a293c9b07 267 return !_button_X->read();
lukeocarwright 1:766a293c9b07 268 }
lukeocarwright 1:766a293c9b07 269
lukeocarwright 1:766a293c9b07 270 bool Gamepad::Y_held()
lukeocarwright 1:766a293c9b07 271 {
lukeocarwright 1:766a293c9b07 272 return !_button_Y->read();
lukeocarwright 1:766a293c9b07 273 }
lukeocarwright 1:766a293c9b07 274
lukeocarwright 1:766a293c9b07 275 bool Gamepad::start_held()
lukeocarwright 1:766a293c9b07 276 {
lukeocarwright 1:766a293c9b07 277 return !_button_start->read();
lukeocarwright 1:766a293c9b07 278 }
lukeocarwright 1:766a293c9b07 279
lukeocarwright 1:766a293c9b07 280 ///////////////////// private methods ////////////////////////
lukeocarwright 1:766a293c9b07 281
lukeocarwright 1:766a293c9b07 282 // get raw joystick coordinate in range -1 to 1
lukeocarwright 1:766a293c9b07 283 // Direction (x,y)
lukeocarwright 1:766a293c9b07 284 // North (0,1)
lukeocarwright 1:766a293c9b07 285 // East (1,0)
lukeocarwright 1:766a293c9b07 286 // South (0,-1)
lukeocarwright 1:766a293c9b07 287 // West (-1,0)
lukeocarwright 1:766a293c9b07 288 Vector2D Gamepad::get_coord()
lukeocarwright 1:766a293c9b07 289 {
lukeocarwright 1:766a293c9b07 290 // read() returns value in range 0.0 to 1.0 so is scaled and centre value
lukeocarwright 1:766a293c9b07 291 // substracted to get values in the range -1.0 to 1.0
lukeocarwright 1:766a293c9b07 292 float x = 2.0f*( _horiz->read() - _x0 );
lukeocarwright 1:766a293c9b07 293 float y = 2.0f*( _vert->read() - _y0 );
lukeocarwright 1:766a293c9b07 294
lukeocarwright 1:766a293c9b07 295 // Note: the y value here is inverted to ensure the positive y is up
lukeocarwright 1:766a293c9b07 296
lukeocarwright 1:766a293c9b07 297 Vector2D coord = {x,-y};
lukeocarwright 1:766a293c9b07 298 return coord;
lukeocarwright 1:766a293c9b07 299 }
lukeocarwright 1:766a293c9b07 300
lukeocarwright 1:766a293c9b07 301 // This maps the raw x,y coord onto a circular grid.
lukeocarwright 1:766a293c9b07 302 // See: http://mathproofs.blogspot.co.uk/2005/07/mapping-square-to-circle.html
lukeocarwright 1:766a293c9b07 303 Vector2D Gamepad::get_mapped_coord()
lukeocarwright 1:766a293c9b07 304 {
lukeocarwright 1:766a293c9b07 305 Vector2D coord = get_coord();
lukeocarwright 1:766a293c9b07 306
lukeocarwright 1:766a293c9b07 307 // do the transformation
lukeocarwright 1:766a293c9b07 308 float x = coord.x*sqrt(1.0f-pow(coord.y,2.0f)/2.0f);
lukeocarwright 1:766a293c9b07 309 float y = coord.y*sqrt(1.0f-pow(coord.x,2.0f)/2.0f);
lukeocarwright 1:766a293c9b07 310
lukeocarwright 1:766a293c9b07 311 Vector2D mapped_coord = {x,y};
lukeocarwright 1:766a293c9b07 312 return mapped_coord;
lukeocarwright 1:766a293c9b07 313 }
lukeocarwright 1:766a293c9b07 314
lukeocarwright 1:766a293c9b07 315 // this function converts the mapped coordinates into polar form
lukeocarwright 1:766a293c9b07 316 Polar Gamepad::get_polar()
lukeocarwright 1:766a293c9b07 317 {
lukeocarwright 1:766a293c9b07 318 // get the mapped coordinate
lukeocarwright 1:766a293c9b07 319 Vector2D coord = get_mapped_coord();
lukeocarwright 1:766a293c9b07 320
lukeocarwright 1:766a293c9b07 321 // at this point, 0 degrees (i.e. x-axis) will be defined to the East.
lukeocarwright 1:766a293c9b07 322 // We want 0 degrees to correspond to North and increase clockwise to 359
lukeocarwright 1:766a293c9b07 323 // like a compass heading, so we need to swap the axis and invert y
lukeocarwright 1:766a293c9b07 324 float x = coord.y;
lukeocarwright 1:766a293c9b07 325 float y = coord.x;
lukeocarwright 1:766a293c9b07 326
lukeocarwright 1:766a293c9b07 327 float mag = sqrt(x*x+y*y); // pythagoras
lukeocarwright 1:766a293c9b07 328 float angle = RAD2DEG*atan2(y,x);
lukeocarwright 1:766a293c9b07 329 // angle will be in range -180 to 180, so add 360 to negative angles to
lukeocarwright 1:766a293c9b07 330 // move to 0 to 360 range
lukeocarwright 1:766a293c9b07 331 if (angle < 0.0f) {
lukeocarwright 1:766a293c9b07 332 angle+=360.0f;
lukeocarwright 1:766a293c9b07 333 }
lukeocarwright 1:766a293c9b07 334
lukeocarwright 1:766a293c9b07 335 // the noise on the ADC causes the values of x and y to fluctuate slightly
lukeocarwright 1:766a293c9b07 336 // around the centred values. This causes the random angle values to get
lukeocarwright 1:766a293c9b07 337 // calculated when the joystick is centred and untouched. This is also when
lukeocarwright 1:766a293c9b07 338 // the magnitude is very small, so we can check for a small magnitude and then
lukeocarwright 1:766a293c9b07 339 // set the angle to -1. This will inform us when the angle is invalid and the
lukeocarwright 1:766a293c9b07 340 // joystick is centred
lukeocarwright 1:766a293c9b07 341
lukeocarwright 1:766a293c9b07 342 if (mag < TOL) {
lukeocarwright 1:766a293c9b07 343 mag = 0.0f;
lukeocarwright 1:766a293c9b07 344 angle = -1.0f;
lukeocarwright 1:766a293c9b07 345 }
lukeocarwright 1:766a293c9b07 346
lukeocarwright 1:766a293c9b07 347 Polar p = {mag,angle};
lukeocarwright 1:766a293c9b07 348 return p;
lukeocarwright 1:766a293c9b07 349 }
lukeocarwright 1:766a293c9b07 350
lukeocarwright 1:766a293c9b07 351 // ISRs for buttons
lukeocarwright 1:766a293c9b07 352 void Gamepad::A_fall_interrupt()
lukeocarwright 1:766a293c9b07 353 {
lukeocarwright 1:766a293c9b07 354 A_fall = true;
lukeocarwright 1:766a293c9b07 355 }
lukeocarwright 1:766a293c9b07 356 void Gamepad::B_fall_interrupt()
lukeocarwright 1:766a293c9b07 357 {
lukeocarwright 1:766a293c9b07 358 B_fall = true;
lukeocarwright 1:766a293c9b07 359 }
lukeocarwright 1:766a293c9b07 360 void Gamepad::X_fall_interrupt()
lukeocarwright 1:766a293c9b07 361 {
lukeocarwright 1:766a293c9b07 362 X_fall = true;
lukeocarwright 1:766a293c9b07 363 }
lukeocarwright 1:766a293c9b07 364 void Gamepad::Y_fall_interrupt()
lukeocarwright 1:766a293c9b07 365 {
lukeocarwright 1:766a293c9b07 366 Y_fall = true;
lukeocarwright 1:766a293c9b07 367 }
lukeocarwright 1:766a293c9b07 368 void Gamepad::start_fall_interrupt()
lukeocarwright 1:766a293c9b07 369 {
lukeocarwright 1:766a293c9b07 370 start_fall = true;
lukeocarwright 1:766a293c9b07 371 }
lukeocarwright 1:766a293c9b07 372
lukeocarwright 1:766a293c9b07 373 void Gamepad::set_bpm(float bpm)
lukeocarwright 1:766a293c9b07 374 {
lukeocarwright 1:766a293c9b07 375 _bpm = bpm;
lukeocarwright 1:766a293c9b07 376 }
lukeocarwright 1:766a293c9b07 377
lukeocarwright 1:766a293c9b07 378 void Gamepad::tone(float frequency,float duration)
lukeocarwright 1:766a293c9b07 379 {
lukeocarwright 1:766a293c9b07 380 // calculate time step between samples
lukeocarwright 1:766a293c9b07 381 float dt = 1.0f/(frequency*_n);
lukeocarwright 1:766a293c9b07 382 // start from beginning of LUT
lukeocarwright 1:766a293c9b07 383 _sample = 0;
lukeocarwright 1:766a293c9b07 384
lukeocarwright 1:766a293c9b07 385 // setup ticker and timeout to stop ticker
lukeocarwright 1:766a293c9b07 386
lukeocarwright 1:766a293c9b07 387 // the ticker repeats every dt to plat each sample in turn
lukeocarwright 1:766a293c9b07 388 ticker->attach(callback(this, &Gamepad::ticker_isr), dt);
lukeocarwright 1:766a293c9b07 389 // the timeout stops the ticker after the required duration
lukeocarwright 1:766a293c9b07 390 timeout->attach(callback(this, &Gamepad::timeout_isr), duration );
lukeocarwright 1:766a293c9b07 391 }
lukeocarwright 1:766a293c9b07 392
lukeocarwright 1:766a293c9b07 393 void Gamepad::play_melody(int length,const int *notes,const int *durations,float bpm,bool repeat)
lukeocarwright 1:766a293c9b07 394 {
lukeocarwright 1:766a293c9b07 395 // copy arguments to member variables
lukeocarwright 1:766a293c9b07 396 _bpm = bpm;
lukeocarwright 1:766a293c9b07 397 _notes = notes; // pointer for array
lukeocarwright 1:766a293c9b07 398 _durations = durations; // pointer for array
lukeocarwright 1:766a293c9b07 399 _melody_length = length;
lukeocarwright 1:766a293c9b07 400 _repeat = repeat;
lukeocarwright 1:766a293c9b07 401
lukeocarwright 1:766a293c9b07 402 _note = 0; // start from first note
lukeocarwright 1:766a293c9b07 403
lukeocarwright 1:766a293c9b07 404 play_next_note(); // play the next note in the melody
lukeocarwright 1:766a293c9b07 405 }
lukeocarwright 1:766a293c9b07 406
lukeocarwright 1:766a293c9b07 407 void Gamepad::write_dac(float val)
lukeocarwright 1:766a293c9b07 408 {
lukeocarwright 1:766a293c9b07 409 if (val < 0.0f) {
lukeocarwright 1:766a293c9b07 410 val = 0.0f;
lukeocarwright 1:766a293c9b07 411 } else if (val > 1.0f) {
lukeocarwright 1:766a293c9b07 412 val = 1.0f;
lukeocarwright 1:766a293c9b07 413 }
lukeocarwright 1:766a293c9b07 414 dac->write(val);
lukeocarwright 1:766a293c9b07 415 }
lukeocarwright 1:766a293c9b07 416
lukeocarwright 2:07cef563acdf 417 //writes DAC value in int format
lukeocarwright 2:07cef563acdf 418 void Gamepad::write_u16(int val)
lukeocarwright 2:07cef563acdf 419 {
lukeocarwright 2:07cef563acdf 420 if (val < 0) {
lukeocarwright 2:07cef563acdf 421 val = 0;
lukeocarwright 2:07cef563acdf 422 } else if (val > 65535) {
lukeocarwright 2:07cef563acdf 423 val = 65535;
lukeocarwright 2:07cef563acdf 424 }
lukeocarwright 2:07cef563acdf 425 dac->write_u16(val);
lukeocarwright 2:07cef563acdf 426 }
lukeocarwright 2:07cef563acdf 427
lukeocarwright 1:766a293c9b07 428
lukeocarwright 1:766a293c9b07 429 void Gamepad::play_next_note()
lukeocarwright 1:766a293c9b07 430 {
lukeocarwright 1:766a293c9b07 431 // _note is the note index to play
lukeocarwright 1:766a293c9b07 432
lukeocarwright 1:766a293c9b07 433 // calculate the duration and frequency of the note
lukeocarwright 1:766a293c9b07 434 float duration = 60.0f/(_bpm*_durations[_note]);
lukeocarwright 1:766a293c9b07 435 float frequency = float(_notes[_note]);
lukeocarwright 1:766a293c9b07 436 //printf("[%i] f = %f d = %f\n",_note,frequency,duration);
lukeocarwright 1:766a293c9b07 437
lukeocarwright 1:766a293c9b07 438 // check if the note is not a space and if not then play the note
lukeocarwright 1:766a293c9b07 439 if (frequency > 0) {
lukeocarwright 1:766a293c9b07 440 tone(frequency,duration);
lukeocarwright 1:766a293c9b07 441 }
lukeocarwright 1:766a293c9b07 442
lukeocarwright 1:766a293c9b07 443 // the timeout goes to the next note in the melody
lukeocarwright 1:766a293c9b07 444 // double the duration to leave a bit of a gap in between notes to be better
lukeocarwright 1:766a293c9b07 445 // able to distinguish them
lukeocarwright 1:766a293c9b07 446 note_timeout->attach(callback(this, &Gamepad::note_timeout_isr), duration*2.0f );
lukeocarwright 1:766a293c9b07 447 }
lukeocarwright 1:766a293c9b07 448
lukeocarwright 1:766a293c9b07 449 // called when the next note needs playing
lukeocarwright 1:766a293c9b07 450 void Gamepad::note_timeout_isr()
lukeocarwright 1:766a293c9b07 451 {
lukeocarwright 1:766a293c9b07 452 _note++; // go onto next note
lukeocarwright 1:766a293c9b07 453
lukeocarwright 1:766a293c9b07 454 // if in repeat mode then reset the note counter when get to end of melody
lukeocarwright 1:766a293c9b07 455 if (_repeat && _note == _melody_length) {
lukeocarwright 1:766a293c9b07 456 _note=0;
lukeocarwright 1:766a293c9b07 457 }
lukeocarwright 1:766a293c9b07 458
lukeocarwright 1:766a293c9b07 459 // check if note is within the melody
lukeocarwright 1:766a293c9b07 460 if (_note < _melody_length) {
lukeocarwright 1:766a293c9b07 461 play_next_note();
lukeocarwright 1:766a293c9b07 462 }
lukeocarwright 1:766a293c9b07 463 }
lukeocarwright 1:766a293c9b07 464
lukeocarwright 1:766a293c9b07 465 void Gamepad::ticker_isr()
lukeocarwright 1:766a293c9b07 466 {
lukeocarwright 1:766a293c9b07 467 dac->write(_sample_array[_sample%_n]); // use modulo to get index to play
lukeocarwright 1:766a293c9b07 468 _sample++; // increment the sample ready for next time
lukeocarwright 1:766a293c9b07 469 }
lukeocarwright 1:766a293c9b07 470
lukeocarwright 1:766a293c9b07 471 void Gamepad::timeout_isr()
lukeocarwright 1:766a293c9b07 472 {
lukeocarwright 1:766a293c9b07 473 // stops the ticker to end the note
lukeocarwright 1:766a293c9b07 474 ticker->detach();
lukeocarwright 1:766a293c9b07 475 }