digital radiography detector used with the Optima XR200/220 AMX mobile X-ray
system, with the goal of freeing these detectors for independent use.
[[File:Xray capture pcb.png|thumb|Xray capture of a PCB for Reverse Engineeringusing a different detector]]
Large numbers of these detectors reach the used market, but each one is
cryptographically and administratively bound to its original Optima 220 AMX
*Clinics and hospitals in countries and regions where a complete commercial system is unaffordable, allowing serviceable detectors to keep providing diagnostic imaging instead of being scrapped.
[[File:Xray current clamp multimeter.png|thumb|xray of a current clamp multimeterusing a different detector]]
This is done for human good. Every detector returned to service is one less
piece of working medical hardware sent to landfill, and potentially one more
== Teardown / Internal Pictures / Hardware analysis ==
<gallery mode="packed" heights="200">
File:Ge flashpad bottom connector ethernet isolation pcb.jpg|Isolation PCB for bottom connector
File:Ge flashpad main pcb powersupply section.jpg|Powersupply section for FPGA and ROIC
File:Ge_flashpad_main_pcb_closeup_3Ge flashpad main pcb closeup 3.jpg|AD9764AR 14-Bit, 125 MSPS DAC and DS1682 integrated elapsed-time recorder
File:Ge flashpad main pcb closeup 4.jpg|Accelerometer is a 834-0500 500G 3 Axis unit, and TJ500AE SPDT gigabit LAN switch
File:Ge flashpad bottom connector.jpg|bottom connector for docking stand
== Main test py script: Usage and Parameters ==
current iteration found here: https://pastebin.com/vEfAresk
registration (pairing) write. It requires only the Python standard library.
=== Default network configuration ===
These defaults match the values in ConnectionPoint.cfg and can be overridden on
{| class="wikitable"
! Setting !! Default !! Meaning
|-
| Detector IP || 192.168.1.30 || the panel; listens for all commands on UDP 8100
|-
| Host IP || 192.168.1.1 || this machine, announced in SYSTEM_STARTUP
|-
| Detector port || 8100 || where commands are sent
|-
| Host command port || 5550 || where the detector returns protocol replies
|-
| Host image port || 6660 || where pixel data would stream
|-
| Discovery port || 4500 || where the detector sends its beacons
|}
=== Connection and general options ===
{| class="wikitable"
! Option !! Default !! Effect
|-
| --detector-ip IP || 192.168.1.30 || detector address
|-
| --host-ip IP || 192.168.1.1 || host address sent in SYSTEM_STARTUP
|-
| --output-dir DIR || . || where raw images are written
|-
| --timeout SECONDS || 5.0 || UDP receive timeout
|-
| --exec-timeout SECONDS || 60 || how long to wait for EXECUTION_COMPLETE
|-
| --skip-discovery || off || send SYSTEM_STARTUP once and proceed, skipping the discovery loop
|-
| --quiet || off || suppress the verbose per packet log
|}
=== Read and diagnostic modes (non destructive) ===
These only read from the detector. None of them write anything.
{| class="wikitable"
! Option !! What it does !! What to expect
|-
| --sensors || Reads the full 32 entry sensor table using cmd 0x7902 (converted) and 0x7900 (raw), side by side. || A decoded table of supply rails in volts. Temperatures show as railed. Unimplemented sensors (accelerometer DEM id, battery, grid) are flagged as stale.
|-
| --no-roe-init || With --sensors, skips the Script7 ROE init before reading. || Slightly faster sensor read, marginally less reliable.
|-
| --probe-data || Reads DetectorInfo, the HostList (registration state), and cal results via the upload protocol (cmd 0x13/0x14). || A hexdump and text decode of each. Shows whether any host is registered and which HostId the detector expects.
|-
| --backup [DIR] || Sweeps all upload IDs 0x00 to 0xFF and saves every readable blob to DIR/detector_backup_timestamp/. || A manifest plus one .bin per readable ID, including the full 64 MB flash image and the calibration maps. Do this before any write. Large blobs take a few minutes each.
|-
| --backup-range LO-HI || Limits the --backup sweep, for example 0x40-0xA0. || Faster, partial backup.
|-
| --dump-scripts || Prints the wire bytes of all built scripts as hex and exits. || No network activity; useful for inspecting the script encoding.
|-
| --listen || Passively listens on the host command port for 30 seconds. || Prints any packets the detector sends; useful for watching beacons.
|}
=== Acquisition modes ===
The default invocation (no mode flag) runs a standard acquisition, which
{| class="wikitable"
! Option !! What it does !! What to expect
|-
| (no flag) || Standard acquisition (Script 0). || Needs an X-ray exposure to reach EXECUTION_COMPLETE.
|-
| --dark || Runs the dark/offset acquisition (Script 1) before the standard one. || Two acquisitions; the dark one needs no X-ray.
|-
| --dark-only || Runs only the dark acquisition (Script 1). || Completes in a few seconds with no X-ray. The detector acquires and holds an 8 buffer image. Best way to test the full flow.
|-
| --no-standby || Omits the Script 8 standby loop. || Use if the standby loop blocks acquisition.
|-
| --two-exec || Executes Script 7 alone, waits, then Script 1. Only with --dark-only. || Tests the two stage execution hypothesis.
|-
| --parallel || Answers the detector status query (0x30000) with the cmd 0x99 ParallelImageTransfer reply instead of cmd 9. || Experiment to see if the parallel reply triggers a pixel push. (Result so far: it does not.)
|-
| --sweep-acq || Sweeps the dark acquisition across type_mode and transfer_mode values, watching for a 0x0F pixel push. || Non destructive experiment; reports which combination, if any, makes the detector stream.
|-
| --preview || Single dark acquisition on the preview path (transfer_mode 2, 4 buffer image). Watches port 6660 for a push. || One clean connection; run a packet capture on the detector address in parallel.
|}
but image streaming is still being investigated.
=== Registration and write operations ===
These can write to the detector's flash. Every write is a dry run by default and
{| class="wikitable"
! Option !! What it does
|-
| --register-self || Adds this host to the detector HostList and sets it as the primary host, so the detector should stream images to it. Appends an entry, sets IndexToPrimaryHost, recomputes the CRC, and writes via id 0x71. Dry run unless --commit.
|-
| --host-mac MAC || The MAC of the interface talking to the detector, used to derive this host's HostId for --register-self. Default 00:6f:00:01:0a:3a.
|-
| --smoke-test-write || Reads the HostList and writes back the identical bytes to validate the write and commit path without changing anything. Dry run unless --commit.
|-
| --restore-hostlist FILE || Writes a saved HostList blob (for example detector_backup_*/upload_0x71_504.bin) back to the detector. This is the undo button. Dry run unless --commit.
|-
| --commit || Arms the actual flash write for the operations above. Without it they only print what they would do. This writes the detector's flash and is irreversible at the chip level, although the HostList region can be restored from a backup.
|}
=== Typical workflow === # Read the current state: <code>python flashpad_acquire.py --probe-data</code># Make a full backup: <code>python flashpad_acquire.py --backup</code># Check sensors and power rails: <code>python flashpad_acquire.py --sensors</code># Dry run the registration: <code>python flashpad_acquire.py --register-self --host-mac YOUR:MAC</code># When satisfied, commit it: add <code>--commit</code># If needed, undo: <code>python flashpad_acquire.py --restore-hostlist detector_backup_*/upload_0x71_504.bin --commit</code>
#Read the current state: <code>python flashpad_acquire.py --probe-data</code>
#Make a full backup: <code>python flashpad_acquire.py --backup</code>
#Check sensors and power rails: <code>python flashpad_acquire.py --sensors</code>
#Dry run the registration: <code>python flashpad_acquire.py --register-self --host-mac YOUR:MAC</code>
#When satisfied, commit it: add <code>--commit</code>
#If needed, undo: <code>python flashpad_acquire.py --restore-hostlist detector_backup_*/upload_0x71_504.bin --commit</code>
== Known Dead Ends ==
Things that were tried and did not work or led nowhere: