Skip to content

Commit

Permalink
Merge pull request #158 from rwaldron/152
Browse files Browse the repository at this point in the history
Interrupts: deliver the state of the pin for change events. Closes gh-152
  • Loading branch information
johnnyman727 committed Apr 2, 2016
2 parents 1c7c86e + fe05842 commit c04a41c
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 5 deletions.
11 changes: 10 additions & 1 deletion firmware/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,16 @@ void port_handle_extint(PortData *p, u32 flags) {
if (port_pin_supports_interrupt(p, pin)) {
Pin sys_pin = p->port->gpio[pin];
if (flags & (1 << pin_extint(sys_pin))) {
port_send_status(p, REPLY_ASYNC_PIN_CHANGE_N + pin);
u8 response = REPLY_ASYNC_PIN_CHANGE_N + pin;

// If the pin's state is high, set bit 3
// of the response byte. This will be used to
// inform "change" listeners of the present state
// at the moment of the interrupt.
if (pin_read(port_selected_pin(p))) {
response |= 1 << 3;
}
port_send_status(p, response);
if (eic_read_config(sys_pin) & EIC_CONFIG_SENSE_LEVEL) {
// Async level interrupts only trigger once
eic_config(sys_pin, EIC_CONFIG_SENSE_NONE);
Expand Down
14 changes: 10 additions & 4 deletions node/tessel-export.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,9 @@ Tessel.Port = function(name, socketPath, board) {
// This is some other async transaction
} else if (byte >= REPLY.MIN_ASYNC) {
// If this is a pin change
if (byte >= REPLY.ASYNC_PIN_CHANGE_N && byte < REPLY.ASYNC_PIN_CHANGE_N + 8) {
// Pull out which pin it is
var pin = this.pin[byte - REPLY.ASYNC_PIN_CHANGE_N];
if (byte >= REPLY.ASYNC_PIN_CHANGE_N && byte < REPLY.ASYNC_PIN_CHANGE_N + 16) {
// Pull out the pin number (requires clearing the value bit)
var pin = this.pin[(byte - REPLY.ASYNC_PIN_CHANGE_N) & ~(1 << 3)];
// Get the mode change
var mode = pin.interruptMode;

Expand All @@ -250,7 +250,13 @@ Tessel.Port = function(name, socketPath, board) {
}

// Emit the change
pin.emit(mode);
if (mode === 'change') {
// "change" is otherwise ambiguous.
pin.emit('change', (byte >> 3) & 1);
} else {
// high, low, rise & fall are _not_ ambiguous
pin.emit(mode);
}
} else {
// Some other async event
this.emit('async-event', byte);
Expand Down
58 changes: 58 additions & 0 deletions node/test/unit/tessel.js
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,64 @@ exports['Tessel.Pin'] = {
test.done();
},

interruptChangeStateLow: function(test) {
test.expect(17);

var spy = sandbox.spy();

[2, 5, 6, 7].forEach(function(pinIndex) {
this.a.pin[pinIndex].on('change', spy);
this.b.pin[pinIndex].on('change', spy);

test.equal(this.a.pin[pinIndex].interruptMode, 'change');
test.equal(this.b.pin[pinIndex].interruptMode, 'change');

// Simulate receipt of pin state changes
this.a.sock.read.returns(new Buffer([REPLY.ASYNC_PIN_CHANGE_N + pinIndex]));
this.a.sock.emit('readable');

this.b.sock.read.returns(new Buffer([REPLY.ASYNC_PIN_CHANGE_N + pinIndex]));
this.b.sock.emit('readable');
}, this);

test.equal(spy.callCount, 8);

for (var i = 0; i < 8; i++) {
test.equal(spy.getCall(i).args[0], 0);
}

test.done();
},

interruptChangeStateHigh: function(test) {
test.expect(17);

var spy = sandbox.spy();

[2, 5, 6, 7].forEach(function(pinIndex) {
this.a.pin[pinIndex].on('change', spy);
this.b.pin[pinIndex].on('change', spy);

test.equal(this.a.pin[pinIndex].interruptMode, 'change');
test.equal(this.b.pin[pinIndex].interruptMode, 'change');

// Simulate receipt of pin state changes
this.a.sock.read.returns(new Buffer([(REPLY.ASYNC_PIN_CHANGE_N + pinIndex) | (1 << 3)]));
this.a.sock.emit('readable');

this.b.sock.read.returns(new Buffer([(REPLY.ASYNC_PIN_CHANGE_N + pinIndex) | (1 << 3)]));
this.b.sock.emit('readable');
}, this);

test.equal(spy.callCount, 8);

for (var i = 0; i < 8; i++) {
test.equal(spy.getCall(i).args[0], 1);
}

test.done();
},

removeListener: function(test) {
test.expect(14);

Expand Down

0 comments on commit c04a41c

Please sign in to comment.