MCU SDK Migration Guide

Last Updated on : 2022-02-16 03:31:46download

MCU SDK is the MCU code automatically generated according to the product functions defined on the Tuya IoT Platform, facilitating MCU program development. This topic describes the process of MCU SDK migration for the Bluetooth Low Energy (LE) general solution.

Development

  1. Configure the product in protocol.h. For example, how the Bluetooth status indicator is processed and whether to support MCU update.
  2. Migrate MCU SDK. For more information about migration steps, see the description in the protocol.c file.
  3. Add the calling function of reporting and sending DPs.

File structure

File
Description
mcu_api.c Contain functions that can be called.
mcu_api.h mcu_api.c function declaration.
protocol.c Contain the content processing function of the protocol data. You can add code to the corresponding function as needed and get data sent by the Bluetooth LE module to the MCU.
protocol.h protocol.h contains the following information:
  • Initialization parameters that the MCU sends to the Bluetooth LE module.
  • Macros defined by the custom SDK. You can enable the corresponding macro definition as needed.
  • protocol.c function declaration.
system.c The implementation of serial communication protocol parsing.
system.h system.h contains the following information:
  • Definitions of protocol commands.
  • Definitions of some global variables.
  • system.c function declaration.
bluetooth.h Contain Bluetooth LE macro definitions.

Note: You need to configure mcu_ota_handler.h and mcu_ota_handler.c. Since OTA is closely related to the chip, you need to debug the applicable chips.

Step 1: Initialize

  1. Add the code include bluetooth.h to the files that use Bluetooth functions.

  2. Call the bt_protocol_init() function in the mcu_api.c file during MCU initialization.

  3. Add the single-byte sending function of the MCU serial port to the uart_transmit_output function in the protocol.c file, and delete #error.

    void uart_transmit_output(unsigned char value)
    {
    	uart_send(&value,1);  
    }
    
  4. Call the uart_receive_input function in the mcu_api.c file in the MCU serial receiving function. Pass in the received bytes as 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 enters the while loop, the bt_uart_service() function in the mcu_api.c file is called.

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

Step 2: Implement functions

Send DP data

	static unsigned char dp_download_switch_1_handle(const unsigned char value[], unsigned short length)
	{
	  // For example, the DP is bool type
	  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;
	}
	……

Report DP 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 by the Tuya IoT Platform. Modify each sendable and reportable function and report-only function according to the actual data.
	  mcu_dp_bool_update(DPID_SWITCH_1,key_onOff_status); // Report bool type data
	  mcu_dp_raw_update(DPID_RAW_TEST,raw_test,sizeof(raw_test)); // Report raw type data
	  mcu_dp_value_update(DPID_INT_TEST,value_test); // Report value type data
	  mcu_dp_string_update(DPID_STRING_TEST,string_test,sizeof(string_test)); // Report string type data
	  mcu_dp_enum_update(DPID_ENUM_TEST,enum_test); // Report enumeration data
	}

Step 3: Select data frame

	//=============================================================================
	// Data frame type
	//=============================================================================
	#define         HEAT_BEAT_CMD                   0                               // Heartbeat packet
	#define         PRODUCT_INFO_CMD                1                               // Product information
	#define         WORK_MODE_CMD                   2                               // Query the module working status set by the MCU 
	#define         BT_STATE_CMD                    3                               // Bluetooth working status
	#define         BT_RESET_CMD                    4                               // Reset Bluetooth
	#define         DATA_QUERT_CMD                  6                               // Send command
	#define         STATE_UPLOAD_CMD                7                               // Report status
	#define         STATE_QUERY_CMD                 8                               // Query status  
	////////////////////////////////// This MCU SDK version supports more protocol interfaces ////////////////////
	//// If a command interface is not needed, you can comment out the definition of the command macro to reduce the code space. The related code will not be compiled.
	#define TUYA_BCI_UART_COMMON_UNBOUND_REQ					0x09				// Unbind the Bluetooth LE module
	#define TUYA_BCI_UART_COMMON_RF_TEST	            	    0x0E				// RF test
	#define TUYA_BCI_UART_COMMON_SEND_STORAGE_TYPE              0xE0				// Report the record type data (offline cache)
	#define TUYA_BCI_UART_COMMON_SEND_TIME_SYNC_TYPE            0xE1				// Get the real time
	#define TUYA_BCI_UART_COMMON_MODIFY_ADV_INTERVAL		    0xE2				// Modify broadcast interval in sleep mode
	#define TUYA_BCI_UART_COMMON_TURNOFF_SYSTEM_TIME		    0xE4				// Disable 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 Bluetooth connection
	#define TUYA_BCI_UART_COMMON_QUERY_MCU_VERSION			    0xE8				// Query the MCU version number
	#define TUYA_BCI_UART_COMMON_MCU_SEND_VERSION			    0xE9				// The MCU sends version number
	
	#define TUYA_BCI_UART_COMMON_MCU_OTA_REQUEST			    0xEA				// Request OTA update
	#define TUYA_BCI_UART_COMMON_MCU_OTA_FILE_INFO			    0xEB				// OTA update file information
	#define TUYA_BCI_UART_COMMON_MCU_OTA_FILE_OFFSET	        0xEC				// Request OTA update file offset
	#define TUYA_BCI_UART_COMMON_MCU_OTA_DATA 			        0xED				// OTA update data
	#define TUYA_BCI_UART_COMMON_MCU_OTA_END			        0xEE				// OTA update ends

