Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions bellows/ezsp/v14/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ class GetTokenDataRsp(Struct):
}

COMMANDS = {
"radioSetSchedulerPriorities": (
0x012B,
{
"priorities": t.SlZigbeeMultiprotocolPriorities,
},
{},
),
"setExtendedTimeout": (
0x007E,
{
Expand Down
10 changes: 10 additions & 0 deletions bellows/ezsp/v16/commands.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
import bellows.types as t

from ..v14.commands import COMMANDS as COMMANDS_v14

COMMANDS = {
**COMMANDS_v14,
# The priorities struct grew from three to five fields
"radioSetSchedulerPriorities": (
0x012B,
{
"priorities": t.Sl802154RadioPriorities,
},
{},
),
}
221 changes: 221 additions & 0 deletions bellows/ezsp/v18/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,225 @@
"messageContents": t.LVBytes,
},
),
# Added in Simplicity SDK 2025.12.0
"setPendingNetworkUpdateChannel": (
0x003D,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional / non-blocking: since the 2025.12.3 SDK reclaimed 0x003D for this command, the inherited getFirstBeacon (at 0x003D since v7) is now a dead opcode in v18 firmware. Harmless as-is — setPendingNetworkUpdateChannel is inserted later so it wins COMMANDS_BY_ID[0x003D], and both stay callable by name — and it mirrors the existing v17 pattern (gpProxyTableRemoveEntry/gpClearProxyTable reusing 0x5D/0x5F). But if you'd like v18 to reflect the firmware exactly, you could drop getFirstBeacon here.

{
"channel": t.uint8_t,
},
{},
),
# NOTE: `radioSetSchedulerPriorities` (0x012B) was removed from NCP firmware in
# Simplicity SDK 2025.12.2 without an EZSP version bump: firmware built from
# SiSDK 2025.6.x (also EZSP v18) still implements it.
# Dynamic Hardware Configuration, added in Simplicity SDK 2025.12.2
"readPaDescriptor": (
0x0152,
{
"index": t.uint8_t,
},
{
"status": t.sl_Status,
"descriptor": t.SlZigbeeDhcPaDescriptor,
},
),
"writePaDescriptor": (
0x0153,
{
"index": t.uint8_t,
"descriptor": t.SlZigbeeDhcPaDescriptor,
},
{
"status": t.sl_Status,
},
),
"readPaCurveSegment": (
0x0154,
{
"index": t.uint8_t,
"segment_index": t.uint8_t,
},
{
"status": t.sl_Status,
"segment": t.SlZigbeeDhcPaCurveSegment,
},
),
"writePaCurveSegment": (
0x0155,
{
"index": t.uint8_t,
"segment_index": t.uint8_t,
"segment": t.SlZigbeeDhcPaCurveSegment,
},
{
"status": t.sl_Status,
},
),
"readPaCurve": (
0x0156,
{
"index": t.uint8_t,
},
{
"status": t.sl_Status,
"curve": t.SlZigbeeDhcPaCurve,
},
),
"writePaCurve": (
0x0157,
{
"index": t.uint8_t,
"curve": t.SlZigbeeDhcPaCurve,
},
{
"status": t.sl_Status,
},
),
"readPaTable": (
0x0158,
{
"index": t.uint8_t,
},
{
"status": t.sl_Status,
"table": t.SlZigbeeDhcPaTable,
},
),
"writePaTable": (
0x0159,
{
"index": t.uint8_t,
"table": t.SlZigbeeDhcPaTable,
},
{
"status": t.sl_Status,
},
),
"readRssiOffset": (
0x015A,
{},
{
"status": t.sl_Status,
"rssi_offset": t.int8s,
},
),
"readPaVoltage": (
0x015B,
{},
{
"status": t.sl_Status,
"pa_voltage": t.uint16_t,
},
),
"writePaVoltage": (
0x015C,
{
"pa_voltage": t.uint16_t,
},
{
"status": t.sl_Status,
},
),
"readPaMode": (
0x015D,
{},
{
"status": t.sl_Status,
"pa_mode": t.uint8_t,
},
),
"writePaMode": (
0x015E,
{
"pa_mode": t.uint8_t,
},
{
"status": t.sl_Status,
},
),
"writeRssiOffset": (
0x015F,
{
"rssi_offset": t.int8s,
},
{
"status": t.sl_Status,
},
),
"readCtune": (
0x0160,
{},
{
"status": t.sl_Status,
"ctune": t.uint32_t,
},
),
"writeCtune": (
0x0161,
{
"ctune": t.uint32_t,
},
{
"status": t.sl_Status,
},
),
"readDhcVersion": (
0x0162,
{},
{
"status": t.sl_Status,
"dhc_version": t.uint8_t,
},
),
"writeDhcVersion": (
0x0163,
{
"dhc_version": t.uint8_t,
},
{
"status": t.sl_Status,
},
),
"readPaVersion": (
0x0164,
{},
{
"status": t.sl_Status,
"pa_version": t.uint8_t,
},
),
"readPaSignature": (
0x0166,
{},
{
"status": t.sl_Status,
"pa_signature": t.uint32_t,
},
),
"writePaSignature": (
0x0167,
{
"pa_signature": t.uint32_t,
},
{
"status": t.sl_Status,
},
),
"readPaMetadata": (
0x0168,
{},
{
"status": t.sl_Status,
"metadata": t.SlZigbeeDhcPaMetadata,
},
),
"writePaMetadata": (
0x0169,
{
"metadata": t.SlZigbeeDhcPaMetadata,
},
{
"status": t.sl_Status,
},
),
}
7 changes: 7 additions & 0 deletions bellows/types/named.py
Original file line number Diff line number Diff line change
Expand Up @@ -2884,3 +2884,10 @@ class RouteRecordConcentratortype(basic.enum8):
NOT_A_CONCENTRATOR = 0
LOW_RAM = 1
HIGH_RAM = 2


