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