Step 4: Configure firmware version information

	//protocol.h
	#define MCU_VER "1.0.0"                                 // Software version, used for MCU firmware update
	#define MCU_APP_VER_NUM      0x010000					// Software version, used for MCU firmware update. This version number shall be modified.    				1.0.0
	#define MCU_HARD_VER_NUM     0x010000					// The hardware version

Step 5: Complete interface

Add a functional interface in protocol.c. The sample is as follows.

	void bt_rf_test_result(unsigned char result,signed char rssi)
	{
	  #error "Implement this function by yourself. Delete this line after completion."
	  if(result == 0)
	  {
	    // Test failed 
	  }
	  else
	  {
	    // Test succeeded
	    // RSSI is the signal strength. The value greater than -70 dBm is qualified
	  }
	  
	}

Step 6: Complete MCU OTA function

You can modify mcu_ota_handler.h and mcu_ota_handler.c files as needed. Since OTA is closely related to the chip, you need to debug the applicable chips. The sample code is as follows:

	/*****************************************************************************
	 Function name: mcu_flash_init
	Function description: Flash initialization function.
	Input parameters: None.
	
	Return parameter: None.
	Note: You need to implement the flash initialization function here. If flash initialization is executed in other processes, calling of this function is not required.
	*****************************************************************************/
	uint8_t mcu_flash_init(void)
	{
		#error "Implement this function by yourself. Delete this line after completion."
	}
	/*****************************************************************************
	Function name: mcu_flash_erase
	Function description: Erase flash function.
	Input parameters: addr indicates the address. size indicates flash size.
	
	Return parameter: None.
	Note: You need to implement this function by yourself.
	*****************************************************************************/
	uint8_t mcu_flash_erase(uint32_t addr,uint32_t size)
	{
		#error "Implement this function by yourself. Delete this line after completion."
	}
	/*****************************************************************************
	Function name: mcu_flash_write
	Function description: Flash write function
	Input parameters: addr indicates the address. size indicates flash size. p_data indicates the data address to be written in.
	
	Return parameter: None.
	Note: You need to implement this function by yourself.
	*****************************************************************************/
	
	uint8_t mcu_flash_write(uint32_t addr, const uint8_t *p_data, uint32_t size)
	{
		#error " Implement this function by yourself. Delete this line after completion."
	}
	
	/*****************************************************************************
	Function name: mcu_flash_read
	Function description: Flash read function
	Input parameters: addr indicates the address. size indicates flash size. p_data indicates the data address to be read.
	
	Return parameter: None.
	Note: You need to implement this function by yourself.
	*****************************************************************************/
	
	uint8_t mcu_flash_read(uint32_t addr, uint8_t *p_data, uint32_t size)
	{
		#error "Implement this function by yourself. Delete this line after completion."
	}
	/*****************************************************************************
	Function name: mcu_device_delay_restart
	Function description: Delay reboot function. It is recommended to delay reboot for 500 ms to wait for the MCU to execute necessary operations.
	Input parameters: None.
	
	Return parameter: None.
	Note: You need to implement this function by yourself.
	*****************************************************************************/
	
	void mcu_device_delay_restart(void)
	{
		error "Implement this function by yourself. Delete this line after completion."
	}

Note: To write the boot flag, you can add it in the on_dfu_complete function.