fsdfds
Dependencies: BLE_API mbed-dev-bin nRF51822
Fork of microbit-dal by
MicroBitPin.cpp
00001 /* 00002 The MIT License (MIT) 00003 00004 Copyright (c) 2016 British Broadcasting Corporation. 00005 This software is provided by Lancaster University by arrangement with the BBC. 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a 00008 copy of this software and associated documentation files (the "Software"), 00009 to deal in the Software without restriction, including without limitation 00010 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 and/or sell copies of the Software, and to permit persons to whom the 00012 Software is furnished to do so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included in 00015 all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00023 DEALINGS IN THE SOFTWARE. 00024 */ 00025 00026 /** 00027 * Class definition for MicroBitPin. 00028 * 00029 * Commonly represents an I/O pin on the edge connector. 00030 */ 00031 #include "MicroBitConfig.h" 00032 #include "MicroBitPin.h" 00033 #include "MicroBitButton.h" 00034 #include "MicroBitSystemTimer.h" 00035 #include "TimedInterruptIn.h" 00036 #include "DynamicPwm.h" 00037 #include "ErrorNo.h" 00038 00039 /** 00040 * Constructor. 00041 * Create a MicroBitPin instance, generally used to represent a pin on the edge connector. 00042 * 00043 * @param id the unique EventModel id of this component. 00044 * 00045 * @param name the mbed PinName for this MicroBitPin instance. 00046 * 00047 * @param capability the capabilities this MicroBitPin instance should have. 00048 * (PIN_CAPABILITY_DIGITAL, PIN_CAPABILITY_ANALOG, PIN_CAPABILITY_AD, PIN_CAPABILITY_ALL) 00049 * 00050 * @code 00051 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL); 00052 * @endcode 00053 */ 00054 MicroBitPin::MicroBitPin(int id, PinName name, PinCapability capability) 00055 { 00056 //set mandatory attributes 00057 this->id = id; 00058 this->name = name; 00059 this->capability = capability; 00060 this->pullMode = MICROBIT_DEFAULT_PULLMODE; 00061 00062 // Power up in a disconnected, low power state. 00063 // If we're unused, this is how it will stay... 00064 this->status = 0x00; 00065 this->pin = NULL; 00066 00067 } 00068 00069 /** 00070 * Disconnect any attached mBed IO from this pin. 00071 * 00072 * Used only when pin changes mode (i.e. Input/Output/Analog/Digital) 00073 */ 00074 void MicroBitPin::disconnect() 00075 { 00076 // This is a bit ugly, but rarely used code. 00077 // It would be much better to use some polymorphism here, but the mBed I/O classes aren't arranged in an inheritance hierarchy... yet. :-) 00078 if (status & IO_STATUS_DIGITAL_IN) 00079 delete ((DigitalIn *)pin); 00080 00081 if (status & IO_STATUS_DIGITAL_OUT) 00082 delete ((DigitalOut *)pin); 00083 00084 if (status & IO_STATUS_ANALOG_IN){ 00085 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled; // forcibly disable the ADC - BUG in mbed.... 00086 delete ((AnalogIn *)pin); 00087 } 00088 00089 if (status & IO_STATUS_ANALOG_OUT) 00090 { 00091 if(((DynamicPwm *)pin)->getPinName() == name) 00092 ((DynamicPwm *)pin)->release(); 00093 } 00094 00095 if (status & IO_STATUS_TOUCH_IN) 00096 delete ((MicroBitButton *)pin); 00097 00098 if ((status & IO_STATUS_EVENT_ON_EDGE) || (status & IO_STATUS_EVENT_PULSE_ON_EDGE)) 00099 delete ((TimedInterruptIn *)pin); 00100 00101 this->pin = NULL; 00102 this->status = 0; 00103 } 00104 00105 /** 00106 * Configures this IO pin as a digital output (if necessary) and sets the pin to 'value'. 00107 * 00108 * @param value 0 (LO) or 1 (HI) 00109 * 00110 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED 00111 * if the given pin does not have digital capability. 00112 * 00113 * @code 00114 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH); 00115 * P0.setDigitalValue(1); // P0 is now HI 00116 * @endcode 00117 */ 00118 int MicroBitPin::setDigitalValue(int value) 00119 { 00120 // Check if this pin has a digital mode... 00121 if(!(PIN_CAPABILITY_DIGITAL & capability)) 00122 return MICROBIT_NOT_SUPPORTED; 00123 00124 // Ensure we have a valid value. 00125 if (value < 0 || value > 1) 00126 return MICROBIT_INVALID_PARAMETER; 00127 00128 // Move into a Digital input state if necessary. 00129 if (!(status & IO_STATUS_DIGITAL_OUT)){ 00130 disconnect(); 00131 pin = new DigitalOut(name); 00132 status |= IO_STATUS_DIGITAL_OUT; 00133 } 00134 00135 // Write the value. 00136 ((DigitalOut *)pin)->write(value); 00137 00138 return MICROBIT_OK; 00139 } 00140 00141 /** 00142 * Configures this IO pin as a digital input (if necessary) and tests its current value. 00143 * 00144 * 00145 * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED 00146 * if the given pin does not have digital capability. 00147 * 00148 * @code 00149 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH); 00150 * P0.getDigitalValue(); // P0 is either 0 or 1; 00151 * @endcode 00152 */ 00153 int MicroBitPin::getDigitalValue() 00154 { 00155 //check if this pin has a digital mode... 00156 if(!(PIN_CAPABILITY_DIGITAL & capability)) 00157 return MICROBIT_NOT_SUPPORTED; 00158 00159 // Move into a Digital input state if necessary. 00160 if (!(status & (IO_STATUS_DIGITAL_IN | IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE))) 00161 { 00162 disconnect(); 00163 pin = new DigitalIn(name, (PinMode)pullMode); 00164 status |= IO_STATUS_DIGITAL_IN; 00165 } 00166 00167 if(status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE)) 00168 return ((TimedInterruptIn *)pin)->read(); 00169 00170 return ((DigitalIn *)pin)->read(); 00171 } 00172 00173 /** 00174 * Configures this IO pin as a digital input with the specified internal pull-up/pull-down configuraiton (if necessary) and tests its current value. 00175 * 00176 * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone 00177 * 00178 * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED 00179 * if the given pin does not have digital capability. 00180 * 00181 * @code 00182 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH); 00183 * P0.getDigitalValue(PullUp); // P0 is either 0 or 1; 00184 * @endcode 00185 */ 00186 int MicroBitPin::getDigitalValue(PinMode pull) 00187 { 00188 setPull(pull); 00189 return getDigitalValue(); 00190 } 00191 00192 int MicroBitPin::obtainAnalogChannel() 00193 { 00194 // Move into an analogue input state if necessary, if we are no longer the focus of a DynamicPWM instance, allocate ourselves again! 00195 if (!(status & IO_STATUS_ANALOG_OUT) || !(((DynamicPwm *)pin)->getPinName() == name)){ 00196 disconnect(); 00197 pin = (void *)DynamicPwm::allocate(name); 00198 status |= IO_STATUS_ANALOG_OUT; 00199 } 00200 00201 return MICROBIT_OK; 00202 } 00203 00204 /** 00205 * Configures this IO pin as an analog/pwm output, and change the output value to the given level. 00206 * 00207 * @param value the level to set on the output pin, in the range 0 - 1024 00208 * 00209 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED 00210 * if the given pin does not have analog capability. 00211 */ 00212 int MicroBitPin::setAnalogValue(int value) 00213 { 00214 //check if this pin has an analogue mode... 00215 if(!(PIN_CAPABILITY_ANALOG & capability)) 00216 return MICROBIT_NOT_SUPPORTED; 00217 00218 //sanitise the level value 00219 if(value < 0 || value > MICROBIT_PIN_MAX_OUTPUT) 00220 return MICROBIT_INVALID_PARAMETER; 00221 00222 float level = (float)value / float(MICROBIT_PIN_MAX_OUTPUT); 00223 00224 //obtain use of the DynamicPwm instance, if it has changed / configure if we do not have one 00225 if(obtainAnalogChannel() == MICROBIT_OK) 00226 return ((DynamicPwm *)pin)->write(level); 00227 00228 return MICROBIT_OK; 00229 } 00230 00231 /** 00232 * Configures this IO pin as an analog/pwm output (if necessary) and configures the period to be 20ms, 00233 * with a duty cycle between 500 us and 2500 us. 00234 * 00235 * A value of 180 sets the duty cycle to be 2500us, and a value of 0 sets the duty cycle to be 500us by default. 00236 * 00237 * This range can be modified to fine tune, and also tolerate different servos. 00238 * 00239 * @param value the level to set on the output pin, in the range 0 - 180. 00240 * 00241 * @param range which gives the span of possible values the i.e. the lower and upper bounds (center +/- range/2). Defaults to MICROBIT_PIN_DEFAULT_SERVO_RANGE. 00242 * 00243 * @param center the center point from which to calculate the lower and upper bounds. Defaults to MICROBIT_PIN_DEFAULT_SERVO_CENTER 00244 * 00245 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED 00246 * if the given pin does not have analog capability. 00247 */ 00248 int MicroBitPin::setServoValue(int value, int range, int center) 00249 { 00250 //check if this pin has an analogue mode... 00251 if(!(PIN_CAPABILITY_ANALOG & capability)) 00252 return MICROBIT_NOT_SUPPORTED; 00253 00254 //sanitise the servo level 00255 if(value < 0 || range < 1 || center < 1) 00256 return MICROBIT_INVALID_PARAMETER; 00257 00258 //clip - just in case 00259 if(value > MICROBIT_PIN_MAX_SERVO_RANGE) 00260 value = MICROBIT_PIN_MAX_SERVO_RANGE; 00261 00262 //calculate the lower bound based on the midpoint 00263 int lower = (center - (range / 2)) * 1000; 00264 00265 value = value * 1000; 00266 00267 //add the percentage of the range based on the value between 0 and 180 00268 int scaled = lower + (range * (value / MICROBIT_PIN_MAX_SERVO_RANGE)); 00269 00270 return setServoPulseUs(scaled / 1000); 00271 } 00272 00273 /** 00274 * Configures this IO pin as an analogue input (if necessary), and samples the Pin for its analog value. 00275 * 00276 * @return the current analogue level on the pin, in the range 0 - 1024, or 00277 * MICROBIT_NOT_SUPPORTED if the given pin does not have analog capability. 00278 * 00279 * @code 00280 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH); 00281 * P0.getAnalogValue(); // P0 is a value in the range of 0 - 1024 00282 * @endcode 00283 */ 00284 int MicroBitPin::getAnalogValue() 00285 { 00286 //check if this pin has an analogue mode... 00287 if(!(PIN_CAPABILITY_ANALOG & capability)) 00288 return MICROBIT_NOT_SUPPORTED; 00289 00290 // Move into an analogue input state if necessary. 00291 if (!(status & IO_STATUS_ANALOG_IN)){ 00292 disconnect(); 00293 pin = new AnalogIn(name); 00294 status |= IO_STATUS_ANALOG_IN; 00295 } 00296 00297 //perform a read! 00298 return ((AnalogIn *)pin)->read_u16(); 00299 } 00300 00301 /** 00302 * Determines if this IO pin is currently configured as an input. 00303 * 00304 * @return 1 if pin is an analog or digital input, 0 otherwise. 00305 */ 00306 int MicroBitPin::isInput() 00307 { 00308 return (status & (IO_STATUS_DIGITAL_IN | IO_STATUS_ANALOG_IN)) == 0 ? 0 : 1; 00309 } 00310 00311 /** 00312 * Determines if this IO pin is currently configured as an output. 00313 * 00314 * @return 1 if pin is an analog or digital output, 0 otherwise. 00315 */ 00316 int MicroBitPin::isOutput() 00317 { 00318 return (status & (IO_STATUS_DIGITAL_OUT | IO_STATUS_ANALOG_OUT)) == 0 ? 0 : 1; 00319 } 00320 00321 /** 00322 * Determines if this IO pin is currently configured for digital use. 00323 * 00324 * @return 1 if pin is digital, 0 otherwise. 00325 */ 00326 int MicroBitPin::isDigital() 00327 { 00328 return (status & (IO_STATUS_DIGITAL_IN | IO_STATUS_DIGITAL_OUT)) == 0 ? 0 : 1; 00329 } 00330 00331 /** 00332 * Determines if this IO pin is currently configured for analog use. 00333 * 00334 * @return 1 if pin is analog, 0 otherwise. 00335 */ 00336 int MicroBitPin::isAnalog() 00337 { 00338 return (status & (IO_STATUS_ANALOG_IN | IO_STATUS_ANALOG_OUT)) == 0 ? 0 : 1; 00339 } 00340 00341 /** 00342 * Configures this IO pin as a "makey makey" style touch sensor (if necessary) 00343 * and tests its current debounced state. 00344 * 00345 * Users can also subscribe to MicroBitButton events generated from this pin. 00346 * 00347 * @return 1 if pin is touched, 0 if not, or MICROBIT_NOT_SUPPORTED if this pin does not support touch capability. 00348 * 00349 * @code 00350 * MicroBitMessageBus bus; 00351 * 00352 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL); 00353 * if(P0.isTouched()) 00354 * { 00355 * //do something! 00356 * } 00357 * 00358 * // subscribe to events generated by this pin! 00359 * bus.listen(MICROBIT_ID_IO_P0, MICROBIT_BUTTON_EVT_CLICK, someFunction); 00360 * @endcode 00361 */ 00362 int MicroBitPin::isTouched() 00363 { 00364 //check if this pin has a touch mode... 00365 if(!(PIN_CAPABILITY_DIGITAL & capability)) 00366 return MICROBIT_NOT_SUPPORTED; 00367 00368 // Move into a touch input state if necessary. 00369 if (!(status & IO_STATUS_TOUCH_IN)){ 00370 disconnect(); 00371 pin = new MicroBitButton(name, id); 00372 status |= IO_STATUS_TOUCH_IN; 00373 } 00374 00375 return ((MicroBitButton *)pin)->isPressed(); 00376 } 00377 00378 /** 00379 * Configures this IO pin as an analog/pwm output if it isn't already, configures the period to be 20ms, 00380 * and sets the pulse width, based on the value it is given. 00381 * 00382 * @param pulseWidth the desired pulse width in microseconds. 00383 * 00384 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED 00385 * if the given pin does not have analog capability. 00386 */ 00387 int MicroBitPin::setServoPulseUs(int pulseWidth) 00388 { 00389 //check if this pin has an analogue mode... 00390 if(!(PIN_CAPABILITY_ANALOG & capability)) 00391 return MICROBIT_NOT_SUPPORTED; 00392 00393 //sanitise the pulse width 00394 if(pulseWidth < 0) 00395 return MICROBIT_INVALID_PARAMETER; 00396 00397 //Check we still have the control over the DynamicPwm instance 00398 if(obtainAnalogChannel() == MICROBIT_OK) 00399 { 00400 //check if the period is set to 20ms 00401 if(((DynamicPwm *)pin)->getPeriodUs() != MICROBIT_DEFAULT_PWM_PERIOD) 00402 ((DynamicPwm *)pin)->setPeriodUs(MICROBIT_DEFAULT_PWM_PERIOD); 00403 00404 ((DynamicPwm *)pin)->pulsewidth_us(pulseWidth); 00405 } 00406 00407 return MICROBIT_OK; 00408 } 00409 00410 /** 00411 * Configures the PWM period of the analog output to the given value. 00412 * 00413 * @param period The new period for the analog output in microseconds. 00414 * 00415 * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the 00416 * given pin is not configured as an analog output. 00417 */ 00418 int MicroBitPin::setAnalogPeriodUs(int period) 00419 { 00420 if (!(status & IO_STATUS_ANALOG_OUT)) 00421 return MICROBIT_NOT_SUPPORTED; 00422 00423 return ((DynamicPwm *)pin)->setPeriodUs(period); 00424 } 00425 00426 /** 00427 * Configures the PWM period of the analog output to the given value. 00428 * 00429 * @param period The new period for the analog output in milliseconds. 00430 * 00431 * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the 00432 * given pin is not configured as an analog output. 00433 */ 00434 int MicroBitPin::setAnalogPeriod(int period) 00435 { 00436 return setAnalogPeriodUs(period*1000); 00437 } 00438 00439 /** 00440 * Obtains the PWM period of the analog output in microseconds. 00441 * 00442 * @return the period on success, or MICROBIT_NOT_SUPPORTED if the 00443 * given pin is not configured as an analog output. 00444 */ 00445 int MicroBitPin::getAnalogPeriodUs() 00446 { 00447 if (!(status & IO_STATUS_ANALOG_OUT)) 00448 return MICROBIT_NOT_SUPPORTED; 00449 00450 return ((DynamicPwm *)pin)->getPeriodUs(); 00451 } 00452 00453 /** 00454 * Obtains the PWM period of the analog output in milliseconds. 00455 * 00456 * @return the period on success, or MICROBIT_NOT_SUPPORTED if the 00457 * given pin is not configured as an analog output. 00458 */ 00459 int MicroBitPin::getAnalogPeriod() 00460 { 00461 return getAnalogPeriodUs()/1000; 00462 } 00463 00464 /** 00465 * Configures the pull of this pin. 00466 * 00467 * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone 00468 * 00469 * @return MICROBIT_NOT_SUPPORTED if the current pin configuration is anything other 00470 * than a digital input, otherwise MICROBIT_OK. 00471 */ 00472 int MicroBitPin::setPull(PinMode pull) 00473 { 00474 pullMode = pull; 00475 00476 if ((status & IO_STATUS_DIGITAL_IN)) 00477 { 00478 ((DigitalIn *)pin)->mode(pull); 00479 return MICROBIT_OK; 00480 } 00481 00482 if((status & IO_STATUS_EVENT_ON_EDGE) || (status & IO_STATUS_EVENT_PULSE_ON_EDGE)) 00483 { 00484 ((TimedInterruptIn *)pin)->mode(pull); 00485 return MICROBIT_OK; 00486 } 00487 00488 return MICROBIT_NOT_SUPPORTED; 00489 } 00490 00491 /** 00492 * This member function manages the calculation of the timestamp of a pulse detected 00493 * on a pin whilst in IO_STATUS_EVENT_PULSE_ON_EDGE or IO_STATUS_EVENT_ON_EDGE modes. 00494 * 00495 * @param eventValue the event value to distribute onto the message bus. 00496 */ 00497 void MicroBitPin::pulseWidthEvent(int eventValue) 00498 { 00499 MicroBitEvent evt(id, eventValue, CREATE_ONLY); 00500 uint64_t now = evt.timestamp; 00501 uint64_t previous = ((TimedInterruptIn *)pin)->getTimestamp(); 00502 00503 if (previous != 0) 00504 { 00505 evt.timestamp -= previous; 00506 evt.fire(); 00507 } 00508 00509 ((TimedInterruptIn *)pin)->setTimestamp(now); 00510 } 00511 00512 /** 00513 * Interrupt handler for when an rise interrupt is triggered. 00514 */ 00515 void MicroBitPin::onRise() 00516 { 00517 if(status & IO_STATUS_EVENT_PULSE_ON_EDGE) 00518 pulseWidthEvent(MICROBIT_PIN_EVT_PULSE_LO); 00519 00520 if(status & IO_STATUS_EVENT_ON_EDGE) 00521 MicroBitEvent(id, MICROBIT_PIN_EVT_RISE); 00522 } 00523 00524 /** 00525 * Interrupt handler for when an fall interrupt is triggered. 00526 */ 00527 void MicroBitPin::onFall() 00528 { 00529 if(status & IO_STATUS_EVENT_PULSE_ON_EDGE) 00530 pulseWidthEvent(MICROBIT_PIN_EVT_PULSE_HI); 00531 00532 if(status & IO_STATUS_EVENT_ON_EDGE) 00533 MicroBitEvent(id, MICROBIT_PIN_EVT_FALL); 00534 } 00535 00536 /** 00537 * This member function will construct an TimedInterruptIn instance, and configure 00538 * interrupts for rise and fall. 00539 * 00540 * @param eventType the specific mode used in interrupt context to determine how an 00541 * edge/rise is processed. 00542 * 00543 * @return MICROBIT_OK on success 00544 */ 00545 int MicroBitPin::enableRiseFallEvents(int eventType) 00546 { 00547 // if we are in neither of the two modes, configure pin as a TimedInterruptIn. 00548 if (!(status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE))) 00549 { 00550 disconnect(); 00551 pin = new TimedInterruptIn(name); 00552 00553 ((TimedInterruptIn *)pin)->mode((PinMode)pullMode); 00554 ((TimedInterruptIn *)pin)->rise(this, &MicroBitPin::onRise); 00555 ((TimedInterruptIn *)pin)->fall(this, &MicroBitPin::onFall); 00556 } 00557 00558 status &= ~(IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE); 00559 00560 // set our status bits accordingly. 00561 if(eventType == MICROBIT_PIN_EVENT_ON_EDGE) 00562 status |= IO_STATUS_EVENT_ON_EDGE; 00563 else if(eventType == MICROBIT_PIN_EVENT_ON_PULSE) 00564 status |= IO_STATUS_EVENT_PULSE_ON_EDGE; 00565 00566 return MICROBIT_OK; 00567 } 00568 00569 /** 00570 * If this pin is in a mode where the pin is generating events, it will destruct 00571 * the current instance attached to this MicroBitPin instance. 00572 * 00573 * @return MICROBIT_OK on success. 00574 */ 00575 int MicroBitPin::disableEvents() 00576 { 00577 if (status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE | IO_STATUS_TOUCH_IN)) 00578 disconnect(); 00579 00580 return MICROBIT_OK; 00581 } 00582 00583 /** 00584 * Configures the events generated by this MicroBitPin instance. 00585 * 00586 * MICROBIT_PIN_EVENT_ON_EDGE - Configures this pin to a digital input, and generates events whenever a rise/fall is detected on this pin. (MICROBIT_PIN_EVT_RISE, MICROBIT_PIN_EVT_FALL) 00587 * MICROBIT_PIN_EVENT_ON_PULSE - Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either HI or LO. (MICROBIT_PIN_EVT_PULSE_HI, MICROBIT_PIN_EVT_PULSE_LO) 00588 * MICROBIT_PIN_EVENT_ON_TOUCH - Configures this pin as a makey makey style touch sensor, in the form of a MicroBitButton. Normal button events will be generated using the ID of this pin. 00589 * MICROBIT_PIN_EVENT_NONE - Disables events for this pin. 00590 * 00591 * @param eventType One of: MICROBIT_PIN_EVENT_ON_EDGE, MICROBIT_PIN_EVENT_ON_PULSE, MICROBIT_PIN_EVENT_ON_TOUCH, MICROBIT_PIN_EVENT_NONE 00592 * 00593 * @code 00594 * MicroBitMessageBus bus; 00595 * 00596 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH); 00597 * P0.eventOn(MICROBIT_PIN_EVENT_ON_PULSE); 00598 * 00599 * void onPulse(MicroBitEvent evt) 00600 * { 00601 * int duration = evt.timestamp; 00602 * } 00603 * 00604 * bus.listen(MICROBIT_ID_IO_P0, MICROBIT_PIN_EVT_PULSE_HI, onPulse, MESSAGE_BUS_LISTENER_IMMEDIATE) 00605 * @endcode 00606 * 00607 * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the given eventype does not match 00608 * 00609 * @note In the MICROBIT_PIN_EVENT_ON_PULSE mode, the smallest pulse that was reliably detected was 85us, around 5khz. If more precision is required, 00610 * please use the InterruptIn class supplied by ARM mbed. 00611 */ 00612 int MicroBitPin::eventOn(int eventType) 00613 { 00614 switch(eventType) 00615 { 00616 case MICROBIT_PIN_EVENT_ON_EDGE: 00617 case MICROBIT_PIN_EVENT_ON_PULSE: 00618 enableRiseFallEvents(eventType); 00619 break; 00620 00621 case MICROBIT_PIN_EVENT_ON_TOUCH: 00622 isTouched(); 00623 break; 00624 00625 case MICROBIT_PIN_EVENT_NONE: 00626 disableEvents(); 00627 break; 00628 00629 default: 00630 return MICROBIT_INVALID_PARAMETER; 00631 } 00632 00633 return MICROBIT_OK; 00634 }
Generated on Wed Jul 13 2022 00:58:03 by 1.7.2