3.1.7.5 Wi-Fi OTA Service Interface

The OTA service role is to enable the module firmware update over the network link. The OTA service has the HTTP based file download and RNWF Device Firmware Update (DFU) implementation. The OTA service open ups a TCP tunnel to receive the OTA server and firmware image details. Any device (say PC or Mobile) in the network can initiate the firmware download process. Once the OTA service receives all the necessary details, it starts downloading the firmware image and reports each downloaded chunk to user application over the callback. The user application needs to store the firmware in the local memory. After the successful download the user application can use the OTA service API's to flash new image into the RNWF module. The OTA service API call syntax is provided below:
RNWF_RESULT_t RNWF_OTA_SrvCtrl( RNWF_OTA_SERVICE_t request, void *input)
The following table provides the list of OTA services available:
Table 3-10. OTA Services
Option/Command Input Description
RNWF_OTA_ENABLE Buffer of 4096 (to align with DFU max write size) bytes Enable OTA service and opens a TCP tunnel to receive the OTA server and Image details
RNWF_OTA_SET_CALLBACK Callback handler Register callback function for the OTA service to report the status
RNWF_OTA_DFU_INIT None Generates the DFU pattern and places the RNWF module in firmware update mode
RNWF_OTA_DFU_WRITE chunk_addr, chunk_size, chunk_ptr Writes the given chunk into the RNWF module. Max chunk size can be 4096 bytes.
RNWF_OTA_DFU_ERASE chunk_addr, chunk_size, chunk_ptr Erases the provided size of memory (chunk_ptr can be NULL)
The following table captures the OTA Callback event codes and event data:
Table 3-11. OTA Event Codes
Event Response Component Description
RNWF_EVENT_DWLD_START Total size of the image file to be downloaded Given image file download has started
RNWF_EVENT_DWLD_DONE Total size of downloaded Image file Firmware download process completed, the application can initialize the DFU and start flle
RNWF_EVENT_FILE_CHUNK chunk_addr, chunk_size, chunk_ptr Received image file chunk, the received data chunk must be saved in non-volatile memory
RNWF_EVENT_DWLD_FAIL None Firmware download failed

The sequence chart for the OTA process is provided below:

Figure 3-37. OTA Process

The example code for OTA DFU is provided below:

/*
    OTA application
*/
extern uint8_t app_buf[OTA_BUF_LEN_MAX];
uint32_t gOta_file_size = 0;
void APP_OTA_Program(uint32_t flash_addr, uint32_t flash_size)
{   
    RNWF_OTA_CHUNK_t ota_chunk = { .chunk_addr = 0x60000000, .chunk_ptr = app_buf, .chunk_size = flash_size}; 
    printf("Triggering DFU %lu\r\n", flash_size);
    RNWF_OTA_SrvCtrl(RNWF_OTA_DFU_INIT, (void *)NULL);            
    while(RNWF_OTA_SrvCtrl(RNWF_OTA_DFU_ERASE, (void *)&ota_chunk) != RNWF_PASS);
    while(flash_size)
    {                
        ota_chunk.chunk_size = (flash_size < OTA_BUF_LEN_MAX)?flash_size:OTA_BUF_LEN_MAX; 
        /* User needs to read the stored OTA image and pass-in to RNWF_OTA_SrvCtrl() */                
        HighSpeed_Read_Cont(flash_addr, ota_chunk.chunk_size, (char *)app_buf);                            
        RNWF_OTA_SrvCtrl(RNWF_OTA_DFU_WRITE, (void *)&ota_chunk);
        flash_size -= ota_chunk.chunk_size;
        ota_chunk.chunk_addr += ota_chunk.chunk_size;
        flash_addr += ota_chunk.chunk_size;
        printf("Remaining %lu bytes\r\n", flash_size);  
    }
}
void APP_OTA_Callback(RNWF_OTA_EVENT_t event, void *p_str)
{
    static uint32_t flash_addr = OTA_FLASH_IMAGE_START;
    switch(event)
    {
        case RNWF_EVENT_MAKE_UART:
            break;
        case RNWF_EVENT_DWLD_START:
        {
            printf("Total Size = %lu\r\n", *(uint32_t *)p_str); 
            printf("Erasing the SPI Flash\r\n");
            WREN();
            Chip_Erase();
            Wait_Busy();
            SPI_Global_Block_Protection_Unlock();
            printf("Erasing Complete!\r\n"); 
        }
        break;
        case RNWF_EVENT_DWLD_DONE:
        {                                                 
            printf("Download Success!= %lu bytes\r\n", *(uint32_t *)p_str);
            /* Completed the Image download, start the DFU */ 
            APP_OTA_Program(OTA_FLASH_IMAGE_START, *(uint32_t *)p_str);            
            APP_SW_RESET_Handler();
        }
        break;        
        case RNWF_EVENT_FILE_CHUNK:
        {
            volatile RNWF_OTA_CHUNK_t *ota_chunk = (RNWF_OTA_CHUNK_t *)p_str;  
            /* Save the received Image chunk into the serial SST flash*/             
            Sector_Program(flash_addr, ota_chunk->chunk_ptr, ota_chunk->chunk_size);            
            flash_addr += ota_chunk->chunk_size;
        }    
        break;
        case RNWF_EVENT_DWLD_FAIL:
        {
            /* Erase the Serial SST flash*/
            WREN();
            Chip_Erase();
            Wait_Busy();            
        }
        break;
        default:
            break;
    }
}
void APP_WIFI_Callback(RNWF_WIFI_EVENT_t event, uint8_t *p_str)
{
    switch(event)
    {
        case RNWF_DHCP_DONE:
        {
            printf("DHCP IP:%s\n", &p_str[2]); 
            // Enable OTA by passing the OTA buffer space
            if(RNWF_OTA_SrvCtrl(RNWF_OTA_ENABLE, (void *)app_buf) == RNWF_PASS)
            {
                printf("Successfully Enabled the OTA\r\n");
            }
            else
            {
                printf("Failed to enable the OTA\r\n");
            }
            break;       
        }
        default:
        {
            break;
        }
    }
}
void RNWF_APP_Initialize(void)
{    
    /* Wi-Fii Connectivity */
    RNWF_WIFI_PARAM_t wifi_sta_cfg = {RNWF_WIFI_MODE_STA, HOME_AP_SSID, HOME_AP_PASSPHRASE, HOME_AP_SECURITY, 1};    
    printf("Connecting to %s\r\n", HOME_AP_SSID);
    RNWF_WIFI_SrvCtrl(RNWF_WIFI_SET_CALLBACK, APP_WIFI_Callback);
    RNWF_WIFI_SrvCtrl(RNWF_SET_WIFI_PARAMS, &wifi_sta_cfg);

    /* RNWF Application Callback register */
    RNWF_OTA_SrvCtrl(RNWF_OTA_SET_CALLBACK, (void *)APP_OTA_Callback);
    while(1)
    {  
        RNWF_EVENT_Handler();
    }    
}    
The data types used for the OTA service are provided below: