Kingst LA2016/Protocol
Developer notes on internal Kingst LA2016 firmware operation
Developer note: These are details which were observed during protocol research, yet are considered "too deep" for the device page (which users will read to some degree), and neither fit the Info page (which is USB centric, lsusb level, not so much USB requests during firmware operation).
Observations of the LA2016 Internal SPI Bus
The software on the host PC controls the logic analyser capture settings by writing to a set of byte-wide control registers within the FPGA.
It contains around 60 registers which are accessed using the SPI bus between the FX2 MCU and the FPGA (see schematic on sigrok wiki page).
The SPI bus is configured with the FX2 as master and FPGA as slave. Every SPI transaction is two bytes and is framed by SPI CS (active low).
The first byte contains the register address and a READ/write bit. The second byte contains the data, which is either written to the
FPGA or read from it. Note that these transactions are all least significant bit first on the SPI bus, so your LA will need to
reverse the bit order to interpret correctly.
Capture status can be read from register address 0x00 and 0x01. After a capture has completed, information about the data location in SDRAM can
be read from addresses 0x10-0x1B. For other registers, reading is not implemented and they just read as 0xFF. Where reading is implemented, the
same address is used to access different registers based on read/write. For example, FPGA status is read from address 0x00 and 0x01 but writing 0x03
to address 0x00 starts an acquistion.
The FX2 MCU is simply acting as a 'dumb' gateway, translating USB requests for FPGA access into SPI bus requests. USB control OUT vendor class
transfers with bRequest of 0x20 will write to the FPGA registers, whereas IN transfers will read them. For example, a USB request to read two
bytes starting from address 0x00 would cause the FX2 to issue a SPI read for address 0x00 and then a read for address 0x01.
SPI bus activity during OEM software initialisation
First byte is FPGA register address. The MSbit is set for READ transfers. | | Second byte is data being written or read | | | | 80 FF <-- Read RUN STATUS 81 FF 80 FF <-- Read RUN STATUS 81 FF 68 3F <-- Write SET INPUT THRESHOLD 69 02 6A F2 6B 00 02 00 <-- Halt USER PWM outputs to begin settings change 70 40 <-- USER PWM1 SETTINGS 71 0D 72 03 73 00 74 A0 75 86 76 01 77 00 78 D0 <-- USER PWM2 SETTINGS 79 07 7A 00 7B 00 7C E8 7D 03 7E 00 7F 00 02 03 <-- enable USER PWM outputs
SPI bus activity during capture sequence
OEM software with no triggers set does this to FPGA regs:
First byte is FPGA register address. The MSbit is set for READ transfers. | | Second byte is data being written or read | | | | 03 00 <-- Set capture mode to be "write to SDRAM", rather than stream mode (where reg 03 = 01) TRIGGER SETUP 20 FF <-- enable all 16 channels (change on any channel will cause new repetition packet) 21 FF 22 00 <-- no triggers active 23 00 24 00 25 00 26 00 27 00 28 00 29 00 2A 00 2B 00 2C 00 2D 00 2E 00 2F 00 SAMPLING SETUP 10 40 <-- 32 bit total samples count request 11 42 12 0F 13 00 14 00 <-- always zero 15 00 <-- 32 bit pre-trigger samples 16 00 17 00 18 00 19 00 <- always zero 1A 00 <--| 1B 00 <--These 3 bytes are pre_trigger_mem_bytes, see set_sample_config() 1C 04 <--| 1D C8 <-- Capture rate 1D is divisor LSbyte 200MHz / divisor - sample rate 1E 00 <-- 1E is divisor MSbyte 1F 00 00 03 <--- RUN now running the capture 80 E2 Reading capture status every 100ms or so from register address 0x00 and 0x01 81 85 The run_state values in order are: 0x85E2: Pre-sampling (for samples before trigger position, e.g. half of samples when set at 50% capture ratio) 0x85EA: Waiting for trigger 0x85EE: Running 0x85ED: Done 80 EE 81 85 80 EE 81 85 80 ED 81 85 Read 12 bytes from the FPGA registers starting at address 0x10 FPGA_REG_CTRL_BULK to get: 32bit n_rep_packets 32bit n_rep_packets_before_trigger 32bit write_pos 90 xx 91 xx 92 xx 93 xx 94 xx see capture_info() driver function 95 xx 96 xx xx == value depends on capture data 97 xx 98 xx 99 xx 9A xx 9B xx FPGA_REG_UPLOAD Write two 32 bit numbers, SDRAM start address and n bytes for bulk upload 08 00 09 00 0A 00 0B 00 values written are derived from the above info on capture data 0C 20 0D A9 0E 61 0F 00 01 01 Write to start the transfer of capture data from SDRAM to FX2 fifos (issued by FX2 when it receives USB command 0x38 START BULK TRANSFER) 3ms gap 00 00 HALT capture engine