/* Generated from spec SHA-256: c8b7736cbd0e5225e8ed78790c3b3191ae08096323ec087c59f0ffc017c6db46 */

#include "actuator_fd.h"
#include <float.h>
#include <math.h>
#include <string.h>
_Static_assert(sizeof(float) == 4 && FLT_RADIX == 2 && FLT_MANT_DIG == 24 && FLT_MAX_EXP == 128,
               "ActuatorFD requires IEEE-754 binary32");
static inline void afd_put_u8(uint8_t *p, uint8_t value) { p[0] = value; }
static inline uint8_t afd_get_u8(const uint8_t *p) { return p[0]; }
static inline void afd_put_u16(uint8_t *p, uint16_t value) {
    p[0] = (uint8_t)value; p[1] = (uint8_t)(value >> 8);
}
static inline uint16_t afd_get_u16(const uint8_t *p) {
    return (uint16_t)((uint16_t)p[0] | ((uint16_t)p[1] << 8));
}
static inline void afd_put_u32(uint8_t *p, uint32_t value) {
    for (unsigned idx = 0; idx < 4; ++idx) p[idx] = (uint8_t)(value >> (8 * idx));
}
static inline uint32_t afd_get_u32(const uint8_t *p) {
    uint32_t value = 0;
    for (unsigned idx = 0; idx < 4; ++idx) value |= (uint32_t)p[idx] << (8 * idx);
    return value;
}
static inline void afd_put_f32(uint8_t *p, float value) {
    uint32_t bits; memcpy(&bits, &value, sizeof bits); afd_put_u32(p, bits);
}
static inline float afd_get_f32(const uint8_t *p) {
    uint32_t bits = afd_get_u32(p); float value; memcpy(&value, &bits, sizeof value); return value;
}
bool afd_encode_identifier(uint32_t priority, uint32_t service, uint32_t source,
                           uint32_t destination, uint32_t *out) {
    if (!out || priority > 7 || service > 255 || source > 127 || destination > 127) return false;
    *out = (priority << 26) | (service << 18) | (source << 11) | (destination << 4) | AFD_MAJOR;
    return true;
}
bool afd_decode_identifier(uint32_t value, afd_identifier_t *out) {
    if (!out || value >= (1u << 29) || (value & 15u) != AFD_MAJOR) return false;
    out->priority = (uint8_t)(value >> 26); out->service = (uint8_t)((value >> 18) & 255u);
    out->source = (uint8_t)((value >> 11) & 127u); out->destination = (uint8_t)((value >> 4) & 127u);
    out->major = (uint8_t)(value & 15u); return true;
}

