MCU SDK Porting

Last Updated on : 2024-11-25 08:06:36download

MCU SDK is a set of MCU codes automatically generated according to the product functions defined on Tuya Developer Platform, facilitating MCU program development. This topic describes the process and notes to port the MCU SDK to Zigbee devices.

File structure

Understand the file structure of the MCU SDK before the porting.

File Description
zigbee.h Defines general macros.
system.h system.h provides the following information:
  • Function declaration: General function, queue handler function, and framing function
system.c system.c provides the following information:
  • Function declaration: Queue handler function
  • Function definition: General function, queue handler function, and framing function
protocol.h protocol.h provides the following information:
  • Configuration item: Device information
  • DP ID macro definition
  • Protocol information: Frame field and command
  • Command information: DP data type and network status and parameters of the Zigbee module
  • Function declaration: Frame receiver function and DP handler function
protocol.c protocol.c provides the following information:
  • Definition of protocol and command
  • Function declaration: Frame receiver and handler function (complete process) and DP message handler function
  • Function definition: DP handler function, frame receiver and handler function (complete process), frame sending function, and DP message handler function
mcu_api.h mcu_api.h provides the following information:
  • Configuration item: Debugging information recording switch, buffer size of serial port and queue, and command information
  • Function declaration: Serial port service function and data sending function, Zigbee module wake-up function, frame receiver and handler function (user interface), and frame sending function
mcu_api.c mcu_api.c provides the following information:
  • Function definition: Serial port service function and data sending function

For more information, see Appendix - Files.

Porting procedure

After the porting, you can try out the MCU SDK by referring to Use process.

  1. Download MCU SDK.
  2. Compile the MCU basic program.
  3. Use mcu_api.h.
  4. Use mcu_api.c.
  5. Use protocol.h.
  6. Use protocol.c.

Step 1: Download MCU SDK

Download MCU SDK. For detailed procedures, see Develop hardware.

Step 2: Compile the MCU basic program

  1. Add the .c and .h files in the MCU SDK folder to the corresponding reference path of the source file and header file of the project.

  2. Add the #include "zigbee.h" code to the files that need to use the MCU SDK interface in the project.

Step 3: Use mcu_api.h

  1. To record debugging information in mcu_api.h, enable the MCU_SDK_DEBUG macro. Then replace the PROJECT_PRINT_FUNC macro with the debugging information recording function of the project (header files might be required).

    #ifndef MCU_SDK_DEBUG
    #define MCU_SDK_DEBUG                           1
    #endif
    
    #if MCU_SDK_DEBUG
    #include "xx_print.h"
    #define PRINT_DEBUG(fmt, ...)                   my_debug_print(fmt, ##__VA_ARGS__)
    #else
    #define PRINT_DEBUG(fmt, ...)
    #endif
    
  2. Confirm the buffer size in mcu_api.h, including UART_RX_BUF_LEN_LMT, UART_TX_BUF_LEN_LMT, and UART_QUEUE_BUF_LEN_LMT.

    • The size of the serial port receiving or sending buffer is 24 bytes by default and shall be greater than the maximum DP data length.
    • If the MCU OTA update is enabled, it is recommended that the buffer size of receive queues be greater than 260 bytes.
    • If the RAM is insufficient, you can reduce the size of three buffers.
    #define UART_RX_BUF_LEN_LMT                     256
    #define UART_TX_BUF_LEN_LMT                     256
    #define UART_QUEUE_BUF_LEN_LMT                  512
    
  3. Modify the OTA single packet size (OTA_PACKET_SIZE) and wait time for the Zigbee module waking up MCU (ZG_WAIT_MCU_TIME_DEFAULT) in mcu_api.h.

    ///< OTA single packet payload length (UART command ID: 0x0c 0x0d 0x0e)
    #define OTA_PACKET_SIZE                         0x30            // max: 0x30
    
    ///< The waiting time after the Zigbee module starts to wake up the MCU (UART command ID: 0x2b)
    #if SLEEP_END_DEVICE
    #define ZG_WAIT_MCU_TIME_DEFAULT                10
    #endif
    
  4. Call the uart_servive_rx_store() function of the serial data receiver and handler function to process received bytes in the project.

    int main(void)
    {
        ...
    
        // MCU receives the data of serial port initialization.
        recv_uart_init(recv_uart_callback);
    
        ...
    }
    
    void recv_uart_callback(uint8_t *buff, uint16_t len)
    {
        for (uint16_t i = 0; i < len; i++) {
            uart_servive_rx_store(buff[i]);
        }
    }
    
  5. Call the uart_service_parse() function during the interruption of the project main loop or timer (executed repeatedly).

    After the initialization is completed, we recommend that you not disable the interruption because a disabled interruption might cause serial data loss. If the interruption must be disabled, the duration must be short. Do not call the reporting function during the interruption.

    int main(void)
    {
        ...
    
        while(1) {
            uart_service_parse();
        }
    
        ...
    }
    
  6. Call the single-byte sending function of the serial port to implement the uart_send_byte() function in the project.

    int main(void)
    {
        ...
    
        ...
    }
    
    void uart_send_byte(unsigned char value)
    {
        my_uart_send_a_byte(value);
    }
    
  7. For low-power devices, initialize GPIO and implement one of the following low-power wake-up sending functions in the project:

    • mcu_wakeup_zg_level_method() function: wake-up by voltage levels.

    • mcu_wakeup_zg_pulse_method() function: wake-up by pulses.

    For more information about the implementation method, see Low power wake-up.

    int main(void)
    {
        ...
    
        // Initialize GPIO used by the MCU to wake up the module.
        // Initialize GPIO used by the module to wake up the MCU.
        wakeup_gpio_init();
    
        ...
    }
    
    void mcu_wakeup_zg_level_method(unsigned char *data, unsigned short data_len)
    {
        // To implement wake-up, see section "Low power wake-up" in Serial Communication Protocol.
    }
    
  8. In the project, all frame receiver and handler functions (user interface, with the mcu_recv_ prefix) of the serial protocol should be implemented and can be implemented as null functions.

    void mcu_recv_factory_recovery_cb(void)
    {
        PRINT_DEBUG("factory recovery\r\n");
    }
    
    void mcu_recv_zg_nwk_status_notify_cb(unsigned char nwk_status)
    {
    }
    
    unsigned char mcu_recv_beacon_notify_cb(void)
    {
        return 1;
    }
    

