'use strict'; import DS5Controller from './ds5-controller.js'; import { sleep, dec2hex32, la, lf } from '../utils.js'; /** * DualSense Edge (DS5 Edge) Controller implementation */ class DS5EdgeController extends DS5Controller { constructor(device) { super(device); this.type = "DS5Edge"; } async getInfo() { // DS5 Edge uses the same info structure as DS5 but with is_edge=true const result = await this._getInfo(true); if (result.ok) { // DS Edge extra module info const empty = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'; try { const sticks_barcode = (await this.getBarcode()).map(barcode => barcode === empty ? this.l("Unknown") : barcode); result.infoItems.push({ key: this.l("Left Module Barcode"), value: sticks_barcode[1], cat: "fw" }); result.infoItems.push({ key: this.l("Right Module Barcode"), value: sticks_barcode[0], cat: "fw" }); } catch(_e) { // ignore module read errors here } } return result; } async flash(progressCallback = null) { la("ds5_edge_flash"); try { const ret = await this.flashModules(progressCallback); if(ret) { return { success: true, message: "" + this.l("Changes saved successfully") + ".

" + this.l("If the calibration is not stored permanently, please double-check the wirings of the hardware mod."), isHtml: true }; } } catch(error) { throw new Error(this.l("Error while saving changes: ") + String(error)); } } async getBarcode() { await this.sendFeatureReport(0x80, [21,34]); await sleep(100); const data = lf("ds5_edge_get_barcode", await this.receiveFeatureReport(0x81)); const td = new TextDecoder(); const r_bc = td.decode(data.buffer.slice(21, 21+17)); const l_bc = td.decode(data.buffer.slice(40, 40+17)); return [r_bc, l_bc]; } async unlockModule(i) { const m_name = i == 0 ? "left module" : "right module"; await this.sendFeatureReport(0x80, [21, 6, i, 11]); await sleep(200); const ret = await this.waitUntilWritten([21, 6, 2]); if(!ret) { throw new Error(this.l("Cannot unlock") + " " + this.l(m_name)); } } async lockModule(i) { const m_name = i == 0 ? "left module" : "right module"; await this.sendFeatureReport(0x80, [21, 4, i, 8]); await sleep(200); const ret = await this.waitUntilWritten([21, 4, 2]); if(!ret) { throw new Error(this.l("Cannot lock") + " " + this.l(m_name)); } } async storeDataInto(i) { const m_name = i == 0 ? "left module" : "right module"; await this.sendFeatureReport(0x80, [21, 5, i]); await sleep(200); const ret = await this.waitUntilWritten([21, 3, 2]); if(!ret) { throw new Error(this.l("Cannot store data into") + " " + this.l(m_name)); } } async flashModules(progressCallback) { la("ds5_edge_flash_modules"); try { progressCallback(0); // Reload data, this ensures correctly writing data in the controller await sleep(100); progressCallback(10); // Unlock modules await this.unlockModule(0); progressCallback(15); await this.unlockModule(1); progressCallback(30); // Unlock NVS await this.nvsUnlock(); await sleep(50); progressCallback(45); // This should trigger write into modules const data = await this.getInMemoryModuleData(); await sleep(50); progressCallback(60); await this.writeFinetuneData(data); // Extra delay await sleep(100); // Lock back modules await this.lockModule(0); progressCallback(80); await this.lockModule(1); progressCallback(100); // Lock back NVS await sleep(100); const lockRes = await this.nvsLock(); if(!lockRes.ok) throw (lockRes.error || new Error("NVS lock failed")); await sleep(250); return true; } catch(error) { la("ds5_edge_flash_modules_failed", {"r": error}); throw error; } } async waitUntilWritten(expected) { for(let it=0;it<10;it++) { const data = await this.receiveFeatureReport(0x81); let again = false for(let i=0;i data.getUint16(4 + i * 2, true)); } async writeFinetuneData(data) { const pkg = data.reduce((acc, val) => acc.concat([val & 0xff, val >> 8]), [12, 1]); await this.sendFeatureReport(0x80, pkg) } } export default DS5EdgeController;