bool afd_encode_emergency_disable(const afd_emergency_disable_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 4u) return false;
    memset(out, 0, 4u);
    afd_put_u32(out + 0, value->reason);
    return true;
}
bool afd_decode_emergency_disable(const uint8_t *data, size_t length, afd_emergency_disable_t *out) {
    if (!data || !out || length != 4u) return false;
    for (size_t idx = 4; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_emergency_disable_t value = {0};
    value.reason = afd_get_u32(data + 0);
    *out = value; return true;
}
bool afd_encode_fault(const afd_fault_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 20u) return false;
    memset(out, 0, 20u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u32(out + 8, value->fault_bits);
    afd_put_u32(out + 12, value->latched_bits);
    afd_put_u32(out + 16, value->time_us);
    return true;
}
bool afd_decode_fault(const uint8_t *data, size_t length, afd_fault_t *out) {
    if (!data || !out || length != 20u) return false;
    for (size_t idx = 20; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_fault_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.fault_bits = afd_get_u32(data + 8);
    value.latched_bits = afd_get_u32(data + 12);
    value.time_us = afd_get_u32(data + 16);
    *out = value; return true;
}
bool afd_encode_sync(const afd_sync_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 12u) return false;
    memset(out, 0, 12u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->time_us);
    afd_put_u32(out + 8, value->cycle);
    return true;
}
bool afd_decode_sync(const uint8_t *data, size_t length, afd_sync_t *out) {
    if (!data || !out || length != 12u) return false;
    for (size_t idx = 12; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_sync_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.time_us = afd_get_u32(data + 4);
    value.cycle = afd_get_u32(data + 8);
    *out = value; return true;
}
bool afd_encode_command(const afd_command_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 48u) return false;
    if (!isfinite(value->position_rad)) return false;
    if (!isfinite(value->velocity_rad_s)) return false;
    if (!isfinite(value->feedforward_nm)) return false;
    if (!isfinite(value->kp_nm_rad)) return false;
    if (!isfinite(value->kd_nm_s_rad)) return false;
    memset(out, 0, 48u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u32(out + 8, value->execute_us);
    afd_put_u32(out + 12, value->valid_until_us);
    afd_put_f32(out + 16, value->position_rad);
    afd_put_f32(out + 20, value->velocity_rad_s);
    afd_put_f32(out + 24, value->feedforward_nm);
    afd_put_f32(out + 28, value->kp_nm_rad);
    afd_put_f32(out + 32, value->kd_nm_s_rad);
    afd_put_u8(out + 36, value->mode);
    afd_put_u8(out + 37, value->flags);
    return true;
}
bool afd_decode_command(const uint8_t *data, size_t length, afd_command_t *out) {
    if (!data || !out || length != 48u) return false;
    for (size_t idx = 38; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_command_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.execute_us = afd_get_u32(data + 8);
    value.valid_until_us = afd_get_u32(data + 12);
    value.position_rad = afd_get_f32(data + 16);
    if (!isfinite(value.position_rad)) return false;
    value.velocity_rad_s = afd_get_f32(data + 20);
    if (!isfinite(value.velocity_rad_s)) return false;
    value.feedforward_nm = afd_get_f32(data + 24);
    if (!isfinite(value.feedforward_nm)) return false;
    value.kp_nm_rad = afd_get_f32(data + 28);
    if (!isfinite(value.kp_nm_rad)) return false;
    value.kd_nm_s_rad = afd_get_f32(data + 32);
    if (!isfinite(value.kd_nm_s_rad)) return false;
    value.mode = afd_get_u8(data + 36);
    value.flags = afd_get_u8(data + 37);
    *out = value; return true;
}
bool afd_encode_state(const afd_state_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 48u) return false;
    if (!isfinite(value->output_position_rad)) return false;
    if (!isfinite(value->motor_position_rad)) return false;
    if (!isfinite(value->velocity_rad_s)) return false;
    if (!isfinite(value->iq_a)) return false;
    if (!isfinite(value->estimated_torque_nm)) return false;
    if (!isfinite(value->temperature_c)) return false;
    memset(out, 0, 48u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u32(out + 8, value->time_us);
    afd_put_f32(out + 12, value->output_position_rad);
    afd_put_f32(out + 16, value->motor_position_rad);
    afd_put_f32(out + 20, value->velocity_rad_s);
    afd_put_f32(out + 24, value->iq_a);
    afd_put_f32(out + 28, value->estimated_torque_nm);
    afd_put_f32(out + 32, value->temperature_c);
    afd_put_u32(out + 36, value->fault_bits);
    return true;
}
bool afd_decode_state(const uint8_t *data, size_t length, afd_state_t *out) {
    if (!data || !out || length != 48u) return false;
    for (size_t idx = 40; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_state_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.time_us = afd_get_u32(data + 8);
    value.output_position_rad = afd_get_f32(data + 12);
    if (!isfinite(value.output_position_rad)) return false;
    value.motor_position_rad = afd_get_f32(data + 16);
    if (!isfinite(value.motor_position_rad)) return false;
    value.velocity_rad_s = afd_get_f32(data + 20);
    if (!isfinite(value.velocity_rad_s)) return false;
    value.iq_a = afd_get_f32(data + 24);
    if (!isfinite(value.iq_a)) return false;
    value.estimated_torque_nm = afd_get_f32(data + 28);
    if (!isfinite(value.estimated_torque_nm)) return false;
    value.temperature_c = afd_get_f32(data + 32);
    if (!isfinite(value.temperature_c)) return false;
    value.fault_bits = afd_get_u32(data + 36);
    *out = value; return true;
}
bool afd_encode_health(const afd_health_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 48u) return false;
    if (!isfinite(value->bus_voltage_v)) return false;
    if (!isfinite(value->winding_temperature_c)) return false;
    if (!isfinite(value->inverter_temperature_c)) return false;
    memset(out, 0, 48u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_f32(out + 8, value->bus_voltage_v);
    afd_put_f32(out + 12, value->winding_temperature_c);
    afd_put_f32(out + 16, value->inverter_temperature_c);
    afd_put_u32(out + 20, value->uptime_ms);
    afd_put_u32(out + 24, value->rx_errors);
    afd_put_u32(out + 28, value->tx_errors);
    afd_put_u8(out + 32, value->mode);
    return true;
}
bool afd_decode_health(const uint8_t *data, size_t length, afd_health_t *out) {
    if (!data || !out || length != 48u) return false;
    for (size_t idx = 33; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_health_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.bus_voltage_v = afd_get_f32(data + 8);
    if (!isfinite(value.bus_voltage_v)) return false;
    value.winding_temperature_c = afd_get_f32(data + 12);
    if (!isfinite(value.winding_temperature_c)) return false;
    value.inverter_temperature_c = afd_get_f32(data + 16);
    if (!isfinite(value.inverter_temperature_c)) return false;
    value.uptime_ms = afd_get_u32(data + 20);
    value.rx_errors = afd_get_u32(data + 24);
    value.tx_errors = afd_get_u32(data + 28);
    value.mode = afd_get_u8(data + 32);
    *out = value; return true;
}
bool afd_encode_discover(const afd_discover_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 12u) return false;
    memset(out, 0, 12u);
    afd_put_u32(out + 0, value->nonce);
    afd_put_u16(out + 4, value->slot_count);
    afd_put_u32(out + 6, value->slot_duration_us);
    return true;
}
bool afd_decode_discover(const uint8_t *data, size_t length, afd_discover_t *out) {
    if (!data || !out || length != 12u) return false;
    for (size_t idx = 10; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_discover_t value = {0};
    value.nonce = afd_get_u32(data + 0);
    value.slot_count = afd_get_u16(data + 4);
    value.slot_duration_us = afd_get_u32(data + 6);
    *out = value; return true;
}
bool afd_encode_identity(const afd_identity_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 32u) return false;
    memset(out, 0, 32u);
    afd_put_u32(out + 0, value->nonce);
    memcpy(out + 4, value->unique_id, 16);
    afd_put_u16(out + 20, value->hardware_revision);
    afd_put_u32(out + 22, value->firmware_version);
    afd_put_u8(out + 26, value->node_id);
    return true;
}
bool afd_decode_identity(const uint8_t *data, size_t length, afd_identity_t *out) {
    if (!data || !out || length != 32u) return false;
    for (size_t idx = 27; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_identity_t value = {0};
    value.nonce = afd_get_u32(data + 0);
    memcpy(value.unique_id, data + 4, 16);
    value.hardware_revision = afd_get_u16(data + 20);
    value.firmware_version = afd_get_u32(data + 22);
    value.node_id = afd_get_u8(data + 26);
    *out = value; return true;
}
bool afd_encode_assign_address(const afd_assign_address_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 24u) return false;
    memset(out, 0, 24u);
    afd_put_u32(out + 0, value->nonce);
    memcpy(out + 4, value->unique_id, 16);
    afd_put_u8(out + 20, value->node_id);
    return true;
}
bool afd_decode_assign_address(const uint8_t *data, size_t length, afd_assign_address_t *out) {
    if (!data || !out || length != 24u) return false;
    for (size_t idx = 21; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_assign_address_t value = {0};
    value.nonce = afd_get_u32(data + 0);
    memcpy(value.unique_id, data + 4, 16);
    value.node_id = afd_get_u8(data + 20);
    *out = value; return true;
}
bool afd_encode_capabilities(const afd_capabilities_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 32u) return false;
    if (!isfinite(value->continuous_torque_nm)) return false;
    if (!isfinite(value->peak_torque_nm)) return false;
    if (!isfinite(value->maximum_velocity_rad_s)) return false;
    memset(out, 0, 32u);
    afd_put_u16(out + 0, value->protocol_minor);
    afd_put_u32(out + 2, value->capability_bits);
    afd_put_f32(out + 6, value->continuous_torque_nm);
    afd_put_f32(out + 10, value->peak_torque_nm);
    afd_put_f32(out + 14, value->maximum_velocity_rad_s);
    afd_put_u32(out + 18, value->watchdog_us);
    afd_put_u32(out + 22, value->encoder_status);
    return true;
}
bool afd_decode_capabilities(const uint8_t *data, size_t length, afd_capabilities_t *out) {
    if (!data || !out || length != 32u) return false;
    for (size_t idx = 26; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_capabilities_t value = {0};
    value.protocol_minor = afd_get_u16(data + 0);
    value.capability_bits = afd_get_u32(data + 2);
    value.continuous_torque_nm = afd_get_f32(data + 6);
    if (!isfinite(value.continuous_torque_nm)) return false;
    value.peak_torque_nm = afd_get_f32(data + 10);
    if (!isfinite(value.peak_torque_nm)) return false;
    value.maximum_velocity_rad_s = afd_get_f32(data + 14);
    if (!isfinite(value.maximum_velocity_rad_s)) return false;
    value.watchdog_us = afd_get_u32(data + 18);
    value.encoder_status = afd_get_u32(data + 22);
    *out = value; return true;
}
bool afd_encode_session_start(const afd_session_start_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 24u) return false;
    memset(out, 0, 24u);
    afd_put_u32(out + 0, value->session);
    memcpy(out + 4, value->unique_id, 16);
    afd_put_u32(out + 20, value->watchdog_us);
    return true;
}
bool afd_decode_session_start(const uint8_t *data, size_t length, afd_session_start_t *out) {
    if (!data || !out || length != 24u) return false;
    for (size_t idx = 24; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_session_start_t value = {0};
    value.session = afd_get_u32(data + 0);
    memcpy(value.unique_id, data + 4, 16);
    value.watchdog_us = afd_get_u32(data + 20);
    *out = value; return true;
}
bool afd_encode_ack(const afd_ack_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 16u) return false;
    memset(out, 0, 16u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u8(out + 8, value->request_service);
    afd_put_u16(out + 9, value->result);
    afd_put_u32(out + 11, value->detail);
    return true;
}
bool afd_decode_ack(const uint8_t *data, size_t length, afd_ack_t *out) {
    if (!data || !out || length != 16u) return false;
    for (size_t idx = 15; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_ack_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.request_service = afd_get_u8(data + 8);
    value.result = afd_get_u16(data + 9);
    value.detail = afd_get_u32(data + 11);
    *out = value; return true;
}
bool afd_encode_configure(const afd_configure_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 48u) return false;
    memset(out, 0, 48u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u16(out + 8, value->key);
    afd_put_u8(out + 10, value->operation);
    memcpy(out + 11, value->value, 32);
    return true;
}
bool afd_decode_configure(const uint8_t *data, size_t length, afd_configure_t *out) {
    if (!data || !out || length != 48u) return false;
    for (size_t idx = 43; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_configure_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.key = afd_get_u16(data + 8);
    value.operation = afd_get_u8(data + 10);
    memcpy(value.value, data + 11, 32);
    *out = value; return true;
}
bool afd_encode_calibrate(const afd_calibrate_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 12u) return false;
    memset(out, 0, 12u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u16(out + 8, value->routine);
    afd_put_u8(out + 10, value->operation);
    return true;
}
bool afd_decode_calibrate(const uint8_t *data, size_t length, afd_calibrate_t *out) {
    if (!data || !out || length != 12u) return false;
    for (size_t idx = 11; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_calibrate_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.routine = afd_get_u16(data + 8);
    value.operation = afd_get_u8(data + 10);
    *out = value; return true;
}
bool afd_encode_clear_faults(const afd_clear_faults_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 12u) return false;
    memset(out, 0, 12u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u32(out + 8, value->mask);
    return true;
}
bool afd_decode_clear_faults(const uint8_t *data, size_t length, afd_clear_faults_t *out) {
    if (!data || !out || length != 12u) return false;
    for (size_t idx = 12; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_clear_faults_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.mask = afd_get_u32(data + 8);
    *out = value; return true;
}
bool afd_encode_firmware_begin(const afd_firmware_begin_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 48u) return false;
    memset(out, 0, 48u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u32(out + 8, value->image_bytes);
    memcpy(out + 12, value->image_sha256, 32);
    afd_put_u8(out + 44, value->target_slot);
    return true;
}
bool afd_decode_firmware_begin(const uint8_t *data, size_t length, afd_firmware_begin_t *out) {
    if (!data || !out || length != 48u) return false;
    for (size_t idx = 45; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_firmware_begin_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.image_bytes = afd_get_u32(data + 8);
    memcpy(value.image_sha256, data + 12, 32);
    value.target_slot = afd_get_u8(data + 44);
    *out = value; return true;
}
bool afd_encode_firmware_chunk(const afd_firmware_chunk_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 48u) return false;
    memset(out, 0, 48u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u32(out + 8, value->offset);
    afd_put_u8(out + 12, value->valid_bytes);
    memcpy(out + 13, value->data, 32);
    return true;
}
bool afd_decode_firmware_chunk(const uint8_t *data, size_t length, afd_firmware_chunk_t *out) {
    if (!data || !out || length != 48u) return false;
    for (size_t idx = 45; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_firmware_chunk_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.offset = afd_get_u32(data + 8);
    value.valid_bytes = afd_get_u8(data + 12);
    memcpy(value.data, data + 13, 32);
    *out = value; return true;
}
bool afd_encode_firmware_commit(const afd_firmware_commit_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 48u) return false;
    memset(out, 0, 48u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    memcpy(out + 8, value->image_sha256, 32);
    return true;
}
bool afd_decode_firmware_commit(const uint8_t *data, size_t length, afd_firmware_commit_t *out) {
    if (!data || !out || length != 48u) return false;
    for (size_t idx = 40; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_firmware_commit_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    memcpy(value.image_sha256, data + 8, 32);
    *out = value; return true;
}
bool afd_encode_enable(const afd_enable_t *value, uint8_t *out, size_t length) {
    if (!value || !out || length != 12u) return false;
    memset(out, 0, 12u);
    afd_put_u32(out + 0, value->session);
    afd_put_u32(out + 4, value->sequence);
    afd_put_u8(out + 8, value->enabled);
    return true;
}
bool afd_decode_enable(const uint8_t *data, size_t length, afd_enable_t *out) {
    if (!data || !out || length != 12u) return false;
    for (size_t idx = 9; idx < length; ++idx) if (data[idx] != 0) return false;
    afd_enable_t value = {0};
    value.session = afd_get_u32(data + 0);
    value.sequence = afd_get_u32(data + 4);
    value.enabled = afd_get_u8(data + 8);
    *out = value; return true;
}
