Beispiel #1
0
static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	if (argc < 4)
		return CMD_RET_USAGE;

	char *usb_controller = argv[1];
	char *interface = argv[2];
	char *devstring = argv[3];

	int ret, i = 0;

	ret = dfu_init_env_entities(interface, simple_strtoul(devstring,
							      NULL, 10));
	if (ret)
		goto done;

	ret = CMD_RET_SUCCESS;
	if (argc > 4 && strcmp(argv[4], "list") == 0) {
		dfu_show_entities();
		goto done;
	}

	int controller_index = simple_strtoul(usb_controller, NULL, 0);
	board_usb_init(controller_index, USB_INIT_DEVICE);

	g_dnl_register("usb_dnl_dfu");
	while (1) {
		if (dfu_reset())
			/*
			 * This extra number of usb_gadget_handle_interrupts()
			 * calls is necessary to assure correct transmission
			 * completion with dfu-util
			 */
			if (++i == 10)
				goto exit;

		if (ctrlc())
			goto exit;

		usb_gadget_handle_interrupts();
	}
exit:
	g_dnl_unregister();
done:
	dfu_free_entities();

	if (dfu_reset())
		run_command("reset", 0);

	return ret;
}
Beispiel #2
0
void dfu_control_setup() {
    switch (usb_setup.bRequest) {
    case DFU_DNLOAD:
        if (dfu_state == DFU_STATE_dfuIDLE || dfu_state == DFU_STATE_dfuDNLOAD_IDLE) {
            if (usb_setup.wLength == 0) {
                dfu_state = DFU_STATE_dfuMANIFEST_SYNC;
                usb_ep0_out();
                return usb_ep0_in(0);
            } else {
                dfu_block_offset = 0;
                dfu_cb_dnload_block(usb_setup.wValue, usb_setup.wLength);

                if (dfu_state != DFU_STATE_dfuERROR) {
                    dfu_state = DFU_STATE_dfuDNBUSY;
                    return usb_ep0_out();
                }
            }
        } else {
            dfu_error(DFU_STATUS_errSTALLEDPKT);
        }
        return usb_ep0_stall();
    case DFU_UPLOAD:
        dfu_error(DFU_STATUS_errSTALLEDPKT);
        return usb_ep0_stall();
    case DFU_GETSTATUS: {
        if (dfu_state == DFU_STATE_dfuMANIFEST_SYNC) {
            dfu_state = DFU_STATE_dfuMANIFEST;
            dfu_cb_manifest();
        }

        uint8_t len = usb_setup.wLength;
        if (len > sizeof(DFU_StatusResponse)) len = sizeof(DFU_StatusResponse);
        DFU_StatusResponse* status = (DFU_StatusResponse*) ep0_buf_in;
        status->bStatus = dfu_status;
        status->bwPollTimeout[0] = (dfu_poll_timeout >>  0) & 0xFF;
        status->bwPollTimeout[1] = (dfu_poll_timeout >>  8) & 0xFF;
        status->bwPollTimeout[2] = (dfu_poll_timeout >> 16) & 0xFF;
        status->bState = dfu_state;
        status->iString = 0;
        usb_ep0_in(len);
        return usb_ep0_out();
    }
    case DFU_ABORT:
    case DFU_CLRSTATUS:
        dfu_reset();
        usb_ep0_in(0);
        return usb_ep0_out();
    case DFU_GETSTATE:
        ep0_buf_in[0] = dfu_state;
        usb_ep0_in(1);
        return usb_ep0_out();
    }
    return usb_ep0_stall();
}
/**@brief     Function for the Device Firmware Update Service event handler.
 *
 * @details   This function will be called for all Device Firmware Update Service events which
 *            are passed to the application.
 *
 * @param[in] p_dfu     Device Firmware Update Service structure.
 * @param[in] p_evt     Event received from the Device Firmware Update Service.
 */
static void on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
{
    uint32_t err_code;

    switch (p_evt->ble_dfu_evt_type)
    {
        case BLE_DFU_VALIDATE:
            err_code = dfu_image_validate();

            // Translate the err_code returned by the above function to DFU Response Value.
            ble_dfu_resp_val_t resp_val;

            resp_val = nrf_err_code_translate(err_code, BLE_DFU_VALIDATE_PROCEDURE);

            err_code = ble_dfu_response_send(p_dfu, BLE_DFU_VALIDATE_PROCEDURE, resp_val);
            APP_ERROR_CHECK(err_code);
            break;

        case BLE_DFU_ACTIVATE_N_RESET:
            err_code = dfu_transport_close();
            APP_ERROR_CHECK(err_code);

            // With the S110 Flash API it is safe to initiate the activate before connection is 
            // fully closed.
            err_code = dfu_image_activate();
            if (err_code != NRF_SUCCESS)
            {
                dfu_reset();
            }
            break;

        case BLE_DFU_SYS_RESET:
            err_code = dfu_transport_close();
            APP_ERROR_CHECK(err_code);
        
            dfu_reset();
            break;

        case BLE_DFU_START:
            m_pkt_type = PKT_TYPE_START;
            if (p_evt->evt.ble_dfu_pkt_write.len == 0)
            {
                m_update_mode = DFU_UPDATE_APP;
            }
            else
            {
                m_update_mode = (uint8_t)p_evt->evt.ble_dfu_pkt_write.p_data[0];
            }
            break;

        case BLE_DFU_RECEIVE_INIT_DATA:
            m_pkt_type = PKT_TYPE_INIT;
            break;

        case BLE_DFU_RECEIVE_APP_DATA:
            m_pkt_type = PKT_TYPE_FIRMWARE_DATA;
            break;

        case BLE_DFU_PACKET_WRITE:
            on_dfu_pkt_write(p_dfu, p_evt);
            break;

        case BLE_DFU_PKT_RCPT_NOTIF_ENABLED:
            m_pkt_rcpt_notif_enabled = true;
            m_pkt_notif_target       = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts;
            m_pkt_notif_target_cnt   = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts;
            break;

        case BLE_DFU_PKT_RCPT_NOTIF_DISABLED:
            m_pkt_rcpt_notif_enabled = false;
            m_pkt_notif_target       = 0;
            break;
        
       case BLE_DFU_BYTES_RECEIVED_SEND:
            err_code = ble_dfu_bytes_rcvd_report(p_dfu, m_num_of_firmware_bytes_rcvd);
            APP_ERROR_CHECK(err_code);
            break;

        default:
            // Unsupported event received from DFU Service. Ignore.
            break;
    }
}