Step 4: Use mcu_api.c

In mcu_api.c, enable an MCU wake-up sending function for low-power devices in the uart_send_frame() function (implemented in the project) and disable another wake-up sending function.

void uart_send_frame(unsigned short payload_len)
{
#if SLEEP_END_DEVICE
    mcu_wakeup_zg_level_method((unsigned char *)g_uart_tx_buf, payload_len + FRAME_LEN_WITHOUT_PAYLOAD);
    // mcu_wakeup_zg_pulse_method((unsigned char *)g_uart_tx_buf, payload_len + FRAME_LEN_WITHOUT_PAYLOAD);
#else
    uart_send_bytes((unsigned char *)g_uart_tx_buf, payload_len + FRAME_LEN_WITHOUT_PAYLOAD);
#endif
}

Step 5: Use protocol.h

  1. Confirm device information in protocol.h.

    Identifier Description Notes
    PRODUCT_KEY The product ID (PID). This is the unique identifier for each product and is available on the product details page on Tuya Developer Platform.
    MCU_VER The MCU firmware version. For more information about OTA update, see OTA Update Guide-Configuration in Developer Platform.
    SUPPORT_RECEIVE_BROADCAST_DATA Whether the identification of the group control messages is required by the MCU.
    • 0x00: No.
    • 0x01: Yes.
    DEVICE_TYPE The device type.
    • 0x00: Standard power consumption (non-scene switch).
    • 0x01: Low power consumption.
    • 0x02: Standard power consumption (scene switch).
    #define PRODUCT_KEY "ksubawat"    // A 16-bit unique identifier of the product that is generated after the product is created on Tuya Developer Platform.
    
    #define MCU_VER          "1.0.0"     // MAX 3.3.15, BIT 7~0, XX.XX.XXXX
    #define SUPPORT_RECEIVE_BROADCAST_DATA    1     // 0: Not supported, 1: Supported.
    #define DEVICE_TYPE     0     // 0: Standard power consumption device (router), 1: Low power consumption device (sleep end device), 2: Scene switch.
    #if (DEVICE_TYPE == 1)
    #define SLEEP_END_DEVICE     1     // Command supported only by this device type: 0x2b.
    #elif (DEVICE_TYPE == 2)
    #define SCENE_SWITCH     1     // Commands supported only by this device type: 0x0a, 0x41, 0x42, and 0x43. Commands not supported only by this device type: 0x25, 0x26, and 0x2a.
    #endif
    
  2. Confirm the DP ID macro (with the DPID_ prefix) in protocol.h.

    #define DPID_TEMP_ROOM 101
    #define DPID_AIRCOND_SWITCH 102
    #define DPID_AIRCOND_TEMP_SET 103
    ...
    

Step 6: Use protocol.c

  1. Confirm the DP information array in protocol.c.

    const DOWNLOAD_CMD_S download_cmd[] =
    {
      {DPID_TEMP_ROOM, DP_TYPE_VALUE},
      {DPID_AIRCOND_SWITCH, DP_TYPE_BOOL},
      {DPID_AIRCOND_TEMP_SET, DP_TYPE_VALUE},
      ...
    };
    
  2. Confirm how the device reports DP data after it receives the DP query command from the gateway in the mcu_rx_gw_check_dp function of protocol.c.

    • If you want to trigger linkage, use the command 0x06.
    • If you do not want to trigger linkage, use the command 0x2c.
    static void mcu_rx_gw_check_dp(UART_FRAME_T *uart_frame)
    {
        ///< 1. Send 0x28 without payload.
        ...
    
        ///< 2. DP reporting type (whether linkage is triggered).
        g_dp_send_type = DP_SEND_TYPE_REPORT_LINKAGE;       // 0x06
        // g_dp_send_type = DP_SEND_TYPE_REPORT_NOT_LINKAGE;   // 0x2c
    
        ///< 3. Report DP.
        ...
    }
    
  3. Refine the all_data_update() function in protocol.c. For example, pass in a predefined variable that represents the true value of the current DP.

    static void all_data_update(void)
    {
        mcu_dp_bool_update(DPID_AIRCOND_SWITCH,my_aircond_switch_value);
        mcu_dp_bool_update(DPID_AIRCOND_ECO,my_aircond_eco_value);
        ...
    }
    
  4. Refine the specific_DP_update() function in protocol.c. Call the DP reporting function that matches the DP data type based on the DP ID.

    static void specific_dp_update(unsigned char dp_id)
    {
        switch (dp_id) {
            /** please refer the following example and 'all_data_update()'
             *
             *     case DPID_SCENE_1: {
             *         mcu_dp_enum_update(DPID_SCENE_1, current scenario 1); // Enumeration data reporting.
             *         break;
             *     }
             *
             *     case DPID_SCENE_2: {
             *         mcu_dp_enum_update(DPID_SCENE_2, current scenario 2); // Enumeration data reporting.
             *         break;
             *     }
             */
    
            case DPID_AIRCOND_SWITCH: {
                mcu_dp_bool_update(DPID_AIRCOND_SWITCH,my_aircond_switch_value);
                break;
            }
    
            case DPID_AIRCOND_ECO: {
                mcu_dp_bool_update(DPID_AIRCOND_ECO,my_aircond_eco_value);
                break;
            }
    
            default: {
                break;
            }
        }
    }
    
  5. View the dp_msg_handle() function in protocol.c and refine the DP sending handler function used by this function. The function format DP_download_xxxxxx_handle() varies with the DP.

    static unsigned char dp_msg_handle(unsigned char dp_id, const unsigned char *value, unsigned short length)
    {
        unsigned char ret;
        if (NULL == value) {
            return ERROR;
        }
    
        switch (dp_id) {
            case DPID_AIRCOND_SWITCH:
                ret = dp_download_aircond_switch_handle(value,length);
            break;
    
            ...
    
            default :
                break;
        }
        return ret;
    }
    
    static unsigned char dp_download_aircond_switch_handle(const unsigned char value[], unsigned short length)
    {
        unsigned char ret;
        //0:off/1:on
        unsigned char aircond_switch;
    
        aircond_switch = mcu_get_dp_download_bool(value,length);
        if(aircond_switch == 0) {
            //bool off
            ...
            my_aircond_switch_off_handle();
            ...
        }else {
            //bool on
            my_aircond_switch_on_handle();
        }
    
        //There should be a report after processing the DP
        ret = mcu_dp_bool_update(DPID_AIRCOND_SWITCH,aircond_switch);
        if(ret == SUCCESS)
            return SUCCESS;
        else
            return ERROR;
    }
    

Use process

When the porting is successful, you only need to focus on the following:

  1. Frame sending function (complete process, with the mcu_tx_ prefix)

    The interface used by the MCU to actively send frames.

    You can call these functions and send the serial protocol frame to Zigbee modules to which the general integration firmware is flashed.

    /*
    void mcu_tx_let_zigbee_reset(void)
    {
        unsigned short payload_len = 0;
        uart_framing_fill_payload_byte(&payload_len, 0x00);
        uart_framing_fill_protocol_field(UART_CMD_RESET_OR_JOIN, payload_len, NULL);
        uart_send_frame(payload_len);
    }
    */
    
    int main(void)
    {
        ...
        mcu_tx_let_zigbee_reset();
        ...
    }
    
  2. Frame receiver and handler function (complete process, with the mcu_rx_ prefix)

    The complete process after the MCU receives the frame, which cannot be modified.

    You can refer to the sequence diagram in Serial Communication Protocol to understand the receiving and processing flow of the command.

    static void mcu_rx_factory_recovery_notify(UART_FRAME_T *uart_frame)
    {
        if (NULL == uart_frame || NULL == uart_frame->frame_payload) {
            return;
        }
    
        ///< 1. Send frames.
        unsigned short payload_len = 0;
        uart_framing_fill_payload_byte(&payload_len, 0x01);
        uart_framing_fill_protocol_field(UART_CMD_FACTORY_RECOVERY, payload_len, &uart_frame->frame_seq);
        uart_send_frame(payload_len);
    
        ///< 2. Reset to factory settings.
        mcu_recv_factory_recovery_cb();
    }
    
  3. Frame receiver and handler function (user interface, with the mcu_recv_ prefix)

    The interface provided to you for processing and implementing after the MCU receives the frame.

    You can view where these functions are called and then refer to the sequence diagram in Serial Communication Protocol to confirm the time point of the corresponding command when these functions are called.

Support and help

Appendix - Files

zigbee.h

Function

  • Defines general macros.

General macros

  • Source code

    #ifndef TRUE
    #define TRUE                    1
    #endif
    
    #ifndef FALSE
    #define FALSE                   0
    #endif
    
    #ifndef NULL
    #define NULL                    ((void *)0)
    #endif
    
    #ifndef SUCCESS
    #define SUCCESS                 1
    #endif
    
    #ifndef ERROR
    #define ERROR                   0
    #endif
    
    #ifndef INVALID
    #define INVALID                 0xFF
    #endif
    
    #ifndef ENABLE
    #define ENABLE                  1
    #endif
    
    #ifndef DISABLE
    #define DISABLE                 0
    #endif
    

system.h

Function

  • Function declaration: General function, queue handler function, and framing function.

General function

  • Description

    Identifier Description Notes
    get_seq_num Generates a 16-bit serial number. It is used to send the serial protocol frame to the module.
    get_u8_checksum Calculates the 8-bit checksum. It is used to calculate the checksum of the serial protocol frame.
    my_strlen Functions the same as strlen. -
    my_memset Functions the same as memset. -
    my_memcpy Functions the same as memcpy. -
    my_strcpy Functions the same as strcpy. The last byte will be replaced by ‘\0’.
    my_strcmp Functions the same as strcmp. -
    my_strncmp Functions the same as strncmp. -
    hex_to_bcd Converts hexadecimal numbers to BCD numbers. -
    int_to_byte Converts a 32-bit number to four 8-bit numbers. -
    byte_to_int Converts four 8-bit numbers to a 32-bit number. -
    ascii_to_hex Converts ASCII numbers to hexadecimal numbers. -

