6.5 KiB
STM32WB55 Zigbee master/slave notes
Project files
- Keil project:
MDK-ARM/Zigbee_OnOff_Server_Coord.uvprojx - Main app config:
App/app_config.h - Shared data types:
App/app_types.h - GPIO/hardware layer:
App/hardware.c - Slave input scan/debounce:
App/slave_inputs.c - App role/process logic:
App/zigbee_app.c - Zigbee adapter:
App/zigbee_port.c - STM32_WPAN Zigbee implementation:
STM32_WPAN/App/app_zigbee.c
Roles
Role is selected at build time while role detect is disabled:
#define APP_ROLE_DEFAULT APP_ROLE_MASTER
#define APP_ROLE_DETECT_ENABLED 0U
For the slave firmware build:
#define APP_ROLE_DEFAULT APP_ROLE_SLAVE
APP_ROLE_MASTER forms the Zigbee network as coordinator.
APP_ROLE_SLAVE joins the coordinator network and sends input reports.
Pins
Button inputs:
| Signal | Port | Pin | Active level |
|---|---|---|---|
| Button 1 | GPIOB | GPIO_PIN_0 | 0 |
| Button 2 | GPIOB | GPIO_PIN_1 | 0 |
| Button 3 | GPIOB | GPIO_PIN_2 | 0 |
Config:
#define APP_BUTTON_ACTIVE_LEVEL 0U
#define APP_BUTTON_DEBOUNCE_MS 20U
#define APP_BUTTON_GPIO_PORT GPIOB
#define APP_BUTTON1_GPIO_PIN GPIO_PIN_0
#define APP_BUTTON2_GPIO_PIN GPIO_PIN_1
#define APP_BUTTON3_GPIO_PIN GPIO_PIN_2
Role/status LED:
| Signal | Port | Pin | Active level |
|---|---|---|---|
| APP_ROLE_LED | GPIOE | GPIO_PIN_4 | GPIO_PIN_SET |
Config:
#define APP_ROLE_LED_GPIO_PORT GPIOE
#define APP_ROLE_LED_GPIO_PIN GPIO_PIN_4
#define APP_ROLE_LED_ACTIVE_LEVEL GPIO_PIN_SET
Role detect pins are currently unused:
#define APP_ROLE_DETECT_ENABLED 0U
#define APP_ROLE_DETECT_GPIO_PORT GPIOA
#define APP_ROLE_DETECT_GPIO_PIN GPIO_PIN_9
#define APP_ROLE_DETECT_PULL GPIO_PULLDOWN
#define APP_ROLE_DETECT_MASTER_LEVEL GPIO_PIN_RESET
ADC is reserved in the app model, but Hardware_ReadAnalogRaw() currently returns 0.
Zigbee network settings
#define APP_ZIGBEE_ENDPOINT 10U
#define APP_ZIGBEE_CLUSTER_INPUTS 0xFC10U
#define APP_ZIGBEE_REPORT_PERIOD_MS 100U
#define APP_ZIGBEE_CHANNEL 20U
#define APP_ZIGBEE_PAN_ID 0x1234U
#define APP_ZIGBEE_EXTENDED_PAN_ID 0x1122334455667788ULL
#define APP_ZIGBEE_PERMIT_JOIN_SEC 0xFFU
#define APP_ZIGBEE_PERMIT_REFRESH_MS 5000U
#define APP_ZIGBEE_REJOIN_FAIL_COUNT 3U
#define APP_ZIGBEE_REJOIN_RETRY_MS 15000U
Master opens permit-join and refreshes it every 5 seconds.
Slave sends reports to coordinator short address 0x0000, endpoint APP_ZIGBEE_ENDPOINT.
Current slave TX options:
ZB_APSDE_DATAREQ_TXOPTIONS_SECURITY | ZB_APSDE_DATAREQ_TXOPTIONS_ACK
ACK is enabled so slave can detect ZB_APS_STATUS_NO_ACK when master is missing.
Slave input data
Local slave input state:
typedef struct
{
AppButton_t buttons[3];
AppAnalogChannel_t analog;
uint32_t sequence;
} AppSlaveInputs_t;
Report sent over Zigbee:
typedef struct
{
uint32_t sequence;
uint8_t button_mask;
uint16_t analog_raw;
uint8_t analog_percent;
} AppSlaveReport_t;
Button mask bits:
| Bit | Button |
|---|---|
| bit0 | Button 1 |
| bit1 | Button 2 |
| bit2 | Button 3 |
Examples:
| button_mask | Meaning |
|---|---|
| 0 | No buttons pressed |
| 1 | Button 1 |
| 2 | Button 2 |
| 4 | Button 3 |
| 3 | Button 1 + Button 2 |
| 7 | All 3 buttons |
Wire payload, 8 bytes:
| Byte | Field |
|---|---|
| 0..3 | sequence, little-endian |
| 4 | button_mask |
| 5..6 | analog_raw, little-endian |
| 7 | analog_percent |
Master stores the last received report here:
g_app.master_node.last_report
g_app.master_node.last_report.button_mask
Connection behavior
Master APP_ZB_CONNECTED means the coordinator formed its Zigbee network.
It does not mean that slave is online.
Slave is considered visible on master only after first report:
g_app.master_node.online = true;
watch_master_online = 1;
watch_report_rx_count++;
When master is turned off while slave is running:
- Slave TX confirm starts returning
0xA7(ZB_APS_STATUS_NO_ACK). watch_report_tx_fail_streakincreases.- After
APP_ZIGBEE_REJOIN_FAIL_COUNTfailures, slave resets local Zigbee stack withZbReset(). - Slave starts normal join again through
CFG_TASK_ZIGBEE_NETWORK_FORM.
When slave is reset while master is running:
- Master must keep permit-join open.
- Check
watch_permit_join_count,watch_permit_join_status, andwatch_permit_join_durationon master. - Expected values: count increases, status
0, duration0xFF.
LED status patterns
LED: APP_ROLE_LED on GPIOE pin 4.
Patterns are non-blocking and updated from ZigbeeApp_UpdateStatusLed().
| State | Pattern |
|---|---|
| DISCONNECTED | Short flash every 400 ms |
| JOINING | Fast 80 ms on / 80 ms off |
| ERROR | Very fast 50 ms on / 50 ms off |
| CONNECTED master | One short flash every second |
| CONNECTED slave | Two short flashes every second |
Useful watch variables
Role/state:
watch_role
watch_is_master
watch_is_slave
watch_zigbee_state
watch_zigbee_ready
Master receive:
watch_master_online
watch_master_last_seen_ms
watch_master_last_sequence
watch_master_button_mask
watch_report_rx_count
watch_report_rx_ind_count
watch_report_rx_decode_fail_count
watch_report_rx_last_cluster
watch_report_rx_last_length
Slave transmit:
watch_slave_sequence
watch_slave_button_mask
watch_report_tx_count
watch_report_tx_attempt_count
watch_report_tx_ok_count
watch_report_tx_busy_count
watch_report_tx_confirm_count
watch_report_tx_confirm_status
watch_report_tx_fail_streak
Rejoin/recovery:
watch_rejoin_request_count
watch_rejoin_success_count
watch_rejoin_fail_count
watch_rejoin_active
watch_rejoin_last_status
Master permit-join:
watch_permit_join_count
watch_permit_join_status
watch_permit_join_duration
Common status codes
| Code | Meaning |
|---|---|
| 0x00 | Success |
| 0xA7 | ZB_APS_STATUS_NO_ACK, destination did not ACK |
| 0xCA | ZB_NWK_STATUS_NO_NETWORKS, no matching network found |
| 0xD0 | ZB_NWK_STATUS_ROUTE_DISCOVERY_FAILED |
| 0xD1 | ZB_NWK_STATUS_ROUTE_ERROR |
Current debug checklist
Master after startup:
watch_is_master = 1
watch_zigbee_state = 2
watch_permit_join_count increasing
watch_permit_join_status = 0
watch_permit_join_duration = 0xFF
Slave after join:
watch_is_slave = 1
watch_zigbee_state = 2
watch_zigbee_ready = 1
watch_report_tx_confirm_status = 0
Master after receiving slave:
watch_master_online = 1
watch_report_rx_count increasing
watch_master_button_mask follows slave buttons