This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Issuse about nRF51822 OTA By Android 9.0

 Hi,I had a problem with  nRF51822 DFU.I tried to OTD nRF51822(version SDK_9.0.0 s110) wiht Android 9.0 devices(nRF tool version  1.9.0),but it always fail at 1%.The problem occured because of the version? The log of Android dfu  is on attachment.

Parents
  • Hi James, the SDK v9.0.0 bootloader will reply with op Code 6 (Operation Failed) if the length of the start DFU packet or Init packet is longer than PKT_START_DFU_PARAM_LEN (2).

    static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt)
    {
        ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
    
        write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
    
        if (!is_cccd_configured(p_dfu))
        {
            // Send an error response to the peer indicating that the CCCD is improperly configured.
            write_authorize_reply.params.write.gatt_status =
                BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
    
            return (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
    
        }
        else
        {
            uint32_t err_code;
    
            write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
    
            err_code = (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply));
    
            if (err_code != NRF_SUCCESS)
            {
                return err_code;
            }
        }
    
        ble_dfu_evt_t ble_dfu_evt;
    
        switch (p_ble_write_evt->data[0])
        {
            case OP_CODE_START_DFU:
                ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_START;
    
                if (p_ble_write_evt->len < PKT_START_DFU_PARAM_LEN)
                {
                    return ble_dfu_response_send(p_dfu,
                                                 (ble_dfu_procedure_t) p_ble_write_evt->data[0],
                                                 BLE_DFU_RESP_VAL_OPER_FAILED);
                }
    
                ble_dfu_evt.evt.ble_dfu_pkt_write.len    = 1;
                ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
    
                p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
                break;
    
            case OP_CODE_RECEIVE_INIT:
                ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_INIT_DATA;
    
                if (p_ble_write_evt->len < PKT_INIT_DFU_PARAM_LEN)
                {
                    return ble_dfu_response_send(p_dfu,
                                                 (ble_dfu_procedure_t) p_ble_write_evt->data[0],
                                                 BLE_DFU_RESP_VAL_OPER_FAILED);
                }
                
                ble_dfu_evt.evt.ble_dfu_pkt_write.len    = 1;
                ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]);
    
                p_dfu->evt_handler(p_dfu, &ble_dfu_evt);
                break;
            .
            .
            .
        }
    }

    Which version of nrfutil did you use to generate the firmware image used for the DFU?

    Best regards

    Bjørn

  • Hi Bjørn, I generate the firmware image by Master Control Panel\3.8.0.7\nrf\nrf.exe

  • HI James, I took a closer look at the Android log and its not the Init or start packet, as I can see that these are processed correctly. The error occurs when the DFU controller(Android phone) is writing to the DFU Packet characteristic. I believe that we're entering the default case in nrf_err_code_translate() which is called by dfu_error_notify() which is in turn called by app_data_process() if something goes wrong during the reception of the firmware data. 

    My bet is that hci_mem_pool_rx_consume() is returning NRF_ERROR_NO_MEM, which is translated to BLE_DFU_RESP_VAL_OPER_FAILED by nrf_err_code_translate(). 

    Could you try to use the nRF connect application and enable the packes receipts notification and set the number of packets to 1 under DFU Settings.? ( DFU settings is found under settings when pressing the three horizontal bars in the upper-left corner of the app window. )

  • Hi Bjørn,I changed the MIN_CONN_INTERVAL from 15 to 25, it worked fine now.I didn't know why.

  • HI James, 

    the older bootloaders SDK v9.0.0 and older had a known issue with the packet buffers being filled up faster than the data could be written to flash, if the the central sent packets with a very short interval and/or sent many packets per connection interval. So that is why we have the PRN (packes receipts notification) which sets the number of packets between each acknowledgement from the DfuTarget. If you set it to 1, the DfuTarget will ack every packet and prevent the buffer from overflowing. Increasing the connection interval will also work, as you have seen. 

    Best regards

    Bjørn

Reply
  • HI James, 

    the older bootloaders SDK v9.0.0 and older had a known issue with the packet buffers being filled up faster than the data could be written to flash, if the the central sent packets with a very short interval and/or sent many packets per connection interval. So that is why we have the PRN (packes receipts notification) which sets the number of packets between each acknowledgement from the DfuTarget. If you set it to 1, the DfuTarget will ack every packet and prevent the buffer from overflowing. Increasing the connection interval will also work, as you have seen. 

    Best regards

    Bjørn

Children
Related