Queue handler function

  • Description

    Identifier Description Notes
    queue_dequeue_byte Dequeue (single byte). Check whether the queue is empty before dequeuing.
    TRUE: Dequeued successfully.
    queue_enqueue_byte Enqueue (single byte). Check whether the queue is full before enqueuing.
    TRUE: Enqueued successfully.

Framing function

  • Description

    Identifier Description Notes
    uart_framing_fill_payload_byte Populates the payload field of the protocol frame: Single-byte. -
    uart_framing_fill_payload_buff Populates the payload field of the protocol frame: Multi-byte. -
    uart_framing_fill_payload_add_group_id Populates the payload field of the protocol frame: Insert the 2-byte group ID at the beginning of the payload field. It is used only to send a group DP message (serial protocol command 0x43).
    uart_framing_fill_protocol_field Populates other fields of the protocol frame. -

system.c

Function

  • Function declaration: Queue handler function.
  • Function definition: General function, queue handler function, and framing function.

Queue handler function

  • Description

    Identifier Description Notes
    queue_is_empty Checks whether the queue is empty. TRUE: Empty.
    queue_is_full Checks whether the queue is full. TRUE: Full.

protocol.h

Function

  • Configuration item: Device information.
  • Macro definition of DP ID.
  • Protocol information: Frame field and command.
  • Command information: DP data type and network status and parameters of the Zigbee module.
  • Function declaration: Frame receiver function and DP handler function.

Configuration item

  • Device information

    Identifier Description Notes
    PRODUCT_KEY PID Only the first 8 bytes are valid.
    Check whether it is the PID of the general integration device.
    MCU_VER The MCU firmware version (local). MCU reports the firmware version number.
    After receiving an OTA update notification, the MCU compares the version number in the OTA package with the local one.
    SUPPORT_RECEIVE_BROADCAST_DATA Whether the identification of the group control message is required by the MCU.
    • 0: No.
    • 1: Yes.
    The Zigbee module gets the value through the product information command (0x01).
    • If the identification of the group control message is required by the MCU after the Zigbee module receives the group control message, the Zigbee module sends the message to the MCU using the group control DP message command (0x2a). If not, the Zigbee module sends the message to the MCU using the DP message command (0x04).
    • If the Zigbee module receives a single control message, it sends the message to the MCU using the DP message command (0x04).
    DEVICE_TYPE The device type.
    • 0: Standard power consumption (non-scene switch).
    • 1: Low power consumption.
    • 2: Standard power consumption (scene switch).
    For more information about commands supported by different device types, see Serial Communication Protocol.
    SLEEP_END_DEVICE Device type identifier: Low power consumption. -
    SCENE_SWITCH Device type identifier: Standard power consumption (scene switch). -
    #define PRODUCT_KEY "ksubawat"    // A 16-bit unique identifier of the product that is generated after the product is created on Tuya Developer Platform.
    
    #define MCU_VER                                 "1.0.0"         // MAX 3.3.15,BIT 7~0, XX.XX.XXXX
    #define SUPPORT_RECEIVE_BROADCAST_DATA          1               // 0: Not supported, 1: Supported.
    #define DEVICE_TYPE                             0               // 0: Standard power consumption device (router), 1: Low power consumption device (sleep end device), 2: Scene switch.
    #if (DEVICE_TYPE == 1)
    #define SLEEP_END_DEVICE                        1               // Command supported only by this device type: 0x2b.
    #elif (DEVICE_TYPE == 2)
    #define SCENE_SWITCH                            1               // Commands supported only by this device type: 0x0a, 0x41, 0x42, and 0x43. Commands not supported only by this device type: 0x25, 0x26, and 0x2a.
    #endif
    

DP ID

  • Example

    #define DPID_TEMP_ROOM 101
    #define DPID_AIRCOND_SWITCH 102
    #define DPID_AIRCOND_TEMP_SET 103
    ...
    

