• There seems to be some questions around this topic... therefore, I though I write this up. Feedback on as PERSONAL forum message is welcome. Personal message I prefer for keeping this post as concise as possible. I prefer to update it with crediting to your contribution rather then make it a pain for the future readers...

    There are Espruino built-in SPIs that use the mc chip's SPI appliance. Hardware SPI can not only be faster but also offloads the mc processor from figuring out the bits and pieces of a single nibble or byte or word or array of... The offloading is significant. Unfortunately, some of the processors on which Espruino can run don't have hardware SPI - and also don't have hardware I2C, USART, or not enough of them for your application. But thanks to @Gordon and even to his personal gain-disadvantage - but in favor of Espruino as a firmware / middleware / software solution and *YOUR convenience and fun, he has implemented it in Espruino for everyone and got also help from the community to make both hardware SPI work reliably and practically completely interchangeable - as I can tell from my most recent tinkering around with my 'old' ESP8266 ESP-07 in the conversation about ESP8266 ESP-09 - 1 powerful cm2 and WebServer and Chirp Sensor (moisture, temperature, light) on ESP-09 - latter then using SPI.

    Now there are some nuances how to use SPI (and I2C) of both hardware and software variants, from now on called SPI/IC2. USART (Serial) I leave out, but same principles apply to that as well.

    In both cases you have or can do some setup.

    For the hardware SPI/I2C you are limited to the *ALL UPPERSCASE* SPI1, SPI2, SPI3,... as available for the particular board the pins that are labeled accordingly to the boards reference page(s). Luckily, there is more than one set of pins that can be used for the hardware SPI/I2C, and that's why you still have to mention the pins in the setup. Important though is that you use. To make your software and application life easy, you still can give it the name for you nees, such as, for example when using SPI1 for yourmyWhatEverSensor(tempSensorortempSensorSPI).

    You assign the SPI1 to the a variable with your desired name as the first item in your code, where you also define the pins. So later on in the code you can use your names and the code becomes much more readable... and transferable to any Espruino type of board, for which you want to use or have to use a different built-in SPI/I2C or even software SPI/I2C. You can even make the code the way that on initialization it knows whether it is a hardware or software SPI/I2C and you can conditionally create the software SPI/I2C as needed and enable it to cater for both hardware and software SPI/I2C.

    At the very beginning of you code you put (for example - *holding your horses

    • about the naming):

      var myTempSensorSPI = SPI1; // HARDWARE SPI
      var myTempSensor_SCK = A5,  myTempSensor_MISO = A6,  myTempSensor_MOSI = A7;
      

    An later in your code - either in the onInit() itself or a function/method called/invoked by onInit(), you put:

      ...
      ...
      myTempSensorSPI.setp(
        { sck:  myTempSensor_SCK
        , miso: myTempSensor_MISO
        , mosi: myTempSensor_MOSI
        , baud: 100000
        } );
      ...
      ...
    

    As you know, SPI is a software addressable bus or multi-drop line... in other words: multiple peripherals - sensors / input/output device - can hang off the same SCK/MISO/MOSI wires and the selection happens by the required sending of an address as prefix to every communication to connected peripheral. Therefore, the suggested naming is a bit misleading and worse -badly - mis-teaching and blurring the concept of a bus. You do not need to give an application or purpose oriented special name if you need only one SPI going for you. If you need only one: just call it a day with calling it plainly var spi = SPI1;, for example... and so also for the pins, where you can call them just var sck = B7, miso = B8, mosi = B9;

    Similar - to some extend - is it with I2C... at leas for the data line SDA. The chip select though - called CS, or negativeCS, or ns (for negative select, because the signal has to be 'negative' which is LOW/0/0V versus HIGH/1/VDD/3V/3.3V/5.5V) - IS application specific and as such deserves . - or requires in by good coding standards / best practices - an application specific name, cush as var tempSensorNS = B0;.

    Back to SPI/I2C howto topic:

    Now you already guess what it has to be for the software SPI/I2C:

    At the very beginning of you code you put (for example):

    var myTempSensorSPI; // will use SOFTWARE SPI
    var myTempSensor_SCK = B7,  myTempSensor_MISO = B8,  myTempSensor_MOSI = B9;
    

    And for the setup you put:

      ...
      ...
      myTempSensorSPI = new SPI(); // SOFTWARE SPI
      myTempSensorSPI.setp(
        { sck:  myTempSensor_SCK
        , miso: myTempSensor_MISO
        , mosi: myTempSensor_MOSI
        } );
      ...
      ...
    

    And if you want to use it for both, HARDWARE and SOFTWARE SPI/I2C, you make the choices in definition part of your code ONLY and make your setup smart:

      ...
      ...
      if (! myTempSensorSPI) { myTempSensorSPI = new SPI(); } // SOFTWARE SPI
      myTempSensorSPI.setp(
        { sck:  myTempSensor_SCK
        , miso: myTempSensor_MISO
        , mosi: myTempSensor_MOSI
        , baud: 100000 // ignored on software SPI
        } );
      ...
      ...
    

    Happy hardware and software SPI/I2C/USART-ing...

    PS: should you run short on a few bytes, you can omit the curly braces ({}) in line 3 of the last code block.

    NB: Setups have more than just pin and speed... and they may also vary based on use of either the hardware of the software implementation for the SPI/I2C.

About

Avatar for allObjects @allObjects started