From 72d5e83e5b639bfd7d69951c5fd5845b38b3bb14 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Mon, 30 Jan 2017 11:19:54 -0800 Subject: [PATCH] Exposing pin eventOn method (#349) --- docs/reference/pins/set-events.md | 30 ++++++++ libs/core/_locales/core-jsdoc-strings.json | 3 + libs/core/_locales/core-strings.json | 5 ++ libs/core/control.cpp | 4 ++ libs/core/enums.d.ts | 16 +++++ libs/core/pins.cpp | 81 ++++++++++++++-------- libs/core/shims.d.ts | 10 +++ sim/state/misc.ts | 3 + 8 files changed, 123 insertions(+), 29 deletions(-) create mode 100644 docs/reference/pins/set-events.md diff --git a/docs/reference/pins/set-events.md b/docs/reference/pins/set-events.md new file mode 100644 index 00000000..105a5cb9 --- /dev/null +++ b/docs/reference/pins/set-events.md @@ -0,0 +1,30 @@ +# Set Events + +Configure the type of events emitted by a given pin. + +```sig +pins.setEvents(DigitalPin.P0, PinEventType.Edge); +``` + +### Parameters + +* ``name``: The @boardname@ hardware pin to configure (``P0`` through ``P20``) +* ``type``: The type of events this pin should emit + +### Example + +The following example configures pin ``P0`` and then +subscribes to the rise and fall events. + +```blocks +control.onEvent(control.eventSourceId(EventBusSource.MICROBIT_ID_IO_P0), control.eventValueId(EventBusValue.MICROBIT_PIN_EVT_RISE), () => { + basic.showString("Rise") +}) +control.onEvent(control.eventSourceId(EventBusSource.MICROBIT_ID_IO_P0), control.eventValueId(EventBusValue.MICROBIT_PIN_EVT_FALL), () => { + basic.showString("Fall") +}) +pins.setEvents(DigitalPin.P0, PinEventType.Edge) +``` + +**This is an advanced API.** For more information, see the +[@boardname@ runtime messageBus documentation](https://lancaster-university.github.io/microbit-docs/ubit/messageBus/) \ No newline at end of file diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index 09936d2f..e56a3a95 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -223,6 +223,9 @@ "pins.servoWritePin": "Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one direction, ``180`` being full speed in the other, and a value near ``90`` being no movement).", "pins.servoWritePin|param|name": "pin to write to, eg: AnalogPin.P0", "pins.servoWritePin|param|value": "angle or rotation speed, eg:180,90,0", + "pins.setEvents": "Configures the events emitted by this pin. Events can be subscribed to\nusing ``control.onEvent()``.", + "pins.setEvents|param|name": "pin to set the event mode on, eg: DigitalPin.P0", + "pins.setEvents|param|type": "the type of events for this pin to emit, eg: PinEventType.Edge", "pins.setPull": "Configures the pull of this pin.", "pins.setPull|param|name": "pin to set the pull mode on, eg: DigitalPin.P0", "pins.setPull|param|pull": "one of the mbed pull configurations, eg: PinPullMode.PullUp", diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index a33b3985..582d3ff0 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -74,6 +74,10 @@ "Note.GSharp4|block": "G#4", "Note.GSharp5|block": "G#5", "Note.GSharp|block": "G#", + "PinEventType.Edge|block": "edge", + "PinEventType.None|block": "none", + "PinEventType.Pulse|block": "pulse", + "PinEventType.Touch|block": "touch", "PinPullMode.PullDown|block": "down", "PinPullMode.PullNone|block": "none", "PinPullMode.PullUp|block": "up", @@ -167,6 +171,7 @@ "pins.pulseIn|block": "pulse in (µs)|pin %name|pulsed %value", "pins.servoSetPulse|block": "servo set pulse|pin %value|to (µs) %micros", "pins.servoWritePin|block": "servo write|pin %name|to %value", + "pins.setEvents|block": "set pin %pin|to emit %type|events", "pins.setPull|block": "set pull|pin %pin|to %pull", "pins.spiWrite|block": "spi write %value", "pins|block": "pins", diff --git a/libs/core/control.cpp b/libs/core/control.cpp index e6df1365..5e64f4ee 100644 --- a/libs/core/control.cpp +++ b/libs/core/control.cpp @@ -56,6 +56,10 @@ enum EventBusValue { MICROBIT_BUTTON_EVT_CLICK_ = MICROBIT_BUTTON_EVT_CLICK, MICROBIT_RADIO_EVT_DATAGRAM_ = MICROBIT_RADIO_EVT_DATAGRAM, MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE_ = MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE, + MICROBIT_PIN_EVT_RISE_ = MICROBIT_PIN_EVT_RISE, + MICROBIT_PIN_EVT_FALL_ = MICROBIT_PIN_EVT_FALL, + MICROBIT_PIN_EVT_PULSE_HI_ = MICROBIT_PIN_EVT_PULSE_HI, + MICROBIT_PIN_EVT_PULSE_LO_ = MICROBIT_PIN_EVT_PULSE_LO, MES_ALERT_EVT_ALARM1_ = MES_ALERT_EVT_ALARM1, MES_ALERT_EVT_ALARM2_ = MES_ALERT_EVT_ALARM2, MES_ALERT_EVT_ALARM3_ = MES_ALERT_EVT_ALARM3, diff --git a/libs/core/enums.d.ts b/libs/core/enums.d.ts index ddd3c4df..3b892107 100644 --- a/libs/core/enums.d.ts +++ b/libs/core/enums.d.ts @@ -179,6 +179,10 @@ declare namespace input { MICROBIT_BUTTON_EVT_CLICK = 3, // MICROBIT_BUTTON_EVT_CLICK MICROBIT_RADIO_EVT_DATAGRAM = 1, // MICROBIT_RADIO_EVT_DATAGRAM MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE = 1, // MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE + MICROBIT_PIN_EVT_RISE = 2, // MICROBIT_PIN_EVT_RISE + MICROBIT_PIN_EVT_FALL = 3, // MICROBIT_PIN_EVT_FALL + MICROBIT_PIN_EVT_PULSE_HI = 4, // MICROBIT_PIN_EVT_PULSE_HI + MICROBIT_PIN_EVT_PULSE_LO = 5, // MICROBIT_PIN_EVT_PULSE_LO MES_ALERT_EVT_ALARM1 = 6, // MES_ALERT_EVT_ALARM1 MES_ALERT_EVT_ALARM2 = 7, // MES_ALERT_EVT_ALARM2 MES_ALERT_EVT_ALARM3 = 8, // MES_ALERT_EVT_ALARM3 @@ -297,6 +301,18 @@ declare namespace led { } + declare enum PinEventType { + //% block="edge" + Edge = 1, // MICROBIT_PIN_EVENT_ON_EDGE + //% block="pulse" + Pulse = 2, // MICROBIT_PIN_EVENT_ON_PULSE + //% block="touch" + Touch = 3, // MICROBIT_PIN_EVENT_ON_TOUCH + //% block="none" + None = 0, // MICROBIT_PIN_EVENT_NONE + } + + declare enum SerialPin { P0 = 7, // MICROBIT_ID_IO_P0 P1 = 8, // MICROBIT_ID_IO_P1 diff --git a/libs/core/pins.cpp b/libs/core/pins.cpp index d7aaa224..b6ea1ed4 100644 --- a/libs/core/pins.cpp +++ b/libs/core/pins.cpp @@ -47,6 +47,17 @@ enum class PinPullMode { PullNone = 2 }; +enum class PinEventType { + //% block="edge" + Edge = MICROBIT_PIN_EVENT_ON_EDGE, + //% block="pulse" + Pulse = MICROBIT_PIN_EVENT_ON_PULSE, + //% block="touch" + Touch = MICROBIT_PIN_EVENT_ON_TOUCH, + //% block="none" + None = MICROBIT_PIN_EVENT_NONE +}; + MicroBitPin *getPin(int id) { switch (id) { case MICROBIT_ID_IO_P0: return &uBit.io.P0; @@ -107,7 +118,7 @@ namespace pins { */ //% help=pins/digital-write-pin weight=29 //% blockId=device_set_digital_pin block="digital write|pin %name|to %value" - void digitalWritePin(DigitalPin name, int value) { + void digitalWritePin(DigitalPin name, int value) { PINOP(setDigitalValue(value)); } @@ -116,7 +127,7 @@ namespace pins { * @param name pin to write to, eg: AnalogPin.P0 */ //% help=pins/analog-read-pin weight=25 - //% blockId=device_get_analog_pin block="analog read|pin %name" blockGap="8" + //% blockId=device_get_analog_pin block="analog read|pin %name" blockGap="8" int analogReadPin(AnalogPin name) { PINREAD(getAnalogValue()); } @@ -128,7 +139,7 @@ namespace pins { */ //% help=pins/analog-write-pin weight=24 //% blockId=device_set_analog_pin block="analog write|pin %name|to %value" blockGap=8 - void analogWritePin(AnalogPin name, int value) { + void analogWritePin(AnalogPin name, int value) { PINOP(setAnalogValue(value)); } @@ -139,11 +150,11 @@ namespace pins { * @param micros period in micro seconds. eg:20000 */ //% help=pins/analog-set-period weight=23 blockGap=8 - //% blockId=device_set_analog_period block="analog set period|pin %pin|to (µs)%micros" - void analogSetPeriod(AnalogPin name, int micros) { + //% blockId=device_set_analog_period block="analog set period|pin %pin|to (µs)%micros" + void analogSetPeriod(AnalogPin name, int micros) { PINOP(setAnalogPeriodUs(micros)); } - + /** * Configures this pin to a digital input, and generates events where the timestamp is the duration that this pin was either ``high`` or ``low``. * @param name digital pin to register to, eg: DigitalPin.P0 @@ -154,11 +165,11 @@ namespace pins { void onPulsed(DigitalPin name, PulseValue pulse, Action body) { MicroBitPin* pin = getPin((int)name); if (!pin) return; - - pin->eventOn(MICROBIT_PIN_EVENT_ON_PULSE); + + pin->eventOn(MICROBIT_PIN_EVENT_ON_PULSE); registerWithDal((int)name, (int)pulse, body); } - + /** * Gets the duration of the last pulse in micro-seconds. This function should be called from a ``onPulsed`` handler. */ @@ -174,7 +185,7 @@ namespace pins { * @param name the pin which measures the pulse, eg: DigitalPin.P0 * @param value the value of the pulse, eg: PulseValue.High * @param maximum duration in micro-seconds - */ + */ //% blockId="pins_pulse_in" block="pulse in (µs)|pin %name|pulsed %value" //% weight=20 advanced=true int pulseIn(DigitalPin name, PulseValue value, int maxDuration = 2000000) { @@ -182,20 +193,20 @@ namespace pins { if (!pin) return 0; int pulse = value == PulseValue::High ? 1 : 0; - uint64_t tick = system_timer_current_time_us(); - uint64_t maxd = (uint64_t)maxDuration; + uint64_t tick = system_timer_current_time_us(); + uint64_t maxd = (uint64_t)maxDuration; while(pin->getDigitalValue() != pulse) { if(system_timer_current_time_us() - tick > maxd) - return 0; + return 0; } - uint64_t start = system_timer_current_time_us(); + uint64_t start = system_timer_current_time_us(); while(pin->getDigitalValue() == pulse) { if(system_timer_current_time_us() - tick > maxd) - return 0; - } - uint64_t end = system_timer_current_time_us(); - return end - start; + return 0; + } + uint64_t end = system_timer_current_time_us(); + return end - start; } /** @@ -206,7 +217,7 @@ namespace pins { //% help=pins/servo-write-pin weight=20 //% blockId=device_set_servo_pin block="servo write|pin %name|to %value" blockGap=8 //% parts=microservo trackArgs=0 - void servoWritePin(AnalogPin name, int value) { + void servoWritePin(AnalogPin name, int value) { PINOP(setServoValue(value)); } @@ -217,7 +228,7 @@ namespace pins { */ //% help=pins/servo-set-pulse weight=19 //% blockId=device_set_servo_pulse block="servo set pulse|pin %value|to (µs) %micros" - void servoSetPulse(AnalogPin name, int micros) { + void servoSetPulse(AnalogPin name, int micros) { PINOP(setServoPulseUs(micros)); } @@ -230,7 +241,7 @@ namespace pins { */ //% blockId=device_analog_set_pitch_pin block="analog set pitch pin %name" //% help=pins/analog-set-pitch weight=3 advanced=true - void analogSetPitchPin(AnalogPin name) { + void analogSetPitchPin(AnalogPin name) { pitchPin = getPin((int)name); } @@ -241,8 +252,8 @@ namespace pins { */ //% blockId=device_analog_pitch block="analog pitch %frequency|for (ms) %ms" //% help=pins/analog-pitch weight=4 async advanced=true blockGap=8 - void analogPitch(int frequency, int ms) { - if (pitchPin == NULL) + void analogPitch(int frequency, int ms) { + if (pitchPin == NULL) analogSetPitchPin(AnalogPin::P0); if (frequency <= 0) { pitchPin->setAnalogValue(0); @@ -250,7 +261,7 @@ namespace pins { pitchPin->setAnalogValue(512); pitchPin->setAnalogPeriodUs(1000000/frequency); } - + if (ms > 0) { fiber_sleep(ms); pitchPin->setAnalogValue(0); @@ -259,7 +270,7 @@ namespace pins { } } - + /** * Configures the pull of this pin. * @param name pin to set the pull mode on, eg: DigitalPin.P0 @@ -268,13 +279,25 @@ namespace pins { //% help=pins/set-pull weight=3 advanced=true //% blockId=device_set_pull block="set pull|pin %pin|to %pull" void setPull(DigitalPin name, PinPullMode pull) { - PinMode m = pull == PinPullMode::PullDown + PinMode m = pull == PinPullMode::PullDown ? PinMode::PullDown - : pull == PinPullMode::PullUp ? PinMode::PullUp + : pull == PinPullMode::PullUp ? PinMode::PullUp : PinMode::PullNone; PINOP(setPull(m)); } + /** + * Configures the events emitted by this pin. Events can be subscribed to + * using ``control.onEvent()``. + * @param name pin to set the event mode on, eg: DigitalPin.P0 + * @param type the type of events for this pin to emit, eg: PinEventType.Edge + */ + //% help=pins/set-events weight=4 advanced=true + //% blockId=device_set_pin_events block="set pin %pin|to emit %type|events" + void setEvents(DigitalPin name, PinEventType type) { + getPin((int)name)->eventOn((int)type); + } + /** * Create a new zero-initialized buffer. * @param size number of bytes in the buffer @@ -295,7 +318,7 @@ namespace pins { uBit.i2c.read(address << 1, (char*)buf->payload, size, repeat); return buf; } - + /** * Write bytes to a 7-bit I2C `address`. */ @@ -322,5 +345,5 @@ namespace pins { auto p = allocSPI(); return p->write(value); } - + } diff --git a/libs/core/shims.d.ts b/libs/core/shims.d.ts index 84e9faf5..2cdcc5c6 100644 --- a/libs/core/shims.d.ts +++ b/libs/core/shims.d.ts @@ -628,6 +628,16 @@ declare namespace pins { //% blockId=device_set_pull block="set pull|pin %pin|to %pull" shim=pins::setPull function setPull(name: DigitalPin, pull: PinPullMode): void; + /** + * Configures the events emitted by this pin. Events can be subscribed to + * using ``control.onEvent()``. + * @param name pin to set the event mode on, eg: DigitalPin.P0 + * @param type the type of events for this pin to emit, eg: PinEventType.Edge + */ + //% help=pins/set-events weight=4 advanced=true + //% blockId=device_set_pin_events block="set pin %pin|to emit %type|events" shim=pins::setEvents + function setEvents(name: DigitalPin, type: PinEventType): void; + /** * Create a new zero-initialized buffer. * @param size number of bytes in the buffer diff --git a/sim/state/misc.ts b/sim/state/misc.ts index 6f5a2237..ca6d549b 100644 --- a/sim/state/misc.ts +++ b/sim/state/misc.ts @@ -119,6 +119,9 @@ namespace pxsim.pins { export function getPinAddress(name: number) { return getPin(name) } + + export function setEvents(name: number, event: number) { + } } namespace pxsim.devices {