/*JSON{ "type":"method", "class": "Serial", "name" : "setup",
         "description" : "Setup this Serial port with the given baud rate and options",
         "generate" : "jswrap_serial_setup",
         "params" : [ [ "baudrate", "int", "The baud rate - the default is 9600"],
                      [ "options", "JsVar", ["An optional structure containing extra information on initialising the serial port.",
                                             "```{rx:pin,tx:pin}```",
                                             "Note that even after changing the RX and TX pins, if you have called setup before then the previous RX and TX pins will still be connected to the Serial port as well - until you set them to something else using digitalWrite" ] ] ]
}*/
void jswrap_serial_setup(JsVar *parent, JsVarInt baud, JsVar *options) {
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  JshUSARTInfo inf;
  jshUSARTInitInfo(&inf);

  if (baud>0) inf.baudRate = (int)baud;

  if (jsvIsObject(options)) {

    inf.pinRX = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "rx", 0));
    inf.pinTX = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "tx", 0));
    inf.bytesize = (unsigned char)jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "bytesize", 0));

    JsVar *v;
    v = jsvObjectGetChild(options, "parity", 0);
    
    if(jsvIsNull(v)) {
      inf.parity = 0;
    }
    else if(jsvIsString(v)) {
      inf.parity = 0xFF;
      char s[8] = "";

      jsvGetString(v, s, sizeof(s) - 1);

      if(!strcmp(s, "o") || !strcmp(s, "odd")) {
        inf.parity = 1;
      }
      else if(!strcmp(s, "e") || !strcmp(s, "even")) {
        inf.parity = 2;
      }
    }
    else if(jsvIsInt(v)) {
      inf.parity = (unsigned char)jsvGetInteger(v);
    }

    jsvUnLock(v);

    v = jsvObjectGetChild(options, "stopbits", 0);
    inf.stopbits = (unsigned char)jsvGetInteger(v);
    jsvUnLock(v);
  }

  jshUSARTSetup(device, &inf);
  // Set baud rate in object, so we can initialise it on startup
  if (baud != DEFAULT_BAUD_RATE) {
    JsVar *baudVar = jsvNewFromInteger(baud);
    jsvUnLock(jsvSetNamedChild(parent, baudVar, USART_BAUDRATE_NAME));
    jsvUnLock(baudVar);
  } else
    jsvRemoveNamedChild(parent, USART_BAUDRATE_NAME);
  // Do the same for options
  if (options)
    jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME));
  else
    jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
}
Exemple #2
0
/*JSON{ "type":"method", "class": "Serial", "name" : "setup",
         "description" : ["Setup this Serial port with the given baud rate and options.",
                          "If not specified in options, the default pins are used (usually the lowest numbered pins on the lowest port that supports this peripheral)"],
         "generate" : "jswrap_serial_setup",
         "params" : [ [ "baudrate", "JsVar", "The baud rate - the default is 9600"],
                      [ "options", "JsVar", ["An optional structure containing extra information on initialising the serial port.",
                                             "```{rx:pin,tx:pin,bytesize:8,parity:null/'none'/'o'/'odd'/'e'/'even',stopbits:1}```",
                                             "You can find out which pins to use by looking at [your board's reference page](#boards) and searching for pins with the `UART`/`USART` markers.",
                                             "Note that even after changing the RX and TX pins, if you have called setup before then the previous RX and TX pins will still be connected to the Serial port as well - until you set them to something else using digitalWrite" ] ] ]
}*/
void jswrap_serial_setup(JsVar *parent, JsVar *baud, JsVar *options) {
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  if (!DEVICE_IS_USART(device)) return;

  JshUSARTInfo inf;
  jshUSARTInitInfo(&inf);

  if (!jsvIsUndefined(baud)) {
    int b = (int)jsvGetInteger(baud);
    if (b<=100 || b > 10000000)
      jsExceptionHere(JSET_ERROR, "Invalid baud rate specified");
    else
      inf.baudRate = b;
  }


  if (jsvIsObject(options)) {
    inf.pinRX = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "rx", 0));
    inf.pinTX = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "tx", 0));    

    JsVar *v;
    v = jsvObjectGetChild(options, "bytesize", 0);
    if (jsvIsInt(v)) 
      inf.bytesize = (unsigned char)jsvGetInteger(v);
    jsvUnLock(v);
    
    inf.parity = 0;
    v = jsvObjectGetChild(options, "parity", 0);
    if(jsvIsString(v)) {
      if(jsvIsStringEqual(v, "o") || jsvIsStringEqual(v, "odd"))
        inf.parity = 1;
      else if(jsvIsStringEqual(v, "e") || jsvIsStringEqual(v, "even"))
        inf.parity = 2;
    } else if(jsvIsInt(v)) {
      inf.parity = (unsigned char)jsvGetInteger(v);
    }
    jsvUnLock(v);
    if (inf.parity>2) {
      jsExceptionHere(JSET_ERROR, "Invalid parity %d", inf.parity);
      return;
    }

    v = jsvObjectGetChild(options, "stopbits", 0);
    if (jsvIsInt(v)) 
      inf.stopbits = (unsigned char)jsvGetInteger(v);
    jsvUnLock(v);
  }

  jshUSARTSetup(device, &inf);
  // Set baud rate in object, so we can initialise it on startup
  if (inf.baudRate != DEFAULT_BAUD_RATE) {
    jsvUnLock(jsvObjectSetChild(parent, USART_BAUDRATE_NAME, jsvNewFromInteger(inf.baudRate)));
  } else
    jsvRemoveNamedChild(parent, USART_BAUDRATE_NAME);
  // Do the same for options
  if (options)
    jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME));
  else
    jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
}
Exemple #3
0
/*JSON{
  "type" : "method",
  "class" : "SPI",
  "name" : "setup",
  "generate" : "jswrap_spi_setup",
  "params" : [
    ["options","JsVar",["An optional structure containing extra information on initialising the SPI port","Please note that baud rate is set to the nearest that can be managed - which may be -+ 50%","```{sck:pin, miso:pin, mosi:pin, baud:integer=100000, mode:integer=0, order:'msb'/'lsb'='msb' }```","If sck,miso and mosi are left out, they will automatically be chosen. However if one or more is specified then the unspecified pins will not be set up.","You can find out which pins to use by looking at [your board's reference page](#boards) and searching for pins with the `SPI` marker.","The SPI ```mode``` is between 0 and 3 - see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Clock_polarity_and_phase","On STM32F1-based parts, you cannot mix AF and non-AF pins (SPI pins are usually grouped on the chip - and you can't mix pins from two groups). Espruino will not warn you about this."]]
  ]
}
Set up this SPI port as an SPI Master.
*/
void jswrap_spi_setup(JsVar *parent, JsVar *options) {
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  JshSPIInfo inf;
  jsspiPopulateSPIInfo(&inf, options);

  if (DEVICE_IS_SPI(device)) {
    jshSPISetup(device, &inf);
#ifdef LINUX
    if (jsvIsObject(options)) {
      jsvUnLock(jsvObjectSetChild(parent, "path", jsvObjectGetChild(options, "path", 0)));
    }
#endif
  } else if (device == EV_NONE) {
    // software mode - at least configure pins properly
    if (inf.pinSCK != PIN_UNDEFINED)
      jshPinSetState(inf.pinSCK,  JSHPINSTATE_GPIO_OUT);
    if (inf.pinMISO != PIN_UNDEFINED)
      jshPinSetState(inf.pinMISO,  JSHPINSTATE_GPIO_IN);
    if (inf.pinMOSI != PIN_UNDEFINED)
      jshPinSetState(inf.pinMOSI,  JSHPINSTATE_GPIO_OUT);
  } else return;
  // Set up options, so we can initialise it on startup
  if (options)
    jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME));
  else
    jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
}
/*JSON{
  "type" : "function",
  "name" : "changeInterval",
  "generate" : "jswrap_interface_changeInterval",
  "params" : [
    ["id","JsVar","The id returned by a previous call to setInterval"],
    ["time","float","The new time period in ms"]
  ]
}
Change the Interval on a callback created with setInterval, for example:

```var id = setInterval(function () { print('foo'); }, 1000); // every second```

```changeInterval(id, 1500); // now runs every 1.5 seconds```

This takes effect the next time the callback is called (so it is not immediate).
 */
void jswrap_interface_changeInterval(JsVar *idVar, JsVarFloat interval) {
  JsVar *timerArrayPtr = jsvLock(timerArray);
  if (interval<TIMER_MIN_INTERVAL) interval=TIMER_MIN_INTERVAL;
  JsVar *timerName = jsvIsBasic(idVar) ? jsvFindChildFromVar(timerArrayPtr, idVar, false) : 0;
  if (timerName) {
    JsVar *timer = jsvSkipNameAndUnLock(timerName);
    JsVar *v;
    JsVarInt intervalInt = (JsVarInt)jshGetTimeFromMilliseconds(interval);
    v = jsvNewFromInteger(intervalInt);
    jsvUnLock2(jsvSetNamedChild(timer, v, "interval"), v);
    v = jsvNewFromInteger((JsVarInt)(jshGetSystemTime()-jsiLastIdleTime) + intervalInt);
    jsvUnLock3(jsvSetNamedChild(timer, v, "time"), v, timer);
    // timerName already unlocked
    jsiTimersChanged(); // mark timers as changed
  } else {
    jsExceptionHere(JSET_ERROR, "Unknown Interval");
  }
  jsvUnLock(timerArrayPtr);
}
Exemple #5
0
/*JSON{ "type":"function", "name" : "changeInterval",
         "description" : ["Change the Interval on a callback created with setInterval, for example:",
                          "```var id = setInterval(function () { print('foo'); }, 1000); // every second```",
                          "```changeInterval(id, 1500); // now runs every 1.5 seconds```",
                          "This takes effect the text time the callback is called (so it is not immediate)."],
         "generate" : "jswrap_interface_changeInterval",
         "params" : [ [ "id", "JsVar", "The id returned by a previous call to setInterval"],
                      [ "time","float","The new time period in ms" ] ]
}*/
void jswrap_interface_changeInterval(JsVar *idVar, JsVarFloat interval) {
  JsVar *timerArrayPtr = jsvLock(timerArray);
  if (interval<TIMER_MIN_INTERVAL) interval=TIMER_MIN_INTERVAL;
  JsVar *timerName = jsvIsBasic(idVar) ? jsvFindChildFromVar(timerArrayPtr, idVar, false) : 0;

  if (timerName) {
    JsVar *timer = jsvSkipNameAndUnLock(timerName);
    JsVar *v;
    v = jsvNewFromInteger(jshGetTimeFromMilliseconds(interval));
    jsvUnLock(jsvSetNamedChild(timer, v, "interval"));
    jsvUnLock(v);
    v = jsvNewFromInteger(jshGetSystemTime() + jshGetTimeFromMilliseconds(interval));
    jsvUnLock(jsvSetNamedChild(timer, v, "time"));
    jsvUnLock(v);
    jsvUnLock(timer);
    // timerName already unlocked
  } else {
    jsError("Unknown Interval");
  }
  jsvUnLock(timerArrayPtr);
}
/*JSON{ "type":"method", "class": "Serial", "name" : "onData",
         "description" : ["When a character is received on this serial port, the function supplied to onData gets called.",
                          "Only one function can ever be supplied, so calling onData(undefined) will stop any function being called"],
         "generate" : "jswrap_serial_onData",
         "params" : [ [ "function", "JsVarName", "A function to call when data arrives. It takes one argument, which is an object with a 'data' field"] ]
}*/
void jswrap_serial_onData(JsVar *parent, JsVar *funcVar) {
  JsVar *skippedFunc = jsvSkipName(funcVar);
  if (!jsvIsFunction(skippedFunc) && !jsvIsString(skippedFunc)) {
    jsiConsolePrint("Function or String not supplied - removing onData handler.\n");
    JsVar *handler = jsvFindChildFromString(parent, USART_CALLBACK_NAME, false);
    if (handler) {
      jsvRemoveChild(parent, handler);
      jsvUnLock(handler);
    }
  } else {
    jsvUnLock(jsvSetNamedChild(parent, funcVar, USART_CALLBACK_NAME));
  }
  jsvUnLock(skippedFunc);
}
Exemple #7
0
/*JSON{
  "type" : "method",
  "class" : "I2C",
  "name" : "setup",
  "generate" : "jswrap_i2c_setup",
  "params" : [
    ["options","JsVar",["An optional structure containing extra information on initialising the I2C port","```{scl:pin, sda:pin, bitrate:100000}```","You can find out which pins to use by looking at [your board's reference page](#boards) and searching for pins with the `I2C` marker. Note that 400000kHz is the maximum bitrate for most parts."]]
  ]
}
Set up this I2C port

If not specified in options, the default pins are used (usually the lowest numbered pins on the lowest port that supports this peripheral)
 */
