Skip to content

Instantly share code, notes, and snippets.

@daGrevis
Created July 26, 2019 20:01
Show Gist options
  • Save daGrevis/0bc98af20496afa5739f148c9b84d7b7 to your computer and use it in GitHub Desktop.
Save daGrevis/0bc98af20496afa5739f148c9b84d7b7 to your computer and use it in GitHub Desktop.
var serial = {};
function buf2hex(buffer) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
(function() {
'use strict';
serial.status = 0; //disconnected
serial.CP210_VENDOR_WRITE_REQUEST_TYPE = 0x40;
serial.CP210_VENDOR_WRITE_REQUEST = 0x01;
serial.CP210_VENDOR_READ_REQUEST_TYPE = 0xc0;
serial.CP210_VENDOR_READ_REQUEST = 0x01;
serial.CP210_GET_LINE_REQUEST_TYPE = 0xa1;
serial.CP210_GET_LINE_REQUEST = 0x21;
serial.CP210_SET_LINE_REQUEST_TYPE = 0x21;
serial.CP210_SET_LINE_REQUEST = 0x20;
serial.CP210_SET_CONTROL_REQUEST_TYPE = 0x21;
serial.CP210_SET_CONTROL_REQUEST = 0x22;
serial.CP210_BREAK_REQUEST_TYPE = 0x21;
serial.CP210_BREAK_REQUEST = 0x23;
serial.CH341_REQ_READ_VERSION = 0x5F;
serial.CH341_REQ_WRITE_REG = 0x9A;
serial.CH341_REQ_READ_REG = 0x95;
serial.CH341_REQ_SERIAL_INIT = 0xA1;
serial.CH341_REQ_MODEM_CTRL = 0xA4;
serial.CH341_REG_BREAK = 0x05;
serial.CH341_REG_LCR = 0x18;
serial.CH341 = 0x1;
serial.CP201 = 0x2;
//CH341
//https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/serial/ch341.c?h=v5.3-rc1
//cp210
//https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/serial/cp210x.c?h=v5.3-rc1
//requestType standard/class/vendor 0=standard, 1=class, 2=vendor, 3=reserved)
//recipient device/inteface/endpoint/other 0=device, 1=interface, 2=endpoint,3=other)
serial.getPorts = async function() {
const devices = await navigator.usb.getDevices();
return devices.map(device => new serial.Port(device));
};
serial.requestPort = async function() {
const filters = [
{ vendorId:0x067b, productId:0x2303 }, //cp210
{ vendorId:0x1a86, productId:0x7523 }, //ch341
];
const device = await navigator.usb.requestDevice({ 'filters': filters });
return new serial.Port(device);
}
serial.Port = function(device) {
this.device = device;
if ((device.vendorId == 0x067b) && (device.productId == 0x2303))
{
this.device.t = serial.CP201;
}
if ((device.vendorId == 0x1a86) && (device.productId == 0x7523))
{
this.device.t = serial.CH341;
}
};
serial.Port.prototype.connect = async function(){
try {
await this.device.open();
if (this.device.configuration === null) {
return this.device.selectConfiguration(1);
}
await this.device.claimInterface(0);
await this.device.selectAlternateInterface(0,0);
} catch (e) {
console.log("ERROR "+e);
}
};
serial.Port.prototype.claim = async function(i) {
try {
await this.device.claimInterface(i)
} catch (e) {
console.log("ERROR "+e);
}
}
serial.Port.prototype.close = function() {
return this.device.close();
}
serial.Port.prototype.reset = function() {
return this.device.reset();
}
serial.Port.prototype.disconnect = async function() {
try {
await this.device_.controlTransferOut({
'requestType': 'class',
'recipient': 'interface',
'request': 0x22,
'value': 0x00,
'index': 0x02,
});
} catch (e) {
await this.device.close();
}
};
serial.Port.prototype.send = function(data) {
return this.device.transferOut(4, data);
};
serial.Port.prototype.vendorWrite = function(value,index) {
console.log("Write idx "+index+" val = "+value)
return this.device.controlTransferOut({
'requestType': 'vendor',
'recipient': 'device',
'request': serial.VENDOR_WRITE_REQUEST,
'value': value,
'index': index,
});
};
serial.Port.prototype.vendorRead = function(value) {
console.log("Read val="+value);
return this.device.controlTransferIn({
'requestType': 'vendor',
'recipient': 'device',
'request':serial.VENDOR_READ_REQUEST,
'value':value,
'index':0,
},1);
};
serial.Port.prototype.checkDevice = function() {
};
serial.Port.prototype.patchDevice = function() {
};
serial.Port.prototype.getLineRequest = function() {
console.log("Get line request");
return this.device.controlTransferIn({
'requestType': 'class',
'recipient': 'interface',
'request':serial.GET_LINE_REQUEST,
'value':0,
'index':0,
},7);
};
serial.Port.prototype.setLineRequest = function() {
console.log("Set line request");
return this.device.controlTransferOut({
'requestType': 'class',
'recipient': 'interface',
'request':serial.SET_LINE_REQUEST,
'value':0,
'index':0,
},7);
};
serial.Port.prototype.setControlRequest = function() {
console.log("Set control request");
return this.device.controlTransferOut({
'requestType': 'class',
'recipient': 'interface',
'request':serial.SET_CONTROL_REQUEST,
'value':0,
'index':0,
},7);
};
serial.Port.prototype.breakRequest = function() {
console.log("Break request");
return this.device.controlTransferOut({
'requestType': 'class',
'recipient': 'interface',
'request':serial.BREAK_REQUEST,
'value':0,
'index':0,
},7);
};
serial.Port.prototype.EncodeBaudRate = function() {
};
//https://gist.github.com/fe1320e2539ce9afc529f51cce656bae
serial.Port.prototype.init = async function() {
try {
await this.vendorRead( 0x8484)
await this.vendorWrite(0x0404 , 0)
await this.vendorRead( 0x8484)
await this.vendorRead( 0x8383)
await this.vendorRead( 0x8484)
await this.vendorWrite(0x0404 , 1)
await this.vendorRead( 0x8484)
await this.vendorRead( 0x8383)
await this.vendorWrite(0 , 1)
await this.vendorWrite(1 , 0)
await this.vendorWrite(2 , 0x24)
console.log("Done "+r);
} catch (e) {
console.log("Error "+e); // 2,0x44
}
};
serial.Port.prototype.CH341controlIn = function() {
console.log("CH341controlIn");
return this.device.controlTransferIn({
'requestType': 'vendor',
'recipient': 'device',
'request':serial.GET_LINE_REQUEST,
'value':0,
'index':0,
},7);
};
serial.Port.prototype.CH341controlOut = function() {
console.log("CH341controlOut");
return this.device.controlTransferOut({
'requestType': 'vendor',
'recipient': 'device',
'request':serial.BREAK_REQUEST,
'value':0,
'index':0,
},7);
};
serial.Port.prototype.CH341configure = async function() {
console.log("CH341configure");
let res1
try {
console.log(res1);
res1 = await this.device.controlTransferIn({
'requestType': 'vendor',
'recipient': 'device',
'request':serial.CH341_REQ_READ_VERSION,
'value':0,
'index':0,
},2)
} catch (e) {
console.log(e);
}
var bufOut = new ArrayBuffer(2);
bufOut[0] = 0;
console.log("CH341_REQ_SERIAL_INIT")
let res2
try {
res2 = await this.device.controlTransferOut({
'requestType': 'vendor',
'recipient': 'device',
'request':serial.CH341_REQ_SERIAL_INIT,
'value':0,
'index':0,
})
console.log(res2);
} catch (e) {
console.log(e)
}
//console.log(buf2hex(res2.));
//return res2;
};
serial.Port.prototype.CH341setHandshake = function() {
};
serial.Port.prototype.CH341getStatus = async function() {
console.log("CH341getStatus");
let res1
try {
await this.device.controlTransferIn({
'requestType': 'vendor',
'recipient': 'device',
'request':serial.CH341_REQ_READ_REG,
'value':0x0706,
'index':0,
},2)
console.log(res1);
} catch (e) {
console.log(e);
}
return res1;
};
serial.Port.prototype.CH341getStatus2 = async function() {
var dev = this.device;
try {
console.log("CH341getStatus");
let res = await dev.controlTransferIn({
'requestType': 'vendor',
'recipient': 'device',
'request':serial.CH341_REQ_READ_REG,
'value':0x0706,
'index':0,
},2);
console.log(res);
return res;
} catch (err) {
console.log(err);
}
};
//serial.Port.prototype.CH341getStatus2
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment