|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
The rotary knob: an MT6701 magnetic angle sensor on the panel's I2C (Inter-Integrated Circuit) bus, read as relative motion. More...
Go to the source code of this file.
Data Structures | |
| struct | knob_t |
| The state of one knob: its attachment and its reference angle. More... | |
Macros | |
| #define | KNOB_I2C_ADDR 0x06 |
| The MT6701's default 7-bit address. | |
| #define | KNOB_REG_ANGLE_HI 0x03 |
| Angle[13:6], bits 7..0. | |
| #define | KNOB_REG_ANGLE_LO 0x04 |
| Angle[5:0] in bits 7..2; bits 1..0 not used. | |
| #define | KNOB_POLL_READS 3 |
| The reads of one poll, one byte each, in this order: 0x03, 0x04, 0x03. | |
| #define | KNOB_COUNTS 16384 |
| Steps in one turn: 14 bits. | |
| #define | KNOB_POLL_MS 10 |
| Poll period while the sensor answers, and while it does not. | |
| #define | KNOB_POLL_IDLE_MS 100 |
| #define | KNOB_MAX_STEP (KNOB_COUNTS / 4) |
| The largest step between two readings taken as motion: a quarter turn, 90 degrees in KNOB_POLL_MS. | |
| #define | KNOB_SCALE_DEG_DEFAULT 270 |
| Degrees of knob per full slider span; the setting's default and range. | |
| #define | KNOB_SCALE_DEG_MIN 90 |
| #define | KNOB_SCALE_DEG_MAX 720 |
Functions | |
| uint16_t | knob_decode (uint8_t hi, uint8_t lo) |
The datasheet's angle, 0..16383, rising counter-clockwise seen from the chip's top: hi read from KNOB_REG_ANGLE_HI, lo from KNOB_REG_ANGLE_LO. | |
| uint16_t | knob_clockwise (uint16_t angle) |
angle mirrored, rising clockwise seen from the top: 0 stays 0. | |
| bool | knob_attach (knob_t *k, unsigned addr) |
Take addr as the sensor's address and forget the reference. | |
| int | knob_poll_addr (const knob_t *k) |
| The address the next poll reads, or -1 for a knob that is not attached: then no transaction is made. | |
| bool | knob_poll_probe_first (const knob_t *k) |
| Whether the next poll probes the address before its reads: an attached knob with no reference. | |
| void | knob_reset (knob_t *k) |
| Forget the reference: the next usable reading moves nothing. | |
| int | knob_feed (knob_t *k, bool usable, uint16_t raw) |
| Feed one poll. | |
| int | knob_poll_done (knob_t *k, bool answered, const uint8_t bytes[KNOB_POLL_READS]) |
| End one poll. | |
| float | knob_span_fraction (int steps, int scale_deg) |
Fraction of a slider's span that steps moves it when the span is scale_deg degrees of knob. | |
Variables | |
| const uint8_t | knob_poll_regs [KNOB_POLL_READS] |
The rotary knob: an MT6701 magnetic angle sensor on the panel's I2C (Inter-Integrated Circuit) bus, read as relative motion.
Owns no hardware. It names the transactions of one poll, decodes the bytes the panel reads and turns two successive angles into a signed count of steps, so the same code is tested on the host. The panel's task does the bus transactions (firmware/panel/main/knob_task.c).
The knob moves a slider by how far it turns, never to where it points: the first reading after power-up, and after the sensor stopped answering, sets a reference and reports no motion. A knob that stops answering stops contributing.
From the MagnTek MT6701 datasheet, version 1.9 (2024-05), section 7.7:
Direction: the angle rises counter-clockwise seen from the chip's top (figure 27) on the MT6701CT-STD and MT6701QT-STD with DIR, register 0x29 bit 1 in EEPROM, at its default 0 (section 8.1). The knob counts that mirrored, so a clockwise turn seen from the top, the magnet above the chip's top face, raises the throttle. An MT6701CT-STV, whose angle rises clockwise (section 2), a part with DIR = 1, or a sensor seen from below turns the knob the other way. Not checked on hardware.
A missing sensor: a read the sensor does not acknowledge makes the bus driver log three error lines. So a knob without a reference, after power-up or after a read went unanswered, first probes its address, an address byte alone, which the driver does not log, and reads only after an acknowledge (knob_poll_probe_first()).
SPDX-License-Identifier: MIT
| #define KNOB_MAX_STEP (KNOB_COUNTS / 4) |
The largest step between two readings taken as motion: a quarter turn, 90 degrees in KNOB_POLL_MS.
A hand turns a knob at a few degrees per period; a bigger step is a glitch of the bus or the sensor and sets a new reference instead of moving anything.
| #define KNOB_POLL_READS 3 |
The reads of one poll, one byte each, in this order: 0x03, 0x04, 0x03.
The angle is taken only when the first and the last agree.
| bool knob_attach | ( | knob_t * | k, |
| unsigned | addr ) |
Take addr as the sensor's address and forget the reference.
An address the panel board answers at (panel_i2c.h) is refused: the knob stays detached, knob_poll_addr() names no address and nothing is ever sent for it. Returns whether the address was taken.
| k | The knob to attach. |
| addr | The 7-bit sensor address. |
| uint16_t knob_clockwise | ( | uint16_t | angle | ) |
angle mirrored, rising clockwise seen from the top: 0 stays 0.
| angle | The angle, 0 to 16383. |
| uint16_t knob_decode | ( | uint8_t | hi, |
| uint8_t | lo ) |
The datasheet's angle, 0..16383, rising counter-clockwise seen from the chip's top: hi read from KNOB_REG_ANGLE_HI, lo from KNOB_REG_ANGLE_LO.
Bits 1 and 0 of lo are ignored.
| hi | The byte read from KNOB_REG_ANGLE_HI. |
| lo | The byte read from KNOB_REG_ANGLE_LO. |
| int knob_feed | ( | knob_t * | k, |
| bool | usable, | ||
| uint16_t | raw ) |
Feed one poll.
usable false (no answer) forgets the reference. Returns the signed steps since the last usable reading, positive for a rising raw, taking the short way across 16383 to 0; zero for the first reading after a reset, and for a step over KNOB_MAX_STEP, which becomes the new reference.
| k | The knob. |
| usable | false for no answer, which forgets the reference. |
| raw | The angle, 0 to 16383. |
| int knob_poll_addr | ( | const knob_t * | k | ) |
The address the next poll reads, or -1 for a knob that is not attached: then no transaction is made.
| k | The knob. |
| int knob_poll_done | ( | knob_t * | k, |
| bool | answered, | ||
| const uint8_t | bytes[KNOB_POLL_READS] ) |
End one poll.
answered: every read of knob_poll_regs answered, and bytes[i] is what knob_poll_regs[i] gave. Returns the steps, positive clockwise seen from the top; a poll that was not answered, or a knob that is not attached, returns 0 and forgets the reference. A poll whose two 0x03 bytes differ returns 0 and keeps the reference.
| k | The knob. |
| answered | true when every read of knob_poll_regs answered. |
| bytes | The bytes read, one per knob_poll_regs entry. |
| bool knob_poll_probe_first | ( | const knob_t * | k | ) |
Whether the next poll probes the address before its reads: an attached knob with no reference.
A probe that is not acknowledged ends the poll as not answered, with no read made.
| k | The knob. |
| void knob_reset | ( | knob_t * | k | ) |
Forget the reference: the next usable reading moves nothing.
| k | The knob to reset. |
| float knob_span_fraction | ( | int | steps, |
| int | scale_deg ) |
Fraction of a slider's span that steps moves it when the span is scale_deg degrees of knob.
scale_deg outside the setting's range is clamped to it.
| steps | The signed steps moved. |
| scale_deg | Degrees of knob per full slider span. |