code: function(callback) {
      var ports = [];
      var newPortToDevice = [];
      // get all devices
      var responses = 0;
      var devices = Espruino.Core.Serial.devices;
      if (!devices || devices.length==0) {
           portToDevice = newPortToDevice;
        return callback(ports, false);
      }
      var shouldCallAgain = false;
      devices.forEach(function (device) {
        //console.log("getPorts -->",device.name);
        device.getPorts(function(devicePorts, instantPorts) {
          //console.log("getPorts <--",device.name);
          if (instantPorts===false) shouldCallAgain = true;
          if (devicePorts) {
            devicePorts.forEach(function(port) {
              var ignored = false;
              if (Espruino.Config.SERIAL_IGNORE)
                Espruino.Config.SERIAL_IGNORE.split("|").forEach(function(wildcard) {
                  var regexp = "^"+wildcard.replace(/\./g,"\\.").replace(/\*/g,".*")+"$";
                  if (port.path.match(new RegExp(regexp)))
                    ignored = true;
                });
  
              if (!ignored) {
                if (port.usb && port.usb[0]==0x0483 && port.usb[1]==0x5740)
                  port.description = "Espruino board";
                ports.push(port);
                newPortToDevice[port.path] = device;
              }
            });
          }
          responses++;
          if (responses == devices.length) {
            portToDevice = newPortToDevice;
            ports.sort(function(a,b) {
              if (a.unimportant && !b.unimportant) return 1;
              if (b.unimportant && !a.unimportant) return -1;
              return 0;
            });
            callback(ports, shouldCallAgain);
          }
        });
      });
    }
docs: /* Calls 'callback(port_list, shouldCallAgain)'
  'shouldCallAgain==true' means that more devices
  may appear later on (eg Bluetooth LE).