Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32: setWatch and digitalWrite Assert failure - DHT11 module #1346

Closed
wilberforce opened this issue Feb 19, 2018 · 10 comments
Closed

ESP32: setWatch and digitalWrite Assert failure - DHT11 module #1346

wilberforce opened this issue Feb 19, 2018 · 10 comments
Labels
ESP32 This is only a problem on ESP32-based devices

Comments

@wilberforce
Copy link
Member

wilberforce commented Feb 19, 2018

Reported as issues with the ESP32 and the DHT11 module:

http://forum.espruino.com/conversations/316936
http://forum.espruino.com/conversations/316733

To reproduce:

>setWatch(function(e) {console.log("Button pressed",e);}, D16, { repeat: true, edge: 'rising' });
=1
>digitalWrite(D16,0);
ASSERT(channel >= EV_EXTI0 && channel <= EV_EXTI_MAX) FAILED AT src/jsdevices.c:413
  #1[r2,l2] Object {
    #2[r1,l2] Name String [1 blocks] "\xFF"      #3[r1,l2] Object {
        #6[r1,l2] Name String [2 blocks] "timers"          #8[r2,l1] Array(0) [ ]
        #9[r1,l2] Name String [2 blocks] "watches"          #11[r2,l1] Array(2) [
            #72[r1,l2] Name Integer 1              #63[r1,l1] Object {
                #65[r1,l2] Name String [1 blocks] "pin"                  #64[r1,l1] Pin 16
                #67[r1,l2] Name String [2 blocks] "recur"                  #66[r1,l1] Bool true
                #70[r1,l2] Name String [1 blocks] "edge"= int 1
                #69[r1,l2] Name String [2 blocks] "callback"                  #46[r1,l1] Function {
                    #45[r1,l2] Name Param "\xFFe"                       undefined
                    #44[r1,l2] Name String [1 blocks] "\xFFcod"                      #57[r1,l1] FlatString [3 blocks] "console.log(\"Button pressed\",e);"
                  }
              }
          ]
        #13[r1,l2] Name String [1 blocks] "net"          #14[r1,l2] String [1 blocks] "\x05\x00\x00\x00\x00\xFF\xFF\xFF"
        #25[r1,l2] Name String [2 blocks] "modules"          #27[r1,l1] Object {
            #29[r1,l2] Name String [1 blocks] "Wifi"              #28[r1,l1] NativeFunction 0x400ea898 (0) { }
          }
        #47[r1,l2] Name String [2 blocks] "history"          #42[r1,l1] Array(1) [
            #61[r1,l2] Name Integer 0              #48[r1,l1] String [9 blocks] "setWatch(function(e) {console.log(\"Button pressed\",e);}, D16, { repeat: true, edge: 'rising' });"
          ]
      }
  }
HALTING.

digitalWrite(D16,0) on it own works ok.

To get the assert (rather than a core dump) - compile:
make clean && BOARD=ESP32 DEBUG=1 make

https://github.com/espruino/Espruino/blob/master/src/jsdevices.c#L413

/**
 * Signal an IO watch event as having happened.
 */
