// Go into flashing mode int flash_start_flashing(int enable_bl_writes,char *serial_port_name) { uint32_t state; if (enter_bootloader(serial_port_name) < 0) return -1; if (get_proxmark_state(&state) < 0) return -1; if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) { // This command is stupid. Why the heck does it care which area we're // flashing, as long as it's not the bootloader area? The mind boggles. UsbCommand c = {CMD_START_FLASH}; if (enable_bl_writes) { c.arg[0] = FLASH_START; c.arg[1] = FLASH_END; c.arg[2] = START_FLASH_MAGIC; } else { c.arg[0] = BOOTLOADER_END; c.arg[1] = FLASH_END; c.arg[2] = 0; } SendCommand(&c); return wait_for_ack(); } else { fprintf(stderr, "Note: Your bootloader does not understand the new START_FLASH command\n"); fprintf(stderr, " It is recommended that you update your bootloader\n\n"); } return 0; }
/**@brief Handle write events to the Location and Navigation Service Control Point characteristic. * * @param[in] p_dfu DFU Service structure. * @param[in] p_evt_write Write event received from the BLE stack. */ static void on_ctrlpt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t const * p_evt_write) { uint32_t err_code; ble_dfu_rsp_code_t rsp_code = DFU_RSP_OPERATION_FAILED; ble_gatts_rw_authorize_reply_params_t write_authorize_reply; memset(&write_authorize_reply, 0, sizeof(write_authorize_reply)); write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; if (p_dfu->is_ctrlpt_notification_enabled) { write_authorize_reply.params.write.update = 1; write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; } else { write_authorize_reply.params.write.gatt_status = DFU_RSP_CCCD_CONFIG_IMPROPER; } // reply to the write authorization do { err_code = sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply); } while (err_code == NRF_ERROR_BUSY); if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) { return; } // Start executing the control point write action switch (p_evt_write->data[0]) { case BLE_DFU_ENTER_BOOTLOADER: rsp_code = DFU_RSP_SUCCESS; break; // Unrecognized Op Code default: rsp_code = DFU_RSP_OP_CODE_NOT_SUPPORTED; break; } resp_send(p_dfu, (ble_dfu_buttonless_op_code_t)p_evt_write->data[0], rsp_code); if (rsp_code == BLE_DFU_ENTER_BOOTLOADER && p_evt_write->data[0] == BLE_DFU_ENTER_BOOTLOADER) { enter_bootloader(p_dfu); } }
/** Event handler for the library USB Control Request reception event. */ bool EVENT_USB_Device_ControlRequest(USB_Request_Header_t* req){ usb_cmd = 0; if ((req->bmRequestType & CONTROL_REQTYPE_TYPE) == REQTYPE_VENDOR){ switch(req->bRequest){ case 0x00: // Info if (req->wIndex == 0){ USB_ep0_send_progmem((uint8_t*)hwversion, sizeof(hwversion)); }else if (req->wIndex == 1){ USB_ep0_send_progmem((uint8_t*)fwversion, sizeof(fwversion)); } return true; case 0xA0: // read ADC readADC((IN_sample *) ep0_buf_in); USB_ep0_send(sizeof(IN_sample)); return true; case 0xAA: // write to channel A writeChannel(0, req->wIndex, req->wValue); USB_ep0_send(0); return true; case 0xAB: // write to channel B writeChannel(1, req->wIndex, req->wValue); USB_ep0_send(0); return true; case 0x65: // set gains switch (req->wIndex){ case 0x00: ADCA.CH0.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | req->wValue; // VS-A break; case 0x01: ADCA.CH1.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | req->wValue; // ADC-A break; case 0x02: ADCA.CH2.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | req->wValue; // ADC-B break; case 0x03: ADCA.CH3.CTRL = ADC_CH_INPUTMODE_DIFFWGAIN_gc | req->wValue; // VS-B break; } USB_ep0_send(0); return true; case 0x15: // ISet DACB.CH0DATA = req->wValue; DACB.CH1DATA = req->wIndex; USB_ep0_send(0); return true; case 0x80: // Configure sampling configureSampling(req->wIndex /*mode*/ , req->wValue /*period*/); USB_ep0_send(0); return true; case 0xE0: // Read EEPROM eeprom_read_block(ep0_buf_in, (void*)(req->wIndex*64), 64); USB_ep0_send(64); return true; case 0xE1: // Write EEPROM usb_cmd = req->bRequest; cmd_data = req->wIndex; USB_ep0_send(0); return true; // Wait for OUT data (expecting an OUT transfer) case 0xBB: // disconnect from USB, jump to bootloader cli(); PMIC.CTRL = 0; USB_ep0_send(0); USB_ep0_wait_for_complete(); _delay_us(10000); USB_Detach(); void (*enter_bootloader)(void) = (void *) 0x47fc /*0x8ff8/2*/; enter_bootloader(); return true; } } return false; }
static uint8_t cmd_bot(char* extra_args, char* output, uint8_t output_len, uint8_t stream) { wdt_disable(); enter_bootloader(); return 0; }