• I got a chance to look into this again and found, not surprisingly, that the OW search failures occurred when the read bit function was apparently interrupted. The image below is a screen cap of the logic analyzer showing the last operation of a failed search. In the photo you can see the read bit sequence took almost 101uS instead of the usual 68uS. While the time is within spec for a OW Time Slot, it indicates there was some interruption during the operation. My guess is that the processor didn't get to read the '0' bit in time and read a '1' bit instead. This would cause the search algorithm to fail since two '1' bits were read in a row (meaning no probes were responding).
    So, with this theory, I modified the jshardware.c file in the targets/nrf5x/ folder to:

    static uint32_t prevPriMask=0;
    
    void jshInterruptOff() {
    [#if](https://forum.espruino.com/search/?q=%23if) defined(BLUETOOTH) && defined(NRF52)
      // TWS: replaced: disable non-softdevice IRQs. This only seems available on Cortex M3 (not the nRF51's M0)
      // TWS: With: turn off all IRQs after saving current priority mask
      prevPriMask = __get_PRIMASK();
      __disable_irq();
      //__set_BASEPRI(4<<5); // Disabling interrupts completely is not reasonable when using one of the SoftDevices.
    [#else](https://forum.espruino.com/search/?q=%23else)
      __disable_irq();
    [#endif](https://forum.espruino.com/search/?q=%23endif)
    }
    
    void jshInterruptOn() {
    [#if](https://forum.espruino.com/search/?q=%23if) defined(BLUETOOTH) && defined(NRF52)
      //__set_BASEPRI(0);
      // TWS: Restore previous piority mask (probably 0)
      __set_PRIMASK(prevPriMask); 
    [#else](https://forum.espruino.com/search/?q=%23else)
      __enable_irq();
    [#endif](https://forum.espruino.com/search/?q=%23endif)
    }
    
    

    Making this change the one wire search routine ALWAYS finds the two probes I have attached to the MDBT42Q. This seems safe for the one wire case since the interrupts are disabled for a short time in the read and write 1 cases (<= 13uS). The write 0 case, however, is longer (65uS), but a change to the OW code would improve this to 15uS if

        } else {  // long pulse
          jshInterruptOff();
          jshPinSetValue(pin, 0);
          jshDelayMicroseconds(65);
          jshPinSetValue(pin, 1);
          jshInterruptOn();
          jshDelayMicroseconds(5);
        }
    

    Was changed to this:

        } else {  // long pulse
          jshInterruptOff();
          jshPinSetValue(pin, 0);
          jshDelayMicroseconds(15);
          jshInterruptOn();
          jshDelayMicroseconds(50);
          jshPinSetValue(pin, 1);
          jshDelayMicroseconds(5);
        }
    
    

    This splits the 65uS delay into a critical 15uS delay and a not so critical 50uS adder.

    I'm not going to generate a pull request for this until I play with it a while, although I'm not sure that jshInterruptOff() is used in that many places (Soft SPI, UART, Neopixel), it would still be worthwhile making sure there aren't any SoftDevice failures because of this...
    Tom


    1 Attachment

    • FailedOW_SearchTiming.JPG
About

Avatar for TomWS @TomWS started