// on the esp8266 we need this to be loaded into static RAM because it can run at interrupt time
void CALLED_FROM_INTERRUPT jshPushIOWatchEvent(
    IOEventFlags channel //!< The channel on which the IO watch event has happened.
  ) {
  assert(channel >= EV_EXTI0 && channel <= EV_EXTI_MAX);

  bool state = jshGetWatchedPinState(channel);

  // If there is a callback associated with this GPIO event then invoke
  // it and we are done.
  if (jshEventCallbacks[channel-EV_EXTI0]) {
    jshEventCallbacks[channel-EV_EXTI0](state, channel);
    return;
  }

EV_EXTI_MAX is defined as: https://github.com/espruino/Espruino/blo­b/e609b94f83f665c26cf4f86acac068c396427e­99/src/jsdevices.h#L54

EV_EXTI15, // External Interrupt 15
  EV_EXTI_MAX = EV_EXTI15,

@jumjum123 did the setwatch code for ESP32 - so I'm unsure how pin numbers (D22 in this case) is mapping to a channel?

@gfwilliams

It seems the code is built for board with pins 0-15? We are getting a failure when a pin > 16 is used.

Sorry - without having an understanding of the code I'm note sure how to fix or the relationship between setWatch() and digitalWrite() and channels and pins?

@wilberforce wilberforce added the ESP32 This is only a problem on ESP32-based devices label Feb 19, 2018
@wilberforce
Copy link
Member Author

wilberforce commented Feb 19, 2018

Looks like in jsdevices.h we need to define:

EV_EXTI16,
EV_EXTI17
....
EV_EXTI38
EV_EXTI39

However that will possibly blow out the EV_DEVICE_MAX which can't be bigger that 64:

Espruino/src/jsdevices.h

Lines 95 to 96 in e609b94

EV_DEVICE_MAX = EV_SERIAL_STATUS_MAX,
// EV_DEVICE_MAX should not be >64 - see DEVICE_INITIALISED_FLAGS

@gfwilliams
Copy link
Member

On all the other platforms there is only a relatively small amount of hardware that can do watches, so EV_EXTIx corresponds to that and there's a mapping, eg: https://github.com/espruino/Espruino/blob/master/targets/nrf5x/jshardware.c#L867

I'm not sure what the case is with ESP32 but if it is then it's hidden behind their API.

Given the competition for space in that enum (otherwise we'd have to double the size of it, which wastes ~128 bytes of input buffer on most platforms), I'd rather not increase that size across the board. We could perhaps define EV_EXTI_COUNT in platform_config.h though and use that?

@jumjum123
Copy link
Contributor

jumjum123 commented Feb 19, 2018 via email

@wilberforce
Copy link
Member Author

Thanks @gfwilliams and @jumjum123
Even thought there are gpio0-gpio39' some are reserved and can't be watched, like 6-11 are reserved for the flash chip. So I guess a mapping table of useable pins that can be watched, mapping to a channel would be the real solution.

I'm not sure how to cleanly do the changes to jsdevice.h without a conditional #ifdef ESP32.

Currently there is no tie up with the generated platform.h, so within the enum defines are made for non-existent serial ports for example, that would free up some of the numbers, (or would that be used for software serial?)

@gfwilliams
Copy link
Member

Yes, I was wondering about the unused Serial/I2C/etc too. The tie-up could have to be done with build_platform_config based on chip family, but it would be nice improvement I think.

Having said that, how many ESP32 pins can't be used? If there are only 16 usable then it totally makes sense to use the 16 EXTI that we have.

Just a note, but if jshPinWatch returns EV_NONE, I believe you get a nice can't watch this pin error message, so it'd be good to add for 6-11 in any case.

@wilberforce
Copy link
Member Author

Thanks. I'm trying to look at the ESP-idf docs to see if there is a function to check watchability of pins like in the nfc sample you pointed me too. I see that checks in a loop - wondering if the speed of that has any bearing?

And do you know a cunning way of checking that enum does not exceed 64 at compile time?

@wilberforce
Copy link
Member Author

According this there appears to be at least 19-20 pins:

void jshPinDefaultPullup() {
// 6-11 are used by Flash chip
// 32-33 are routed to rtc for xtal
jshPinSetStateRange(0,0,JSHPINSTATE_GPIO_IN_PULLUP);
jshPinSetStateRange(12,19,JSHPINSTATE_GPIO_IN_PULLUP);
jshPinSetStateRange(21,22,JSHPINSTATE_GPIO_IN_PULLUP);
jshPinSetStateRange(25,27,JSHPINSTATE_GPIO_IN_PULLUP);
jshPinSetStateRange(34,39,JSHPINSTATE_GPIO_IN_PULLUP);

@gfwilliams
Copy link
Member

Ok, one sec and I'll update devices.h - while adding 4 isn't a big deal it'd be good to have flexible numbers as on some other platforms I'm throwing some RAM away for them

@gfwilliams
Copy link
Member

And do you know a cunning way of checking that enum does not exceed 64 at compile time?

Turns out we already do this with DEVICE_SANITY_CHECK (although it's not compile-time)

I just committed a patch that might fix this. Honestly, not the tidiest stuff I've ever done, but should save some code space on a bunch of platforms

@wilberforce
Copy link
Member Author

Thanks @gfwilliams

This is now working on the ESP32:

setWatch(function(e) {console.log("Button pressed",e);}, D22, { repeat: true, edge: 'rising' });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ESP32 This is only a problem on ESP32-based devices
Projects
None yet
Development

No branches or pull requests

3 participants