示例#1
0
/*JSON{
  "type" : "function",
  "name" : "clearTimeout",
  "generate" : "jswrap_interface_clearTimeout",
  "params" : [
    ["id","JsVar","The id returned by a previous call to setTimeout"]
  ]
}
Clear the Timeout that was created with setTimeout, for example:

```var id = setTimeout(function () { print('foo'); }, 1000);```

```clearTimeout(id);```

If no argument is supplied, all timers and intervals are stopped
 */
void _jswrap_interface_clearTimeoutOrInterval(JsVar *idVar, bool isTimeout) {
  JsVar *timerArrayPtr = jsvLock(timerArray);
  if (jsvIsUndefined(idVar)) {
    /* Delete all timers EXCEPT those with a 'watch' field,
     as those were generated by jsinteractive.c for debouncing watches */
    JsvObjectIterator it;
    jsvObjectIteratorNew(&it, timerArrayPtr);
    while (jsvObjectIteratorHasValue(&it)) {
      JsVar *timerPtr = jsvObjectIteratorGetValue(&it);
      JsVar *watchPtr = jsvObjectGetChild(timerPtr, "watch", 0);
      if (!watchPtr)
        jsvObjectIteratorRemoveAndGotoNext(&it, timerArrayPtr);
      else
        jsvObjectIteratorNext(&it); 
      jsvUnLock2(watchPtr, timerPtr);
    }
    jsvObjectIteratorFree(&it);
  } else {
    JsVar *child = jsvIsBasic(idVar) ? jsvFindChildFromVar(timerArrayPtr, idVar, false) : 0;
    if (child) {
      JsVar *timerArrayPtr = jsvLock(timerArray);
      jsvRemoveChild(timerArrayPtr, child);
      jsvUnLock2(child, timerArrayPtr);
    } else {
      if (isTimeout)
        jsExceptionHere(JSET_ERROR, "Unknown Timeout");
      else
        jsExceptionHere(JSET_ERROR, "Unknown Interval");
    }
  }
  jsvUnLock(timerArrayPtr);
  jsiTimersChanged(); // mark timers as changed
}
示例#2
0
/*JSON{
  "type" : "method",
  "class" : "Function",
  "name" : "apply",
  "generate" : "jswrap_function_apply_or_call",
  "params" : [
    ["this","JsVar","The value to use as the 'this' argument when executing the function"],
    ["args","JsVar","Optional Array of Arguments"]
  ],
  "return" : ["JsVar","The return value of executing this function"]
}
This executes the function with the supplied 'this' argument and parameters
 */
JsVar *jswrap_function_apply_or_call(JsVar *parent, JsVar *thisArg, JsVar *argsArray) {
  unsigned int i;
  JsVar **args = 0;
  unsigned int argC = 0;

  if (jsvIsIterable(argsArray)) {
    argC = (unsigned int)jsvGetLength(argsArray);
    if (argC>64) {
      jsExceptionHere(JSET_ERROR, "Array passed to Function.apply is too big! Maximum 64 arguments, got %d", argC);
      return 0;
    }
    args = (JsVar**)alloca((size_t)argC * sizeof(JsVar*));
    for (i=0;i<argC;i++) args[i] = 0;
    // TODO: Use jsvGetArrayItems?
    JsvIterator it;
    jsvIteratorNew(&it, argsArray);
    while (jsvIteratorHasElement(&it)) {
      JsVarInt idx = jsvGetIntegerAndUnLock(jsvIteratorGetKey(&it));
      if (idx>=0 && idx<(int)argC) {
        assert(!args[idx]); // just in case there were dups
        args[idx] = jsvIteratorGetValue(&it);
      }
      jsvIteratorNext(&it);
    }
    jsvIteratorFree(&it);
  } else if (!jsvIsUndefined(argsArray)) {
    jsExceptionHere(JSET_ERROR, "Second argument to Function.apply must be iterable, got %t", argsArray);
    return 0;
  }

  JsVar *r = jspeFunctionCall(parent, 0, thisArg, false, (int)argC, args);
  jsvUnLockMany(argC, args);
  return r;
}
示例#3
0
/*JSON{
    "type" : "staticmethod",
    "class" : "NRF",
    "name" : "setAdvertising",
    "generate" : "jswrap_nrf_bluetooth_setAdvertising",
    "params" : [
      ["data","JsVar","The data to advertise as an object - see below for more info"]
    ]
}

Data is of the form `{ UUID : data_as_byte_array }`. For example to return battery level at 95%, do:

```
NRF.setAdvertising({
  0x180F : [95]
});
```

Or you could report the current temperature:

```
setInterval(function() {
  NRF.setAdvertising({
    0x1809 : [0|E.getTemperature()]
  });
}, 30000);
```
*/
void jswrap_nrf_bluetooth_setAdvertising(JsVar *data) {
  uint32_t err_code;
  ble_advdata_t advdata;
  setup_advdata(&advdata);

  if (jsvIsObject(data)) {
    ble_advdata_service_data_t *service_data = (ble_advdata_service_data_t*)alloca(jsvGetChildren(data)*sizeof(ble_advdata_service_data_t));
    int n = 0;
    JsvObjectIterator it;
    jsvObjectIteratorNew(&it, data);
    while (jsvObjectIteratorHasValue(&it)) {
      service_data[n].service_uuid = jsvGetIntegerAndUnLock(jsvObjectIteratorGetKey(&it));
      JsVar *v = jsvObjectIteratorGetValue(&it);
      JSV_GET_AS_CHAR_ARRAY(dPtr, dLen, v);
      jsvUnLock(v);
      service_data[n].data.size    = dLen;
      service_data[n].data.p_data  = dPtr;
      jsvObjectIteratorNext(&it);
      n++;
    }
    jsvObjectIteratorFree(&it);

    advdata.service_data_count   = n;
    advdata.p_service_data_array = service_data;
  } else if (!jsvIsUndefined(data)) {
    jsExceptionHere(JSET_TYPEERROR, "Expecting object or undefined, got %t", data);
  }

  err_code = ble_advdata_set(&advdata, NULL);
  if (err_code)
    jsExceptionHere(JSET_ERROR, "Got BLE error code %d", err_code);
}
示例#4
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);
}
示例#5
0
/*JSON{
  "type" : "staticmethod",
  "class" : "fs",
  "name" : "pipe",
  "ifndef" : "SAVE_ON_FLASH",
  "generate" : "jswrap_pipe",
  "params" : [
    ["source","JsVar","The source file/stream that will send content."],
    ["destination","JsVar","The destination file/stream that will receive content from the source."],
    ["options","JsVar",["An optional object `{ chunkSize : int=64, end : bool=true, complete : function }`","chunkSize : The amount of data to pipe from source to destination at a time","complete : a function to call when the pipe activity is complete","end : call the 'end' function on the destination when the source is finished"]]
  ]
}*/
void jswrap_pipe(JsVar* source, JsVar* dest, JsVar* options) {
  if (!source || !dest) return;
  JsVar *pipe = jspNewObject(0, "Pipe");
  JsVar *arr = pipeGetArray(true);
  JsVar* position = jsvNewFromInteger(0);
  if (pipe && arr && position) {// out of memory?
    JsVar *readFunc = jspGetNamedField(source, "read", false);
    JsVar *writeFunc = jspGetNamedField(dest, "write", false);
    if(jsvIsFunction(readFunc)) {
      if(jsvIsFunction(writeFunc)) {
        JsVarInt chunkSize = 64;
        bool callEnd = true;
        // parse Options Object
        if (jsvIsObject(options)) {
          JsVar *c;
          c = jsvObjectGetChild(options, "complete", false);
          if (c) {
            jsvObjectSetChild(pipe, "#oncomplete", c);
            jsvUnLock(c);
          }
          c = jsvObjectGetChild(options, "end", false);
          if (c) callEnd = jsvGetBoolAndUnLock(c);
          c = jsvObjectGetChild(options, "chunkSize", false);
          if (c) {
            if (jsvIsNumeric(c) && jsvGetInteger(c)>0)
              chunkSize = jsvGetInteger(c);
            else
              jsWarn("chunkSize must be an integer > 0");
            jsvUnLock(c);
          }
        } else if (!jsvIsUndefined(options)) {
          jsWarn("'options' must be an object, or undefined");
        }
        // set up our event listeners
        jswrap_object_addEventListener(source, "close", jswrap_pipe_src_close_listener, JSWAT_VOID | (JSWAT_JSVAR << (JSWAT_BITS*1)));
        jswrap_object_addEventListener(dest, "drain", jswrap_pipe_drain_listener, JSWAT_VOID | (JSWAT_JSVAR << (JSWAT_BITS*1)));
        jswrap_object_addEventListener(dest, "close", jswrap_pipe_dst_close_listener, JSWAT_VOID | (JSWAT_JSVAR << (JSWAT_BITS*1)));
        // set up the rest of the pipe
        jsvUnLock(jsvObjectSetChild(pipe, "chunkSize", jsvNewFromInteger(chunkSize)));
        jsvUnLock(jsvObjectSetChild(pipe, "end", jsvNewFromBool(callEnd)));
        jsvUnLock(jsvAddNamedChild(pipe, position, "position"));
        jsvUnLock(jsvAddNamedChild(pipe, source, "source"));
        jsvUnLock(jsvAddNamedChild(pipe, dest, "destination"));
        // add the pipe to our list
        jsvArrayPush(arr, pipe);
      } else {
        jsExceptionHere(JSET_ERROR, "Destination object does not implement the required write(buffer, length, position) method.");
      }
    } else {
      jsExceptionHere(JSET_ERROR, "Source object does not implement the required read(buffer, length, position) method.");
    }
    jsvUnLock(readFunc);
    jsvUnLock(writeFunc);
  }
  jsvUnLock(arr);
  jsvUnLock(pipe);
  jsvUnLock(position);
}
示例#6
0
static void jswrap_waveform_start(JsVar *waveform, Pin pin, JsVarFloat freq, JsVar *options, bool isWriting) {
  bool running = jsvGetBoolAndUnLock(jsvObjectGetChild(waveform, "running", 0));
  if (running) {
    jsExceptionHere(JSET_ERROR, "Waveform is already running");
    return;
  }
  if (!jshIsPinValid(pin)) {
    jsExceptionHere(JSET_ERROR, "Invalid pin");
    return;
  }
  if (!isfinite(freq) || freq<0.001) {
    jsExceptionHere(JSET_ERROR, "Frequency must be above 0.001Hz");
    return;
  }

  JsSysTime startTime = jshGetSystemTime();
  bool repeat = false;
  if (jsvIsObject(options)) {
    JsVarFloat t = jsvGetFloatAndUnLock(jsvObjectGetChild(options, "time", 0));
    if (isfinite(t) && t>0)
       startTime = jshGetTimeFromMilliseconds(t*1000);
    repeat = jsvGetBoolAndUnLock(jsvObjectGetChild(options, "repeat", 0));
  } else if (!jsvIsUndefined(options)) {
    jsExceptionHere(JSET_ERROR, "Expecting options to be undefined or an Object, not %t", options);
  }

  bool is16Bit = false;
  JsVar *buffer = jswrap_waveform_getBuffer(waveform,0, &is16Bit);
  JsVar *buffer2 = jswrap_waveform_getBuffer(waveform,1,0);

  UtilTimerEventType eventType;

  if (is16Bit) {
    eventType = isWriting ? UET_WRITE_SHORT : UET_READ_SHORT;
  } else {
    eventType = isWriting ? UET_WRITE_BYTE : UET_READ_BYTE;
  }


  // And finally set it up
  if (!jstStartSignal(startTime, jshGetTimeFromMilliseconds(1000.0 / freq), pin, buffer, repeat?(buffer2?buffer2:buffer):0, eventType))
    jsWarn("Unable to schedule a timer");
  jsvUnLock(buffer);
  jsvUnLock(buffer2);

  jsvUnLock(jsvObjectSetChild(waveform, "running", jsvNewFromBool(true)));
  jsvUnLock(jsvObjectSetChild(waveform, "freq", jsvNewFromFloat(freq)));
  // Add to our list of active waveforms
  JsVar *waveforms = jsvObjectGetChild(execInfo.hiddenRoot, JSI_WAVEFORM_NAME, JSV_ARRAY);
  if (waveforms) {
    jsvArrayPush(waveforms, waveform);
    jsvUnLock(waveforms);
  }
}
示例#7
0
/*JSON{
  "type" : "function",
  "name" : "edit",
  "generate" : "jswrap_interface_edit",
  "params" : [
    ["funcName","JsVar","The name of the function to edit (either a string or just the unquoted name)"]
  ]
}
Fill the console with the contents of the given function, so you can edit it.

NOTE: This is a convenience function - it will not edit 'inner functions'. For that, you must edit the 'outer function' and re-execute it.
 */
