Esempio n. 1
0
void jswrap_serial_write(JsVar *parent, JsVar *args) {
  NOT_USED(parent);
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  if (!DEVICE_IS_USART(device)) return;

  jsvIterateCallback(args, jswrap_serial_write_cb, (void*)&device);
}
Esempio n. 2
0
/**
 * Try and get a character for transmission.
 * \return The next byte to transmit or -1 if there is none.
 */
int jshGetCharToTransmit(
    IOEventFlags device // The device being looked at for a transmission.
  ) {
  if (DEVICE_IS_USART(device)) {
    JshSerialDeviceState *deviceState = &jshSerialDeviceStates[TO_SERIAL_DEVICE_STATE(device)];
    if ((*deviceState)&SDS_XOFF_PENDING) {
      (*deviceState) = ((*deviceState)&(~SDS_XOFF_PENDING)) | SDS_XOFF_SENT;
      return 19/*XOFF*/;
    }
    if ((*deviceState)&SDS_XON_PENDING) {
      (*deviceState) = ((*deviceState)&(~(SDS_XON_PENDING|SDS_XOFF_SENT)));
      return 17/*XON*/;
    }
  }

  unsigned char tempTail = txTail;
  while (txHead != tempTail) {
    if (IOEVENTFLAGS_GETTYPE(txBuffer[tempTail].flags) == device) {
      unsigned char data = txBuffer[tempTail].data;
      if (tempTail != txTail) { // so we weren't right at the back of the queue
        // we need to work back from tempTail (until we hit tail), shifting everything forwards
        unsigned char this = tempTail;
        unsigned char last = (unsigned char)((this+TXBUFFERMASK)&TXBUFFERMASK);
        while (this!=txTail) { // if this==txTail, then last is before it, so stop here
          txBuffer[this] = txBuffer[last];
          this = last;
          last = (unsigned char)((this+TXBUFFERMASK)&TXBUFFERMASK);
        }
      }
      txTail = (unsigned char)((txTail+1)&TXBUFFERMASK); // advance the tail
      return data; // return data
    }
Esempio n. 3
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);
}
Esempio n. 4
0
void _jswrap_serial_print(JsVar *parent, JsVar *arg, bool isPrint, bool newLine) {
  NOT_USED(parent);
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  if (!DEVICE_IS_USART(device)) return;

  if (isPrint) arg = jsvAsString(arg, false);
  jsvIterateCallback(arg, _jswrap_serial_print_cb, (void*)&device);
  if (isPrint) jsvUnLock(arg);
  if (newLine) {
    _jswrap_serial_print_cb((unsigned char)'\r', (void*)&device);
    _jswrap_serial_print_cb((unsigned char)'\n', (void*)&device);
  }
}
Esempio n. 5
0
/*JSON{
  "type" : "method",
  "class" : "Serial",
  "name" : "println",
  "generate" : "jswrap_serial_println",
  "params" : [
    ["string","JsVar","A String to print"]
  ]
}
Print a line to the serial port with a newline (`\r\n`) at the end of it.

**Note:** This function replaces any occurances of `\n` in the string with `\r\n`. To avoid this, use `Serial.write`.
*/
void _jswrap_serial_print(JsVar *parent, JsVar *str, bool newLine) {
  NOT_USED(parent);
  IOEventFlags device = jsiGetDeviceFromClass(parent);
  if (!DEVICE_IS_USART(device)) return;

  str = jsvAsString(str, false);
  jsiTransmitStringVar(device,str);
  jsvUnLock(str);
  if (newLine) {
    jshTransmit(device, (unsigned char)'\r');
    jshTransmit(device, (unsigned char)'\n');
  }
}
Esempio n. 6
0
/*JSON{
  "type" : "staticmethod",
  "class" : "ESP8266",
  "name" : "connect",
  "generate" : "jswrap_esp8266_connect_device",
  "params" : [
    ["serial","JsVar","The Serial port used for communications with the ESP8266 (must already be setup)"],
    ["callback","JsVar","Function to call back when connected"]
  ],
  "return" : ["JsVar","An ESP8266 Object"],
  "return_object" : "ESP8266"
}
Initialise the WIZnet module and return an Ethernet object
*/
JsVar *jswrap_esp8266_connect_device(JsVar *usart, JsVar *callback) {

  IOEventFlags usartDevice;
  usartDevice = jsiGetDeviceFromClass(usart);
  if (!DEVICE_IS_USART(usartDevice)) {
    jsExceptionHere(JSET_ERROR, "Expecting USART device, got %q", usart);
    return 0;
  }

  JsNetwork net;
  networkCreate(&net, JSNETWORKTYPE_ESP8266);
  net.data.device = usartDevice;
  networkSet(&net);

  JsVar *wifiObj = 0;

  JsVar *cmd = jsvNewFromString("AT+RST\r\n");
  esp8266_send(cmd);
  jsvUnLock(cmd);
  if (esp8266_wait_for("OK", 100, false)) {
    if (esp8266_wait_for("ready", 4000, false)) {
      networkState = NETWORKSTATE_ONLINE;
      wifiObj = jspNewObject(0, "ESPWifi");
    } else {
      jsExceptionHere(JSET_ERROR, "Module not ready");
    }
  } else {
    jsExceptionHere(JSET_ERROR, "No Acknowledgement");
  }


  networkFree(&net);

  if (callback)
    jsiQueueEvents(callback, 0, 0);

  return wifiObj;
}
Esempio n. 7
0
/** Kick a device into action (if required). For instance we may need
 * to set up interrupts */
