From: Gerhard Sittig Date: Sat, 9 May 2020 16:28:02 +0000 (+0200) Subject: asix-sigma: rephrase some of the FPGA command exchange X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=07411a605ed83f7a57db9d805731c0abe5893df7 asix-sigma: rephrase some of the FPGA command exchange Eliminate a few magic numbers in FPGA commands, use symbolic identifiers for automatic register address increments, and DRAM access bank selects. Improve grouping of related declarations in the header file. --- diff --git a/src/hardware/asix-sigma/protocol.c b/src/hardware/asix-sigma/protocol.c index 0e27f07a..c4012d78 100644 --- a/src/hardware/asix-sigma/protocol.c +++ b/src/hardware/asix-sigma/protocol.c @@ -134,15 +134,18 @@ static int sigma_read_register(uint8_t reg, uint8_t *data, size_t len, static int sigma_read_pos(uint32_t *stoppos, uint32_t *triggerpos, struct dev_context *devc) { + /* + * Read 6 registers starting at trigger position LSB. + * Which yields two 24bit counter values. + */ uint8_t buf[] = { REG_ADDR_LOW | READ_TRIGGER_POS_LOW, - - REG_READ_ADDR | NEXT_REG, - REG_READ_ADDR | NEXT_REG, - REG_READ_ADDR | NEXT_REG, - REG_READ_ADDR | NEXT_REG, - REG_READ_ADDR | NEXT_REG, - REG_READ_ADDR | NEXT_REG, + REG_READ_ADDR | REG_ADDR_INC, + REG_READ_ADDR | REG_ADDR_INC, + REG_READ_ADDR | REG_ADDR_INC, + REG_READ_ADDR | REG_ADDR_INC, + REG_READ_ADDR | REG_ADDR_INC, + REG_READ_ADDR | REG_ADDR_INC, }; uint8_t result[6]; @@ -172,32 +175,35 @@ static int sigma_read_pos(uint32_t *stoppos, uint32_t *triggerpos, static int sigma_read_dram(uint16_t startchunk, size_t numchunks, uint8_t *data, struct dev_context *devc) { - size_t i; uint8_t buf[4096]; int idx; + size_t chunk; + int sel; + gboolean is_last; - /* Send the startchunk. Index start with 1. */ + /* Communicate DRAM start address (memory row, aka samples line). */ idx = 0; buf[idx++] = startchunk >> 8; buf[idx++] = startchunk & 0xff; sigma_write_register(WRITE_MEMROW, buf, idx, devc); - /* Read the DRAM. */ + /* + * Access DRAM content. Fetch from DRAM to FPGA's internal RAM, + * then transfer via USB. Interleave the FPGA's DRAM access and + * USB transfer, use alternating buffers (0/1) in the process. + */ idx = 0; buf[idx++] = REG_DRAM_BLOCK; buf[idx++] = REG_DRAM_WAIT_ACK; - - for (i = 0; i < numchunks; i++) { - /* Alternate bit to copy from DRAM to cache. */ - if (i != (numchunks - 1)) - buf[idx++] = REG_DRAM_BLOCK | (((i + 1) % 2) << 4); - - buf[idx++] = REG_DRAM_BLOCK_DATA | ((i % 2) << 4); - - if (i != (numchunks - 1)) + for (chunk = 0; chunk < numchunks; chunk++) { + sel = chunk % 2; + is_last = chunk == numchunks - 1; + if (!is_last) + buf[idx++] = REG_DRAM_BLOCK | REG_DRAM_SEL_BOOL(!sel); + buf[idx++] = REG_DRAM_BLOCK_DATA | REG_DRAM_SEL_BOOL(sel); + if (!is_last) buf[idx++] = REG_DRAM_WAIT_ACK; } - sigma_write(buf, idx, devc); return sigma_read(data, numchunks * CHUNK_SIZE, devc); diff --git a/src/hardware/asix-sigma/protocol.h b/src/hardware/asix-sigma/protocol.h index a32ee15e..edace1e5 100644 --- a/src/hardware/asix-sigma/protocol.h +++ b/src/hardware/asix-sigma/protocol.h @@ -85,22 +85,34 @@ enum sigma_read_register { READ_TEST = 15, }; +/* + * FPGA commands are 8bits wide. The upper nibble is a command opcode, + * the lower nibble can carry operand values. 8bit register addresses + * and 8bit data values get communicated in two steps. + */ + +/* Register access. */ #define REG_ADDR_LOW (0x0 << 4) #define REG_ADDR_HIGH (0x1 << 4) #define REG_DATA_LOW (0x2 << 4) #define REG_DATA_HIGH_WRITE (0x3 << 4) #define REG_READ_ADDR (0x4 << 4) -#define REG_DRAM_WAIT_ACK (0x5 << 4) - -/* Bit (1 << 4) can be low or high (double buffer / cache) */ -#define REG_DRAM_BLOCK (0x6 << 4) -#define REG_DRAM_BLOCK_BEGIN (0x8 << 4) -#define REG_DRAM_BLOCK_DATA (0xa << 4) +#define REG_ADDR_ADJUST (1 << 0) /* Auto adjust register address. */ +#define REG_ADDR_DOWN (1 << 1) /* 1 decrement, 0 increment. */ +#define REG_ADDR_INC (REG_ADDR_ADJUST) +#define REG_ADDR_DEC (REG_ADDR_ADJUST | REG_ADDR_DOWN) + +/* Sample memory access. */ +#define REG_DRAM_WAIT_ACK (0x5 << 4) /* Wait for completion. */ +#define REG_DRAM_BLOCK (0x6 << 4) /* DRAM to BRAM, plus bank select. */ +#define REG_DRAM_BLOCK_BEGIN (0x8 << 4) /* Read first BRAM bytes. */ +#define REG_DRAM_BLOCK_DATA (0xa << 4) /* Read full BRAM block. */ +#define REG_DRAM_SEL_N (0x1 << 4) /* Bank select, added to 6/8/a. */ +#define REG_DRAM_SEL_BOOL(b) ((b) ? REG_DRAM_SEL_N : 0) #define LEDSEL0 6 #define LEDSEL1 7 -#define NEXT_REG 1 #define EVENTS_PER_CLUSTER 7