Commit 5718693d authored by Dorota Czaplejewicz's avatar Dorota Czaplejewicz

buspirate-adc: Initial working version VERY DIRTY

parent cc4b8f5c
/*
* This file is part of the libsigrok project.
*
* Copyright (C) 2013 Bert Vermeulen <bert@biot.com>
* Copyright (C) 2018 Purism SPC
*
* This program is free software: you can redistribute it and/or modify
......@@ -17,39 +18,150 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* This adds verry ugly BusPirate ADC support.
* Borrows heavily from openbench-logic-sniffer.
*/
#include <config.h>
#include <string.h>
#include "protocol.h"
#define SERIALCOMM "115200/8n1"
#define RESPONSE_DELAY_US (10 * 1000)
/* Default supported samplerates, can be overridden by device metadata. */
static const uint64_t samplerates[] = {
SR_HZ(1000),
};
static const uint32_t scanopts[] = {
SR_CONF_CONN,
SR_CONF_SERIALCOMM,
};
static const uint32_t drvopts[] = {
SR_CONF_OSCILLOSCOPE,
};
static const uint32_t devopts[] = {
SR_CONF_EXTERNAL_CLOCK | SR_CONF_GET,
SR_CONF_VOLTAGE | SR_CONF_GET,
SR_CONF_CONTINUOUS | SR_CONF_GET,
};
SR_PRIV int bpa_send_shortcommand(struct sr_serial_dev_inst *serial,
uint8_t command)
{
char buf[1];
sr_dbg("Sending cmd 0x%.2x.", command);
buf[0] = command;
if (serial_write_blocking(serial, buf, 1, serial_timeout(serial, 1)) != 1)
return SR_ERR;
return SR_OK;
}
SR_PRIV int bpa_send_reset(struct sr_serial_dev_inst *serial)
{
unsigned int i;
for (i = 0; i < 10; i++) {
if (bpa_send_shortcommand(serial, 0) != SR_OK)
return SR_ERR;
}
return SR_OK;
}
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
struct drv_context *drvc;
GSList *devices;
GSList *l;
(void)options;
struct sr_config *src;
struct sr_dev_inst *sdi;
int ret;
char buf[8];
devices = NULL;
drvc = di->context;
drvc->instances = NULL;
/* TODO: scan for devices, either based on a SR_CONF_CONN option
* or on a USB scan. */
return devices;
}
static int dev_open(struct sr_dev_inst *sdi)
{
(void)sdi;
const char *conn, *serialcomm;
struct sr_serial_dev_inst *serial;
printf("scan\n");
conn = serialcomm = NULL;
for (l = options; l; l = l->next) {
src = l->data;
switch (src->key) {
case SR_CONF_CONN:
conn = g_variant_get_string(src->data, NULL);
printf("conn %s\n", conn);
break;
case SR_CONF_SERIALCOMM:
serialcomm = g_variant_get_string(src->data, NULL);
break;
}
}
if (!conn)
return NULL;
if (!serialcomm)
serialcomm = SERIALCOMM;
serial = sr_serial_dev_inst_new(conn, serialcomm);
printf("ioenong\n");
sr_info("Probing %s.", conn);
if (serial_open(serial, SERIAL_RDWR) != SR_OK)
return NULL;
printf("resetting\n");
if (bpa_send_reset(serial) != SR_OK) {
serial_close(serial);
sr_err("Could not use port %s. Quitting.", conn);
return NULL;
}
g_usleep(RESPONSE_DELAY_US * 10);
printf("replying\n");
if (sp_input_waiting(serial->data) == 0) {
sr_dbg("Didn't get any reply.");
return NULL;
}
printf("sssss\n");
ret = serial_read_blocking(serial, buf, 5, serial_timeout(serial, 5));
if (ret != 5) {
sr_err("Invalid reply (expected 5 bytes, got %d).", ret);
return NULL;
}
/* TODO: get handle from sdi->conn and open it. */
if (strncmp(buf, "BBIO1", 5)) {
sr_err("Invalid reply (expected 'BBIO1', got "
"'%c%c%c%c%c').", buf[0], buf[1], buf[2], buf[3], buf[4]);
return NULL;
}
return SR_OK;
sdi = g_malloc0(sizeof(struct sr_dev_inst));
sdi->status = SR_ST_INACTIVE;
sdi->vendor = g_strdup("Dangerous Prototypes");
sdi->model = g_strdup("BusPirate ADC");
sdi->version = g_strdup("v1.0");
sdi->inst_type = SR_INST_SERIAL;
sdi->conn = serial;
sr_channel_new(sdi, 0, SR_CHANNEL_ANALOG, TRUE,
"ADC");
return std_scan_complete(di, g_slist_append(NULL, sdi));
return devices;
}
static int dev_close(struct sr_dev_inst *sdi)
{
(void)sdi;
printf("close\n");
/* TODO: get handle from sdi->conn and close it. */
return SR_OK;
......@@ -63,7 +175,7 @@ static int config_get(uint32_t key, GVariant **data,
(void)sdi;
(void)data;
(void)cg;
printf("get\n");
ret = SR_OK;
switch (key) {
/* TODO */
......@@ -82,7 +194,7 @@ static int config_set(uint32_t key, GVariant *data,
(void)sdi;
(void)data;
(void)cg;
printf("set\n");
ret = SR_OK;
switch (key) {
/* TODO */
......@@ -101,24 +213,122 @@ static int config_list(uint32_t key, GVariant **data,
(void)sdi;
(void)data;
(void)cg;
printf("list\n");
ret = SR_OK;
switch (key) {
/* TODO */
case SR_CONF_SCAN_OPTIONS:
case SR_CONF_DEVICE_OPTIONS:
printf("options\n");
return STD_CONFIG_LIST(key, data, sdi, cg, scanopts, drvopts, devopts);
case SR_CONF_SAMPLERATE:
*data = std_gvar_samplerates_steps(ARRAY_AND_SIZE(samplerates));
break;
case SR_CONF_TRIGGER_MATCH:
printf("1\n");
break;
case SR_CONF_PATTERN_MODE:
case SR_CONF_LIMIT_SAMPLES:
printf("other\n");
break;
default:
return SR_ERR_NA;
}
printf("doe\n");
return ret;
}
struct sr_analog_encoding encoding = {
2,
FALSE,
FALSE,
FALSE,
1,
FALSE,
{ 33, 5120 },
{ 0, 1 },
};
SR_PRIV int bpa_receive_data(int fd, int revents, void *cb_data)
{
struct sr_dev_inst *sdi;
struct sr_serial_dev_inst *serial;
struct sr_datafeed_packet packet;
struct sr_datafeed_analog analog;
(void)fd;
(void)revents;
sdi = cb_data;
serial = sdi->conn;
/*
if (devc->num_transfers++ == 0) {
devc->raw_sample_buf = g_try_malloc(devc->limit_samples * 4);
if (!devc->raw_sample_buf) {
sr_err("Sample buffer malloc failed.");
return FALSE;
}*/
/* fill with 1010... for debugging */
/* memset(devc->raw_sample_buf, 0x82, devc->limit_samples * 4);
}
*/
{
/*
* This is the main loop telling us a timeout was reached, or
* we've acquired all the samples we asked for -- we're done.
* Send the (properly-ordered) buffer to the frontend.
*/
{
unsigned char byte[2];
// save the 1st byte in private data and use nonblocking instead
if (serial_read_blocking(serial, &byte, 2, serial_timeout(serial, 1)) != 2) {
return FALSE;
}
struct sr_analog_meaning meaning = {
SR_MQ_VOLTAGE,
SR_UNIT_VOLT,
SR_MQFLAG_DC,
sdi->channels,
};
analog.num_samples = 1;
analog.encoding = &encoding;
analog.meaning = &meaning;
struct sr_analog_spec spec = {1};
analog.spec = &spec;
uint16_t data = (byte[0] << 8) + byte[1];
analog.data = &data;
packet.type = SR_DF_ANALOG;
packet.payload = &analog;
sr_session_send(sdi, &packet);
}
}
return TRUE;
}
static int dev_acquisition_start(const struct sr_dev_inst *sdi)
{
/* TODO: configure hardware, reset acquisition state, set up
* callbacks and send header packet. */
(void)sdi;
printf("start\n");
struct sr_serial_dev_inst *serial;
serial = sdi->conn;
/* Start acquisition on the device. */
if (bpa_send_shortcommand(serial, 0b10101) != SR_OK)
return SR_ERR;
/* Reset all operational states. */
// memset(devc->sample, 0, 4);
std_session_send_df_header(sdi);
/* If the device stops sending for longer than it takes to send a byte,
* that means it's finished. But wait at least 100 ms to be safe.
*/
serial_source_add(sdi->session, serial, G_IO_IN, 100,
bpa_receive_data, (struct sr_dev_inst *)sdi);
printf("started\n");
return SR_OK;
}
......@@ -126,8 +336,8 @@ static int dev_acquisition_stop(struct sr_dev_inst *sdi)
{
/* TODO: stop acquisition. */
(void)sdi;
printf("stop\n");
abort_acquisition(sdi);
return SR_OK;
}
......@@ -143,7 +353,7 @@ SR_PRIV struct sr_dev_driver buspirate_adc_driver_info = {
.config_get = config_get,
.config_set = config_set,
.config_list = config_list,
.dev_open = dev_open,
.dev_open = std_serial_dev_open,
.dev_close = dev_close,
.dev_acquisition_start = dev_acquisition_start,
.dev_acquisition_stop = dev_acquisition_stop,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment