cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB55 - First data sent but no one after connection to ZigBee network

Aquatwix
Associate

Hello everyone,

I decided to write on this forum after encountering a problem with the implementation of ZigBee on my STM32WB55 microcontroller. Currently, the board connects to the network and sends the first data, but nothing happens afterwards.

I am using the LAUNCHXL-CC1352P as the RCP which is connected to my computer and I run the Zigbee2MQTT 1.37.0 process. I'm using the same configuration for the Zlinky module and everything works fine, so I assume that part of the receiver works.

As far as the FW is concerned, I would like to use the RTC to set a measurement task and send data every 30 seconds (for the moment). On the other hand, I have used some examples on ST's GitHub, in particular for the SED configuration. After some tests with LEDs, I can confirm that the RTC is working correctly.

I have the impression that each new task configuration is ignored but I don't know why and the debbug mode do not help me at all.

Thank you in advance for your help.

Here is HAL_RTC_AlarmAEventCallback(), which is triggered every second but sends data every 30 seconds :

 

 

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
    // Désactivation du mode STOP pendant les mesures du capteur
    // UTIL_LPM_SetStopMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE);

    RTC_AlarmTypeDef sAlarm;
    HAL_RTC_GetAlarm(hrtc, &sAlarm, RTC_ALARM_A, FORMAT_BIN);

    if(sAlarm.AlarmTime.Seconds % 30 == 0)
    {
    	HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET);
    	sAlarm.AlarmTime.Seconds = 0;
    	UTIL_SEQ_SetTask(1U << CFG_TASK_MEASURE_SENSOR, CFG_SCH_PRIO_0);
    }

	sAlarm.AlarmTime.Seconds = sAlarm.AlarmTime.Seconds + 1;


    while(HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, FORMAT_BIN)!=HAL_OK){}

    // Réactivation du mode STOP après les mesures du capteur
    // UTIL_LPM_SetStopMode(1 << CFG_LPM_APP, UTIL_LPM_ENABLE);
}

 

 

Here is the app_zigbee.c : 

 

/* Includes ------------------------------------------------------------------*/
#include "app_common.h"
#include "app_entry.h"
#include "dbg_trace.h"
#include "app_zigbee.h"
#include "zigbee_interface.h"
#include "shci.h"
#include "stm_logging.h"
#include "app_conf.h"
#include "stm32wbxx_core_interface_def.h"
#include "zigbee_types.h"
#include "stm32_seq.h"
#include "stm32_lpm.h"

/* Private includes -----------------------------------------------------------*/
#include <assert.h>
#include "zcl/zcl.h"

/* USER CODE BEGIN Includes */
#include "gpio.h"
#include "scd4x_i2c.h"
#include "lptim.h"
#include "SensorsController.h"
#include "zcl/general/zcl.temp.meas.h"

#define HW_TS_SERVER_1S_NB_TICKS                    (1*1000*1000/CFG_TS_TICK_VAL) /* 1s */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* Temperature_meas (endpoint 1) specific defines ------------------------------------------------*/
#define TEMP_MIN_1                      0xf060 /* -40C */
#define TEMP_MAX_1                      0x30d4 /* 125C */
#define TEMP_TOLERANCE_1                0x0032 /* +/- 0.5C */
/* USER CODE BEGIN Temperature_meas (endpoint 1) defines */
/* USER CODE END Temperature_meas (endpoint 1) defines */

/* Water_content (endpoint 1) specific defines ------------------------------------------------*/

/* USER CODE END PTD */

/* Private defines -----------------------------------------------------------*/
#define APP_ZIGBEE_STARTUP_FAIL_DELAY               500U
#define CHANNEL                                     25
#define ZED_SLEEP_TIME_30S                           1 /* 30s sleep time unit */

#define SW1_ENDPOINT                                1

/* USER CODE BEGIN PD */
#define TEMP_INI 0
#define HUMIDITY_INI 0
#define CO2_INI 0
/* USER CODE END PD */

/* Private macros ------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */

/* External definition -------------------------------------------------------*/
enum ZbStatusCodeT ZbStartupWait(struct ZigBeeT *zb, struct ZbStartupT *config);

/* USER CODE BEGIN ED */
/* USER CODE END ED */

/* Private function prototypes -----------------------------------------------*/
static void APP_ZIGBEE_StackLayersInit(void);
static void APP_ZIGBEE_ConfigEndpoints(void);
static void APP_ZIGBEE_NwkForm(void);

