8.2 Host Assisted DFU
The DFU utility functions can be ported on a given Host MCU to perform the DFU operations. There is an example host MCU code (ota_demo) to simulate the DFU utility and perform the update operations on a given partition.
Host MCU can send AT command +TBL to trigger the RNWF11 module to reboot and enter the bootloader for
            DFU. Another method to enter bootloader is configuring MCLR pin to reset the RNWF11 and send boot command (0xa7)
            over UART. 
int Reset_To_Bootloader(void) { unsigned char value; int timeout = ENTER_BTL_CMD_TIMEOUT; DFU_Reset(); while (timeout) { if(UART2.IsTxReady()) { UART2.Write(BL_CMD_ENTER_BTL); while(!UART2.IsTxDone()); } if(UART2.IsRxReady()) { value = UART2.Read(); if (value == BL_RESP_OK) { printf("[%s] success entering bootloader..\r\n",__func__); return APP_FUNC_RESULT_SUCCESS; } } DELAY_milliseconds(200); timeout -= 200; } return APP_FUNC_RESULT_FAIL; }
Bootloader Command
When the RNWF11 module executes bootloader, the host MCU can communicate with the RNWF11 by sending bootloader commands over UART.
Following table lists the details of the commands which can be sent by Host MCU to communicate with bootloader on the RNWF11:
| Bootloader Command | Description | 
|---|---|
| #define BL_CMD_UNLOCK (0xa0) | Unlocks the memory for writing | 
| #define BL_CMD_DATA (0xa1) | Sends image data for DFU | 
| #define BL_CMD_VERIFY (0xa2) | Verifies the CRC | 
| #define BL_CMD_RESET (0xa3) | Performs module Reset | 
| #define BL_CMD_READ_VERSION (0xa6) | Reads bootloader version | 
| #define BL_CMD_ENTER_BTL (0xa7) | Enter bootloader mode | 
| #define BL_CMD_ERASE_APP (0xa8) | Erases program Flash | 
| #define BL_CMD_SET_BAUD_RATE (0xa9) | Sets UART baudrate | 
| Byte | 0 .. 3 | 4 .. 7 | 8 | 9 .. 9 + Payload size | 
| Size (Bytes) | 4 | 4 | 1 | Payload Size | 
| Value | BL_GUARD (0x5048434D) | Size | Command Type | Payload | 
Bootloader Response Byte
For each command, 1 byte response is received from the bootloader. Following is the response byte value:
| Bootloader Command | Response Byte Value | 
|---|---|
| #define BL_RESP_OK | 0x50 | 
| #define BL_RESP_ERROR | 0x51 | 
| #define BL_RESP_INVALID | 0x52 | 
| #define BL_RESP_CRC_OK | 0x53 | 
| #define BL_RESP_CRC_FAIL | 0x54 | 
| #define BL_RESP_NONE | 0xFF | 
Following snippet of code can send the bootloader command according to the command format:
uint8_t send_request(uint8_t cmd, uint8_t *data, int dataLen) {
    uint8_t req[HEADER_SIZE + CMD_ONLY_EXTRA_SIZE + dataLen];
    int resp;
    int cnt = 10;
    uint8_t byteResp;
    
    memset (req, 0, sizeof(req));
    
    req[0] = (uint8_t)(BL_GUARD & 0xFF);        // store the least significant byte
    req[1] = (uint8_t)((BL_GUARD >> 8) & 0xFF); 
    req[2] = (uint8_t)((BL_GUARD >> 16) & 0xFF);
    req[3] = (uint8_t)((BL_GUARD >> 24) & 0xFF);
    req[4] = (uint8_t)(dataLen & 0xFF);        // store the least significant byte
    req[5] = (uint8_t)((dataLen >> 8) & 0xFF); 
    req[6] = (uint8_t)((dataLen >> 16) & 0xFF);
    req[7] = (uint8_t)((dataLen >> 24) & 0xFF);
    req[8] = cmd;
    
    RNWF_IF_Write((uint8_t *)&req, HEADER_SIZE);
    DELAY_microseconds(WRITE_DELAY_USEC);
    
    if ( 0 == dataLen)
    {
        uint8_t extraData[4];
        memset(extraData, 0, sizeof(extraData));
        RNWF_IF_Write(extraData, CMD_ONLY_EXTRA_SIZE);
        DELAY_microseconds(WRITE_DELAY_USEC);
    }
    else
    {  
        RNWF_IF_Write(data, dataLen);
        DELAY_microseconds(WRITE_DELAY_USEC);
    }
    
    resp = 0;
    while (resp == 0 && cnt > 0)
    {
        resp = RNWF_IF_Read(&byteResp, 1);
        
        if (resp == 0)
        {
            DBG_MSG_OTA("ERROR: no response after write, %d\r\n", cnt);
            byteResp = BL_RESP_NONE;
        }
        cnt--;
    }
    
    return byteResp;
}
        DFU Process
The following sequence diagram and procedure describes the DFU process between the host MCU and the RNWF11 bootloader.
- Host MCU sends
                        
BL_CMD_READ_VERSIONcommand line to check the Bootloader revision and determines if the RNWF11 is in the Bootloader mode. The RNWF11 Bootloader responds withBL_RESP_OKcommand and the bootloader version. Host MCU verifies the bootloader version to determine if the RNWF11 is in the Bootloader mode. - Host MCU sends
                        
BL_CMD_UNLOCKcommand line to unlock the Flash memory for programming. Start address and size need to be input with this command. The RNWF11 Bootloader responds withBL_RESP_OKcommand. - Host MCU sends
                        
BL_CMD_DATAcommand line to transfer the image data to the RNWF11 for programming. Address, image data and size are required to be input with this command. - After all the image data is
                    programmed to the RNWF11, send
                        
BL_CMD_VERIFYcommand line to check the CRC of the flashed image. CRC value is input with this command. The RNWF11 Bootloader responds withBL_RESP_CRC_OKcommand if the CRC verification is success. - Host MCU sends
                        
BL_CMD_RESETcommand line to reset the RNWF11 to run the new firmware image. TheRNWF11Bootloader responds withBL_RESP_OKcommand. - After the RNWF11 resets and run to application, Host MCU
                    can send 
AT+GMRcommand to read the firmware version and verify if the RNWF11 is executing the new firmware. 
