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.
This commit is contained in:
Gerhard Sittig 2020-05-09 18:28:02 +02:00
parent 9fb4c6324d
commit 07411a605e
2 changed files with 44 additions and 26 deletions

View File

@ -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);

View File

@ -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)
#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)
/* 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)
/* 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