static void APP_ZIGBEE_TraceError(const char *pMess, uint32_t ErrCode);
static void APP_ZIGBEE_CheckWirelessFirmwareInfo(void);

static void Wait_Getting_Ack_From_M0(void);
static void Receive_Ack_From_M0(void);
static void Receive_Notification_From_M0(void);

static void APP_ZIGBEE_ProcessNotifyM0ToM4(void);
static void APP_ZIGBEE_ProcessRequestM0ToM4(void);

/* USER CODE BEGIN PFP */
static void APP_ZIGBEE_MeasureSensor(void);
/* USER CODE END PFP */

/* Private variables ---------------------------------------------------------*/
static TL_CmdPacket_t   *p_ZIGBEE_otcmdbuffer;
static TL_EvtPacket_t   *p_ZIGBEE_notif_M0_to_M4;
static TL_EvtPacket_t   *p_ZIGBEE_request_M0_to_M4;
static __IO uint32_t    CptReceiveNotifyFromM0 = 0;
static __IO uint32_t    CptReceiveRequestFromM0 = 0;

PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_ZIGBEE_Config_t ZigbeeConfigBuffer;
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t ZigbeeOtCmdBuffer;
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ZigbeeNotifRspEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U];
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ZigbeeNotifRequestBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U];

struct zigbee_app_info
{
  bool has_init;
  struct ZigBeeT *zb;
  enum ZbStartType startupControl;
  enum ZbStatusCodeT join_status;
  uint32_t join_delay;
  bool init_after_join;

  struct ZbZclClusterT *temperature_meas_server_1;
};
static struct zigbee_app_info zigbee_app_info;

/* USER CODE BEGIN PV */
  //struct ZbZclClusterT *temperature_meas_server_1;
  struct sensors_controller_t sensors_controller;
/* USER CODE END PV */
/* Functions Definition ------------------------------------------------------*/

/**
 * @brief  Zigbee application initialization
 * @PAram  None
 * @retval None
 */
void APP_ZIGBEE_Init(void)
{
   SHCI_CmdStatus_t ZigbeeInitStatus;

  APP_ZIGBEE_CheckWirelessFirmwareInfo();

  APP_ZIGBEE_RegisterCmdBuffer(&ZigbeeOtCmdBuffer);

  /* Init config buffer and call TL_ZIGBEE_Init */
  APP_ZIGBEE_TL_INIT();

  /* Register task */
  UTIL_SEQ_RegTask(1U << (uint32_t)CFG_TASK_NOTIFY_FROM_M0_TO_M4, UTIL_SEQ_RFU, APP_ZIGBEE_ProcessNotifyM0ToM4);
  UTIL_SEQ_RegTask(1U << (uint32_t)CFG_TASK_REQUEST_FROM_M0_TO_M4, UTIL_SEQ_RFU, APP_ZIGBEE_ProcessRequestM0ToM4);

  UTIL_SEQ_RegTask(1U << CFG_TASK_ZIGBEE_NETWORK_FORM, UTIL_SEQ_RFU, APP_ZIGBEE_NwkForm);

  /* USER CODE BEGIN APP_ZIGBEE_INIT */
  UTIL_SEQ_RegTask(1U << CFG_TASK_MEASURE_SENSOR, UTIL_SEQ_RFU, APP_ZIGBEE_MeasureSensor);
  /* USER CODE END APP_ZIGBEE_INIT */

  /* Start the Zigbee on the CPU2 side */
  ZigbeeInitStatus = SHCI_C2_ZIGBEE_Init();
  /* Prevent unused argument(s) compilation warning */
  UNUSED(ZigbeeInitStatus);

  /* Initialize Zigbee stack layers */
  APP_ZIGBEE_StackLayersInit();
}

/**
 * @brief  Initialize Zigbee stack layers
 * @PAram  None
 * @retval None
 */
static void APP_ZIGBEE_StackLayersInit(void)
{
  APP_DBG("APP_ZIGBEE_StackLayersInit");

  zigbee_app_info.zb = ZbInit(0U, NULL, NULL);
  assert(zigbee_app_info.zb != NULL);

  /* Create the endpoint and cluster(s) */
  APP_ZIGBEE_ConfigEndpoints();

  /* USER CODE BEGIN APP_ZIGBEE_StackLayersInit */
  /* USER CODE END APP_ZIGBEE_StackLayersInit */

  /* Configure the joining parameters */
  zigbee_app_info.join_status = (enum ZbStatusCodeT) 0x01; /* init to error status */
  zigbee_app_info.join_delay = HAL_GetTick(); /* now */
  zigbee_app_info.startupControl = ZbStartTypeJoin;

  /* Initialization Complete */
  zigbee_app_info.has_init = true;

  /* run the task */
  UTIL_SEQ_SetTask(1U << CFG_TASK_ZIGBEE_NETWORK_FORM, CFG_SCH_PRIO_0);
}

/**
 * @brief  Configure Zigbee application endpoints
 * @PAram  None
 * @retval None
 */
static void APP_ZIGBEE_ConfigEndpoints(void)
{
  struct ZbApsmeAddEndpointReqT req;
  struct ZbApsmeAddEndpointConfT conf;

  memset(&req, 0, sizeof(req));

  /* Endpoint: SW1_ENDPOINT */
  req.profileId = ZCL_PROFILE_HOME_AUTOMATION;
  req.deviceId = ZCL_DEVICE_SIMPLE_SENSOR;
  req.endpoint = SW1_ENDPOINT;
  ZbZclAddEndpoint(zigbee_app_info.zb, &req, &conf);
  assert(conf.status == ZB_STATUS_SUCCESS);

  /* USER CODE BEGIN CONFIG_ENDPOINT */

  /* Temperature meas server */
   zigbee_app_info.temperature_meas_server_1 = ZbZclTempMeasServerAlloc(zigbee_app_info.zb, SW1_ENDPOINT, TEMP_MIN_1, TEMP_MAX_1, TEMP_TOLERANCE_1);
   assert(zigbee_app_info.temperature_meas_server_1 != NULL);
   ZbZclClusterEndpointRegister(zigbee_app_info.temperature_meas_server_1);
  /* USER CODE END CONFIG_ENDPOINT */
}

/**
 * @brief  Handle Zigbee network forming and joining
 * @PAram  None
 * @retval None
 */
static void APP_ZIGBEE_NwkForm(void)
{
  if ((zigbee_app_info.join_status != ZB_STATUS_SUCCESS) && (HAL_GetTick() >= zigbee_app_info.join_delay))
  {
    struct ZbStartupT config;
    enum ZbStatusCodeT status;

    /* Configure Zigbee Logging */
    ZbSetLogging(zigbee_app_info.zb, ZB_LOG_MASK_LEVEL_5, NULL);

    /* Attempt to join a zigbee network */
    ZbStartupConfigGetProDefaults(&config);

    /* Set the centralized network */
    APP_DBG("Network config : APP_STARTUP_CENTRALIZED_END_DEVICE");
    config.startupControl = zigbee_app_info.startupControl;

    /* Using the default HA preconfigured Link Key */
    memcpy(config.security.preconfiguredLinkKey, sec_key_ha, ZB_SEC_KEYSIZE);

    config.channelList.count = 1;
    config.channelList.list[0].page = 0;
    config.channelList.list[0].channelMask = 1 << CHANNEL; /*Channel in use */

    /* Add End device configuration */
    config.capability &= ~(MCP_ASSOC_CAP_RXONIDLE | MCP_ASSOC_CAP_DEV_TYPE | MCP_ASSOC_CAP_ALT_COORD);
    config.endDeviceTimeout=ZED_SLEEP_TIME_30S;

    /* Using ZbStartupWait (blocking) */
    status = ZbStartupWait(zigbee_app_info.zb, &config);

    APP_DBG("ZbStartup Callback (status = 0x%02x)", status);
    zigbee_app_info.join_status = status;

    if (status == ZB_STATUS_SUCCESS)
    {
      /* Enabling Stop mode */
      UTIL_LPM_SetStopMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE);
      UTIL_LPM_SetOffMode(1U << CFG_LPM_APP, UTIL_LPM_DISABLE);

      zigbee_app_info.join_delay = 0U;
      zigbee_app_info.init_after_join = true;
      APP_DBG("Startup done !\n");
      /* USER CODE BEGIN 0 */
      UTIL_LPM_SetStopMode(1U << CFG_LPM_APP, UTIL_LPM_DISABLE);   //We deactivate the stop mode however the bind is not effective
      HAL_Delay(3000);		//We put a delay to be sure that the different fields are binded with the server
      /* USER CODE END 0 */
    }
    else
    {
      APP_DBG("Startup failed, attempting again after a short delay (%d ms)", APP_ZIGBEE_STARTUP_FAIL_DELAY);
      zigbee_app_info.join_delay = HAL_GetTick() + APP_ZIGBEE_STARTUP_FAIL_DELAY;
      /* USER CODE BEGIN 1 */

      /* USER CODE END 1 */
    }
  }

  /* If Network forming/joining was not successful reschedule the current task to retry the process */
  if (zigbee_app_info.join_status != ZB_STATUS_SUCCESS)
  {
    UTIL_SEQ_SetTask(1U << CFG_TASK_ZIGBEE_NETWORK_FORM, CFG_SCH_PRIO_0);
  }
  /* USER CODE BEGIN NW_FORM */
  else {
	  UTIL_SEQ_SetTask(1U << CFG_TASK_MEASURE_SENSOR, CFG_SCH_PRIO_0);
  }
  /* USER CODE END NW_FORM */
}