Protocol information

  • Frame field ID

    Identifier Description Notes
    FRAME_FIELD_HDR_HIGH The sequence number of the high byte of the frame header. -
    FRAME_FIELD_HDR_LOW The sequence number of the low byte of the frame header. -
    FRAME_FIELD_PROT_VER The serial protocol version number. -
    FRAME_FIELD_SEQ_HIGH The sequence number of the high byte in the frame serial number. -
    FRAME_FIELD_SEQ_LOW The sequence number of the low byte in the frame serial number. -
    FRAME_FIELD_CMD_ID The sequence number of the frame command. -
    FRAME_FIELD_PAYLOAD_LEN_HIGH The sequence number of the high byte of the frame payload length. If no payload exists, the length and high and low bytes are 0.
    FRAME_FIELD_SEQ_LOW The sequence number of the low byte of the frame payload length. -
    FRAME_FIELD_PAYLOAD_START The start number of the frame payload. -
    FRAME_LEN_WITHOUT_PAYLOAD The minimum frame length. The length of the frame without payload.

    The frame tail is represented as a checksum instead of a sequence number because the payload length is variable.

    #define FRAME_FIELD_HDR_HIGH                    0
    #define FRAME_FIELD_HDR_LOW                     1
    #define FRAME_FIELD_PROT_VER                    2
    #define FRAME_FIELD_SEQ_HIGH                    3
    #define FRAME_FIELD_SEQ_LOW                     4
    #define FRAME_FIELD_CMD_ID                      5
    #define FRAME_FIELD_PAYLOAD_LEN_HIGH            6
    #define FRAME_FIELD_PAYLOAD_LEN_LOW             7
    #define FRAME_FIELD_PAYLOAD_START               8
    
    #define FRAME_LEN_WITHOUT_PAYLOAD               9           // the shortest frame length (no payload)
    
  • Frame field value

    Identifier Description
    FRAME_VALUE_HDR_HIGH The value of the high byte of the frame header.
    FRAME_VALUE_HDR_LOW The value of the low byte of the frame header.
    FRAME_VALUE_HDR The value of the frame header.
    FRAME_VALUE_PROT_VER The value of the serial protocol version.

    The header and version number are used to identify the general integration serial protocol frame.

    #define FRAME_VALUE_HDR_HIGH                    0x55
    #define FRAME_VALUE_HDR_LOW                     0xaa
    #define FRAME_VALUE_HDR                         0x55aa
    #define FRAME_VALUE_PROT_VER                    0x02
    
  • Command

    For more information, see Serial Communication Protocol.

    #define UART_CMD_FACTORY_RECOVERY               0x00
    #define UART_CMD_PRODUCT_INFO                   0x01
    #define UART_CMD_ZG_NWK_STATUS_NOTIFY           0x02
    #define UART_CMD_RESET_OR_JOIN                  0x03
    #define UART_CMD_RX_DP                          0x04
    #define UART_CMD_RESPOND_DP                     0x05
    #define UART_CMD_REPORT_DP_LINKAGE              0x06
    #define UART_CMD_ZG_INFO                        0x07
    #define UART_CMD_RF_TEST                        0x08
    #define UART_CMD_SCENE_INFO                     0x0A
    #define UART_CMD_MCU_VER                        0x0B
    #define UART_CMD_OTA_NOTIFY                     0x0C
    #define UART_CMD_OTA_DATA                       0x0D
    #define UART_CMD_OTA_RESULT                     0x0E
    #define UART_CMD_ZG_NWK_STATUS_REQUEST          0x20
    #define UART_CMD_DOUBLE_DONGLE_DATA_NOTIFY      0x21
    #define UART_CMD_DOUBLE_DONGLE_REPORT           0x22
    #define UART_CMD_TIME_SYNC                      0x24
    #define UART_CMD_MCU_CHECK_GW_NWK_STAUTS        0x25
    #define UART_CMD_MCU_SET_ZG_NWK_PARAM           0x26
    #define UART_CMD_SEND_DP_BROADCAST              0x27
    #define UART_CMD_GW_CHECK_DP                    0x28
    #define UART_CMD_BEACON_TEST                    0x29
    #define UART_CMD_RX_DP_GROUP                    0x2A
    #define UART_CMD_ZG_WAIT_MCU_TIME               0x2B
    #define UART_CMD_REPORT_DP_NOT_LINKAGE          0x2C
    #define UART_CMD_CONFIG_ZG_GPIO                 0x36
    #define UART_CMD_READ_ZG_GPIO                   0x37
    #define UART_CMD_WRITE_ZG_GPIO                  0x38
    #define UART_CMD_ZG_GPIO_IRQ                    0x39
    #define UART_CMD_WEATHER_REQUEST                0x3A
    #define UART_CMD_WEATHER_RESPONSE               0x3B
    #define UART_CMD_SCENE_CONFIG                   0x41
    #define UART_CMD_SEND_CMD_GROUP                 0x42
    #define UART_CMD_SEND_DP_GROUP                  0x43
    

