X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fasix-sigma%2Fasix-sigma.c;h=cdc0988ba63971a641ca5b8023e2b08be06580ed;hb=00c8650877a169a04f309f5ecccf7b1b67c75987;hp=2cd9b9e86a6d1743c01339e6743bd709d091f4f8;hpb=a80226bbb9966e8692a6d8b63c63e0630831041f;p=libsigrok.git diff --git a/hardware/asix-sigma/asix-sigma.c b/hardware/asix-sigma/asix-sigma.c index 2cd9b9e8..cdc0988b 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", @@ -454,6 +448,51 @@ static int sigma_fpga_init_bitbang(struct dev_context *devc) return SR_ERR_TIMEOUT; } +/* + * 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[] = { + 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]; + int ret; + + /* Initialize the logic analyzer mode. */ + sigma_write(logic_mode_start, sizeof(logic_mode_start), devc); + + /* Expect a 3 byte reply since we issued three READ requests. */ + 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 @@ -532,7 +571,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; @@ -589,19 +627,13 @@ 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. */ - 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; @@ -1088,65 +1120,85 @@ 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; + uint32_t stoppos, triggerpos; - sdi = cb_data; - devc = sdi->priv; + /* 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; + if (running_msec >= devc->limit_msec) + goto download; + + /* 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); - if (devc->state.state == SIGMA_IDLE) - return TRUE; - - if (devc->state.state == SIGMA_CAPTURE) { - numchunks = (devc->state.stoppos + 511) / 512; + /* 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; - /* 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; + /* Transfer captured data from device. */ + download_capture(sdi); - if (running_msec < devc->limit_msec && numchunks < 32767) - /* Still capturing. */ - return TRUE; + /* All done. */ + packet.type = SR_DF_END; + sr_session_send(sdi, &packet); - /* Stop acquisition. */ - sigma_set_register(WRITE_MODE, 0x11, devc); + dev_acquisition_stop(sdi, sdi); - /* Set SDRAM Read Enable. */ - sigma_set_register(WRITE_MODE, 0x02, devc); + return TRUE; +} - /* Get the current position. */ - sigma_read_pos(&devc->state.stoppos, &devc->state.triggerpos, devc); +static int receive_data(int fd, int revents, void *cb_data) +{ + struct sr_dev_inst *sdi; + struct dev_context *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; + (void)fd; + (void)revents; - /* Transfer captured data from device. */ - download_capture(sdi); + sdi = cb_data; + devc = sdi->priv; - /* All done. */ - packet.type = SR_DF_END; - sr_session_send(sdi, &packet); + if (devc->state.state == SIGMA_IDLE) + return TRUE; - dev_acquisition_stop(sdi, sdi); - } + if (devc->state.state == SIGMA_CAPTURE) + return sigma_capture_mode(sdi); return TRUE; }