/*************************************************************
 * ZbStartupWait Blocking Call
 *************************************************************/
struct ZbStartupWaitInfo
{
  bool active;
  enum ZbStatusCodeT status;
};

static void ZbStartupWaitCb(enum ZbStatusCodeT status, void *cb_arg)
{
  struct ZbStartupWaitInfo *info = cb_arg;

  info->status = status;
  info->active = false;
  UTIL_SEQ_SetEvt(EVENT_ZIGBEE_STARTUP_ENDED);
}

enum ZbStatusCodeT ZbStartupWait(struct ZigBeeT *zb, struct ZbStartupT *config)
{
  struct ZbStartupWaitInfo *info;
  enum ZbStatusCodeT status;

  info = malloc(sizeof(struct ZbStartupWaitInfo));
  if (info == NULL)
  {
    return ZB_STATUS_ALLOC_FAIL;
  }
  memset(info, 0, sizeof(struct ZbStartupWaitInfo));

  info->active = true;
  status = ZbStartup(zb, config, ZbStartupWaitCb, info);
  if (status != ZB_STATUS_SUCCESS)
  {
    free(info);
    return status;
  }

  UTIL_SEQ_WaitEvt(EVENT_ZIGBEE_STARTUP_ENDED);
  status = info->status;
  free(info);
  return status;
}

/**
 * @brief  Trace the error or the warning reported.
 * @PAram  ErrId :
 * @PAram  ErrCode
 * @retval None
 */
void APP_ZIGBEE_Error(uint32_t ErrId, uint32_t ErrCode)
{
  switch (ErrId)
  {
    default:
      APP_ZIGBEE_TraceError("ERROR Unknown ", 0);
      break;
  }
}

/*************************************************************
 *
 * LOCAL FUNCTIONS
 *
 *************************************************************/

/**
 * @brief  Warn the user that an error has occurred.
 *
 * @PAram  pMess  : Message associated to the error.
 * @PAram  ErrCode: Error code associated to the module (Zigbee or other module if any)
 * @retval None
 */
static void APP_ZIGBEE_TraceError(const char *pMess, uint32_t ErrCode)
{
  APP_DBG("**** Fatal error = %s (Err = %d)", pMess, ErrCode);
  /* USER CODE BEGIN TRACE_ERROR */
  /* USER CODE END TRACE_ERROR */

}

/**
 * @brief Check if the Coprocessor Wireless Firmware loaded supports Zigbee
 *        and display associated information
 * @PAram  None
 * @retval None
 */
