X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=src%2Fhardware%2Fasix-sigma%2Fprotocol.c;h=2aec141a691345ac56879dfac98d35a881f96b84;hb=419f10950500d37489db3e3842670ac49e3607e7;hp=60970a8d89d498755959ae8575b0d0756bfe6617;hpb=88a5f9eabe72113d70c29d45dc12eabc0add9c49;p=libsigrok.git diff --git a/src/hardware/asix-sigma/protocol.c b/src/hardware/asix-sigma/protocol.c index 60970a8d..2aec141a 100644 --- a/src/hardware/asix-sigma/protocol.c +++ b/src/hardware/asix-sigma/protocol.c @@ -37,7 +37,7 @@ * few discrete values, while setter routines accept any user specified * rate that is supported by the hardware. */ -SR_PRIV const uint64_t samplerates[] = { +static const uint64_t samplerates[] = { /* 50MHz and integer divider. 1/2/5 steps (where possible). */ SR_KHZ(200), SR_KHZ(500), SR_MHZ(1), SR_MHZ(2), SR_MHZ(5), @@ -46,7 +46,10 @@ SR_PRIV const uint64_t samplerates[] = { SR_MHZ(100), SR_MHZ(200), }; -SR_PRIV const size_t samplerates_count = ARRAY_SIZE(samplerates); +SR_PRIV GVariant *sigma_get_samplerates_list(void) +{ + return std_gvar_samplerates(samplerates, ARRAY_SIZE(samplerates)); +} static const char *firmware_files[] = { [SIGMA_FW_50MHZ] = "asix-sigma-50.fw", /* 50MHz, 8bit divider. */ @@ -58,6 +61,119 @@ static const char *firmware_files[] = { #define SIGMA_FIRMWARE_SIZE_LIMIT (256 * 1024) +static int sigma_ftdi_open(const struct sr_dev_inst *sdi) +{ + struct dev_context *devc; + int vid, pid; + const char *serno; + int ret; + + devc = sdi->priv; + if (!devc) + return SR_ERR_ARG; + + if (devc->ftdi.is_open) + return SR_OK; + + vid = devc->id.vid; + pid = devc->id.pid; + serno = sdi->serial_num; + if (!vid || !pid || !serno || !*serno) + return SR_ERR_ARG; + + ret = ftdi_init(&devc->ftdi.ctx); + if (ret < 0) { + sr_err("Cannot initialize FTDI context (%d): %s.", + ret, ftdi_get_error_string(&devc->ftdi.ctx)); + return SR_ERR_IO; + } + ret = ftdi_usb_open_desc_index(&devc->ftdi.ctx, + vid, pid, NULL, serno, 0); + if (ret < 0) { + sr_err("Cannot open device (%d): %s.", + ret, ftdi_get_error_string(&devc->ftdi.ctx)); + return SR_ERR_IO; + } + devc->ftdi.is_open = TRUE; + + return SR_OK; +} + +static int sigma_ftdi_close(struct dev_context *devc) +{ + int ret; + + ret = ftdi_usb_close(&devc->ftdi.ctx); + devc->ftdi.is_open = FALSE; + devc->ftdi.must_close = FALSE; + ftdi_deinit(&devc->ftdi.ctx); + + return ret == 0 ? SR_OK : SR_ERR_IO; +} + +SR_PRIV int sigma_check_open(const struct sr_dev_inst *sdi) +{ + struct dev_context *devc; + int ret; + + if (!sdi) + return SR_ERR_ARG; + devc = sdi->priv; + if (!devc) + return SR_ERR_ARG; + + if (devc->ftdi.is_open) + return SR_OK; + + ret = sigma_ftdi_open(sdi); + if (ret != SR_OK) + return ret; + devc->ftdi.must_close = TRUE; + + return ret; +} + +SR_PRIV int sigma_check_close(struct dev_context *devc) +{ + int ret; + + if (!devc) + return SR_ERR_ARG; + + if (devc->ftdi.must_close) { + ret = sigma_ftdi_close(devc); + if (ret != SR_OK) + return ret; + devc->ftdi.must_close = FALSE; + } + + return SR_OK; +} + +SR_PRIV int sigma_force_open(const struct sr_dev_inst *sdi) +{ + struct dev_context *devc; + int ret; + + if (!sdi) + return SR_ERR_ARG; + devc = sdi->priv; + if (!devc) + return SR_ERR_ARG; + + ret = sigma_ftdi_open(sdi); + if (ret != SR_OK) + return ret; + devc->ftdi.must_close = FALSE; + + return SR_OK; +} + +SR_PRIV int sigma_force_close(struct dev_context *devc) +{ + return sigma_ftdi_close(devc); +} + /* * BEWARE! Error propagation is important, as are kinds of return values. * @@ -77,10 +193,10 @@ static int sigma_read_raw(struct dev_context *devc, void *buf, size_t size) { int ret; - ret = ftdi_read_data(&devc->ftdic, (unsigned char *)buf, size); + ret = ftdi_read_data(&devc->ftdi.ctx, (unsigned char *)buf, size); if (ret < 0) { sr_err("USB data read failed: %s", - ftdi_get_error_string(&devc->ftdic)); + ftdi_get_error_string(&devc->ftdi.ctx)); } return ret; @@ -90,10 +206,10 @@ static int sigma_write_raw(struct dev_context *devc, const void *buf, size_t siz { int ret; - ret = ftdi_write_data(&devc->ftdic, buf, size); + ret = ftdi_write_data(&devc->ftdi.ctx, buf, size); if (ret < 0) { sr_err("USB data write failed: %s", - ftdi_get_error_string(&devc->ftdic)); + ftdi_get_error_string(&devc->ftdi.ctx)); } else if ((size_t)ret != size) { sr_err("USB data write length mismatch."); } @@ -342,10 +458,13 @@ SR_PRIV int sigma_write_trigger_lut(struct dev_context *devc, wrptr = buf; write_u8_inc(&wrptr, tmp[0]); write_u8_inc(&wrptr, tmp[1]); - ret = sigma_write_register(devc, WRITE_TRIGGER_SELECT, buf, wrptr - buf); + ret = sigma_write_register(devc, WRITE_TRIGGER_SELECT, + buf, wrptr - buf); if (ret != SR_OK) return ret; - ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, 0x30 | i); + ret = sigma_set_register(devc, WRITE_TRIGGER_SELECT2, + TRGSEL2_RESET | TRGSEL2_LUT_WRITE | + (i & TRGSEL2_LUT_ADDR_MASK)); if (ret != SR_OK) return ret; } @@ -459,7 +578,7 @@ static int sigma_fpga_init_bitbang_once(struct dev_context *devc) if (ret != SR_OK) return ret; g_usleep(10 * 1000); - ftdi_usb_purge_buffers(&devc->ftdic); + ftdi_usb_purge_buffers(&devc->ftdi.ctx); /* * Wait until the FPGA asserts INIT_B. Check in a maximum number @@ -677,16 +796,16 @@ static int upload_firmware(struct sr_context *ctx, struct dev_context *devc, devc->state.state = SIGMA_CONFIG; /* Set the cable to bitbang mode. */ - ret = ftdi_set_bitmode(&devc->ftdic, BB_PINMASK, BITMODE_BITBANG); + ret = ftdi_set_bitmode(&devc->ftdi.ctx, BB_PINMASK, BITMODE_BITBANG); if (ret < 0) { sr_err("Could not setup cable mode for upload: %s", - ftdi_get_error_string(&devc->ftdic)); + ftdi_get_error_string(&devc->ftdi.ctx)); return SR_ERR; } - ret = ftdi_set_baudrate(&devc->ftdic, BB_BITRATE); + ret = ftdi_set_baudrate(&devc->ftdi.ctx, BB_BITRATE); if (ret < 0) { sr_err("Could not setup bitrate for upload: %s", - ftdi_get_error_string(&devc->ftdic)); + ftdi_get_error_string(&devc->ftdi.ctx)); return SR_ERR; } @@ -714,13 +833,13 @@ static int upload_firmware(struct sr_context *ctx, struct dev_context *devc, } /* Leave bitbang mode and discard pending input data. */ - ret = ftdi_set_bitmode(&devc->ftdic, 0, BITMODE_RESET); + ret = ftdi_set_bitmode(&devc->ftdi.ctx, 0, BITMODE_RESET); if (ret < 0) { sr_err("Could not setup cable mode after upload: %s", - ftdi_get_error_string(&devc->ftdic)); + ftdi_get_error_string(&devc->ftdi.ctx)); return SR_ERR; } - ftdi_usb_purge_buffers(&devc->ftdic); + ftdi_usb_purge_buffers(&devc->ftdi.ctx); while (sigma_read_raw(devc, &pins, sizeof(pins)) > 0) ; @@ -851,6 +970,13 @@ SR_PRIV int sigma_normalize_samplerate(uint64_t want_rate, uint64_t *have_rate) return SR_ERR_ARG; } +SR_PRIV uint64_t sigma_get_samplerate(const struct sr_dev_inst *sdi) +{ + /* TODO Retrieve value from hardware. */ + (void)sdi; + return samplerates[0]; +} + SR_PRIV int sigma_set_samplerate(const struct sr_dev_inst *sdi) { struct dev_context *devc; @@ -1676,7 +1802,7 @@ static void add_trigger_function(enum triggerop oper, enum triggerfunc func, SR_PRIV int sigma_build_basic_trigger(struct dev_context *devc, struct triggerlut *lut) { - int i,j; + int i, j; uint16_t masks[2]; memset(lut, 0, sizeof(*lut));