void jswrap_i2c_setup(JsVar *parent, JsVar *options) {
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  if (!DEVICE_IS_I2C(device)) return;
  JshI2CInfo inf;
  jshI2CInitInfo(&inf);
  if (jsvIsObject(options)) {
    inf.pinSCL = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "scl", 0));
    inf.pinSDA = jshGetPinFromVarAndUnLock(jsvObjectGetChild(options, "sda", 0));
    JsVar *v = jsvObjectGetChild(options, "bitrate", 0);
    if (v)
      inf.bitrate = jsvGetIntegerAndUnLock(v);
  }
  jshI2CSetup(device, &inf);
  // Set up options, so we can initialise it on startup
  if (options)
    jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME));
  else
    jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
}
Exemple #8
0
/*JSON{
  "type" : "method",
  "class" : "SPI",
  "name" : "setup",
  "generate" : "jswrap_spi_setup",
  "params" : [
    ["options","JsVar",["An optional structure containing extra information on initialising the SPI port","Please note that baud rate is set to the nearest that can be managed - which may be -+ 50%","```{sck:pin, miso:pin, mosi:pin, baud:integer=100000, mode:integer=0, order:'msb'/'lsb'='msb' }```","If sck,miso and mosi are left out, they will automatically be chosen. However if one or more is specified then the unspecified pins will not be set up.","You can find out which pins to use by looking at [your board's reference page](#boards) and searching for pins with the `SPI` marker.","The SPI ```mode``` is between 0 and 3 - see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Clock_polarity_and_phase","On STM32F1-based parts, you cannot mix AF and non-AF pins (SPI pins are usually grouped on the chip - and you can't mix pins from two groups). Espruino will not warn you about this."]]
  ]
}
Set up this SPI port as an SPI Master.
 */
