mirror of
https://github.com/esphome/esphome.git
synced 2026-08-24 15:16:20 +00:00
Simplify startup state machine by using direct NVRAM access
This commit is contained in:
@@ -28,55 +28,47 @@ static constexpr uint8_t EZSP_FRAME_CONTROL_EXTENDED = 0x01;
|
||||
// Everything after that is extended, with no per-NCP exceptions.
|
||||
|
||||
// EZSP Frame IDs - Commands (host to NCP)
|
||||
static constexpr uint16_t EZSP_VERSION = 0x0000; // Version negotiation
|
||||
static constexpr uint16_t EZSP_NETWORK_INIT = 0x0017; // Initialize network
|
||||
static constexpr uint16_t EZSP_NETWORK_STATE = 0x0018; // Get network state
|
||||
static constexpr uint16_t EZSP_GET_EUI64 = 0x0026; // Get IEEE address
|
||||
static constexpr uint16_t EZSP_GET_NETWORK_PARAMETERS = 0x0028; // Get network parameters
|
||||
static constexpr uint16_t EZSP_SET_CONFIGURATION_VALUE = 0x0053; // Set a stack config value
|
||||
static constexpr uint16_t EZSP_VERSION = 0x0000; // Version negotiation
|
||||
static constexpr uint16_t EZSP_GET_EUI64 = 0x0026; // Get IEEE address
|
||||
static constexpr uint16_t EZSP_GET_TOKEN_DATA = 0x0102; // Read an NVM3 token
|
||||
|
||||
// Stack configuration. CONFIG_STACK_PROFILE must be set to ZigBee PRO before
|
||||
// networkInit, or the NCP answers NOT_JOINED for a node that is in fact joined
|
||||
// and getNetworkParameters then fails, leaving PAN ID and channel unreadable.
|
||||
// The NCP boots with stack profile 0, so this is not optional.
|
||||
static constexpr uint8_t EZSP_CONFIG_STACK_PROFILE = 0x0C;
|
||||
static constexpr uint16_t STACK_PROFILE_ZIGBEE_PRO = 2;
|
||||
// Network metadata comes straight out of NVM3 instead of from a running stack.
|
||||
// NVM3KEY_STACK_NODE_DATA holds the PAN ID, channel, extended PAN ID and node type of
|
||||
// the network this radio is commissioned onto, and reading it requires nothing beyond a
|
||||
// completed version negotiation: no stack configuration, no networkInit, no waiting on
|
||||
// stackStatusHandler, and above all no joining the network -- so simply plugging the
|
||||
// device in never brings the radio up.
|
||||
//
|
||||
// Note the 0x0001 domain prefix on the NVM3 object key. The bare creator ID
|
||||
// 0x0000EE64 is a different thing and getTokenData answers FAIL for it.
|
||||
static constexpr uint32_t NVM3KEY_STACK_NODE_DATA = 0x0001EE64;
|
||||
|
||||
// EZSP Frame IDs - Callbacks (NCP to host, async)
|
||||
static constexpr uint16_t EZSP_STACK_STATUS_HANDLER = 0x0019; // Stack status callback
|
||||
// getTokenData response: [status (4)] [length (4)] [value (length)]
|
||||
static constexpr size_t TOKEN_DATA_LENGTH_OFFSET = 4;
|
||||
static constexpr size_t TOKEN_DATA_VALUE_OFFSET = 8;
|
||||
|
||||
// EZSP Network Status
|
||||
enum class EzspNetworkStatus : uint8_t {
|
||||
NO_NETWORK = 0x00,
|
||||
JOINING_NETWORK = 0x01,
|
||||
JOINED_NETWORK = 0x02,
|
||||
JOINED_NETWORK_NO_PARENT = 0x03,
|
||||
LEAVING_NETWORK = 0x04,
|
||||
};
|
||||
// NV3StackNodeData value layout (16 bytes, little-endian):
|
||||
// [panId (2)] [radioTxPower (1)] [radioFreqChannel (1)] [stackProfile (1)]
|
||||
// [nodeType (1)] [zigbeeNodeId (2)] [extendedPanId (8)]
|
||||
static constexpr size_t NV3_NODE_DATA_SIZE = 16;
|
||||
static constexpr size_t NV3_NODE_DATA_PAN_ID_OFFSET = 0;
|
||||
static constexpr size_t NV3_NODE_DATA_CHANNEL_OFFSET = 3;
|
||||
static constexpr size_t NV3_NODE_DATA_NODE_TYPE_OFFSET = 5;
|
||||
static constexpr size_t NV3_NODE_DATA_EXT_PAN_ID_OFFSET = 8;
|
||||
|
||||
// A radio with no network still has the token, holding a sentinel rather than being
|
||||
// absent: panId reads 0xFFFF and nodeType reads UNKNOWN_DEVICE. Detecting "no network"
|
||||
// therefore means inspecting nodeType, not treating the read as failed.
|
||||
static constexpr uint8_t NV3_NODE_TYPE_UNKNOWN_DEVICE = 0x00;
|
||||
|
||||
// Status codes (subset). EZSP v13+ / EmberZNet 8.x report sl_status_t, not the
|
||||
// legacy 8-bit EmberStatus, and the two disagree on every value that matters
|
||||
// here: legacy NETWORK_UP/NOT_JOINED were 0x90/0x93.
|
||||
// legacy 8-bit EmberStatus.
|
||||
enum class SlStatus : uint8_t {
|
||||
OK = 0x00,
|
||||
NETWORK_UP = 0x15,
|
||||
NETWORK_DOWN = 0x16,
|
||||
NOT_JOINED = 0x17,
|
||||
};
|
||||
|
||||
// sl_status_t is 32-bit little-endian on the wire, so a status field occupies
|
||||
// four bytes even though every code used here fits in the first one.
|
||||
static constexpr size_t SL_STATUS_SIZE = 4;
|
||||
|
||||
// Network parameters structure offsets (in getNetworkParameters response)
|
||||
// Response format: [status (4)] [nodeType (1)] [parameters (20)] = 25 bytes
|
||||
// Parameters: [extendedPanId (8)] [panId (2)] [radioTxPower (1)] [radioChannel (1)]
|
||||
// [joinMethod (1)] [nwkManagerId (2)] [nwkUpdateId (1)] [channels (4)]
|
||||
static constexpr size_t NETWORK_PARAMS_STATUS_OFFSET = 0;
|
||||
static constexpr size_t NETWORK_PARAMS_NODE_TYPE_OFFSET = 4;
|
||||
static constexpr size_t NETWORK_PARAMS_EXT_PAN_ID_OFFSET = 5;
|
||||
static constexpr size_t NETWORK_PARAMS_PAN_ID_OFFSET = 13;
|
||||
static constexpr size_t NETWORK_PARAMS_CHANNEL_OFFSET = 16;
|
||||
static constexpr size_t NETWORK_PARAMS_RESPONSE_SIZE = 25;
|
||||
|
||||
} // namespace esphome::zigbee_proxy
|
||||
|
||||
@@ -569,21 +569,16 @@ void ZigbeeProxy::handle_retransmission_() {
|
||||
this->start_ack_timer_();
|
||||
}
|
||||
|
||||
// Boot-time NCP initialization sequence
|
||||
// Sequence: RST -> RSTACK -> version() -> setConfigurationValue(STACK_PROFILE) ->
|
||||
// networkInit() -> stackStatus -> getNetworkParameters() -> getEui64() ->
|
||||
// RST -> RSTACK
|
||||
// Boot-time NCP metadata harvest
|
||||
// Sequence: RST -> RSTACK -> version() -> getTokenData(NVM3KEY_STACK_NODE_DATA) ->
|
||||
// getEui64() -> RST -> RSTACK
|
||||
//
|
||||
// The stack profile must be set before networkInit. The NCP boots with profile 0,
|
||||
// and on profile 0 it reports NOT_JOINED for a node that is joined, which makes
|
||||
// getNetworkParameters fail and leaves PAN ID and channel unreadable. Verified by
|
||||
// bisecting bellows' config writes against a ZBT-2 on a known network: profile 2
|
||||
// alone flips networkInit from NOT_JOINED to OK, and none of the other values
|
||||
// bellows writes make any difference.
|
||||
//
|
||||
// getEui64 comes last, after networkInit has brought the stack up: asking earlier
|
||||
// makes the NCP answer with error frame 0x0058 instead of the address. bellows
|
||||
// orders it the same way.
|
||||
// Both values are read with the stack left down. The alternative -- set the stack
|
||||
// profile, call networkInit, wait for a stackStatusHandler callback announcing
|
||||
// NETWORK_UP, then call getNetworkParameters -- does work, but it joins the network
|
||||
// just to read four fields, so merely powering the device on brings the radio up.
|
||||
// Reading the NVM3 token needs none of it, and getEui64 answers with the stack down
|
||||
// as well, so nothing in this sequence starts the stack.
|
||||
|
||||
void ZigbeeProxy::advance_boot_state_() {
|
||||
switch (this->boot_state_) {
|
||||
@@ -592,26 +587,16 @@ void ZigbeeProxy::advance_boot_state_() {
|
||||
this->boot_state_ = BootState::WAIT_VERSION;
|
||||
break;
|
||||
|
||||
case BootState::SEND_TOKEN_DATA:
|
||||
this->send_get_token_data_();
|
||||
this->boot_state_ = BootState::WAIT_TOKEN_DATA;
|
||||
break;
|
||||
|
||||
case BootState::SEND_GET_EUI64:
|
||||
this->send_get_eui64_();
|
||||
this->boot_state_ = BootState::WAIT_EUI64;
|
||||
break;
|
||||
|
||||
case BootState::SEND_STACK_PROFILE:
|
||||
this->send_stack_profile_();
|
||||
this->boot_state_ = BootState::WAIT_STACK_PROFILE;
|
||||
break;
|
||||
|
||||
case BootState::SEND_NETWORK_INIT:
|
||||
this->send_network_init_();
|
||||
this->boot_state_ = BootState::WAIT_STACK_STATUS;
|
||||
break;
|
||||
|
||||
case BootState::SEND_GET_NETWORK_PARAMS:
|
||||
this->send_get_network_params_();
|
||||
this->boot_state_ = BootState::WAIT_NETWORK_PARAMS;
|
||||
break;
|
||||
|
||||
case BootState::SEND_FINAL_RST:
|
||||
ESP_LOGV(TAG, "Sending final RST to reset NCP to clean state");
|
||||
this->boot_state_ = BootState::WAIT_FINAL_RSTACK;
|
||||
@@ -684,46 +669,9 @@ void ZigbeeProxy::handle_boot_data_frame_(const uint8_t *data, size_t length) {
|
||||
}
|
||||
break;
|
||||
|
||||
case BootState::WAIT_STACK_PROFILE:
|
||||
if (frame_id == EZSP_SET_CONFIGURATION_VALUE && is_response) {
|
||||
// Response is an EzspStatus, not an sl_status_t. A failure here is not fatal:
|
||||
// networkInit will report NOT_JOINED and the harvest still yields the IEEE
|
||||
// address, so log it and carry on rather than abandoning the sequence.
|
||||
if (payload_length >= 1 && payload[0] != 0x00) {
|
||||
ESP_LOGW(TAG, "setConfigurationValue(CONFIG_STACK_PROFILE) failed: 0x%02X", payload[0]);
|
||||
}
|
||||
this->boot_state_ = BootState::SEND_NETWORK_INIT;
|
||||
this->advance_boot_state_();
|
||||
}
|
||||
break;
|
||||
|
||||
case BootState::WAIT_STACK_STATUS:
|
||||
if (frame_id == EZSP_STACK_STATUS_HANDLER && is_callback) {
|
||||
this->handle_stack_status_(payload, payload_length);
|
||||
} else if (frame_id == EZSP_NETWORK_INIT && is_response) {
|
||||
// networkInit response carries a 32-bit sl_status_t. It only reports that the
|
||||
// request was accepted -- the stack comes up asynchronously afterwards and
|
||||
// announces itself with a stackStatusHandler callback. Querying network
|
||||
// parameters here, before that callback, races the stack and the NCP answers
|
||||
// NOT_JOINED even when the radio is on a network.
|
||||
if (payload_length >= 1) {
|
||||
uint8_t status = payload[0];
|
||||
ESP_LOGV(TAG, "networkInit response: status=0x%02X", status);
|
||||
if (status == static_cast<uint8_t>(SlStatus::NOT_JOINED)) {
|
||||
// No network to bring up, so no callback is coming
|
||||
ESP_LOGD(TAG, "NCP has no network configured");
|
||||
this->boot_state_ = BootState::SEND_GET_EUI64;
|
||||
this->advance_boot_state_();
|
||||
}
|
||||
// Otherwise stay in WAIT_STACK_STATUS for the callback; the boot timeout
|
||||
// guarantees forward progress if it never arrives.
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BootState::WAIT_NETWORK_PARAMS:
|
||||
if (frame_id == EZSP_GET_NETWORK_PARAMETERS && is_response) {
|
||||
this->handle_network_params_response_(payload, payload_length);
|
||||
case BootState::WAIT_TOKEN_DATA:
|
||||
if (frame_id == EZSP_GET_TOKEN_DATA && is_response) {
|
||||
this->handle_token_data_response_(payload, payload_length);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -764,48 +712,25 @@ void ZigbeeProxy::send_get_eui64_() {
|
||||
this->send_data_frame_(cmd, sizeof(cmd), false);
|
||||
}
|
||||
|
||||
void ZigbeeProxy::send_stack_profile_() {
|
||||
void ZigbeeProxy::send_get_token_data_() {
|
||||
// getTokenData takes a 32-bit NVM3 key and a 32-bit index, both little-endian.
|
||||
uint8_t cmd[] = {
|
||||
this->ezsp_sequence_++, // Sequence
|
||||
EZSP_FRAME_CONTROL_COMMAND, // Frame control (low)
|
||||
EZSP_FRAME_CONTROL_EXTENDED, // Frame control (high)
|
||||
EZSP_SET_CONFIGURATION_VALUE & 0xFF, // Frame ID (low)
|
||||
(EZSP_SET_CONFIGURATION_VALUE >> 8) & 0xFF, // Frame ID (high)
|
||||
EZSP_CONFIG_STACK_PROFILE, // configId
|
||||
STACK_PROFILE_ZIGBEE_PRO & 0xFF, // value (low)
|
||||
(STACK_PROFILE_ZIGBEE_PRO >> 8) & 0xFF, // value (high)
|
||||
this->ezsp_sequence_++, // Sequence
|
||||
EZSP_FRAME_CONTROL_COMMAND, // Frame control (low)
|
||||
EZSP_FRAME_CONTROL_EXTENDED, // Frame control (high)
|
||||
EZSP_GET_TOKEN_DATA & 0xFF, // Frame ID (low)
|
||||
(EZSP_GET_TOKEN_DATA >> 8) & 0xFF, // Frame ID (high)
|
||||
NVM3KEY_STACK_NODE_DATA & 0xFF, // token
|
||||
(NVM3KEY_STACK_NODE_DATA >> 8) & 0xFF, //
|
||||
(NVM3KEY_STACK_NODE_DATA >> 16) & 0xFF, //
|
||||
(NVM3KEY_STACK_NODE_DATA >> 24) & 0xFF, //
|
||||
0x00, // index
|
||||
0x00, //
|
||||
0x00, //
|
||||
0x00, //
|
||||
};
|
||||
ash_randomize(cmd, sizeof(cmd));
|
||||
ESP_LOGV(TAG, "Sending EZSP setConfigurationValue(CONFIG_STACK_PROFILE, 2)");
|
||||
this->send_data_frame_(cmd, sizeof(cmd), false);
|
||||
}
|
||||
|
||||
void ZigbeeProxy::send_network_init_() {
|
||||
// networkInitStruct: [bitmask (2 bytes)] - use 0x0000 for default
|
||||
uint8_t cmd[] = {
|
||||
this->ezsp_sequence_++, // Sequence
|
||||
EZSP_FRAME_CONTROL_COMMAND, // Frame control (low)
|
||||
EZSP_FRAME_CONTROL_EXTENDED, // Frame control (high)
|
||||
EZSP_NETWORK_INIT & 0xFF, // Frame ID (low)
|
||||
(EZSP_NETWORK_INIT >> 8) & 0xFF, // Frame ID (high)
|
||||
0x00, // networkInitStruct bitmask (default)
|
||||
0x00,
|
||||
};
|
||||
ash_randomize(cmd, sizeof(cmd));
|
||||
ESP_LOGV(TAG, "Sending EZSP networkInit command");
|
||||
this->send_data_frame_(cmd, sizeof(cmd), false);
|
||||
}
|
||||
|
||||
void ZigbeeProxy::send_get_network_params_() {
|
||||
uint8_t cmd[] = {
|
||||
this->ezsp_sequence_++, // Sequence
|
||||
EZSP_FRAME_CONTROL_COMMAND, // Frame control (low)
|
||||
EZSP_FRAME_CONTROL_EXTENDED, // Frame control (high)
|
||||
EZSP_GET_NETWORK_PARAMETERS & 0xFF, // Frame ID (low)
|
||||
(EZSP_GET_NETWORK_PARAMETERS >> 8) & 0xFF, // Frame ID (high)
|
||||
};
|
||||
ash_randomize(cmd, sizeof(cmd));
|
||||
ESP_LOGV(TAG, "Sending EZSP getNetworkParameters command");
|
||||
ESP_LOGV(TAG, "Sending EZSP getTokenData(NVM3KEY_STACK_NODE_DATA)");
|
||||
this->send_data_frame_(cmd, sizeof(cmd), false);
|
||||
}
|
||||
|
||||
@@ -835,7 +760,7 @@ void ZigbeeProxy::handle_version_response_(const uint8_t *data, size_t length) {
|
||||
// NCP accepted our requested version - treat as success
|
||||
ESP_LOGV(TAG, "NCP accepted EZSP v%d", ncp_version);
|
||||
this->ezsp_version_ = ncp_version;
|
||||
this->boot_state_ = BootState::SEND_STACK_PROFILE;
|
||||
this->boot_state_ = BootState::SEND_TOKEN_DATA;
|
||||
this->advance_boot_state_();
|
||||
return;
|
||||
}
|
||||
@@ -901,7 +826,7 @@ void ZigbeeProxy::handle_version_response_(const uint8_t *data, size_t length) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->boot_state_ = BootState::SEND_STACK_PROFILE;
|
||||
this->boot_state_ = BootState::SEND_TOKEN_DATA;
|
||||
this->advance_boot_state_();
|
||||
}
|
||||
|
||||
@@ -917,69 +842,38 @@ void ZigbeeProxy::handle_eui64_response_(const uint8_t *data, size_t length) {
|
||||
this->advance_boot_state_();
|
||||
}
|
||||
|
||||
void ZigbeeProxy::handle_stack_status_(const uint8_t *data, size_t length) {
|
||||
// stackStatusHandler callback: [status]
|
||||
if (length < 1) {
|
||||
ESP_LOGW(TAG, "Stack status too short");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t status = data[0];
|
||||
ESP_LOGV(TAG, "Stack status: 0x%02X", status);
|
||||
|
||||
// Check for network up status
|
||||
if (status == static_cast<uint8_t>(SlStatus::NETWORK_UP) || status == static_cast<uint8_t>(SlStatus::OK)) {
|
||||
ESP_LOGV(TAG, "Network is up, querying parameters");
|
||||
this->boot_state_ = BootState::SEND_GET_NETWORK_PARAMS;
|
||||
this->advance_boot_state_();
|
||||
} else if (status == static_cast<uint8_t>(SlStatus::NOT_JOINED)) {
|
||||
// No network configured, so there are no parameters to read -- but still read
|
||||
// the EUI64. It is a hardware address that exists regardless of membership, and
|
||||
// it is what lets a client tell an unformed radio apart from an unreachable one.
|
||||
ESP_LOGD(TAG, "No network configured on NCP");
|
||||
this->boot_state_ = BootState::SEND_GET_EUI64;
|
||||
this->advance_boot_state_();
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Unexpected stack status: 0x%02X, continuing anyway", status);
|
||||
// Try to get network params anyway
|
||||
this->boot_state_ = BootState::SEND_GET_NETWORK_PARAMS;
|
||||
this->advance_boot_state_();
|
||||
}
|
||||
}
|
||||
|
||||
void ZigbeeProxy::handle_network_params_response_(const uint8_t *data, size_t length) {
|
||||
// getNetworkParameters response:
|
||||
// [status] [nodeType] [extendedPanId (8)] [panId (2)] [radioTxPower] [radioChannel] ...
|
||||
// A 1-byte response (status only) is normal when the NCP has no network configured.
|
||||
if (length < NETWORK_PARAMS_RESPONSE_SIZE) {
|
||||
if (length <= SL_STATUS_SIZE) {
|
||||
ESP_LOGD(TAG, "NCP has no network configured (status=0x%02X)", data[0]);
|
||||
} else {
|
||||
ESP_LOGW(TAG, "getNetworkParameters response unexpected length: %u bytes", length);
|
||||
}
|
||||
void ZigbeeProxy::handle_token_data_response_(const uint8_t *data, size_t length) {
|
||||
// getTokenData response: [status (4)] [length (4)] [value (length)]
|
||||
// The EUI64 read follows regardless of what happens here: it is a hardware address
|
||||
// that exists whether or not the radio is commissioned, and it is what lets a client
|
||||
// tell an unformed radio apart from an unreachable one.
|
||||
if (length < TOKEN_DATA_VALUE_OFFSET + NV3_NODE_DATA_SIZE) {
|
||||
ESP_LOGW(TAG, "getTokenData response too short: %u bytes", length);
|
||||
this->boot_state_ = BootState::SEND_GET_EUI64;
|
||||
this->advance_boot_state_();
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t status = data[NETWORK_PARAMS_STATUS_OFFSET];
|
||||
if (status != static_cast<uint8_t>(SlStatus::OK)) {
|
||||
ESP_LOGW(TAG, "getNetworkParameters failed with status: 0x%02X", status);
|
||||
if (data[0] != static_cast<uint8_t>(SlStatus::OK)) {
|
||||
ESP_LOGW(TAG, "getTokenData(NVM3KEY_STACK_NODE_DATA) failed: 0x%02X", data[0]);
|
||||
this->boot_state_ = BootState::SEND_GET_EUI64;
|
||||
this->advance_boot_state_();
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract Extended PAN ID (8 bytes, little-endian)
|
||||
memcpy(this->network_info_.extended_pan_id.data(), data + NETWORK_PARAMS_EXT_PAN_ID_OFFSET, 8);
|
||||
const uint8_t *node_data = data + TOKEN_DATA_VALUE_OFFSET;
|
||||
|
||||
// Extract PAN ID (2 bytes, little-endian)
|
||||
if (node_data[NV3_NODE_DATA_NODE_TYPE_OFFSET] == NV3_NODE_TYPE_UNKNOWN_DEVICE) {
|
||||
ESP_LOGD(TAG, "NCP has no network configured");
|
||||
this->boot_state_ = BootState::SEND_GET_EUI64;
|
||||
this->advance_boot_state_();
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(this->network_info_.extended_pan_id.data(), node_data + NV3_NODE_DATA_EXT_PAN_ID_OFFSET, 8);
|
||||
this->network_info_.pan_id =
|
||||
data[NETWORK_PARAMS_PAN_ID_OFFSET] | (static_cast<uint16_t>(data[NETWORK_PARAMS_PAN_ID_OFFSET + 1]) << 8);
|
||||
|
||||
// Extract channel
|
||||
this->network_info_.channel = data[NETWORK_PARAMS_CHANNEL_OFFSET];
|
||||
|
||||
node_data[NV3_NODE_DATA_PAN_ID_OFFSET] | (static_cast<uint16_t>(node_data[NV3_NODE_DATA_PAN_ID_OFFSET + 1]) << 8);
|
||||
this->network_info_.channel = node_data[NV3_NODE_DATA_CHANNEL_OFFSET];
|
||||
this->network_info_.valid = true;
|
||||
this->send_network_info_changed_msg_();
|
||||
|
||||
@@ -994,7 +888,6 @@ void ZigbeeProxy::handle_network_params_response_(const uint8_t *data, size_t le
|
||||
this->network_info_.extended_pan_id[1], this->network_info_.extended_pan_id[0], this->network_info_.pan_id,
|
||||
this->network_info_.channel);
|
||||
|
||||
// The stack is up, so the EUI64 can finally be read
|
||||
this->boot_state_ = BootState::SEND_GET_EUI64;
|
||||
this->advance_boot_state_();
|
||||
}
|
||||
|
||||
@@ -47,22 +47,18 @@ enum ZigbeeProxyFeature : uint32_t {
|
||||
|
||||
// Boot-time initialization state machine
|
||||
enum class BootState : uint8_t {
|
||||
IDLE, // Not initializing
|
||||
WAIT_RSTACK, // Sent RST, waiting for RSTACK
|
||||
SEND_VERSION, // Send EZSP version command
|
||||
WAIT_VERSION, // Waiting for version response
|
||||
SEND_GET_EUI64, // Send getEui64 command
|
||||
WAIT_EUI64, // Waiting for EUI64 response
|
||||
SEND_STACK_PROFILE, // Send setConfigurationValue(CONFIG_STACK_PROFILE)
|
||||
WAIT_STACK_PROFILE, // Waiting for setConfigurationValue response
|
||||
SEND_NETWORK_INIT, // Send networkInit command
|
||||
WAIT_STACK_STATUS, // Waiting for stackStatusHandler callback
|
||||
SEND_GET_NETWORK_PARAMS, // Send getNetworkParameters command
|
||||
WAIT_NETWORK_PARAMS, // Waiting for network parameters response
|
||||
SEND_FINAL_RST, // Send final RST to reset NCP
|
||||
WAIT_FINAL_RSTACK, // Waiting for final RSTACK
|
||||
COMPLETE, // Boot sequence complete
|
||||
FAILED, // Boot sequence failed
|
||||
IDLE, // Not initializing
|
||||
WAIT_RSTACK, // Sent RST, waiting for RSTACK
|
||||
SEND_VERSION, // Send EZSP version command
|
||||
WAIT_VERSION, // Waiting for version response
|
||||
SEND_TOKEN_DATA, // Send getTokenData(NVM3KEY_STACK_NODE_DATA)
|
||||
WAIT_TOKEN_DATA, // Waiting for token data response
|
||||
SEND_GET_EUI64, // Send getEui64 command
|
||||
WAIT_EUI64, // Waiting for EUI64 response
|
||||
SEND_FINAL_RST, // Send final RST to reset NCP
|
||||
WAIT_FINAL_RSTACK, // Waiting for final RSTACK
|
||||
COMPLETE, // Boot sequence complete
|
||||
FAILED, // Boot sequence failed
|
||||
};
|
||||
|
||||
class ZigbeeProxy : public uart::UARTDevice, public Component {
|
||||
@@ -157,13 +153,10 @@ class ZigbeeProxy : public uart::UARTDevice, public Component {
|
||||
void handle_boot_data_frame_(const uint8_t *data, size_t length);
|
||||
void send_ezsp_version_();
|
||||
void send_get_eui64_();
|
||||
void send_stack_profile_();
|
||||
void send_network_init_();
|
||||
void send_get_network_params_();
|
||||
void send_get_token_data_();
|
||||
void handle_version_response_(const uint8_t *data, size_t length);
|
||||
void handle_eui64_response_(const uint8_t *data, size_t length);
|
||||
void handle_stack_status_(const uint8_t *data, size_t length);
|
||||
void handle_network_params_response_(const uint8_t *data, size_t length);
|
||||
void handle_token_data_response_(const uint8_t *data, size_t length);
|
||||
|
||||
// IEEE address and network info
|
||||
bool set_ieee_address_(const uint8_t *new_address);
|
||||
@@ -313,7 +306,7 @@ class ZigbeeProxy : public uart::UARTDevice, public Component {
|
||||
bool owns_uart_{false}; // True while this component drives the UART
|
||||
uint32_t configured_baud_rate_{0}; // Line rate to restore after another device
|
||||
|
||||
bool boot_sequence_active_{false}; // True during boot-time init
|
||||
bool boot_sequence_active_{false}; // True during boot-time init
|
||||
};
|
||||
|
||||
extern ZigbeeProxy *global_zigbee_proxy; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
|
||||
Reference in New Issue
Block a user