SDK 9.0 ( BLE+SERIAL ) Dual Bootloader

We have a custom board with nrf51822 chipset, and we need to implement the firmware update process, which can support both over-the-air and uart type firmware update.

1、Just an update - I was able to test the UART DFU and it works,Route:nRF51_SDK_9.0.0_2e23562\examples\dfu\bootloader\pca10028\dual_bank_serial_s110\arm5_no_packs.

2、Just an update - I was able to test the BLE DFU and it works,Route:nRF51_SDK_9.0.0_2e23562\examples\dfu\bootloader\pca10028\dual_bank_ble_s110\arm5_no_packs.

So our app on our custom board supports DFU over either BLE or UART.

I want combine BLE DFU and serial DFU in one demo, but when I transplant serial DFU function into BLE DFU demo,  this combine DFU can’t, could you tell me how you solve this problem?

combine  DFU  code:

main function:

bool app_reset  = false;
if (NRF_POWER->GPREGRET == BOOTLOADER_BLE_DFU_START)
{
	app_reset = true;
	flag_ble_selected = true;
}
else if (NRF_POWER->GPREGRET == BOOTLOADER_SERIAL_DFU_START)
{
	app_reset = true;
	flag_ble_selected = false;
}

bootloader_dfu_start() function:

uint32_t bootloader_dfu_start(void)
{
    uint32_t err_code;

    // Clear swap if banked update is used.
    err_code = dfu_init(); 
    if (err_code != NRF_SUCCESS)    
    {
        return err_code;
    }

    //err_code = dfu_transport_update_start();
	//Branch out SERIAL - BLE
    if ( flag_ble_selected ) 
	{
        err_code = dfu_ble_transport_update_start();
    }
	else			
	{   
		err_code = dfu_serial_transport_update_start();				
    }
    wait_for_events();

    return err_code;
}

uint32_t dfu_ble_transport_update_start(void)
{
    uint32_t err_code;

    m_tear_down_in_progress = false;
    m_pkt_type              = PKT_TYPE_INVALID;

    leds_init();

    err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    dfu_register_callback(dfu_cb_handler);

    err_code = hci_mem_pool_open();
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    err_code = dfu_ble_peer_data_get(&m_ble_peer_data);
    if (err_code == NRF_SUCCESS)
    {
        m_ble_peer_data_valid = true;
    }
    else
    {
        ble_gap_addr_t addr;

        err_code = sd_ble_gap_address_get(&addr);
        APP_ERROR_CHECK(err_code);

        // Increase the BLE address by one when advertising openly.
        addr.addr[0] += 1;

        err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr);
        APP_ERROR_CHECK(err_code);
    }

    gap_params_init();
    services_init();
    conn_params_init();
    sec_params_init();
    advertising_start();

    return NRF_SUCCESS;
}


uint32_t dfu_serial_transport_update_start(void)
{
    uint32_t err_code;

    // Initialize data buffer queue.
    data_queue_init();

    dfu_register_callback(dfu_cb_seraial_handler);

	//Open transport layer.
    err_code = hci_uart_transport_open();
    APP_ERROR_CHECK(err_code);

    // Register callback to be run when commands have been received by the transport layer.
    err_code = hci_transport_evt_handler_reg(rpc_transport_event_handler);
    APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}

if  flag_ble_selected = true; this combine DFU can’t work.if  I mask err_code = dfu_serial_transport_update_start();  the combine DFU  ble dfu  can work,why? flag_ble_selected = 

true, The dfu_serial_transport_update_start()  statement in the bootloader_dfu_start()  function is not called

uint32_t bootloader_dfu_start(void)
{
    uint32_t err_code;

    // Clear swap if banked update is used.
    err_code = dfu_init(); 
    if (err_code != NRF_SUCCESS)    
    {
        return err_code;
    }

    //err_code = dfu_transport_update_start();
	//Branch out SERIAL - BLE
    if ( flag_ble_selected ) 
	{
        err_code = dfu_ble_transport_update_start();
    }
	else			
	{   
		//err_code = dfu_serial_transport_update_start();				
    }
    wait_for_events();

    return err_code;
}

I did an experiment: 

 //hci_uart_transport_open();

//hci_transport_evt_handler_reg(rpc_transport_event_handler);

the combine DFU  ble dfu  can work。why? What else do I need to modify? thanks!

uint32_t bootloader_dfu_start(void)
{
    uint32_t err_code;

    // Clear swap if banked update is used.
    err_code = dfu_init(); 
    if (err_code != NRF_SUCCESS)    
    {
        return err_code;
    }

    //err_code = dfu_transport_update_start();
	//Branch out SERIAL - BLE
    if ( flag_ble_selected ) 
	{
        err_code = dfu_ble_transport_update_start();
    }
	else			
	{   
		err_code = dfu_serial_transport_update_start();				
    }
    wait_for_events();

    return err_code;
}

uint32_t dfu_serial_transport_update_start(void)
{
    uint32_t err_code;

    // Initialize data buffer queue.
    data_queue_init();

    dfu_register_callback(dfu_cb_seraial_handler);

    //Open transport layer.
    //err_code = hci_uart_transport_open();
    //APP_ERROR_CHECK(err_code);

    // Register callback to be run when commands have been received by the transport layer.
    //err_code = hci_transport_evt_handler_reg(rpc_transport_event_handler);
    //APP_ERROR_CHECK(err_code);

    return NRF_SUCCESS;
}


uint32_t hci_uart_transport_open(void)
{
    //uint32_t err_code;
	
    mp_tx_buffer                 = NULL;
    m_tx_buffer_length           = 0;
    m_tx_retry_counter           = 0;
    m_is_slip_decode_ready       = false;
    m_tx_state                   = TX_STATE_IDLE;
    m_packet_expected_seq_number = INITIAL_ACK_NUMBER_EXPECTED;
    m_packet_transmit_seq_number = INITIAL_ACK_NUMBER_TX;
    m_tx_done_result_code        = HCI_TRANSPORT_TX_DONE_FAILURE;
    
    uint32_t err_code = app_timer_create(&m_app_timer_id, 
                                         APP_TIMER_MODE_REPEATED, 
                                         hci_transport_timeout_handle);
    if (err_code != NRF_SUCCESS)
    {    
        // @note: conduct required interface adjustment.
        return NRF_ERROR_INTERNAL;
    }
    
    err_code = hci_mem_pool_open();
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }    
    
    err_code = hci_slip_open();
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }     
    
    err_code = hci_mem_pool_rx_produce(RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
    if (err_code != NRF_SUCCESS)
    {
        // @note: conduct required interface adjustment.
        return NRF_ERROR_INTERNAL;
    }   
    
    err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE);
    
    return err_code;    
}

I'm working on a custom board based on the nRF51822. I'm developing on Win7, nRFgo Studio version 1.21.13. nRF51_SDK_9.0.0_2e23562

Related