void jswrap_spi_setup(
    JsVar *parent, //!< The variable that is the class instance of this function.
    JsVar *options //!< The options controlling SPI.
  ) {
  //
  // Design: The options variable is a JS Object which contains a series of settings.  These
  // settings are parsed by `jsspiPopulateSPIInfo` to populate a C structure of type
  // `JshSPIInfo`.
  //
  // The options are also hung off the class instance variable in a property symbolically called
  // DEVICE_OPTIONS_NAME ("_options").
  //
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  JshSPIInfo inf;

  // Debug
  // jsiConsolePrintf("jswrap_spi_setup called parent=%v, options=%v\n", parent, options);

  jsspiPopulateSPIInfo(&inf, options);

  if (DEVICE_IS_SPI(device)) {
    jshSPISetup(device, &inf);
#ifdef LINUX
    if (jsvIsObject(options)) {
      jsvObjectSetChildAndUnLock(parent, "path", jsvObjectGetChild(options, "path", 0));
    }
#endif
  } else if (device == EV_NONE) {
    // software mode - at least configure pins properly
    if (inf.pinSCK != PIN_UNDEFINED)
      jshPinSetState(inf.pinSCK,  JSHPINSTATE_GPIO_OUT);
    if (inf.pinMISO != PIN_UNDEFINED)
      jshPinSetState(inf.pinMISO,  JSHPINSTATE_GPIO_IN);
    if (inf.pinMOSI != PIN_UNDEFINED)
      jshPinSetState(inf.pinMOSI,  JSHPINSTATE_GPIO_OUT);
  } else return;
  // Set up options, so we can initialise it on startup
  if (options)
    jsvUnLock(jsvSetNamedChild(parent, options, DEVICE_OPTIONS_NAME));
  else
    jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
}