MCU SDK Migration Guide

Last Updated on : 2024-05-14 07:37:18download

The MCU SDK contains all you need to get started with MCU development, such as functions and sample code. The SDK is automatically generated based on the product features defined on the Tuya Developer Platform. This topic describes how to port the MCU SDK to your project in Bluetooth Low Energy (LE) common solutions.

Procedure

  1. Configure the product in the protocol.h file. For example, how the Bluetooth status indicator is handled and whether the MCU update is supported.
  2. Port the MCU SDK. For specific steps, see the instructions in the protocol.c file.
  3. Add the functions for processing the received data and reported data.

File structure

File
Description
mcu_api.c Contains functions that can be called.
mcu_api.h Contains declarations for functions in mcu_api.c.
protocol.c Contains functions for processing protocol data. You can add code to related functions as needed and get data sent by the Bluetooth LE module to the MCU.
protocol.h protocol.h contains the following information:
  • Parameters that the MCU sends to the Bluetooth LE module for initialization.
  • Macros defined for custom features, which can be enabled as needed.
  • Declarations for functions in protocol.c.
system.c Contains the implementation of parsing the serial protocol.
system.h system.h contains the following information:
  • Definitions of commands.
  • Some global variables.
  • Declarations for functions in system.c.
bluetooth.h Contains macro definitions for the Bluetooth protocol.

You need to configure mcu_ota_handler.h and mcu_ota_handler.c. OTA update is closely related to the chip, and you need to debug and modify it to suit your chipset platform.

Step 1: Initialize the MCU

  1. Add the code include "bluetooth.h" to the file that needs to use the Bluetooth features.

  2. Call the bt_protocol_init() function in the mcu_api.c file when the MCU is initialized.

  3. Specify the serial transmission function in uart_transmit_output in the protocol.c file, and delete #error.

    void uart_transmit_output(unsigned char value)
    {
        uart_send(&value,1);
    }
    
  4. In the MCU’s function for serial data reception, call uart_receive_input in the mcu_api.c file and pass in the received data as the parameters.

    void uart_isr(void)
    {
        uint32_t IntStat;
        IntStat = uart_isr_stat_get();
        if(uart_rx_fifo_need_rd_isr_getf() || uart_rx_end_isr_getf()|| uart_rxd_wakeup_isr_getf())
        {
            while((REG_APB3_UART_FIFO_STAT & (0x01 << 21)))
            {
                uint8_t ch = UART_READ_BYTE();
                uart_receive_input(ch);
                    …
            }
            …
        }
        …
    }
    
  5. After the MCU runs in the while loop, it calls the bt_uart_service() function in the mcu_api.c file.

    void main_loop(void)
    {
        while(1)
        {
        bt_uart_service();
        …
        }
    }
    

Step 2: Implement specific user functions

Process the received data

    static unsigned char dp_download_switch_1_handle(const unsigned char value[], unsigned short length)
    {
      // Example: The current DP type is Boolean.
      unsigned char ret;
      // 0: off. 1: on.
      unsigned char switch_1;
      switch_1 = mcu_get_dp_download_bool(value,length);
      if(switch_1 == 0)
      {
        // The switch is off.
      }
      else
      {
        // The switch is on.
      }
      // Feedback after the DP data is processed
      ret = mcu_dp_bool_update(DPID_SWITCH_1,switch_1);
      if(ret == SUCCESS)
        return SUCCESS;
      else
        return ERROR;
    }
    …

Process the reported data

    uint8_t key_onOff_status;
    uint8_t raw_test[4];
    uint32_t value_test;
    uint8_t string_test[16];
    uint8_t enum_test;
    void all_data_update(void)
    {
      // This code is automatically generated. You need to edit it based on the actual DPs.
      mcu_dp_bool_update(DPID_SWITCH_1,key_onOff_status); // Report Boolean data.
      mcu_dp_raw_update(DPID_RAW_TEST,raw_test,sizeof(raw_test)); // Report raw data.
      mcu_dp_value_update(DPID_INT_TEST,value_test); // Report value data.
      mcu_dp_string_update(DPID_STRING_TEST,string_test,sizeof(string_test)); // Report string data.
      mcu_dp_enum_update(DPID_ENUM_TEST,enum_test); //Report enum data.
    }

Step 3: Select the data frame

    //=============================================================================
    // The data frame type.
    //=============================================================================
    #define         HEAT_BEAT_CMD                   0                               // Send a heartbeat.
    #define         PRODUCT_INFO_CMD                1                               // Request product information.
    #define         WORK_MODE_CMD                   2 // Query the working mode of the module set by MCU.
    #define         BT_STATE_CMD                    3                               // Query Bluetooth working status.
    #define         BT_RESET_CMD                    4                               // Reset the Bluetooth module.
    #define         DATA_QUERT_CMD                  6                               // Send a command.
    #define         STATE_UPLOAD_CMD                7                               // Report the status.
    #define         STATE_QUERY_CMD                 8                               // Query the status.
    /////////////////////////////////////The current MCU SDK version supports the following protocol interfaces compared to the previous version/ ////////////////////
    // If you do not need a certain command interface, you can comment out the command macro definition to reduce the code space. The specified code will not be compiled.
    #define TUYA_BCI_UART_COMMON_UNBOUND_REQ                    0x09                // Unbind the module.
    #define TUYA_BCI_UART_COMMON_RF_TEST                        0x0E                //RF test.
    #define TUYA_BCI_UART_COMMON_SEND_STORAGE_TYPE              0xE0                // Report record-type data that is cached when offline.
    #define TUYA_BCI_UART_COMMON_SEND_TIME_SYNC_TYPE            0xE1                // Get the current time.
    #define TUYA_BCI_UART_COMMON_MODIFY_ADV_INTERVAL            0xE2                // Modify the broadcast interval in sleep mode.
    #define TUYA_BCI_UART_COMMON_TURNOFF_SYSTEM_TIME            0xE4                // Turn off the system clock.
    #define TUYA_BCI_UART_COMMON_ENANBLE_LOWER_POWER            0xE5                // Enable the low power mode.
    #define TUYA_BCI_UART_COMMON_SEND_ONE_TIME_PASSWORD_TOKEN     0xE6                // Get the matching result of one-time dynamic password.
    #define TUYA_BCI_UART_COMMON_ACTIVE_DISCONNECT                0xE7                // Disconnect from the Bluetooth connection.
    #define TUYA_BCI_UART_COMMON_QUERY_MCU_VERSION                0xE8                // Query the version number of the MCU.
    #define TUYA_BCI_UART_COMMON_MCU_SEND_VERSION                0xE9                // The MCU proactively sends its version number.
    
    #define TUYA_BCI_UART_COMMON_MCU_OTA_REQUEST                0xEA                // Request an OTA update.
    #define TUYA_BCI_UART_COMMON_MCU_OTA_FILE_INFO                0xEB                // The OTA update file information.
    #define TUYA_BCI_UART_COMMON_MCU_OTA_FILE_OFFSET            0xEC                // The offset of the OTA update file.
    #define TUYA_BCI_UART_COMMON_MCU_OTA_DATA                     0xED                // The OTA update data.
    #define TUYA_BCI_UART_COMMON_MCU_OTA_END                    0xEE                // The OTA update is completed.

Step 4: Configure the firmware version information

    //protocol.h
    #define MCU_VER "1.0.0"                  // The MCU firmware version number, which must be changed to the new one after MCU updates. #define MCU_APP_VER_NUM      0x010000                    // The MCU firmware version number, which must be changed to the new one after MCU updates. 0x010000 indicates 1.0.0.     #define MCU_HARD_VER_NUM     0x010000                    // The hardware version.

Step 5: Configure the interface

Add a functional interface to the protocol.c file, as shown in the following example.

    void bt_rf_test_result(unsigned char result,signed char rssi)
    {
      #error "Complete the implementation and then delete this row."
      if(result == 0)
      {
        // Test failed.
      }
      else
      {
        // Test succeeded.
        // RSSI is the received signal strength indication. Values ​​greater than -70 dBm are considered normal signal strength.
      }
    }

Step 6: Configure the MCU OTA update feature

You need to configure mcu_ota_handler.h and mcu_ota_handler.c as needed. OTA update is closely related to the chip, and you need to debug and modify it to suit your chipset platform. Here is an example:

    /*****************************************************************************
    Function name: mcu_flash_init.
    Functional description: Initialize the flash memory.
    Input parameter:

    Return parameter: none.
    Note: You need to complete the flash initialization function here. If you perform flash initialization operations elsewhere, this function does not need to be called.
    *****************************************************************************/
    uint8_t mcu_flash_init(void)
    {
        #error "Complete the implementation and then delete this row."
    }
    /*****************************************************************************
    Function name: mcu_flash_erase.
    Functional description: Erase the flash memory.
    Input parameters: addr: the address, size: the size.

    Return parameter: none.
    Note: This function is intended to be implemented by you.
    *****************************************************************************/
    uint8_t mcu_flash_erase(uint32_t addr,uint32_t size)
    {
        #error "Complete the implementation and then delete this row."
    }
    /*****************************************************************************
    Function name: mcu_flash_write.
    Functional description: Write to the flash memory.
    Input parameters: addr: the address, size: the size, and p_data: the address of the data to be written.

    Return parameter: none.
    Note: This function is intended to be implemented by you.
    *****************************************************************************/
    uint8_t mcu_flash_write(uint32_t addr, const uint8_t *p_data, uint32_t size)
    {
        #error "Complete the implementation and then delete this row."
    }
    /****************************************************************************
    Function name: mcu_flash_read.
    Functional description: Read from the flash memory.
    Input parameters: addr: the address, size: the size, and p_data: the address of the data to be read.

    Return parameter: none.
    Note: This function is intended to be implemented by you.
   *****************************************************************************/
    uint8_t mcu_flash_read(uint32_t addr, uint8_t *p_data, uint32_t size)
    {
        #error "Complete the implementation and then delete this row."
    }
    /*****************************************************************************
    Function name: mcu_device_delay_restart.
    Functional description: Delayed restart function. It is recommended to delay the restart for 500 ms to wait for the MCU to complete the necessary operations.
    Input parameter:

    Return parameter: none.
    Note: This function is intended to be implemented by you.
    *****************************************************************************/
    void mcu_device_delay_restart(void)
    {
        error "Complete the implementation and then delete this row."
    }

If you need to write to the boot flag, you can add it in the on_dfu_complete function.