Command information

  • DP data type

    Identifier Description Notes
    DP_TYPE_RAW Raw -
    DP_TYPE_BOOL Boolean -
    DP_TYPE_VALUE Value -
    DP_TYPE_STRING String -
    DP_TYPE_ENUM Enumeration -
    DP_TYPE_BITMAP Bitmap -
    DP_TYPE_FAULT Fault The processing of this data type is the same as that of DP_TYPE_BITMAP.
    #define DP_TYPE_RAW                             0x00
    #define DP_TYPE_BOOL                            0x01
    #define DP_TYPE_VALUE                           0x02
    #define DP_TYPE_STRING                          0x03
    #define DP_TYPE_ENUM                            0x04
    #define DP_TYPE_BITMAP                          0x05
    #define DP_TYPE_FAULT                           DP_TYPE_BITMAP
    
  • Zigbee module information query identifier (command 0x07)

    Identifier Description
    ZG_INFO_TYPE_SW_VER The MCU queries the firmware version of the Zigbee module.
    ZG_INFO_TYPE_AUTH The MCU queries the authorization information of the Zigbee module.
    ZG_INFO_TYPE_MAC_ADDR The MCU queries the MAC address of the Zigbee module.
    #define ZG_INFO_TYPE_SW_VER                     0x01
    #define ZG_INFO_TYPE_AUTH                       0x02
    #define ZG_INFO_TYPE_MAC_ADDR                   0x03
    
  • Zigbee module network parameters (command 0x26)

    Identifier Description
    HEART_PERIOD_DEFAULT_SET The MCU sets the heartbeat interval of the Zigbee module to the default value.
    JOIN_TIMEOUT_DEFAULT_SET The MCU sets the join timeout of the Zigbee module to the default value.
    REJOIN_INTERVAL_DEFAULT_SET The MCU sets the rejoin interval of the Zigbee module to the default value.
    POLL_INTERVAL_DEFAULT_SET The MCU sets the poll interval of the Zigbee module to the default value.
    FAST_POLL_PERIOD_DEFAULT_SET The MCU sets the poll power-on time of the Zigbee module to the default value.
    POLL_FAIL_TIMES_DEFAULT_SET The MCU sets the maximum number of failed poll attempts of the Zigbee module to the default value.
    APP_DATA_TRIG_REJOIN_DEFAULT_SET The MCU sets the rejoin trigger threshold of the Zigbee module to the default value.
    REJOIN_TRY_TIMES_DEFAULT_SET The MCU sets the maximum number of rejoin attempts per round of the Zigbee module to the default value.
    RF_POWER_DEFAULT_SET The MCU sets the transmission power of the Zigbee module to the default value.
    NWK_PARAM_DEFAULT_SET The MCU sets all parameters of the Zigbee module to the default value.
    #define HEART_PERIOD_DEFAULT_SET                0xfffe
    #define JOIN_TIMEOUT_DEFAULT_SET                0xfffe
    #define REJOIN_INTERVAL_DEFAULT_SET             0xfffe
    #define POLL_INTERVAL_DEFAULT_SET               0xfffe
    #define FAST_POLL_PERIOD_DEFAULT_SET            0xfffe
    #define POLL_FAIL_TIMES_DEFAULT_SET             0xfe
    #define APP_DATA_TRIG_REJOIN_DEFAULT_SET        0xfe
    #define REJOIN_TRY_TIMES_DEFAULT_SET            0xfe
    #define RF_POWER_DEFAULT_SET                    0xfe
    #define NWK_PARAM_DEFAULT_SET                   {HEART_PERIOD_DEFAULT_SET, JOIN_TIMEOUT_DEFAULT_SET, REJOIN_INTERVAL_DEFAULT_SET, POLL_INTERVAL_DEFAULT_SET, FAST_POLL_PERIOD_DEFAULT_SET, POLL_FAIL_TIMES_DEFAULT_SET, APP_DATA_TRIG_REJOIN_DEFAULT_SET, REJOIN_TRY_TIMES_DEFAULT_SET, RF_POWER_DEFAULT_SET}
    

Command data type

  • Module network status (command 0x02 and 0x20)

    Identifier Description Notes
    ZG_NWK_STATUS_NOT_JOIN The module is not paired. -
    ZG_NWK_STATUS_JOINED The module is paired. -
    ZG_NWK_STATUS_ERROR The module is in abnormal network status. It indicates that the module has not received the product information returned by the MCU.
    ZG_NWK_STATUS_JOINING The module is being paired. -
    typedef enum {
        ZG_NWK_STATUS_NOT_JOIN = 0,
        ZG_NWK_STATUS_JOINED,
        ZG_NWK_STATUS_ERROR,
        ZG_NWK_STATUS_JOINING,
    } ZG_NWK_STATUS_E;
    
  • Time synchronization struct (command 0x24)

    Identifier Description
    TIME_SYNC_CALENDAR_T Used to store the conversion result of the timestamp.
    typedef struct {
        unsigned short w_year;
        unsigned char w_month;
        unsigned char w_day;
        unsigned char hour;         // +8 for Beijing time
        unsigned char min;
        unsigned char sec;
    } TIME_SYNC_CALENDAR_T;
    
  • Gateway network status (command 0x25)

    Identifier Description Notes
    GW_NWK_STATUS_OFFLINE The gateway is offline. The gateway is not connected to the Internet.
    GW_NWK_STATUS_ONLINE The gateway is online. -
    GW_NWK_STATUS_RESPOND_TIMEOUT The gateway response times out. -
    typedef enum {
        GW_NWK_STATUS_OFFLINE = 0,
        GW_NWK_STATUS_ONLINE,
        GW_NWK_STATUS_RESPOND_TIMEOUT,
    } GW_NWK_STATUS_E;
    
  • Zigbee module network parameter struct (command 0x26)

    Identifier Description
    NWK_PARAM_T The network parameters used to set the Zigbee module.
    typedef struct {
        unsigned short heart_period;
        unsigned short join_timeout;
        unsigned short rejoin_interval;
        unsigned short poll_interval;
        unsigned short fast_poll_period;            // power on poll period
        unsigned char poll_fail_times;
        unsigned char app_data_trig_rejoin;
        unsigned char rejoin_try_times;
        unsigned char rf_power;
    } NWK_PARAM_T;
    
  • Zigbee module GPIO (command 0x36, 0x37, and 0x38)

    Identifier Description Notes
    MCU_CONFIG_GPIO_T Used to set the GPIO level of the Zigbee module. -
    MCU_READ_GPIO_T Used to read the GPIO level of the Zigbee module. Input or output is supported.
    MCU_WRITE_GPIO_T Used to write the GPIO level of the Zigbee module. Only output is supported.
    typedef struct {
        unsigned char port_num;
        unsigned char pin_num;
        unsigned char gpio_mode;
        unsigned char gpio_level;
    } MCU_CONFIG_GPIO_T;
    
    typedef struct {
        unsigned char port_num;
        unsigned char pin_num;
    } MCU_READ_GPIO_T;
    
    typedef struct {
        unsigned char port_num;
        unsigned char pin_num;
        unsigned char gpio_level;
    } MCU_WRITE_GPIO_T;
    
  • Weather/City information (command 0x3b)

    Identifier Description Notes
    WEATHER_INFO_T Used to process the weather information returned by the module. Weather information is parsed based on protocol documents.
    CITY_INFO_T Used to process the city information returned by the module. City information is parsed based on protocol documents.
    typedef struct {
        unsigned char version;                  // 0x11
        unsigned char addr_type;
        unsigned char forecast_flag;            // 0x12
        unsigned char forecast_days;
        unsigned char real_time_weather_flag;   // 0x13
        unsigned char real_time_enable;
        unsigned char *weather_detail;
        unsigned char weather_detail_len;
    } WEATHER_INFO_T;
    
    typedef struct {
        unsigned char version;                  // 0x11
        unsigned char addr_type;
        unsigned char *city_detail;
        unsigned char city_detail_len;
    } CITY_INFO_T;
    
  • Group standard command (command 0x42)

    Identifier Description
    MCU_SEND_CMD_GROUP_T Used to send group standard command to the Zigbee module.
    #if SCENE_SWITCH
    typedef struct {
        unsigned short group_id;
        unsigned short cluster_id;
        unsigned char command_id;
        unsigned char *payload;
        unsigned char payload_len;
    } MCU_SEND_CMD_GROUP_T;
    #endif
    
  • DP sending type

    Identifier Description Notes
    DP_SEND_TYPE_NOT_SEND Response to the received DP message is not required. The MCU does not need to respond to the DP message for group control (command 0x2a) when receiving it.
    DP_SEND_TYPE_RESPOND Response to the received DP message is required (command 0x05). The MCU needs to respond to the DP message (command 0x04) when receiving it.
    DP_SEND_TYPE_REPORT_LINKAGE The DP message is reported, and the linkage is triggered (command 0x06). -
    DP_SEND_TYPE_REPORT_NOT_LINKAGE The DP message is reported, and the linkage is not triggered (command 0x2c). -
    DP_SEND_TYPE_SEND_BROADCAST A broadcast DP message is sent (command 0x27). -
    DP_SEND_TYPE_SEND_GROUP A group DP message is sent (command 0x43) -
    typedef enum {
        DP_SEND_TYPE_NOT_SEND,                      // Not send: when the MCU receives a broadcast DP message (UART command ID: 0x2a), it doesn't need to respond.
        DP_SEND_TYPE_RESPOND,                       // Respond to DP messages (UART command ID: 0x05): when the MCU receives a DP message (UART command ID: 0x04), it needs to respond to the Zigbee module.
        DP_SEND_TYPE_REPORT_LINKAGE,                // Report a DP message with linkage trigger (UART command ID: 0x06)
        DP_SEND_TYPE_REPORT_NOT_LINKAGE,            // Report a DP message without linkage trigger (UART command ID: 0x2c)
        DP_SEND_TYPE_SEND_BROADCAST,                // Send a DP message broadcast (UART command ID: 0x27)
        DP_SEND_TYPE_SEND_GROUP,                    // Send a DP message to a group (UART command ID: 0x43)
    } DP_SEND_TYPE_E;
    

Frame receiver function

  • Description

    Identifier Description Notes
    frame_rx_handle The main interface for frame receiving and processing. After the frame is parsed, call the corresponding frame receiver and handler function (complete process) according to the command.

DP handler function

  • Description

    Identifier Description Notes
    dp_info_check Used to check the DP ID and data type. -
    mcu_get_dp_download_bool

    mcu_get_dp_download_value
    Used to get the value of DP data. -
    mcu_dp_raw_update

    mcu_dp_fault_update
    Used to send DP messages. These functions send DP messages using __dp_send_type_handle.

protocol.c

Function

  • The definition of protocol and command.
  • Function declaration: Frame receiver and handler function (complete process) and DP message handler function.
  • Function definition: DP handler function, frame receiver and handler function (complete process), frame sending function, and DP message handler function.
  • You can refer to the sequence diagram in Serial Communication Protocol and check the frame receiver and handler function (complete process) and frame sending function to understand how the serial protocol is processed on the MCU side.
  • You can view the frame receiving and sending process in Serial Communication Protocol and call the frame sending function.

Definition of protocol and command

  • Source code

    Identifier Description Notes
    DOWNLOAD_CMD_S The data type of the DP message array. The DP ID and corresponding DP data type are included.
    UART_FRAME_T The incomplete data struct of the serial protocol frame. The checksum is not included, which is only used to parse the frame.
    OTA_FW_INFO_T The information of MCU firmware OTA update. -
    typedef struct {
        unsigned char DP_id;
        unsigned char DP_type;
    } DOWNLOAD_CMD_S;
    
    typedef struct {
        unsigned short frame_hdr;
        unsigned char frame_ver;
        unsigned short frame_seq;
        unsigned char frame_cmd;
        unsigned short frame_payload_len;
        unsigned char *frame_payload;
    } UART_FRAME_T;
    
    typedef struct {
        unsigned char ota_pid[8];               // MCU PID
        unsigned char ota_fw_ver;               // new MCU fw version
        unsigned int ota_fw_size;               // MCU firmware total size
        unsigned int ota_current_offset;        // MCU firmware current offset
        unsigned int ota_expect_checksum;       // MCU firmware expective checksum
    } OTA_FW_INFO_T;
    

Frame receiver and handler function (complete process)

  • Description

    Identifier Description Notes
    mcu_rx_factory_recovery_notify

    mcu_rx_scene_config
    The frame receiver and handler function (complete process) with the mcu_rx_ prefix.
    These functions show the complete flow of frame receiving and processing. A user interface with the mcu_recv_ prefix is provided for processing the time points.

DP message handler function

  • Description

    Identifier Description Notes
    __dp_send_type_handle Used to send DPs (bottom layer). Specify the value of g_dp_send_type, which is the DP sending type before calling this function.
    DP_download_xxxxxx_handle The sending handler function for a specific DP ID. These functions are generated by Tuya IoT Cloud Platform and should be refined.
    DP_msg_handle The main interface for sending and processing all DP IDs. -
    all_data_update The all DP reporting function. The MCU reports all DPs after receiving the DP query command (0x28) sent by the gateway if the query list is empty. The refinement of the function is required. For example, use a variable to represent the DP true value.
    specific_DP_update The single DP reporting function. The MCU reports listed DPs after receiving the DP query command (0x28) sent by the gateway if the query list is not empty. Refer to all_data_update() to refine the function, that is, call the corresponding DP reporting function according to the DP ID.

mcu_api.h

Function

  • Configuration item: Debugging information recording switch, buffer size of serial port and queue, and command information.
  • Function declaration: Serial port service function and data sending function, Zigbee module wake-up function, frame receiver and handler function (user interface), and frame sending function.

You can refer to the sequence diagram in Serial Communication Protocol and check the frame receiver and handler function (complete process) to get the call time point of frame receiver and handler function (user interface) and thus accurately process frame receiving data.

Configuration item

  • Debugging information recording switch

    Identifier Description Notes
    MCU_SDK_DEBUG The debugging information recording switch.
    • 1: Enable.
    • 0: Disable.
    PRINT_DEBUG(fmt, …) The implementation of debugging information recording. Replace PROJECT_PRINT_FUNC with the debugging information recording function of the project.
    #ifndef MCU_SDK_DEBUG
    #define MCU_SDK_DEBUG           1
    #endif
    
    #if MCU_SDK_DEBUG
    #define PRINT_DEBUG(fmt, ...)   PROJECT_PRINT_FUNC(fmt, ##__VA_ARGS__)
    #else
    #define PRINT_DEBUG(fmt, ...)
    #endif
    
  • Buffer size of serial port and queue

    Identifier Description
    UART_RX_BUF_LEN_LMT The receiving buffer size of the serial port.
    UART_TX_BUF_LEN_LMT The sending buffer size of the serial port.
    UART_QUEUE_BUF_LEN_LMT The buffer size of the queue.

    The procedure for receiving and processing MCU SDK serial data:

    1. The MCU receives serial data, and the data is enqueued (stored in the queue buffer).
    2. Periodically dequeue serial data in the main loop (stored in the serial port receiving buffer) and then start data parsing.
    3. Call the main interface for frame receiving and processing after data parsing.

    The procedure for sending MCU SDK serial data:

    1. Populate the payload field (stored in the serial port sending buffer).
    2. Populate other fields (stored in the serial port sending buffer).
    3. Send the frame.
    #define UART_RX_BUF_LEN_LMT                     256
    #define UART_TX_BUF_LEN_LMT                     256
    #define UART_QUEUE_BUF_LEN_LMT                  512
    
  • Command information

    Identifier Description Notes
    OTA_PACKET_SIZE The size of OTA single packet. Used when receiving OTA update data. The maximum value is 0x30.
    ZG_WAIT_MCU_TIME_DEFAULT The time the Zigbee module waits for the MCU to wake up from sleep mode. Used when the Zigbee module wakes up the MCU by voltage levels or the MCU wakes up the Zigbee module by pulses. The value needs to be modified based on the specific MCU.
    ///< OTA single packet payload length (uart command id: 0x0c 0x0d 0x0e)
    #define OTA_PACKET_SIZE                         0x30            // max: 0x30
    
    ///< Zigbee module waits MCU time after Zigbee module starting wakeuping MCU (uart command id: 0x2b)
    #if SLEEP_END_DEVICE
    #define ZG_WAIT_MCU_TIME_DEFAULT                10
    #endif
    

Serial port service function

  • Description

    Identifier Description Notes
    uart_servive_rx_store The serial data single-byte receiver and handler function. It enqueues every byte of data received by the serial port. Add this function to the serial data single-byte receiver and handler function in the project.
    uart_service_parse The frame parsing function. It is dequeued and then parses all the dequeued data (including the data that has not been successfully parsed before). Add this function to the main loop or timer callback in the project.

Serial data sending function

  • Description

    Identifier Description Notes
    uart_send_frame The frame sending function. Select the mode for the MCU to wake up the Zigbee module in this function for low-power devices and implement the corresponding wake-up sending function in the project.
    uart_send_bytes The serial port multi-byte sending function. -
    uart_send_byte The serial port single-byte sending function. Call the serial data single-byte sending function to implement this function in the project.

Zigbee module wake-up function

  • Description

    Identifier Description
    mcu_wakeup_zg_level_method The Zigbee module wake-up function by MCU . Wake-up method: By voltage levels.
    mcu_wakeup_zg_pulse_method The Zigbee module wake-up function by MCU . Wake-up method: By pulses.

Frame receiver and handler function (user interface)

  • Description

    Identifier Description
    mcu_recv_factory_recovery_cb

    mcu_recv_scene_config_cb
    The frame receiver and handler function (user interface) with the mcu_recv_ prefix for each command.

Frame sending function

  • Description

    Identifier Description
    mcu_tx_let_zigbee_reset

    mcu_tx_send_DP_group
    The frame sending function with the mcu_tx_ prefix for each command.

mcu_api.c

Function

  • Function definition: Serial port service function and data sending function.