• You're almost certainly hitting timing issues because Espruino doesn't execute JS code in an interrupt.

    However there's a solution to this. Espruino's setWatch provides a data pin argument, which samples the data pin in the interrupt and writes the result into the queue along with the event:


    setWatch(function(e) {
    },CLK_PIN,{edge:"rising", data:MOSI_PIN, repeat: true});

    And in this particular case I wouldn't do a setWatch in a setWatch either - just leave them both running:

    var isActive = false;
    setWatch(function(e) {
      isActive = !e.state;
    },CS_PIN,{edge:"both", repeat: true});
    setWatch(function(e) {
      if (isActive) print(e.data);
    },CLK_PIN,{edge:"rising", data:MOSI_PIN, repeat: true});

    Because they're both running, events will be put in the queue in the correct order. Even though they are not processed immediately everything will still work great.

    HOWEVER this will only work for small packets of SPI data. Anything with >100 clock cycles will fill up the input FIFO before Espruino is able to process it.

  • Sun 2019.08.04

    'HOWEVER this will only work for small packets of SPI data'

    Only have a need for four bytes, around 32 edges, so shouldn't be an issue.

    @Gordon, would it be possible to provide the option to allow slower than the SPI 100Kbit default rate? How difficult/time frame would that be to implement with your already over limit demands? fingers crossed

    The snippet in #8 works as outlined, but, and a big butt at that, ;-) not at the default SPI speeds. setWatch() not responsive enough.


    "Pretty much all SPI devices are guaranteed to support 100kBits/sec transfer speed, so that is the default in Espruino. However you can specify higher speeds with bitrate in SPI.setup if your device supports it, eg:"


    "Note: baud rate is ignored for software SPI - it will always send as fast as possible."

    Made several attempts to slow SPI by dividing 100000 by 10's down as far as 5000, but the result is the same. The slowest clock pulse is around 3usec 333KHz or the same as the default for both hardware and software SPI.

    I ended up writing a Javascript pin toggler a slow SPI emulator that clocks out 1000 times slower, so that I could verify added code to the snippet you provided. Data is solid and the slave is able to absorb at that slow speed. The fastest that Javascript would eventually run is limited by how fast setInterval can be called, and that appears to be around 1.8msec so two pulses at 2msec 0.004 is 250Hz. So using Javascript, that is limited to around 1000 times not fast enough to approach the current SPI default setting implementation.

    The source I have cobbled together runs at 2 pulses 0.01 10msec or 100Hz

    When clocked out of the MDBT42Q using the only available software SPI at the default, which is the slowest SPI will clock data, pulses are counted but the bits are not as they should be. I'm going to play with the clock mode setting tomorrow, but even inverting the bits doesn't come close the the data sent.

    60usec for two bytes   15KHz
    SCK   3usec    333KHz

    Pin wiring

          MDBT         Pulse View          WiFi
     Pin Label  Name   Color  PV     Name     Label   Pin
      1   D25   SCK     Blu   D6   SPI3.SCK    B3     15
      2   D26   MISO    Yel   D4   SPI3.MISO   B4     16
      3   D27   MOSI    Grn   D5   SPI3.MOSI   B5     17
      4   D28   CS      Brn   D1   SS          B1      7

    Found the send cmd bool jsspiSend() but don't know where to find object spi_sender


    This proof of concept does indeed show the WiFi running as a slave, at 1000 times slower but only as true SPI appears to be too fast for setWatch() to monitor.

    Will mess with clock mode and attempting to speed up the Javascript.

    Cleaning up both code modules to upload shortly (late Monday). . . .


Avatar for Gordon @Gordon started