// STRIX raw capture tool: boots the STRIX FPGA image and gives the host (tools/jitter.py) // register access and raw captures over USB serial. For characterization only; the device // firmware is arduino/strix. // // Commands (one per line, numbers in decimal): // id print the FPGA identification // r read a register, prints its value // w write a register, prints "OK" // cap start a capture with the current settings and send it as // "DATA \n" followed by n raw bytes // stats print the latest statistics trial snapshot as hex // amp print the latest bias amplifier trial snapshot as hex #include using namespace strix; const size_t CHUNK_BYTES = 512; StrixFPGA fpga; void printId() { char id[5] = {0}; for (uint8_t i = 0; i < 4; i++) id[i] = fpga.read(REG_ID0 + i); Serial.print(id); Serial.print(" v"); Serial.println(fpga.read(REG_VERSION)); } void capture() { fpga.write(REG_CONTROL, CONTROL_START_CAPTURE); // 262,144 samples at 120 MHz take up to 143 s at the maximum decimation of 65535. unsigned long start = millis(); while (!(fpga.read(REG_STATUS) & STATUS_CAPTURE_DONE)) { if (millis() - start > 180000) { Serial.println("ERR timeout"); return; } } Serial.print("DATA "); Serial.println(CAPTURE_BYTES); static uint8_t chunk[CHUNK_BYTES]; for (size_t sent = 0; sent < CAPTURE_BYTES; sent += CHUNK_BYTES) { fpga.readBurst(REG_DATA, chunk, CHUNK_BYTES); Serial.write(chunk, CHUNK_BYTES); } } void printSnapshot(uint8_t reg, size_t length) { uint8_t snapshot[STATS_SNAPSHOT_BYTES]; fpga.readBurst(reg, snapshot, length); for (size_t i = 0; i < length; i++) { if (snapshot[i] < 0x10) Serial.print('0'); Serial.print(snapshot[i], HEX); } Serial.println(); } // Parses "" or " " after the command word; returns the number of values found. int parseArgs(const String &args, long &a, long &b) { int space = args.indexOf(' '); if (args.length() == 0) return 0; a = args.substring(0, space < 0 ? args.length() : space).toInt(); if (space < 0) return 1; b = args.substring(space + 1).toInt(); return 2; } void handleCommand(String line) { line.trim(); int space = line.indexOf(' '); String command = space < 0 ? line : line.substring(0, space); String args = space < 0 ? "" : line.substring(space + 1); long reg = 0, value = 0; int count = parseArgs(args, reg, value); if (command == "id") { printId(); } else if (command == "r" && count == 1 && reg >= 0 && reg < 0x80) { Serial.println(fpga.read(reg)); } else if (command == "w" && count == 2 && reg >= 0 && reg < 0x80 && value >= 0 && value < 256) { fpga.write(reg, value); Serial.println("OK"); } else if (command == "cap") { capture(); } else if (command == "stats") { printSnapshot(REG_STATS, STATS_SNAPSHOT_BYTES); } else if (command == "amp") { printSnapshot(REG_AMP, AMP_SNAPSHOT_BYTES); } else if (line.length() > 0) { Serial.println("ERR unknown or malformed command"); } } void setup() { Serial.begin(115200); while (!Serial); if (!fpga.begin()) { Serial.println("ERR FPGA boot failed"); } printId(); } void loop() { if (Serial.available()) handleCommand(Serial.readStringUntil('\n')); }