Hitec servo programming protocols: the register models, the parameter table and the write plans.
More...
|
| enum | hitec_layout_t { HITEC_LAYOUT_D = 0
, HITEC_LAYOUT_HS5
, HITEC_LAYOUT_HS7
, HITEC_LAYOUT_COUNT
} |
| | Register layouts. More...
|
| enum | hitec_src_t { HITEC_SRC_RCBENCH = 0
, HITEC_SRC_CAPTURED
, HITEC_SRC_READ
, HITEC_SRC_DOC
} |
| | Where an entry comes from. More...
|
| enum | hitec_model_id_t {
HITEC_MODEL_NONE = 0
, HITEC_MODEL_D485HW
, HITEC_MODEL_D645MW
, HITEC_MODEL_D_OTHER
,
HITEC_MODEL_HS5645MG
, HITEC_MODEL_HS5955TG
, HITEC_MODEL_HS7955TG
, HITEC_MODEL_HS5_OTHER
,
HITEC_MODEL_HS7_OTHER
, HITEC_MODEL_C_OTHER
, HITEC_MODEL_COUNT
} |
| | Models the module knows by name. More...
|
| enum | hitec_param_t {
HITEC_P_D_MODEL = 0
, HITEC_P_D_POSITION
, HITEC_P_D_ID
, HITEC_P_D_DIRECTION
,
HITEC_P_D_NEUTRAL
, HITEC_P_D_LEFT_END
, HITEC_P_D_RIGHT_END
, HITEC_P_D_DEAD_BAND
,
HITEC_P_D_SPEED
, HITEC_P_D_FAILSAFE
, HITEC_P_D_SOFT_START
, HITEC_P_D_OVERLOAD
,
HITEC_P_D_SMART_SENSOR
, HITEC_P_D_SENSITIVITY
, HITEC_P_D_R04
, HITEC_P_D_R22
,
HITEC_P_D_R8A
, HITEC_P_D_R8C
, HITEC_P_D_RD4
, HITEC_P_D_RD6
,
HITEC_P_C_VERSION
, HITEC_P_C_DATE
, HITEC_P_C_SERIAL
, HITEC_P_C_CHECKSUM
,
HITEC_P_C_DEAD_BAND
, HITEC_P_C_SPEED
, HITEC_P_C_CENTRE
, HITEC_P_C_LEFT_END
,
HITEC_P_C_RIGHT_END
, HITEC_P_C_DIRECTION
, HITEC_P_C_FAILSAFE
, HITEC_P_C_FS_POSITION
,
HITEC_P_C_OVERLOAD
, HITEC_P_C_RESOLUTION
, HITEC_P_COUNT
} |
| | The parameters of both series. More...
|
| enum | hitec_unit_t {
HITEC_UNIT_RAW = 0
, HITEC_UNIT_COUNTS
, HITEC_UNIT_PERCENT
, HITEC_UNIT_STEP
,
HITEC_UNIT_CHOICE
, HITEC_UNIT_FS_US
, HITEC_UNIT_OVERLOAD
, HITEC_UNIT_QUARTER_US
,
HITEC_UNIT_DATE
, HITEC_UNIT_NUMBER
} |
| | Unit of a decoded value. More...
|
| enum | hitec_choice_t {
HITEC_CW = 0
, HITEC_CCW = 1
, HITEC_OFF = 0
, HITEC_ON = 1
,
HITEC_RES_NORMAL = 0
, HITEC_RES_HIGH = 1
, HITEC_SUM_BAD = 0
, HITEC_SUM_OK = 1
} |
| | The values of the CHOICE parameters. More...
|
| enum | hitec_access_t { HITEC_RO = 0
, HITEC_RW
} |
| | Access of a parameter. More...
|
| enum | hitec_get_t { HITEC_GET_OK = 0
, HITEC_GET_RAW
, HITEC_GET_UNKNOWN
, HITEC_GET_ERR_ARG
} |
| | Result of a decode. More...
|
| enum | hitec_set_t {
HITEC_SET_OK = 0
, HITEC_SET_ERR_ARG
, HITEC_SET_ERR_RO
, HITEC_SET_ERR_RANGE
,
HITEC_SET_ERR_RAW
, HITEC_SET_ERR_UNKNOWN
, HITEC_SET_ERR_MIRROR
, HITEC_SET_ERR_ORDER
} |
| | Result of an edit. More...
|
| enum | hitec_step_kind_t {
HITEC_STEP_C_CELL = 0
, HITEC_STEP_C_SUM
, HITEC_STEP_D_WRITE
, HITEC_STEP_D_SAVE
,
HITEC_STEP_D_REBOOT
} |
| | Kind of a write. More...
|
| enum | hitec_plan_result_t { HITEC_PLAN_OK = 0
, HITEC_PLAN_ERR_ARG
, HITEC_PLAN_ERR_UNKNOWN
} |
| | Result of planning. More...
|
|
| void | hitec_image_init (hitec_image_t *img, uint8_t series) |
| | Empty an image of series: no byte known, no version.
|
| 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).
|
| 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.
|
| 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.
|
| 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.
|
| 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.
|
| hitec_get_t | hitec_param_get (const hitec_image_t *img, uint8_t layout, uint8_t id, hitec_value_t *out) |
| | Decode a parameter.
|
| 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_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.
|
| 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.
|
| 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.
|
Hitec servo programming protocols: the register models, the parameter table and the write plans.
Implements the register models of Hitec servos. Hitec is a name or trademark of its owner; it is used here only to say which servos this module works with (README.md, "Legal notice and disclaimer").
Two models share one image type (hitec_image_t, 256 bytes):
- Classic, the HS-5xxx and HS-7xxx servos: 256 EEPROM cells of 8 bits. A two-cell value is stored high byte first. Cells 0x00 to 0x1C sum to 0 modulo 256; cell 0x1C is the balance. 0x30 to 0x53 hold the factory block in the layout of 0x00 to 0x23, 0x60 to 0x6F the model name in ASCII.
- D series: registers of 16 bits at even addresses 0x00 to 0xFE, the low byte at the even address. A write takes effect in the servo's RAM; a save (0x70 = 0xFFFF) stores it, and a reboot (0x46 = 1) restarts the servo with it.
The image stores raw values. A parameter (hitec_param_t) is decoded from the image and encoded into it with the encoding the vendor programmers use: the HFP-30 for the D series, measured on a D485HW; the HPP-21 Plus for classic servos, measured on an HS-5645MG and an HS-7955TG. A raw value that fits no encoding is shown raw; an edit replaces it with a value of the table, and only a restore writes the raw value back. Every value is an integer in the unit of its hitec_unit_t; no floating point is used.
An edit (hitec_param_set()) changes a draft image as the vendor programmer changes the servo, with the side effects it writes: the D series direction mirrors the neutral and both end points; the classic centre resets both end points; the classic direction swaps the end points and takes the fail-safe position from the factory block. A plan (hitec_plan()) lists the writes that take a servo from its read image to the draft, in the vendor programmer's order, with the classic checksum write and the D series save and reboot.
Every table row says where its encoding comes from (hitec_src_t). The module identifies the model from the read data (hitec_identify()); a model other than the measured ones takes its series' layout.
The module has no hardware access, no heap and no global or static mutable state, and includes nothing outside the C standard headers and this folder.
SPDX-License-Identifier: MIT
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.
- Parameters
-
- Returns
- A hitec_set_t; on an error the draft is unchanged.
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.
- Parameters
-
| from | Image the servo holds. |
| to | Draft. |
| out | Receives the plan; empty on an error. |
- Returns
- A hitec_plan_result_t.