void jshUSARTKick(IOEventFlags device) {
  assert(DEVICE_IS_USART(device));
  // all done by the idle loop
}
Esempio n. 8
0
void jshUSARTSetup(IOEventFlags device, JshUSARTInfo *inf) {
  assert(DEVICE_IS_USART(device));
  if (ioDevices[device]) close(ioDevices[device]);
  ioDevices[device] = 0;
  char path[256];
  if (jshGetDevicePath(device, path, sizeof(path))) {
    ioDevices[device] = open(path, O_RDWR | O_NOCTTY | O_NONBLOCK);
    if (!ioDevices[device]) {
      jsError("Open of path %s failed", path);
    } else {
      struct termios settings;
      tcgetattr(ioDevices[device], &settings); // get current settings

      int baud = 0;
      switch (inf->baudRate) {
        case 50      : baud = B50     ;break;
        case 75      : baud = B75     ;break;
        case 110     : baud = B110    ;break;
        case 134     : baud = B134    ;break;
        case 150     : baud = B150    ;break;
        case 200     : baud = B200    ;break;
        case 300     : baud = B300    ;break;
        case 600     : baud = B600    ;break;
        case 1200    : baud = B1200   ;break;
        case 1800    : baud = B1800   ;break;
        case 2400    : baud = B2400   ;break;
        case 4800    : baud = B4800   ;break;
        case 9600    : baud = B9600   ;break;
        case 19200   : baud = B19200  ;break;
        case 38400   : baud = B38400  ;break;
        case 57600   : baud = B57600  ;break;
        case 115200  : baud = B115200 ;break;
        case 230400  : baud = B230400 ;break;
#ifndef __MACOSX__
        case 460800  : baud = B460800 ;break;
        case 500000  : baud = B500000 ;break;
        case 576000  : baud = B576000 ;break;
        case 921600  : baud = B921600 ;break;
        case 1000000 : baud = B1000000;break;
        case 1152000 : baud = B1152000;break;
        case 1500000 : baud = B1500000;break;
        case 2000000 : baud = B2000000;break;
        case 2500000 : baud = B2500000;break;
        case 3000000 : baud = B3000000;break;
        case 3500000 : baud = B3500000;break;
        case 4000000 : baud = B4000000;break;
#endif
      }

      if (baud) {
        cfsetispeed(&settings, baud); // set baud rates
        cfsetospeed(&settings, baud);

        settings.c_cflag &= ~(PARENB|PARODD); // none
        
        if (inf->parity == 1) settings.c_cflag |= PARENB|PARODD; // odd
        if (inf->parity == 2) settings.c_cflag |= PARENB; // even
        
        settings.c_cflag &= ~CSTOPB;
        if (inf->stopbits==2) settings.c_cflag |= CSTOPB;

        settings.c_cflag &= ~CSIZE;

        switch (inf->bytesize) {
          case 5 : settings.c_cflag |= CS5; break;
          case 6 : settings.c_cflag |= CS6; break;
          case 7 : settings.c_cflag |= CS7; break;
          case 8 : settings.c_cflag |= CS8; break;
        }

        // raw mode
        cfmakeraw(&settings);

        // finally set current settings
        tcsetattr(ioDevices[device], TCSANOW, &settings);
      } else {
        jsError("No baud rate defined for device");
      }
    }
  } else {
    jsError("No path defined for device");
  }
}
Esempio n. 9
0
/*JSON{
  "type" : "method",
  "class" : "Serial",
  "name" : "setup",
  "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,flow:null/undefined/'none'/'xon'}```","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"]]
  ]
}
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)
 */
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(options)) {
    options = jsvObjectGetChild(parent, DEVICE_OPTIONS_NAME, 0);
  } else
    jsvLockAgain(options);

  JsVar *parity = 0;
  JsVar *flow = 0;
  jsvConfigObject configs[] = {
      {"rx", JSV_PIN, &inf.pinRX},
      {"tx", JSV_PIN, &inf.pinTX},
      {"ck", JSV_PIN, &inf.pinCK},
      {"bytesize", JSV_INTEGER, &inf.bytesize},
      {"stopbits", JSV_INTEGER, &inf.stopbits},
      {"parity", JSV_OBJECT /* a variable */, &parity},
      {"flow", JSV_OBJECT /* a variable */, &flow},
  };



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

  bool ok = true;
  if (jsvReadConfigObject(options, configs, sizeof(configs) / sizeof(jsvConfigObject))) {
    // sort out parity
    inf.parity = 0;
    if(jsvIsString(parity)) {
      if (jsvIsStringEqual(parity, "o") || jsvIsStringEqual(parity, "odd"))
        inf.parity = 1;
      else if (jsvIsStringEqual(parity, "e") || jsvIsStringEqual(parity, "even"))
        inf.parity = 2;
    } else if (jsvIsInt(parity)) {
      inf.parity = (unsigned char)jsvGetInteger(parity);
    }
    if (inf.parity>2) {
      jsExceptionHere(JSET_ERROR, "Invalid parity %d", inf.parity);
      ok = false;
    }

    if (ok) {
      if (jsvIsUndefined(flow) || jsvIsNull(flow) || jsvIsStringEqual(flow, "none"))
        inf.xOnXOff = false;
      else if (jsvIsStringEqual(flow, "xon"))
        inf.xOnXOff = true;
      else {
        jsExceptionHere(JSET_ERROR, "Invalid flow control: %q", flow);
        ok = false;
      }
    }

#ifdef LINUX
    if (ok && jsvIsObject(options))
      jsvObjectSetChildAndUnLock(parent, "path", jsvObjectGetChild(options, "path", 0));
#endif
  }
  jsvUnLock(parity);
  jsvUnLock(flow);
  if (!ok) {
    jsvUnLock(options);
    return;
  }

  jshUSARTSetup(device, &inf);
  // Set baud rate in object, so we can initialise it on startup
  jsvObjectSetChildAndUnLock(parent, USART_BAUDRATE_NAME, jsvNewFromInteger(inf.baudRate));
  // Do the same for options
  if (options)
    jsvObjectSetChildAndUnLock(parent, DEVICE_OPTIONS_NAME, options);
  else
    jsvRemoveNamedChild(parent, DEVICE_OPTIONS_NAME);
}