Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal workings #2

Open
MohrJonas opened this issue Jun 24, 2023 · 5 comments
Open

Internal workings #2

MohrJonas opened this issue Jun 24, 2023 · 5 comments

Comments

@MohrJonas
Copy link

I'm trying to adapt this software to a DIY spacemouse and was wondering if you could elaborate on the internal workings a bit more.
Looking at the source code, descriptors.c seems pretty clear to me. As far as I understand it, it defines the USB manufacturer, model and some other stuff.
My understanding of magellan.c is the following:

  • It sets up UART, USB and GPIO pins
  • What does this do? 🤔
    uint8_t init_buf[] = { '\r', 'v', 'Q', '\r', 'm', '3', '\r' };
    uart_write_blocking(SERIAL_MOUSE_UART, init_buf, sizeof(init_buf));
  • In the infinite loop, it calls tinyusb's tud_task() function to do some USB-related stuff
  • It then checks in
    if (trans_pending && tud_hid_ready()) {
    if (rot_pending && tud_hid_ready()) {
    if (buttons_pending && tud_hid_ready()) {
    if a translation, rotation or button press has occured that has to be reported via USB
  • After that, it reads a char from UART and that's basically where my understanding stops. Could you therefore please elaborate what this does?
    buf[idx] = c;
    idx = (idx + 1) % sizeof(buf);
    printf("%c", c);
    if (c == '\r') {
    printf("\n");
    switch (buf[0]) {
    case 'd': {
    if (idx != 26) {
    break;
    }
    int16_t values[6];
    for (int i = 0; i < 6; i++) {
    values[i] = -32768;
    for (int j = 0; j < 4; j++) {
    values[i] += (buf[1 + i * 4 + 3 - j] & 0xf) << (4 * j);
    }
    printf("%d %d ", i, values[i]);
    }
    printf("\n");
    trans_report[0] = values[0];
    trans_report[1] = values[2];
    trans_report[2] = -values[1];
    rot_report[0] = values[3];
    rot_report[1] = values[5];
    rot_report[2] = -values[4];
    trans_pending = 1;
    rot_pending = 1;
    break;
    }
    case 'k': {
    if (idx != 5) {
    break;
    }
    uint16_t buttons = 0;
    for (int i = 0; i < 3; i++) {
    buttons |= (buf[1 + i] & 0x0f) << (4 * i);
    }
    printf("%04x\n", buttons);
    memset(buttons_report, 0, sizeof(buttons_report));
    for (int i = 0; i < 12; i++) {
    if (buttons & (1 << i)) {
    buttons_report[button_bits[i] / 8] |= 1 << (button_bits[i] % 8);
    }
    }
    buttons_pending = 1;
    }
    default:
    break;
    }
    idx = 0;
    }
    }
    }
    return 0;
    }

    Thank you in advance 😀
@jfedor2
Copy link
Owner

jfedor2 commented Jun 24, 2023

That's the serial protocol that the legacy device speaks (the one we're adapting). If you're making your own it's not really relevant to you. You'll be reading the data from whatever sensors your device has instead.

@MohrJonas
Copy link
Author

Alright, thank you for that information.
What data does the trans_report, rot_report and buttons_report expect?

@jfedor2
Copy link
Owner

jfedor2 commented Jun 24, 2023

The translations and rotations are 16-bit signed values (though only -350..+350 range is used I think), one for each axis. Buttons are one bit per button, though not all of them are actually used. button_bits has some bit positions that are definitely mapped to something on a SpaceMouse Pro.

@MohrJonas
Copy link
Author

Awesome, thanks for the answer 😀
Are these values absolute or relative to the previous one, meaning if, for example, the X axis is rotated 20 degrees and is then rotated to 25 degrees, do you report 25 degrees (the absolute value) or 5 degrees (because that's the relative change that has occurred)?

@jfedor2
Copy link
Owner

jfedor2 commented Jun 24, 2023

They are absolute (despite the fact that the report descriptor says they're relative).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants