|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
The register models of Hitec servos: images, the parameter table, encodings, model identification and write plans. More...
Data Structures | |
| struct | pair_t |
| A decoded value and the raw value it is stored as. More... | |
| struct | pairs_t |
| The pair table of an encoding and its length. More... | |
| struct | model_row_t |
| One known model. More... | |
| struct | d_item_t |
| A register a D series setting writes. More... | |
Macros | |
| #define | ROW(id, lay, addr, addr2, size, enc, unit, acc, src, step, min, max) |
| Row of the table: one layout. | |
| #define | D_RAW(id, addr, src) |
| A read-only D series register shown raw. | |
| #define | LD HITEC_LAYOUT_BIT(HITEC_LAYOUT_D) |
| #define | L5 HITEC_LAYOUT_BIT(HITEC_LAYOUT_HS5) |
| #define | L7 HITEC_LAYOUT_BIT(HITEC_LAYOUT_HS7) |
| #define | LC ((uint8_t)(L5 | L7)) |
| #define | NO HITEC_ADDR_NONE |
| #define | RO HITEC_RO |
| #define | RW HITEC_RW |
| #define | SR HITEC_SRC_RCBENCH |
| #define | SC HITEC_SRC_CAPTURED |
| #define | SD HITEC_SRC_READ |
| #define | ROW_COUNT (sizeof(k_rows) / sizeof(k_rows[0])) |
| Rows in k_rows. | |
| #define | D_OP_DIRECTION 1u |
| The direction's setting in k_d_ops. | |
| #define | D_OP_COUNT (sizeof(k_d_ops) / sizeof(k_d_ops[0])) |
| Settings in k_d_ops. | |
| #define | D_ITEM_COUNT (sizeof(k_d_ops[0]) / sizeof(k_d_ops[0][0])) |
| Items of one setting. | |
Enumerations | |
| enum | { ENC_RAW = 0 , ENC_D_ID , ENC_D_POS , ENC_D_DIR , ENC_STEP5 , ENC_D_SPEED , ENC_D_FS , ENC_D_SOFT , ENC_OVERLOAD , ENC_D_SMART , ENC_C_VERSION , ENC_C_DATE , ENC_C_SERIAL , ENC_C_SUM , ENC_C_SPEED , ENC_C_CENTRE5 , ENC_C_CENTRE7 , ENC_C_END , ENC_C_DIR , ENC_C_FS , ENC_C_FSPOS5 , ENC_C_OVL5 , ENC_C_OVL7 , ENC_C_RES } |
| Encodings of the rows. More... | |
| enum | { D_IMG = 0 , D_TRIG , D_CONST } |
| How a D series setting writes a register. More... | |
Functions | |
| void | hitec_image_init (hitec_image_t *img, uint8_t series) |
Empty an image of series: no byte known, no version. | |
| static void | mark (hitec_image_t *img, unsigned addr) |
Mark byte addr known. | |
| bool | hitec_image_put_cell (hitec_image_t *img, uint8_t cell, uint8_t value) |
| Store a classic cell as read. | |
| bool | hitec_image_put_reg (hitec_image_t *img, uint8_t addr, uint16_t value) |
| Store a D series register as read. | |
| bool | hitec_image_put_version (hitec_image_t *img, uint8_t version) |
| Store the classic reply to the first command (0x67). | |
| static void | unmark (hitec_image_t *img, unsigned addr) |
Clear the known bit of byte addr. | |
| bool | hitec_image_forget (hitec_image_t *img, uint8_t addr) |
| Mark a cell or a D series register as not known: the servo may hold another value than the image. | |
| bool | hitec_image_known (const hitec_image_t *img, uint8_t addr) |
True when byte addr was read. | |
| uint8_t | hitec_image_cell (const hitec_image_t *img, uint8_t cell) |
| A classic cell; 0 for NULL. | |
| uint16_t | hitec_image_reg (const hitec_image_t *img, uint8_t addr) |
| A D series register; 0 for NULL or an odd address. | |
| static bool | known_run (const hitec_image_t *img, unsigned first, unsigned count) |
True when count bytes from first are known. | |
| static void | put_be16 (hitec_image_t *img, uint8_t cell, unsigned value) |
| Store a classic value of 2 cells, high byte first. | |
| static unsigned | be16 (const hitec_image_t *img, uint8_t cell) |
| A classic value of 2 cells, high byte first. | |
| static void | put_reg (hitec_image_t *img, uint8_t addr, unsigned value) |
| Store a D series register in a draft. | |
| const uint8_t * | hitec_d_read_list (size_t *n) |
| The D series registers a full read takes: the 19 the HFP-30 reads, less 0x6E (write only), plus the model 0x00, the position 0x0C and 0x22. | |
| const hitec_range_t * | hitec_c_read_ranges (size_t *n) |
| The classic cells a full read takes: 0x00 to 0x23, the factory block 0x30 to 0x53, the name 0x60 to 0x6F, the date 0x70 to 0x73 and the serial 0x80 to 0x87, 100 cells. | |
| static uint8_t | sum_cells (const uint8_t *mem, unsigned count) |
Sum of count cells from 0x00 of mem, modulo 256. | |
| uint8_t | hitec_c_eeprom_sum (const hitec_image_t *img) |
| Sum of classic cells 0x00 to 0x1C modulo 256; 0 is a good image. | |
| uint8_t | hitec_c_balance (const hitec_image_t *img) |
| The value of cell 0x1C that makes cells 0x00 to 0x1C sum to 0. | |
| bool | hitec_c_rebalance (hitec_image_t *img) |
| Write the balance into cell 0x1C of a classic draft. | |
| bool | hitec_d_mirror (uint16_t pos, uint16_t *out) |
| A D series position mirrored by a direction change: 16384 less the position, as the HFP-30 writes it. | |
| uint8_t | hitec_layout_series (uint8_t layout) |
| The series of a layout. | |
| static void | take_model (hitec_model_t *out, uint8_t model) |
Fill out from row model of k_models. | |
| bool | hitec_identify (const hitec_image_t *img, hitec_model_t *out) |
| Identify the model from a read image. | |
| const char * | hitec_model_name (uint8_t model) |
| The model's name as Hitec writes it, "D485HW", "HS-5645MG"; "" for the OTHER and NONE models. | |
| const hitec_param_info_t * | hitec_param (uint8_t layout, uint8_t id) |
The row of id for layout; NULL when the layout has no such parameter. | |
| static const hitec_param_info_t * | row_for (const hitec_image_t *img, uint8_t layout, uint8_t id) |
The row of id for an image of layout; NULL for a bad argument or an image of the other series. | |
| static pairs_t | pairs_of (uint8_t enc) |
The pair table of encoding enc; an empty one for an encoding without. | |
| static uint8_t | end_cell (const hitec_image_t *img, const hitec_param_info_t *p) |
The cell a classic end point is in: addr on a CW servo, addr2 on a CCW one. | |
| static unsigned | quarter_offset (uint8_t enc) |
| The 0.25us a classic position adds to its stored value. | |
| static uint32_t | raw_of (const hitec_image_t *img, const hitec_param_info_t *p) |
The stored value of row p: the register, the cells high byte first, or the value cell. | |
| static bool | known_for_get (const hitec_image_t *img, const hitec_param_info_t *p) |
True when the bytes a decode of p reads are known; the smart sensor's 0x8A and 0x8C are checked where they are compared. | |
| static hitec_get_t | from_pairs (pairs_t t, uint32_t raw, hitec_value_t *out) |
| Look a raw value up in a pair table. | |
| static hitec_get_t | fit (bool fits, int32_t value, hitec_value_t *out) |
OK with value when fits, else RAW with the raw value. | |
| static hitec_get_t | get_date (const hitec_image_t *img, hitec_value_t *out) |
| Decode the date cells: day, month, year high byte first. | |
| static hitec_get_t | get_serial (const hitec_image_t *img, hitec_value_t *out) |
| Decode the serial digits. | |
| static hitec_get_t | get_smart (const hitec_image_t *img, hitec_value_t *out) |
| Decode the smart sensor: on is 0x6C = 0x44 = 0, off is 0x6C = 0x8A and 0x44 = 0x8C. | |
| static hitec_get_t | decode (const hitec_image_t *img, const hitec_param_info_t *p, hitec_value_t *out) |
Decode row p of a checked image. | |
| hitec_get_t | hitec_param_get (const hitec_image_t *img, uint8_t layout, uint8_t id, hitec_value_t *out) |
| Decode a parameter. | |
| static bool | value_ok (const hitec_param_info_t *p, int32_t v) |
True when v is a value an edit of row p takes. | |
| bool | hitec_param_ok (uint8_t layout, uint8_t id, int32_t value) |
True when value is a value an edit of id takes. | |
| int32_t | hitec_param_clamp (uint8_t layout, uint8_t id, int32_t value) |
The nearest value an edit of id takes. | |
| static uint16_t | to_raw (pairs_t t, int32_t v) |
The raw value of v in pair table t: the first pair that shows it. value_ok() has checked that one does. | |
| static bool | known_for_set (const hitec_image_t *img, const hitec_param_info_t *p) |
True when the bytes an edit of p reads or writes are known, beyond those of its decode. | |
| static hitec_set_t | set_d_pos (hitec_image_t *d, const hitec_param_info_t *p, int32_t v) |
| Edit a D series position and keep left end < neutral < right end; the other two positions must fit the encoding. | |
| static hitec_set_t | set_d_dir (hitec_image_t *d, int32_t v) |
| Edit the D series direction: 0x5E and the three positions mirrored, the ends swapped. From a 0x5E that is neither 0 nor 1 the servo's direction is not known: 0x5E alone. | |
| static void | set_c_dir (hitec_image_t *d, int32_t v) |
| Edit the classic direction: 0x1B bit 0, the end points swapped, the fail-safe position from the factory block. | |
| static hitec_set_t | encode (hitec_image_t *d, const hitec_param_info_t *p, int32_t v) |
Encode v into a draft with its side effects; the draft is checked and v is a value of the row. | |
| hitec_set_t | hitec_param_set (hitec_image_t *img, uint8_t layout, uint8_t id, int32_t value) |
Edit a draft: encode value and write its side effects. | |
| bool | hitec_c_factory (hitec_image_t *img) |
| Classic factory reset on a draft: cells 0x00 to 0x23 from the factory block 0x30 to 0x53, then the balance. | |
| bool | hitec_writable (uint8_t series, uint8_t addr) |
True when a plan writes addr of series. | |
| static void | push (hitec_plan_t *out, uint8_t kind, uint8_t addr, uint16_t value, uint16_t wait_ms) |
Append a write to out. | |
| static hitec_plan_result_t | plan_c (const hitec_image_t *from, const hitec_image_t *to, hitec_plan_t *out) |
| The classic plan; both images are classic. | |
| static bool | d_op_changed (const hitec_image_t *from, const hitec_image_t *to, size_t op, bool *unknown) |
True when a trigger of D series setting op differs; false with *unknown set when one is known in the draft only. | |
| static bool | d_item_written (const hitec_image_t *from, size_t op, const d_item_t *it) |
True when a plan from from writes item it of setting op: from a direction that is neither 0 nor 1 the direction's setting writes 0x5E alone. | |
| static hitec_plan_result_t | plan_d (const hitec_image_t *from, const hitec_image_t *to, hitec_plan_t *out) |
| The D series plan; both images are D series. | |
| hitec_plan_result_t | hitec_plan (const hitec_image_t *from, const hitec_image_t *to, hitec_plan_t *out) |
The writes that take a servo from image from to to. | |
| void | hitec_d_factory_plan (hitec_plan_t *out) |
| The D series factory reset: 0x6E = 0x0F0F, save, reboot, as the HFP-30 writes it. | |
Variables | |
| static const pair_t | k_step5 [] |
| Dead band steps, HPP-21 Plus and D series. | |
| static const pair_t | k_d_speed [] |
| HFP-30 speed: 5% a count; the factory 4095 shows as 100%. | |
| static const pair_t | k_d_soft [] |
| HFP-30 soft start. | |
| static const pair_t | k_overload [] |
| Overload protection, HFP-30 and HPP-21 Plus alike. | |
| static const pair_t | k_c_speed [] |
| HPP-21 Plus speed. | |
| static const pair_t | k_c_res [] |
| HPP-21 Plus resolution; the factory 0x0B shows as High. | |
| static const pair_t | k_d_dir [] |
| A D series direction. | |
| static const hitec_param_info_t | k_rows [] |
| The parameter table. | |
| static const model_row_t | k_models [HITEC_MODEL_COUNT] |
| In the order of hitec_model_id_t. | |
| static const uint8_t | k_d_read [] |
| The D series registers of a full read. | |
| static const hitec_range_t | k_c_read [] |
| The classic cells of a full read. | |
| static const uint8_t | k_c_ops [][2] |
| The HPP-21 Plus's settings: first cell and count, in its order. | |
| static const d_item_t | k_d_ops [][6] |
| The HFP-30's settings, in order, each ending at a 0 address. | |
The register models of Hitec servos: images, the parameter table, encodings, model identification and write plans.
Sources of the tables, by mark of hitec_src_t:
The D series dead band steps 1 and 5 are captured from the HFP-30; steps 2 to 4 (4, 8, 12) are the DPC-11's on a D485HW as HitecDServo reports them, and equal the HPP-21 Plus's classic steps.
SPDX-License-Identifier: MIT
| #define D_RAW | ( | id, | |
| addr, | |||
| src ) |
A read-only D series register shown raw.
| #define L5 HITEC_LAYOUT_BIT(HITEC_LAYOUT_HS5) |
HS-5xxx
| #define L7 HITEC_LAYOUT_BIT(HITEC_LAYOUT_HS7) |
HS-7xxx
| #define LD HITEC_LAYOUT_BIT(HITEC_LAYOUT_D) |
D series
| #define NO HITEC_ADDR_NONE |
no second address
| #define RO HITEC_RO |
read only
| #define ROW | ( | id, | |
| lay, | |||
| addr, | |||
| addr2, | |||
| size, | |||
| enc, | |||
| unit, | |||
| acc, | |||
| src, | |||
| step, | |||
| min, | |||
| max ) |
Row of the table: one layout.
| #define RW HITEC_RW |
writable
| #define SC HITEC_SRC_CAPTURED |
captured write
| #define SD HITEC_SRC_READ |
read only on a servo
| #define SR HITEC_SRC_RCBENCH |
rcbench write
| anonymous enum |
| anonymous enum |
Encodings of the rows.
| uint8_t hitec_c_balance | ( | const hitec_image_t * | img | ) |
The value of cell 0x1C that makes cells 0x00 to 0x1C sum to 0.
| img | Classic image; NULL gives 0. |
| uint8_t hitec_c_eeprom_sum | ( | const hitec_image_t * | img | ) |
Sum of classic cells 0x00 to 0x1C modulo 256; 0 is a good image.
| img | Classic image; NULL gives 0. |
| bool hitec_c_factory | ( | hitec_image_t * | img | ) |
Classic factory reset on a draft: cells 0x00 to 0x23 from the factory block 0x30 to 0x53, then the balance.
| img | Classic draft. |
| const hitec_range_t * hitec_c_read_ranges | ( | size_t * | n | ) |
The classic cells a full read takes: 0x00 to 0x23, the factory block 0x30 to 0x53, the name 0x60 to 0x6F, the date 0x70 to 0x73 and the serial 0x80 to 0x87, 100 cells.
| n | Receives the count of runs, 5; may be NULL. |
| bool hitec_c_rebalance | ( | hitec_image_t * | img | ) |
Write the balance into cell 0x1C of a classic draft.
| img | Classic image. |
| void hitec_d_factory_plan | ( | hitec_plan_t * | out | ) |
The D series factory reset: 0x6E = 0x0F0F, save, reboot, as the HFP-30 writes it.
| out | Receives the plan; NULL does nothing. |
| bool hitec_d_mirror | ( | uint16_t | pos, |
| uint16_t * | out ) |
A D series position mirrored by a direction change: 16384 less the position, as the HFP-30 writes it.
| pos | Position, 1 to HITEC_D_POS_MAX. |
| out | Receives the mirrored position. |
out: the mirror would leave the range. | const uint8_t * hitec_d_read_list | ( | size_t * | n | ) |
The D series registers a full read takes: the 19 the HFP-30 reads, less 0x6E (write only), plus the model 0x00, the position 0x0C and 0x22.
| n | Receives the count, 21; may be NULL. |
| bool hitec_identify | ( | const hitec_image_t * | img, |
| hitec_model_t * | out ) |
Identify the model from a read image.
D series: register 0x00. Classic: the name cells 0x60 to 0x6F. The classic version byte is not used.
| img | Read image. |
| out | Receives the model; on false its model is HITEC_MODEL_NONE. |
| uint8_t hitec_image_cell | ( | const hitec_image_t * | img, |
| uint8_t | cell ) |
A classic cell; 0 for NULL.
| img | Image. |
| cell | Cell address. |
| bool hitec_image_forget | ( | hitec_image_t * | img, |
| uint8_t | addr ) |
Mark a cell or a D series register as not known: the servo may hold another value than the image.
The bytes keep their values; decodes and plans that need them fail with an UNKNOWN code until they are stored again.
| img | Image. |
| addr | Classic cell, or the even address of a D series register. |
| void hitec_image_init | ( | hitec_image_t * | img, |
| uint8_t | series ) |
Empty an image of series: no byte known, no version.
| img | Image to empty; NULL does nothing. |
| series | hitec_family_t of the servo. |
| bool hitec_image_known | ( | const hitec_image_t * | img, |
| uint8_t | addr ) |
True when byte addr was read.
| img | Image; NULL gives false. |
| addr | Cell, or the even address of a D series register. |
| bool hitec_image_put_cell | ( | hitec_image_t * | img, |
| uint8_t | cell, | ||
| uint8_t | value ) |
Store a classic cell as read.
| img | Classic image. |
| cell | Cell address. |
| value | Value read. |
| bool hitec_image_put_reg | ( | hitec_image_t * | img, |
| uint8_t | addr, | ||
| uint16_t | value ) |
Store a D series register as read.
| img | D series image. |
| addr | Register address, even. |
| value | Value read. |
| bool hitec_image_put_version | ( | hitec_image_t * | img, |
| uint8_t | version ) |
Store the classic reply to the first command (0x67).
| img | Classic image. |
| version | First byte of the reply. |
| uint16_t hitec_image_reg | ( | const hitec_image_t * | img, |
| uint8_t | addr ) |
A D series register; 0 for NULL or an odd address.
| img | Image. |
| addr | Register address. |
| uint8_t hitec_layout_series | ( | uint8_t | layout | ) |
The series of a layout.
| layout | hitec_layout_t. |
| const char * hitec_model_name | ( | uint8_t | model | ) |
The model's name as Hitec writes it, "D485HW", "HS-5645MG"; "" for the OTHER and NONE models.
| model | hitec_model_id_t. |
| const hitec_param_info_t * hitec_param | ( | uint8_t | layout, |
| uint8_t | id ) |
The row of id for layout; NULL when the layout has no such parameter.
| layout | hitec_layout_t. |
| id | hitec_param_t. |
| int32_t hitec_param_clamp | ( | uint8_t | layout, |
| uint8_t | id, | ||
| int32_t | value ) |
The nearest value an edit of id takes.
Clamped to the row's limits, then to the nearest step from min, a tie going up. FS_US keeps HITEC_FS_LIMP and HITEC_FS_OFF, takes a value under 0 as HITEC_FS_LIMP and a position under min as min. A read-only or unknown parameter gives value unchanged.
| layout | hitec_layout_t. |
| id | hitec_param_t. |
| value | Value in the row's unit. |
| hitec_get_t hitec_param_get | ( | const hitec_image_t * | img, |
| uint8_t | layout, | ||
| uint8_t | id, | ||
| hitec_value_t * | out ) |
Decode a parameter.
| img | Image. |
| layout | hitec_layout_t of the servo. |
| id | hitec_param_t. |
| out | Receives the value; zero on HITEC_GET_UNKNOWN and on an error. |
| bool hitec_param_ok | ( | uint8_t | layout, |
| uint8_t | id, | ||
| int32_t | value ) |
True when value is a value an edit of id takes.
| layout | hitec_layout_t. |
| id | hitec_param_t. |
| value | Value in the row's unit. |
| hitec_set_t hitec_param_set | ( | hitec_image_t * | img, |
| uint8_t | layout, | ||
| uint8_t | id, | ||
| int32_t | value ) |
Edit a draft: encode value and write its side effects.
A value equal to the decoded one changes nothing, side effects included. A stored value that fits no encoding is replaced by the table value of value, with the side effects; no edit writes a raw value. Side effects, as the vendor programmers write them:
D direction 0xC2, 0xB2, 0xB0 mirrored (hitec_d_mirror()), 0xB2 from 0xB0 and 0xB0 from 0xB2; from a 0x5E that is neither 0 nor 1 the present direction is not known, and 0x5E is written alone D smart sensor on: 0x6C = 0x44 = 0; off: 0x6C = 0x8A, 0x44 = 0x8C C centre 0x13 = 0x14 = 0x10 C direction 0x13 and 0x14 swapped, 0x19 and 0x1A from 0x49 and 0x4A C fail-safe position 0x1B bit 1 set C overload HS-5xxx 0x21 = 0xFF, HS-7xxx 0x20 = 0x00
A classic edit writes the balance into 0x1C. A D series neutral or end point keeps left end < neutral < right end.
| img | Draft image. |
| layout | hitec_layout_t of the servo. |
| id | hitec_param_t. |
| value | Value in the row's unit. |
| hitec_plan_result_t hitec_plan | ( | const hitec_image_t * | from, |
| const hitec_image_t * | to, | ||
| hitec_plan_t * | out ) |
The writes that take a servo from image from to to.
Only writable addresses (hitec_writable()) are compared; a difference anywhere else is not written.
Classic, in the order of the HPP-21 Plus's operations: cells 0x00 to 0x06, the pairs 0x07/08 to 0x11/12, 0x13, 0x14, the pairs 0x15/16 to 0x19/1A, 0x1B, 0x1D, the pairs 0x1E/1F and 0x20/21, 0x22, 0x23. A setting with a changed cell writes all its cells; a setting of cells up to 0x1B is followed by a write of the balance to 0x1C. Cells above 0x1C get no balance. When from has a bad checksum and no setting up to 0x1B changes, one balance write ends the plan.
D series, by setting, each with the registers the HFP-30 writes for it: ID 0x32; direction 0xC2, 0xB2, 0xB0, 0x4C, 0x5E, and 0x5E alone when from holds a 0x5E that is neither 0 nor 1; neutral 0xC2; left end 0xB2; right end 0xB0; dead band 0x4E; speed 0x54; fail-safe 0x4C; soft start 0x60; overload protection 0x9C, 0x9A = 3, 0x98 = 200; smart sensor 0x72 = 0x4E54, 0x6C, 0x44. A register already written with the same value is not written again. A register the plan does not write need not be known. The save and the reboot end a plan with a write.
| from | Image the servo holds. |
| to | Draft. |
| out | Receives the plan; empty on an error. |
| bool hitec_writable | ( | uint8_t | series, |
| uint8_t | addr ) |
True when a plan writes addr of series.
Classic: cells 0x00 to 0x23 but 0x1C, which the balance writes. D series: 0x32, 0x44, 0x4C, 0x4E, 0x54, 0x5E, 0x60, 0x6C, 0x9C, 0xB0, 0xB2, 0xC2.
| series | hitec_family_t. |
| addr | Cell or register. |
|
static |
Clear the known bit of byte addr.
| img | Image. |
| addr | Byte. |
|
static |
The HPP-21 Plus's settings: first cell and count, in its order.
|
static |
The classic cells of a full read.
|
static |
HPP-21 Plus resolution; the factory 0x0B shows as High.
|
static |
HPP-21 Plus speed.
|
static |
|
static |
|
static |
The D series registers of a full read.
|
static |
HFP-30 soft start.
|
static |
HFP-30 speed: 5% a count; the factory 4095 shows as 100%.
|
static |
In the order of hitec_model_id_t.
|
static |
Overload protection, HFP-30 and HPP-21 Plus alike.
|
static |
Dead band steps, HPP-21 Plus and D series.