void jswrap_interface_edit(JsVar *funcName) {
  JsVar *func = 0;
  if (jsvIsString(funcName)) {
    funcName = jsvLockAgain(funcName);
    func = jsvSkipNameAndUnLock(jsvFindChildFromVar(execInfo.root, funcName, 0));
  } else {
    func = funcName;
    funcName = jsvGetPathTo(execInfo.root, func, 2, 0);
  }

  if (jsvIsString(funcName)) {
    if (jsvIsFunction(func)) {
      JsVar *scopeVar = jsvFindChildFromString(func, JSPARSE_FUNCTION_SCOPE_NAME, false);
      JsVar *inRoot = jsvGetArrayIndexOf(execInfo.root, func, true);
      bool normalDecl = scopeVar==0 && inRoot!=0;
      jsvUnLock(inRoot);
      jsvUnLock(scopeVar);
      JsVar *newLine = jsvNewFromEmptyString();
      if (newLine) { // could be out of memory
        /* normalDecl:
         *
         * function foo() { ... }
         *
         * NOT normalDecl:
         *
         * foo.replaceWith(function() { ... });
         *
         */
        JsVar *funcData = jsvAsString(func, false);

        if (normalDecl) {
          jsvAppendString(newLine, "function ");
          jsvAppendStringVarComplete(newLine, funcName);
          jsvAppendStringVar(newLine, funcData, 9, JSVAPPENDSTRINGVAR_MAXLENGTH);

        } else {
          jsvAppendStringVarComplete(newLine, funcName);
          jsvAppendString(newLine, ".replaceWith(");
          jsvAppendStringVarComplete(newLine, funcData);
          jsvAppendString(newLine, ");");
        }
        jsvUnLock(funcData);
        jsiReplaceInputLine(newLine);
        jsvUnLock(newLine);
      }
    } else {
      jsExceptionHere(JSET_ERROR, "Edit should be called with the name of a function");
    }
  } else {
    jsExceptionHere(JSET_ERROR, "Edit should be called with edit(funcName) or edit('funcName')");
  }
  jsvUnLock(func);
  jsvUnLock(funcName);
}
示例#8
0
/*JSON{
  "type"     : "staticmethod",
  "class"    : "ESP8266WiFi",
  "name"     : "beAccessPoint",
  "generate" : "jswrap_ESP8266WiFi_beAccessPoint",
  "params"   : [
    ["jsv_ssid", "JsVar", "The network SSID"],
    ["jsv_password", "JsVar", "The password to allow stations to connect to the access point"]
  ]
}*/
void jswrap_ESP8266WiFi_beAccessPoint(
    JsVar *jsv_ssid,    //!< The network identity that the access point will advertize itself as.
    JsVar *jsv_password //!< The password a station will need to connect to the access point.
  ) {
  os_printf("> jswrap_ESP8266WiFi_beAccessPoint\n");
  // Validate that the SSID and password are somewhat useful.
  if (jsv_ssid == NULL || !jsvIsString(jsv_ssid)) {
      jsExceptionHere(JSET_ERROR, "No SSID.");
    return;
  }

  // Build our SoftAP configuration details
  struct softap_config softApConfig;
  memset(&softApConfig, 0, sizeof(softApConfig));

  // If no password has been supplied, then be open.  Otherwise, use WPA2 and the
  // password supplied.  Also check that the password is at least 8 characters long.
  if (jsv_password == NULL || !jsvIsString(jsv_password)) {
    softApConfig.authmode = AUTH_OPEN;
  } else {
    if (jsvGetStringLength(jsv_password) < 8) {
      jsExceptionHere(JSET_ERROR, "Password must be 8 characters or more in length.");
      return;
    }
    softApConfig.authmode = AUTH_WPA2_PSK;
    int len = jsvGetString(jsv_password, (char *)softApConfig.password, sizeof(softApConfig.password)-1);
    softApConfig.password[len]='\0';
  }

  int len = jsvGetString(jsv_ssid, (char *)softApConfig.ssid, sizeof(softApConfig.ssid)-1);
  softApConfig.ssid[len]='\0';

  // Define that we are in Soft AP mode.
  os_printf("Wifi: switching to soft-AP mode, authmode=%d\n", softApConfig.authmode);
  wifi_set_opmode_current(SOFTAP_MODE);

  softApConfig.ssid_len       = 0; // Null terminated SSID
  softApConfig.ssid_hidden    = 0; // Not hidden.
  softApConfig.max_connection = 4; // Maximum number of connections.

  // Set the WiFi configuration.
  int rc = wifi_softap_set_config_current(&softApConfig);
  // We should really check that becoming an access point works, however as of SDK 1.4, we
  // are finding that if we are currently connected to an access point and we switch to being
  // an access point, it works ... but returns 1 indicating an error.
  /*
  if (rc != 1) {
      os_printf(" - Error returned from wifi_softap_set_config_current=%d\n", rc);
      jsExceptionHere(JSET_ERROR, "Error setting ESP8266 softap config.");
  }
  */
  os_printf("< jswrap_ESP8266WiFi_beAccessPoint\n");
}
示例#9
0
/*JSON{
  "type" : "method",
  "class" : "ArrayBufferView",
  "name" : "map",
  "generate" : "jswrap_arraybufferview_map",
  "params" : [
    ["function","JsVar","Function used to map one item to another"],
    ["thisArg","JsVar","if specified, the function is called with 'this' set to thisArg (optional)"]
  ],
  "return" : ["JsVar","An array containing the results"],
  "return_object" : "ArrayBufferView"
}
Return an array which is made from the following: ```A.map(function) = [function(A[0]), function(A[1]), ...]```

**Note:** This returns an ArrayBuffer of the same type it was called on. To get an Array, use `Array.prototype.map`
*/
JsVar *jswrap_arraybufferview_map(JsVar *parent, JsVar *funcVar, JsVar *thisVar) {
  if (!jsvIsArrayBuffer(parent)) {
    jsExceptionHere(JSET_ERROR, "ArrayBufferView.map can only be called on an ArrayBufferView");
    return 0;
  }
  if (!jsvIsFunction(funcVar)) {
    jsExceptionHere(JSET_ERROR, "ArrayBufferView.map's first argument should be a function");
    return 0;
  }
  if (!jsvIsUndefined(thisVar) && !jsvIsObject(thisVar)) {
    jsExceptionHere(JSET_ERROR, "ArrayBufferView.map's second argument should be undefined, or an object");
    return 0;
  }

  // create ArrayBuffer result
  JsVarDataArrayBufferViewType arrayBufferType = parent->varData.arraybuffer.type;
  JsVar *arrayBufferLength = jsvNewFromInteger((JsVarInt)jsvGetArrayBufferLength(parent));
  JsVar *array = jswrap_typedarray_constructor(arrayBufferType, arrayBufferLength, 0, 0);
  jsvUnLock(arrayBufferLength);
  if (!array) return 0;

  // now iterate
  JsvIterator it; // TODO: if we really are limited to ArrayBuffers, this could be an ArrayBufferIterator.
  jsvIteratorNew(&it, parent);
  JsvArrayBufferIterator itdst;
  jsvArrayBufferIteratorNew(&itdst, array, 0);

  while (jsvIteratorHasElement(&it)) {
    JsVar *index = jsvIteratorGetKey(&it);
    if (jsvIsInt(index)) {
      JsVarInt idxValue = jsvGetInteger(index);

      JsVar *args[3], *mapped;
      args[0] = jsvIteratorGetValue(&it);
      args[1] = jsvNewFromInteger(idxValue); // child is a variable name, create a new variable for the index
      args[2] = parent;
      mapped = jspeFunctionCall(funcVar, 0, thisVar, false, 3, args);
      jsvUnLock(args[0]);
      jsvUnLock(args[1]);
      if (mapped) {
        jsvArrayBufferIteratorSetValue(&itdst, mapped);
        jsvUnLock(mapped);
      }
    }
    jsvUnLock(index);
    jsvIteratorNext(&it);
    jsvArrayBufferIteratorNext(&itdst);
  }
  jsvIteratorFree(&it);
  jsvArrayBufferIteratorFree(&itdst);

  return array;
}
示例#10
0
文件: lcd_sdl.c 项目: 0x00f/Espruino
void lcdInit_SDL(JsGraphics *gfx) {
  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) {
    jsExceptionHere(JSET_ERROR, "SDL_Init failed\n");
    exit(1);
  }
  if (!(screen = SDL_SetVideoMode(gfx->data.width, gfx->data.height, gfx->data.bpp, SDL_SWSURFACE)))
  {
    jsExceptionHere(JSET_ERROR, "SDL_SetVideoMode failed\n");
    SDL_Quit();
    exit(1);
  }
}
示例#11
0
/*JSON{
  "type" : "method",
  "class" : "SPI",
  "name" : "send4bit",
  "generate" : "jswrap_spi_send4bit",
  "params" : [
    ["data","JsVar","The data to send - either an integer, array, or string"],
    ["bit0","int32","The 4 bits to send for a 0 (MSB first)"],
    ["bit1","int32","The 4 bits to send for a 1 (MSB first)"],
    ["nss_pin","pin","An nSS pin - this will be lowered before SPI output and raised afterwards (optional). There will be a small delay between when this is lowered and when sending starts, and also between sending finishing and it being raised."]
  ]
}
Send data down SPI, using 4 bits for each 'real' bit (MSB first). This can be useful for faking one-wire style protocols

Sending multiple bytes in one call to send is preferable as they can then be transmitted end to end. Using multiple calls to send() will result in significantly slower transmission speeds.
 */
void jswrap_spi_send4bit(JsVar *parent, JsVar *srcdata, int bit0, int bit1, Pin nss_pin) {
  NOT_USED(parent);
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  if (!DEVICE_IS_SPI(device)) {
    jsExceptionHere(JSET_ERROR, "SPI.send4bit only works on hardware SPI");
    return;
  }

  jshSPISet16(device, true); // 16 bit output

  if (bit0==0 && bit1==0) {
    bit0 = 0x01;
    bit1 = 0x03;
  }
  bit0 = bit0 & 0x0F;
  bit1 = bit1 & 0x0F;

  if (!jshIsDeviceInitialised(device)) {
    JshSPIInfo inf;
    jshSPIInitInfo(&inf);
    jshSPISetup(device, &inf);
  }

  // we're just sending (no receive)
  jshSPISetReceive(device, false);
  // assert NSS
  if (nss_pin!=PIN_UNDEFINED) jshPinOutput(nss_pin, false);

  // send data
  if (jsvIsNumeric(srcdata)) {
    jsspiSend4bit(device, (unsigned char)jsvGetInteger(srcdata), bit0, bit1);
  } else if (jsvIsIterable(srcdata)) {
    jshInterruptOff();
    JsvIterator it;
    jsvIteratorNew(&it, srcdata);
    while (jsvIteratorHasElement(&it)) {
      unsigned char in = (unsigned char)jsvIteratorGetIntegerValue(&it);
      jsspiSend4bit(device, in, bit0, bit1);
      jsvIteratorNext(&it);
    }
    jsvIteratorFree(&it);
    jshInterruptOn();
  } else {
    jsExceptionHere(JSET_ERROR, "Variable type %t not suited to transmit operation", srcdata);
  }

  jshSPIWait(device); // wait until SPI send finished and clear the RX buffer

  // de-assert NSS
  if (nss_pin!=PIN_UNDEFINED) jshPinOutput(nss_pin, true);
  jshSPISet16(device, false); // back to 8 bit
}
示例#12
0
/*JSON{
  "type" : "method",
  "class" : "Array",
  "name" : "reduce",
  "ifndef" : "SAVE_ON_FLASH",
  "generate" : "jswrap_array_reduce",
  "params" : [
    ["callback","JsVar","Function used to reduce the array"],
    ["initialValue","JsVar","if specified, the initial value to pass to the function"]
  ],
  "return" : ["JsVar","The value returned by the last function called"]
}
Execute `previousValue=initialValue` and then `previousValue = callback(previousValue, currentValue, index, array)` for each element in the array, and finally return previousValue.
*/
JsVar *jswrap_array_reduce(JsVar *parent, JsVar *funcVar, JsVar *initialValue) {
  const char *name = "reduce";
  if (!jsvIsIterable(parent)) {
    jsExceptionHere(JSET_ERROR, "Array.%s can only be called on something iterable", name);
    return 0;
  }
  if (!jsvIsFunction(funcVar)) {
    jsExceptionHere(JSET_ERROR, "Array.%s's first argument should be a function", name);
    return 0;
  }
  JsVar *previousValue = initialValue ? jsvLockAgain(initialValue) : 0;
  JsvIterator it;
  jsvIteratorNew(&it, parent);
  if (!previousValue) {
    bool isDone = false;
    while (!isDone && jsvIteratorHasElement(&it)) {
      JsVar *index = jsvIteratorGetKey(&it);
      if (jsvIsInt(index)) {
        previousValue = jsvIteratorGetValue(&it);
        isDone = true;
      }
      jsvUnLock(index);
      jsvIteratorNext(&it);
    }
    if (!previousValue) {
      jsExceptionHere(JSET_ERROR, "Array.%s without initial value required non-empty array", name);
    }
  }
  while (jsvIteratorHasElement(&it)) {
    JsVar *index = jsvIteratorGetKey(&it);
    if (jsvIsInt(index)) {
      JsVarInt idxValue = jsvGetInteger(index);

      JsVar *args[4];
      args[0] = previousValue;
      args[1] = jsvIteratorGetValue(&it);
      args[2] = jsvNewFromInteger(idxValue); // child is a variable name, create a new variable for the index
      args[3] = parent;
      previousValue = jspeFunctionCall(funcVar, 0, 0, false, 4, args);
      jsvUnLock(args[0]);
      jsvUnLock(args[1]);
      jsvUnLock(args[2]);
    }
    jsvUnLock(index);
    jsvIteratorNext(&it);
  }
  jsvIteratorFree(&it);

  return previousValue;
}
示例#13
0
/*JSON{
  "type"     : "staticmethod",
  "class"    : "ESP8266WiFi",
  "name"     : "ping",
  "generate" : "jswrap_ESP8266WiFi_ping",
  "params"   : [
    ["ipAddr","JsVar","A string or integer representation of an IP address."],
    ["pingCallback", "JsVar", "Optional callback function."]
  ]
}*/
void jswrap_ESP8266WiFi_ping(
    JsVar *ipAddr,      //!< A string or integer representation of an IP address.
    JsVar *pingCallback //!< Optional callback function.
  ) {
  // If the parameter is a string, get the IP address from the string
  // representation.
  if (jsvIsString(ipAddr)) {
    char ipString[20];
    int len = jsvGetString(ipAddr, ipString, sizeof(ipString)-1);
    ipString[len] = '\0';
    pingOpt.ip = networkParseIPAddress(ipString);
    if (pingOpt.ip == 0) {
        jsExceptionHere(JSET_ERROR, "Not a valid IP address.");
      return;
    }
  } else
  // If the parameter is an integer, treat it as an IP address.
  if (jsvIsInt(ipAddr)) {
    pingOpt.ip = jsvGetInteger(ipAddr);
  } else
  // The parameter was neither a string nor an IP address and hence we don't
  // know how to get the IP address of the partner to ping so throw an
  // exception.
  {
      jsExceptionHere(JSET_ERROR, "IP address must be string or integer.");
    return;
  }

  if (jsvIsUndefined(pingCallback) || jsvIsNull(pingCallback)) {
    if (g_jsPingCallback != NULL) {
      jsvUnLock(g_jsPingCallback);
    }
    g_jsPingCallback = NULL;
  } else if (!jsvIsFunction(pingCallback)) {
      jsExceptionHere(JSET_ERROR, "Callback is not a function.");
    return;
  } else {
    if (g_jsPingCallback != NULL) {
      jsvUnLock(g_jsPingCallback);
    }
    g_jsPingCallback = pingCallback;
    jsvLockAgainSafe(g_jsPingCallback);
  }

  // We now have an IP address to ping ... so ping.
  memset(&pingOpt, 0, sizeof(pingOpt));
  pingOpt.count = 5;
  pingOpt.recv_function = pingRecvCB;
  ping_start(&pingOpt);
}
示例#14
0
/*JSON{ "type":"method", "class": "Waveform", "name" : "stop", "ifndef" : "SAVE_ON_FLASH",
         "description" : "Stop a waveform that is currently outputting",
         "generate" : "jswrap_waveform_stop"
}*/
void jswrap_waveform_stop(JsVar *waveform) {
  bool running = jsvGetBoolAndUnLock(jsvObjectGetChild(waveform, "running", 0));
  if (!running) {
    jsExceptionHere(JSET_ERROR, "Waveform is not running");
    return;
  }
  JsVar *buffer = jswrap_waveform_getBuffer(waveform,0,0);
  if (!jstStopBufferTimerTask(buffer)) {
    jsExceptionHere(JSET_ERROR, "Waveform couldn't be stopped");
  }
  jsvUnLock(buffer);
  // now run idle loop as this will issue the finish event and will clean up
  jswrap_waveform_idle();
}
示例#15
0
/*JSON{
  "type"     : "staticmethod",
  "class"    : "ESP8266WiFi",
  "name"     : "updateCPUFreq",
  "generate" : "jswrap_ESP8266WiFi_updateCPUFreq",
  "params"   : [
    ["freq", "JsVar", "Desired frequency - either 80 or 160."]
  ]
}
 * Update the operating frequency of the ESP8266 processor.
 */
void jswrap_ESP8266WiFi_updateCPUFreq(
    JsVar *jsFreq //!< Operating frequency of the processor.  Either 80 or 160.
  ) {
  if (!jsvIsInt(jsFreq)) {
    jsExceptionHere(JSET_ERROR, "Invalid frequency.");
    return;
  }
  int newFreq = jsvGetInteger(jsFreq);
  if (newFreq != 80 && newFreq != 160) {
    jsExceptionHere(JSET_ERROR, "Invalid frequency value, must be 80 or 160.");
    return;
  }
  system_update_cpu_freq(newFreq);
}
示例#16
0
/*JSON{
  "type" : "constructor",
  "class" : "ArrayBuffer",
  "name" : "ArrayBuffer",
  "generate" : "jswrap_arraybuffer_constructor",
  "params" : [
    ["byteLength","int","The length in Bytes"]
  ],
  "return" : ["JsVar","An ArrayBuffer object"]
}
Create an Array Buffer object
*/
JsVar *jswrap_arraybuffer_constructor(JsVarInt byteLength) {
  if (byteLength <= 0 || byteLength>65535) {
    jsExceptionHere(JSET_ERROR, "Invalid length for ArrayBuffer\n");
    return 0;
  }
  if (byteLength > JSV_ARRAYBUFFER_MAX_LENGTH) {
    jsExceptionHere(JSET_ERROR, "ArrayBuffer too long\n");
    return 0;
  }
  JsVar *arrData = jsvNewStringOfLength((unsigned int)byteLength);
  if (!arrData) return 0;
  JsVar *v = jsvNewArrayBufferFromString(arrData, (unsigned int)byteLength);
  jsvUnLock(arrData);
  return v;
}
示例#17
0
static bool handlePipe(JsVar *arr, JsvObjectIterator *it, JsVar* pipe) {
  bool paused = jsvGetBoolAndUnLock(jsvObjectGetChild(pipe,"drainWait",0));
  if (paused) return false;

  JsVar *position = jsvObjectGetChild(pipe,"position",0);
  JsVar *chunkSize = jsvObjectGetChild(pipe,"chunkSize",0);
  JsVar *source = jsvObjectGetChild(pipe,"source",0);
  JsVar *destination = jsvObjectGetChild(pipe,"destination",0);

  bool dataTransferred = false;
  if(source && destination && chunkSize && position) {
    JsVar *readFunc = jspGetNamedField(source, "read", false);
    JsVar *writeFunc = jspGetNamedField(destination, "write", false);
    if (jsvIsFunction(readFunc) && jsvIsFunction(writeFunc)) { // do the objects have the necessary methods on them?
      JsVar *buffer = jspExecuteFunction(readFunc, source, 1, &chunkSize);
      if(buffer) {
        JsVarInt bufferSize = jsvGetLength(buffer);
        if (bufferSize>0) {
          JsVar *response = jspExecuteFunction(writeFunc, destination, 1, &buffer);
          if (jsvIsBoolean(response) && jsvGetBool(response)==false) {
            // If boolean false was returned, wait for drain event (http://nodejs.org/api/stream.html#stream_writable_write_chunk_encoding_callback)
            jsvUnLock(jsvObjectSetChild(pipe,"drainWait",jsvNewFromBool(true)));
          }
          jsvUnLock(response);
          jsvSetInteger(position, jsvGetInteger(position) + bufferSize);
        }
        jsvUnLock(buffer);
        dataTransferred = true; // so we don't close the pipe if we get an empty string
      }
    } else {
      if(!jsvIsFunction(readFunc))
        jsExceptionHere(JSET_ERROR, "Source Stream does not implement the required read(length) method.");
      if(!jsvIsFunction(writeFunc))
        jsExceptionHere(JSET_ERROR, "Destination Stream does not implement the required write(buffer) method.");
    }
    jsvUnLock(readFunc);
    jsvUnLock(writeFunc);
  }

  if(!dataTransferred) { // when no more chunks are possible, execute the callback
    handlePipeClose(arr, it, pipe);
  }
  jsvUnLock(source);
  jsvUnLock(destination);
  jsvUnLock(chunkSize);
  jsvUnLock(position);
  return dataTransferred;
}
示例#18
0
/*JSON{
  "type" : "staticmethod",
  "class" : "E",
  "name" : "connectSDCard",
  "generate" : "jswrap_E_connectSDCard",
  "ifndef" : "SAVE_ON_FLASH",
  "params" : [
    ["spi","JsVar","The SPI object to use for communication"],
    ["csPin","pin","The pin to use for Chip Select"]
  ]
}
Setup the filesystem so that subsequent calls to `E.openFile` and `require('fs').*` will use an SD card on the supplied SPI device and pin.

It can even work using software SPI - for instance:

```
var spi = new SPI();
spi.setup({mosi:C7,miso:C8,sck:C9});
E.connectSDCard(spi,C6);
console.log(require("fs").readdirSync());
```
*/
void jswrap_E_connectSDCard(JsVar *spi, Pin csPin) {
#ifdef SD_CARD_ANYWHERE
    if (!jsvIsObject(spi)) {
        jsExceptionHere(JSET_ERROR, "First argument is a %t, not an SPI object\n", spi);
        return;
    }
    if (!jshIsPinValid(csPin)) {
        jsExceptionHere(JSET_ERROR, "Second argument is not a valid pin");
        return;
    }
    jswrap_E_unmountSD();
    sdSPISetup(spi, csPin);
#else
    jsExceptionHere(JSET_ERROR, "Unimplemented on Linux");
#endif
}
示例#19
0
/*JSON{
  "type"     : "staticmethod",
  "class"    : "ESP8266WiFi",
  "name"     : "getAccessPoints",
  "generate" : "jswrap_ESP8266WiFi_getAccessPoints",
  "params"   : [
    ["callback","JsVar","Function to call back when access points retrieved."]
  ]
}*/
void jswrap_ESP8266WiFi_getAccessPoints(
    JsVar *callback //!< Function to call back when access points retrieved.
  ) {
  os_printf("> ESP8266WiFi_getAccessPoints\n");
  if (callback == NULL || !jsvIsFunction(callback)) {
      jsExceptionHere(JSET_ERROR, "No callback.");
    return;
  }

  // If we had saved a previous scan callback function, release it.
  if (g_jsScanCallback != NULL) {
    jsvUnLock(g_jsScanCallback);
  }

  // Save the callback for the scan in the global variable called jsScanCallback.
  g_jsScanCallback = jsvLockAgainSafe(callback);

  // Ask the ESP8266 to perform a network scan after first entering
  // station mode.  The network scan will eventually result in a callback
  // being executed (scanCB) which will contain the results.

  // Ensure we are in station mode
  wifi_set_opmode_current(STATION_MODE);

  // Request a scan of the network calling "scanCB" on completion
  wifi_station_scan(NULL, scanCB);

  os_printf("< ESP8266WiFi_getAccessPoints\n");
}
示例#20
0
/*JSON{
  "type" : "function",
  "name" : "setTimeout",
  "generate" : "jswrap_interface_setTimeout",
  "params" : [
    ["function","JsVar","A Function or String to be executed"],
    ["timeout","float","The time until the function will be executed"],
    ["args","JsVarArray","Optional arguments to pass to the function when executed"]
  ],
  "return" : ["JsVar","An ID that can be passed to clearTimeout"]
}
Call the function (or evaluate the string) specified ONCE after the timeout in milliseconds.

For instance:

```
setTimeout(function () {
  console.log("Hello World");
}, 1000);
// or
setTimeout('console.log("Hello World");', 1000);
// both print 'Hello World' after a second
```

You can also specify extra arguments that will be sent to the function when it is executed. For example:

```
setTimeout(function (a,b) {
  console.log(a+" "+b);
}, 1000, "Hello", "World");
// prints 'Hello World' after 1 second
```

If you want to stop the function from being called, pass the number that
was returned by `setTimeout` into the `clearInterval` function.

 **Note:** If `setDeepSleep(true)` has been called and the interval is greater than 5 seconds, Espruino may execute the interval up to 1 second late. This is because Espruino can only wake from deep sleep every second - and waking early would cause Espruino to waste power while it waited for the correct time.
 */
JsVar *_jswrap_interface_setTimeoutOrInterval(JsVar *func, JsVarFloat interval, JsVar *args, bool isTimeout) {
  // NOTE: The 5 sec delay mentioned in the description is handled by jshSleep
  JsVar *itemIndex = 0;
  if (!jsvIsFunction(func) && !jsvIsString(func)) {
    jsExceptionHere(JSET_ERROR, "Function or String not supplied!");
  } else {
    // Create a new timer
    JsVar *timerPtr = jsvNewWithFlags(JSV_OBJECT);
    if (interval<TIMER_MIN_INTERVAL) interval=TIMER_MIN_INTERVAL;
    JsSysTime intervalInt = jshGetTimeFromMilliseconds(interval);
    jsvObjectSetChildAndUnLock(timerPtr, "time", jsvNewFromLongInteger((jshGetSystemTime() - jsiLastIdleTime) + intervalInt));
    if (!isTimeout) {
      jsvObjectSetChildAndUnLock(timerPtr, "interval", jsvNewFromLongInteger(intervalInt));
    }
    jsvObjectSetChild(timerPtr, "callback", func); // intentionally no unlock
    if (jsvGetArrayLength(args))
      jsvObjectSetChild(timerPtr, "args", args); // intentionally no unlock

    // Add to array
    itemIndex = jsvNewFromInteger(jsiTimerAdd(timerPtr));
    jsvUnLock(timerPtr);
    jsiTimersChanged(); // mark timers as changed
  }
  return itemIndex;
}
示例#21
0
void jshPinOutput(Pin pin, bool value) {
  if (jshIsPinValid(pin)) {
    if (!jshGetPinStateIsManual(pin))
      jshPinSetState(pin, JSHPINSTATE_GPIO_OUT);
    jshPinSetValue(pin, value);
  } else jsExceptionHere(JSET_ERROR, "Invalid pin!");
}
示例#22
0
/*JSON{
  "type" : "method",
  "class" : "ArrayBufferView",
  "name" : "set",
  "generate" : "jswrap_arraybufferview_set",
  "params" : [
    ["arr","JsVar","Floating point index to access"],
    ["offset","int32","The offset in this array at which to write the values (optional)"]
  ]
}
Copy the contents of `array` into this one, mapping `this[x+offset]=array[x];`
*/
void jswrap_arraybufferview_set(JsVar *parent, JsVar *arr, int offset) {
  if (!(jsvIsString(arr) || jsvIsArray(arr) || jsvIsArrayBuffer(arr))) {
    jsExceptionHere(JSET_ERROR, "Expecting first argument to be an array, not %t", arr);
    return;
  }
  JsvIterator itsrc;
  jsvIteratorNew(&itsrc, arr);
  JsvArrayBufferIterator itdst;
  jsvArrayBufferIteratorNew(&itdst, parent, (size_t)offset);

  bool useInts = !JSV_ARRAYBUFFER_IS_FLOAT(itdst.type) || jsvIsString(arr);

  while (jsvIteratorHasElement(&itsrc) && jsvArrayBufferIteratorHasElement(&itdst)) {
    if (useInts) {
      jsvArrayBufferIteratorSetIntegerValue(&itdst, jsvIteratorGetIntegerValue(&itsrc));
    } else {
      JsVar *value = jsvIteratorGetValue(&itsrc);
      jsvArrayBufferIteratorSetValue(&itdst, value);
      jsvUnLock(value);
    }
    jsvArrayBufferIteratorNext(&itdst);
    jsvIteratorNext(&itsrc);
  }
  jsvArrayBufferIteratorFree(&itdst);
  jsvIteratorFree(&itsrc);
}
示例#23
0
/*JSON{
  "type" : "staticmethod",
  "ifndef" : "SAVE_ON_FLASH",
  "class" : "E",
  "name" : "convolve",
  "generate" : "jswrap_espruino_convolve",
  "params" : [
    ["arr1","JsVar","An array to convolve"],
    ["arr2","JsVar","An array to convolve"],
    ["offset","int32","The mean value of the array"]
  ],
  "return" : ["float","The variance of the given buffer"]
}
Convolve arr1 with arr2. This is equivalent to `v=0;for (i in arr1) v+=arr1[i] * arr2[(i+offset) % arr2.length]`
*/
JsVarFloat jswrap_espruino_convolve(JsVar *arr1, JsVar *arr2, int offset) {
  if (!(jsvIsIterable(arr1)) ||
      !(jsvIsIterable(arr2))) {
    jsExceptionHere(JSET_ERROR, "Expecting first 2 arguments to be iterable, not %t and %t", arr1, arr2);
    return NAN;
  }
  JsVarFloat conv = 0;

  JsvIterator it1;
  jsvIteratorNew(&it1, arr1);
  JsvIterator it2;
  jsvIteratorNew(&it2, arr2);

  // get iterator2 at the correct offset
  int l = (int)jsvGetLength(arr2);
  offset = offset % l;
  if (offset<0) offset += l;
  while (offset-->0)
    jsvIteratorNext(&it2);


  while (jsvIteratorHasElement(&it1)) {
    conv += jsvIteratorGetFloatValue(&it1) * jsvIteratorGetFloatValue(&it2);
    jsvIteratorNext(&it1);
    jsvIteratorNext(&it2);
    // restart iterator if it hit the end
    if (!jsvIteratorHasElement(&it2)) {
      jsvIteratorFree(&it2);
      jsvIteratorNew(&it2, arr2);
    }
  }
  jsvIteratorFree(&it1);
  jsvIteratorFree(&it2);
  return conv;
}
示例#24
0
/*JSON{
  "type" : "constructor",
  "ifndef" : "SAVE_ON_FLASH",
  "class" : "RegExp",
  "name" : "RegExp",
  "generate" : "jswrap_regexp_constructor",
  "params" : [
    ["regex","JsVar","A regular expression as a string"],
    ["regex","JsVar","Flags for the regular expression as a string"]
  ],
  "return" : ["JsVar","A RegExp object"],
  "return_object" : "RegExp"
}
Creates a RegExp object, for handling Regular Expressions
 */
