ds4_calibrate_sticks_end bug? #39

Closed
opened 2026-02-10 18:43:55 +03:00 by OVERLORD · 2 comments
Owner

Originally created by @raingart on GitHub (Apr 25, 2025).

Hi,

I'm currently working on refactoring the JavaScript ver of the DS4/DS5 calibration tool and trying to ensure the low-level hardware communication logic is accurate.

I've encountered a potentially confusing part in the ds4_calibrate_sticks_end function in the original JavaScript code:

async function ds4_calibrate_sticks_end(has_perm_changes) {
    // ... error setup ...
    try {
        // Send the "Write" command for stick calibration
        await device.sendFeatureReport(0x90, alloc_req(0x90, [2,1,1])) // Command [2,1,1]

        // Check the result?
        // This 'if' condition seems to use 'data' and 'data2' variables
        // which were likely populated during the *previous* 'sample' step.
        // It checks against the values expected after a SAMPLE command (0x91010101, 0x920101FF).
        if(data.getUint32(0, false) != 0x91010101 || data2.getUint32(0, false) != 0x920101FF) {
            d1 = dec2hex32(data.getUint32(0, false));
            d2 = dec2hex32(data2.getUint32(0, false));
            la("ds4_calibrate_sticks_end_failed", {"d1": d1, "d2": d2});
            show_popup(err + l("Error 3") + " (" + d1 + ", " + d2 + " at i=" + i + ")"); // Also uses global 'i'?
            return false;
        }

        // Continue with NV lock if needed...
        if(has_perm_changes) {
            await ds4_nvlock();
            if(await ds4_nvstatus() != 1) {
                // ... handle NVS lock error ...
                return false;
            }
        }
        return true;
    } catch(e) {
        // ... error handling ...
        return false;
    }
}

he confusing part is the if condition after sending the Write command ([2,1,1]). It appears to check the results (data, data2) from the previous Sample command ([3,1,1]) against the expected Sample success codes (0x91010101, 0x920101FF). This seems counter-intuitive, as it doesn't seem to validate the result of the Write command itself.

For comparison, the ds5_calibrate_sticks_end function does read a new report (0x83) after its Write command ([2,1,1]) and checks for a specific "Write success" code (0x83010102).

Could you please clarify the intended logic here for the DS4?

  1. Is checking the result of the previous Sample step after the Write command intentional? If so, what is the reason?
  2. Or is this potentially a bug/typo, and maybe this check should be removed, or perhaps new reports (0x91, 0x92) should be read and validated after the DS4 Write command?
  3. If new reports should be read after the DS4 Write command ([2,1,1]), do you happen to know what success values/status codes are expected in the 0x91 and 0x92 reports? (Similar to how DS5 expects 0x83010102 in its 0x83 report).

Any insight you could provide would be extremely helpful for ensuring the refactored version behaves correctly.

Thank you for your time and for creating this useful tool!

Originally created by @raingart on GitHub (Apr 25, 2025). Hi, I'm currently working on refactoring the JavaScript ver of the DS4/DS5 calibration tool and trying to ensure the low-level hardware communication logic is accurate. I've encountered a potentially confusing part in the ds4_calibrate_sticks_end function in the original JavaScript code: ``` async function ds4_calibrate_sticks_end(has_perm_changes) { // ... error setup ... try { // Send the "Write" command for stick calibration await device.sendFeatureReport(0x90, alloc_req(0x90, [2,1,1])) // Command [2,1,1] // Check the result? // This 'if' condition seems to use 'data' and 'data2' variables // which were likely populated during the *previous* 'sample' step. // It checks against the values expected after a SAMPLE command (0x91010101, 0x920101FF). if(data.getUint32(0, false) != 0x91010101 || data2.getUint32(0, false) != 0x920101FF) { d1 = dec2hex32(data.getUint32(0, false)); d2 = dec2hex32(data2.getUint32(0, false)); la("ds4_calibrate_sticks_end_failed", {"d1": d1, "d2": d2}); show_popup(err + l("Error 3") + " (" + d1 + ", " + d2 + " at i=" + i + ")"); // Also uses global 'i'? return false; } // Continue with NV lock if needed... if(has_perm_changes) { await ds4_nvlock(); if(await ds4_nvstatus() != 1) { // ... handle NVS lock error ... return false; } } return true; } catch(e) { // ... error handling ... return false; } } ``` he confusing part is the if condition after sending the Write command ([2,1,1]). It appears to check the results (data, data2) from the previous Sample command ([3,1,1]) against the expected Sample success codes (`0x91010101`, `0x920101FF`). This seems counter-intuitive, as it doesn't seem to validate the result of the Write command itself. For comparison, the `ds5_calibrate_sticks_end` function does read a new report (`0x83`) after its Write command ([2,1,1]) and checks for a specific "Write success" code (`0x83010102`). Could you please clarify the intended logic here for the DS4? 1. Is checking the result of the previous Sample step after the Write command intentional? If so, what is the reason? 2. Or is this potentially a bug/typo, and maybe this check should be removed, or perhaps new reports (`0x91`, `0x92`) should be read and validated after the DS4 Write command? 3. If new reports should be read after the DS4 Write command ([2,1,1]), do you happen to know what success values/status codes are expected in the `0x91` and `0x92` reports? (Similar to how DS5 expects `0x83010102` in its `0x83` report). Any insight you could provide would be extremely helpful for ensuring the refactored version behaves correctly. Thank you for your time and for creating this useful tool!
Author
Owner

@dualshock-tools commented on GitHub (May 2, 2025):

Hi, you found a bug, thank you! The lines:

        data = await device.receiveFeatureReport(0x91);
        data2 = await device.receiveFeatureReport(0x92);

are missing from that function and should be there. Will fix that soon!

  1. No it was not intentional, it should check if the last command is executed correctly or failed.
  2. Yup that's a typo
  3. Not sure, will check on my DS4
@dualshock-tools commented on GitHub (May 2, 2025): Hi, you found a bug, thank you! The lines: ``` data = await device.receiveFeatureReport(0x91); data2 = await device.receiveFeatureReport(0x92); ``` are missing from that function and should be there. Will fix that soon! 1. No it was not intentional, it should check if the last command is executed correctly or failed. 2. Yup that's a typo 3. Not sure, will check on my DS4
Author
Owner

@dualshock-tools commented on GitHub (May 2, 2025):

Should be fixed!

@dualshock-tools commented on GitHub (May 2, 2025): Should be fixed!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dualshock-tools/dualshock-tools.github.io#39