Skip to main content

I2C and Registers

I2C (Inter-Integrated Circuit), also known as TWI (Two-Wire Interface), is a communication protocol that allows multiple devices to talk over just two shared signal lines:

  • SDA (Serial Data): carries the data
  • SCL (Serial Clock): keeps everything in sync

On the bus, one device acts as the controller (your expansion board) and the other as a peripheral (the moddoMOUSE Main Board). The controller drives the clock and initiates all transactions whereas the peripheral only responds when addressed.

Addressing

Every I2C peripheral has a unique 7-bit address that the controller uses to identify it on the bus. The moddoMOUSE Main Board always responds at address 0x0A. Since the Front and Back boards are on separate I2C buses (I2C0 and I2C1), there is no address conflict even though both buses use the same address.

Registers

The moddoMOUSE Main Board exposes its data and settings through a register map which is a list of memory locations, each holding a specific piece of information. Registers are addressed sequentially starting at index 0, and the Main Board supports sequential (burst) reads and writes, meaning you can read or write multiple consecutive registers in a single I2C transaction rather than one at a time.

RegisterNameDescription
0x00DEVICE_ID (low)Unique device identifier (low byte)
0x01DEVICE_ID (high)Unique device identifier (high byte)
0x02PROD_IDProduct ID (always 0x01 for moddoMOUSE)
0x03STATUSNot currently used
0x04BATTERY_VOLTAGE (low)Battery voltage in mV (low byte)
0x05BATTERY_VOLTAGE (high)Battery voltage in mV (high byte)
0x06BATTERY_CAPACITYBattery capacity in percent (0–100), or 255 if unknown
0x07BATTERY_CHARGER_STATUSCharger and battery status flags
0x08MOUSE_SETTINGSPolling rate, invert X/Y, swap XY
0x09MOUSE_X (low)Accumulated X motion delta (low byte)
0x0AMOUSE_X (high)Accumulated X motion delta (high byte)
0x0BMOUSE_Y (low)Accumulated Y motion delta (low byte)
0x0CMOUSE_Y (high)Accumulated Y motion delta (high byte)
0x0DANGLE_TUNEAngle tune offset (–30 to +30 degrees)
0x0EMAIN_BUTTONSMain button states (left, right, middle, back, forward)
0x0FV_WHEELVertical scroll wheel accumulated delta
0x10H_WHEELHorizontal scroll wheel accumulated delta
0x11INT_ENInterrupt enable flags
0x12LIFT_DISTANCELift-off distance setting (1mm or 2mm)
0x13CPI_X (low)X-axis DPI/CPI (low byte)
0x14CPI_X (high)X-axis DPI/CPI (high byte)
0x15CPI_Y (low)Y-axis DPI/CPI (low byte)
0x16CPI_Y (high)Y-axis DPI/CPI (high byte)
0x17EXP_BOARD_BUTTONS_0Expansion board buttons (bits 0–7)
0x18EXP_BOARD_BUTTONS_1Expansion board buttons (bits 8–15)
0x19EXP_BOARD_BUTTONS_2Expansion board buttons (bits 16–23)
0x1AEXP_BOARD_BUTTONS_3Expansion board buttons (bits 24–31)

💡 Motion (X/Y) and scroll wheel registers accumulate their values until read. Reading them resets the accumulator, so you always get the delta since the last read rather than an instantaneous snapshot.

Interrupt Pin (INT)

Rather than constantly polling the Main Board for updates, your expansion board can wait for the INT pin to signal that something has changed. The Main Board will assert INT when any of the following enabled events occur:

  • Mouse motion detected
  • Main button state changed
  • Scroll wheel moved
  • Battery status changed
  • A fault condition occurred

Interrupt sources are individually enabled or disabled via the INT_EN register. When an interrupt fires, you read the relevant register(s) to clear it.