JsVar *jswrap_regexp_constructor(JsVar *str, JsVar *flags) {
  if (!jsvIsString(str)) {
    jsExceptionHere(JSET_TYPEERROR, "Expecting String as first argument, got %t", str);
    return 0;
  }
  JsVar *r = jspNewObject(0,"RegExp");
  jsvObjectSetChild(r, "source", str);
  if (!jsvIsUndefined(flags)) {
    if (!jsvIsString(flags))
      jsExceptionHere(JSET_TYPEERROR, "Expecting String as first argument, got %t", str);
    else
      jsvObjectSetChild(r, "flags", flags);
  }
  jsvObjectSetChildAndUnLock(r, "lastIndex", jsvNewFromInteger(0));
  return r;
}
示例#25
0
/*JSON{
  "type" : "method",
  "class" : "I2C",
  "name" : "readFrom",
  "generate" : "jswrap_i2c_readFrom",
  "params" : [
    ["address","JsVar","The 7 bit address of the device to request bytes from, or an object of the form `{address:12, stop:false}` to send this data without a STOP signal."],
    ["quantity","int32","The number of bytes to request"]
  ],
  "return" : ["JsVar","The data that was returned - as a Uint8Array"],
  "return_object" : "Uint8Array"
}
Request bytes from the given slave device, and return them as a Uint8Array (packed array of bytes). This is like using Arduino Wire's requestFrom, available and read functions.  Sends a STOP
 */
JsVar *jswrap_i2c_readFrom(JsVar *parent, JsVar *addressVar, int nBytes) {
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  if (!DEVICE_IS_I2C(device)) return 0;

  bool sendStop = true;
  int address = i2c_get_address(addressVar, &sendStop);

  if (nBytes<=0)
    return 0;
  if ((unsigned int)nBytes+256 > jsuGetFreeStack()) {
    jsExceptionHere(JSET_ERROR, "Not enough free stack to receive this amount of data");
    return 0;
  }
  unsigned char *buf = (unsigned char *)alloca((size_t)nBytes);

  jshI2CRead(device, (unsigned char)address, nBytes, buf, sendStop);

  JsVar *array = jsvNewTypedArray(ARRAYBUFFERVIEW_UINT8, nBytes);
  if (array) {
    JsvArrayBufferIterator it;
    jsvArrayBufferIteratorNew(&it, array, 0);
    unsigned int i;
    for (i=0;i<(unsigned)nBytes;i++) {
      jsvArrayBufferIteratorSetByteValue(&it, (char)buf[i]);
      jsvArrayBufferIteratorNext(&it);
    }
    jsvArrayBufferIteratorFree(&it);
  }
  return array;
}
示例#26
0
bool graphicsGetFromVar(JsGraphics *gfx, JsVar *parent) {
  gfx->graphicsVar = parent;
  JsVar *data = jsvObjectGetChild(parent, JS_HIDDEN_CHAR_STR"gfx", 0);
  assert(data);
  if (data) {
    jsvGetString(data, (char*)&gfx->data, sizeof(JsGraphicsData)+1/*trailing zero*/);
    jsvUnLock(data);
    gfx->setPixel = graphicsFallbackSetPixel;
    gfx->getPixel = graphicsFallbackGetPixel;
    gfx->fillRect = graphicsFallbackFillRect;
#ifdef USE_LCD_SDL
    if (gfx->data.type == JSGRAPHICSTYPE_SDL) {
      lcdSetCallbacks_SDL(gfx);
    } else
#endif
#ifdef USE_LCD_FSMC
    if (gfx->data.type == JSGRAPHICSTYPE_FSMC) {
      lcdSetCallbacks_FSMC(gfx);
    } else
#endif
    if (gfx->data.type == JSGRAPHICSTYPE_ARRAYBUFFER) {
      lcdSetCallbacks_ArrayBuffer(gfx);
    } else if (gfx->data.type == JSGRAPHICSTYPE_JS) {
      lcdSetCallbacks_JS(gfx);
    } else {
      jsExceptionHere(JSET_INTERNALERROR, "Unknown graphics type\n");
      assert(0);
    }

    return true;
  } else
    return false;
}
示例#27
0
/*JSON{
  "type" : "method",
  "class" : "OneWire",
  "name" : "select",
  "generate" : "jswrap_onewire_select",
  "params" : [
    ["rom","JsVar","The device to select (get this using `OneWire.search()`)"]
  ]
}
Select a ROM - always performs a reset first
 */
void jswrap_onewire_select(JsVar *parent, JsVar *rom) {
  Pin pin = onewire_getpin(parent);
  if (!jshIsPinValid(pin)) return;
  if (!jsvIsString(rom) || jsvGetStringLength(rom)!=16) {
    jsExceptionHere(JSET_TYPEERROR, "Invalid OneWire device address %q", rom);
    return;
  }

  // perform a reset
  OneWireReset(pin);

  // decode the address
  unsigned long long romdata = 0;
  JsvStringIterator it;
  jsvStringIteratorNew(&it, rom, 0);
  int i;
  for (i=0;i<8;i++) {
    char b[3];
    b[0] = jsvStringIteratorGetChar(&it);
    jsvStringIteratorNext(&it);
    b[1] = jsvStringIteratorGetChar(&it);
    jsvStringIteratorNext(&it);
    b[2] = 0;
    romdata = romdata | (((unsigned long long)stringToIntWithRadix(b,16,NULL,NULL)) << (i*8));

  }
  jsvStringIteratorFree(&it);

  // finally write data out
  OneWireWrite(pin, 8, 0x55);
  OneWireWrite(pin, 64, romdata);
}
示例#28
0
// 'path' must be of JS_DIR_BUF_SIZE
bool jsfsGetPathString(char *pathStr, JsVar *path) {
  if (jsvGetString(path, pathStr, JS_DIR_BUF_SIZE)==JS_DIR_BUF_SIZE) {
    jsExceptionHere(JSET_ERROR, "File path too long\n");
    return false;
  }
  return true;
}
示例#29
0
/*JSON{
  "type" : "method",
  "class" : "Object",
  "name" : "valueOf",
  "generate" : "jswrap_object_valueOf",
  "return" : ["JsVar","The primitive value of this object"]
}
Returns the primitive value of this object.
 */
JsVar *jswrap_object_valueOf(JsVar *parent) {
  if (!parent) {
    jsExceptionHere(JSET_TYPEERROR, "Invalid type %t for valueOf", parent);
    return 0;
  }
  return jsvLockAgain(parent);
}
示例#30
0
/*JSON{
  "type"     : "staticmethod",
  "class"    : "ESP8266WiFi",
  "name"     : "onWiFiEvent",
  "generate" : "jswrap_ESP8266WiFi_onWiFiEvent",
  "params"   : [
    ["callback","JsVar","WiFi event callback"]
  ]
}*/
void jswrap_ESP8266WiFi_onWiFiEvent(
    JsVar *callback //!< WiFi event callback.
  ) {
  // If the callback is null
  if (callback == NULL || jsvIsNull(callback)) {
    if (g_jsWiFiEventCallback != NULL) {
      jsvUnLock(g_jsWiFiEventCallback);
    }
    g_jsWiFiEventCallback = NULL;
    return;
  }

  if (!jsvIsFunction(callback)) {
      jsExceptionHere(JSET_ERROR, "No callback.");
    return;
  }

  // We are about to save a new global WiFi even callback handler.  If we have previously
  // had one, we need to unlock it so that we don't leak memory.
  if (g_jsWiFiEventCallback != NULL) {
    jsvUnLock(g_jsWiFiEventCallback);
  }

  // Save the global WiFi event callback handler.
  g_jsWiFiEventCallback = jsvLockAgainSafe(callback);
}