From: Marek V. <ma...@de...> - 2014-04-22 16:06:34
|
This patchset fixes support for ASIX Sigma2 in libsigrok and cleans up the code. The code was rather convoluted mess. This patchset also adjusts parts of the code to follow naming from the ASIX Sigma programmers manual. Bert Vermeulen (1): asix-sigma: Acquisition fixes. Marek Vasut (27): asix-sigma: Document sampling rate table asix-sigma: Remove NUM_CHANNELS macro asix-sigma: Cleanup FPGA initialization asix-sigma: Fix firmware path construction asix-sigma: Weed out in-condition assignments asix-sigma: Cleanup the bit2bitbang asix-sigma: Move the sigma_fw_2_bitbang() asix-sigma: Squash yoda-condition in upload_firmware() asix-sigma: Pull out the logic-mode switching asix-sigma: Encode the opcodes as hex values asix-sigma: Decrypt the LA mode switch sequence asix-sigma: Read position only in CAPTURE state asix-sigma: Pull out the CAPTURE mode handler asix-sigma: Clearly separate the sample download asix-sigma: Move all register I/O into download_capture() asix-sigma: Localize variables asix-sigma: Remove stack-based alloc in download_capture() asix-sigma: Rework download_capture() to support more than 32 lines asix-sigma: Unify calling of decode_chunk_ts() asix-sigma: Introduce function to read DRAM cluster timestamp asix-sigma: Use proper structure for DRAM lines asix-sigma: Properly fetch timestamp in decode_chunk_ts() asix-sigma: Suspend support for trailing DRAM lines asix-sigma: Rework decode_chunk_ts() asix-sigma: Exterminate passing lastts and lastsample asix-sigma: Pull out cluster decoding asix-sigma: Fix the trigger handling hardware/asix-sigma/asix-sigma.c | 864 ++++++++++++++++++++++----------------- hardware/asix-sigma/asix-sigma.h | 42 +- 2 files changed, 519 insertions(+), 387 deletions(-) -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:33
|
Rework the bit2bitbang function. Remarkable changes are: - The function was renamed to sigma_fw_2_bitbang() - We use glib function calls to work with the file - We mmap the file containing firmware instead of opening the file and then reading it into a buffer. - The magic firmware transformation is now type-safe. - Documentation and comments were added where applicable. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 131 ++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 70 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 931dfae..3883bc8 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -299,85 +299,76 @@ static int sigma_write_trigger_lut(struct triggerlut *lut, struct dev_context *d return SR_OK; } -/* Generate the bitbang stream for programming the FPGA. */ -static int bin2bitbang(const char *filename, - unsigned char **buf, size_t *buf_size) +/* + * Read the firmware from a file and transform it into a series of bitbang + * pulses used to program the FPGA. Note that the *bb_cmd must be free()'d + * by the caller of this function. + */ +static int sigma_fw_2_bitbang(const char *filename, + uint8_t **bb_cmd, gsize *bb_cmd_size) { - FILE *f; - unsigned long file_size; - unsigned long offset = 0; - unsigned char *p; - uint8_t *firmware; - unsigned long fwsize = 0; - const int buffer_size = 65536; - size_t i; - int c, bit, v; - uint32_t imm = 0x3f6df2ab; - - f = g_fopen(filename, "rb"); - if (!f) { - sr_err("g_fopen(\"%s\", \"rb\")", filename); - return SR_ERR; - } - - if (-1 == fseek(f, 0, SEEK_END)) { - sr_err("fseek on %s failed", filename); - fclose(f); - return SR_ERR; - } - - file_size = ftell(f); - - fseek(f, 0, SEEK_SET); - - if (!(firmware = g_try_malloc(buffer_size))) { - sr_err("%s: firmware malloc failed", __func__); - fclose(f); - return SR_ERR_MALLOC; - } - - while ((c = getc(f)) != EOF) { + GMappedFile *file; + GError *error; + gsize i, file_size, bb_size; + gchar *firmware; + uint8_t *bb_stream, *bbs; + uint32_t imm; + int bit, v; + int ret = SR_OK; + + /* + * Map the file and make the mapped buffer writable. + * NOTE: Using writable=TRUE does _NOT_ mean that file that is mapped + * will be modified. It will not be modified until someone uses + * g_file_set_contents() on it. + */ + error = NULL; + file = g_mapped_file_new(filename, TRUE, &error); + g_assert_no_error(error); + + file_size = g_mapped_file_get_length(file); + firmware = g_mapped_file_get_contents(file); + g_assert(firmware); + + /* Weird magic transformation below, I have no idea what it does. */ + imm = 0x3f6df2ab; + for (i = 0; i < file_size; i++) { imm = (imm + 0xa853753) % 177 + (imm * 0x8034052); - firmware[fwsize++] = c ^ imm; - } - fclose(f); - - if(fwsize != file_size) { - sr_err("%s: Error reading firmware", filename); - fclose(f); - g_free(firmware); - return SR_ERR; + firmware[i] ^= imm & 0xff; } - *buf_size = fwsize * 2 * 8; - - *buf = p = (unsigned char *)g_try_malloc(*buf_size); - if (!p) { - sr_err("%s: buf/p malloc failed", __func__); - g_free(firmware); - return SR_ERR_MALLOC; + /* + * Now that the firmware is "transformed", we will transcribe the + * firmware blob into a sequence of toggles of the Dx wires. This + * sequence will be fed directly into the Sigma, which must be in + * the FPGA bitbang programming mode. + */ + + /* Each bit of firmware is transcribed as two toggles of Dx wires. */ + bb_size = file_size * 8 * 2; + bb_stream = (uint8_t *)g_try_malloc(bb_size); + if (!bb_stream) { + sr_err("%s: Failed to allocate bitbang stream", __func__); + ret = SR_ERR_MALLOC; + goto exit; } - for (i = 0; i < fwsize; ++i) { - for (bit = 7; bit >= 0; --bit) { - v = firmware[i] & 1 << bit ? 0x40 : 0x00; - p[offset++] = v | 0x01; - p[offset++] = v; + bbs = bb_stream; + for (i = 0; i < file_size; i++) { + for (bit = 7; bit >= 0; bit--) { + v = (firmware[i] & (1 << bit)) ? 0x40 : 0x00; + *bbs++ = v | 0x01; + *bbs++ = v; } } - g_free(firmware); - - if (offset != *buf_size) { - g_free(*buf); - sr_err("Error reading firmware %s " - "offset=%ld, file_size=%ld, buf_size=%zd.", - filename, offset, file_size, *buf_size); + /* The transformation completed successfully, return the result. */ + *bb_cmd = bb_stream; + *bb_cmd_size = bb_size; - return SR_ERR; - } - - return SR_OK; +exit: + g_mapped_file_unref(file); + return ret; } static void clear_helper(void *priv) @@ -575,7 +566,7 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) return ret; /* Prepare firmware. */ - ret = bin2bitbang(firmware, &buf, &buf_size); + ret = sigma_fw_2_bitbang(firmware, &buf, &buf_size); if (ret != SR_OK) { sr_err("An error occured while reading the firmware: %s", firmware); -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:34
|
Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 2cd9b9e..8e79403 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -589,7 +589,7 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) ftdi_usb_purge_buffers(ftdic); /* Discard garbage. */ - while (1 == sigma_read(&pins, 1, devc)) + while (sigma_read(&pins, 1, devc) == 1) ; /* Initialize the logic analyzer mode. */ -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:35
|
Pull out the code which switches Sigma from the FPGA programming mode into Logic-Analyzer mode into separate function. Also, given the reply is only ever 3-byte long, do not allocate 32 byte big buffer, but only a 3-byte long one. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 52 +++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 8e79403..06373d6 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -80,12 +80,6 @@ static const int32_t hwcaps[] = { SR_CONF_LIMIT_SAMPLES, }; -/* Initialize the logic analyzer mode. */ -static uint8_t logic_mode_start[] = { - 0x00, 0x40, 0x0f, 0x25, 0x35, 0x40, - 0x2a, 0x3a, 0x40, 0x03, 0x20, 0x38, -}; - static const char *sigma_firmware_files[] = { /* 50 MHz, supports 8 bit fractions */ FIRMWARE_DIR "/asix-sigma-50.fw", @@ -455,6 +449,37 @@ static int sigma_fpga_init_bitbang(struct dev_context *devc) } /* + * Configure the FPGA for logic-analyzer mode. + */ +static int sigma_fpga_init_la(struct dev_context *devc) +{ + /* Initialize the logic analyzer mode. */ + uint8_t logic_mode_start[] = { + 0x00, 0x40, 0x0f, 0x25, 0x35, 0x40, + 0x2a, 0x3a, 0x40, 0x03, 0x20, 0x38, + }; + + uint8_t result[3]; + int ret; + + /* Initialize the logic analyzer mode. */ + sigma_write(logic_mode_start, sizeof(logic_mode_start), devc); + + /* Expect a 3 byte reply. */ + ret = sigma_read(result, 3, devc); + if (ret != 3) + goto err; + + if (result[0] != 0xa6 || result[1] != 0x55 || result[2] != 0xaa) + goto err; + + return SR_OK; +err: + sr_err("Configuration failed. Invalid reply received."); + return SR_ERR; +} + +/* * Read the firmware from a file and transform it into a series of bitbang * pulses used to program the FPGA. Note that the *bb_cmd must be free()'d * by the caller of this function. @@ -532,7 +557,6 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) unsigned char *buf; unsigned char pins; size_t buf_size; - unsigned char result[32]; const char *firmware = sigma_firmware_files[firmware_idx]; struct ftdi_context *ftdic = &devc->ftdic; @@ -592,16 +616,10 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) while (sigma_read(&pins, 1, devc) == 1) ; - /* Initialize the logic analyzer mode. */ - sigma_write(logic_mode_start, sizeof(logic_mode_start), devc); - - /* Expect a 3 byte reply. */ - ret = sigma_read(result, 3, devc); - if (ret != 3 || - result[0] != 0xa6 || result[1] != 0x55 || result[2] != 0xaa) { - sr_err("Configuration failed. Invalid reply received."); - return SR_ERR; - } + /* Initialize the FPGA for logic-analyzer mode. */ + ret = sigma_fpga_init_la(devc); + if (ret != SR_OK) + return ret; devc->cur_firmware = firmware_idx; -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:33
|
From: Bert Vermeulen <be...@bi...> --- hardware/asix-sigma/asix-sigma.c | 183 ++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 87 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index dbd4ddf..1c8e04b 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -73,6 +73,7 @@ static const int32_t hwcaps[] = { SR_CONF_TRIGGER_TYPE, SR_CONF_CAPTURE_RATIO, SR_CONF_LIMIT_MSEC, + SR_CONF_LIMIT_SAMPLES, }; /* Force the FPGA to reboot. */ @@ -770,6 +771,7 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { struct dev_context *devc; + uint64_t num_samples; int ret; (void)cg; @@ -779,21 +781,29 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi, devc = sdi->priv; - if (id == SR_CONF_SAMPLERATE) { + switch (id) { + case SR_CONF_SAMPLERATE: ret = set_samplerate(sdi, g_variant_get_uint64(data)); - } else if (id == SR_CONF_LIMIT_MSEC) { + break; + case SR_CONF_LIMIT_MSEC: devc->limit_msec = g_variant_get_uint64(data); if (devc->limit_msec > 0) ret = SR_OK; else ret = SR_ERR; - } else if (id == SR_CONF_CAPTURE_RATIO) { + break; + case SR_CONF_LIMIT_SAMPLES: + num_samples = g_variant_get_uint64(data); + devc->limit_msec = num_samples * 1000 / devc->cur_samplerate; + break; + case SR_CONF_CAPTURE_RATIO: devc->capture_ratio = g_variant_get_uint64(data); if (devc->capture_ratio < 0 || devc->capture_ratio > 100) ret = SR_ERR; else ret = SR_OK; - } else { + break; + default: ret = SR_ERR_NA; } @@ -1002,93 +1012,115 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts, return SR_OK; } -static int receive_data(int fd, int revents, void *cb_data) +static void download_capture(struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi = cb_data; - struct dev_context *devc = sdi->priv; - struct sr_datafeed_packet packet; + struct dev_context *devc; const int chunks_per_read = 32; unsigned char buf[chunks_per_read * CHUNK_SIZE]; - int bufsz, numchunks, i, newchunks; + int bufsz, i, numchunks, newchunks; + + sr_info("Downloading sample data."); + + devc = sdi->priv; + devc->state.chunks_downloaded = 0; + numchunks = (devc->state.stoppos + 511) / 512; + newchunks = MIN(chunks_per_read, numchunks - devc->state.chunks_downloaded); + + bufsz = sigma_read_dram(devc->state.chunks_downloaded, newchunks, buf, devc); + /* TODO: Check bufsz. For now, just avoid compiler warnings. */ + (void)bufsz; + + /* Find first ts. */ + if (devc->state.chunks_downloaded == 0) { + devc->state.lastts = RL16(buf) - 1; + devc->state.lastsample = 0; + } + + /* Decode chunks and send them to sigrok. */ + for (i = 0; i < newchunks; ++i) { + int limit_chunk = 0; + + /* The last chunk may potentially be only in part. */ + if (devc->state.chunks_downloaded == numchunks - 1) { + /* Find the last valid timestamp */ + limit_chunk = devc->state.stoppos % 512 + devc->state.lastts; + } + + if (devc->state.chunks_downloaded + i == devc->state.triggerchunk) + decode_chunk_ts(buf + (i * CHUNK_SIZE), + &devc->state.lastts, + &devc->state.lastsample, + devc->state.triggerpos & 0x1ff, + limit_chunk, sdi); + else + decode_chunk_ts(buf + (i * CHUNK_SIZE), + &devc->state.lastts, + &devc->state.lastsample, + -1, limit_chunk, sdi); + + ++devc->state.chunks_downloaded; + } + +} + +static int receive_data(int fd, int revents, void *cb_data) +{ + struct sr_dev_inst *sdi; + struct dev_context *devc; + struct sr_datafeed_packet packet; uint64_t running_msec; struct timeval tv; + int numchunks; + uint8_t modestatus; (void)fd; (void)revents; + sdi = cb_data; + devc = sdi->priv; + /* Get the current position. */ sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); - numchunks = (devc->state.stoppos + 511) / 512; - if (devc->state.state == SIGMA_IDLE) return TRUE; if (devc->state.state == SIGMA_CAPTURE) { + numchunks = (devc->state.stoppos + 511) / 512; + /* Check if the timer has expired, or memory is full. */ gettimeofday(&tv, 0); running_msec = (tv.tv_sec - devc->start_tv.tv_sec) * 1000 + (tv.tv_usec - devc->start_tv.tv_usec) / 1000; if (running_msec < devc->limit_msec && numchunks < 32767) - return TRUE; /* While capturing... */ - else - dev_acquisition_stop(sdi, sdi); - - } - - if (devc->state.state == SIGMA_DOWNLOAD) { - if (devc->state.chunks_downloaded >= numchunks) { - /* End of samples. */ - packet.type = SR_DF_END; - sr_session_send(devc->cb_data, &packet); - - devc->state.state = SIGMA_IDLE; - + /* Still capturing. */ return TRUE; - } - newchunks = MIN(chunks_per_read, - numchunks - devc->state.chunks_downloaded); + /* Stop acquisition. */ + sigma_set_register(WRITE_MODE, 0x11, devc); - sr_info("Downloading sample data: %.0f %%.", - 100.0 * devc->state.chunks_downloaded / numchunks); + /* Set SDRAM Read Enable. */ + sigma_set_register(WRITE_MODE, 0x02, devc); - bufsz = sigma_read_dram(devc->state.chunks_downloaded, - newchunks, buf, devc); - /* TODO: Check bufsz. For now, just avoid compiler warnings. */ - (void)bufsz; + /* Get the current position. */ + sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); - /* Find first ts. */ - if (devc->state.chunks_downloaded == 0) { - devc->state.lastts = RL16(buf) - 1; - devc->state.lastsample = 0; - } + /* Check if trigger has fired. */ + modestatus = sigma_get_register(READ_MODE, devc); + if (modestatus & 0x20) + devc->state.triggerchunk = devc->state.triggerpos / 512; + else + devc->state.triggerchunk = -1; - /* Decode chunks and send them to sigrok. */ - for (i = 0; i < newchunks; ++i) { - int limit_chunk = 0; + /* Transfer captured data from device. */ + download_capture(sdi); - /* The last chunk may potentially be only in part. */ - if (devc->state.chunks_downloaded == numchunks - 1) { - /* Find the last valid timestamp */ - limit_chunk = devc->state.stoppos % 512 + devc->state.lastts; - } + /* All done. */ + packet.type = SR_DF_END; + sr_session_send(sdi, &packet); - if (devc->state.chunks_downloaded + i == devc->state.triggerchunk) - decode_chunk_ts(buf + (i * CHUNK_SIZE), - &devc->state.lastts, - &devc->state.lastsample, - devc->state.triggerpos & 0x1ff, - limit_chunk, sdi); - else - decode_chunk_ts(buf + (i * CHUNK_SIZE), - &devc->state.lastts, - &devc->state.lastsample, - -1, limit_chunk, sdi); - - ++devc->state.chunks_downloaded; - } + dev_acquisition_stop(sdi, sdi); } return TRUE; @@ -1364,36 +1396,13 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) { struct dev_context *devc; - uint8_t modestatus; (void)cb_data; - sr_source_remove(0); - - if (!(devc = sdi->priv)) { - sr_err("%s: sdi->priv was NULL", __func__); - return SR_ERR_BUG; - } - - /* Stop acquisition. */ - sigma_set_register(WRITE_MODE, 0x11, devc); - - /* Set SDRAM Read Enable. */ - sigma_set_register(WRITE_MODE, 0x02, devc); - - /* Get the current position. */ - sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); - - /* Check if trigger has fired. */ - modestatus = sigma_get_register(READ_MODE, devc); - if (modestatus & 0x20) - devc->state.triggerchunk = devc->state.triggerpos / 512; - else - devc->state.triggerchunk = -1; - - devc->state.chunks_downloaded = 0; + devc = sdi->priv; + devc->state.state = SIGMA_IDLE; - devc->state.state = SIGMA_DOWNLOAD; + sr_source_remove(0); return SR_OK; } -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:33
|
Rework the pre-firmware-upload FPGA initialization sequence so it matches the documentation. Also, since this sequence is documented in a separate section, wrap it into separate function. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 74 +++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 039a527..7f49dc2 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -80,16 +80,6 @@ static const int32_t hwcaps[] = { SR_CONF_LIMIT_SAMPLES, }; -/* Force the FPGA to reboot. */ -static uint8_t suicide[] = { - 0x84, 0x84, 0x88, 0x84, 0x88, 0x84, 0x88, 0x84, -}; - -/* Prepare to upload firmware (FPGA specific). */ -static uint8_t init_array[] = { - 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -}; - /* Initialize the logic analyzer mode. */ static uint8_t logic_mode_start[] = { 0x00, 0x40, 0x0f, 0x25, 0x35, 0x40, @@ -497,6 +487,49 @@ static GSList *dev_list(void) return ((struct drv_context *)(di->priv))->instances; } +/* + * Configure the FPGA for bitbang mode. + * This sequence is documented in section 2. of the ASIX Sigma programming + * manual. This sequence is necessary to configure the FPGA in the Sigma + * into Bitbang mode, in which it can be programmed with the firmware. + */ +static int sigma_fpga_init_bitbang(struct dev_context *devc) +{ + uint8_t suicide[] = { + 0x84, 0x84, 0x88, 0x84, 0x88, 0x84, 0x88, 0x84, + }; + uint8_t init_array[] = { + 0x01, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, + }; + int i, ret, timeout = 10000; + uint8_t data; + + /* Section 2. part 1), do the FPGA suicide. */ + sigma_write(suicide, sizeof(suicide), devc); + sigma_write(suicide, sizeof(suicide), devc); + sigma_write(suicide, sizeof(suicide), devc); + sigma_write(suicide, sizeof(suicide), devc); + + /* Section 2. part 2), do pulse on D1. */ + sigma_write(init_array, sizeof(init_array), devc); + ftdi_usb_purge_buffers(&devc->ftdic); + + /* Wait until the FPGA asserts D6/INIT_B. */ + for (i = 0; i < timeout; i++) { + ret = sigma_read(&data, 1, devc); + if (ret < 0) + return ret; + /* Test if pin D6 got asserted. */ + if (data & (1 << 5)) + return 0; + /* The D6 was not asserted yet, wait a bit. */ + usleep(10000); + } + + return SR_ERR_TIMEOUT; +} + static int upload_firmware(int firmware_idx, struct dev_context *devc) { int ret; @@ -527,23 +560,10 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) return 0; } - /* Force the FPGA to reboot. */ - sigma_write(suicide, sizeof(suicide), devc); - sigma_write(suicide, sizeof(suicide), devc); - sigma_write(suicide, sizeof(suicide), devc); - sigma_write(suicide, sizeof(suicide), devc); - - /* Prepare to upload firmware (FPGA specific). */ - sigma_write(init_array, sizeof(init_array), devc); - - ftdi_usb_purge_buffers(&devc->ftdic); - - /* Wait until the FPGA asserts INIT_B. */ - while (1) { - ret = sigma_read(result, 1, devc); - if (result[0] & 0x20) - break; - } + /* Initialize the FPGA for firmware upload. */ + ret = sigma_fpga_init_bitbang(devc); + if (ret) + return ret; /* Prepare firmware. */ snprintf(firmware_path, sizeof(firmware_path), "%s/%s", FIRMWARE_DIR, -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:40
|
Check the position of ForceStop and Trigger events only in case we are in CAPTURE state, it's useless to do this unconditionally when receive_data() is called. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 9860702..4d8f238 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -1136,13 +1136,14 @@ static int receive_data(int fd, int revents, void *cb_data) sdi = cb_data; devc = sdi->priv; - /* Get the current position. */ - sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); - if (devc->state.state == SIGMA_IDLE) return TRUE; if (devc->state.state == SIGMA_CAPTURE) { + /* Get the current position. */ + sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, + devc); + numchunks = (devc->state.stoppos + 511) / 512; /* Check if the timer has expired, or memory is full. */ -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:40
|
Move all the register I/O that is necessary to do the download of samples from Sigma into download_capture() function. This makes the downloading code contained a bit more again. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 66 ++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index cdc0988..734eccf 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -1069,16 +1069,34 @@ static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts, return SR_OK; } -static void download_capture(struct sr_dev_inst *sdi) +static int download_capture(struct sr_dev_inst *sdi) { - struct dev_context *devc; + struct dev_context *devc = sdi->priv; const int chunks_per_read = 32; unsigned char buf[chunks_per_read * CHUNK_SIZE]; int bufsz, i, numchunks, newchunks; + struct sr_datafeed_packet packet; + uint8_t modestatus; + sr_info("Downloading sample data."); - devc = sdi->priv; + /* Stop acquisition. */ + sigma_set_register(WRITE_MODE, 0x11, devc); + + /* Set SDRAM Read Enable. */ + sigma_set_register(WRITE_MODE, 0x02, devc); + + /* Get the current position. */ + sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); + + /* Check if trigger has fired. */ + modestatus = sigma_get_register(READ_MODE, devc); + if (modestatus & 0x20) + devc->state.triggerchunk = devc->state.triggerpos / 512; + else + devc->state.triggerchunk = -1; + devc->state.chunks_downloaded = 0; numchunks = (devc->state.stoppos + 511) / 512; newchunks = MIN(chunks_per_read, numchunks - devc->state.chunks_downloaded); @@ -1118,6 +1136,13 @@ static void download_capture(struct sr_dev_inst *sdi) ++devc->state.chunks_downloaded; } + /* All done. */ + packet.type = SR_DF_END; + sr_session_send(sdi, &packet); + + dev_acquisition_stop(sdi, sdi); + + return TRUE; } /* @@ -1131,10 +1156,8 @@ static int sigma_capture_mode(struct sr_dev_inst *sdi) { struct dev_context *devc = sdi->priv; - struct sr_datafeed_packet packet; uint64_t running_msec; struct timeval tv; - uint8_t modestatus; uint32_t stoppos, triggerpos; @@ -1143,42 +1166,13 @@ static int sigma_capture_mode(struct sr_dev_inst *sdi) running_msec = (tv.tv_sec - devc->start_tv.tv_sec) * 1000 + (tv.tv_usec - devc->start_tv.tv_usec) / 1000; if (running_msec >= devc->limit_msec) - goto download; + return download_capture(sdi); /* Get the position in DRAM to which the FPGA is writing now. */ sigma_read_pos(&stoppos, &triggerpos, devc); /* Test if DRAM is full and if so, download the data. */ if ((stoppos >> 9) == 32767) - goto download; - - return TRUE; - -download: - - /* Stop acquisition. */ - sigma_set_register(WRITE_MODE, 0x11, devc); - - /* Set SDRAM Read Enable. */ - sigma_set_register(WRITE_MODE, 0x02, devc); - - /* Get the current position. */ - sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); - - /* Check if trigger has fired. */ - modestatus = sigma_get_register(READ_MODE, devc); - if (modestatus & 0x20) - devc->state.triggerchunk = devc->state.triggerpos / 512; - else - devc->state.triggerchunk = -1; - - /* Transfer captured data from device. */ - download_capture(sdi); - - /* All done. */ - packet.type = SR_DF_END; - sr_session_send(sdi, &packet); - - dev_acquisition_stop(sdi, sdi); + return download_capture(sdi); return TRUE; } -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:41
|
Add comments to the sampling rate table explaining how the frequencies are selected and where do those numbers come from. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 1c8e04b..d17558d 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -43,17 +43,23 @@ SR_PRIV struct sr_dev_driver asix_sigma_driver_info; static struct sr_dev_driver *di = &asix_sigma_driver_info; static int dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data); +/* + * The ASIX Sigma supports arbitrary integer frequency divider in + * the 50MHz mode. The divider is in range 1...256 , allowing for + * very precise sampling rate selection. This driver supports only + * a subset of the sampling rates. + */ static const uint64_t samplerates[] = { - SR_KHZ(200), - SR_KHZ(250), - SR_KHZ(500), - SR_MHZ(1), - SR_MHZ(5), - SR_MHZ(10), - SR_MHZ(25), - SR_MHZ(50), - SR_MHZ(100), - SR_MHZ(200), + SR_KHZ(200), /* div=250 */ + SR_KHZ(250), /* div=200 */ + SR_KHZ(500), /* div=100 */ + SR_MHZ(1), /* div=50 */ + SR_MHZ(5), /* div=10 */ + SR_MHZ(10), /* div=5 */ + SR_MHZ(25), /* div=2 */ + SR_MHZ(50), /* div=1 */ + SR_MHZ(100), /* Special FW needed */ + SR_MHZ(200), /* Special FW needed */ }; /* -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:46
|
Reorder the sigma_capture_mode() function so that the part which handles the download of samples from Sigma is clearly separated from the tests if the download should be started. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index e7fa7d3..cdc0988 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -1134,23 +1134,26 @@ static int sigma_capture_mode(struct sr_dev_inst *sdi) struct sr_datafeed_packet packet; uint64_t running_msec; struct timeval tv; - int numchunks; uint8_t modestatus; - /* Get the current position. */ - sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, - devc); - - numchunks = (devc->state.stoppos + 511) / 512; + uint32_t stoppos, triggerpos; - /* Check if the timer has expired, or memory is full. */ + /* Check if the selected sampling duration passed. */ gettimeofday(&tv, 0); running_msec = (tv.tv_sec - devc->start_tv.tv_sec) * 1000 + - (tv.tv_usec - devc->start_tv.tv_usec) / 1000; + (tv.tv_usec - devc->start_tv.tv_usec) / 1000; + if (running_msec >= devc->limit_msec) + goto download; - if (running_msec < devc->limit_msec && numchunks < 32767) - /* Still capturing. */ - return TRUE; + /* Get the position in DRAM to which the FPGA is writing now. */ + sigma_read_pos(&stoppos, &triggerpos, devc); + /* Test if DRAM is full and if so, download the data. */ + if ((stoppos >> 9) == 32767) + goto download; + + return TRUE; + +download: /* Stop acquisition. */ sigma_set_register(WRITE_MODE, 0x11, devc); -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:46
|
Avoid allocating 32KiB of data on stack in download_capture(). Instead, do a glib-variant of calloc(1, ) to allocate the data for the samples which will be downloaded. This avoids explosions of stack on systems with tight stack limits. Furthermore, define structures describing the organisation of Sigma's DRAM memory and start using those instead of ad-hoc preprocessor macros defining the sizes of various structures in memory. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 11 ++++++++++- hardware/asix-sigma/asix-sigma.h | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index c44bae7..7e4b3ca 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -1073,13 +1073,20 @@ static int download_capture(struct sr_dev_inst *sdi) { struct dev_context *devc = sdi->priv; const int chunks_per_read = 32; - unsigned char buf[chunks_per_read * CHUNK_SIZE]; + struct sigma_dram_line *dram_line; + unsigned char *buf; int bufsz, i, numchunks, newchunks; uint32_t stoppos, triggerpos; int triggerchunk, chunks_downloaded; struct sr_datafeed_packet packet; uint8_t modestatus; + dram_line = g_try_malloc0(chunks_per_read * sizeof(*dram_line)); + if (!dram_line) + return FALSE; + + buf = (unsigned char *)dram_line; + sr_info("Downloading sample data."); /* Stop acquisition. */ @@ -1143,6 +1150,8 @@ static int download_capture(struct sr_dev_inst *sdi) dev_acquisition_stop(sdi, sdi); + g_free(dram_line); + return TRUE; } diff --git a/hardware/asix-sigma/asix-sigma.h b/hardware/asix-sigma/asix-sigma.h index 1933064..87c92fb 100644 --- a/hardware/asix-sigma/asix-sigma.h +++ b/hardware/asix-sigma/asix-sigma.h @@ -76,6 +76,25 @@ enum sigma_read_register { #define CHUNK_SIZE 1024 +/* + * The entire ASIX Sigma DRAM is an array of struct sigma_dram_line[1024]; + */ + +/* One "DRAM cluster" contains a timestamp and 7 samples, 16b total. */ +struct sigma_dram_cluster { + uint8_t timestamp_lo; + uint8_t timestamp_hi; + struct { + uint8_t sample_hi; + uint8_t sample_lo; + } samples[7]; +}; + +/* One "DRAM line" contains 64 "DRAM clusters", 1024b total. */ +struct sigma_dram_line { + struct sigma_dram_cluster cluster[64]; +}; + struct clockselect_50 { uint8_t async; uint8_t fraction; -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:46
|
Just encode the opcodes as hexadecimal values. This makes for better readability when mapping the communication dump with the sigma to the code. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.h b/hardware/asix-sigma/asix-sigma.h index 528e661..b8362e0 100644 --- a/hardware/asix-sigma/asix-sigma.h +++ b/hardware/asix-sigma/asix-sigma.h @@ -55,17 +55,17 @@ enum sigma_read_register { READ_TEST = 15, }; -#define REG_ADDR_LOW (0 << 4) -#define REG_ADDR_HIGH (1 << 4) -#define REG_DATA_LOW (2 << 4) -#define REG_DATA_HIGH_WRITE (3 << 4) -#define REG_READ_ADDR (4 << 4) -#define REG_DRAM_WAIT_ACK (5 << 4) +#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 (6 << 4) -#define REG_DRAM_BLOCK_BEGIN (8 << 4) -#define REG_DRAM_BLOCK_DATA (10 << 4) +#define REG_DRAM_BLOCK (0x6 << 4) +#define REG_DRAM_BLOCK_BEGIN (0x8 << 4) +#define REG_DRAM_BLOCK_DATA (0xa << 4) #define LEDSEL0 6 #define LEDSEL1 7 -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:46
|
Decode the logic mode start sequence into a series of FPGA instructions instead and get rid of this sequence of magic numbers. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 06373d6..9860702 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -455,8 +455,22 @@ static int sigma_fpga_init_la(struct dev_context *devc) { /* Initialize the logic analyzer mode. */ uint8_t logic_mode_start[] = { - 0x00, 0x40, 0x0f, 0x25, 0x35, 0x40, - 0x2a, 0x3a, 0x40, 0x03, 0x20, 0x38, + REG_ADDR_LOW | (READ_ID & 0xf), + REG_ADDR_HIGH | (READ_ID >> 8), + REG_READ_ADDR, /* Read ID register. */ + + REG_ADDR_LOW | (WRITE_TEST & 0xf), + REG_DATA_LOW | 0x5, + REG_DATA_HIGH_WRITE | 0x5, + REG_READ_ADDR, /* Read scratch register. */ + + REG_DATA_LOW | 0xa, + REG_DATA_HIGH_WRITE | 0xa, + REG_READ_ADDR, /* Read scratch register. */ + + REG_ADDR_LOW | (WRITE_MODE & 0xf), + REG_DATA_LOW | 0x0, + REG_DATA_HIGH_WRITE | 0x8, }; uint8_t result[3]; @@ -465,7 +479,7 @@ static int sigma_fpga_init_la(struct dev_context *devc) /* Initialize the logic analyzer mode. */ sigma_write(logic_mode_start, sizeof(logic_mode_start), devc); - /* Expect a 3 byte reply. */ + /* Expect a 3 byte reply since we issued three READ requests. */ ret = sigma_read(result, 3, devc); if (ret != 3) goto err; -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:48
|
The code silently assumed the firmware path can be no longer than 128 bytes. This doesn't scale. This patch fixes it in such a way that it completely rips out the run-time computation of firmware path and instead replaces it with compile-time computation. It's true this makes the library grow by a couple bytes, but makes the code cleaner. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 7f49dc2..f813edd 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -86,12 +86,17 @@ static uint8_t logic_mode_start[] = { 0x2a, 0x3a, 0x40, 0x03, 0x20, 0x38, }; -static const char *firmware_files[] = { - "asix-sigma-50.fw", /* 50 MHz, supports 8 bit fractions */ - "asix-sigma-100.fw", /* 100 MHz */ - "asix-sigma-200.fw", /* 200 MHz */ - "asix-sigma-50sync.fw", /* Synchronous clock from pin */ - "asix-sigma-phasor.fw", /* Frequency counter */ +static const char *sigma_firmware_files[] = { + /* 50 MHz, supports 8 bit fractions */ + FIRMWARE_DIR "/asix-sigma-50.fw", + /* 100 MHz */ + FIRMWARE_DIR "/asix-sigma-100.fw", + /* 200 MHz */ + FIRMWARE_DIR "/asix-sigma-200.fw", + /* Synchronous clock from pin */ + FIRMWARE_DIR "/asix-sigma-50sync.fw", + /* Frequency counter */ + FIRMWARE_DIR "/asix-sigma-phasor.fw", }; static int sigma_read(void *buf, size_t size, struct dev_context *devc) @@ -537,7 +542,7 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) unsigned char pins; size_t buf_size; unsigned char result[32]; - char firmware_path[128]; + const char *firmware = sigma_firmware_files[firmware_idx]; /* Make sure it's an ASIX SIGMA. */ if ((ret = ftdi_usb_open_desc(&devc->ftdic, @@ -566,17 +571,14 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) return ret; /* Prepare firmware. */ - snprintf(firmware_path, sizeof(firmware_path), "%s/%s", FIRMWARE_DIR, - firmware_files[firmware_idx]); - - if ((ret = bin2bitbang(firmware_path, &buf, &buf_size)) != SR_OK) { + if ((ret = bin2bitbang(firmware, &buf, &buf_size)) != SR_OK) { sr_err("An error occured while reading the firmware: %s", - firmware_path); + firmware); return ret; } /* Upload firmare. */ - sr_info("Uploading firmware file '%s'.", firmware_files[firmware_idx]); + sr_info("Uploading firmware file '%s'.", firmware); sigma_write(buf, buf_size, devc); g_free(buf); -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:48
|
In the current configuration, the download capture used 32KiB buffer for samples. This was the upper limit this function could download from the Sigma. Even the sigma_read_dram() was only called once to read up-to 32 DRAM line from address 0x0 in the DRAM. This patch reworks the function to call sigma_read_dram() in a loop in case there is need to download more than 32 DRAM lines of data from Sigma. The data are then correctly passed for decoding to the decoding function. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 80 +++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 7e4b3ca..a4d6076 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -1075,12 +1075,16 @@ static int download_capture(struct sr_dev_inst *sdi) const int chunks_per_read = 32; struct sigma_dram_line *dram_line; unsigned char *buf; - int bufsz, i, numchunks, newchunks; + int bufsz; uint32_t stoppos, triggerpos; - int triggerchunk, chunks_downloaded; struct sr_datafeed_packet packet; uint8_t modestatus; + uint32_t i; + uint32_t dl_lines_total, dl_lines_curr, dl_lines_done; + uint32_t dl_trailing_events; + uint32_t trg_line; + dram_line = g_try_malloc0(chunks_per_read * sizeof(*dram_line)); if (!dram_line) return FALSE; @@ -1101,47 +1105,55 @@ static int download_capture(struct sr_dev_inst *sdi) /* Check if trigger has fired. */ modestatus = sigma_get_register(READ_MODE, devc); if (modestatus & 0x20) - triggerchunk = triggerpos / 512; + trg_line = triggerpos >> 9; else - triggerchunk = -1; + trg_line = ~0; - chunks_downloaded = 0; - numchunks = (stoppos + 511) / 512; - newchunks = MIN(chunks_per_read, numchunks - chunks_downloaded); + /* + * Determine how many 1024b "DRAM lines" do we need to read from the + * Sigma so we have a complete set of samples. Note that the last + * line can be only partial, containing less than 64 clusters. + */ + dl_lines_total = (stoppos >> 9) + 1; + dl_trailing_events = stoppos & 0x1ff; - bufsz = sigma_read_dram(chunks_downloaded, newchunks, buf, devc); - /* TODO: Check bufsz. For now, just avoid compiler warnings. */ - (void)bufsz; + dl_lines_done = 0; - /* Find first ts. */ - if (chunks_downloaded == 0) { - devc->state.lastts = RL16(buf) - 1; - devc->state.lastsample = 0; - } + while (dl_lines_total > dl_lines_done) { + /* We can download only up-to 32 DRAM lines in one go! */ + dl_lines_curr = MIN(chunks_per_read, dl_lines_total); - /* Decode chunks and send them to sigrok. */ - for (i = 0; i < newchunks; ++i) { - int limit_chunk = 0; + bufsz = sigma_read_dram(dl_lines_done, dl_lines_curr, buf, devc); + /* TODO: Check bufsz. For now, just avoid compiler warnings. */ + (void)bufsz; - /* The last chunk may potentially be only in part. */ - if (chunks_downloaded == numchunks - 1) { - /* Find the last valid timestamp */ - limit_chunk = stoppos % 512 + devc->state.lastts; + /* This is the first DRAM line, so find the initial timestamp. */ + if (dl_lines_done == 0) { + devc->state.lastts = RL16(buf) - 1; + devc->state.lastsample = 0; } - if (chunks_downloaded + i == triggerchunk) - decode_chunk_ts(buf + (i * CHUNK_SIZE), - &devc->state.lastts, - &devc->state.lastsample, - triggerpos & 0x1ff, - limit_chunk, sdi); - else - decode_chunk_ts(buf + (i * CHUNK_SIZE), - &devc->state.lastts, - &devc->state.lastsample, - -1, limit_chunk, sdi); + for (i = 0; i < dl_lines_curr; i++) { + uint32_t dl_limit = 0; + /* The last "DRAM line" can be only partially full. */ + if (dl_lines_done + i == dl_lines_total - 1) + dl_limit = dl_trailing_events; + + if (dl_lines_done + i == trg_line) + decode_chunk_ts(buf + (i * CHUNK_SIZE), + &devc->state.lastts, + &devc->state.lastsample, + triggerpos & 0x1ff, + dl_limit, sdi); + else + decode_chunk_ts(buf + (i * CHUNK_SIZE), + &devc->state.lastts, + &devc->state.lastsample, + -1, + dl_limit, sdi); + } - ++chunks_downloaded; + dl_lines_done += dl_lines_curr; } /* All done. */ -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:50
|
The NUM_CHANNELS macro is inflexible, since in 100MHz and 200MHz modes we don't support 16 channels. Moreover, it's only used to limit the size of array of channel labels, which can be done in much cleaner way. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index d17558d..039a527 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -37,7 +37,6 @@ #define USB_VENDOR_NAME "ASIX" #define USB_MODEL_NAME "SIGMA" #define TRIGGER_TYPE "rf10" -#define NUM_CHANNELS 16 SR_PRIV struct sr_dev_driver asix_sigma_driver_info; static struct sr_dev_driver *di = &asix_sigma_driver_info; @@ -67,10 +66,9 @@ static const uint64_t samplerates[] = { * http://tools.asix.net/img/sigma_sigmacab_pins_720.jpg * (the cable has two additional GND pins, and a TI and TO pin) */ -static const char *channel_names[NUM_CHANNELS + 1] = { +static const char *channel_names[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", - NULL, }; static const int32_t hwcaps[] = { @@ -416,7 +414,8 @@ static GSList *scan(GSList *options) struct ftdi_device_list *devlist; char serial_txt[10]; uint32_t serial; - int ret, i; + int ret; + unsigned int i; (void)options; @@ -470,9 +469,10 @@ static GSList *scan(GSList *options) } sdi->driver = di; - for (i = 0; channel_names[i]; i++) { - if (!(ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, - channel_names[i]))) + for (i = 0; i < ARRAY_SIZE(channel_names); i++) { + ch = sr_channel_new(i, SR_CHANNEL_LOGIC, TRUE, + channel_names[i]); + if (!ch) return NULL; sdi->channels = g_slist_append(sdi->channels, ch); } -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:51
|
Pull out the code handling the Sigma which is in CAPTURE mode into a separate function. This is so we can start reworking this entire code easily soon. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 94 +++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 39 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 4d8f238..e7fa7d3 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -1120,66 +1120,82 @@ static void download_capture(struct sr_dev_inst *sdi) } -static int receive_data(int fd, int revents, void *cb_data) +/* + * Handle the Sigma when in CAPTURE mode. This function checks: + * - Sampling time ended + * - DRAM capacity overflow + * This function triggers download of the samples from Sigma + * in case either of the above conditions is true. + */ +static int sigma_capture_mode(struct sr_dev_inst *sdi) { - struct sr_dev_inst *sdi; - struct dev_context *devc; + struct dev_context *devc = sdi->priv; + struct sr_datafeed_packet packet; uint64_t running_msec; struct timeval tv; int numchunks; uint8_t modestatus; - (void)fd; - (void)revents; + /* Get the current position. */ + sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, + devc); - sdi = cb_data; - devc = sdi->priv; + numchunks = (devc->state.stoppos + 511) / 512; - if (devc->state.state == SIGMA_IDLE) + /* Check if the timer has expired, or memory is full. */ + gettimeofday(&tv, 0); + running_msec = (tv.tv_sec - devc->start_tv.tv_sec) * 1000 + + (tv.tv_usec - devc->start_tv.tv_usec) / 1000; + + if (running_msec < devc->limit_msec && numchunks < 32767) + /* Still capturing. */ return TRUE; - if (devc->state.state == SIGMA_CAPTURE) { - /* Get the current position. */ - sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, - devc); + /* Stop acquisition. */ + sigma_set_register(WRITE_MODE, 0x11, devc); - numchunks = (devc->state.stoppos + 511) / 512; + /* Set SDRAM Read Enable. */ + sigma_set_register(WRITE_MODE, 0x02, devc); - /* Check if the timer has expired, or memory is full. */ - gettimeofday(&tv, 0); - running_msec = (tv.tv_sec - devc->start_tv.tv_sec) * 1000 + - (tv.tv_usec - devc->start_tv.tv_usec) / 1000; + /* Get the current position. */ + sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); - if (running_msec < devc->limit_msec && numchunks < 32767) - /* Still capturing. */ - return TRUE; + /* Check if trigger has fired. */ + modestatus = sigma_get_register(READ_MODE, devc); + if (modestatus & 0x20) + devc->state.triggerchunk = devc->state.triggerpos / 512; + else + devc->state.triggerchunk = -1; - /* Stop acquisition. */ - sigma_set_register(WRITE_MODE, 0x11, devc); + /* Transfer captured data from device. */ + download_capture(sdi); - /* Set SDRAM Read Enable. */ - sigma_set_register(WRITE_MODE, 0x02, devc); + /* All done. */ + packet.type = SR_DF_END; + sr_session_send(sdi, &packet); - /* Get the current position. */ - sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); + dev_acquisition_stop(sdi, sdi); - /* Check if trigger has fired. */ - modestatus = sigma_get_register(READ_MODE, devc); - if (modestatus & 0x20) - devc->state.triggerchunk = devc->state.triggerpos / 512; - else - devc->state.triggerchunk = -1; + return TRUE; +} - /* Transfer captured data from device. */ - download_capture(sdi); +static int receive_data(int fd, int revents, void *cb_data) +{ + struct sr_dev_inst *sdi; + struct dev_context *devc; - /* All done. */ - packet.type = SR_DF_END; - sr_session_send(sdi, &packet); + (void)fd; + (void)revents; - dev_acquisition_stop(sdi, sdi); - } + sdi = cb_data; + devc = sdi->priv; + + if (devc->state.state == SIGMA_IDLE) + return TRUE; + + if (devc->state.state == SIGMA_CAPTURE) + return sigma_capture_mode(sdi); return TRUE; } -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:51
|
The trigger position, stop position and chunk in which the trigger happened are no longer needed in the global scope. Make those variables local to the download_capture() function. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 29 +++++++++++++++-------------- hardware/asix-sigma/asix-sigma.h | 4 ---- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 734eccf..c44bae7 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -1075,7 +1075,8 @@ static int download_capture(struct sr_dev_inst *sdi) const int chunks_per_read = 32; unsigned char buf[chunks_per_read * CHUNK_SIZE]; int bufsz, i, numchunks, newchunks; - + uint32_t stoppos, triggerpos; + int triggerchunk, chunks_downloaded; struct sr_datafeed_packet packet; uint8_t modestatus; @@ -1088,25 +1089,25 @@ static int download_capture(struct sr_dev_inst *sdi) sigma_set_register(WRITE_MODE, 0x02, devc); /* Get the current position. */ - sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); + sigma_read_pos(&stoppos, &triggerpos, devc); /* Check if trigger has fired. */ modestatus = sigma_get_register(READ_MODE, devc); if (modestatus & 0x20) - devc->state.triggerchunk = devc->state.triggerpos / 512; + triggerchunk = triggerpos / 512; else - devc->state.triggerchunk = -1; + triggerchunk = -1; - devc->state.chunks_downloaded = 0; - numchunks = (devc->state.stoppos + 511) / 512; - newchunks = MIN(chunks_per_read, numchunks - devc->state.chunks_downloaded); + chunks_downloaded = 0; + numchunks = (stoppos + 511) / 512; + newchunks = MIN(chunks_per_read, numchunks - chunks_downloaded); - bufsz = sigma_read_dram(devc->state.chunks_downloaded, newchunks, buf, devc); + bufsz = sigma_read_dram(chunks_downloaded, newchunks, buf, devc); /* TODO: Check bufsz. For now, just avoid compiler warnings. */ (void)bufsz; /* Find first ts. */ - if (devc->state.chunks_downloaded == 0) { + if (chunks_downloaded == 0) { devc->state.lastts = RL16(buf) - 1; devc->state.lastsample = 0; } @@ -1116,16 +1117,16 @@ static int download_capture(struct sr_dev_inst *sdi) int limit_chunk = 0; /* The last chunk may potentially be only in part. */ - if (devc->state.chunks_downloaded == numchunks - 1) { + if (chunks_downloaded == numchunks - 1) { /* Find the last valid timestamp */ - limit_chunk = devc->state.stoppos % 512 + devc->state.lastts; + limit_chunk = stoppos % 512 + devc->state.lastts; } - if (devc->state.chunks_downloaded + i == devc->state.triggerchunk) + if (chunks_downloaded + i == triggerchunk) decode_chunk_ts(buf + (i * CHUNK_SIZE), &devc->state.lastts, &devc->state.lastsample, - devc->state.triggerpos & 0x1ff, + triggerpos & 0x1ff, limit_chunk, sdi); else decode_chunk_ts(buf + (i * CHUNK_SIZE), @@ -1133,7 +1134,7 @@ static int download_capture(struct sr_dev_inst *sdi) &devc->state.lastsample, -1, limit_chunk, sdi); - ++devc->state.chunks_downloaded; + ++chunks_downloaded; } /* All done. */ diff --git a/hardware/asix-sigma/asix-sigma.h b/hardware/asix-sigma/asix-sigma.h index b8362e0..1933064 100644 --- a/hardware/asix-sigma/asix-sigma.h +++ b/hardware/asix-sigma/asix-sigma.h @@ -167,12 +167,8 @@ struct sigma_state { SIGMA_DOWNLOAD, } state; - uint32_t stoppos, triggerpos; uint16_t lastts; uint16_t lastsample; - - int triggerchunk; - int chunks_downloaded; }; /* Private, per-device-instance driver context. */ -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:52
|
Clean up the way decode_chunk_ts() is called a little. Introduce a variable which will not be -1 only in case a trigger happened on the particular DRAM line. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index a4d6076..e573732 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -1083,7 +1083,7 @@ static int download_capture(struct sr_dev_inst *sdi) uint32_t i; uint32_t dl_lines_total, dl_lines_curr, dl_lines_done; uint32_t dl_trailing_events; - uint32_t trg_line; + uint32_t trg_line = ~0; dram_line = g_try_malloc0(chunks_per_read * sizeof(*dram_line)); if (!dram_line) @@ -1106,8 +1106,6 @@ static int download_capture(struct sr_dev_inst *sdi) modestatus = sigma_get_register(READ_MODE, devc); if (modestatus & 0x20) trg_line = triggerpos >> 9; - else - trg_line = ~0; /* * Determine how many 1024b "DRAM lines" do we need to read from the @@ -1135,22 +1133,19 @@ static int download_capture(struct sr_dev_inst *sdi) for (i = 0; i < dl_lines_curr; i++) { uint32_t dl_limit = 0; + int trigger_line = -1; /* The last "DRAM line" can be only partially full. */ if (dl_lines_done + i == dl_lines_total - 1) dl_limit = dl_trailing_events; + /* Test if the trigger happened on this line. */ if (dl_lines_done + i == trg_line) - decode_chunk_ts(buf + (i * CHUNK_SIZE), - &devc->state.lastts, - &devc->state.lastsample, - triggerpos & 0x1ff, - dl_limit, sdi); - else - decode_chunk_ts(buf + (i * CHUNK_SIZE), - &devc->state.lastts, - &devc->state.lastsample, - -1, - dl_limit, sdi); + trigger_line = trg_line; + + decode_chunk_ts(buf + (i * CHUNK_SIZE), + &devc->state.lastts, + &devc->state.lastsample, + trigger_line, dl_limit, sdi); } dl_lines_done += dl_lines_curr; -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:57
|
Use proper structure instead of plain buffer of uint8_t for the contents of DRAM in download_capture(). This is beneficial as we can interpret the contents easily. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index d2543a4..8be458e 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -947,10 +947,11 @@ static uint16_t sigma_dram_cluster_ts(struct sigma_dram_cluster *cluster) * For 50 MHz and below, events contain one sample for each channel, * spread 20 ns apart. */ -static int decode_chunk_ts(uint8_t *buf, uint16_t *lastts, +static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts, uint16_t *lastsample, int triggerpos, uint16_t limit_chunk, void *cb_data) { + uint8_t *buf = (uint8_t *)dram_line; struct sr_dev_inst *sdi = cb_data; struct dev_context *devc = sdi->priv; uint16_t tsdiff, ts; @@ -1083,7 +1084,6 @@ static int download_capture(struct sr_dev_inst *sdi) struct dev_context *devc = sdi->priv; const int chunks_per_read = 32; struct sigma_dram_line *dram_line; - unsigned char *buf; int bufsz; uint32_t stoppos, triggerpos; struct sr_datafeed_packet packet; @@ -1098,8 +1098,6 @@ static int download_capture(struct sr_dev_inst *sdi) if (!dram_line) return FALSE; - buf = (unsigned char *)dram_line; - sr_info("Downloading sample data."); /* Stop acquisition. */ @@ -1130,7 +1128,8 @@ static int download_capture(struct sr_dev_inst *sdi) /* We can download only up-to 32 DRAM lines in one go! */ dl_lines_curr = MIN(chunks_per_read, dl_lines_total); - bufsz = sigma_read_dram(dl_lines_done, dl_lines_curr, buf, devc); + bufsz = sigma_read_dram(dl_lines_done, dl_lines_curr, + (uint8_t *)dram_line, devc); /* TODO: Check bufsz. For now, just avoid compiler warnings. */ (void)bufsz; @@ -1152,7 +1151,7 @@ static int download_capture(struct sr_dev_inst *sdi) if (dl_lines_done + i == trg_line) trigger_line = trg_line; - decode_chunk_ts(buf + (i * CHUNK_SIZE), + decode_chunk_ts(dram_line + i, &devc->state.lastts, &devc->state.lastsample, trigger_line, dl_limit, sdi); -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:57
|
Introduce helper function which returns the timestamp of DRAM cluster and use it in download_capture(). Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index e573732..d2543a4 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -929,6 +929,15 @@ static int get_trigger_offset(uint16_t *samples, uint16_t last_sample, return i & 0x7; } + +/* + * Return the timestamp of "DRAM cluster". + */ +static uint16_t sigma_dram_cluster_ts(struct sigma_dram_cluster *cluster) +{ + return (cluster->timestamp_hi << 8) | cluster->timestamp_lo; +} + /* * Decode chunk of 1024 bytes, 64 clusters, 7 events per cluster. * Each event is 20ns apart, and can contain multiple samples. @@ -1127,7 +1136,8 @@ static int download_capture(struct sr_dev_inst *sdi) /* This is the first DRAM line, so find the initial timestamp. */ if (dl_lines_done == 0) { - devc->state.lastts = RL16(buf) - 1; + devc->state.lastts = + sigma_dram_cluster_ts(&dram_line[0].cluster[0]); devc->state.lastsample = 0; } -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:57
|
The support for trailing DRAM lines was broken. This patch starts rework of support for this, but in order to do that, we need to rework decode_chunk_ts() a little first. This patch adjusts the decode_chunk_ts() a little to receive the total amount of events in DRAM line instead of some nonsense value. This patch temporarily removes the support for the trailing DRAM lines until the decode_chunk_ts() is fixed to cope with this, so yes, this patch introduces breakage! Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 64ebcbb..59acdcb 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -949,7 +949,7 @@ static uint16_t sigma_dram_cluster_ts(struct sigma_dram_cluster *cluster) */ static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts, uint16_t *lastsample, int triggerpos, - uint16_t limit_chunk, void *cb_data) + uint16_t events_in_line, void *cb_data) { uint8_t *buf = (uint8_t *)dram_line; struct sigma_dram_cluster *dram_cluster; @@ -979,16 +979,12 @@ static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts, } /* For each ts. */ - for (i = 0; i < 64; i++) { + for (i = 0; i < (events_in_line / 7); i++) { dram_cluster = &dram_line->cluster[i]; ts = sigma_dram_cluster_ts(dram_cluster); tsdiff = ts - *lastts; *lastts = ts; - /* Decode partial chunk. */ - if (limit_chunk && ts > limit_chunk) - return SR_OK; - /* Pad last sample up to current point. */ numpad = tsdiff * devc->samples_per_event - clustersize; if (numpad > 0) { @@ -1093,7 +1089,7 @@ static int download_capture(struct sr_dev_inst *sdi) uint32_t i; uint32_t dl_lines_total, dl_lines_curr, dl_lines_done; - uint32_t dl_trailing_events; + uint32_t dl_events_in_line = 64 * 7; uint32_t trg_line = ~0; dram_line = g_try_malloc0(chunks_per_read * sizeof(*dram_line)); @@ -1122,7 +1118,6 @@ static int download_capture(struct sr_dev_inst *sdi) * line can be only partial, containing less than 64 clusters. */ dl_lines_total = (stoppos >> 9) + 1; - dl_trailing_events = stoppos & 0x1ff; dl_lines_done = 0; @@ -1143,11 +1138,10 @@ static int download_capture(struct sr_dev_inst *sdi) } for (i = 0; i < dl_lines_curr; i++) { - uint32_t dl_limit = 0; int trigger_line = -1; /* The last "DRAM line" can be only partially full. */ if (dl_lines_done + i == dl_lines_total - 1) - dl_limit = dl_trailing_events; + dl_events_in_line = stoppos & 0x1ff; /* Test if the trigger happened on this line. */ if (dl_lines_done + i == trg_line) @@ -1156,7 +1150,8 @@ static int download_capture(struct sr_dev_inst *sdi) decode_chunk_ts(dram_line + i, &devc->state.lastts, &devc->state.lastsample, - trigger_line, dl_limit, sdi); + trigger_line, + dl_events_in_line, sdi); } dl_lines_done += dl_lines_curr; -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:06:57
|
These two values can pulled out from devc->state, so there really is no need to pass them as function argument when we already pass the devc. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 14eeee1..4a0b263 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -949,8 +949,7 @@ static uint16_t sigma_dram_cluster_ts(struct sigma_dram_cluster *cluster) * For 50 MHz and below, events contain one sample for each channel, * spread 20 ns apart. */ -static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts, - uint16_t *lastsample, int triggerpos, +static int decode_chunk_ts(struct sigma_dram_line *dram_line, int triggerpos, uint16_t events_in_line, void *cb_data) { struct sigma_dram_cluster *dram_cluster; @@ -965,6 +964,7 @@ static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts, unsigned int clusters_in_line = (events_in_line + (EVENTS_PER_CLUSTER - 1)) / EVENTS_PER_CLUSTER; unsigned int events_in_cluster; + struct sigma_state *ss = &devc->state; /* Check if trigger is in this chunk. */ if (triggerpos != -1) { @@ -988,8 +988,8 @@ static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts, dram_cluster = &dram_line->cluster[i]; ts = sigma_dram_cluster_ts(dram_cluster); - tsdiff = ts - *lastts; - *lastts = ts; + tsdiff = ts - ss->lastts; + ss->lastts = ts; logic.data = samples; @@ -1006,8 +1006,8 @@ static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts, */ for (ts = 0; ts < tsdiff - (EVENTS_PER_CLUSTER - 1); ts++) { j = ts % 1024; - samples[2 * j + 0] = *lastsample & 0xff; - samples[2 * j + 1] = *lastsample >> 8; + samples[2 * j + 0] = ss->lastsample & 0xff; + samples[2 * j + 1] = ss->lastsample >> 8; /* * If we have 1024 samples ready or we're at the @@ -1045,7 +1045,7 @@ static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts, * samples to pinpoint the exact position of the trigger. */ trigger_offset = get_trigger_offset(samples, - *lastsample, &devc->trigger); + ss->lastsample, &devc->trigger); if (trigger_offset > 0) { packet.type = SR_DF_LOGIC; @@ -1069,7 +1069,7 @@ static int decode_chunk_ts(struct sigma_dram_line *dram_line, uint16_t *lastts, sr_session_send(devc->cb_data, &packet); } - *lastsample = samples[2 * (events_in_cluster - 1)] | + ss->lastsample = samples[2 * (events_in_cluster - 1)] | (samples[2 * (events_in_cluster - 1) + 1] << 8); } @@ -1146,10 +1146,7 @@ static int download_capture(struct sr_dev_inst *sdi) if (dl_lines_done + i == trg_line) trigger_line = trg_line; - decode_chunk_ts(dram_line + i, - &devc->state.lastts, - &devc->state.lastsample, - trigger_line, + decode_chunk_ts(dram_line + i, trigger_line, dl_events_in_line, sdi); } -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:07:05
|
Remove all those if ((ret = foo(bar)) < 0) constructs from upload_firmware() function. This is just a confusing programming practice, kill it. While at it, replace all the uses of &devc->ftdic with plain ftdic , which is defined at the begining. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index f813edd..931dfae 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -543,25 +543,29 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) size_t buf_size; unsigned char result[32]; const char *firmware = sigma_firmware_files[firmware_idx]; + struct ftdi_context *ftdic = &devc->ftdic; /* Make sure it's an ASIX SIGMA. */ - if ((ret = ftdi_usb_open_desc(&devc->ftdic, - USB_VENDOR, USB_PRODUCT, USB_DESCRIPTION, NULL)) < 0) { + ret = ftdi_usb_open_desc(ftdic, USB_VENDOR, USB_PRODUCT, + USB_DESCRIPTION, NULL); + if (ret < 0) { sr_err("ftdi_usb_open failed: %s", - ftdi_get_error_string(&devc->ftdic)); + ftdi_get_error_string(ftdic)); return 0; } - if ((ret = ftdi_set_bitmode(&devc->ftdic, 0xdf, BITMODE_BITBANG)) < 0) { + ret = ftdi_set_bitmode(ftdic, 0xdf, BITMODE_BITBANG); + if (ret < 0) { sr_err("ftdi_set_bitmode failed: %s", - ftdi_get_error_string(&devc->ftdic)); + ftdi_get_error_string(ftdic)); return 0; } /* Four times the speed of sigmalogan - Works well. */ - if ((ret = ftdi_set_baudrate(&devc->ftdic, 750000)) < 0) { + ret = ftdi_set_baudrate(ftdic, 750000); + if (ret < 0) { sr_err("ftdi_set_baudrate failed: %s", - ftdi_get_error_string(&devc->ftdic)); + ftdi_get_error_string(ftdic)); return 0; } @@ -571,7 +575,8 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) return ret; /* Prepare firmware. */ - if ((ret = bin2bitbang(firmware, &buf, &buf_size)) != SR_OK) { + ret = bin2bitbang(firmware, &buf, &buf_size); + if (ret != SR_OK) { sr_err("An error occured while reading the firmware: %s", firmware); return ret; @@ -583,13 +588,14 @@ static int upload_firmware(int firmware_idx, struct dev_context *devc) g_free(buf); - if ((ret = ftdi_set_bitmode(&devc->ftdic, 0x00, BITMODE_RESET)) < 0) { + ret = ftdi_set_bitmode(ftdic, 0x00, BITMODE_RESET); + if (ret < 0) { sr_err("ftdi_set_bitmode failed: %s", - ftdi_get_error_string(&devc->ftdic)); + ftdi_get_error_string(ftdic)); return SR_ERR; } - ftdi_usb_purge_buffers(&devc->ftdic); + ftdi_usb_purge_buffers(ftdic); /* Discard garbage. */ while (1 == sigma_read(&pins, 1, devc)) -- 1.8.5.3 |
From: Marek V. <ma...@de...> - 2014-04-22 16:07:07
|
Move the sigma_fw_2_bitbang() function closer to the upload_firmware() function so there's not such a horrible mess in the file. Signed-off-by: Marek Vasut <ma...@de...> --- hardware/asix-sigma/asix-sigma.c | 144 +++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 3883bc8..2cd9b9e 100644 --- a/hardware/asix-sigma/asix-sigma.c +++ b/hardware/asix-sigma/asix-sigma.c @@ -299,78 +299,6 @@ static int sigma_write_trigger_lut(struct triggerlut *lut, struct dev_context *d return SR_OK; } -/* - * Read the firmware from a file and transform it into a series of bitbang - * pulses used to program the FPGA. Note that the *bb_cmd must be free()'d - * by the caller of this function. - */ -static int sigma_fw_2_bitbang(const char *filename, - uint8_t **bb_cmd, gsize *bb_cmd_size) -{ - GMappedFile *file; - GError *error; - gsize i, file_size, bb_size; - gchar *firmware; - uint8_t *bb_stream, *bbs; - uint32_t imm; - int bit, v; - int ret = SR_OK; - - /* - * Map the file and make the mapped buffer writable. - * NOTE: Using writable=TRUE does _NOT_ mean that file that is mapped - * will be modified. It will not be modified until someone uses - * g_file_set_contents() on it. - */ - error = NULL; - file = g_mapped_file_new(filename, TRUE, &error); - g_assert_no_error(error); - - file_size = g_mapped_file_get_length(file); - firmware = g_mapped_file_get_contents(file); - g_assert(firmware); - - /* Weird magic transformation below, I have no idea what it does. */ - imm = 0x3f6df2ab; - for (i = 0; i < file_size; i++) { - imm = (imm + 0xa853753) % 177 + (imm * 0x8034052); - firmware[i] ^= imm & 0xff; - } - - /* - * Now that the firmware is "transformed", we will transcribe the - * firmware blob into a sequence of toggles of the Dx wires. This - * sequence will be fed directly into the Sigma, which must be in - * the FPGA bitbang programming mode. - */ - - /* Each bit of firmware is transcribed as two toggles of Dx wires. */ - bb_size = file_size * 8 * 2; - bb_stream = (uint8_t *)g_try_malloc(bb_size); - if (!bb_stream) { - sr_err("%s: Failed to allocate bitbang stream", __func__); - ret = SR_ERR_MALLOC; - goto exit; - } - - bbs = bb_stream; - for (i = 0; i < file_size; i++) { - for (bit = 7; bit >= 0; bit--) { - v = (firmware[i] & (1 << bit)) ? 0x40 : 0x00; - *bbs++ = v | 0x01; - *bbs++ = v; - } - } - - /* The transformation completed successfully, return the result. */ - *bb_cmd = bb_stream; - *bb_cmd_size = bb_size; - -exit: - g_mapped_file_unref(file); - return ret; -} - static void clear_helper(void *priv) { struct dev_context *devc; @@ -526,6 +454,78 @@ static int sigma_fpga_init_bitbang(struct dev_context *devc) return SR_ERR_TIMEOUT; } +/* + * Read the firmware from a file and transform it into a series of bitbang + * pulses used to program the FPGA. Note that the *bb_cmd must be free()'d + * by the caller of this function. + */ +static int sigma_fw_2_bitbang(const char *filename, + uint8_t **bb_cmd, gsize *bb_cmd_size) +{ + GMappedFile *file; + GError *error; + gsize i, file_size, bb_size; + gchar *firmware; + uint8_t *bb_stream, *bbs; + uint32_t imm; + int bit, v; + int ret = SR_OK; + + /* + * Map the file and make the mapped buffer writable. + * NOTE: Using writable=TRUE does _NOT_ mean that file that is mapped + * will be modified. It will not be modified until someone uses + * g_file_set_contents() on it. + */ + error = NULL; + file = g_mapped_file_new(filename, TRUE, &error); + g_assert_no_error(error); + + file_size = g_mapped_file_get_length(file); + firmware = g_mapped_file_get_contents(file); + g_assert(firmware); + + /* Weird magic transformation below, I have no idea what it does. */ + imm = 0x3f6df2ab; + for (i = 0; i < file_size; i++) { + imm = (imm + 0xa853753) % 177 + (imm * 0x8034052); + firmware[i] ^= imm & 0xff; + } + + /* + * Now that the firmware is "transformed", we will transcribe the + * firmware blob into a sequence of toggles of the Dx wires. This + * sequence will be fed directly into the Sigma, which must be in + * the FPGA bitbang programming mode. + */ + + /* Each bit of firmware is transcribed as two toggles of Dx wires. */ + bb_size = file_size * 8 * 2; + bb_stream = (uint8_t *)g_try_malloc(bb_size); + if (!bb_stream) { + sr_err("%s: Failed to allocate bitbang stream", __func__); + ret = SR_ERR_MALLOC; + goto exit; + } + + bbs = bb_stream; + for (i = 0; i < file_size; i++) { + for (bit = 7; bit >= 0; bit--) { + v = (firmware[i] & (1 << bit)) ? 0x40 : 0x00; + *bbs++ = v | 0x01; + *bbs++ = v; + } + } + + /* The transformation completed successfully, return the result. */ + *bb_cmd = bb_stream; + *bb_cmd_size = bb_size; + +exit: + g_mapped_file_unref(file); + return ret; +} + static int upload_firmware(int firmware_idx, struct dev_context *devc) { int ret; -- 1.8.5.3 |