/* * DFU_UPLOAD response * * ------------- * |4B|TYPE | * ------------| * |2B|DATA_LEN| * ------------| * |xB|DATA | * ------------- * */ static void handle_upload_req(qda_upl_req_payload_t *req) { uint16_t max_len; uint16_t block_num; qda_pkt_t *pkt; qda_upl_rsp_payload_t *rsp; int retv; /* store request parameters in temporary variables */ block_num = req->block_num; max_len = req->max_data_len; /* prepare upload response packet */ pkt = (qda_pkt_t *)qda_buf; pkt->type = QDA_PKT_DFU_UPLOAD_RSP; rsp = (qda_upl_rsp_payload_t *)pkt->payload; retv = dfu_process_upload(block_num, max_len, rsp->data, &rsp->data_len); if (retv == 0) { xmodem_transmit_package(qda_buf, sizeof(*pkt) + sizeof(*rsp) + rsp->data_len); } else { qda_stall(); } }
/* * USB Stall response * * ------------- * |4B|TYPE | * ------------- */ static void qda_stall() { qda_pkt_t *pkt; pkt = (qda_pkt_t *)qda_buf; pkt->type = QDA_PKT_STALL; xmodem_transmit_package(qda_buf, sizeof(*pkt)); }
/* * DFU_GETSTATE response * * ----------------- * |4B|TYPE | * ----------------- * |1B|STATE | * ----------------- */ static void qda_dfu_get_state_rsp(dfu_dev_state_t state) { qda_pkt_t *pkt; qda_get_state_rsp_payload_t *rsp; pkt = (qda_pkt_t *)qda_buf; pkt->type = QDA_PKT_DFU_GETSTATE_RSP; rsp = (qda_get_state_rsp_payload_t *)pkt->payload; rsp->state = state; xmodem_transmit_package(qda_buf, sizeof(*pkt) + sizeof(*rsp)); }
/* * Reply with a USB Device Descriptor response * ----------------- * |4B|TYPE | * ----------------- * |2B|VENDOR_ID | * ----------------- * |2B|PRODUCT_ID | * ----------------- * |2B|DEVICE_BCD | * ----------------- */ static void qda_dev_dsc_rsp() { qda_pkt_t *pkt; qda_dev_dsc_rsp_payload_t *rsp; pkt = (qda_pkt_t *)qda_buf; pkt->type = QDA_PKT_DEV_DESC_RSP; rsp = (qda_dev_dsc_rsp_payload_t *)pkt->payload; rsp->id_vendor = DFU_CFG_VID; rsp->id_product = DFU_CFG_PID_DFU; rsp->bcd_device = DFU_CFG_DEV_BCD; xmodem_transmit_package(qda_buf, sizeof(*pkt) + sizeof(*rsp)); }
/* * Reply with a DFU Descriptors response * * ---------------------- * |4B|TYPE | * ---------------------- * |1B|NUM_ALT_SETTINGS | * ---------------------- * |1B|DFU_ATTRIBUTES | * ---------------------- * |2B|DETACH_TIMEOUT | * ---------------------- * |2B|MAX BLOCK SIZE | * ---------------------- * |2B|DFU_VERSION | * ---------------------- */ static void qda_dfu_dsc_rsp() { qda_pkt_t *pkt; qda_dfu_dsc_rsp_payload_t *rsp; pkt = (qda_pkt_t *)qda_buf; pkt->type = QDA_PKT_DFU_DESC_RSP; rsp = (qda_dfu_dsc_rsp_payload_t *)pkt->payload; rsp->num_alt_settings = DFU_CFG_NUM_ALT_SETTINGS; rsp->bm_attributes = DFU_CFG_DFU_ATTRIBUTES; rsp->detach_timeout = DFU_CFG_DETACH_TIMEOUT; rsp->transfer_size = DFU_CFG_MAX_BLOCK_SIZE; rsp->bcd_dfu_ver = DFU_CFG_DFU_VERSION_BCD; xmodem_transmit_package(qda_buf, sizeof(*pkt) + sizeof(*rsp)); }
/* * DFU_GETSTATUS response * * ----------------- * |4B|TYPE | * ----------------| * |1B|STATUS | * ----------------| * |3B|POLL_TIMEOUT| * ----------------- * |1B|STATE | * ----------------- * */ static void qda_dfu_get_status_rsp(dfu_dev_state_t state, dfu_dev_status_t status, uint32_t poll_timeout) { qda_pkt_t *pkt; qda_get_status_rsp_payload_t *rsp; pkt = (qda_pkt_t *)qda_buf; pkt->type = QDA_PKT_DFU_GETSTATUS_RSP; rsp = (qda_get_status_rsp_payload_t *)pkt->payload; rsp->status = status; rsp->poll_timeout = poll_timeout; rsp->state = state; xmodem_transmit_package(qda_buf, sizeof(*pkt) + sizeof(*rsp)); }
/* called from QDA */ int dfu_util_qda_send(uint8_t *data, size_t len) { printd("QDA send: (%d)\n", len); return xmodem_transmit_package(data, len); }