class SlZigbeeDhcPaAlgorithm(basic.enum8):
"""Dynamic Hardware Configuration PA descriptor algorithm."""

CURVE = 0
TABLE = 1
82 changes: 82 additions & 0 deletions bellows/types/struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,3 +769,85 @@ class SlRxPacketInfo(EzspStruct):
last_hop_rssi: basic.int8s
# Timestamp of the moment when Start Frame Delimiter (SFD) was received
last_hop_timestamp: basic.uint32_t


class SlZigbeeDhcPaCurveSegment(EzspStruct):
"""One PA curve segment (piecewise linear)."""

# Segment upper bound power level
maxPowerLevel: basic.uint8_t
# Signed slope coefficient
slope: basic.int32s
# Signed intercept coefficient
intercept: basic.int32s


class SlZigbeeDhcPaCurve(EzspStruct):
"""Full PA curve (fixed 9 segments)."""

# Curve min ddbm
curve_min_ddbm: basic.int16s
# Curve max ddbm
curve_max_ddbm: basic.int16s
# Curve segments
segments: basic.FixedList[SlZigbeeDhcPaCurveSegment, 9]


class SlZigbeeDhcPaDescriptor(EzspStruct):
"""Descriptor for either a curve (algorithm=0) or table (algorithm=1)."""

algorithm: named.SlZigbeeDhcPaAlgorithm
# 9 for curve, 16 for table
num_segments_or_entries: basic.uint8_t
# Minimum ddbm (may be negative)
min_ddbm: basic.int16s
# Maximum ddbm (may be negative)
max_ddbm: basic.int16s


class SlZigbeeDhcPaTable(EzspStruct):
"""Discrete PA table (16 entries)."""

# Signed ddbm table entries
ddbm_values: basic.FixedList[basic.int16s, 16]


class SlZigbeeDhcPaMetadata(EzspStruct):
"""Top-level PA calibration metadata."""

# Calibration metadata / dataset version
version: basic.uint8_t
# Number of PA descriptors present
num_descriptors: basic.uint8_t
# PA supply voltage (e.g. mV)
pa_voltage: basic.uint16_t
# Integrity signature / CRC for whole set
signature: basic.uint32_t


class SlZigbeeMultiprotocolPriorities(EzspStruct):
"""Priorities for Zigbee radio operations in multiprotocol (EZSP v14)."""

# The priority of a Zigbee RX operation while not receiving a packet
backgroundRx: basic.uint8_t
# The priority of a Zigbee TX operation
tx: basic.uint8_t
# The priority of a Zigbee RX operation while receiving a packet
activeRx: basic.uint8_t


class Sl802154RadioPriorities(EzspStruct):
"""Scheduler priorities for radio operations (EZSP v16+)."""

# The priority of a Zigbee RX operation while not receiving a packet
background_rx: basic.uint8_t
# Starting priority of a Zigbee TX operation. The first transmit of the
# packet, before retries, uses this priority
min_tx_priority: basic.uint8_t
# The increase in TX priority (which is a decrement in value) for each retry
tx_step: basic.uint8_t
# Maximum priority of a Zigbee TX operation. Retried messages have
# priorities bumped by tx_step, up to a maximum of max_tx_priority
max_tx_priority: basic.uint8_t
# The priority of a Zigbee RX operation while receiving a packet
active_rx: basic.uint8_t
Loading