static void APP_ZIGBEE_CheckWirelessFirmwareInfo(void)
{
  WirelessFwInfo_t wireless_info_instance;
  WirelessFwInfo_t *p_wireless_info = &wireless_info_instance;

  if (SHCI_GetWirelessFwInfo(p_wireless_info) != SHCI_Success)
  {
    APP_ZIGBEE_Error((uint32_t)ERR_ZIGBEE_CHECK_WIRELESS, (uint32_t)ERR_INTERFACE_FATAL);
  }
  else
  {
    APP_DBG("**********************************************************");
    APP_DBG("WIRELESS COPROCESSOR FW:");
    /* Print version */
    APP_DBG("VERSION ID = %d.%d.%d", p_wireless_info->VersionMajor, p_wireless_info->VersionMinor, p_wireless_info->VersionSub);

    switch (p_wireless_info->StackType)
    {
      case INFO_STACK_TYPE_ZIGBEE_FFD:
        APP_DBG("FW Type : FFD Zigbee stack");
        break;

      case INFO_STACK_TYPE_ZIGBEE_RFD:
        APP_DBG("FW Type : RFD Zigbee stack");
        break;

      default:
        /* No Zigbee device supported ! */
        APP_ZIGBEE_Error((uint32_t)ERR_ZIGBEE_CHECK_WIRELESS, (uint32_t)ERR_INTERFACE_FATAL);
        break;
    }

    /* print the application name */
    char *__PathProject__ = (strstr(__FILE__, "Zigbee") ? strstr(__FILE__, "Zigbee") + 7 : __FILE__);
    char *pdel = NULL;
    if((strchr(__FILE__, '/')) == NULL)
    {
      pdel = strchr(__PathProject__, '\\');
    }
    else
    {
      pdel = strchr(__PathProject__, '/');
    }

    int index = (int)(pdel - __PathProject__);
    APP_DBG("Application flashed: %*.*s", index, index, __PathProject__);

    /* print channel */
    APP_DBG("Channel used: %d", CHANNEL);
    /* print Link Key */
    APP_DBG("Link Key: %.16s", sec_key_ha);
    /* print Link Key value hex */
    char Z09_LL_string[ZB_SEC_KEYSIZE*3+1];
    Z09_LL_string[0] = 0;
    for (int str_index = 0; str_index < ZB_SEC_KEYSIZE; str_index++)
    {
      sprintf(&Z09_LL_string[str_index*3], "%02x ", sec_key_ha[str_index]);
    }

    APP_DBG("Link Key value: %s", Z09_LL_string);
    /* print clusters allocated */
    APP_DBG("Clusters allocated are:");
    APP_DBG("**********************************************************");
  }
}

/* Wrap Functions */

/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */
static void APP_ZIGBEE_MeasureSensor(void)
{
	uint16_t test = 0x000E;
	ZbZclAttrIntegerWrite(zigbee_app_info.temperature_meas_server_1, ZCL_TEMP_MEAS_ATTR_MEAS_VAL, (int16_t)(test));
	HAL_Delay(375); //Useful to let MCU the time for sending data before sleep
}

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Ouadi
ST Employee

Hi @Aquatwix,

First, welcome to the community.

Looking at your source code, I understand that your application configures the device as a Zigbee Sleepy end device and updates the attribute ZCL_TEMP_MEAS_ATTR_MEAS_VAL locally each 30 seconds, however, I don't see any task of sending the attribute over the air. 

API ZbZclAttrIntegerWrite is used to perform a local write attribute where the new value is updated on the application side, the client can then read this value over the air. For more details on the differences between remote and local write APIs, please have a look to this Application Note 

In your case, you can configure the Temp Meas Attribute to be reportable with a defined period, you can follow steps on these posts describing the procedure :

Post1 : Zigbee example/help on how to configure and send values 

Post2 : STM32WB55 Zigbee - Can't report value 

Please be careful using Hal_Delay() which is an active polling loop that blocks the process waiting the end of the delay, for Zigbee applications, a callback condition can be used to check the status of an over the air request. 

Kind regards,

Ouadi

View solution in original post

2 REPLIES 2
Ouadi
ST Employee

Hi @Aquatwix,

First, welcome to the community.

Looking at your source code, I understand that your application configures the device as a Zigbee Sleepy end device and updates the attribute ZCL_TEMP_MEAS_ATTR_MEAS_VAL locally each 30 seconds, however, I don't see any task of sending the attribute over the air. 

API ZbZclAttrIntegerWrite is used to perform a local write attribute where the new value is updated on the application side, the client can then read this value over the air. For more details on the differences between remote and local write APIs, please have a look to this Application Note 

In your case, you can configure the Temp Meas Attribute to be reportable with a defined period, you can follow steps on these posts describing the procedure :

Post1 : Zigbee example/help on how to configure and send values 

Post2 : STM32WB55 Zigbee - Can't report value 

Please be careful using Hal_Delay() which is an active polling loop that blocks the process waiting the end of the delay, for Zigbee applications, a callback condition can be used to check the status of an over the air request. 

Kind regards,

Ouadi

Hi @Ouadi,

Thank you for your response. I read Post1 that you sent and was able to finally fix the problem.

Have a great day.

Best regards,