#include "app_config.h" #include "app_types.h" AppContext_t g_app = { .role = APP_ROLE_DEFAULT, .zigbee_state = APP_ZB_DISCONNECTED, .slave_inputs = { .buttons = { { .pressed = false, .changed = false, .last_change_ms = 0U }, { .pressed = false, .changed = false, .last_change_ms = 0U }, { .pressed = false, .changed = false, .last_change_ms = 0U } }, .analog = { .raw = 0U, .filtered = 0U, .percent = 0U }, .sequence = 0U }, .master_node = { .online = false, .last_report = { .sequence = 0U, .button_mask = 0U, .analog_raw = 0U, .analog_percent = 0U }, .last_seen_ms = 0U }, .zigbee = { .pan_id = APP_ZIGBEE_PAN_ID, .channel = APP_ZIGBEE_CHANNEL, .endpoint = APP_ZIGBEE_ENDPOINT, .cluster_id = APP_ZIGBEE_CLUSTER_INPUTS }, .uptime_ms = 0U, .last_report_ms = 0U }; volatile uint32_t watch_role = APP_ROLE_DEFAULT; volatile uint32_t watch_is_master = 0U; volatile uint32_t watch_is_slave = 1U; volatile uint32_t watch_role_pin_is_master = 0U; volatile uint32_t watch_zigbee_state = APP_ZB_DISCONNECTED; volatile uint32_t watch_master_online = 0U; volatile uint32_t watch_master_last_seen_ms = 0U; volatile uint32_t watch_master_last_sequence = 0U; volatile uint32_t watch_master_button_mask = 0U; volatile uint32_t watch_master_analog_raw = 0U; volatile uint32_t watch_master_analog_percent = 0U; volatile uint32_t watch_slave_sequence = 0U; volatile uint32_t watch_slave_button_mask = 0U; volatile uint32_t watch_slave_analog_raw = 0U; volatile uint32_t watch_slave_analog_percent = 0U; volatile uint32_t watch_report_tx_count = 0U; volatile uint32_t watch_report_rx_count = 0U; volatile uint32_t watch_report_tx_attempt_count = 0U; volatile uint32_t watch_report_tx_ok_count = 0U; volatile uint32_t watch_report_tx_busy_count = 0U; volatile uint32_t watch_report_tx_confirm_count = 0U; volatile uint32_t watch_report_tx_confirm_status = 0U; volatile uint32_t watch_report_rx_ind_count = 0U; volatile uint32_t watch_report_rx_decode_fail_count = 0U; volatile uint32_t watch_report_rx_last_cluster = 0U; volatile uint32_t watch_report_rx_last_length = 0U; volatile uint32_t watch_zigbee_ready = 0U; volatile uint32_t watch_rejoin_request_count = 0U; volatile uint32_t watch_rejoin_success_count = 0U; volatile uint32_t watch_rejoin_fail_count = 0U; volatile uint32_t watch_rejoin_active = 0U; volatile uint32_t watch_rejoin_last_status = 0U; volatile uint32_t watch_report_tx_fail_streak = 0U; volatile uint32_t watch_permit_join_count = 0U; volatile uint32_t watch_permit_join_status = 0U; volatile uint32_t watch_permit_join_duration = 0U; volatile uint32_t watch_join_watchdog_count = 0U; static void App_DebugCopyReportToMasterWatch(const AppSlaveReport_t *report) { watch_master_last_sequence = report->sequence; watch_master_button_mask = report->button_mask; watch_master_analog_raw = report->analog_raw; watch_master_analog_percent = report->analog_percent; } static void App_DebugCopyReportToSlaveWatch(const AppSlaveReport_t *report) { watch_slave_sequence = report->sequence; watch_slave_button_mask = report->button_mask; watch_slave_analog_raw = report->analog_raw; watch_slave_analog_percent = report->analog_percent; } const char *App_RoleName(AppRole_t role) { return (role == APP_ROLE_MASTER) ? "master" : "slave"; } void App_SetRole(AppRole_t role) { g_app.role = role; g_app.zigbee_state = APP_ZB_DISCONNECTED; g_app.last_report_ms = 0U; } AppSlaveReport_t App_MakeSlaveReport(const AppSlaveInputs_t *inputs) { AppSlaveReport_t report; uint8_t mask = 0U; for (uint8_t i = 0U; i < APP_BUTTON_COUNT; i++) { if (inputs->buttons[i].pressed) { mask |= (uint8_t)(1U << i); } } report.sequence = inputs->sequence; report.button_mask = mask; report.analog_raw = inputs->analog.raw; report.analog_percent = inputs->analog.percent; return report; } void App_MasterAcceptReport(const AppSlaveReport_t *report, uint32_t now_ms) { g_app.master_node.online = true; g_app.master_node.last_report = *report; g_app.master_node.last_seen_ms = now_ms; watch_report_rx_count++; App_DebugCopyReportToMasterWatch(report); App_DebugRefresh(watch_role_pin_is_master); } void App_DebugRefresh(uint32_t role_pin_is_master) { watch_role = (uint32_t)g_app.role; watch_is_master = (g_app.role == APP_ROLE_MASTER) ? 1U : 0U; watch_is_slave = (g_app.role == APP_ROLE_SLAVE) ? 1U : 0U; watch_role_pin_is_master = role_pin_is_master; watch_zigbee_state = (uint32_t)g_app.zigbee_state; watch_master_online = g_app.master_node.online ? 1U : 0U; watch_master_last_seen_ms = g_app.master_node.last_seen_ms; App_DebugCopyReportToMasterWatch(&g_app.master_node.last_report); } void App_DebugOnSlaveReportTx(const AppSlaveReport_t *report) { watch_report_tx_count++; App_DebugCopyReportToSlaveWatch(report); }