Revised to disable BLE for radio communication as needed.

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit

Committer:
tsfarber
Date:
Tue Nov 26 04:12:46 2019 +0000
Revision:
74:26717338739d
Parent:
66:2fc7d7c2fffc
This program combines samples programs radio TX and radio RX so that both units can send or receive depending on which unit's buttons are pressed. Tested successfully. MicroBitConfig.h has been edited to disable BLE.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 /**
Jonathan Austin 1:8aa5cdb4ab67 27 * Class definition for MicroBitPin.
Jonathan Austin 1:8aa5cdb4ab67 28 *
Jonathan Austin 1:8aa5cdb4ab67 29 * Commonly represents an I/O pin on the edge connector.
Jonathan Austin 1:8aa5cdb4ab67 30 */
Jonathan Austin 1:8aa5cdb4ab67 31 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 32 #include "MicroBitPin.h"
Jonathan Austin 1:8aa5cdb4ab67 33 #include "MicroBitButton.h"
LancasterUniversity 49:88f03f3feff1 34 #include "MicroBitSystemTimer.h"
LancasterUniversity 49:88f03f3feff1 35 #include "TimedInterruptIn.h"
Jonathan Austin 1:8aa5cdb4ab67 36 #include "DynamicPwm.h"
Jonathan Austin 1:8aa5cdb4ab67 37 #include "ErrorNo.h"
Jonathan Austin 1:8aa5cdb4ab67 38
Jonathan Austin 1:8aa5cdb4ab67 39 /**
Jonathan Austin 1:8aa5cdb4ab67 40 * Constructor.
Jonathan Austin 1:8aa5cdb4ab67 41 * Create a MicroBitPin instance, generally used to represent a pin on the edge connector.
Jonathan Austin 1:8aa5cdb4ab67 42 *
Jonathan Austin 1:8aa5cdb4ab67 43 * @param id the unique EventModel id of this component.
Jonathan Austin 1:8aa5cdb4ab67 44 *
Jonathan Austin 1:8aa5cdb4ab67 45 * @param name the mbed PinName for this MicroBitPin instance.
Jonathan Austin 1:8aa5cdb4ab67 46 *
Jonathan Austin 1:8aa5cdb4ab67 47 * @param capability the capabilities this MicroBitPin instance should have.
LancasterUniversity 45:23b71960fe6c 48 * (PIN_CAPABILITY_DIGITAL, PIN_CAPABILITY_ANALOG, PIN_CAPABILITY_AD, PIN_CAPABILITY_ALL)
Jonathan Austin 1:8aa5cdb4ab67 49 *
Jonathan Austin 1:8aa5cdb4ab67 50 * @code
Jonathan Austin 1:8aa5cdb4ab67 51 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL);
Jonathan Austin 1:8aa5cdb4ab67 52 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 53 */
Jonathan Austin 1:8aa5cdb4ab67 54 MicroBitPin::MicroBitPin(int id, PinName name, PinCapability capability)
Jonathan Austin 1:8aa5cdb4ab67 55 {
Jonathan Austin 1:8aa5cdb4ab67 56 //set mandatory attributes
Jonathan Austin 1:8aa5cdb4ab67 57 this->id = id;
Jonathan Austin 1:8aa5cdb4ab67 58 this->name = name;
Jonathan Austin 1:8aa5cdb4ab67 59 this->capability = capability;
LancasterUniversity 66:2fc7d7c2fffc 60 this->pullMode = MICROBIT_DEFAULT_PULLMODE;
Jonathan Austin 1:8aa5cdb4ab67 61
Jonathan Austin 1:8aa5cdb4ab67 62 // Power up in a disconnected, low power state.
Jonathan Austin 1:8aa5cdb4ab67 63 // If we're unused, this is how it will stay...
Jonathan Austin 1:8aa5cdb4ab67 64 this->status = 0x00;
Jonathan Austin 1:8aa5cdb4ab67 65 this->pin = NULL;
Jonathan Austin 1:8aa5cdb4ab67 66
Jonathan Austin 1:8aa5cdb4ab67 67 }
Jonathan Austin 1:8aa5cdb4ab67 68
Jonathan Austin 1:8aa5cdb4ab67 69 /**
Jonathan Austin 1:8aa5cdb4ab67 70 * Disconnect any attached mBed IO from this pin.
Jonathan Austin 1:8aa5cdb4ab67 71 *
Jonathan Austin 1:8aa5cdb4ab67 72 * Used only when pin changes mode (i.e. Input/Output/Analog/Digital)
Jonathan Austin 1:8aa5cdb4ab67 73 */
Jonathan Austin 1:8aa5cdb4ab67 74 void MicroBitPin::disconnect()
Jonathan Austin 1:8aa5cdb4ab67 75 {
Jonathan Austin 1:8aa5cdb4ab67 76 // This is a bit ugly, but rarely used code.
Jonathan Austin 1:8aa5cdb4ab67 77 // It would be much better to use some polymorphism here, but the mBed I/O classes aren't arranged in an inheritance hierarchy... yet. :-)
Jonathan Austin 1:8aa5cdb4ab67 78 if (status & IO_STATUS_DIGITAL_IN)
Jonathan Austin 1:8aa5cdb4ab67 79 delete ((DigitalIn *)pin);
Jonathan Austin 1:8aa5cdb4ab67 80
Jonathan Austin 1:8aa5cdb4ab67 81 if (status & IO_STATUS_DIGITAL_OUT)
Jonathan Austin 1:8aa5cdb4ab67 82 delete ((DigitalOut *)pin);
Jonathan Austin 1:8aa5cdb4ab67 83
Jonathan Austin 1:8aa5cdb4ab67 84 if (status & IO_STATUS_ANALOG_IN){
Jonathan Austin 1:8aa5cdb4ab67 85 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Disabled; // forcibly disable the ADC - BUG in mbed....
Jonathan Austin 1:8aa5cdb4ab67 86 delete ((AnalogIn *)pin);
Jonathan Austin 1:8aa5cdb4ab67 87 }
Jonathan Austin 1:8aa5cdb4ab67 88
Jonathan Austin 1:8aa5cdb4ab67 89 if (status & IO_STATUS_ANALOG_OUT)
Jonathan Austin 1:8aa5cdb4ab67 90 {
Jonathan Austin 1:8aa5cdb4ab67 91 if(((DynamicPwm *)pin)->getPinName() == name)
Jonathan Austin 1:8aa5cdb4ab67 92 ((DynamicPwm *)pin)->release();
Jonathan Austin 1:8aa5cdb4ab67 93 }
Jonathan Austin 1:8aa5cdb4ab67 94
Jonathan Austin 1:8aa5cdb4ab67 95 if (status & IO_STATUS_TOUCH_IN)
Jonathan Austin 1:8aa5cdb4ab67 96 delete ((MicroBitButton *)pin);
Jonathan Austin 1:8aa5cdb4ab67 97
LancasterUniversity 49:88f03f3feff1 98 if ((status & IO_STATUS_EVENT_ON_EDGE) || (status & IO_STATUS_EVENT_PULSE_ON_EDGE))
LancasterUniversity 49:88f03f3feff1 99 delete ((TimedInterruptIn *)pin);
LancasterUniversity 49:88f03f3feff1 100
Jonathan Austin 1:8aa5cdb4ab67 101 this->pin = NULL;
LancasterUniversity 49:88f03f3feff1 102 this->status = 0;
Jonathan Austin 1:8aa5cdb4ab67 103 }
Jonathan Austin 1:8aa5cdb4ab67 104
Jonathan Austin 1:8aa5cdb4ab67 105 /**
Jonathan Austin 1:8aa5cdb4ab67 106 * Configures this IO pin as a digital output (if necessary) and sets the pin to 'value'.
Jonathan Austin 1:8aa5cdb4ab67 107 *
Jonathan Austin 1:8aa5cdb4ab67 108 * @param value 0 (LO) or 1 (HI)
Jonathan Austin 1:8aa5cdb4ab67 109 *
Jonathan Austin 1:8aa5cdb4ab67 110 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
Jonathan Austin 1:8aa5cdb4ab67 111 * if the given pin does not have digital capability.
Jonathan Austin 1:8aa5cdb4ab67 112 *
Jonathan Austin 1:8aa5cdb4ab67 113 * @code
Jonathan Austin 1:8aa5cdb4ab67 114 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
Jonathan Austin 1:8aa5cdb4ab67 115 * P0.setDigitalValue(1); // P0 is now HI
Jonathan Austin 1:8aa5cdb4ab67 116 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 117 */
Jonathan Austin 1:8aa5cdb4ab67 118 int MicroBitPin::setDigitalValue(int value)
Jonathan Austin 1:8aa5cdb4ab67 119 {
Jonathan Austin 1:8aa5cdb4ab67 120 // Check if this pin has a digital mode...
Jonathan Austin 1:8aa5cdb4ab67 121 if(!(PIN_CAPABILITY_DIGITAL & capability))
Jonathan Austin 1:8aa5cdb4ab67 122 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 123
Jonathan Austin 1:8aa5cdb4ab67 124 // Ensure we have a valid value.
Jonathan Austin 1:8aa5cdb4ab67 125 if (value < 0 || value > 1)
Jonathan Austin 1:8aa5cdb4ab67 126 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 127
Jonathan Austin 1:8aa5cdb4ab67 128 // Move into a Digital input state if necessary.
Jonathan Austin 1:8aa5cdb4ab67 129 if (!(status & IO_STATUS_DIGITAL_OUT)){
Jonathan Austin 1:8aa5cdb4ab67 130 disconnect();
Jonathan Austin 1:8aa5cdb4ab67 131 pin = new DigitalOut(name);
Jonathan Austin 1:8aa5cdb4ab67 132 status |= IO_STATUS_DIGITAL_OUT;
Jonathan Austin 1:8aa5cdb4ab67 133 }
Jonathan Austin 1:8aa5cdb4ab67 134
Jonathan Austin 1:8aa5cdb4ab67 135 // Write the value.
Jonathan Austin 1:8aa5cdb4ab67 136 ((DigitalOut *)pin)->write(value);
Jonathan Austin 1:8aa5cdb4ab67 137
Jonathan Austin 1:8aa5cdb4ab67 138 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 139 }
Jonathan Austin 1:8aa5cdb4ab67 140
Jonathan Austin 1:8aa5cdb4ab67 141 /**
Jonathan Austin 1:8aa5cdb4ab67 142 * Configures this IO pin as a digital input (if necessary) and tests its current value.
Jonathan Austin 1:8aa5cdb4ab67 143 *
LancasterUniversity 49:88f03f3feff1 144 *
Jonathan Austin 1:8aa5cdb4ab67 145 * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
LancasterUniversity 49:88f03f3feff1 146 * if the given pin does not have digital capability.
Jonathan Austin 1:8aa5cdb4ab67 147 *
Jonathan Austin 1:8aa5cdb4ab67 148 * @code
Jonathan Austin 1:8aa5cdb4ab67 149 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
Jonathan Austin 1:8aa5cdb4ab67 150 * P0.getDigitalValue(); // P0 is either 0 or 1;
Jonathan Austin 1:8aa5cdb4ab67 151 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 152 */
Jonathan Austin 1:8aa5cdb4ab67 153 int MicroBitPin::getDigitalValue()
Jonathan Austin 1:8aa5cdb4ab67 154 {
Jonathan Austin 1:8aa5cdb4ab67 155 //check if this pin has a digital mode...
Jonathan Austin 1:8aa5cdb4ab67 156 if(!(PIN_CAPABILITY_DIGITAL & capability))
Jonathan Austin 1:8aa5cdb4ab67 157 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 158
Jonathan Austin 1:8aa5cdb4ab67 159 // Move into a Digital input state if necessary.
LancasterUniversity 49:88f03f3feff1 160 if (!(status & (IO_STATUS_DIGITAL_IN | IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE)))
LancasterUniversity 49:88f03f3feff1 161 {
Jonathan Austin 1:8aa5cdb4ab67 162 disconnect();
LancasterUniversity 66:2fc7d7c2fffc 163 pin = new DigitalIn(name, (PinMode)pullMode);
Jonathan Austin 1:8aa5cdb4ab67 164 status |= IO_STATUS_DIGITAL_IN;
Jonathan Austin 1:8aa5cdb4ab67 165 }
Jonathan Austin 1:8aa5cdb4ab67 166
LancasterUniversity 49:88f03f3feff1 167 if(status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE))
LancasterUniversity 49:88f03f3feff1 168 return ((TimedInterruptIn *)pin)->read();
LancasterUniversity 49:88f03f3feff1 169
Jonathan Austin 1:8aa5cdb4ab67 170 return ((DigitalIn *)pin)->read();
Jonathan Austin 1:8aa5cdb4ab67 171 }
Jonathan Austin 1:8aa5cdb4ab67 172
LancasterUniversity 66:2fc7d7c2fffc 173 /**
LancasterUniversity 66:2fc7d7c2fffc 174 * Configures this IO pin as a digital input with the specified internal pull-up/pull-down configuraiton (if necessary) and tests its current value.
LancasterUniversity 66:2fc7d7c2fffc 175 *
LancasterUniversity 66:2fc7d7c2fffc 176 * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
LancasterUniversity 66:2fc7d7c2fffc 177 *
LancasterUniversity 66:2fc7d7c2fffc 178 * @return 1 if this input is high, 0 if input is LO, or MICROBIT_NOT_SUPPORTED
LancasterUniversity 66:2fc7d7c2fffc 179 * if the given pin does not have digital capability.
LancasterUniversity 66:2fc7d7c2fffc 180 *
LancasterUniversity 66:2fc7d7c2fffc 181 * @code
LancasterUniversity 66:2fc7d7c2fffc 182 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
LancasterUniversity 66:2fc7d7c2fffc 183 * P0.getDigitalValue(PullUp); // P0 is either 0 or 1;
LancasterUniversity 66:2fc7d7c2fffc 184 * @endcode
LancasterUniversity 66:2fc7d7c2fffc 185 */
LancasterUniversity 66:2fc7d7c2fffc 186 int MicroBitPin::getDigitalValue(PinMode pull)
LancasterUniversity 66:2fc7d7c2fffc 187 {
LancasterUniversity 66:2fc7d7c2fffc 188 setPull(pull);
LancasterUniversity 66:2fc7d7c2fffc 189 return getDigitalValue();
LancasterUniversity 66:2fc7d7c2fffc 190 }
LancasterUniversity 66:2fc7d7c2fffc 191
Jonathan Austin 1:8aa5cdb4ab67 192 int MicroBitPin::obtainAnalogChannel()
Jonathan Austin 1:8aa5cdb4ab67 193 {
Jonathan Austin 1:8aa5cdb4ab67 194 // Move into an analogue input state if necessary, if we are no longer the focus of a DynamicPWM instance, allocate ourselves again!
Jonathan Austin 1:8aa5cdb4ab67 195 if (!(status & IO_STATUS_ANALOG_OUT) || !(((DynamicPwm *)pin)->getPinName() == name)){
Jonathan Austin 1:8aa5cdb4ab67 196 disconnect();
Jonathan Austin 1:8aa5cdb4ab67 197 pin = (void *)DynamicPwm::allocate(name);
Jonathan Austin 1:8aa5cdb4ab67 198 status |= IO_STATUS_ANALOG_OUT;
Jonathan Austin 1:8aa5cdb4ab67 199 }
Jonathan Austin 1:8aa5cdb4ab67 200
Jonathan Austin 1:8aa5cdb4ab67 201 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 202 }
Jonathan Austin 1:8aa5cdb4ab67 203
Jonathan Austin 1:8aa5cdb4ab67 204 /**
Jonathan Austin 1:8aa5cdb4ab67 205 * Configures this IO pin as an analog/pwm output, and change the output value to the given level.
Jonathan Austin 1:8aa5cdb4ab67 206 *
Jonathan Austin 1:8aa5cdb4ab67 207 * @param value the level to set on the output pin, in the range 0 - 1024
Jonathan Austin 1:8aa5cdb4ab67 208 *
Jonathan Austin 1:8aa5cdb4ab67 209 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
Jonathan Austin 1:8aa5cdb4ab67 210 * if the given pin does not have analog capability.
Jonathan Austin 1:8aa5cdb4ab67 211 */
Jonathan Austin 1:8aa5cdb4ab67 212 int MicroBitPin::setAnalogValue(int value)
Jonathan Austin 1:8aa5cdb4ab67 213 {
Jonathan Austin 1:8aa5cdb4ab67 214 //check if this pin has an analogue mode...
Jonathan Austin 1:8aa5cdb4ab67 215 if(!(PIN_CAPABILITY_ANALOG & capability))
Jonathan Austin 1:8aa5cdb4ab67 216 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 217
Jonathan Austin 1:8aa5cdb4ab67 218 //sanitise the level value
Jonathan Austin 1:8aa5cdb4ab67 219 if(value < 0 || value > MICROBIT_PIN_MAX_OUTPUT)
Jonathan Austin 1:8aa5cdb4ab67 220 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 221
Jonathan Austin 1:8aa5cdb4ab67 222 float level = (float)value / float(MICROBIT_PIN_MAX_OUTPUT);
Jonathan Austin 1:8aa5cdb4ab67 223
Jonathan Austin 1:8aa5cdb4ab67 224 //obtain use of the DynamicPwm instance, if it has changed / configure if we do not have one
Jonathan Austin 1:8aa5cdb4ab67 225 if(obtainAnalogChannel() == MICROBIT_OK)
Jonathan Austin 1:8aa5cdb4ab67 226 return ((DynamicPwm *)pin)->write(level);
Jonathan Austin 1:8aa5cdb4ab67 227
Jonathan Austin 1:8aa5cdb4ab67 228 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 229 }
Jonathan Austin 1:8aa5cdb4ab67 230
Jonathan Austin 1:8aa5cdb4ab67 231 /**
Jonathan Austin 1:8aa5cdb4ab67 232 * Configures this IO pin as an analog/pwm output (if necessary) and configures the period to be 20ms,
Jonathan Austin 1:8aa5cdb4ab67 233 * with a duty cycle between 500 us and 2500 us.
Jonathan Austin 1:8aa5cdb4ab67 234 *
Jonathan Austin 1:8aa5cdb4ab67 235 * 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.
Jonathan Austin 1:8aa5cdb4ab67 236 *
Jonathan Austin 1:8aa5cdb4ab67 237 * This range can be modified to fine tune, and also tolerate different servos.
Jonathan Austin 1:8aa5cdb4ab67 238 *
Jonathan Austin 1:8aa5cdb4ab67 239 * @param value the level to set on the output pin, in the range 0 - 180.
Jonathan Austin 1:8aa5cdb4ab67 240 *
Jonathan Austin 1:8aa5cdb4ab67 241 * @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.
Jonathan Austin 1:8aa5cdb4ab67 242 *
Jonathan Austin 1:8aa5cdb4ab67 243 * @param center the center point from which to calculate the lower and upper bounds. Defaults to MICROBIT_PIN_DEFAULT_SERVO_CENTER
Jonathan Austin 1:8aa5cdb4ab67 244 *
Jonathan Austin 1:8aa5cdb4ab67 245 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
Jonathan Austin 1:8aa5cdb4ab67 246 * if the given pin does not have analog capability.
Jonathan Austin 1:8aa5cdb4ab67 247 */
Jonathan Austin 1:8aa5cdb4ab67 248 int MicroBitPin::setServoValue(int value, int range, int center)
Jonathan Austin 1:8aa5cdb4ab67 249 {
Jonathan Austin 1:8aa5cdb4ab67 250 //check if this pin has an analogue mode...
Jonathan Austin 1:8aa5cdb4ab67 251 if(!(PIN_CAPABILITY_ANALOG & capability))
Jonathan Austin 1:8aa5cdb4ab67 252 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 253
Jonathan Austin 1:8aa5cdb4ab67 254 //sanitise the servo level
Jonathan Austin 1:8aa5cdb4ab67 255 if(value < 0 || range < 1 || center < 1)
Jonathan Austin 1:8aa5cdb4ab67 256 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 257
Jonathan Austin 1:8aa5cdb4ab67 258 //clip - just in case
Jonathan Austin 1:8aa5cdb4ab67 259 if(value > MICROBIT_PIN_MAX_SERVO_RANGE)
Jonathan Austin 1:8aa5cdb4ab67 260 value = MICROBIT_PIN_MAX_SERVO_RANGE;
Jonathan Austin 1:8aa5cdb4ab67 261
Jonathan Austin 1:8aa5cdb4ab67 262 //calculate the lower bound based on the midpoint
Jonathan Austin 1:8aa5cdb4ab67 263 int lower = (center - (range / 2)) * 1000;
Jonathan Austin 1:8aa5cdb4ab67 264
Jonathan Austin 1:8aa5cdb4ab67 265 value = value * 1000;
Jonathan Austin 1:8aa5cdb4ab67 266
Jonathan Austin 1:8aa5cdb4ab67 267 //add the percentage of the range based on the value between 0 and 180
Jonathan Austin 1:8aa5cdb4ab67 268 int scaled = lower + (range * (value / MICROBIT_PIN_MAX_SERVO_RANGE));
Jonathan Austin 1:8aa5cdb4ab67 269
Jonathan Austin 1:8aa5cdb4ab67 270 return setServoPulseUs(scaled / 1000);
Jonathan Austin 1:8aa5cdb4ab67 271 }
Jonathan Austin 1:8aa5cdb4ab67 272
Jonathan Austin 1:8aa5cdb4ab67 273 /**
Jonathan Austin 1:8aa5cdb4ab67 274 * Configures this IO pin as an analogue input (if necessary), and samples the Pin for its analog value.
Jonathan Austin 1:8aa5cdb4ab67 275 *
Jonathan Austin 1:8aa5cdb4ab67 276 * @return the current analogue level on the pin, in the range 0 - 1024, or
Jonathan Austin 1:8aa5cdb4ab67 277 * MICROBIT_NOT_SUPPORTED if the given pin does not have analog capability.
Jonathan Austin 1:8aa5cdb4ab67 278 *
Jonathan Austin 1:8aa5cdb4ab67 279 * @code
Jonathan Austin 1:8aa5cdb4ab67 280 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
Jonathan Austin 1:8aa5cdb4ab67 281 * P0.getAnalogValue(); // P0 is a value in the range of 0 - 1024
Jonathan Austin 1:8aa5cdb4ab67 282 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 283 */
Jonathan Austin 1:8aa5cdb4ab67 284 int MicroBitPin::getAnalogValue()
Jonathan Austin 1:8aa5cdb4ab67 285 {
Jonathan Austin 1:8aa5cdb4ab67 286 //check if this pin has an analogue mode...
Jonathan Austin 1:8aa5cdb4ab67 287 if(!(PIN_CAPABILITY_ANALOG & capability))
Jonathan Austin 1:8aa5cdb4ab67 288 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 289
Jonathan Austin 1:8aa5cdb4ab67 290 // Move into an analogue input state if necessary.
Jonathan Austin 1:8aa5cdb4ab67 291 if (!(status & IO_STATUS_ANALOG_IN)){
Jonathan Austin 1:8aa5cdb4ab67 292 disconnect();
Jonathan Austin 1:8aa5cdb4ab67 293 pin = new AnalogIn(name);
Jonathan Austin 1:8aa5cdb4ab67 294 status |= IO_STATUS_ANALOG_IN;
Jonathan Austin 1:8aa5cdb4ab67 295 }
Jonathan Austin 1:8aa5cdb4ab67 296
Jonathan Austin 1:8aa5cdb4ab67 297 //perform a read!
Jonathan Austin 1:8aa5cdb4ab67 298 return ((AnalogIn *)pin)->read_u16();
Jonathan Austin 1:8aa5cdb4ab67 299 }
Jonathan Austin 1:8aa5cdb4ab67 300
Jonathan Austin 1:8aa5cdb4ab67 301 /**
Jonathan Austin 1:8aa5cdb4ab67 302 * Determines if this IO pin is currently configured as an input.
Jonathan Austin 1:8aa5cdb4ab67 303 *
Jonathan Austin 1:8aa5cdb4ab67 304 * @return 1 if pin is an analog or digital input, 0 otherwise.
Jonathan Austin 1:8aa5cdb4ab67 305 */
Jonathan Austin 1:8aa5cdb4ab67 306 int MicroBitPin::isInput()
Jonathan Austin 1:8aa5cdb4ab67 307 {
Jonathan Austin 1:8aa5cdb4ab67 308 return (status & (IO_STATUS_DIGITAL_IN | IO_STATUS_ANALOG_IN)) == 0 ? 0 : 1;
Jonathan Austin 1:8aa5cdb4ab67 309 }
Jonathan Austin 1:8aa5cdb4ab67 310
Jonathan Austin 1:8aa5cdb4ab67 311 /**
Jonathan Austin 1:8aa5cdb4ab67 312 * Determines if this IO pin is currently configured as an output.
Jonathan Austin 1:8aa5cdb4ab67 313 *
Jonathan Austin 1:8aa5cdb4ab67 314 * @return 1 if pin is an analog or digital output, 0 otherwise.
Jonathan Austin 1:8aa5cdb4ab67 315 */
Jonathan Austin 1:8aa5cdb4ab67 316 int MicroBitPin::isOutput()
Jonathan Austin 1:8aa5cdb4ab67 317 {
Jonathan Austin 1:8aa5cdb4ab67 318 return (status & (IO_STATUS_DIGITAL_OUT | IO_STATUS_ANALOG_OUT)) == 0 ? 0 : 1;
Jonathan Austin 1:8aa5cdb4ab67 319 }
Jonathan Austin 1:8aa5cdb4ab67 320
Jonathan Austin 1:8aa5cdb4ab67 321 /**
Jonathan Austin 1:8aa5cdb4ab67 322 * Determines if this IO pin is currently configured for digital use.
Jonathan Austin 1:8aa5cdb4ab67 323 *
Jonathan Austin 1:8aa5cdb4ab67 324 * @return 1 if pin is digital, 0 otherwise.
Jonathan Austin 1:8aa5cdb4ab67 325 */
Jonathan Austin 1:8aa5cdb4ab67 326 int MicroBitPin::isDigital()
Jonathan Austin 1:8aa5cdb4ab67 327 {
Jonathan Austin 1:8aa5cdb4ab67 328 return (status & (IO_STATUS_DIGITAL_IN | IO_STATUS_DIGITAL_OUT)) == 0 ? 0 : 1;
Jonathan Austin 1:8aa5cdb4ab67 329 }
Jonathan Austin 1:8aa5cdb4ab67 330
Jonathan Austin 1:8aa5cdb4ab67 331 /**
Jonathan Austin 1:8aa5cdb4ab67 332 * Determines if this IO pin is currently configured for analog use.
Jonathan Austin 1:8aa5cdb4ab67 333 *
Jonathan Austin 1:8aa5cdb4ab67 334 * @return 1 if pin is analog, 0 otherwise.
Jonathan Austin 1:8aa5cdb4ab67 335 */
Jonathan Austin 1:8aa5cdb4ab67 336 int MicroBitPin::isAnalog()
Jonathan Austin 1:8aa5cdb4ab67 337 {
Jonathan Austin 1:8aa5cdb4ab67 338 return (status & (IO_STATUS_ANALOG_IN | IO_STATUS_ANALOG_OUT)) == 0 ? 0 : 1;
Jonathan Austin 1:8aa5cdb4ab67 339 }
Jonathan Austin 1:8aa5cdb4ab67 340
Jonathan Austin 1:8aa5cdb4ab67 341 /**
Jonathan Austin 1:8aa5cdb4ab67 342 * Configures this IO pin as a "makey makey" style touch sensor (if necessary)
Jonathan Austin 1:8aa5cdb4ab67 343 * and tests its current debounced state.
Jonathan Austin 1:8aa5cdb4ab67 344 *
Jonathan Austin 1:8aa5cdb4ab67 345 * Users can also subscribe to MicroBitButton events generated from this pin.
Jonathan Austin 1:8aa5cdb4ab67 346 *
Jonathan Austin 1:8aa5cdb4ab67 347 * @return 1 if pin is touched, 0 if not, or MICROBIT_NOT_SUPPORTED if this pin does not support touch capability.
Jonathan Austin 1:8aa5cdb4ab67 348 *
Jonathan Austin 1:8aa5cdb4ab67 349 * @code
Jonathan Austin 1:8aa5cdb4ab67 350 * MicroBitMessageBus bus;
Jonathan Austin 1:8aa5cdb4ab67 351 *
Jonathan Austin 1:8aa5cdb4ab67 352 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL);
Jonathan Austin 1:8aa5cdb4ab67 353 * if(P0.isTouched())
Jonathan Austin 1:8aa5cdb4ab67 354 * {
Jonathan Austin 1:8aa5cdb4ab67 355 * //do something!
Jonathan Austin 1:8aa5cdb4ab67 356 * }
Jonathan Austin 1:8aa5cdb4ab67 357 *
Jonathan Austin 1:8aa5cdb4ab67 358 * // subscribe to events generated by this pin!
Jonathan Austin 1:8aa5cdb4ab67 359 * bus.listen(MICROBIT_ID_IO_P0, MICROBIT_BUTTON_EVT_CLICK, someFunction);
Jonathan Austin 1:8aa5cdb4ab67 360 * @endcode
Jonathan Austin 1:8aa5cdb4ab67 361 */
Jonathan Austin 1:8aa5cdb4ab67 362 int MicroBitPin::isTouched()
Jonathan Austin 1:8aa5cdb4ab67 363 {
Jonathan Austin 1:8aa5cdb4ab67 364 //check if this pin has a touch mode...
LancasterUniversity 45:23b71960fe6c 365 if(!(PIN_CAPABILITY_DIGITAL & capability))
Jonathan Austin 1:8aa5cdb4ab67 366 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 367
Jonathan Austin 1:8aa5cdb4ab67 368 // Move into a touch input state if necessary.
Jonathan Austin 1:8aa5cdb4ab67 369 if (!(status & IO_STATUS_TOUCH_IN)){
Jonathan Austin 1:8aa5cdb4ab67 370 disconnect();
Jonathan Austin 1:8aa5cdb4ab67 371 pin = new MicroBitButton(name, id);
Jonathan Austin 1:8aa5cdb4ab67 372 status |= IO_STATUS_TOUCH_IN;
Jonathan Austin 1:8aa5cdb4ab67 373 }
Jonathan Austin 1:8aa5cdb4ab67 374
Jonathan Austin 1:8aa5cdb4ab67 375 return ((MicroBitButton *)pin)->isPressed();
Jonathan Austin 1:8aa5cdb4ab67 376 }
Jonathan Austin 1:8aa5cdb4ab67 377
Jonathan Austin 1:8aa5cdb4ab67 378 /**
Jonathan Austin 1:8aa5cdb4ab67 379 * Configures this IO pin as an analog/pwm output if it isn't already, configures the period to be 20ms,
Jonathan Austin 1:8aa5cdb4ab67 380 * and sets the pulse width, based on the value it is given.
Jonathan Austin 1:8aa5cdb4ab67 381 *
Jonathan Austin 1:8aa5cdb4ab67 382 * @param pulseWidth the desired pulse width in microseconds.
Jonathan Austin 1:8aa5cdb4ab67 383 *
Jonathan Austin 1:8aa5cdb4ab67 384 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER if value is out of range, or MICROBIT_NOT_SUPPORTED
Jonathan Austin 1:8aa5cdb4ab67 385 * if the given pin does not have analog capability.
Jonathan Austin 1:8aa5cdb4ab67 386 */
Jonathan Austin 1:8aa5cdb4ab67 387 int MicroBitPin::setServoPulseUs(int pulseWidth)
Jonathan Austin 1:8aa5cdb4ab67 388 {
Jonathan Austin 1:8aa5cdb4ab67 389 //check if this pin has an analogue mode...
Jonathan Austin 1:8aa5cdb4ab67 390 if(!(PIN_CAPABILITY_ANALOG & capability))
Jonathan Austin 1:8aa5cdb4ab67 391 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 392
Jonathan Austin 1:8aa5cdb4ab67 393 //sanitise the pulse width
Jonathan Austin 1:8aa5cdb4ab67 394 if(pulseWidth < 0)
Jonathan Austin 1:8aa5cdb4ab67 395 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 396
Jonathan Austin 1:8aa5cdb4ab67 397 //Check we still have the control over the DynamicPwm instance
Jonathan Austin 1:8aa5cdb4ab67 398 if(obtainAnalogChannel() == MICROBIT_OK)
Jonathan Austin 1:8aa5cdb4ab67 399 {
Jonathan Austin 1:8aa5cdb4ab67 400 //check if the period is set to 20ms
Jonathan Austin 1:8aa5cdb4ab67 401 if(((DynamicPwm *)pin)->getPeriodUs() != MICROBIT_DEFAULT_PWM_PERIOD)
Jonathan Austin 1:8aa5cdb4ab67 402 ((DynamicPwm *)pin)->setPeriodUs(MICROBIT_DEFAULT_PWM_PERIOD);
Jonathan Austin 1:8aa5cdb4ab67 403
Jonathan Austin 1:8aa5cdb4ab67 404 ((DynamicPwm *)pin)->pulsewidth_us(pulseWidth);
Jonathan Austin 1:8aa5cdb4ab67 405 }
Jonathan Austin 1:8aa5cdb4ab67 406
Jonathan Austin 1:8aa5cdb4ab67 407 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 408 }
Jonathan Austin 1:8aa5cdb4ab67 409
Jonathan Austin 1:8aa5cdb4ab67 410 /**
Jonathan Austin 1:8aa5cdb4ab67 411 * Configures the PWM period of the analog output to the given value.
Jonathan Austin 1:8aa5cdb4ab67 412 *
Jonathan Austin 1:8aa5cdb4ab67 413 * @param period The new period for the analog output in microseconds.
Jonathan Austin 1:8aa5cdb4ab67 414 *
Jonathan Austin 1:8aa5cdb4ab67 415 * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the
Jonathan Austin 1:8aa5cdb4ab67 416 * given pin is not configured as an analog output.
Jonathan Austin 1:8aa5cdb4ab67 417 */
Jonathan Austin 1:8aa5cdb4ab67 418 int MicroBitPin::setAnalogPeriodUs(int period)
Jonathan Austin 1:8aa5cdb4ab67 419 {
Jonathan Austin 1:8aa5cdb4ab67 420 if (!(status & IO_STATUS_ANALOG_OUT))
Jonathan Austin 1:8aa5cdb4ab67 421 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 422
Jonathan Austin 1:8aa5cdb4ab67 423 return ((DynamicPwm *)pin)->setPeriodUs(period);
Jonathan Austin 1:8aa5cdb4ab67 424 }
Jonathan Austin 1:8aa5cdb4ab67 425
Jonathan Austin 1:8aa5cdb4ab67 426 /**
Jonathan Austin 1:8aa5cdb4ab67 427 * Configures the PWM period of the analog output to the given value.
Jonathan Austin 1:8aa5cdb4ab67 428 *
Jonathan Austin 1:8aa5cdb4ab67 429 * @param period The new period for the analog output in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 430 *
Jonathan Austin 1:8aa5cdb4ab67 431 * @return MICROBIT_OK on success, or MICROBIT_NOT_SUPPORTED if the
Jonathan Austin 1:8aa5cdb4ab67 432 * given pin is not configured as an analog output.
Jonathan Austin 1:8aa5cdb4ab67 433 */
Jonathan Austin 1:8aa5cdb4ab67 434 int MicroBitPin::setAnalogPeriod(int period)
Jonathan Austin 1:8aa5cdb4ab67 435 {
Jonathan Austin 1:8aa5cdb4ab67 436 return setAnalogPeriodUs(period*1000);
Jonathan Austin 1:8aa5cdb4ab67 437 }
Jonathan Austin 1:8aa5cdb4ab67 438
Jonathan Austin 1:8aa5cdb4ab67 439 /**
Jonathan Austin 1:8aa5cdb4ab67 440 * Obtains the PWM period of the analog output in microseconds.
Jonathan Austin 1:8aa5cdb4ab67 441 *
Jonathan Austin 1:8aa5cdb4ab67 442 * @return the period on success, or MICROBIT_NOT_SUPPORTED if the
Jonathan Austin 1:8aa5cdb4ab67 443 * given pin is not configured as an analog output.
Jonathan Austin 1:8aa5cdb4ab67 444 */
Jonathan Austin 1:8aa5cdb4ab67 445 int MicroBitPin::getAnalogPeriodUs()
Jonathan Austin 1:8aa5cdb4ab67 446 {
Jonathan Austin 1:8aa5cdb4ab67 447 if (!(status & IO_STATUS_ANALOG_OUT))
Jonathan Austin 1:8aa5cdb4ab67 448 return MICROBIT_NOT_SUPPORTED;
Jonathan Austin 1:8aa5cdb4ab67 449
Jonathan Austin 1:8aa5cdb4ab67 450 return ((DynamicPwm *)pin)->getPeriodUs();
Jonathan Austin 1:8aa5cdb4ab67 451 }
Jonathan Austin 1:8aa5cdb4ab67 452
Jonathan Austin 1:8aa5cdb4ab67 453 /**
Jonathan Austin 1:8aa5cdb4ab67 454 * Obtains the PWM period of the analog output in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 455 *
Jonathan Austin 1:8aa5cdb4ab67 456 * @return the period on success, or MICROBIT_NOT_SUPPORTED if the
Jonathan Austin 1:8aa5cdb4ab67 457 * given pin is not configured as an analog output.
Jonathan Austin 1:8aa5cdb4ab67 458 */
Jonathan Austin 1:8aa5cdb4ab67 459 int MicroBitPin::getAnalogPeriod()
Jonathan Austin 1:8aa5cdb4ab67 460 {
Jonathan Austin 1:8aa5cdb4ab67 461 return getAnalogPeriodUs()/1000;
LancasterUniversity 49:88f03f3feff1 462 }
LancasterUniversity 49:88f03f3feff1 463
LancasterUniversity 49:88f03f3feff1 464 /**
LancasterUniversity 49:88f03f3feff1 465 * Configures the pull of this pin.
LancasterUniversity 49:88f03f3feff1 466 *
LancasterUniversity 53:ee44932401cb 467 * @param pull one of the mbed pull configurations: PullUp, PullDown, PullNone
LancasterUniversity 49:88f03f3feff1 468 *
LancasterUniversity 49:88f03f3feff1 469 * @return MICROBIT_NOT_SUPPORTED if the current pin configuration is anything other
LancasterUniversity 49:88f03f3feff1 470 * than a digital input, otherwise MICROBIT_OK.
LancasterUniversity 49:88f03f3feff1 471 */
LancasterUniversity 49:88f03f3feff1 472 int MicroBitPin::setPull(PinMode pull)
LancasterUniversity 49:88f03f3feff1 473 {
LancasterUniversity 66:2fc7d7c2fffc 474 pullMode = pull;
LancasterUniversity 66:2fc7d7c2fffc 475
LancasterUniversity 49:88f03f3feff1 476 if ((status & IO_STATUS_DIGITAL_IN))
LancasterUniversity 49:88f03f3feff1 477 {
LancasterUniversity 49:88f03f3feff1 478 ((DigitalIn *)pin)->mode(pull);
LancasterUniversity 49:88f03f3feff1 479 return MICROBIT_OK;
LancasterUniversity 49:88f03f3feff1 480 }
LancasterUniversity 49:88f03f3feff1 481
LancasterUniversity 49:88f03f3feff1 482 if((status & IO_STATUS_EVENT_ON_EDGE) || (status & IO_STATUS_EVENT_PULSE_ON_EDGE))
LancasterUniversity 49:88f03f3feff1 483 {
LancasterUniversity 49:88f03f3feff1 484 ((TimedInterruptIn *)pin)->mode(pull);
LancasterUniversity 49:88f03f3feff1 485 return MICROBIT_OK;
LancasterUniversity 49:88f03f3feff1 486 }
LancasterUniversity 49:88f03f3feff1 487
LancasterUniversity 49:88f03f3feff1 488 return MICROBIT_NOT_SUPPORTED;
LancasterUniversity 49:88f03f3feff1 489 }
LancasterUniversity 49:88f03f3feff1 490
LancasterUniversity 49:88f03f3feff1 491 /**
LancasterUniversity 49:88f03f3feff1 492 * This member function manages the calculation of the timestamp of a pulse detected
LancasterUniversity 49:88f03f3feff1 493 * on a pin whilst in IO_STATUS_EVENT_PULSE_ON_EDGE or IO_STATUS_EVENT_ON_EDGE modes.
LancasterUniversity 49:88f03f3feff1 494 *
LancasterUniversity 49:88f03f3feff1 495 * @param eventValue the event value to distribute onto the message bus.
LancasterUniversity 49:88f03f3feff1 496 */
LancasterUniversity 49:88f03f3feff1 497 void MicroBitPin::pulseWidthEvent(int eventValue)
LancasterUniversity 49:88f03f3feff1 498 {
LancasterUniversity 49:88f03f3feff1 499 MicroBitEvent evt(id, eventValue, CREATE_ONLY);
LancasterUniversity 49:88f03f3feff1 500 uint64_t now = evt.timestamp;
LancasterUniversity 49:88f03f3feff1 501 uint64_t previous = ((TimedInterruptIn *)pin)->getTimestamp();
LancasterUniversity 49:88f03f3feff1 502
LancasterUniversity 49:88f03f3feff1 503 if (previous != 0)
LancasterUniversity 49:88f03f3feff1 504 {
LancasterUniversity 49:88f03f3feff1 505 evt.timestamp -= previous;
LancasterUniversity 49:88f03f3feff1 506 evt.fire();
LancasterUniversity 49:88f03f3feff1 507 }
LancasterUniversity 49:88f03f3feff1 508
LancasterUniversity 49:88f03f3feff1 509 ((TimedInterruptIn *)pin)->setTimestamp(now);
LancasterUniversity 49:88f03f3feff1 510 }
LancasterUniversity 49:88f03f3feff1 511
LancasterUniversity 49:88f03f3feff1 512 /**
LancasterUniversity 49:88f03f3feff1 513 * Interrupt handler for when an rise interrupt is triggered.
LancasterUniversity 49:88f03f3feff1 514 */
LancasterUniversity 49:88f03f3feff1 515 void MicroBitPin::onRise()
LancasterUniversity 49:88f03f3feff1 516 {
LancasterUniversity 49:88f03f3feff1 517 if(status & IO_STATUS_EVENT_PULSE_ON_EDGE)
LancasterUniversity 49:88f03f3feff1 518 pulseWidthEvent(MICROBIT_PIN_EVT_PULSE_LO);
LancasterUniversity 49:88f03f3feff1 519
LancasterUniversity 49:88f03f3feff1 520 if(status & IO_STATUS_EVENT_ON_EDGE)
LancasterUniversity 49:88f03f3feff1 521 MicroBitEvent(id, MICROBIT_PIN_EVT_RISE);
LancasterUniversity 49:88f03f3feff1 522 }
LancasterUniversity 49:88f03f3feff1 523
LancasterUniversity 49:88f03f3feff1 524 /**
LancasterUniversity 49:88f03f3feff1 525 * Interrupt handler for when an fall interrupt is triggered.
LancasterUniversity 49:88f03f3feff1 526 */
LancasterUniversity 49:88f03f3feff1 527 void MicroBitPin::onFall()
LancasterUniversity 49:88f03f3feff1 528 {
LancasterUniversity 49:88f03f3feff1 529 if(status & IO_STATUS_EVENT_PULSE_ON_EDGE)
LancasterUniversity 49:88f03f3feff1 530 pulseWidthEvent(MICROBIT_PIN_EVT_PULSE_HI);
LancasterUniversity 49:88f03f3feff1 531
LancasterUniversity 49:88f03f3feff1 532 if(status & IO_STATUS_EVENT_ON_EDGE)
LancasterUniversity 49:88f03f3feff1 533 MicroBitEvent(id, MICROBIT_PIN_EVT_FALL);
LancasterUniversity 49:88f03f3feff1 534 }
LancasterUniversity 49:88f03f3feff1 535
LancasterUniversity 49:88f03f3feff1 536 /**
LancasterUniversity 49:88f03f3feff1 537 * This member function will construct an TimedInterruptIn instance, and configure
LancasterUniversity 49:88f03f3feff1 538 * interrupts for rise and fall.
LancasterUniversity 49:88f03f3feff1 539 *
LancasterUniversity 49:88f03f3feff1 540 * @param eventType the specific mode used in interrupt context to determine how an
LancasterUniversity 49:88f03f3feff1 541 * edge/rise is processed.
LancasterUniversity 49:88f03f3feff1 542 *
LancasterUniversity 49:88f03f3feff1 543 * @return MICROBIT_OK on success
LancasterUniversity 49:88f03f3feff1 544 */
LancasterUniversity 49:88f03f3feff1 545 int MicroBitPin::enableRiseFallEvents(int eventType)
LancasterUniversity 49:88f03f3feff1 546 {
LancasterUniversity 49:88f03f3feff1 547 // if we are in neither of the two modes, configure pin as a TimedInterruptIn.
LancasterUniversity 49:88f03f3feff1 548 if (!(status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE)))
LancasterUniversity 49:88f03f3feff1 549 {
LancasterUniversity 49:88f03f3feff1 550 disconnect();
LancasterUniversity 49:88f03f3feff1 551 pin = new TimedInterruptIn(name);
LancasterUniversity 49:88f03f3feff1 552
LancasterUniversity 66:2fc7d7c2fffc 553 ((TimedInterruptIn *)pin)->mode((PinMode)pullMode);
LancasterUniversity 49:88f03f3feff1 554 ((TimedInterruptIn *)pin)->rise(this, &MicroBitPin::onRise);
LancasterUniversity 49:88f03f3feff1 555 ((TimedInterruptIn *)pin)->fall(this, &MicroBitPin::onFall);
LancasterUniversity 49:88f03f3feff1 556 }
LancasterUniversity 49:88f03f3feff1 557
LancasterUniversity 49:88f03f3feff1 558 status &= ~(IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE);
LancasterUniversity 49:88f03f3feff1 559
LancasterUniversity 49:88f03f3feff1 560 // set our status bits accordingly.
LancasterUniversity 49:88f03f3feff1 561 if(eventType == MICROBIT_PIN_EVENT_ON_EDGE)
LancasterUniversity 49:88f03f3feff1 562 status |= IO_STATUS_EVENT_ON_EDGE;
LancasterUniversity 49:88f03f3feff1 563 else if(eventType == MICROBIT_PIN_EVENT_ON_PULSE)
LancasterUniversity 49:88f03f3feff1 564 status |= IO_STATUS_EVENT_PULSE_ON_EDGE;
LancasterUniversity 49:88f03f3feff1 565
LancasterUniversity 49:88f03f3feff1 566 return MICROBIT_OK;
LancasterUniversity 49:88f03f3feff1 567 }
LancasterUniversity 49:88f03f3feff1 568
LancasterUniversity 49:88f03f3feff1 569 /**
LancasterUniversity 49:88f03f3feff1 570 * If this pin is in a mode where the pin is generating events, it will destruct
LancasterUniversity 49:88f03f3feff1 571 * the current instance attached to this MicroBitPin instance.
LancasterUniversity 49:88f03f3feff1 572 *
LancasterUniversity 49:88f03f3feff1 573 * @return MICROBIT_OK on success.
LancasterUniversity 49:88f03f3feff1 574 */
LancasterUniversity 49:88f03f3feff1 575 int MicroBitPin::disableEvents()
LancasterUniversity 49:88f03f3feff1 576 {
LancasterUniversity 49:88f03f3feff1 577 if (status & (IO_STATUS_EVENT_ON_EDGE | IO_STATUS_EVENT_PULSE_ON_EDGE | IO_STATUS_TOUCH_IN))
LancasterUniversity 49:88f03f3feff1 578 disconnect();
LancasterUniversity 49:88f03f3feff1 579
LancasterUniversity 49:88f03f3feff1 580 return MICROBIT_OK;
LancasterUniversity 49:88f03f3feff1 581 }
LancasterUniversity 49:88f03f3feff1 582
LancasterUniversity 49:88f03f3feff1 583 /**
LancasterUniversity 49:88f03f3feff1 584 * Configures the events generated by this MicroBitPin instance.
LancasterUniversity 49:88f03f3feff1 585 *
LancasterUniversity 49:88f03f3feff1 586 * 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)
LancasterUniversity 49:88f03f3feff1 587 * 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)
LancasterUniversity 49:88f03f3feff1 588 * 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.
LancasterUniversity 49:88f03f3feff1 589 * MICROBIT_PIN_EVENT_NONE - Disables events for this pin.
LancasterUniversity 49:88f03f3feff1 590 *
LancasterUniversity 49:88f03f3feff1 591 * @param eventType One of: MICROBIT_PIN_EVENT_ON_EDGE, MICROBIT_PIN_EVENT_ON_PULSE, MICROBIT_PIN_EVENT_ON_TOUCH, MICROBIT_PIN_EVENT_NONE
LancasterUniversity 49:88f03f3feff1 592 *
LancasterUniversity 49:88f03f3feff1 593 * @code
LancasterUniversity 49:88f03f3feff1 594 * MicroBitMessageBus bus;
LancasterUniversity 49:88f03f3feff1 595 *
LancasterUniversity 49:88f03f3feff1 596 * MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_BOTH);
LancasterUniversity 49:88f03f3feff1 597 * P0.eventOn(MICROBIT_PIN_EVENT_ON_PULSE);
LancasterUniversity 49:88f03f3feff1 598 *
LancasterUniversity 49:88f03f3feff1 599 * void onPulse(MicroBitEvent evt)
LancasterUniversity 49:88f03f3feff1 600 * {
LancasterUniversity 49:88f03f3feff1 601 * int duration = evt.timestamp;
LancasterUniversity 49:88f03f3feff1 602 * }
LancasterUniversity 49:88f03f3feff1 603 *
LancasterUniversity 49:88f03f3feff1 604 * bus.listen(MICROBIT_ID_IO_P0, MICROBIT_PIN_EVT_PULSE_HI, onPulse, MESSAGE_BUS_LISTENER_IMMEDIATE)
LancasterUniversity 49:88f03f3feff1 605 * @endcode
LancasterUniversity 49:88f03f3feff1 606 *
LancasterUniversity 49:88f03f3feff1 607 * @return MICROBIT_OK on success, or MICROBIT_INVALID_PARAMETER if the given eventype does not match
LancasterUniversity 49:88f03f3feff1 608 *
LancasterUniversity 49:88f03f3feff1 609 * @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,
LancasterUniversity 49:88f03f3feff1 610 * please use the InterruptIn class supplied by ARM mbed.
LancasterUniversity 49:88f03f3feff1 611 */
LancasterUniversity 49:88f03f3feff1 612 int MicroBitPin::eventOn(int eventType)
LancasterUniversity 49:88f03f3feff1 613 {
LancasterUniversity 49:88f03f3feff1 614 switch(eventType)
LancasterUniversity 49:88f03f3feff1 615 {
LancasterUniversity 49:88f03f3feff1 616 case MICROBIT_PIN_EVENT_ON_EDGE:
LancasterUniversity 49:88f03f3feff1 617 case MICROBIT_PIN_EVENT_ON_PULSE:
LancasterUniversity 49:88f03f3feff1 618 enableRiseFallEvents(eventType);
LancasterUniversity 49:88f03f3feff1 619 break;
LancasterUniversity 49:88f03f3feff1 620
LancasterUniversity 49:88f03f3feff1 621 case MICROBIT_PIN_EVENT_ON_TOUCH:
LancasterUniversity 49:88f03f3feff1 622 isTouched();
LancasterUniversity 49:88f03f3feff1 623 break;
LancasterUniversity 49:88f03f3feff1 624
LancasterUniversity 49:88f03f3feff1 625 case MICROBIT_PIN_EVENT_NONE:
LancasterUniversity 49:88f03f3feff1 626 disableEvents();
LancasterUniversity 49:88f03f3feff1 627 break;
LancasterUniversity 49:88f03f3feff1 628
LancasterUniversity 49:88f03f3feff1 629 default:
LancasterUniversity 49:88f03f3feff1 630 return MICROBIT_INVALID_PARAMETER;
LancasterUniversity 49:88f03f3feff1 631 }
LancasterUniversity 49:88f03f3feff1 632
LancasterUniversity 49:88f03f3feff1 633 return MICROBIT_OK;
LancasterUniversity 35:8ce23bc1af38 634 }